55 #define RSS_HKEY_LEN 40
57 uint8_t rss_hkey[] = {
58 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
59 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
60 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
61 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
65 #define ROUNDUP(x, y) ((((x) + ((y)-1)) / (y)) * (y))
76 static char *AllocArgument(
size_t arg_len);
77 static char *AllocAndSetArgument(
const char *arg);
78 static char *AllocAndSetOption(
const char *arg);
80 static void ArgumentsInit(
struct Arguments *args,
unsigned capacity);
81 static void ArgumentsCleanup(
struct Arguments *args);
82 static void ArgumentsAdd(
struct Arguments *args,
char *value);
83 static void ArgumentsAddOptionAndArgument(
struct Arguments *args,
const char *opt,
const char *arg);
84 static void InitEal(
void);
86 static void ConfigSetIface(
DPDKIfaceConfig *iconf,
const char *entry_str);
87 static int ConfigSetThreads(
DPDKIfaceConfig *iconf,
const char *entry_str);
88 static int ConfigSetRxQueues(
DPDKIfaceConfig *iconf, uint16_t nb_queues);
89 static int ConfigSetTxQueues(
DPDKIfaceConfig *iconf, uint16_t nb_queues);
90 static int ConfigSetMempoolSize(
DPDKIfaceConfig *iconf, intmax_t entry_int);
91 static int ConfigSetMempoolCacheSize(
DPDKIfaceConfig *iconf,
const char *entry_str);
92 static int ConfigSetRxDescriptors(
DPDKIfaceConfig *iconf, intmax_t entry_int);
93 static int ConfigSetTxDescriptors(
DPDKIfaceConfig *iconf, intmax_t entry_int);
95 static bool ConfigSetPromiscuousMode(
DPDKIfaceConfig *iconf,
int entry_bool);
97 static int ConfigSetChecksumChecks(
DPDKIfaceConfig *iconf,
int entry_bool);
98 static int ConfigSetChecksumOffload(
DPDKIfaceConfig *iconf,
int entry_bool);
99 static int ConfigSetCopyIface(
DPDKIfaceConfig *iconf,
const char *entry_str);
100 static int ConfigSetCopyMode(
DPDKIfaceConfig *iconf,
const char *entry_str);
101 static int ConfigSetCopyIfaceSettings(
DPDKIfaceConfig *iconf,
const char *iface,
const char *mode);
107 const struct rte_eth_dev_info *dev_info,
struct rte_eth_conf *port_conf);
108 static int DeviceConfigureQueues(
DPDKIfaceConfig *iconf,
const struct rte_eth_dev_info *dev_info,
109 const struct rte_eth_conf *port_conf);
113 static void *ParseDpdkConfigAndConfigureDevice(
const char *iface);
114 static void DPDKDerefConfig(
void *conf);
116 #define DPDK_CONFIG_DEFAULT_THREADS "auto"
117 #define DPDK_CONFIG_DEFAULT_INTERRUPT_MODE false
118 #define DPDK_CONFIG_DEFAULT_MEMPOOL_SIZE 65535
119 #define DPDK_CONFIG_DEFAULT_MEMPOOL_CACHE_SIZE "auto"
120 #define DPDK_CONFIG_DEFAULT_RX_DESCRIPTORS 1024
121 #define DPDK_CONFIG_DEFAULT_TX_DESCRIPTORS 1024
122 #define DPDK_CONFIG_DEFAULT_RSS_HASH_FUNCTIONS RTE_ETH_RSS_IP
123 #define DPDK_CONFIG_DEFAULT_MTU 1500
124 #define DPDK_CONFIG_DEFAULT_PROMISCUOUS_MODE 1
125 #define DPDK_CONFIG_DEFAULT_MULTICAST_MODE 1
126 #define DPDK_CONFIG_DEFAULT_CHECKSUM_VALIDATION 1
127 #define DPDK_CONFIG_DEFAULT_CHECKSUM_VALIDATION_OFFLOAD 1
128 #define DPDK_CONFIG_DEFAULT_VLAN_STRIP 0
129 #define DPDK_CONFIG_DEFAULT_COPY_MODE "none"
130 #define DPDK_CONFIG_DEFAULT_COPY_INTERFACE "none"
134 .irq_mode =
"interrupt-mode",
135 .promisc =
"promisc",
136 .multicast =
"multicast",
137 .checksum_checks =
"checksum-checks",
138 .checksum_checks_offload =
"checksum-checks-offload",
140 .vlan_strip_offload =
"vlan-strip-offload",
141 .rss_hf =
"rss-hash-functions",
142 .mempool_size =
"mempool-size",
143 .mempool_cache_size =
"mempool-cache-size",
144 .rx_descriptors =
"rx-descriptors",
145 .tx_descriptors =
"tx-descriptors",
146 .copy_mode =
"copy-mode",
147 .copy_iface =
"copy-iface",
150 static int GreatestDivisorUpTo(uint32_t num, uint32_t max_num)
152 for (
int i = max_num; i >= 2; i--) {
160 static char *AllocArgument(
size_t arg_len)
166 ptr = (
char *)
SCCalloc(arg_len,
sizeof(
char));
168 FatalError(
"Could not allocate memory for an argument");
178 static char *AllocAndSetArgument(
const char *arg)
182 FatalError(
"Passed argument is NULL in DPDK config initialization");
185 size_t arg_len = strlen(arg);
187 ptr = AllocArgument(arg_len);
188 strlcpy(ptr, arg, arg_len + 1);
192 static char *AllocAndSetOption(
const char *arg)
196 FatalError(
"Passed option is NULL in DPDK config initialization");
199 size_t arg_len = strlen(arg);
200 uint8_t is_long_arg = arg_len > 1;
201 const char *dash_prefix = is_long_arg ?
"--" :
"-";
202 size_t full_len = arg_len + strlen(dash_prefix);
204 ptr = AllocArgument(full_len);
205 strlcpy(ptr, dash_prefix, strlen(dash_prefix) + 1);
206 strlcat(ptr, arg, full_len + 1);
210 static void ArgumentsInit(
struct Arguments *args,
unsigned capacity)
213 args->argv =
SCCalloc(capacity,
sizeof(*args->argv));
214 if (args->argv == NULL)
215 FatalError(
"Could not allocate memory for Arguments structure");
217 args->capacity = capacity;
222 static void ArgumentsCleanup(
struct Arguments *args)
225 for (
int i = 0; i < args->argc; i++) {
226 if (args->argv[i] != NULL) {
228 args->argv[i] = NULL;
238 static void ArgumentsAdd(
struct Arguments *args,
char *value)
241 if (args->argc + 1 > args->capacity)
242 FatalError(
"No capacity for more arguments (Max: %" PRIu32
")", EAL_ARGS);
244 args->argv[args->argc++] = value;
248 static void ArgumentsAddOptionAndArgument(
struct Arguments *args,
const char *opt,
const char *arg)
254 option = AllocAndSetOption(opt);
255 ArgumentsAdd(args, option);
258 if (arg == NULL || arg[0] ==
'\0')
261 argument = AllocAndSetArgument(arg);
262 ArgumentsAdd(args, argument);
266 static void InitEal(
void)
272 struct Arguments args;
275 if (eal_params == NULL) {
276 FatalError(
"DPDK EAL parameters not found in the config");
279 ArgumentsInit(&args, EAL_ARGS);
280 ArgumentsAdd(&args, AllocAndSetArgument(
"suricata"));
284 const char *key = param->
name;
287 ArgumentsAddOptionAndArgument(&args, key, (
const char *)val->
val);
291 ArgumentsAddOptionAndArgument(&args, param->
name, param->
val);
295 eal_argv =
SCCalloc(args.argc,
sizeof(*args.argv));
296 if (eal_argv == NULL) {
297 FatalError(
"Failed to allocate memory for the array of DPDK EAL arguments");
299 memcpy(eal_argv, args.argv, args.argc *
sizeof(*args.argv));
301 rte_log_set_global_level(RTE_LOG_WARNING);
302 retval = rte_eal_init(args.argc, eal_argv);
304 ArgumentsCleanup(&args);
308 FatalError(
"DPDK EAL initialization error: %s", rte_strerror(-retval));
312 static void DPDKDerefConfig(
void *conf)
318 if (iconf->pkt_mempool != NULL) {
319 rte_mempool_free(iconf->pkt_mempool);
333 FatalError(
"Could not allocate memory for DPDKIfaceConfig");
335 ptr->pkt_mempool = NULL;
336 ptr->out_port_id = -1;
339 ptr->DerefFunc = DPDKDerefConfig;
346 static void ConfigSetIface(
DPDKIfaceConfig *iconf,
const char *entry_str)
351 if (entry_str == NULL || entry_str[0] ==
'\0')
352 FatalError(
"Interface name in DPDK config is NULL or empty");
354 retval = rte_eth_dev_get_port_by_name(entry_str, &iconf->port_id);
356 FatalError(
"%s: interface not found: %s", entry_str, rte_strerror(-retval));
358 strlcpy(iconf->iface, entry_str,
sizeof(iconf->iface));
362 static int ConfigSetThreads(
DPDKIfaceConfig *iconf,
const char *entry_str)
365 static int32_t remaining_auto_cpus = -1;
367 SCLogError(
"DPDK runmode requires configured thread affinity");
373 SCLogError(
"Specify worker-cpu-set list in the threading section");
378 SCLogError(
"Specify management-cpu-set list in the threading section");
384 "\"all\" specified in worker CPU cores affinity, excluding management threads");
385 UtilAffinityCpusExclude(wtaf, mtaf);
389 if (sched_cpus == 0) {
390 SCLogError(
"No worker CPU cores with configured affinity were configured");
392 }
else if (UtilAffinityCpusOverlap(wtaf, mtaf) != 0) {
393 SCLogWarning(
"Worker threads should not overlap with management threads in the CPU core "
394 "affinity configuration");
398 if (active_runmode && !strcmp(
"single", active_runmode)) {
403 if (entry_str == NULL) {
404 SCLogError(
"Number of threads for interface \"%s\" not specified", iconf->iface);
408 if (strcmp(entry_str,
"auto") == 0) {
410 if (iconf->threads == 0) {
411 SCLogError(
"Not enough worker CPU cores with affinity were configured");
415 if (remaining_auto_cpus > 0) {
417 remaining_auto_cpus--;
418 }
else if (remaining_auto_cpus == -1) {
420 if (remaining_auto_cpus > 0) {
422 remaining_auto_cpus--;
425 SCLogConfig(
"%s: auto-assigned %u threads", iconf->iface, iconf->threads);
430 SCLogError(
"Threads entry for interface %s contain non-numerical characters - \"%s\"",
431 iconf->iface, entry_str);
435 if (iconf->threads <= 0) {
436 SCLogError(
"%s: positive number of threads required", iconf->iface);
443 static bool ConfigSetInterruptMode(
DPDKIfaceConfig *iconf,
bool enable)
452 static int ConfigSetRxQueues(
DPDKIfaceConfig *iconf, uint16_t nb_queues)
455 iconf->nb_rx_queues = nb_queues;
456 if (iconf->nb_rx_queues < 1) {
457 SCLogError(
"%s: positive number of RX queues is required", iconf->iface);
464 static int ConfigSetTxQueues(
DPDKIfaceConfig *iconf, uint16_t nb_queues)
467 iconf->nb_tx_queues = nb_queues;
468 if (iconf->nb_tx_queues < 1) {
469 SCLogError(
"%s: positive number of TX queues is required", iconf->iface);
476 static int ConfigSetMempoolSize(
DPDKIfaceConfig *iconf, intmax_t entry_int)
479 if (entry_int <= 0) {
480 SCLogError(
"%s: positive memory pool size is required", iconf->iface);
482 }
else if (entry_int > UINT32_MAX) {
483 SCLogError(
"%s: memory pool size cannot exceed %" PRIu32, iconf->iface, UINT32_MAX);
487 iconf->mempool_size = entry_int;
491 static int ConfigSetMempoolCacheSize(
DPDKIfaceConfig *iconf,
const char *entry_str)
494 if (entry_str == NULL || entry_str[0] ==
'\0' || strcmp(entry_str,
"auto") == 0) {
499 if (iconf->mempool_size == 0) {
500 SCLogError(
"%s: cannot calculate mempool cache size of a mempool with size %d",
501 iconf->iface, iconf->mempool_size);
505 uint32_t max_cache_size =
MIN(RTE_MEMPOOL_CACHE_MAX_SIZE, iconf->mempool_size / 1.5);
506 iconf->mempool_cache_size = GreatestDivisorUpTo(iconf->mempool_size, max_cache_size);
511 SCLogError(
"%s: mempool cache size entry contain non-numerical characters - \"%s\"",
512 iconf->iface, entry_str);
516 if (iconf->mempool_cache_size <= 0 || iconf->mempool_cache_size > RTE_MEMPOOL_CACHE_MAX_SIZE) {
517 SCLogError(
"%s: mempool cache size requires a positive number smaller than %" PRIu32,
518 iconf->iface, RTE_MEMPOOL_CACHE_MAX_SIZE);
525 static int ConfigSetRxDescriptors(
DPDKIfaceConfig *iconf, intmax_t entry_int)
528 if (entry_int <= 0) {
529 SCLogError(
"%s: positive number of RX descriptors is required", iconf->iface);
531 }
else if (entry_int > UINT16_MAX) {
532 SCLogError(
"%s: number of RX descriptors cannot exceed %" PRIu16, iconf->iface, UINT16_MAX);
536 iconf->nb_rx_desc = entry_int;
540 static int ConfigSetTxDescriptors(
DPDKIfaceConfig *iconf, intmax_t entry_int)
543 if (entry_int <= 0) {
544 SCLogError(
"%s: positive number of TX descriptors is required", iconf->iface);
546 }
else if (entry_int > UINT16_MAX) {
547 SCLogError(
"%s: number of TX descriptors cannot exceed %" PRIu16, iconf->iface, UINT16_MAX);
551 iconf->nb_tx_desc = entry_int;
555 static int ConfigSetRSSHashFunctions(
DPDKIfaceConfig *iconf,
const char *entry_str)
558 if (entry_str == NULL || entry_str[0] ==
'\0' || strcmp(entry_str,
"auto") == 0) {
559 iconf->rss_hf = DPDK_CONFIG_DEFAULT_RSS_HASH_FUNCTIONS;
564 SCLogError(
"%s: RSS hash functions entry contain non-numerical characters - \"%s\"",
565 iconf->iface, entry_str);
575 if (entry_int < RTE_ETHER_MIN_MTU || entry_int > RTE_ETHER_MAX_JUMBO_FRAME_LEN) {
576 SCLogError(
"%s: MTU size can only be between %" PRIu32
" and %" PRIu32, iconf->iface,
577 RTE_ETHER_MIN_MTU, RTE_ETHER_MAX_JUMBO_FRAME_LEN);
581 iconf->mtu = entry_int;
585 static bool ConfigSetPromiscuousMode(
DPDKIfaceConfig *iconf,
int entry_bool)
603 static int ConfigSetChecksumChecks(
DPDKIfaceConfig *iconf,
int entry_bool)
612 static int ConfigSetChecksumOffload(
DPDKIfaceConfig *iconf,
int entry_bool)
624 iconf->vlan_strip_enabled = entry_bool;
628 static int ConfigSetCopyIface(
DPDKIfaceConfig *iconf,
const char *entry_str)
633 if (entry_str == NULL || entry_str[0] ==
'\0' || strcmp(entry_str,
"none") == 0) {
634 iconf->out_iface = NULL;
638 retval = rte_eth_dev_get_port_by_name(entry_str, &iconf->out_port_id);
640 SCLogError(
"%s: copy interface (%s) not found: %s", iconf->iface, entry_str,
641 rte_strerror(-retval));
645 iconf->out_iface = entry_str;
649 static int ConfigSetCopyMode(
DPDKIfaceConfig *iconf,
const char *entry_str)
652 if (entry_str == NULL) {
653 SCLogWarning(
"%s: no copy mode specified, changing to %s ", iconf->iface,
654 DPDK_CONFIG_DEFAULT_COPY_MODE);
655 entry_str = DPDK_CONFIG_DEFAULT_COPY_MODE;
658 if (strcmp(entry_str,
"none") != 0 && strcmp(entry_str,
"tap") != 0 &&
659 strcmp(entry_str,
"ips") != 0) {
660 SCLogWarning(
"%s: copy mode \"%s\" is not one of the possible values (none|tap|ips). "
662 entry_str, iconf->iface, DPDK_CONFIG_DEFAULT_COPY_MODE);
663 entry_str = DPDK_CONFIG_DEFAULT_COPY_MODE;
666 if (strcmp(entry_str,
"none") == 0) {
668 }
else if (strcmp(entry_str,
"tap") == 0) {
670 }
else if (strcmp(entry_str,
"ips") == 0) {
677 static int ConfigSetCopyIfaceSettings(
DPDKIfaceConfig *iconf,
const char *iface,
const char *mode)
682 retval = ConfigSetCopyIface(iconf, iface);
686 retval = ConfigSetCopyMode(iconf, mode);
691 if (iconf->out_iface != NULL)
692 iconf->out_iface = NULL;
696 if (iconf->out_iface == NULL || strlen(iconf->out_iface) <= 0) {
697 SCLogError(
"%s: copy mode enabled but interface not set", iconf->iface);
710 const char *entry_str = NULL;
711 intmax_t entry_int = 0;
713 const char *copy_iface_str = NULL;
714 const char *copy_mode_str = NULL;
716 ConfigSetIface(iconf, iface);
720 FatalError(
"failed to find DPDK configuration for the interface %s", iconf->iface);
724 ? ConfigSetThreads(iconf, DPDK_CONFIG_DEFAULT_THREADS)
725 : ConfigSetThreads(iconf, entry_str);
732 irq_enable = DPDK_CONFIG_DEFAULT_INTERRUPT_MODE;
734 irq_enable = entry_bool ? true :
false;
736 retval = ConfigSetInterruptMode(iconf, irq_enable);
741 retval = ConfigSetRxQueues(iconf, (uint16_t)iconf->threads);
746 retval = ConfigSetTxQueues(iconf, (uint16_t)iconf->threads);
751 if_root, if_default, dpdk_yaml.
mempool_size, &entry_int) != 1
752 ? ConfigSetMempoolSize(iconf, DPDK_CONFIG_DEFAULT_MEMPOOL_SIZE)
753 : ConfigSetMempoolSize(iconf, entry_int);
759 ? ConfigSetMempoolCacheSize(iconf, DPDK_CONFIG_DEFAULT_MEMPOOL_CACHE_SIZE)
760 : ConfigSetMempoolCacheSize(iconf, entry_str);
766 ? ConfigSetRxDescriptors(iconf, DPDK_CONFIG_DEFAULT_RX_DESCRIPTORS)
767 : ConfigSetRxDescriptors(iconf, entry_int);
773 ? ConfigSetTxDescriptors(iconf, DPDK_CONFIG_DEFAULT_TX_DESCRIPTORS)
774 : ConfigSetTxDescriptors(iconf, entry_int);
779 ? ConfigSetMtu(iconf, DPDK_CONFIG_DEFAULT_MTU)
780 : ConfigSetMtu(iconf, entry_int);
785 ? ConfigSetRSSHashFunctions(iconf, NULL)
786 : ConfigSetRSSHashFunctions(iconf, entry_str);
791 if_root, if_default, dpdk_yaml.
promisc, &entry_bool) != 1
792 ? ConfigSetPromiscuousMode(iconf, DPDK_CONFIG_DEFAULT_PROMISCUOUS_MODE)
793 : ConfigSetPromiscuousMode(iconf, entry_bool);
798 if_root, if_default, dpdk_yaml.
multicast, &entry_bool) != 1
799 ? ConfigSetMulticast(iconf, DPDK_CONFIG_DEFAULT_MULTICAST_MODE)
800 : ConfigSetMulticast(iconf, entry_bool);
806 ? ConfigSetChecksumChecks(iconf, DPDK_CONFIG_DEFAULT_CHECKSUM_VALIDATION)
807 : ConfigSetChecksumChecks(iconf, entry_bool);
813 ? ConfigSetChecksumOffload(
814 iconf, DPDK_CONFIG_DEFAULT_CHECKSUM_VALIDATION_OFFLOAD)
815 : ConfigSetChecksumOffload(iconf, entry_bool);
822 ConfigSetVlanStrip(iconf, DPDK_CONFIG_DEFAULT_VLAN_STRIP);
824 ConfigSetVlanStrip(iconf, entry_bool);
834 if_root, if_default, dpdk_yaml.
copy_iface, ©_iface_str);
840 retval = ConfigSetCopyIfaceSettings(iconf, copy_iface_str, copy_mode_str);
847 static int32_t ConfigValidateThreads(uint16_t iface_threads)
849 static uint32_t total_cpus = 0;
850 total_cpus += iface_threads;
853 SCLogError(
"Specify worker-cpu-set list in the threading section");
857 SCLogError(
"Interfaces requested more cores than configured in the threading section "
858 "(requested %d configured %d",
875 retval = ConfigLoad(iconf, iface);
876 if (retval < 0 || ConfigValidateThreads(iconf->threads) != 0) {
877 iconf->DerefFunc(iconf);
884 static void DeviceSetPMDSpecificRSS(
struct rte_eth_rss_conf *rss_conf,
const char *driver_name)
887 if (strcmp(driver_name,
"net_i40e") == 0)
888 i40eDeviceSetRSSConf(rss_conf);
889 if (strcmp(driver_name,
"net_ice") == 0)
890 iceDeviceSetRSSConf(rss_conf);
891 if (strcmp(driver_name,
"net_ixgbe") == 0)
892 ixgbeDeviceSetRSSHashFunction(&rss_conf->rss_hf);
893 if (strcmp(driver_name,
"net_e1000_igb") == 0)
894 rss_conf->rss_hf = (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_IPV6_EX);
898 static int GetFirstSetBitPosition(uint64_t bits)
900 for (uint64_t i = 0; i < 64; i++) {
907 static void DumpRSSFlags(
const uint64_t requested,
const uint64_t actual)
912 "RTE_ETH_RSS_IP %sset", ((requested & RTE_ETH_RSS_IP) == RTE_ETH_RSS_IP) ?
"" :
"NOT ");
914 ((requested & RTE_ETH_RSS_TCP) == RTE_ETH_RSS_TCP) ?
"" :
"NOT ");
916 ((requested & RTE_ETH_RSS_UDP) == RTE_ETH_RSS_UDP) ?
"" :
"NOT ");
918 ((requested & RTE_ETH_RSS_SCTP) == RTE_ETH_RSS_SCTP) ?
"" :
"NOT ");
920 ((requested & RTE_ETH_RSS_TUNNEL) == RTE_ETH_RSS_TUNNEL) ?
"" :
"NOT ");
923 SCLogConfig(
"RTE_ETH_RSS_IPV4 (Bit position: %d) %sset",
924 GetFirstSetBitPosition(RTE_ETH_RSS_IPV4), (requested & RTE_ETH_RSS_IPV4) ?
"" :
"NOT ");
925 SCLogConfig(
"RTE_ETH_RSS_FRAG_IPV4 (Bit position: %d) %sset",
926 GetFirstSetBitPosition(RTE_ETH_RSS_FRAG_IPV4),
927 (requested & RTE_ETH_RSS_FRAG_IPV4) ?
"" :
"NOT ");
928 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_TCP (Bit position: %d) %sset",
929 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV4_TCP),
930 (requested & RTE_ETH_RSS_NONFRAG_IPV4_TCP) ?
"" :
"NOT ");
931 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_UDP (Bit position: %d) %sset",
932 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV4_UDP),
933 (requested & RTE_ETH_RSS_NONFRAG_IPV4_UDP) ?
"" :
"NOT ");
934 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_SCTP (Bit position: %d) %sset",
935 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV4_SCTP),
936 (requested & RTE_ETH_RSS_NONFRAG_IPV4_SCTP) ?
"" :
"NOT ");
937 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_OTHER (Bit position: %d) %sset",
938 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV4_OTHER),
939 (requested & RTE_ETH_RSS_NONFRAG_IPV4_OTHER) ?
"" :
"NOT ");
940 SCLogConfig(
"RTE_ETH_RSS_IPV6 (Bit position: %d) %sset",
941 GetFirstSetBitPosition(RTE_ETH_RSS_IPV6), (requested & RTE_ETH_RSS_IPV6) ?
"" :
"NOT ");
942 SCLogConfig(
"RTE_ETH_RSS_FRAG_IPV6 (Bit position: %d) %sset",
943 GetFirstSetBitPosition(RTE_ETH_RSS_FRAG_IPV6),
944 (requested & RTE_ETH_RSS_FRAG_IPV6) ?
"" :
"NOT ");
945 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_TCP (Bit position: %d) %sset",
946 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV6_TCP),
947 (requested & RTE_ETH_RSS_NONFRAG_IPV6_TCP) ?
"" :
"NOT ");
948 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_UDP (Bit position: %d) %sset",
949 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV6_UDP),
950 (requested & RTE_ETH_RSS_NONFRAG_IPV6_UDP) ?
"" :
"NOT ");
951 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_SCTP (Bit position: %d) %sset",
952 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV6_SCTP),
953 (requested & RTE_ETH_RSS_NONFRAG_IPV6_SCTP) ?
"" :
"NOT ");
954 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_OTHER (Bit position: %d) %sset",
955 GetFirstSetBitPosition(RTE_ETH_RSS_NONFRAG_IPV6_OTHER),
956 (requested & RTE_ETH_RSS_NONFRAG_IPV6_OTHER) ?
"" :
"NOT ");
958 SCLogConfig(
"RTE_ETH_RSS_L2_PAYLOAD (Bit position: %d) %sset",
959 GetFirstSetBitPosition(RTE_ETH_RSS_L2_PAYLOAD),
960 (requested & RTE_ETH_RSS_L2_PAYLOAD) ?
"" :
"NOT ");
961 SCLogConfig(
"RTE_ETH_RSS_IPV6_EX (Bit position: %d) %sset",
962 GetFirstSetBitPosition(RTE_ETH_RSS_IPV6_EX),
963 (requested & RTE_ETH_RSS_IPV6_EX) ?
"" :
"NOT ");
964 SCLogConfig(
"RTE_ETH_RSS_IPV6_TCP_EX (Bit position: %d) %sset",
965 GetFirstSetBitPosition(RTE_ETH_RSS_IPV6_TCP_EX),
966 (requested & RTE_ETH_RSS_IPV6_TCP_EX) ?
"" :
"NOT ");
967 SCLogConfig(
"RTE_ETH_RSS_IPV6_UDP_EX (Bit position: %d) %sset",
968 GetFirstSetBitPosition(RTE_ETH_RSS_IPV6_UDP_EX),
969 (requested & RTE_ETH_RSS_IPV6_UDP_EX) ?
"" :
"NOT ");
971 SCLogConfig(
"RTE_ETH_RSS_PORT (Bit position: %d) %sset",
972 GetFirstSetBitPosition(RTE_ETH_RSS_PORT), (requested & RTE_ETH_RSS_PORT) ?
"" :
"NOT ");
973 SCLogConfig(
"RTE_ETH_RSS_VXLAN (Bit position: %d) %sset",
974 GetFirstSetBitPosition(RTE_ETH_RSS_VXLAN),
975 (requested & RTE_ETH_RSS_VXLAN) ?
"" :
"NOT ");
976 SCLogConfig(
"RTE_ETH_RSS_NVGRE (Bit position: %d) %sset",
977 GetFirstSetBitPosition(RTE_ETH_RSS_NVGRE),
978 (requested & RTE_ETH_RSS_NVGRE) ?
"" :
"NOT ");
979 SCLogConfig(
"RTE_ETH_RSS_GTPU (Bit position: %d) %sset",
980 GetFirstSetBitPosition(RTE_ETH_RSS_GTPU), (requested & RTE_ETH_RSS_GTPU) ?
"" :
"NOT ");
982 SCLogConfig(
"RTE_ETH_RSS_L3_SRC_ONLY (Bit position: %d) %sset",
983 GetFirstSetBitPosition(RTE_ETH_RSS_L3_SRC_ONLY),
984 (requested & RTE_ETH_RSS_L3_SRC_ONLY) ?
"" :
"NOT ");
985 SCLogConfig(
"RTE_ETH_RSS_L3_DST_ONLY (Bit position: %d) %sset",
986 GetFirstSetBitPosition(RTE_ETH_RSS_L3_DST_ONLY),
987 (requested & RTE_ETH_RSS_L3_DST_ONLY) ?
"" :
"NOT ");
988 SCLogConfig(
"RTE_ETH_RSS_L4_SRC_ONLY (Bit position: %d) %sset",
989 GetFirstSetBitPosition(RTE_ETH_RSS_L4_SRC_ONLY),
990 (requested & RTE_ETH_RSS_L4_SRC_ONLY) ?
"" :
"NOT ");
991 SCLogConfig(
"RTE_ETH_RSS_L4_DST_ONLY (Bit position: %d) %sset",
992 GetFirstSetBitPosition(RTE_ETH_RSS_L4_DST_ONLY),
993 (requested & RTE_ETH_RSS_L4_DST_ONLY) ?
"" :
"NOT ");
996 "RTE_ETH_RSS_IP %sset", ((actual & RTE_ETH_RSS_IP) == RTE_ETH_RSS_IP) ?
"" :
"NOT ");
998 "RTE_ETH_RSS_TCP %sset", ((actual & RTE_ETH_RSS_TCP) == RTE_ETH_RSS_TCP) ?
"" :
"NOT ");
1000 "RTE_ETH_RSS_UDP %sset", ((actual & RTE_ETH_RSS_UDP) == RTE_ETH_RSS_UDP) ?
"" :
"NOT ");
1002 ((actual & RTE_ETH_RSS_SCTP) == RTE_ETH_RSS_SCTP) ?
"" :
"NOT ");
1004 ((actual & RTE_ETH_RSS_TUNNEL) == RTE_ETH_RSS_TUNNEL) ?
"" :
"NOT ");
1007 SCLogConfig(
"RTE_ETH_RSS_IPV4 %sset", (actual & RTE_ETH_RSS_IPV4) ?
"" :
"NOT ");
1008 SCLogConfig(
"RTE_ETH_RSS_FRAG_IPV4 %sset", (actual & RTE_ETH_RSS_FRAG_IPV4) ?
"" :
"NOT ");
1010 (actual & RTE_ETH_RSS_NONFRAG_IPV4_TCP) ?
"" :
"NOT ");
1012 (actual & RTE_ETH_RSS_NONFRAG_IPV4_UDP) ?
"" :
"NOT ");
1013 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_SCTP %sset",
1014 (actual & RTE_ETH_RSS_NONFRAG_IPV4_SCTP) ?
"" :
"NOT ");
1015 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV4_OTHER %sset",
1016 (actual & RTE_ETH_RSS_NONFRAG_IPV4_OTHER) ?
"" :
"NOT ");
1017 SCLogConfig(
"RTE_ETH_RSS_IPV6 %sset", (actual & RTE_ETH_RSS_IPV6) ?
"" :
"NOT ");
1018 SCLogConfig(
"RTE_ETH_RSS_FRAG_IPV6 %sset", (actual & RTE_ETH_RSS_FRAG_IPV6) ?
"" :
"NOT ");
1020 (actual & RTE_ETH_RSS_NONFRAG_IPV6_TCP) ?
"" :
"NOT ");
1022 (actual & RTE_ETH_RSS_NONFRAG_IPV6_UDP) ?
"" :
"NOT ");
1023 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_SCTP %sset",
1024 (actual & RTE_ETH_RSS_NONFRAG_IPV6_SCTP) ?
"" :
"NOT ");
1025 SCLogConfig(
"RTE_ETH_RSS_NONFRAG_IPV6_OTHER %sset",
1026 (actual & RTE_ETH_RSS_NONFRAG_IPV6_OTHER) ?
"" :
"NOT ");
1028 SCLogConfig(
"RTE_ETH_RSS_L2_PAYLOAD %sset", (actual & RTE_ETH_RSS_L2_PAYLOAD) ?
"" :
"NOT ");
1029 SCLogConfig(
"RTE_ETH_RSS_IPV6_EX %sset", (actual & RTE_ETH_RSS_IPV6_EX) ?
"" :
"NOT ");
1030 SCLogConfig(
"RTE_ETH_RSS_IPV6_TCP_EX %sset", (actual & RTE_ETH_RSS_IPV6_TCP_EX) ?
"" :
"NOT ");
1031 SCLogConfig(
"RTE_ETH_RSS_IPV6_UDP_EX %sset", (actual & RTE_ETH_RSS_IPV6_UDP_EX) ?
"" :
"NOT ");
1033 SCLogConfig(
"RTE_ETH_RSS_PORT %sset", (actual & RTE_ETH_RSS_PORT) ?
"" :
"NOT ");
1034 SCLogConfig(
"RTE_ETH_RSS_VXLAN %sset", (actual & RTE_ETH_RSS_VXLAN) ?
"" :
"NOT ");
1035 SCLogConfig(
"RTE_ETH_RSS_NVGRE %sset", (actual & RTE_ETH_RSS_NVGRE) ?
"" :
"NOT ");
1036 SCLogConfig(
"RTE_ETH_RSS_GTPU %sset", (actual & RTE_ETH_RSS_GTPU) ?
"" :
"NOT ");
1038 SCLogConfig(
"RTE_ETH_RSS_L3_SRC_ONLY %sset", (actual & RTE_ETH_RSS_L3_SRC_ONLY) ?
"" :
"NOT ");
1039 SCLogConfig(
"RTE_ETH_RSS_L3_DST_ONLY %sset", (actual & RTE_ETH_RSS_L3_DST_ONLY) ?
"" :
"NOT ");
1040 SCLogConfig(
"RTE_ETH_RSS_L4_SRC_ONLY %sset", (actual & RTE_ETH_RSS_L4_SRC_ONLY) ?
"" :
"NOT ");
1041 SCLogConfig(
"RTE_ETH_RSS_L4_DST_ONLY %sset", (actual & RTE_ETH_RSS_L4_DST_ONLY) ?
"" :
"NOT ");
1044 static void DumpRXOffloadCapabilities(
const uint64_t rx_offld_capa)
1046 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_VLAN_STRIP - %savailable",
1047 rx_offld_capa & RTE_ETH_RX_OFFLOAD_VLAN_STRIP ?
"" :
"NOT ");
1048 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_IPV4_CKSUM - %savailable",
1049 rx_offld_capa & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM ?
"" :
"NOT ");
1050 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_UDP_CKSUM - %savailable",
1051 rx_offld_capa & RTE_ETH_RX_OFFLOAD_UDP_CKSUM ?
"" :
"NOT ");
1052 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_TCP_CKSUM - %savailable",
1053 rx_offld_capa & RTE_ETH_RX_OFFLOAD_TCP_CKSUM ?
"" :
"NOT ");
1054 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_TCP_LRO - %savailable",
1055 rx_offld_capa & RTE_ETH_RX_OFFLOAD_TCP_LRO ?
"" :
"NOT ");
1056 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_QINQ_STRIP - %savailable",
1057 rx_offld_capa & RTE_ETH_RX_OFFLOAD_QINQ_STRIP ?
"" :
"NOT ");
1058 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM - %savailable",
1059 rx_offld_capa & RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM ?
"" :
"NOT ");
1060 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_MACSEC_STRIP - %savailable",
1061 rx_offld_capa & RTE_ETH_RX_OFFLOAD_MACSEC_STRIP ?
"" :
"NOT ");
1062 #if RTE_VERSION < RTE_VERSION_NUM(22, 11, 0, 0)
1063 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_HEADER_SPLIT - %savailable",
1064 rx_offld_capa & RTE_ETH_RX_OFFLOAD_HEADER_SPLIT ?
"" :
"NOT ");
1066 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_VLAN_FILTER - %savailable",
1067 rx_offld_capa & RTE_ETH_RX_OFFLOAD_VLAN_FILTER ?
"" :
"NOT ");
1068 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_VLAN_EXTEND - %savailable",
1069 rx_offld_capa & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND ?
"" :
"NOT ");
1070 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_SCATTER - %savailable",
1071 rx_offld_capa & RTE_ETH_RX_OFFLOAD_SCATTER ?
"" :
"NOT ");
1072 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_TIMESTAMP - %savailable",
1073 rx_offld_capa & RTE_ETH_RX_OFFLOAD_TIMESTAMP ?
"" :
"NOT ");
1074 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_SECURITY - %savailable",
1075 rx_offld_capa & RTE_ETH_RX_OFFLOAD_SECURITY ?
"" :
"NOT ");
1076 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_KEEP_CRC - %savailable",
1077 rx_offld_capa & RTE_ETH_RX_OFFLOAD_KEEP_CRC ?
"" :
"NOT ");
1078 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_SCTP_CKSUM - %savailable",
1079 rx_offld_capa & RTE_ETH_RX_OFFLOAD_SCTP_CKSUM ?
"" :
"NOT ");
1080 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_OUTER_UDP_CKSUM - %savailable",
1081 rx_offld_capa & RTE_ETH_RX_OFFLOAD_OUTER_UDP_CKSUM ?
"" :
"NOT ");
1082 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_RSS_HASH - %savailable",
1083 rx_offld_capa & RTE_ETH_RX_OFFLOAD_RSS_HASH ?
"" :
"NOT ");
1084 #if RTE_VERSION >= RTE_VERSION_NUM(20, 11, 0, 0)
1085 SCLogConfig(
"RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT - %savailable",
1086 rx_offld_capa & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT ?
"" :
"NOT ");
1090 static int DeviceValidateMTU(
const DPDKIfaceConfig *iconf,
const struct rte_eth_dev_info *dev_info)
1093 if (iconf->mtu > dev_info->max_mtu || iconf->mtu < dev_info->min_mtu) {
1095 "Min MTU: %" PRIu16
" Max MTU: %" PRIu16,
1096 iconf->iface, dev_info->min_mtu, dev_info->max_mtu);
1100 #if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0)
1102 if (iconf->mtu > RTE_ETHER_MAX_LEN &&
1103 !(dev_info->rx_offload_capa & DEV_RX_OFFLOAD_JUMBO_FRAME)) {
1104 SCLogError(
"%s: jumbo frames not supported, set MTU to 1500", iconf->iface);
1112 static void DeviceSetMTU(
struct rte_eth_conf *port_conf, uint16_t mtu)
1114 #if RTE_VERSION >= RTE_VERSION_NUM(21, 11, 0, 0)
1115 port_conf->rxmode.mtu = mtu;
1117 port_conf->rxmode.max_rx_pkt_len = mtu;
1118 if (mtu > RTE_ETHER_MAX_LEN) {
1119 port_conf->rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
1129 static int32_t DeviceSetSocketID(uint16_t port_id, int32_t *socket_id)
1132 int retval = rte_eth_dev_socket_id(port_id);
1133 *socket_id = retval;
1135 #if RTE_VERSION >= RTE_VERSION_NUM(22, 11, 0, 0) // DPDK API changed since 22.11
1136 retval = -rte_errno;
1138 if (retval == SOCKET_ID_ANY)
1145 static void PortConfSetInterruptMode(
const DPDKIfaceConfig *iconf,
struct rte_eth_conf *port_conf)
1147 SCLogConfig(
"%s: interrupt mode is %s", iconf->iface,
1150 port_conf->intr_conf.rxq = 1;
1154 const struct rte_eth_dev_info *dev_info,
struct rte_eth_conf *port_conf)
1156 if (dev_info->rx_offload_capa & RTE_ETH_RX_OFFLOAD_RSS_HASH) {
1157 if (iconf->nb_rx_queues > 1) {
1158 SCLogConfig(
"%s: RSS enabled for %d queues", iconf->iface, iconf->nb_rx_queues);
1159 port_conf->rx_adv_conf.rss_conf = (
struct rte_eth_rss_conf){
1160 .rss_key = rss_hkey,
1161 .rss_key_len = RSS_HKEY_LEN,
1162 .rss_hf = iconf->rss_hf,
1165 const char *dev_driver = dev_info->driver_name;
1166 if (strcmp(dev_info->driver_name,
"net_bonding") == 0) {
1167 dev_driver = BondingDeviceDriverGet(iconf->port_id);
1170 DeviceSetPMDSpecificRSS(&port_conf->rx_adv_conf.rss_conf, dev_driver);
1172 uint64_t rss_hf_tmp =
1173 port_conf->rx_adv_conf.rss_conf.rss_hf & dev_info->flow_type_rss_offloads;
1174 if (port_conf->rx_adv_conf.rss_conf.rss_hf != rss_hf_tmp) {
1175 DumpRSSFlags(port_conf->rx_adv_conf.rss_conf.rss_hf, rss_hf_tmp);
1177 SCLogWarning(
"%s: modified RSS hash function based on hardware support: "
1178 "requested:%#" PRIx64
", configured:%#" PRIx64,
1179 iconf->iface, port_conf->rx_adv_conf.rss_conf.rss_hf, rss_hf_tmp);
1180 port_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf_tmp;
1182 port_conf->rxmode.mq_mode = RTE_ETH_MQ_RX_RSS;
1185 port_conf->rx_adv_conf.rss_conf.rss_key = NULL;
1186 port_conf->rx_adv_conf.rss_conf.rss_hf = 0;
1189 SCLogConfig(
"%s: RSS not supported", iconf->iface);
1194 const struct rte_eth_dev_info *dev_info,
struct rte_eth_conf *port_conf)
1197 SCLogConfig(
"%s: checksum validation disabled", iconf->iface);
1198 }
else if ((dev_info->rx_offload_capa & RTE_ETH_RX_OFFLOAD_CHECKSUM) ==
1199 RTE_ETH_RX_OFFLOAD_CHECKSUM) {
1202 SCLogConfig(
"%s: IP, TCP and UDP checksum validation offloaded", iconf->iface);
1203 port_conf->rxmode.offloads |= RTE_ETH_RX_OFFLOAD_CHECKSUM;
1206 SCLogConfig(
"%s: checksum validation enabled (but can be offloaded)", iconf->iface);
1212 const struct rte_eth_dev_info *dev_info,
struct rte_eth_conf *port_conf)
1214 if (iconf->vlan_strip_enabled) {
1215 if (dev_info->rx_offload_capa & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
1216 port_conf->rxmode.offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
1217 SCLogConfig(
"%s: hardware VLAN stripping enabled", iconf->iface);
1219 SCLogWarning(
"%s: hardware VLAN stripping enabled but not supported, disabling",
1226 const struct rte_eth_dev_info *dev_info,
struct rte_eth_conf *port_conf)
1228 DumpRXOffloadCapabilities(dev_info->rx_offload_capa);
1229 *port_conf = (
struct rte_eth_conf){
1231 .mq_mode = RTE_ETH_MQ_RX_NONE,
1235 .mq_mode = RTE_ETH_MQ_TX_NONE,
1240 PortConfSetInterruptMode(iconf, port_conf);
1243 PortConfSetRSSConf(iconf, dev_info, port_conf);
1244 PortConfSetChsumOffload(iconf, dev_info, port_conf);
1245 DeviceSetMTU(port_conf, iconf->mtu);
1246 PortConfSetVlanOffload(iconf, dev_info, port_conf);
1248 if (dev_info->tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) {
1249 port_conf->txmode.offloads |= RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
1253 static int DeviceConfigureQueues(
DPDKIfaceConfig *iconf,
const struct rte_eth_dev_info *dev_info,
1254 const struct rte_eth_conf *port_conf)
1260 struct rte_eth_rxconf rxq_conf;
1261 struct rte_eth_txconf txq_conf;
1263 char mempool_name[64];
1264 snprintf(mempool_name, 64,
"mempool_%.20s", iconf->iface);
1266 mtu_size = iconf->mtu + RTE_ETHER_CRC_LEN + RTE_ETHER_HDR_LEN + 4;
1267 mbuf_size = ROUNDUP(mtu_size, 1024) + RTE_PKTMBUF_HEADROOM;
1268 SCLogConfig(
"%s: creating packet mbuf pool %s of size %d, cache size %d, mbuf size %d",
1269 iconf->iface, mempool_name, iconf->mempool_size, iconf->mempool_cache_size, mbuf_size);
1271 iconf->pkt_mempool = rte_pktmbuf_pool_create(mempool_name, iconf->mempool_size,
1272 iconf->mempool_cache_size, 0, mbuf_size, (
int)iconf->socket_id);
1273 if (iconf->pkt_mempool == NULL) {
1274 retval = -rte_errno;
1275 SCLogError(
"%s: rte_pktmbuf_pool_create failed with code %d (mempool: %s): %s",
1276 iconf->iface, rte_errno, mempool_name, rte_strerror(rte_errno));
1280 for (uint16_t queue_id = 0; queue_id < iconf->nb_rx_queues; queue_id++) {
1281 rxq_conf = dev_info->default_rxconf;
1282 rxq_conf.offloads = port_conf->rxmode.offloads;
1283 rxq_conf.rx_thresh.hthresh = 0;
1284 rxq_conf.rx_thresh.pthresh = 0;
1285 rxq_conf.rx_thresh.wthresh = 0;
1286 rxq_conf.rx_free_thresh = 0;
1287 rxq_conf.rx_drop_en = 0;
1288 SCLogConfig(
"%s: setting up RX queue %d: rx_desc: %u offloads: 0x%" PRIx64
1289 " hthresh: %" PRIu8
" pthresh: %" PRIu8
" wthresh: %" PRIu8
1290 " free_thresh: %" PRIu16
" drop_en: %" PRIu8,
1291 iconf->iface, queue_id, iconf->nb_rx_desc, rxq_conf.offloads,
1292 rxq_conf.rx_thresh.hthresh, rxq_conf.rx_thresh.pthresh, rxq_conf.rx_thresh.wthresh,
1293 rxq_conf.rx_free_thresh, rxq_conf.rx_drop_en);
1295 retval = rte_eth_rx_queue_setup(iconf->port_id, queue_id, iconf->nb_rx_desc,
1296 iconf->socket_id, &rxq_conf, iconf->pkt_mempool);
1298 rte_mempool_free(iconf->pkt_mempool);
1299 SCLogError(
"%s: failed to setup RX queue %u: %s", iconf->iface, queue_id,
1300 rte_strerror(-retval));
1305 for (uint16_t queue_id = 0; queue_id < iconf->nb_tx_queues; queue_id++) {
1306 txq_conf = dev_info->default_txconf;
1307 txq_conf.offloads = port_conf->txmode.offloads;
1308 SCLogConfig(
"%s: setting up TX queue %d: tx_desc: %" PRIu16
" tx: offloads: 0x%" PRIx64
1309 " hthresh: %" PRIu8
" pthresh: %" PRIu8
" wthresh: %" PRIu8
1310 " tx_free_thresh: %" PRIu16
" tx_rs_thresh: %" PRIu16
1311 " txq_deferred_start: %" PRIu8,
1312 iconf->iface, queue_id, iconf->nb_tx_desc, txq_conf.offloads,
1313 txq_conf.tx_thresh.hthresh, txq_conf.tx_thresh.pthresh, txq_conf.tx_thresh.wthresh,
1314 txq_conf.tx_free_thresh, txq_conf.tx_rs_thresh, txq_conf.tx_deferred_start);
1315 retval = rte_eth_tx_queue_setup(
1316 iconf->port_id, queue_id, iconf->nb_tx_desc, iconf->socket_id, &txq_conf);
1318 rte_mempool_free(iconf->pkt_mempool);
1319 SCLogError(
"%s: failed to setup TX queue %u: %s", iconf->iface, queue_id,
1320 rte_strerror(-retval));
1333 ConfigInit(&out_iconf);
1334 if (out_iconf == NULL) {
1335 FatalError(
"Copy interface of the interface \"%s\" is NULL", iconf->iface);
1338 retval = ConfigLoad(out_iconf, iconf->out_iface);
1340 SCLogError(
"%s: fail to load config of interface", iconf->out_iface);
1341 out_iconf->DerefFunc(out_iconf);
1345 if (iconf->nb_rx_queues != out_iconf->nb_tx_queues) {
1347 SCLogError(
"%s: configured %d RX queues but copy interface %s has %d TX queues"
1348 " - number of queues must be equal",
1349 iconf->iface, iconf->nb_rx_queues, out_iconf->iface, out_iconf->nb_tx_queues);
1350 out_iconf->DerefFunc(out_iconf);
1352 }
else if (iconf->mtu != out_iconf->mtu) {
1353 SCLogError(
"%s: configured MTU of %d but copy interface %s has MTU set to %d"
1354 " - MTU must be equal",
1355 iconf->iface, iconf->mtu, out_iconf->iface, out_iconf->mtu);
1356 out_iconf->DerefFunc(out_iconf);
1358 }
else if (iconf->copy_mode != out_iconf->copy_mode) {
1359 SCLogError(
"%s: copy modes of interfaces %s and %s are not equal", iconf->iface,
1360 iconf->iface, out_iconf->iface);
1361 out_iconf->DerefFunc(out_iconf);
1363 }
else if (strcmp(iconf->iface, out_iconf->out_iface) != 0) {
1365 SCLogError(
"%s: copy interface of %s is not set to %s", iconf->iface, out_iconf->iface,
1367 out_iconf->DerefFunc(out_iconf);
1371 out_iconf->DerefFunc(out_iconf);
1378 if (iconf->out_iface != NULL) {
1379 if (!rte_eth_dev_is_valid_port(iconf->out_port_id)) {
1380 SCLogError(
"%s: retrieved copy interface port ID \"%d\" is invalid or the device is "
1382 iconf->iface, iconf->out_port_id);
1385 int32_t out_port_socket_id;
1386 int retval = DeviceSetSocketID(iconf->out_port_id, &out_port_socket_id);
1388 SCLogError(
"%s: invalid socket id: %s", iconf->out_iface, rte_strerror(-retval));
1392 if (iconf->socket_id != out_port_socket_id) {
1394 "%s: out iface %s is not on the same NUMA node (%s - NUMA %d, %s - NUMA %d)",
1395 iconf->iface, iconf->out_iface, iconf->iface, iconf->socket_id,
1396 iconf->out_iface, out_port_socket_id);
1399 retval = DeviceValidateOutIfaceConfig(iconf);
1406 SCLogInfo(
"%s: DPDK IPS mode activated: %s->%s", iconf->iface, iconf->iface,
1409 SCLogInfo(
"%s: DPDK TAP mode activated: %s->%s", iconf->iface, iconf->iface,
1423 static int32_t DeviceVerifyPostConfigure(
1424 const DPDKIfaceConfig *iconf,
const struct rte_eth_dev_info *dev_info)
1427 struct rte_eth_dev_info post_conf_dev_info = { 0 };
1428 int32_t ret = rte_eth_dev_info_get(iconf->port_id, &post_conf_dev_info);
1430 SCLogError(
"%s: getting device info failed: %s", iconf->iface, rte_strerror(-ret));
1434 if (dev_info->flow_type_rss_offloads != post_conf_dev_info.flow_type_rss_offloads ||
1435 dev_info->rx_offload_capa != post_conf_dev_info.rx_offload_capa ||
1436 dev_info->tx_offload_capa != post_conf_dev_info.tx_offload_capa ||
1437 dev_info->max_rx_queues != post_conf_dev_info.max_rx_queues ||
1438 dev_info->max_tx_queues != post_conf_dev_info.max_tx_queues ||
1439 dev_info->max_mtu != post_conf_dev_info.max_mtu) {
1440 SCLogWarning(
"%s: device information severely changed after configuration, reconfiguring",
1445 if (strcmp(dev_info->driver_name,
"net_bonding") == 0) {
1446 ret = BondingAllDevicesSameDriver(iconf->port_id);
1448 SCLogError(
"%s: bond port uses port with different DPDK drivers", iconf->iface);
1459 if (!rte_eth_dev_is_valid_port(iconf->port_id)) {
1460 SCLogError(
"%s: retrieved port ID \"%d\" is invalid or the device is not attached ",
1461 iconf->iface, iconf->port_id);
1465 int32_t retval = DeviceSetSocketID(iconf->port_id, &iconf->socket_id);
1467 SCLogError(
"%s: invalid socket id: %s", iconf->iface, rte_strerror(-retval));
1471 struct rte_eth_dev_info dev_info = { 0 };
1472 retval = rte_eth_dev_info_get(iconf->port_id, &dev_info);
1474 SCLogError(
"%s: getting device info failed: %s", iconf->iface, rte_strerror(-retval));
1478 if (iconf->nb_rx_queues > dev_info.max_rx_queues) {
1479 SCLogError(
"%s: configured RX queues %u is higher than device maximum (%" PRIu16
")",
1480 iconf->iface, iconf->nb_rx_queues, dev_info.max_rx_queues);
1484 if (iconf->nb_tx_queues > dev_info.max_tx_queues) {
1485 SCLogError(
"%s: configured TX queues %u is higher than device maximum (%" PRIu16
")",
1486 iconf->iface, iconf->nb_tx_queues, dev_info.max_tx_queues);
1490 retval = DeviceValidateMTU(iconf, &dev_info);
1494 struct rte_eth_conf port_conf = { 0 };
1495 DeviceInitPortConf(iconf, &dev_info, &port_conf);
1496 if (port_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_CHECKSUM) {
1501 retval = rte_eth_dev_configure(
1502 iconf->port_id, iconf->nb_rx_queues, iconf->nb_tx_queues, &port_conf);
1504 SCLogError(
"%s: failed to configure the device: %s", iconf->iface, rte_strerror(-retval));
1508 retval = DeviceVerifyPostConfigure(iconf, &dev_info);
1512 uint16_t tmp_nb_rx_desc = iconf->nb_rx_desc;
1513 uint16_t tmp_nb_tx_desc = iconf->nb_tx_desc;
1514 retval = rte_eth_dev_adjust_nb_rx_tx_desc(
1515 iconf->port_id, &iconf->nb_rx_desc, &iconf->nb_tx_desc);
1517 SCLogError(
"%s: failed to adjust device queue descriptors: %s", iconf->iface,
1518 rte_strerror(-retval));
1520 }
else if (tmp_nb_rx_desc != iconf->nb_rx_desc || tmp_nb_tx_desc != iconf->nb_tx_desc) {
1521 SCLogWarning(
"%s: device queue descriptors adjusted (RX: from %u to %u, TX: from %u to %u)",
1522 iconf->iface, tmp_nb_rx_desc, iconf->nb_rx_desc, tmp_nb_tx_desc, iconf->nb_tx_desc);
1525 retval = iconf->flags &
DPDK_MULTICAST ? rte_eth_allmulticast_enable(iconf->port_id)
1526 : rte_eth_allmulticast_disable(iconf->port_id);
1527 if (retval == -ENOTSUP) {
1528 retval = rte_eth_allmulticast_get(iconf->port_id);
1532 SCLogWarning(
"%s: cannot configure allmulticast, the port is %sin allmulticast mode",
1533 iconf->iface, retval == 1 ?
"" :
"not ");
1534 }
else if (retval < 0) {
1535 SCLogError(
"%s: failed to get multicast mode: %s", iconf->iface, rte_strerror(-retval));
1538 }
else if (retval < 0) {
1539 SCLogError(
"%s: error when changing multicast setting: %s", iconf->iface,
1540 rte_strerror(-retval));
1544 retval = iconf->flags &
DPDK_PROMISC ? rte_eth_promiscuous_enable(iconf->port_id)
1545 : rte_eth_promiscuous_disable(iconf->port_id);
1546 if (retval == -ENOTSUP) {
1547 retval = rte_eth_promiscuous_get(iconf->port_id);
1550 SCLogError(
"%s: cannot configure promiscuous mode, the port is in %spromiscuous mode",
1551 iconf->iface, retval == 1 ?
"" :
"non-");
1553 }
else if (retval < 0) {
1555 "%s: failed to get promiscuous mode: %s", iconf->iface, rte_strerror(-retval));
1558 }
else if (retval < 0) {
1559 SCLogError(
"%s: error when changing promiscuous setting: %s", iconf->iface,
1560 rte_strerror(-retval));
1565 SCLogConfig(
"%s: setting MTU to %d", iconf->iface, iconf->mtu);
1566 retval = rte_eth_dev_set_mtu(iconf->port_id, iconf->mtu);
1567 if (retval == -ENOTSUP) {
1569 retval = rte_eth_dev_get_mtu(iconf->port_id, &iconf->mtu);
1571 SCLogError(
"%s: failed to retrieve MTU: %s", iconf->iface, rte_strerror(-retval));
1575 "%s: changing MTU is not supported, current MTU: %u", iconf->iface, iconf->mtu);
1576 }
else if (retval < 0) {
1578 "%s: failed to set MTU to %u: %s", iconf->iface, iconf->mtu, rte_strerror(-retval));
1582 retval = DeviceConfigureQueues(iconf, &dev_info, &port_conf);
1587 retval = DeviceConfigureIPS(iconf);
1595 static void *ParseDpdkConfigAndConfigureDevice(
const char *iface)
1599 if (iconf == NULL) {
1600 FatalError(
"DPDK configuration could not be parsed");
1603 retval = DeviceConfigure(iconf);
1604 if (retval == -EAGAIN) {
1606 retval = DeviceConfigure(iconf);
1610 iconf->DerefFunc(iconf);
1611 if (rte_eal_cleanup() != 0)
1612 FatalError(
"EAL cleanup failed: %s", rte_strerror(-retval));
1614 if (retval == -ENOMEM) {
1615 FatalError(
"%s: memory allocation failed - consider"
1616 "%s freeing up some memory.",
1618 rte_eal_has_hugepages() != 0 ?
" increasing the number of hugepages or" :
"");
1620 FatalError(
"%s: failed to configure", iface);
1629 iconf->workers_sync =
SCCalloc(1,
sizeof(*iconf->workers_sync));
1630 if (iconf->workers_sync == NULL) {
1631 FatalError(
"Failed to allocate memory for workers_sync");
1634 iconf->workers_sync->worker_cnt = iconf->threads;
1638 if (ldev_instance == NULL) {
1639 FatalError(
"Device %s is not registered as a live device", iface);
1641 ldev_instance->dpdk_vars.pkt_mp = iconf->pkt_mempool;
1658 static int DPDKConfigGetThreadsCount(
void *conf)
1664 return dpdk_conf->threads;
1669 static int DPDKRunModeIsIPS(
void)
1672 const char dpdk_node_query[] =
"dpdk.interfaces";
1674 if (dpdk_node == NULL) {
1675 FatalError(
"Unable to get %s configuration node", dpdk_node_query);
1678 const char default_iface[] =
"default";
1681 bool has_ips =
false;
1682 bool has_ids =
false;
1683 for (
int ldev = 0; ldev < nlive; ldev++) {
1685 if (live_dev == NULL)
1686 FatalError(
"Unable to get device id %d from LiveDevice list", ldev);
1689 if (if_root == NULL) {
1690 if (if_default == NULL)
1691 FatalError(
"Unable to get %s or %s interface", live_dev, default_iface);
1693 if_root = if_default;
1696 const char *copymodestr = NULL;
1697 const char *copyifacestr = NULL;
1700 if (strcmp(copymodestr,
"ips") == 0) {
1709 if (has_ids && has_ips) {
1710 FatalError(
"Copy-mode of interface %s mixes with the previously set copy-modes "
1711 "(only IDS/TAP and IPS copy-mode combinations are allowed in DPDK",
1719 static int DPDKRunModeEnableIPS(
void)
1721 int r = DPDKRunModeIsIPS();
1737 "Workers DPDK mode, each thread does all"
1738 " tasks from acquisition to logging",
1763 SCLogDebug(
"RunModeIdsDpdkWorkers initialised");