From f751c93cb8de05c0baaa46d9506b064086dada03 Mon Sep 17 00:00:00 2001 From: Lukas Sismis Date: Mon, 24 Apr 2023 18:04:42 +0200 Subject: [PATCH] dpdk: warn about processing segmented DPDK mbufs Segmented mbufs should never happen in Suricata. Mbuf segmentation divides the received packet into multiple mbufs. This can happen when MTU of the NIC is larger than the allocated mbufs in the mbuf mempool. As Suricata sets the size of the mbuf to be slightly higher than the configured MTU, mbuf segmentation should never happen in Suricata. This is especially true, if Suricata runs as a primary process and configures the packet source (NIC). Processing segmented mbufs can lead to missed/false (pattern-matching) detections as Suricata only inspects the first segment of the packet. It can also lead to segfault if Suricata moves the detection window out of the segment boundaries. --- src/source-dpdk.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/source-dpdk.c b/src/source-dpdk.c index cf59ad9bba..7afce350ed 100644 --- a/src/source-dpdk.c +++ b/src/source-dpdk.c @@ -345,6 +345,7 @@ static TmEcode ReceiveDPDKLoop(ThreadVars *tv, void *data, void *slot) uint16_t nb_rx; time_t last_dump = 0; time_t current_time; + bool segmented_mbufs_warned = 0; DPDKThreadVars *ptv = (DPDKThreadVars *)data; TmSlot *s = (TmSlot *)slot; @@ -409,6 +410,23 @@ static TmEcode ReceiveDPDKLoop(ThreadVars *tv, void *data, void *slot) } } + if (!rte_pktmbuf_is_contiguous(p->dpdk_v.mbuf) && !segmented_mbufs_warned) { + char warn_s[] = "Segmented mbufs detected! Redmine Ticket #6012 " + "Check your configuration or report the issue"; + enum rte_proc_type_t eal_t = rte_eal_process_type(); + if (eal_t == RTE_PROC_SECONDARY) { + SCLogWarning("%s. To avoid segmented mbufs, " + "try to increase mbuf size in your primary application", + warn_s); + } else if (eal_t == RTE_PROC_PRIMARY) { + SCLogWarning("%s. To avoid segmented mbufs, " + "try to increase MTU in your suricata.yaml", + warn_s); + } + + segmented_mbufs_warned = 1; + } + PacketSetData(p, rte_pktmbuf_mtod(p->dpdk_v.mbuf, uint8_t *), rte_pktmbuf_pkt_len(p->dpdk_v.mbuf)); if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) { -- 2.47.2