dpdk: allow zero TX queues when running in IDS mode

When running in non-forwarding (IDS) mode, it is not required
to create TX queues for the interface.
This can be acheived by setting tx-descriptors configuration
field to 0.

Ticket: 7633
pull/12888/head
Lukas Sismis 3 months ago committed by Victor Julien
parent 1be1c65b6e
commit 4f2ce17dc5

@ -2263,6 +2263,10 @@ Individual Suricata workers then poll packets from the NIC queues.
Internally, DPDK runmode uses a `symmetric hash (0x6d5a) Internally, DPDK runmode uses a `symmetric hash (0x6d5a)
<https://www.ran-lifshitz.com/2014/08/28/symmetric-rss-receive-side-scaling/>`_ <https://www.ran-lifshitz.com/2014/08/28/symmetric-rss-receive-side-scaling/>`_
that redirects bi-flows to specific workers. that redirects bi-flows to specific workers.
Each worker operates on 1 RX (and 1 TX) queue. The number of RX queues is always
equal to the number of threads/workers. The number of TX queues is the same as
the number of RX queues or can be set to 0 if Suricata runs in IDS mode by
configuring ``tx-descriptors`` to 0 or ``auto`` in the interface configuration node.
Before Suricata can be run, it is required to allocate a sufficient number of Before Suricata can be run, it is required to allocate a sufficient number of
hugepages. For efficiency, hugepages are continuous chunks of memory (pages) hugepages. For efficiency, hugepages are continuous chunks of memory (pages)

@ -79,11 +79,13 @@ static void InitEal(void);
static void ConfigSetIface(DPDKIfaceConfig *iconf, const char *entry_str); static void ConfigSetIface(DPDKIfaceConfig *iconf, const char *entry_str);
static int ConfigSetThreads(DPDKIfaceConfig *iconf, const char *entry_str); static int ConfigSetThreads(DPDKIfaceConfig *iconf, const char *entry_str);
static int ConfigSetRxQueues(DPDKIfaceConfig *iconf, uint16_t nb_queues, uint16_t max_queues); static int ConfigSetRxQueues(DPDKIfaceConfig *iconf, uint16_t nb_queues, uint16_t max_queues);
static int ConfigSetTxQueues(DPDKIfaceConfig *iconf, uint16_t nb_queues, uint16_t max_queues); static int ConfigSetTxQueues(
DPDKIfaceConfig *iconf, uint16_t nb_queues, uint16_t max_queues, bool iface_sends_pkts);
static int ConfigSetMempoolSize(DPDKIfaceConfig *iconf, const char *entry_str); static int ConfigSetMempoolSize(DPDKIfaceConfig *iconf, const char *entry_str);
static int ConfigSetMempoolCacheSize(DPDKIfaceConfig *iconf, const char *entry_str); static int ConfigSetMempoolCacheSize(DPDKIfaceConfig *iconf, const char *entry_str);
static int ConfigSetRxDescriptors(DPDKIfaceConfig *iconf, const char *entry_str, uint16_t max_desc); static int ConfigSetRxDescriptors(DPDKIfaceConfig *iconf, const char *entry_str, uint16_t max_desc);
static int ConfigSetTxDescriptors(DPDKIfaceConfig *iconf, const char *entry_str, uint16_t max_desc); static int ConfigSetTxDescriptors(
DPDKIfaceConfig *iconf, const char *entry_str, uint16_t max_desc, bool iface_sends_pkts);
static int ConfigSetMtu(DPDKIfaceConfig *iconf, intmax_t entry_int); static int ConfigSetMtu(DPDKIfaceConfig *iconf, intmax_t entry_int);
static bool ConfigSetPromiscuousMode(DPDKIfaceConfig *iconf, int entry_bool); static bool ConfigSetPromiscuousMode(DPDKIfaceConfig *iconf, int entry_bool);
static bool ConfigSetMulticast(DPDKIfaceConfig *iconf, int entry_bool); static bool ConfigSetMulticast(DPDKIfaceConfig *iconf, int entry_bool);
@ -483,10 +485,20 @@ static int ConfigSetRxQueues(DPDKIfaceConfig *iconf, uint16_t nb_queues, uint16_
SCReturnInt(0); SCReturnInt(0);
} }
static int ConfigSetTxQueues(DPDKIfaceConfig *iconf, uint16_t nb_queues, uint16_t max_queues) static bool ConfigIfaceSendsPkts(const char *mode)
{ {
SCEnter(); SCEnter();
if (nb_queues == 0) { if (strcmp(mode, "ips") == 0 || strcmp(mode, "tap") == 0) {
SCReturnBool(true);
}
SCReturnBool(false);
}
static int ConfigSetTxQueues(
DPDKIfaceConfig *iconf, uint16_t nb_queues, uint16_t max_queues, bool iface_sends_pkts)
{
SCEnter();
if (nb_queues == 0 && iface_sends_pkts) {
SCLogInfo("%s: positive number of TX queues is required", iconf->iface); SCLogInfo("%s: positive number of TX queues is required", iconf->iface);
SCReturnInt(-ERANGE); SCReturnInt(-ERANGE);
} }
@ -631,7 +643,8 @@ static int ConfigSetRxDescriptors(DPDKIfaceConfig *iconf, const char *entry_str,
SCReturnInt(0); SCReturnInt(0);
} }
static int ConfigSetTxDescriptors(DPDKIfaceConfig *iconf, const char *entry_str, uint16_t max_desc) static int ConfigSetTxDescriptors(
DPDKIfaceConfig *iconf, const char *entry_str, uint16_t max_desc, bool iface_sends_pkts)
{ {
SCEnter(); SCEnter();
if (entry_str == NULL || entry_str[0] == '\0') { if (entry_str == NULL || entry_str[0] == '\0') {
@ -641,7 +654,11 @@ static int ConfigSetTxDescriptors(DPDKIfaceConfig *iconf, const char *entry_str,
} }
if (strcmp(entry_str, "auto") == 0) { if (strcmp(entry_str, "auto") == 0) {
iconf->nb_tx_desc = GreatestPowOf2UpTo(max_desc); if (iface_sends_pkts) {
iconf->nb_tx_desc = GreatestPowOf2UpTo(max_desc);
} else {
iconf->nb_tx_desc = 0;
}
SCReturnInt(0); SCReturnInt(0);
} }
@ -651,7 +668,7 @@ static int ConfigSetTxDescriptors(DPDKIfaceConfig *iconf, const char *entry_str,
SCReturnInt(-EINVAL); SCReturnInt(-EINVAL);
} }
if (iconf->nb_tx_desc == 0) { if (iconf->nb_tx_desc == 0 && iface_sends_pkts) {
SCLogError("%s: positive number of TX descriptors is required", iconf->iface); SCLogError("%s: positive number of TX descriptors is required", iconf->iface);
SCReturnInt(-ERANGE); SCReturnInt(-ERANGE);
} else if (iconf->nb_tx_desc > max_desc) { } else if (iconf->nb_tx_desc > max_desc) {
@ -866,20 +883,9 @@ static int ConfigLoad(DPDKIfaceConfig *iconf, const char *iface)
if (retval != true) if (retval != true)
SCReturnInt(-EINVAL); SCReturnInt(-EINVAL);
// currently only mapping "1 thread == 1 RX (and 1 TX queue in IPS mode)" is supported retval = ConfGetChildValueWithDefault(if_root, if_default, dpdk_yaml.copy_mode, &copy_mode_str);
retval = ConfigSetRxQueues(iconf, (uint16_t)iconf->threads, dev_info.max_rx_queues); if (retval != 1) {
if (retval < 0) { copy_mode_str = DPDK_CONFIG_DEFAULT_COPY_MODE;
SCLogError("%s: too many threads configured - reduce thread count to: %" PRIu16,
iconf->iface, dev_info.max_rx_queues);
SCReturnInt(retval);
}
// currently only mapping "1 thread == 1 RX (and 1 TX queue in IPS mode)" is supported
retval = ConfigSetTxQueues(iconf, (uint16_t)iconf->threads, dev_info.max_tx_queues);
if (retval < 0) {
SCLogError("%s: too many threads configured - reduce thread count to: %" PRIu16,
iconf->iface, dev_info.max_tx_queues);
SCReturnInt(retval);
} }
retval = ConfGetChildValueWithDefault( retval = ConfGetChildValueWithDefault(
@ -890,14 +896,33 @@ static int ConfigLoad(DPDKIfaceConfig *iconf, const char *iface)
if (retval < 0) if (retval < 0)
SCReturnInt(retval); SCReturnInt(retval);
bool iface_sends_pkts = ConfigIfaceSendsPkts(copy_mode_str);
retval = ConfGetChildValueWithDefault( retval = ConfGetChildValueWithDefault(
if_root, if_default, dpdk_yaml.tx_descriptors, &entry_str) != 1 if_root, if_default, dpdk_yaml.tx_descriptors, &entry_str) != 1
? ConfigSetTxDescriptors(iconf, DPDK_CONFIG_DEFAULT_TX_DESCRIPTORS, ? ConfigSetTxDescriptors(iconf, DPDK_CONFIG_DEFAULT_TX_DESCRIPTORS,
dev_info.tx_desc_lim.nb_max) dev_info.tx_desc_lim.nb_max, iface_sends_pkts)
: ConfigSetTxDescriptors(iconf, entry_str, dev_info.tx_desc_lim.nb_max); : ConfigSetTxDescriptors(
iconf, entry_str, dev_info.tx_desc_lim.nb_max, iface_sends_pkts);
if (retval < 0) if (retval < 0)
SCReturnInt(retval); SCReturnInt(retval);
// currently only mapping "1 thread == 1 RX (and 1 TX queue in IPS mode)" is supported
retval = ConfigSetRxQueues(iconf, (uint16_t)iconf->threads, dev_info.max_rx_queues);
if (retval < 0) {
SCLogError("%s: too many threads configured - reduce thread count to: %" PRIu16,
iconf->iface, dev_info.max_rx_queues);
SCReturnInt(retval);
}
// currently only mapping "1 thread == 1 RX (and 1 TX queue in IPS mode)" is supported
uint16_t tx_queues = iconf->nb_tx_desc > 0 ? (uint16_t)iconf->threads : 0;
retval = ConfigSetTxQueues(iconf, tx_queues, dev_info.max_tx_queues, iface_sends_pkts);
if (retval < 0) {
SCLogError("%s: too many threads configured - reduce thread count to: %" PRIu16,
iconf->iface, dev_info.max_tx_queues);
SCReturnInt(retval);
}
retval = ConfGetChildValueWithDefault( retval = ConfGetChildValueWithDefault(
if_root, if_default, dpdk_yaml.mempool_size, &entry_str) != 1 if_root, if_default, dpdk_yaml.mempool_size, &entry_str) != 1
? ConfigSetMempoolSize(iconf, DPDK_CONFIG_DEFAULT_MEMPOOL_SIZE) ? ConfigSetMempoolSize(iconf, DPDK_CONFIG_DEFAULT_MEMPOOL_SIZE)
@ -968,11 +993,6 @@ static int ConfigLoad(DPDKIfaceConfig *iconf, const char *iface)
if (retval < 0) if (retval < 0)
SCReturnInt(retval); SCReturnInt(retval);
retval = ConfGetChildValueWithDefault(if_root, if_default, dpdk_yaml.copy_mode, &copy_mode_str);
if (retval != 1) {
copy_mode_str = DPDK_CONFIG_DEFAULT_COPY_MODE;
}
retval = ConfGetChildValueWithDefault( retval = ConfGetChildValueWithDefault(
if_root, if_default, dpdk_yaml.copy_iface, &copy_iface_str); if_root, if_default, dpdk_yaml.copy_iface, &copy_iface_str);
if (retval != 1) { if (retval != 1) {

Loading…
Cancel
Save