From e5a6d49303738a6119cefea2cdc247b21765ecb6 Mon Sep 17 00:00:00 2001 From: Shubham Shrivastava Date: Fri, 9 Apr 2021 18:26:04 +0530 Subject: [PATCH] DPI: Avoid concurrent access of ndpi_flow_struct by multiple lcores For each flow, an instance of `ndpi_flow_struct` is maintained in the respective row in the connection table. The `ndpi_flow_struct` structure contains `ndpi_packet_struct` (`packet` in `struct ndpi_flow_struct`) which holds per-packet data and is updated by nDPI library for each packet of the session handled by it. The per packet data includes pointers to L3, L4 headers and L4 payload which are contained inside the `rte_mbuf` of the given packet. Since the connection table is global and if there are not any explicit locks, any of the lcores can access it at any time. Under such circumstances, if the forward and backward packets from the same flow are handled by different lcores, it is possible that the `ndpi_flow_struct` of the session is concurrently accessed by the two lcores. Fixes DAN-316 Co-developed-by: Anshul Thakur Signed-off-by: Anshul Thakur Signed-off-by: Shubham Shrivastava --- src/npf/dpi/ndpi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/npf/dpi/ndpi.c b/src/npf/dpi/ndpi.c index 6959f9b0..197b443a 100644 --- a/src/npf/dpi/ndpi.c +++ b/src/npf/dpi/ndpi.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2020 AT&T Intellectual Property. All rights reserved. + * Copyright (c) 2021 Centre for Development of Telematics. All rights reserved. * * SPDX-License-Identifier: LGPL-2.1-only */ @@ -54,6 +55,7 @@ struct ndpi_flow { uint32_t type; struct ndpi_id_struct *src_id; struct ndpi_id_struct *dest_id; + rte_spinlock_t fl_lock; struct rcu_head n_rcu_head; }; @@ -150,6 +152,7 @@ dpi_ndpi_process_pkt(struct dpi_engine_flow *engine_flow, if (unlikely(!flow->key)) return false; + rte_spinlock_lock(&flow->fl_lock); if (!dpi_ndpi_process(detection_modules[dp_lcore_id()], mbuf, flow)) { flow->protocol = DPI_APP_ERROR; @@ -157,6 +160,7 @@ dpi_ndpi_process_pkt(struct dpi_engine_flow *engine_flow, flow->error = true; } + rte_spinlock_unlock(&flow->fl_lock); return true; } @@ -302,6 +306,7 @@ dpi_ndpi_session_first_packet(struct npf_session *se __unused, flow->type = DPI_APP_TYPE_NONE; flow->error = false; flow->offloaded = false; + rte_spinlock_init(&flow->fl_lock); flow->key = ndpi_flow_malloc(SIZEOF_FLOW_STRUCT); if (!flow->key)