57 #define ROUNDUP(x, y) ((((x) + ((y)-1)) / (y)) * (y))
68 static char *AllocArgument(
size_t arg_len);
69 static char *AllocAndSetArgument(
const char *arg);
70 static char *AllocAndSetOption(
const char *arg);
72 static void ArgumentsInit(
struct Arguments *args, uint16_t capacity);
73 static void ArgumentsCleanup(
struct Arguments *args);
74 static void ArgumentsAdd(
struct Arguments *args,
char *value);
75 static void ArgumentsAddOptionAndArgument(
struct Arguments *args,
const char *opt,
const char *arg);
76 static void InitEal(
void);
78 static void ConfigSetIface(
DPDKIfaceConfig *iconf,
const char *entry_str);
79 static int ConfigSetThreads(
DPDKIfaceConfig *iconf,
const char *entry_str);
80 static int ConfigSetRxQueues(
DPDKIfaceConfig *iconf, uint16_t nb_queues, uint16_t max_queues);
81 static int ConfigSetTxQueues(
82 DPDKIfaceConfig *iconf, uint16_t nb_queues, uint16_t max_queues,
bool iface_sends_pkts);
83 static int ConfigSetMempoolSize(
84 DPDKIfaceConfig *iconf,
const char *entry_str,
const struct rte_eth_dev_info *dev_info);
85 static int ConfigSetMempoolCacheSize(
DPDKIfaceConfig *iconf,
const char *entry_str);
86 static int ConfigSetRxDescriptors(
DPDKIfaceConfig *iconf,
const char *entry_str, uint16_t max_desc);
87 static int ConfigSetTxDescriptors(
88 DPDKIfaceConfig *iconf,
const char *entry_str, uint16_t max_desc,
bool iface_sends_pkts);
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_INTERRUPT_MODE false
113 #define DPDK_CONFIG_DEFAULT_MEMPOOL_SIZE "auto"
114 #define DPDK_CONFIG_DEFAULT_MEMPOOL_CACHE_SIZE "auto"
115 #define DPDK_CONFIG_DEFAULT_RX_DESCRIPTORS "auto"
116 #define DPDK_CONFIG_DEFAULT_TX_DESCRIPTORS "auto"
117 #define DPDK_CONFIG_DEFAULT_RSS_HASH_FUNCTIONS RTE_ETH_RSS_IP
118 #define DPDK_CONFIG_DEFAULT_MTU 1500
119 #define DPDK_CONFIG_DEFAULT_PROMISCUOUS_MODE 1
120 #define DPDK_CONFIG_DEFAULT_MULTICAST_MODE 1
121 #define DPDK_CONFIG_DEFAULT_CHECKSUM_VALIDATION 1
122 #define DPDK_CONFIG_DEFAULT_CHECKSUM_VALIDATION_OFFLOAD 1
123 #define DPDK_CONFIG_DEFAULT_VLAN_STRIP 0
124 #define DPDK_CONFIG_DEFAULT_LINKUP_TIMEOUT 0
125 #define DPDK_CONFIG_DEFAULT_COPY_MODE "none"
126 #define DPDK_CONFIG_DEFAULT_COPY_INTERFACE "none"
130 .irq_mode =
"interrupt-mode",
131 .promisc =
"promisc",
132 .multicast =
"multicast",
133 .checksum_checks =
"checksum-checks",
134 .checksum_checks_offload =
"checksum-checks-offload",
136 .vlan_strip_offload =
"vlan-strip-offload",
137 .rss_hf =
"rss-hash-functions",
138 .linkup_timeout =
"linkup-timeout",
139 .mempool_size =
"mempool-size",
140 .mempool_cache_size =
"mempool-cache-size",
141 .rx_descriptors =
"rx-descriptors",
142 .tx_descriptors =
"tx-descriptors",
143 .copy_mode =
"copy-mode",
144 .copy_iface =
"copy-iface",
151 static uint32_t GreatestDivisorUpTo(uint32_t num, uint32_t max_num)
153 for (uint32_t i = max_num; i >= 2; i--) {
165 static uint64_t GreatestPowOf2UpTo(uint64_t num)
178 num = num - (num >> 1);
183 static char *AllocArgument(
size_t arg_len)
189 ptr = (
char *)
SCCalloc(arg_len,
sizeof(
char));
191 FatalError(
"Could not allocate memory for an argument");
201 static char *AllocAndSetArgument(
const char *arg)
205 FatalError(
"Passed argument is NULL in DPDK config initialization");
208 size_t arg_len = strlen(arg);
210 ptr = AllocArgument(arg_len);
211 strlcpy(ptr, arg, arg_len + 1);
215 static char *AllocAndSetOption(
const char *arg)
219 FatalError(
"Passed option is NULL in DPDK config initialization");
222 size_t arg_len = strlen(arg);
223 uint8_t is_long_arg = arg_len > 1;
224 const char *dash_prefix = is_long_arg ?
"--" :
"-";
225 size_t full_len = arg_len + strlen(dash_prefix);
227 ptr = AllocArgument(full_len);
228 strlcpy(ptr, dash_prefix, full_len);
229 strlcat(ptr, arg, full_len + 1);
233 static void ArgumentsInit(
struct Arguments *args, uint16_t capacity)
236 args->argv =
SCCalloc(capacity,
sizeof(*args->argv));
237 if (args->argv == NULL)
238 FatalError(
"Could not allocate memory for Arguments structure");
240 args->capacity = capacity;
245 static void ArgumentsCleanup(
struct Arguments *args)
248 for (
int i = 0; i < args->argc; i++) {
249 if (args->argv[i] != NULL) {
251 args->argv[i] = NULL;
261 static void ArgumentsAdd(
struct Arguments *args,
char *value)
264 if (args->argc + 1 > args->capacity)
265 FatalError(
"No capacity for more arguments (Max: %" PRIu32
")", EAL_ARGS);
267 args->argv[args->argc++] = value;
271 static void ArgumentsAddOptionAndArgument(
struct Arguments *args,
const char *opt,
const char *arg)
277 option = AllocAndSetOption(opt);
278 ArgumentsAdd(args, option);
281 if (arg == NULL || arg[0] ==
'\0')
284 argument = AllocAndSetArgument(arg);
285 ArgumentsAdd(args, argument);
289 static void InitEal(
void)
295 struct Arguments args;
298 if (eal_params == NULL) {
299 FatalError(
"DPDK EAL parameters not found in the config");
302 ArgumentsInit(&args, EAL_ARGS);
303 ArgumentsAdd(&args, AllocAndSetArgument(
"suricata"));
307 const char *key = param->
name;
310 ArgumentsAddOptionAndArgument(&args, key, (
const char *)val->
val);
314 ArgumentsAddOptionAndArgument(&args, param->
name, param->
val);
318 eal_argv =
SCCalloc(args.argc,
sizeof(*args.argv));
319 if (eal_argv == NULL) {
320 FatalError(
"Failed to allocate memory for the array of DPDK EAL arguments");
322 memcpy(eal_argv, args.argv, args.argc *
sizeof(*args.argv));
324 rte_log_set_global_level(RTE_LOG_WARNING);
325 retval = rte_eal_init(args.argc, eal_argv);
327 ArgumentsCleanup(&args);
331 FatalError(
"DPDK EAL initialization error: %s", rte_strerror(-retval));
335 static void DPDKDerefConfig(
void *conf)
341 DPDKDeviceResourcesDeinit(&iconf->pkt_mempools);
353 FatalError(
"Could not allocate memory for DPDKIfaceConfig");
355 ptr->out_port_id = UINT16_MAX;
358 ptr->DerefFunc = DPDKDerefConfig;
365 static void ConfigSetIface(
DPDKIfaceConfig *iconf,
const char *entry_str)
370 if (entry_str == NULL || entry_str[0] ==
'\0')
371 FatalError(
"Interface name in DPDK config is NULL or empty");
373 retval = rte_eth_dev_get_port_by_name(entry_str, &iconf->port_id);
375 FatalError(
"%s: interface not found: %s", entry_str, rte_strerror(-retval));
377 strlcpy(iconf->iface, entry_str,
sizeof(iconf->iface));
381 static int ConfigSetThreads(
DPDKIfaceConfig *iconf,
const char *entry_str)
384 static uint16_t remaining_auto_cpus = UINT16_MAX;
386 SCLogError(
"DPDK runmode requires configured thread affinity");
390 bool wtaf_periface =
true;
393 wtaf_periface =
false;
396 SCLogError(
"Specify worker-cpu-set list in the threading section");
402 SCLogError(
"Specify management-cpu-set list in the threading section");
408 "\"all\" specified in worker CPU cores affinity, excluding management threads");
409 UtilAffinityCpusExclude(wtaf, mtaf);
413 if (sched_cpus == 0) {
414 SCLogError(
"No worker CPU cores with configured affinity were configured");
416 }
else if (UtilAffinityCpusOverlap(wtaf, mtaf) != 0) {
417 SCLogWarning(
"Worker threads should not overlap with management threads in the CPU core "
418 "affinity configuration");
422 if (active_runmode && !strcmp(
"single", active_runmode)) {
427 if (entry_str == NULL) {
428 SCLogError(
"Number of threads for interface \"%s\" not specified", iconf->iface);
432 if (strcmp(entry_str,
"auto") == 0) {
434 iconf->threads = (uint16_t)sched_cpus;
435 SCLogConfig(
"%s: auto-assigned %u threads", iconf->iface, iconf->threads);
440 if (live_dev_count == 0) {
441 SCLogError(
"No live devices found, cannot auto-assign threads");
444 iconf->threads = sched_cpus / live_dev_count;
445 if (iconf->threads == 0) {
446 SCLogError(
"Not enough worker CPU cores with affinity were configured");
450 if (remaining_auto_cpus == UINT16_MAX) {
452 remaining_auto_cpus = sched_cpus % live_dev_count;
453 if (remaining_auto_cpus > 0) {
455 remaining_auto_cpus--;
457 }
else if (remaining_auto_cpus > 0) {
459 remaining_auto_cpus--;
461 SCLogConfig(
"%s: auto-assigned %u threads", iconf->iface, iconf->threads);
466 SCLogError(
"Threads entry for interface %s contain non-numerical characters - \"%s\"",
467 iconf->iface, entry_str);
471 if (iconf->threads <= 0) {
472 SCLogError(
"%s: positive number of threads required", iconf->iface);
479 static bool ConfigSetInterruptMode(
DPDKIfaceConfig *iconf,
bool enable)
488 static int ConfigSetRxQueues(
DPDKIfaceConfig *iconf, uint16_t nb_queues, uint16_t max_queues)
491 if (nb_queues == 0) {
492 SCLogInfo(
"%s: positive number of RX queues is required", iconf->iface);
496 if (nb_queues > max_queues) {
497 SCLogInfo(
"%s: number of RX queues cannot exceed %" PRIu16, iconf->iface, max_queues);
501 iconf->nb_rx_queues = nb_queues;
505 static bool ConfigIfaceSendsPkts(
const char *mode)
508 if (strcmp(mode,
"ips") == 0 || strcmp(mode,
"tap") == 0) {
514 static int ConfigSetTxQueues(
515 DPDKIfaceConfig *iconf, uint16_t nb_queues, uint16_t max_queues,
bool iface_sends_pkts)
518 if (nb_queues == 0 && iface_sends_pkts) {
519 SCLogInfo(
"%s: positive number of TX queues is required", iconf->iface);
523 if (nb_queues > max_queues) {
524 SCLogInfo(
"%s: number of TX queues cannot exceed %" PRIu16, iconf->iface, max_queues);
528 iconf->nb_tx_queues = nb_queues;
532 static uint32_t MempoolSizeCalculateAutosize(
536 rte_align32pow2(iconf->nb_rx_desc + iconf->nb_tx_desc +
539 uint32_t mp_size = next_p2;
540 if (dev_info != NULL) {
541 if (strcmp(dev_info->driver_name,
"net_bonding") == 0) {
542 mp_size = BondingMempoolSizeCalculate(iconf->port_id, dev_info, mp_size);
550 static uint32_t MempoolSizeDistributeToQueues(uint32_t global_mp_size, uint16_t nic_queues)
552 if (nic_queues == 0) {
556 uint32_t mp_size_per_queue = global_mp_size / nic_queues;
557 if (mp_size_per_queue == 0) {
561 uint32_t next_p2 = rte_align32pow2(mp_size_per_queue);
562 return (mp_size_per_queue == next_p2 || mp_size_per_queue == next_p2 - 1)
564 : (next_p2 >> 1) - 1;
567 static uint32_t MempoolSizeCalculateMinimal(
571 rte_align32pow2(iconf->nb_rx_desc + iconf->nb_tx_desc +
573 if (dev_info != NULL) {
574 if (strcmp(dev_info->driver_name,
"net_bonding") == 0) {
575 mp_size = BondingMempoolSizeCalculate(iconf->port_id, dev_info, mp_size);
581 static int ConfigSetMempoolSize(
582 DPDKIfaceConfig *iconf,
const char *entry_str,
const struct rte_eth_dev_info *dev_info)
585 if (entry_str == NULL || entry_str[0] ==
'\0' || strcmp(entry_str,
"auto") == 0) {
590 if (iconf->nb_rx_queues == 0) {
592 SCLogError(
"%s: cannot autocalculate mempool size without RX queues", iconf->iface);
596 if (iconf->nb_rx_desc == 0) {
598 "%s: cannot autocalculate mempool size without RX descriptors", iconf->iface);
606 iconf->queue_mempool_size = MempoolSizeCalculateAutosize(iconf, dev_info);
610 uint32_t global_mempool_size;
612 SCLogError(
"%s: mempool size entry contain non-numerical characters - \"%s\"", iconf->iface,
617 iconf->queue_mempool_size =
618 MempoolSizeDistributeToQueues(global_mempool_size, iconf->nb_rx_queues);
619 uint32_t required_mp_size = MempoolSizeCalculateMinimal(iconf, dev_info);
620 if (required_mp_size > iconf->queue_mempool_size) {
621 uint32_t required_global_mp_size =
622 required_mp_size * iconf->nb_rx_queues + iconf->nb_rx_queues - 1;
623 SCLogError(
"%s: mempool size is likely too small for the number of descriptors and queues, "
624 "set to \"auto\" or adjust to the value of \"%" PRIu32
"\"",
625 iconf->iface, required_global_mp_size);
629 if (iconf->queue_mempool_size == 0) {
630 SCLogError(
"%s: mempool size requires a positive integer", iconf->iface);
637 static uint32_t MempoolCacheSizeCalculate(uint32_t mp_sz)
642 uint32_t max_cache_size =
MIN(RTE_MEMPOOL_CACHE_MAX_SIZE, (uint32_t)(mp_sz / 1.5));
643 return GreatestDivisorUpTo(mp_sz, max_cache_size);
646 static int ConfigSetMempoolCacheSize(
DPDKIfaceConfig *iconf,
const char *entry_str)
649 if (entry_str == NULL || entry_str[0] ==
'\0' || strcmp(entry_str,
"auto") == 0) {
651 if (iconf->queue_mempool_size == 0) {
652 SCLogError(
"%s: cannot calculate mempool cache size of a mempool with size %" PRIu32,
653 iconf->iface, iconf->queue_mempool_size);
657 iconf->mempool_cache_size_auto =
true;
661 iconf->mempool_cache_size_auto =
false;
663 SCLogError(
"%s: mempool cache size entry contain non-numerical characters - \"%s\"",
664 iconf->iface, entry_str);
668 if (iconf->mempool_cache_size <= 0 || iconf->mempool_cache_size > RTE_MEMPOOL_CACHE_MAX_SIZE) {
669 SCLogError(
"%s: mempool cache size requires a positive number smaller than %" PRIu32,
670 iconf->iface, RTE_MEMPOOL_CACHE_MAX_SIZE);
677 static int ConfigSetRxDescriptors(
DPDKIfaceConfig *iconf,
const char *entry_str, uint16_t max_desc)
680 if (entry_str == NULL || entry_str[0] ==
'\0') {
681 SCLogInfo(
"%s: number of RX descriptors not found, going with: %s", iconf->iface,
682 DPDK_CONFIG_DEFAULT_RX_DESCRIPTORS);
683 entry_str = DPDK_CONFIG_DEFAULT_RX_DESCRIPTORS;
686 if (strcmp(entry_str,
"auto") == 0) {
687 iconf->nb_rx_desc = (uint16_t)GreatestPowOf2UpTo(max_desc);
692 SCLogError(
"%s: RX descriptors entry contains non-numerical characters - \"%s\"",
693 iconf->iface, entry_str);
697 if (iconf->nb_rx_desc == 0) {
698 SCLogError(
"%s: positive number of RX descriptors is required", iconf->iface);
700 }
else if (iconf->nb_rx_desc > max_desc) {
701 SCLogError(
"%s: number of RX descriptors cannot exceed %" PRIu16, iconf->iface, max_desc);
708 static int ConfigSetTxDescriptors(
709 DPDKIfaceConfig *iconf,
const char *entry_str, uint16_t max_desc,
bool iface_sends_pkts)
712 if (entry_str == NULL || entry_str[0] ==
'\0') {
713 SCLogInfo(
"%s: number of TX descriptors not found, going with: %s", iconf->iface,
714 DPDK_CONFIG_DEFAULT_TX_DESCRIPTORS);
715 entry_str = DPDK_CONFIG_DEFAULT_TX_DESCRIPTORS;
718 if (strcmp(entry_str,
"auto") == 0) {
719 if (iface_sends_pkts) {
720 iconf->nb_tx_desc = (uint16_t)GreatestPowOf2UpTo(max_desc);
722 iconf->nb_tx_desc = 0;
728 SCLogError(
"%s: TX descriptors entry contains non-numerical characters - \"%s\"",
729 iconf->iface, entry_str);
733 if (iconf->nb_tx_desc == 0 && iface_sends_pkts) {
734 SCLogError(
"%s: positive number of TX descriptors is required", iconf->iface);
736 }
else if (iconf->nb_tx_desc > max_desc) {
737 SCLogError(
"%s: number of TX descriptors cannot exceed %" PRIu16, iconf->iface, max_desc);
744 static int ConfigSetRSSHashFunctions(
DPDKIfaceConfig *iconf,
const char *entry_str)
747 if (entry_str == NULL || entry_str[0] ==
'\0' || strcmp(entry_str,
"auto") == 0) {
748 iconf->rss_hf = DPDK_CONFIG_DEFAULT_RSS_HASH_FUNCTIONS;
753 SCLogError(
"%s: RSS hash functions entry contain non-numerical characters - \"%s\"",
754 iconf->iface, entry_str);
764 if (entry_int < RTE_ETHER_MIN_MTU || entry_int > RTE_ETHER_MAX_JUMBO_FRAME_LEN) {
765 SCLogError(
"%s: MTU size can only be between %" PRIu32
" and %" PRIu32, iconf->iface,
766 RTE_ETHER_MIN_MTU, RTE_ETHER_MAX_JUMBO_FRAME_LEN);
770 iconf->mtu = (uint16_t)entry_int;
774 static int ConfigSetLinkupTimeout(
DPDKIfaceConfig *iconf, intmax_t entry_int)
777 if (entry_int < 0 || entry_int > UINT16_MAX) {
778 SCLogError(
"%s: Link-up waiting timeout needs to be a positive number (up to %u) or 0 to "
780 iconf->iface, UINT16_MAX);
784 iconf->linkup_timeout = (uint16_t)entry_int;
788 static bool ConfigSetPromiscuousMode(
DPDKIfaceConfig *iconf,
int entry_bool)
806 static int ConfigSetChecksumChecks(
DPDKIfaceConfig *iconf,
int entry_bool)
815 static int ConfigSetChecksumOffload(
DPDKIfaceConfig *iconf,
int entry_bool)
827 iconf->vlan_strip_enabled = entry_bool;
831 static int ConfigSetCopyIface(
DPDKIfaceConfig *iconf,
const char *entry_str)
836 if (entry_str == NULL || entry_str[0] ==
'\0' || strcmp(entry_str,
"none") == 0) {
837 iconf->out_iface = NULL;
841 retval = rte_eth_dev_get_port_by_name(entry_str, &iconf->out_port_id);
843 SCLogError(
"%s: copy interface (%s) not found: %s", iconf->iface, entry_str,
844 rte_strerror(-retval));
848 iconf->out_iface = entry_str;
852 static int ConfigSetCopyMode(
DPDKIfaceConfig *iconf,
const char *entry_str)
855 if (entry_str == NULL) {
856 SCLogWarning(
"%s: no copy mode specified, changing to %s ", iconf->iface,
857 DPDK_CONFIG_DEFAULT_COPY_MODE);
858 entry_str = DPDK_CONFIG_DEFAULT_COPY_MODE;
861 if (strcmp(entry_str,
"none") != 0 && strcmp(entry_str,
"tap") != 0 &&
862 strcmp(entry_str,
"ips") != 0) {
863 SCLogWarning(
"%s: copy mode \"%s\" is not one of the possible values (none|tap|ips). "
865 entry_str, iconf->iface, DPDK_CONFIG_DEFAULT_COPY_MODE);
866 entry_str = DPDK_CONFIG_DEFAULT_COPY_MODE;
869 if (strcmp(entry_str,
"none") == 0) {
871 }
else if (strcmp(entry_str,
"tap") == 0) {
873 }
else if (strcmp(entry_str,
"ips") == 0) {
880 static int ConfigSetCopyIfaceSettings(
DPDKIfaceConfig *iconf,
const char *iface,
const char *mode)
885 retval = ConfigSetCopyIface(iconf, iface);
889 retval = ConfigSetCopyMode(iconf, mode);
894 if (iconf->out_iface != NULL)
895 iconf->out_iface = NULL;
899 if (iconf->out_iface == NULL || strlen(iconf->out_iface) <= 0) {
900 SCLogError(
"%s: copy mode enabled but interface not set", iconf->iface);
913 const char *entry_str = NULL;
914 intmax_t entry_int = 0;
916 const char *copy_iface_str = NULL;
917 const char *copy_mode_str = NULL;
919 ConfigSetIface(iconf, iface);
920 struct rte_eth_dev_info dev_info = { 0 };
921 retval = rte_eth_dev_info_get(iconf->port_id, &dev_info);
923 SCLogError(
"%s: getting device info failed: %s", iconf->iface, rte_strerror(-retval));
929 FatalError(
"failed to find DPDK configuration for the interface %s", iconf->iface);
933 ? ConfigSetThreads(iconf, DPDK_CONFIG_DEFAULT_THREADS)
934 : ConfigSetThreads(iconf, entry_str);
940 if_root, if_default, dpdk_yaml.
irq_mode, &entry_bool);
942 irq_enable = DPDK_CONFIG_DEFAULT_INTERRUPT_MODE;
944 irq_enable = entry_bool;
946 retval = ConfigSetInterruptMode(iconf, irq_enable);
951 if_root, if_default, dpdk_yaml.
copy_mode, ©_mode_str);
953 copy_mode_str = DPDK_CONFIG_DEFAULT_COPY_MODE;
958 ? ConfigSetRxDescriptors(iconf, DPDK_CONFIG_DEFAULT_RX_DESCRIPTORS,
959 dev_info.rx_desc_lim.nb_max)
960 : ConfigSetRxDescriptors(iconf, entry_str, dev_info.rx_desc_lim.nb_max);
964 bool iface_sends_pkts = ConfigIfaceSendsPkts(copy_mode_str);
967 ? ConfigSetTxDescriptors(iconf, DPDK_CONFIG_DEFAULT_TX_DESCRIPTORS,
968 dev_info.tx_desc_lim.nb_max, iface_sends_pkts)
969 : ConfigSetTxDescriptors(
970 iconf, entry_str, dev_info.tx_desc_lim.nb_max, iface_sends_pkts);
975 retval = ConfigSetRxQueues(iconf, iconf->threads, dev_info.max_rx_queues);
977 SCLogError(
"%s: too many threads configured - reduce thread count to: %" PRIu16,
978 iconf->iface, dev_info.max_rx_queues);
983 uint16_t tx_queues = iconf->nb_tx_desc > 0 ? iconf->threads : 0;
984 retval = ConfigSetTxQueues(iconf, tx_queues, dev_info.max_tx_queues, iface_sends_pkts);
986 SCLogError(
"%s: too many threads configured - reduce thread count to: %" PRIu16,
987 iconf->iface, dev_info.max_tx_queues);
992 if_root, if_default, dpdk_yaml.
mempool_size, &entry_str) != 1
993 ? ConfigSetMempoolSize(iconf, DPDK_CONFIG_DEFAULT_MEMPOOL_SIZE, &dev_info)
994 : ConfigSetMempoolSize(iconf, entry_str, &dev_info);
1000 ? ConfigSetMempoolCacheSize(iconf, DPDK_CONFIG_DEFAULT_MEMPOOL_CACHE_SIZE)
1001 : ConfigSetMempoolCacheSize(iconf, entry_str);
1006 ? ConfigSetMtu(iconf, DPDK_CONFIG_DEFAULT_MTU)
1007 : ConfigSetMtu(iconf, entry_int);
1012 ? ConfigSetRSSHashFunctions(iconf, NULL)
1013 : ConfigSetRSSHashFunctions(iconf, entry_str);
1018 if_root, if_default, dpdk_yaml.
promisc, &entry_bool) != 1
1019 ? ConfigSetPromiscuousMode(iconf, DPDK_CONFIG_DEFAULT_PROMISCUOUS_MODE)
1020 : ConfigSetPromiscuousMode(iconf, entry_bool);
1025 if_root, if_default, dpdk_yaml.
multicast, &entry_bool) != 1
1026 ? ConfigSetMulticast(iconf, DPDK_CONFIG_DEFAULT_MULTICAST_MODE)
1027 : ConfigSetMulticast(iconf, entry_bool);
1033 ? ConfigSetChecksumChecks(iconf, DPDK_CONFIG_DEFAULT_CHECKSUM_VALIDATION)
1034 : ConfigSetChecksumChecks(iconf, entry_bool);
1040 ? ConfigSetChecksumOffload(
1041 iconf, DPDK_CONFIG_DEFAULT_CHECKSUM_VALIDATION_OFFLOAD)
1042 : ConfigSetChecksumOffload(iconf, entry_bool);
1049 ConfigSetVlanStrip(iconf, DPDK_CONFIG_DEFAULT_VLAN_STRIP);
1051 ConfigSetVlanStrip(iconf, entry_bool);
1056 ? ConfigSetLinkupTimeout(iconf, DPDK_CONFIG_DEFAULT_LINKUP_TIMEOUT)
1057 : ConfigSetLinkupTimeout(iconf, entry_int);
1062 if_root, if_default, dpdk_yaml.
copy_iface, ©_iface_str);
1064 copy_iface_str = DPDK_CONFIG_DEFAULT_COPY_INTERFACE;
1067 retval = ConfigSetCopyIfaceSettings(iconf, copy_iface_str, copy_mode_str);
1074 static bool ConfigThreadsGenericIsValid(uint16_t iface_threads,
ThreadsAffinityType *wtaf)
1076 static uint32_t total_cpus = 0;
1077 total_cpus += iface_threads;
1079 SCLogError(
"Specify worker-cpu-set list in the threading section");
1083 SCLogError(
"Interfaces requested more cores than configured in the worker-cpu-set "
1084 "threading section (requested %d configured %d",
1092 static bool ConfigThreadsInterfaceIsValid(uint16_t iface_threads,
ThreadsAffinityType *itaf)
1095 SCLogError(
"Interface requested more cores than configured in the interface-specific "
1096 "threading section (requested %d configured %d",
1104 static bool ConfigIsThreadingValid(uint16_t iface_threads,
const char *iface)
1108 if (itaf && !ConfigThreadsInterfaceIsValid(iface_threads, itaf)) {
1110 }
else if (itaf == NULL && !ConfigThreadsGenericIsValid(iface_threads, wtaf)) {
1125 retval = ConfigLoad(iconf, iface);
1126 if (retval < 0 || !ConfigIsThreadingValid(iconf->threads, iface)) {
1127 iconf->DerefFunc(iconf);
1134 static void DeviceSetPMDSpecificRSS(
struct rte_eth_rss_conf *rss_conf,
const char *driver_name)
1136 if (strcmp(driver_name,
"net_i40e") == 0)
1137 i40eDeviceSetRSSConf(rss_conf);
1138 if (strcmp(driver_name,
"net_ice") == 0)
1139 iceDeviceSetRSSConf(rss_conf);
1140 if (strcmp(driver_name,
"net_ixgbe") == 0)
1141 ixgbeDeviceSetRSSHashFunction(&rss_conf->rss_hf);
1142 if (strcmp(driver_name,
"net_e1000_igb") == 0)
1143 rss_conf->rss_hf = (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_IPV6_EX);
1147 static int32_t GetFirstSetBitPosition(uint64_t bits)
1149 for (int32_t i = 0; i < 64; i++) {
1156 static void DumpRSSFlags(
const uint64_t requested,
const uint64_t actual)
1161 "RTE_ETH_RSS_IP %sset", ((requested & RTE_ETH_RSS_IP) == RTE_ETH_RSS_IP) ?
"" :
"NOT ");
1163 ((requested & RTE_ETH_RSS_TCP) == RTE_ETH_RSS_TCP) ?
"" :
"NOT ");
1165 ((requested & RTE_ETH_RSS_UDP) == RTE_ETH_RSS_UDP) ?
"" :
"NOT ");
1167 ((requested & RTE_ETH_RSS_SCTP) == RTE_ETH_RSS_SCTP) ?
"" :
"NOT ");
1169 ((requested & RTE_ETH_RSS_TUNNEL) == RTE_ETH_RSS_TUNNEL) ?
"" :
"NOT ");
1172 SCLogConfig(
"RTE_ETH_RSS_IPV4 (Bit position: %d) %sset",
1173 GetFirstSetBitPosition(RTE_ETH_RSS_IPV4), (requested & RTE_ETH_RSS_IPV4) ?
"" :
"NOT ");
1174 SCLogConfig(
"RTE_ETH_RSS_FRAG_IPV4 (Bit position: %d) %sset",
1175 GetFirstSetBitPosition(RTE_ETH_RSS_FRAG_IPV4),
1176 (requested & RTE_ETH_RSS_FRAG_IPV4) ?
"" :
"NOT ");
1177 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_TCP (Bit position: %d) %sset",
1178 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV4_TCP),
1179 (requested & RTE_ETH_RSS_NONFRAG_IPV4_TCP) ?
"" :
"NOT ");
1180 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_UDP (Bit position: %d) %sset",
1181 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV4_UDP),
1182 (requested & RTE_ETH_RSS_NONFRAG_IPV4_UDP) ?
"" :
"NOT ");
1183 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_SCTP (Bit position: %d) %sset",
1184 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV4_SCTP),
1185 (requested & RTE_ETH_RSS_NONFRAG_IPV4_SCTP) ?
"" :
"NOT ");
1186 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_OTHER (Bit position: %d) %sset",
1187 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV4_OTHER),
1188 (requested & RTE_ETH_RSS_NONFRAG_IPV4_OTHER) ?
"" :
"NOT ");
1189 SCLogConfig(
"RTE_ETH_RSS_IPV6 (Bit position: %d) %sset",
1190 GetFirstSetBitPosition(RTE_ETH_RSS_IPV6), (requested & RTE_ETH_RSS_IPV6) ?
"" :
"NOT ");
1191 SCLogConfig(
"RTE_ETH_RSS_FRAG_IPV6 (Bit position: %d) %sset",
1192 GetFirstSetBitPosition(RTE_ETH_RSS_FRAG_IPV6),
1193 (requested & RTE_ETH_RSS_FRAG_IPV6) ?
"" :
"NOT ");
1194 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_TCP (Bit position: %d) %sset",
1195 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV6_TCP),
1196 (requested & RTE_ETH_RSS_NONFRAG_IPV6_TCP) ?
"" :
"NOT ");
1197 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_UDP (Bit position: %d) %sset",
1198 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV6_UDP),
1199 (requested & RTE_ETH_RSS_NONFRAG_IPV6_UDP) ?
"" :
"NOT ");
1200 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_SCTP (Bit position: %d) %sset",
1201 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV6_SCTP),
1202 (requested & RTE_ETH_RSS_NONFRAG_IPV6_SCTP) ?
"" :
"NOT ");
1203 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_OTHER (Bit position: %d) %sset",
1204 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV6_OTHER),
1205 (requested & RTE_ETH_RSS_NONFRAG_IPV6_OTHER) ?
"" :
"NOT ");
1207 SCLogConfig(
"RTE_ETH_RSS_L2_PAYLOAD (Bit position: %d) %sset",
1208 GetFirstSetBitPosition(RTE_ETH_RSS_L2_PAYLOAD),
1209 (requested & RTE_ETH_RSS_L2_PAYLOAD) ?
"" :
"NOT ");
1210 SCLogConfig(
"RTE_ETH_RSS_IPV6_EX (Bit position: %d) %sset",
1211 GetFirstSetBitPosition(RTE_ETH_RSS_IPV6_EX),
1212 (requested & RTE_ETH_RSS_IPV6_EX) ?
"" :
"NOT ");
1213 SCLogConfig(
"RTE_ETH_RSS_IPV6_TCP_EX (Bit position: %d) %sset",
1214 GetFirstSetBitPosition(RTE_ETH_RSS_IPV6_TCP_EX),
1215 (requested & RTE_ETH_RSS_IPV6_TCP_EX) ?
"" :
"NOT ");
1216 SCLogConfig(
"RTE_ETH_RSS_IPV6_UDP_EX (Bit position: %d) %sset",
1217 GetFirstSetBitPosition(RTE_ETH_RSS_IPV6_UDP_EX),
1218 (requested & RTE_ETH_RSS_IPV6_UDP_EX) ?
"" :
"NOT ");
1220 SCLogConfig(
"RTE_ETH_RSS_PORT (Bit position: %d) %sset",
1221 GetFirstSetBitPosition(RTE_ETH_RSS_PORT), (requested & RTE_ETH_RSS_PORT) ?
"" :
"NOT ");
1222 SCLogConfig(
"RTE_ETH_RSS_VXLAN (Bit position: %d) %sset",
1223 GetFirstSetBitPosition(RTE_ETH_RSS_VXLAN),
1224 (requested & RTE_ETH_RSS_VXLAN) ?
"" :
"NOT ");
1225 SCLogConfig(
"RTE_ETH_RSS_NVGRE (Bit position: %d) %sset",
1226 GetFirstSetBitPosition(RTE_ETH_RSS_NVGRE),
1227 (requested & RTE_ETH_RSS_NVGRE) ?
"" :
"NOT ");
1228 SCLogConfig(
"RTE_ETH_RSS_GTPU (Bit position: %d) %sset",
1229 GetFirstSetBitPosition(RTE_ETH_RSS_GTPU), (requested & RTE_ETH_RSS_GTPU) ?
"" :
"NOT ");
1231 SCLogConfig(
"RTE_ETH_RSS_L3_SRC_ONLY (Bit position: %d) %sset",
1232 GetFirstSetBitPosition(RTE_ETH_RSS_L3_SRC_ONLY),
1233 (requested & RTE_ETH_RSS_L3_SRC_ONLY) ?
"" :
"NOT ");
1234 SCLogConfig(
"RTE_ETH_RSS_L3_DST_ONLY (Bit position: %d) %sset",
1235 GetFirstSetBitPosition(RTE_ETH_RSS_L3_DST_ONLY),
1236 (requested & RTE_ETH_RSS_L3_DST_ONLY) ?
"" :
"NOT ");
1237 SCLogConfig(
"RTE_ETH_RSS_L4_SRC_ONLY (Bit position: %d) %sset",
1238 GetFirstSetBitPosition(RTE_ETH_RSS_L4_SRC_ONLY),
1239 (requested & RTE_ETH_RSS_L4_SRC_ONLY) ?
"" :
"NOT ");
1240 SCLogConfig(
"RTE_ETH_RSS_L4_DST_ONLY (Bit position: %d) %sset",
1241 GetFirstSetBitPosition(RTE_ETH_RSS_L4_DST_ONLY),
1242 (requested & RTE_ETH_RSS_L4_DST_ONLY) ?
"" :
"NOT ");
1245 "RTE_ETH_RSS_IP %sset", ((actual & RTE_ETH_RSS_IP) == RTE_ETH_RSS_IP) ?
"" :
"NOT ");
1247 "RTE_ETH_RSS_TCP %sset", ((actual & RTE_ETH_RSS_TCP) == RTE_ETH_RSS_TCP) ?
"" :
"NOT ");
1249 "RTE_ETH_RSS_UDP %sset", ((actual & RTE_ETH_RSS_UDP) == RTE_ETH_RSS_UDP) ?
"" :
"NOT ");
1251 ((actual & RTE_ETH_RSS_SCTP) == RTE_ETH_RSS_SCTP) ?
"" :
"NOT ");
1253 ((actual & RTE_ETH_RSS_TUNNEL) == RTE_ETH_RSS_TUNNEL) ?
"" :
"NOT ");
1256 SCLogConfig(
"RTE_ETH_RSS_IPV4 %sset", (actual & RTE_ETH_RSS_IPV4) ?
"" :
"NOT ");
1257 SCLogConfig(
"RTE_ETH_RSS_FRAG_IPV4 %sset", (actual & RTE_ETH_RSS_FRAG_IPV4) ?
"" :
"NOT ");
1259 (actual & RTE_ETH_RSS_NONFRAG_IPV4_TCP) ?
"" :
"NOT ");
1261 (actual & RTE_ETH_RSS_NONFRAG_IPV4_UDP) ?
"" :
"NOT ");
1262 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_SCTP %sset",
1263 (actual & RTE_ETH_RSS_NONFRAG_IPV4_SCTP) ?
"" :
"NOT ");
1264 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_OTHER %sset",
1265 (actual & RTE_ETH_RSS_NONFRAG_IPV4_OTHER) ?
"" :
"NOT ");
1266 SCLogConfig(
"RTE_ETH_RSS_IPV6 %sset", (actual & RTE_ETH_RSS_IPV6) ?
"" :
"NOT ");
1267 SCLogConfig(
"RTE_ETH_RSS_FRAG_IPV6 %sset", (actual & RTE_ETH_RSS_FRAG_IPV6) ?
"" :
"NOT ");
1269 (actual & RTE_ETH_RSS_NONFRAG_IPV6_TCP) ?
"" :
"NOT ");
1271 (actual & RTE_ETH_RSS_NONFRAG_IPV6_UDP) ?
"" :
"NOT ");
1272 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_SCTP %sset",
1273 (actual & RTE_ETH_RSS_NONFRAG_IPV6_SCTP) ?
"" :
"NOT ");
1274 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_OTHER %sset",
1275 (actual & RTE_ETH_RSS_NONFRAG_IPV6_OTHER) ?
"" :
"NOT ");
1277 SCLogConfig(
"RTE_ETH_RSS_L2_PAYLOAD %sset", (actual & RTE_ETH_RSS_L2_PAYLOAD) ?
"" :
"NOT ");
1278 SCLogConfig(
"RTE_ETH_RSS_IPV6_EX %sset", (actual & RTE_ETH_RSS_IPV6_EX) ?
"" :
"NOT ");
1279 SCLogConfig(
"RTE_ETH_RSS_IPV6_TCP_EX %sset", (actual & RTE_ETH_RSS_IPV6_TCP_EX) ?
"" :
"NOT ");
1280 SCLogConfig(
"RTE_ETH_RSS_IPV6_UDP_EX %sset", (actual & RTE_ETH_RSS_IPV6_UDP_EX) ?
"" :
"NOT ");
1282 SCLogConfig(
"RTE_ETH_RSS_PORT %sset", (actual & RTE_ETH_RSS_PORT) ?
"" :
"NOT ");
1283 SCLogConfig(
"RTE_ETH_RSS_VXLAN %sset", (actual & RTE_ETH_RSS_VXLAN) ?
"" :
"NOT ");
1284 SCLogConfig(
"RTE_ETH_RSS_NVGRE %sset", (actual & RTE_ETH_RSS_NVGRE) ?
"" :
"NOT ");
1285 SCLogConfig(
"RTE_ETH_RSS_GTPU %sset", (actual & RTE_ETH_RSS_GTPU) ?
"" :
"NOT ");
1287 SCLogConfig(
"RTE_ETH_RSS_L3_SRC_ONLY %sset", (actual & RTE_ETH_RSS_L3_SRC_ONLY) ?
"" :
"NOT ");
1288 SCLogConfig(
"RTE_ETH_RSS_L3_DST_ONLY %sset", (actual & RTE_ETH_RSS_L3_DST_ONLY) ?
"" :
"NOT ");
1289 SCLogConfig(
"RTE_ETH_RSS_L4_SRC_ONLY %sset", (actual & RTE_ETH_RSS_L4_SRC_ONLY) ?
"" :
"NOT ");
1290 SCLogConfig(
"RTE_ETH_RSS_L4_DST_ONLY %sset", (actual & RTE_ETH_RSS_L4_DST_ONLY) ?
"" :
"NOT ");
1293 static void DumpRXOffloadCapabilities(
const uint64_t rx_offld_capa)
1295 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_VLAN_STRIP - %savailable",
1296 rx_offld_capa & RTE_ETH_RX_OFFLOAD_VLAN_STRIP ?
"" :
"NOT ");
1297 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_IPV4_CKSUM - %savailable",
1298 rx_offld_capa & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM ?
"" :
"NOT ");
1299 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_UDP_CKSUM - %savailable",
1300 rx_offld_capa & RTE_ETH_RX_OFFLOAD_UDP_CKSUM ?
"" :
"NOT ");
1301 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_TCP_CKSUM - %savailable",
1302 rx_offld_capa & RTE_ETH_RX_OFFLOAD_TCP_CKSUM ?
"" :
"NOT ");
1303 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_TCP_LRO - %savailable",
1304 rx_offld_capa & RTE_ETH_RX_OFFLOAD_TCP_LRO ?
"" :
"NOT ");
1305 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_QINQ_STRIP - %savailable",
1306 rx_offld_capa & RTE_ETH_RX_OFFLOAD_QINQ_STRIP ?
"" :
"NOT ");
1307 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM - %savailable",
1308 rx_offld_capa & RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM ?
"" :
"NOT ");
1309 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_MACSEC_STRIP - %savailable",
1310 rx_offld_capa & RTE_ETH_RX_OFFLOAD_MACSEC_STRIP ?
"" :
"NOT ");
1311 #if RTE_VERSION < RTE_VERSION_NUM(22, 11, 0, 0)
1312 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_HEADER_SPLIT - %savailable",
1313 rx_offld_capa & RTE_ETH_RX_OFFLOAD_HEADER_SPLIT ?
"" :
"NOT ");
1315 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_VLAN_FILTER - %savailable",
1316 rx_offld_capa & RTE_ETH_RX_OFFLOAD_VLAN_FILTER ?
"" :
"NOT ");
1317 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_VLAN_EXTEND - %savailable",
1318 rx_offld_capa & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND ?
"" :
"NOT ");
1319 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_SCATTER - %savailable",
1320 rx_offld_capa & RTE_ETH_RX_OFFLOAD_SCATTER ?
"" :
"NOT ");
1321 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_TIMESTAMP - %savailable",
1322 rx_offld_capa & RTE_ETH_RX_OFFLOAD_TIMESTAMP ?
"" :
"NOT ");
1323 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_SECURITY - %savailable",
1324 rx_offld_capa & RTE_ETH_RX_OFFLOAD_SECURITY ?
"" :
"NOT ");
1325 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_KEEP_CRC - %savailable",
1326 rx_offld_capa & RTE_ETH_RX_OFFLOAD_KEEP_CRC ?
"" :
"NOT ");
1327 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_SCTP_CKSUM - %savailable",
1328 rx_offld_capa & RTE_ETH_RX_OFFLOAD_SCTP_CKSUM ?
"" :
"NOT ");
1329 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_OUTER_UDP_CKSUM - %savailable",
1330 rx_offld_capa & RTE_ETH_RX_OFFLOAD_OUTER_UDP_CKSUM ?
"" :
"NOT ");
1331 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_RSS_HASH - %savailable",
1332 rx_offld_capa & RTE_ETH_RX_OFFLOAD_RSS_HASH ?
"" :
"NOT ");
1333 #if RTE_VERSION >= RTE_VERSION_NUM(20, 11, 0, 0)
1334 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT - %savailable",
1335 rx_offld_capa & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT ?
"" :
"NOT ");
1339 static int DeviceValidateMTU(
const DPDKIfaceConfig *iconf,
const struct rte_eth_dev_info *dev_info)
1342 if (iconf->mtu > dev_info->max_mtu || iconf->mtu < dev_info->min_mtu) {
1344 "Min MTU: %" PRIu16
" Max MTU: %" PRIu16,
1345 iconf->iface, dev_info->min_mtu, dev_info->max_mtu);
1349 #if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0)
1351 if (iconf->mtu > RTE_ETHER_MAX_LEN &&
1352 !(dev_info->rx_offload_capa & DEV_RX_OFFLOAD_JUMBO_FRAME)) {
1353 SCLogError(
"%s: jumbo frames not supported, set MTU to 1500", iconf->iface);
1361 static void DeviceSetMTU(
struct rte_eth_conf *port_conf, uint16_t mtu)
1363 #if RTE_VERSION >= RTE_VERSION_NUM(21, 11, 0, 0)
1364 port_conf->rxmode.mtu = mtu;
1366 port_conf->rxmode.max_rx_pkt_len = mtu;
1367 if (mtu > RTE_ETHER_MAX_LEN) {
1368 port_conf->rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
1373 static void PortConfSetInterruptMode(
const DPDKIfaceConfig *iconf,
struct rte_eth_conf *port_conf)
1375 SCLogConfig(
"%s: interrupt mode is %s", iconf->iface,
1378 port_conf->intr_conf.rxq = 1;
1382 const struct rte_eth_dev_info *dev_info,
struct rte_eth_conf *port_conf)
1384 if (dev_info->rx_offload_capa & RTE_ETH_RX_OFFLOAD_RSS_HASH) {
1385 if (iconf->nb_rx_queues > 1) {
1386 SCLogConfig(
"%s: RSS enabled for %d queues", iconf->iface, iconf->nb_rx_queues);
1387 port_conf->rx_adv_conf.rss_conf = (
struct rte_eth_rss_conf){
1388 .rss_key = RSS_HKEY,
1389 .rss_key_len = RSS_HKEY_LEN,
1390 .rss_hf = iconf->rss_hf,
1393 const char *dev_driver = dev_info->driver_name;
1394 if (strcmp(dev_info->driver_name,
"net_bonding") == 0) {
1395 dev_driver = BondingDeviceDriverGet(iconf->port_id);
1398 DeviceSetPMDSpecificRSS(&port_conf->rx_adv_conf.rss_conf, dev_driver);
1400 uint64_t rss_hf_tmp =
1401 port_conf->rx_adv_conf.rss_conf.rss_hf & dev_info->flow_type_rss_offloads;
1402 if (port_conf->rx_adv_conf.rss_conf.rss_hf != rss_hf_tmp) {
1403 DumpRSSFlags(port_conf->rx_adv_conf.rss_conf.rss_hf, rss_hf_tmp);
1405 SCLogWarning(
"%s: modified RSS hash function based on hardware support: "
1406 "requested:%#" PRIx64
", configured:%#" PRIx64,
1407 iconf->iface, port_conf->rx_adv_conf.rss_conf.rss_hf, rss_hf_tmp);
1408 port_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf_tmp;
1410 port_conf->rxmode.mq_mode = RTE_ETH_MQ_RX_RSS;
1413 port_conf->rx_adv_conf.rss_conf.rss_key = NULL;
1414 port_conf->rx_adv_conf.rss_conf.rss_hf = 0;
1417 SCLogConfig(
"%s: RSS not supported", iconf->iface);
1422 const struct rte_eth_dev_info *dev_info,
struct rte_eth_conf *port_conf)
1425 SCLogConfig(
"%s: checksum validation disabled", iconf->iface);
1426 }
else if ((dev_info->rx_offload_capa & RTE_ETH_RX_OFFLOAD_CHECKSUM) ==
1427 RTE_ETH_RX_OFFLOAD_CHECKSUM) {
1430 SCLogConfig(
"%s: IP, TCP and UDP checksum validation offloaded", iconf->iface);
1431 port_conf->rxmode.offloads |= RTE_ETH_RX_OFFLOAD_CHECKSUM;
1434 SCLogConfig(
"%s: checksum validation enabled (but can be offloaded)", iconf->iface);
1440 const struct rte_eth_dev_info *dev_info,
struct rte_eth_conf *port_conf)
1442 if (iconf->vlan_strip_enabled) {
1443 if (dev_info->rx_offload_capa & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
1444 port_conf->rxmode.offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
1445 SCLogConfig(
"%s: hardware VLAN stripping enabled", iconf->iface);
1447 SCLogWarning(
"%s: hardware VLAN stripping enabled but not supported, disabling",
1454 const struct rte_eth_dev_info *dev_info,
struct rte_eth_conf *port_conf)
1456 DumpRXOffloadCapabilities(dev_info->rx_offload_capa);
1457 *port_conf = (
struct rte_eth_conf){
1459 .mq_mode = RTE_ETH_MQ_RX_NONE,
1463 .mq_mode = RTE_ETH_MQ_TX_NONE,
1468 PortConfSetInterruptMode(iconf, port_conf);
1471 PortConfSetRSSConf(iconf, dev_info, port_conf);
1472 PortConfSetChsumOffload(iconf, dev_info, port_conf);
1473 DeviceSetMTU(port_conf, iconf->mtu);
1474 PortConfSetVlanOffload(iconf, dev_info, port_conf);
1476 if (dev_info->tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) {
1477 port_conf->txmode.offloads |= RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
1481 static int DeviceConfigureQueues(
DPDKIfaceConfig *iconf,
const struct rte_eth_dev_info *dev_info,
1482 const struct rte_eth_conf *port_conf)
1486 struct rte_eth_rxconf rxq_conf;
1487 struct rte_eth_txconf txq_conf;
1489 retval = DPDKDeviceResourcesInit(&(iconf->pkt_mempools), iconf->nb_rx_queues);
1495 uint16_t mtu_size = iconf->mtu + RTE_ETHER_CRC_LEN + RTE_ETHER_HDR_LEN + 4;
1496 uint16_t mbuf_size = ROUNDUP(mtu_size, 1024) + RTE_PKTMBUF_HEADROOM;
1497 uint32_t q_mp_cache_sz = iconf->mempool_cache_size_auto
1498 ? MempoolCacheSizeCalculate(iconf->queue_mempool_size)
1499 : iconf->mempool_cache_size;
1500 SCLogInfo(
"%s: creating %u packet mempools of size %u, cache size %u, mbuf size %u",
1501 iconf->iface, iconf->nb_rx_queues, iconf->queue_mempool_size, q_mp_cache_sz, mbuf_size);
1502 for (
int i = 0; i < iconf->nb_rx_queues; i++) {
1503 char mempool_name[64];
1504 snprintf(mempool_name,
sizeof(mempool_name),
"mp_%d_%.20s", i, iconf->iface);
1505 iconf->pkt_mempools->pkt_mp[i] = rte_pktmbuf_pool_create(mempool_name,
1506 iconf->queue_mempool_size, q_mp_cache_sz, 0, mbuf_size, (
int)iconf->socket_id);
1507 if (iconf->pkt_mempools->pkt_mp[i] == NULL) {
1508 retval = -rte_errno;
1509 SCLogError(
"%s: rte_pktmbuf_pool_create failed with code %d (mempool: %s) - %s",
1510 iconf->iface, rte_errno, mempool_name, rte_strerror(rte_errno));
1515 for (uint16_t queue_id = 0; queue_id < iconf->nb_rx_queues; queue_id++) {
1516 rxq_conf = dev_info->default_rxconf;
1517 rxq_conf.offloads = port_conf->rxmode.offloads;
1518 rxq_conf.rx_thresh.hthresh = 0;
1519 rxq_conf.rx_thresh.pthresh = 0;
1520 rxq_conf.rx_thresh.wthresh = 0;
1521 rxq_conf.rx_free_thresh = 0;
1522 rxq_conf.rx_drop_en = 0;
1523 SCLogConfig(
"%s: setting up RX queue %d: rx_desc: %u offloads: 0x%" PRIx64
1524 " hthresh: %" PRIu8
" pthresh: %" PRIu8
" wthresh: %" PRIu8
1525 " free_thresh: %" PRIu16
" drop_en: %" PRIu8,
1526 iconf->iface, queue_id, iconf->nb_rx_desc, rxq_conf.offloads,
1527 rxq_conf.rx_thresh.hthresh, rxq_conf.rx_thresh.pthresh, rxq_conf.rx_thresh.wthresh,
1528 rxq_conf.rx_free_thresh, rxq_conf.rx_drop_en);
1530 retval = rte_eth_rx_queue_setup(iconf->port_id, queue_id, iconf->nb_rx_desc,
1531 (
unsigned int)iconf->socket_id, &rxq_conf, iconf->pkt_mempools->pkt_mp[queue_id]);
1533 SCLogError(
"%s: failed to setup RX queue %u: %s", iconf->iface, queue_id,
1534 rte_strerror(-retval));
1539 for (uint16_t queue_id = 0; queue_id < iconf->nb_tx_queues; queue_id++) {
1540 txq_conf = dev_info->default_txconf;
1541 txq_conf.offloads = port_conf->txmode.offloads;
1542 SCLogConfig(
"%s: setting up TX queue %d: tx_desc: %" PRIu16
" tx: offloads: 0x%" PRIx64
1543 " hthresh: %" PRIu8
" pthresh: %" PRIu8
" wthresh: %" PRIu8
1544 " tx_free_thresh: %" PRIu16
" tx_rs_thresh: %" PRIu16
1545 " txq_deferred_start: %" PRIu8,
1546 iconf->iface, queue_id, iconf->nb_tx_desc, txq_conf.offloads,
1547 txq_conf.tx_thresh.hthresh, txq_conf.tx_thresh.pthresh, txq_conf.tx_thresh.wthresh,
1548 txq_conf.tx_free_thresh, txq_conf.tx_rs_thresh, txq_conf.tx_deferred_start);
1549 retval = rte_eth_tx_queue_setup(iconf->port_id, queue_id, iconf->nb_tx_desc,
1550 (
unsigned int)iconf->socket_id, &txq_conf);
1552 SCLogError(
"%s: failed to setup TX queue %u: %s", iconf->iface, queue_id,
1553 rte_strerror(-retval));
1562 DPDKDeviceResourcesDeinit(&iconf->pkt_mempools);
1571 ConfigInit(&out_iconf);
1572 if (out_iconf == NULL) {
1573 FatalError(
"Copy interface of the interface \"%s\" is NULL", iconf->iface);
1576 retval = ConfigLoad(out_iconf, iconf->out_iface);
1578 SCLogError(
"%s: fail to load config of interface", iconf->out_iface);
1579 out_iconf->DerefFunc(out_iconf);
1583 if (iconf->nb_rx_queues != out_iconf->nb_tx_queues) {
1585 SCLogError(
"%s: configured %d RX queues but copy interface %s has %d TX queues"
1586 " - number of queues must be equal",
1587 iconf->iface, iconf->nb_rx_queues, out_iconf->iface, out_iconf->nb_tx_queues);
1588 out_iconf->DerefFunc(out_iconf);
1590 }
else if (iconf->mtu != out_iconf->mtu) {
1591 SCLogError(
"%s: configured MTU of %d but copy interface %s has MTU set to %d"
1592 " - MTU must be equal",
1593 iconf->iface, iconf->mtu, out_iconf->iface, out_iconf->mtu);
1594 out_iconf->DerefFunc(out_iconf);
1596 }
else if (iconf->copy_mode != out_iconf->copy_mode) {
1597 SCLogError(
"%s: copy modes of interfaces %s and %s are not equal", iconf->iface,
1598 iconf->iface, out_iconf->iface);
1599 out_iconf->DerefFunc(out_iconf);
1601 }
else if (strcmp(iconf->iface, out_iconf->out_iface) != 0) {
1603 SCLogError(
"%s: copy interface of %s is not set to %s", iconf->iface, out_iconf->iface,
1605 out_iconf->DerefFunc(out_iconf);
1609 out_iconf->DerefFunc(out_iconf);
1616 if (iconf->out_iface != NULL) {
1617 if (!rte_eth_dev_is_valid_port(iconf->out_port_id)) {
1618 SCLogError(
"%s: retrieved copy interface port ID \"%d\" is invalid or the device is "
1620 iconf->iface, iconf->out_port_id);
1623 int32_t out_port_socket_id;
1626 SCLogError(
"%s: invalid socket id: %s", iconf->out_iface, rte_strerror(-retval));
1630 if (iconf->socket_id != out_port_socket_id) {
1632 "%s: out iface %s is not on the same NUMA node (%s - NUMA %d, %s - NUMA %d)",
1633 iconf->iface, iconf->out_iface, iconf->iface, iconf->socket_id,
1634 iconf->out_iface, out_port_socket_id);
1637 retval = DeviceValidateOutIfaceConfig(iconf);
1644 SCLogInfo(
"%s: DPDK IPS mode activated: %s->%s", iconf->iface, iconf->iface,
1647 SCLogInfo(
"%s: DPDK TAP mode activated: %s->%s", iconf->iface, iconf->iface,
1661 static int32_t DeviceVerifyPostConfigure(
1662 const DPDKIfaceConfig *iconf,
const struct rte_eth_dev_info *dev_info)
1665 struct rte_eth_dev_info post_conf_dev_info = { 0 };
1666 int32_t ret = rte_eth_dev_info_get(iconf->port_id, &post_conf_dev_info);
1668 SCLogError(
"%s: getting device info failed: %s", iconf->iface, rte_strerror(-ret));
1672 if (dev_info->flow_type_rss_offloads != post_conf_dev_info.flow_type_rss_offloads ||
1673 dev_info->rx_offload_capa != post_conf_dev_info.rx_offload_capa ||
1674 dev_info->tx_offload_capa != post_conf_dev_info.tx_offload_capa ||
1675 dev_info->max_rx_queues != post_conf_dev_info.max_rx_queues ||
1676 dev_info->max_tx_queues != post_conf_dev_info.max_tx_queues ||
1677 dev_info->max_mtu != post_conf_dev_info.max_mtu) {
1678 SCLogWarning(
"%s: device information severely changed after configuration, reconfiguring",
1683 if (strcmp(dev_info->driver_name,
"net_bonding") == 0) {
1684 ret = BondingAllDevicesSameDriver(iconf->port_id);
1686 SCLogError(
"%s: bond port uses port with different DPDK drivers", iconf->iface);
1697 if (!rte_eth_dev_is_valid_port(iconf->port_id)) {
1698 SCLogError(
"%s: retrieved port ID \"%d\" is invalid or the device is not attached ",
1699 iconf->iface, iconf->port_id);
1705 SCLogError(
"%s: invalid socket id: %s", iconf->iface, rte_strerror(-retval));
1709 struct rte_eth_dev_info dev_info = { 0 };
1710 retval = rte_eth_dev_info_get(iconf->port_id, &dev_info);
1712 SCLogError(
"%s: getting device info failed: %s", iconf->iface, rte_strerror(-retval));
1716 if (iconf->nb_rx_queues > dev_info.max_rx_queues) {
1717 SCLogError(
"%s: configured RX queues %u is higher than device maximum (%" PRIu16
")",
1718 iconf->iface, iconf->nb_rx_queues, dev_info.max_rx_queues);
1722 if (iconf->nb_tx_queues > dev_info.max_tx_queues) {
1723 SCLogError(
"%s: configured TX queues %u is higher than device maximum (%" PRIu16
")",
1724 iconf->iface, iconf->nb_tx_queues, dev_info.max_tx_queues);
1728 retval = DeviceValidateMTU(iconf, &dev_info);
1732 struct rte_eth_conf port_conf = { 0 };
1733 DeviceInitPortConf(iconf, &dev_info, &port_conf);
1734 if (port_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_CHECKSUM) {
1739 retval = rte_eth_dev_configure(
1740 iconf->port_id, iconf->nb_rx_queues, iconf->nb_tx_queues, &port_conf);
1742 SCLogError(
"%s: failed to configure the device: %s", iconf->iface, rte_strerror(-retval));
1746 retval = DeviceVerifyPostConfigure(iconf, &dev_info);
1750 uint16_t tmp_nb_rx_desc = iconf->nb_rx_desc;
1751 uint16_t tmp_nb_tx_desc = iconf->nb_tx_desc;
1752 retval = rte_eth_dev_adjust_nb_rx_tx_desc(
1753 iconf->port_id, &iconf->nb_rx_desc, &iconf->nb_tx_desc);
1755 SCLogError(
"%s: failed to adjust device queue descriptors: %s", iconf->iface,
1756 rte_strerror(-retval));
1758 }
else if (tmp_nb_rx_desc != iconf->nb_rx_desc || tmp_nb_tx_desc != iconf->nb_tx_desc) {
1759 SCLogWarning(
"%s: device queue descriptors adjusted (RX: from %u to %u, TX: from %u to %u)",
1760 iconf->iface, tmp_nb_rx_desc, iconf->nb_rx_desc, tmp_nb_tx_desc, iconf->nb_tx_desc);
1763 retval = iconf->flags &
DPDK_MULTICAST ? rte_eth_allmulticast_enable(iconf->port_id)
1764 : rte_eth_allmulticast_disable(iconf->port_id);
1765 if (retval == -ENOTSUP) {
1766 retval = rte_eth_allmulticast_get(iconf->port_id);
1770 SCLogWarning(
"%s: cannot configure allmulticast, the port is %sin allmulticast mode",
1771 iconf->iface, retval == 1 ?
"" :
"not ");
1772 }
else if (retval < 0) {
1773 SCLogError(
"%s: failed to get multicast mode: %s", iconf->iface, rte_strerror(-retval));
1776 }
else if (retval < 0) {
1777 SCLogError(
"%s: error when changing multicast setting: %s", iconf->iface,
1778 rte_strerror(-retval));
1782 retval = iconf->flags &
DPDK_PROMISC ? rte_eth_promiscuous_enable(iconf->port_id)
1783 : rte_eth_promiscuous_disable(iconf->port_id);
1784 if (retval == -ENOTSUP) {
1785 retval = rte_eth_promiscuous_get(iconf->port_id);
1788 SCLogError(
"%s: cannot configure promiscuous mode, the port is in %spromiscuous mode",
1789 iconf->iface, retval == 1 ?
"" :
"non-");
1791 }
else if (retval < 0) {
1793 "%s: failed to get promiscuous mode: %s", iconf->iface, rte_strerror(-retval));
1796 }
else if (retval < 0) {
1797 SCLogError(
"%s: error when changing promiscuous setting: %s", iconf->iface,
1798 rte_strerror(-retval));
1803 SCLogConfig(
"%s: setting MTU to %d", iconf->iface, iconf->mtu);
1804 retval = rte_eth_dev_set_mtu(iconf->port_id, iconf->mtu);
1805 if (retval == -ENOTSUP) {
1807 retval = rte_eth_dev_get_mtu(iconf->port_id, &iconf->mtu);
1809 SCLogError(
"%s: failed to retrieve MTU: %s", iconf->iface, rte_strerror(-retval));
1813 "%s: changing MTU is not supported, current MTU: %u", iconf->iface, iconf->mtu);
1814 }
else if (retval < 0) {
1816 "%s: failed to set MTU to %u: %s", iconf->iface, iconf->mtu, rte_strerror(-retval));
1820 retval = DeviceConfigureQueues(iconf, &dev_info, &port_conf);
1825 retval = DeviceConfigureIPS(iconf);
1833 static void *ParseDpdkConfigAndConfigureDevice(
const char *iface)
1837 if (iconf == NULL) {
1838 FatalError(
"DPDK configuration could not be parsed");
1841 retval = DeviceConfigure(iconf);
1842 if (retval == -EAGAIN) {
1844 retval = DeviceConfigure(iconf);
1848 iconf->DerefFunc(iconf);
1849 if (rte_eal_cleanup() != 0)
1850 FatalError(
"EAL cleanup failed: %s", rte_strerror(-retval));
1852 if (retval == -ENOMEM) {
1853 FatalError(
"%s: memory allocation failed - consider"
1854 "%s freeing up some memory.",
1856 rte_eal_has_hugepages() != 0 ?
" increasing the number of hugepages or" :
"");
1858 FatalError(
"%s: failed to configure", iface);
1867 iconf->workers_sync =
SCCalloc(1,
sizeof(*iconf->workers_sync));
1868 if (iconf->workers_sync == NULL) {
1869 FatalError(
"Failed to allocate memory for workers_sync");
1872 iconf->workers_sync->worker_cnt = iconf->threads;
1876 if (ldev_instance == NULL) {
1877 FatalError(
"Device %s is not registered as a live device", iface);
1879 ldev_instance->dpdk_vars = iconf->pkt_mempools;
1880 iconf->pkt_mempools = NULL;
1897 static uint16_t DPDKConfigGetThreadsCount(
void *conf)
1903 return dpdk_conf->threads;
1908 static int DPDKRunModeIsIPS(
void)
1911 const char dpdk_node_query[] =
"dpdk.interfaces";
1913 if (dpdk_node == NULL) {
1914 FatalError(
"Unable to get %s configuration node", dpdk_node_query);
1917 const char default_iface[] =
"default";
1920 bool has_ips =
false;
1921 bool has_ids =
false;
1922 for (
int ldev = 0; ldev < nlive; ldev++) {
1924 if (live_dev == NULL)
1925 FatalError(
"Unable to get device id %d from LiveDevice list", ldev);
1928 if (if_root == NULL) {
1929 if (if_default == NULL)
1930 FatalError(
"Unable to get %s or %s interface", live_dev, default_iface);
1932 if_root = if_default;
1935 const char *copymodestr = NULL;
1936 const char *copyifacestr = NULL;
1939 if (strcmp(copymodestr,
"ips") == 0) {
1948 if (has_ids && has_ips) {
1949 FatalError(
"Copy-mode of interface %s mixes with the previously set copy-modes "
1950 "(only IDS/TAP and IPS copy-mode combinations are allowed in DPDK",
1958 static int DPDKRunModeEnableIPS(
void)
1960 int r = DPDKRunModeIsIPS();
1976 "Workers DPDK mode, each thread does all"
1977 " tasks from acquisition to logging",
2002 SCLogDebug(
"RunModeIdsDpdkWorkers initialised");