53 #define RSS_HKEY_LEN 40
55 uint8_t rss_hkey[] = { 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D,
56 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D,
57 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A };
60 #define ROUNDUP(x, y) ((((x) + ((y)-1)) / (y)) * (y))
71 static char *AllocArgument(
size_t arg_len);
72 static char *AllocAndSetArgument(
const char *arg);
73 static char *AllocAndSetOption(
const char *arg);
75 static void ArgumentsInit(
struct Arguments *args,
unsigned capacity);
76 static void ArgumentsCleanup(
struct Arguments *args);
77 static void ArgumentsAdd(
struct Arguments *args,
char *value);
78 static void ArgumentsAddOptionAndArgument(
struct Arguments *args,
const char *opt,
const char *arg);
79 static void InitEal(
void);
81 static void ConfigSetIface(
DPDKIfaceConfig *iconf,
const char *entry_str);
82 static int ConfigSetThreads(
DPDKIfaceConfig *iconf,
const char *entry_str);
83 static int ConfigSetRxQueues(
DPDKIfaceConfig *iconf, uint16_t nb_queues);
84 static int ConfigSetTxQueues(
DPDKIfaceConfig *iconf, uint16_t nb_queues);
85 static int ConfigSetMempoolSize(
DPDKIfaceConfig *iconf, intmax_t entry_int);
86 static int ConfigSetMempoolCacheSize(
DPDKIfaceConfig *iconf,
const char *entry_str);
87 static int ConfigSetRxDescriptors(
DPDKIfaceConfig *iconf, intmax_t entry_int);
88 static int ConfigSetTxDescriptors(
DPDKIfaceConfig *iconf, intmax_t entry_int);
90 static bool ConfigSetPromiscuousMode(
DPDKIfaceConfig *iconf,
int entry_bool);
92 static int ConfigSetChecksumChecks(
DPDKIfaceConfig *iconf,
int entry_bool);
93 static int ConfigSetChecksumOffload(
DPDKIfaceConfig *iconf,
int entry_bool);
94 static int ConfigSetCopyIface(
DPDKIfaceConfig *iconf,
const char *entry_str);
95 static int ConfigSetCopyMode(
DPDKIfaceConfig *iconf,
const char *entry_str);
96 static int ConfigSetCopyIfaceSettings(
DPDKIfaceConfig *iconf,
const char *iface,
const char *mode);
102 const struct rte_eth_dev_info *dev_info,
struct rte_eth_conf *port_conf);
103 static int DeviceConfigureQueues(
DPDKIfaceConfig *iconf,
const struct rte_eth_dev_info *dev_info,
104 const struct rte_eth_conf *port_conf);
108 static void *ParseDpdkConfigAndConfigureDevice(
const char *iface);
109 static void DPDKDerefConfig(
void *conf);
111 #define DPDK_CONFIG_DEFAULT_THREADS "auto"
112 #define DPDK_CONFIG_DEFAULT_MEMPOOL_SIZE 65535
113 #define DPDK_CONFIG_DEFAULT_MEMPOOL_CACHE_SIZE "auto"
114 #define DPDK_CONFIG_DEFAULT_RX_DESCRIPTORS 1024
115 #define DPDK_CONFIG_DEFAULT_TX_DESCRIPTORS 1024
116 #define DPDK_CONFIG_DEFAULT_RSS_HASH_FUNCTIONS RTE_ETH_RSS_IP
117 #define DPDK_CONFIG_DEFAULT_MTU 1500
118 #define DPDK_CONFIG_DEFAULT_PROMISCUOUS_MODE 1
119 #define DPDK_CONFIG_DEFAULT_MULTICAST_MODE 1
120 #define DPDK_CONFIG_DEFAULT_CHECKSUM_VALIDATION 1
121 #define DPDK_CONFIG_DEFAULT_CHECKSUM_VALIDATION_OFFLOAD 1
122 #define DPDK_CONFIG_DEFAULT_COPY_MODE "none"
123 #define DPDK_CONFIG_DEFAULT_COPY_INTERFACE "none"
127 .promisc =
"promisc",
128 .multicast =
"multicast",
129 .checksum_checks =
"checksum-checks",
130 .checksum_checks_offload =
"checksum-checks-offload",
132 .rss_hf =
"rss-hash-functions",
133 .mempool_size =
"mempool-size",
134 .mempool_cache_size =
"mempool-cache-size",
135 .rx_descriptors =
"rx-descriptors",
136 .tx_descriptors =
"tx-descriptors",
137 .copy_mode =
"copy-mode",
138 .copy_iface =
"copy-iface",
141 static int GreatestDivisorUpTo(uint32_t num, uint32_t max_num)
143 for (
int i = max_num; i >= 2; i--) {
151 static char *AllocArgument(
size_t arg_len)
157 ptr = (
char *)
SCCalloc(arg_len,
sizeof(
char));
159 FatalError(
"Could not allocate memory for an argument");
169 static char *AllocAndSetArgument(
const char *arg)
173 FatalError(
"Passed argument is NULL in DPDK config initialization");
176 size_t arg_len = strlen(arg);
178 ptr = AllocArgument(arg_len);
179 strlcpy(ptr, arg, arg_len + 1);
183 static char *AllocAndSetOption(
const char *arg)
187 FatalError(
"Passed option is NULL in DPDK config initialization");
190 size_t arg_len = strlen(arg);
191 uint8_t is_long_arg = arg_len > 1;
192 const char *dash_prefix = is_long_arg ?
"--" :
"-";
193 size_t full_len = arg_len + strlen(dash_prefix);
195 ptr = AllocArgument(full_len);
196 strlcpy(ptr, dash_prefix, strlen(dash_prefix) + 1);
197 strlcat(ptr, arg, full_len + 1);
201 static void ArgumentsInit(
struct Arguments *args,
unsigned capacity)
204 args->argv =
SCCalloc(capacity,
sizeof(ptrdiff_t));
205 if (args->argv == NULL)
206 FatalError(
"Could not allocate memory for Arguments structure");
208 args->capacity = capacity;
213 static void ArgumentsCleanup(
struct Arguments *args)
216 for (
int i = 0; i < args->argc; i++) {
217 if (args->argv[i] != NULL) {
219 args->argv[i] = NULL;
229 static void ArgumentsAdd(
struct Arguments *args,
char *value)
232 if (args->argc + 1 > args->capacity)
233 FatalError(
"No capacity for more arguments (Max: %" PRIu32
")", EAL_ARGS);
235 args->argv[args->argc++] = value;
239 static void ArgumentsAddOptionAndArgument(
struct Arguments *args,
const char *opt,
const char *arg)
245 option = AllocAndSetOption(opt);
246 ArgumentsAdd(args, option);
249 if (arg == NULL || arg[0] ==
'\0')
252 argument = AllocAndSetArgument(arg);
253 ArgumentsAdd(args, argument);
257 static void InitEal(
void)
263 struct Arguments args;
266 if (eal_params == NULL) {
267 FatalError(
"DPDK EAL parameters not found in the config");
270 ArgumentsInit(&args, EAL_ARGS);
271 ArgumentsAdd(&args, AllocAndSetArgument(
"suricata"));
274 ArgumentsAddOptionAndArgument(&args, param->
name, param->
val);
278 eal_argv =
SCMalloc(args.argc *
sizeof(args.argv));
279 if (eal_argv == NULL) {
280 FatalError(
"Failed to allocate memory for the array of DPDK EAL arguments");
282 memcpy(eal_argv, args.argv, args.argc *
sizeof(*args.argv));
284 rte_log_set_global_level(RTE_LOG_WARNING);
285 retval = rte_eal_init(args.argc, eal_argv);
287 ArgumentsCleanup(&args);
291 FatalError(
"DPDK EAL initialization error: %s", rte_strerror(-retval));
296 static void DPDKDerefConfig(
void *conf)
302 if (iconf->pkt_mempool != NULL) {
303 rte_mempool_free(iconf->pkt_mempool);
317 FatalError(
"Could not allocate memory for DPDKIfaceConfig");
319 ptr->pkt_mempool = NULL;
320 ptr->out_port_id = -1;
323 ptr->DerefFunc = DPDKDerefConfig;
330 static void ConfigSetIface(
DPDKIfaceConfig *iconf,
const char *entry_str)
335 if (entry_str == NULL || entry_str[0] ==
'\0')
336 FatalError(
"Interface name in DPDK config is NULL or empty");
338 retval = rte_eth_dev_get_port_by_name(entry_str, &iconf->port_id);
340 FatalError(
"Interface \"%s\": %s", entry_str, rte_strerror(-retval));
342 strlcpy(iconf->iface, entry_str,
sizeof(iconf->iface));
346 static int ConfigSetThreads(
DPDKIfaceConfig *iconf,
const char *entry_str)
351 if (active_runmode && !strcmp(
"single", active_runmode)) {
356 if (entry_str == NULL) {
357 SCLogError(
"Number of threads for interface \"%s\" not specified", iconf->iface);
361 if (strcmp(entry_str,
"auto") == 0) {
363 SCLogPerf(
"%u cores, so using %u threads", iconf->threads, iconf->threads);
368 SCLogError(
"Threads entry for interface %s contain non-numerical characters - \"%s\"",
369 iconf->iface, entry_str);
373 if (iconf->threads < 0) {
374 SCLogError(
"Interface %s has a negative number of threads", iconf->iface);
381 static int ConfigSetRxQueues(
DPDKIfaceConfig *iconf, uint16_t nb_queues)
384 iconf->nb_rx_queues = nb_queues;
385 if (iconf->nb_rx_queues < 1) {
386 SCLogError(
"Interface %s requires to have positive number of RX queues", iconf->iface);
393 static int ConfigSetTxQueues(
DPDKIfaceConfig *iconf, uint16_t nb_queues)
396 iconf->nb_tx_queues = nb_queues;
397 if (iconf->nb_tx_queues < 1) {
398 SCLogError(
"Interface %s requires to have positive number of TX queues", iconf->iface);
405 static int ConfigSetMempoolSize(
DPDKIfaceConfig *iconf, intmax_t entry_int)
408 if (entry_int <= 0) {
409 SCLogError(
"Interface %s requires to have positive memory pool size", iconf->iface);
413 iconf->mempool_size = entry_int;
417 static int ConfigSetMempoolCacheSize(
DPDKIfaceConfig *iconf,
const char *entry_str)
420 if (entry_str == NULL || entry_str[0] ==
'\0' || strcmp(entry_str,
"auto") == 0) {
425 if (iconf->mempool_size == 0) {
426 SCLogError(
"Cannot calculate mempool cache size of a mempool with size %d",
427 iconf->mempool_size);
431 uint32_t max_cache_size =
MAX(RTE_MEMPOOL_CACHE_MAX_SIZE, iconf->mempool_size / 1.5);
432 iconf->mempool_cache_size = GreatestDivisorUpTo(iconf->mempool_size, max_cache_size);
437 SCLogError(
"Mempool cache size entry for interface %s contain non-numerical "
438 "characters - \"%s\"",
439 iconf->iface, entry_str);
443 if (iconf->mempool_cache_size <= 0 || iconf->mempool_cache_size > RTE_MEMPOOL_CACHE_MAX_SIZE) {
445 "Interface %s requires to have mempool cache size set to a positive number smaller "
447 iconf->iface, RTE_MEMPOOL_CACHE_MAX_SIZE);
454 static int ConfigSetRxDescriptors(
DPDKIfaceConfig *iconf, intmax_t entry_int)
457 if (entry_int <= 0) {
458 SCLogError(
"Interface %s requires to have positive number of RX descriptors", iconf->iface);
462 iconf->nb_rx_desc = entry_int;
466 static int ConfigSetTxDescriptors(
DPDKIfaceConfig *iconf, intmax_t entry_int)
469 if (entry_int <= 0) {
470 SCLogError(
"Interface %s requires to have positive number of TX descriptors", iconf->iface);
474 iconf->nb_tx_desc = entry_int;
478 static int ConfigSetRSSHashFunctions(
DPDKIfaceConfig *iconf,
const char *entry_str)
481 if (entry_str == NULL || entry_str[0] ==
'\0' || strcmp(entry_str,
"auto") == 0) {
482 iconf->rss_hf = DPDK_CONFIG_DEFAULT_RSS_HASH_FUNCTIONS;
487 SCLogError(
"RSS hash functions entry for interface %s contain non-numerical "
488 "characters - \"%s\"",
489 iconf->iface, entry_str);
499 if (entry_int < RTE_ETHER_MIN_MTU || entry_int > RTE_ETHER_MAX_JUMBO_FRAME_LEN) {
500 SCLogError(
"Interface %s requires to have size of MTU between %" PRIu32
" and %" PRIu32,
501 iconf->iface, RTE_ETHER_MIN_MTU, RTE_ETHER_MAX_JUMBO_FRAME_LEN);
505 iconf->mtu = entry_int;
509 static bool ConfigSetPromiscuousMode(
DPDKIfaceConfig *iconf,
int entry_bool)
527 static int ConfigSetChecksumChecks(
DPDKIfaceConfig *iconf,
int entry_bool)
536 static int ConfigSetChecksumOffload(
DPDKIfaceConfig *iconf,
int entry_bool)
545 static int ConfigSetCopyIface(
DPDKIfaceConfig *iconf,
const char *entry_str)
550 if (entry_str == NULL || entry_str[0] ==
'\0' || strcmp(entry_str,
"none") == 0) {
551 iconf->out_iface = NULL;
555 retval = rte_eth_dev_get_port_by_name(entry_str, &iconf->out_port_id);
557 SCLogError(
"%s: name of the copy interface (%s) is invalid (err %d)", iconf->iface,
562 iconf->out_iface = entry_str;
566 static int ConfigSetCopyMode(
DPDKIfaceConfig *iconf,
const char *entry_str)
569 if (entry_str == NULL) {
570 SCLogWarning(
"Interface %s has no copy mode specified, changing to %s ", iconf->iface,
571 DPDK_CONFIG_DEFAULT_COPY_MODE);
572 entry_str = DPDK_CONFIG_DEFAULT_COPY_MODE;
575 if (strcmp(entry_str,
"none") != 0 && strcmp(entry_str,
"tap") != 0 &&
576 strcmp(entry_str,
"ips") != 0) {
578 "Copy mode \"%s\" is not one of the possible values (none|tap|ips) for interface "
579 "%s. Changing to %s",
580 entry_str, iconf->iface, DPDK_CONFIG_DEFAULT_COPY_MODE);
581 entry_str = DPDK_CONFIG_DEFAULT_COPY_MODE;
584 if (strcmp(entry_str,
"none") == 0) {
586 }
else if (strcmp(entry_str,
"tap") == 0) {
588 }
else if (strcmp(entry_str,
"ips") == 0) {
595 static int ConfigSetCopyIfaceSettings(
DPDKIfaceConfig *iconf,
const char *iface,
const char *mode)
600 retval = ConfigSetCopyIface(iconf, iface);
604 retval = ConfigSetCopyMode(iconf, mode);
609 if (iconf->out_iface != NULL)
610 iconf->out_iface = NULL;
614 if (iconf->out_iface == NULL || strlen(iconf->out_iface) <= 0) {
615 SCLogError(
"%s: copy mode enabled but interface not set", iconf->iface);
628 const char *entry_str = NULL;
629 intmax_t entry_int = 0;
631 const char *copy_iface_str = NULL;
632 const char *copy_mode_str = NULL;
634 ConfigSetIface(iconf, iface);
638 FatalError(
"failed to find DPDK configuration for the interface %s", iconf->iface);
642 ? ConfigSetThreads(iconf, DPDK_CONFIG_DEFAULT_THREADS)
643 : ConfigSetThreads(iconf, entry_str);
648 retval = ConfigSetRxQueues(iconf, (uint16_t)iconf->threads);
653 retval = ConfigSetTxQueues(iconf, (uint16_t)iconf->threads);
658 if_root, if_default, dpdk_yaml.
mempool_size, &entry_int) != 1
659 ? ConfigSetMempoolSize(iconf, DPDK_CONFIG_DEFAULT_MEMPOOL_SIZE)
660 : ConfigSetMempoolSize(iconf, entry_int);
666 ? ConfigSetMempoolCacheSize(iconf, DPDK_CONFIG_DEFAULT_MEMPOOL_CACHE_SIZE)
667 : ConfigSetMempoolCacheSize(iconf, entry_str);
673 ? ConfigSetRxDescriptors(iconf, DPDK_CONFIG_DEFAULT_RX_DESCRIPTORS)
674 : ConfigSetRxDescriptors(iconf, entry_int);
680 ? ConfigSetTxDescriptors(iconf, DPDK_CONFIG_DEFAULT_TX_DESCRIPTORS)
681 : ConfigSetTxDescriptors(iconf, entry_int);
686 ? ConfigSetMtu(iconf, DPDK_CONFIG_DEFAULT_MTU)
687 : ConfigSetMtu(iconf, entry_int);
692 ? ConfigSetRSSHashFunctions(iconf, NULL)
693 : ConfigSetRSSHashFunctions(iconf, entry_str);
698 if_root, if_default, dpdk_yaml.
promisc, &entry_bool) != 1
699 ? ConfigSetPromiscuousMode(iconf, DPDK_CONFIG_DEFAULT_PROMISCUOUS_MODE)
700 : ConfigSetPromiscuousMode(iconf, entry_bool);
705 if_root, if_default, dpdk_yaml.
multicast, &entry_bool) != 1
706 ? ConfigSetMulticast(iconf, DPDK_CONFIG_DEFAULT_MULTICAST_MODE)
707 : ConfigSetMulticast(iconf, entry_bool);
713 ? ConfigSetChecksumChecks(iconf, DPDK_CONFIG_DEFAULT_CHECKSUM_VALIDATION)
714 : ConfigSetChecksumChecks(iconf, entry_bool);
720 ? ConfigSetChecksumOffload(
721 iconf, DPDK_CONFIG_DEFAULT_CHECKSUM_VALIDATION_OFFLOAD)
722 : ConfigSetChecksumOffload(iconf, entry_bool);
733 if_root, if_default, dpdk_yaml.
copy_iface, ©_iface_str);
739 retval = ConfigSetCopyIfaceSettings(iconf, copy_iface_str, copy_mode_str);
755 retval = ConfigLoad(iconf, iface);
757 iconf->DerefFunc(iconf);
764 static void DeviceSetPMDSpecificRSS(
struct rte_eth_rss_conf *rss_conf,
const char *driver_name)
767 if (strcmp(driver_name,
"net_i40e") == 0)
768 i40eDeviceSetRSSHashFunction(&rss_conf->rss_hf);
769 if (strcmp(driver_name,
"net_ice") == 0)
770 iceDeviceSetRSSHashFunction(&rss_conf->rss_hf);
771 if (strcmp(driver_name,
"net_ixgbe") == 0)
772 ixgbeDeviceSetRSSHashFunction(&rss_conf->rss_hf);
773 if (strcmp(driver_name,
"net_e1000_igb") == 0)
774 rss_conf->rss_hf = (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_IPV6_EX);
778 static int GetFirstSetBitPosition(uint64_t bits)
780 for (uint64_t i = 0; i < 64; i++) {
787 static void DumpRSSFlags(
const uint64_t requested,
const uint64_t actual)
792 "RTE_ETH_RSS_IP %sset", ((requested & RTE_ETH_RSS_IP) == RTE_ETH_RSS_IP) ?
"" :
"NOT ");
794 ((requested & RTE_ETH_RSS_TCP) == RTE_ETH_RSS_TCP) ?
"" :
"NOT ");
796 ((requested & RTE_ETH_RSS_UDP) == RTE_ETH_RSS_UDP) ?
"" :
"NOT ");
798 ((requested & RTE_ETH_RSS_SCTP) == RTE_ETH_RSS_SCTP) ?
"" :
"NOT ");
800 ((requested & RTE_ETH_RSS_TUNNEL) == RTE_ETH_RSS_TUNNEL) ?
"" :
"NOT ");
803 SCLogConfig(
"RTE_ETH_RSS_IPV4 (Bit position: %d) %sset",
804 GetFirstSetBitPosition(RTE_ETH_RSS_IPV4), (requested & RTE_ETH_RSS_IPV4) ?
"" :
"NOT ");
805 SCLogConfig(
"RTE_ETH_RSS_FRAG_IPV4 (Bit position: %d) %sset",
806 GetFirstSetBitPosition(RTE_ETH_RSS_FRAG_IPV4),
807 (requested & RTE_ETH_RSS_FRAG_IPV4) ?
"" :
"NOT ");
808 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_TCP (Bit position: %d) %sset",
809 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV4_TCP),
810 (requested & RTE_ETH_RSS_NONFRAG_IPV4_TCP) ?
"" :
"NOT ");
811 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_UDP (Bit position: %d) %sset",
812 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV4_UDP),
813 (requested & RTE_ETH_RSS_NONFRAG_IPV4_UDP) ?
"" :
"NOT ");
814 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_SCTP (Bit position: %d) %sset",
815 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV4_SCTP),
816 (requested & RTE_ETH_RSS_NONFRAG_IPV4_SCTP) ?
"" :
"NOT ");
817 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_OTHER (Bit position: %d) %sset",
818 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV4_OTHER),
819 (requested & RTE_ETH_RSS_NONFRAG_IPV4_OTHER) ?
"" :
"NOT ");
820 SCLogConfig(
"RTE_ETH_RSS_IPV6 (Bit position: %d) %sset",
821 GetFirstSetBitPosition(RTE_ETH_RSS_IPV6), (requested & RTE_ETH_RSS_IPV6) ?
"" :
"NOT ");
822 SCLogConfig(
"RTE_ETH_RSS_FRAG_IPV6 (Bit position: %d) %sset",
823 GetFirstSetBitPosition(RTE_ETH_RSS_FRAG_IPV6),
824 (requested & RTE_ETH_RSS_FRAG_IPV6) ?
"" :
"NOT ");
825 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_TCP (Bit position: %d) %sset",
826 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV6_TCP),
827 (requested & RTE_ETH_RSS_NONFRAG_IPV6_TCP) ?
"" :
"NOT ");
828 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_UDP (Bit position: %d) %sset",
829 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV6_UDP),
830 (requested & RTE_ETH_RSS_NONFRAG_IPV6_UDP) ?
"" :
"NOT ");
831 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_SCTP (Bit position: %d) %sset",
832 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV6_SCTP),
833 (requested & RTE_ETH_RSS_NONFRAG_IPV6_SCTP) ?
"" :
"NOT ");
834 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_OTHER (Bit position: %d) %sset",
835 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV6_OTHER),
836 (requested & RTE_ETH_RSS_NONFRAG_IPV6_OTHER) ?
"" :
"NOT ");
838 SCLogConfig(
"RTE_ETH_RSS_L2_PAYLOAD (Bit position: %d) %sset",
839 GetFirstSetBitPosition(RTE_ETH_RSS_L2_PAYLOAD),
840 (requested & RTE_ETH_RSS_L2_PAYLOAD) ?
"" :
"NOT ");
841 SCLogConfig(
"RTE_ETH_RSS_IPV6_EX (Bit position: %d) %sset",
842 GetFirstSetBitPosition(RTE_ETH_RSS_IPV6_EX),
843 (requested & RTE_ETH_RSS_IPV6_EX) ?
"" :
"NOT ");
844 SCLogConfig(
"RTE_ETH_RSS_IPV6_TCP_EX (Bit position: %d) %sset",
845 GetFirstSetBitPosition(RTE_ETH_RSS_IPV6_TCP_EX),
846 (requested & RTE_ETH_RSS_IPV6_TCP_EX) ?
"" :
"NOT ");
847 SCLogConfig(
"RTE_ETH_RSS_IPV6_UDP_EX (Bit position: %d) %sset",
848 GetFirstSetBitPosition(RTE_ETH_RSS_IPV6_UDP_EX),
849 (requested & RTE_ETH_RSS_IPV6_UDP_EX) ?
"" :
"NOT ");
851 SCLogConfig(
"RTE_ETH_RSS_PORT (Bit position: %d) %sset",
852 GetFirstSetBitPosition(RTE_ETH_RSS_PORT), (requested & RTE_ETH_RSS_PORT) ?
"" :
"NOT ");
853 SCLogConfig(
"RTE_ETH_RSS_VXLAN (Bit position: %d) %sset",
854 GetFirstSetBitPosition(RTE_ETH_RSS_VXLAN),
855 (requested & RTE_ETH_RSS_VXLAN) ?
"" :
"NOT ");
856 SCLogConfig(
"RTE_ETH_RSS_NVGRE (Bit position: %d) %sset",
857 GetFirstSetBitPosition(RTE_ETH_RSS_NVGRE),
858 (requested & RTE_ETH_RSS_NVGRE) ?
"" :
"NOT ");
859 SCLogConfig(
"RTE_ETH_RSS_GTPU (Bit position: %d) %sset",
860 GetFirstSetBitPosition(RTE_ETH_RSS_GTPU), (requested & RTE_ETH_RSS_GTPU) ?
"" :
"NOT ");
862 SCLogConfig(
"RTE_ETH_RSS_L3_SRC_ONLY (Bit position: %d) %sset",
863 GetFirstSetBitPosition(RTE_ETH_RSS_L3_SRC_ONLY),
864 (requested & RTE_ETH_RSS_L3_SRC_ONLY) ?
"" :
"NOT ");
865 SCLogConfig(
"RTE_ETH_RSS_L3_DST_ONLY (Bit position: %d) %sset",
866 GetFirstSetBitPosition(RTE_ETH_RSS_L3_DST_ONLY),
867 (requested & RTE_ETH_RSS_L3_DST_ONLY) ?
"" :
"NOT ");
868 SCLogConfig(
"RTE_ETH_RSS_L4_SRC_ONLY (Bit position: %d) %sset",
869 GetFirstSetBitPosition(RTE_ETH_RSS_L4_SRC_ONLY),
870 (requested & RTE_ETH_RSS_L4_SRC_ONLY) ?
"" :
"NOT ");
871 SCLogConfig(
"RTE_ETH_RSS_L4_DST_ONLY (Bit position: %d) %sset",
872 GetFirstSetBitPosition(RTE_ETH_RSS_L4_DST_ONLY),
873 (requested & RTE_ETH_RSS_L4_DST_ONLY) ?
"" :
"NOT ");
876 "RTE_ETH_RSS_IP %sset", ((actual & RTE_ETH_RSS_IP) == RTE_ETH_RSS_IP) ?
"" :
"NOT ");
878 "RTE_ETH_RSS_TCP %sset", ((actual & RTE_ETH_RSS_TCP) == RTE_ETH_RSS_TCP) ?
"" :
"NOT ");
880 "RTE_ETH_RSS_UDP %sset", ((actual & RTE_ETH_RSS_UDP) == RTE_ETH_RSS_UDP) ?
"" :
"NOT ");
882 ((actual & RTE_ETH_RSS_SCTP) == RTE_ETH_RSS_SCTP) ?
"" :
"NOT ");
884 ((actual & RTE_ETH_RSS_TUNNEL) == RTE_ETH_RSS_TUNNEL) ?
"" :
"NOT ");
887 SCLogConfig(
"RTE_ETH_RSS_IPV4 %sset", (actual & RTE_ETH_RSS_IPV4) ?
"" :
"NOT ");
888 SCLogConfig(
"RTE_ETH_RSS_FRAG_IPV4 %sset", (actual & RTE_ETH_RSS_FRAG_IPV4) ?
"" :
"NOT ");
890 (actual & RTE_ETH_RSS_NONFRAG_IPV4_TCP) ?
"" :
"NOT ");
892 (actual & RTE_ETH_RSS_NONFRAG_IPV4_UDP) ?
"" :
"NOT ");
894 (actual & RTE_ETH_RSS_NONFRAG_IPV4_SCTP) ?
"" :
"NOT ");
895 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_OTHER %sset",
896 (actual & RTE_ETH_RSS_NONFRAG_IPV4_OTHER) ?
"" :
"NOT ");
897 SCLogConfig(
"RTE_ETH_RSS_IPV6 %sset", (actual & RTE_ETH_RSS_IPV6) ?
"" :
"NOT ");
898 SCLogConfig(
"RTE_ETH_RSS_FRAG_IPV6 %sset", (actual & RTE_ETH_RSS_FRAG_IPV6) ?
"" :
"NOT ");
900 (actual & RTE_ETH_RSS_NONFRAG_IPV6_TCP) ?
"" :
"NOT ");
902 (actual & RTE_ETH_RSS_NONFRAG_IPV6_UDP) ?
"" :
"NOT ");
904 (actual & RTE_ETH_RSS_NONFRAG_IPV6_SCTP) ?
"" :
"NOT ");
905 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_OTHER %sset",
906 (actual & RTE_ETH_RSS_NONFRAG_IPV6_OTHER) ?
"" :
"NOT ");
908 SCLogConfig(
"RTE_ETH_RSS_L2_PAYLOAD %sset", (actual & RTE_ETH_RSS_L2_PAYLOAD) ?
"" :
"NOT ");
909 SCLogConfig(
"RTE_ETH_RSS_IPV6_EX %sset", (actual & RTE_ETH_RSS_IPV6_EX) ?
"" :
"NOT ");
910 SCLogConfig(
"RTE_ETH_RSS_IPV6_TCP_EX %sset", (actual & RTE_ETH_RSS_IPV6_TCP_EX) ?
"" :
"NOT ");
911 SCLogConfig(
"RTE_ETH_RSS_IPV6_UDP_EX %sset", (actual & RTE_ETH_RSS_IPV6_UDP_EX) ?
"" :
"NOT ");
913 SCLogConfig(
"RTE_ETH_RSS_PORT %sset", (actual & RTE_ETH_RSS_PORT) ?
"" :
"NOT ");
914 SCLogConfig(
"RTE_ETH_RSS_VXLAN %sset", (actual & RTE_ETH_RSS_VXLAN) ?
"" :
"NOT ");
915 SCLogConfig(
"RTE_ETH_RSS_NVGRE %sset", (actual & RTE_ETH_RSS_NVGRE) ?
"" :
"NOT ");
916 SCLogConfig(
"RTE_ETH_RSS_GTPU %sset", (actual & RTE_ETH_RSS_GTPU) ?
"" :
"NOT ");
918 SCLogConfig(
"RTE_ETH_RSS_L3_SRC_ONLY %sset", (actual & RTE_ETH_RSS_L3_SRC_ONLY) ?
"" :
"NOT ");
919 SCLogConfig(
"RTE_ETH_RSS_L3_DST_ONLY %sset", (actual & RTE_ETH_RSS_L3_DST_ONLY) ?
"" :
"NOT ");
920 SCLogConfig(
"RTE_ETH_RSS_L4_SRC_ONLY %sset", (actual & RTE_ETH_RSS_L4_SRC_ONLY) ?
"" :
"NOT ");
921 SCLogConfig(
"RTE_ETH_RSS_L4_DST_ONLY %sset", (actual & RTE_ETH_RSS_L4_DST_ONLY) ?
"" :
"NOT ");
924 static int DeviceValidateMTU(
const DPDKIfaceConfig *iconf,
const struct rte_eth_dev_info *dev_info)
926 if (iconf->mtu > dev_info->max_mtu || iconf->mtu < dev_info->min_mtu) {
928 "Min MTU: %" PRIu16
" Max MTU: %" PRIu16,
929 iconf->iface, dev_info->min_mtu, dev_info->max_mtu);
933 #if RTE_VER_YEAR < 21 || RTE_VER_YEAR == 21 && RTE_VER_MONTH < 11
935 if (iconf->mtu > RTE_ETHER_MAX_LEN &&
936 !(dev_info->rx_offload_capa & DEV_RX_OFFLOAD_JUMBO_FRAME)) {
937 SCLogError(
"%s: jumbo frames not supported, set MTU to 1500", iconf->iface);
945 static void DeviceSetMTU(
struct rte_eth_conf *port_conf, uint16_t mtu)
947 #if RTE_VER_YEAR > 21 || RTE_VER_YEAR == 21 && RTE_VER_MONTH == 11
948 port_conf->rxmode.mtu = mtu;
950 port_conf->rxmode.max_rx_pkt_len = mtu;
951 if (mtu > RTE_ETHER_MAX_LEN) {
952 port_conf->rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
958 const struct rte_eth_dev_info *dev_info,
struct rte_eth_conf *port_conf)
960 *port_conf = (
struct rte_eth_conf){
962 .mq_mode = RTE_ETH_MQ_RX_NONE,
966 .mq_mode = RTE_ETH_MQ_TX_NONE,
972 if (dev_info->rx_offload_capa & RTE_ETH_RX_OFFLOAD_RSS_HASH) {
973 if (iconf->nb_rx_queues > 1) {
974 SCLogConfig(
"%s: RSS enabled for %d queues", iconf->iface, iconf->nb_rx_queues);
975 port_conf->rx_adv_conf.rss_conf = (
struct rte_eth_rss_conf){
977 .rss_key_len = RSS_HKEY_LEN,
978 .rss_hf = iconf->rss_hf,
981 DeviceSetPMDSpecificRSS(&port_conf->rx_adv_conf.rss_conf, dev_info->driver_name);
983 uint64_t rss_hf_tmp =
984 port_conf->rx_adv_conf.rss_conf.rss_hf & dev_info->flow_type_rss_offloads;
985 if (port_conf->rx_adv_conf.rss_conf.rss_hf != rss_hf_tmp) {
986 DumpRSSFlags(port_conf->rx_adv_conf.rss_conf.rss_hf, rss_hf_tmp);
988 SCLogWarning(
"%s: modified RSS hash function based on hardware support: "
989 "requested:%#" PRIx64
", configured:%#" PRIx64,
990 iconf->iface, port_conf->rx_adv_conf.rss_conf.rss_hf, rss_hf_tmp);
991 port_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf_tmp;
993 port_conf->rxmode.mq_mode = RTE_ETH_MQ_RX_RSS;
996 port_conf->rx_adv_conf.rss_conf.rss_key = NULL;
997 port_conf->rx_adv_conf.rss_conf.rss_hf = 0;
1000 SCLogConfig(
"%s: RSS not supported", iconf->iface);
1004 SCLogConfig(
"%s: checksum validation disabled", iconf->iface);
1005 }
else if (dev_info->rx_offload_capa & RTE_ETH_RX_OFFLOAD_CHECKSUM) {
1008 SCLogConfig(
"%s: IP, TCP and UDP checksum validation offloaded", iconf->iface);
1009 port_conf->rxmode.offloads |= RTE_ETH_RX_OFFLOAD_CHECKSUM;
1012 SCLogConfig(
"%s: checksum validation enabled (but can be offloaded)", iconf->iface);
1016 DeviceSetMTU(port_conf, iconf->mtu);
1018 if (dev_info->tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) {
1019 port_conf->txmode.offloads |= RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
1023 static int DeviceConfigureQueues(
DPDKIfaceConfig *iconf,
const struct rte_eth_dev_info *dev_info,
1024 const struct rte_eth_conf *port_conf)
1030 struct rte_eth_rxconf rxq_conf;
1031 struct rte_eth_txconf txq_conf;
1033 char mempool_name[64];
1034 snprintf(mempool_name, 64,
"mempool_%.20s", iconf->iface);
1036 mtu_size = iconf->mtu + RTE_ETHER_CRC_LEN + RTE_ETHER_HDR_LEN + 4;
1037 mbuf_size = ROUNDUP(mtu_size, 1024) + RTE_PKTMBUF_HEADROOM;
1038 SCLogInfo(
"%s: creating packet mbuf pool %s of size %d, cache size %d, mbuf size %d",
1039 iconf->iface, mempool_name, iconf->mempool_size, iconf->mempool_cache_size, mbuf_size);
1041 iconf->pkt_mempool = rte_pktmbuf_pool_create(mempool_name, iconf->mempool_size,
1042 iconf->mempool_cache_size, 0, mbuf_size, (
int)iconf->socket_id);
1043 if (iconf->pkt_mempool == NULL) {
1044 retval = -rte_errno;
1045 SCLogError(
"%s: rte_pktmbuf_pool_create failed with code %d (mempool: %s) - %s",
1046 iconf->iface, rte_errno, mempool_name, rte_strerror(rte_errno));
1050 for (uint16_t queue_id = 0; queue_id < iconf->nb_rx_queues; queue_id++) {
1051 rxq_conf = dev_info->default_rxconf;
1052 rxq_conf.offloads = port_conf->rxmode.offloads;
1053 rxq_conf.rx_thresh.hthresh = 0;
1054 rxq_conf.rx_thresh.pthresh = 0;
1055 rxq_conf.rx_thresh.wthresh = 0;
1056 rxq_conf.rx_free_thresh = 0;
1057 rxq_conf.rx_drop_en = 0;
1058 SCLogPerf(
"%s: rx queue setup: queue:%d port:%d rx_desc:%d tx_desc:%d rx: htresh: %d "
1059 "pthresh %d wtresh %d free_tresh %d drop_en %d offloads %lu",
1060 iconf->iface, queue_id, iconf->port_id, iconf->nb_rx_desc, iconf->nb_tx_desc,
1061 rxq_conf.rx_thresh.hthresh, rxq_conf.rx_thresh.pthresh, rxq_conf.rx_thresh.wthresh,
1062 rxq_conf.rx_free_thresh, rxq_conf.rx_drop_en, rxq_conf.offloads);
1064 retval = rte_eth_rx_queue_setup(iconf->port_id, queue_id, iconf->nb_rx_desc,
1065 iconf->socket_id, &rxq_conf, iconf->pkt_mempool);
1067 rte_mempool_free(iconf->pkt_mempool);
1069 "%s: rte_eth_rx_queue_setup failed with code %d for device queue %u of port %u",
1070 iconf->iface, retval, queue_id, iconf->port_id);
1075 for (uint16_t queue_id = 0; queue_id < iconf->nb_tx_queues; queue_id++) {
1076 txq_conf = dev_info->default_txconf;
1077 txq_conf.offloads = port_conf->txmode.offloads;
1078 SCLogPerf(
"%s: tx queue setup: queue:%d port:%d", iconf->iface, queue_id, iconf->port_id);
1079 retval = rte_eth_tx_queue_setup(
1080 iconf->port_id, queue_id, iconf->nb_tx_desc, iconf->socket_id, &txq_conf);
1082 rte_mempool_free(iconf->pkt_mempool);
1084 "%s: rte_eth_tx_queue_setup failed with code %d for device queue %u of port %u",
1085 iconf->iface, retval, queue_id, iconf->port_id);
1098 ConfigInit(&out_iconf);
1099 if (out_iconf == NULL) {
1100 FatalError(
"Copy interface of the interface \"%s\" is NULL", iconf->iface);
1103 retval = ConfigLoad(out_iconf, iconf->out_iface);
1105 SCLogError(
"Fail to load config of interface %s", iconf->out_iface);
1106 out_iconf->DerefFunc(out_iconf);
1110 if (iconf->nb_rx_queues != out_iconf->nb_tx_queues) {
1112 SCLogError(
"%s: configured %d RX queues but copy interface %s has %d TX queues"
1113 " - number of queues must be equal",
1114 iconf->iface, iconf->nb_rx_queues, out_iconf->iface, out_iconf->nb_tx_queues);
1115 out_iconf->DerefFunc(out_iconf);
1117 }
else if (iconf->mtu != out_iconf->mtu) {
1118 SCLogError(
"%s: configured MTU of %d but copy interface %s has MTU set to %d"
1119 " - MTU must be equal",
1120 iconf->iface, iconf->mtu, out_iconf->iface, out_iconf->mtu);
1121 out_iconf->DerefFunc(out_iconf);
1123 }
else if (iconf->copy_mode != out_iconf->copy_mode) {
1124 SCLogError(
"%s: copy modes of interfaces %s and %s are not equal", iconf->iface,
1125 iconf->iface, out_iconf->iface);
1126 out_iconf->DerefFunc(out_iconf);
1128 }
else if (strcmp(iconf->iface, out_iconf->out_iface) != 0) {
1130 SCLogError(
"%s: copy interface of %s is not set to %s", iconf->iface, out_iconf->iface,
1132 out_iconf->DerefFunc(out_iconf);
1136 out_iconf->DerefFunc(out_iconf);
1145 if (iconf->out_iface != NULL) {
1146 retval = rte_eth_dev_get_port_by_name(iconf->out_iface, &iconf->out_port_id);
1148 SCLogError(
"%s: failed to obtain out iface %s port id (err=%d)", iconf->iface,
1149 iconf->out_iface, retval);
1153 if (rte_eth_dev_socket_id(iconf->port_id) != rte_eth_dev_socket_id(iconf->out_port_id)) {
1154 SCLogWarning(
"%s: out iface %s is not on the same NUMA node", iconf->iface,
1158 retval = DeviceValidateOutIfaceConfig(iconf);
1165 SCLogInfo(
"%s: DPDK IPS mode activated: %s->%s", iconf->iface, iconf->iface,
1168 SCLogInfo(
"%s: DPDK TAP mode activated: %s->%s", iconf->iface, iconf->iface,
1179 struct rte_eth_dev_info dev_info;
1180 struct rte_eth_conf port_conf;
1182 retval = rte_eth_dev_get_port_by_name(iconf->iface, &(iconf->port_id));
1184 SCLogError(
"%s: getting port id failed (err=%d). Is device enabled?", iconf->iface, retval);
1188 if (!rte_eth_dev_is_valid_port(iconf->port_id)) {
1189 SCLogError(
"%s: specified port %d is invalid", iconf->iface, iconf->port_id);
1193 retval = rte_eth_dev_socket_id(iconf->port_id);
1195 SCLogError(
"%s: invalid socket id (err=%d)", iconf->iface, retval);
1198 iconf->socket_id = retval;
1200 retval = rte_eth_dev_info_get(iconf->port_id, &dev_info);
1202 SCLogError(
"%s: getting device info failed (err=%d)", iconf->iface, retval);
1206 if (iconf->nb_rx_queues > dev_info.max_rx_queues) {
1207 SCLogError(
"%s: configured RX queues %u is higher than device maximum (%" PRIu16
")",
1208 iconf->iface, iconf->nb_rx_queues, dev_info.max_rx_queues);
1212 if (iconf->nb_tx_queues > dev_info.max_tx_queues) {
1213 SCLogError(
"%s: configured TX queues %u is higher than device maximum (%" PRIu16
")",
1214 iconf->iface, iconf->nb_tx_queues, dev_info.max_tx_queues);
1218 retval = DeviceValidateMTU(iconf, &dev_info);
1222 DeviceInitPortConf(iconf, &dev_info, &port_conf);
1223 if (port_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_CHECKSUM) {
1228 retval = rte_eth_dev_configure(
1229 iconf->port_id, iconf->nb_rx_queues, iconf->nb_tx_queues, &port_conf);
1231 SCLogError(
"%s: failed to configure the device (port %u, err %d)", iconf->iface,
1232 iconf->port_id, retval);
1236 retval = rte_eth_dev_adjust_nb_rx_tx_desc(
1237 iconf->port_id, &iconf->nb_rx_desc, &iconf->nb_tx_desc);
1239 SCLogError(
"%s: failed to adjust device queue descriptors (port %u, err %d)", iconf->iface,
1240 iconf->port_id, retval);
1244 retval = iconf->flags &
DPDK_MULTICAST ? rte_eth_allmulticast_enable(iconf->port_id)
1245 : rte_eth_allmulticast_disable(iconf->port_id);
1246 if (retval == -ENOTSUP) {
1247 retval = rte_eth_allmulticast_get(iconf->port_id);
1251 SCLogError(
"%s: Allmulticast setting of port (%" PRIu16
1252 ") can not be configured. Set it to %s",
1253 iconf->iface, iconf->port_id, retval == 1 ?
"true" :
"false");
1254 }
else if (retval < 0) {
1255 SCLogError(
"%s: failed to get multicast mode (port %u, err %d)", iconf->iface,
1256 iconf->port_id, retval);
1259 }
else if (retval < 0) {
1260 SCLogError(
"%s: error when changing multicast setting (port %u err %d)", iconf->iface,
1261 iconf->port_id, retval);
1265 retval = iconf->flags &
DPDK_PROMISC ? rte_eth_promiscuous_enable(iconf->port_id)
1266 : rte_eth_promiscuous_disable(iconf->port_id);
1267 if (retval == -ENOTSUP) {
1268 retval = rte_eth_promiscuous_get(iconf->port_id);
1271 SCLogError(
"%s: promiscuous setting of port (%" PRIu16
1272 ") can not be configured. Set it to %s",
1273 iconf->iface, iconf->port_id, retval == 1 ?
"true" :
"false");
1275 }
else if (retval < 0) {
1276 SCLogError(
"%s: failed to get promiscuous mode (port %u, err=%d)", iconf->iface,
1277 iconf->port_id, retval);
1280 }
else if (retval < 0) {
1281 SCLogError(
"%s: error when changing promiscuous setting (port %u, err %d)", iconf->iface,
1282 iconf->port_id, retval);
1287 SCLogConfig(
"%s: setting MTU to %d", iconf->iface, iconf->mtu);
1288 retval = rte_eth_dev_set_mtu(iconf->port_id, iconf->mtu);
1289 if (retval == -ENOTSUP) {
1290 SCLogWarning(
"%s: changing MTU on port %u is not supported, ignoring the setting",
1291 iconf->iface, iconf->port_id);
1293 retval = rte_eth_dev_get_mtu(iconf->port_id, &iconf->mtu);
1295 SCLogError(
"%s: failed to retrieve MTU (port %u, err %d)", iconf->iface, iconf->port_id,
1299 }
else if (retval < 0) {
1300 SCLogError(
"%s: failed to set MTU to %u (port %u, err %d)", iconf->iface, iconf->mtu,
1301 iconf->port_id, retval);
1305 retval = DeviceConfigureQueues(iconf, &dev_info, &port_conf);
1310 retval = DeviceConfigureIPS(iconf);
1318 static void *ParseDpdkConfigAndConfigureDevice(
const char *iface)
1322 if (iconf == NULL) {
1323 FatalError(
"DPDK configuration could not be parsed");
1326 if (DeviceConfigure(iconf) != 0) {
1327 iconf->DerefFunc(iconf);
1328 retval = rte_eal_cleanup();
1330 FatalError(
"EAL cleanup failed: %s", strerror(-retval));
1332 FatalError(
"%s: failed to configure", iface);
1356 static int DPDKConfigGetThreadsCount(
void *conf)
1362 return dpdk_conf->threads;
1367 static int DPDKRunModeIsIPS(
void)
1370 const char dpdk_node_query[] =
"dpdk.interfaces";
1372 if (dpdk_node == NULL) {
1373 FatalError(
"Unable to get %s configuration node", dpdk_node_query);
1376 const char default_iface[] =
"default";
1379 bool has_ips =
false;
1380 bool has_ids =
false;
1381 for (
int ldev = 0; ldev < nlive; ldev++) {
1383 if (live_dev == NULL)
1384 FatalError(
"Unable to get device id %d from LiveDevice list", ldev);
1387 if (if_root == NULL) {
1388 if (if_default == NULL)
1389 FatalError(
"Unable to get %s or %s interface", live_dev, default_iface);
1391 if_root = if_default;
1394 const char *copymodestr = NULL;
1396 if (strcmp(copymodestr,
"ips") == 0) {
1405 if (has_ids && has_ips) {
1406 FatalError(
"Copy-mode of interface %s mixes with the previously set copy-modes "
1407 "(only IDS/TAP and IPS copy-mode combinations are allowed in DPDK",
1415 static void DPDKRunModeEnableIPS(
void)
1417 if (DPDKRunModeIsIPS()) {
1431 "Workers DPDK mode, each thread does all"
1432 " tasks from acquisition to logging",
1458 SCLogDebug(
"RunModeIdsDpdkWorkers initialised");