udp: avoid listener cleanups with active opens 83/37883/6
authorFlorin Coras <fcoras@cisco.com>
Mon, 9 Jan 2023 20:46:07 +0000 (12:46 -0800)
committerDave Barach <vpp@barachs.net>
Tue, 10 Jan 2023 18:25:32 +0000 (18:25 +0000)
Type: fix

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: Ibff9f32e4fcaf0344207d8e43f3547180cbd4eef

src/vnet/udp/udp.c
src/vnet/udp/udp.h

index e095a66..4553701 100644 (file)
@@ -38,6 +38,9 @@ udp_connection_register_port (u16 lcl_port, u8 is_ip4)
     n = sparse_vec_validate (um->next_by_dst_port6, lcl_port);
 
   n[0] = um->local_to_input_edge[is_ip4];
+
+  __atomic_add_fetch (&um->transport_ports_refcnt[is_ip4][lcl_port], 1,
+                     __ATOMIC_RELAXED);
 }
 
 static void
@@ -46,6 +49,11 @@ udp_connection_unregister_port (u16 lcl_port, u8 is_ip4)
   udp_main_t *um = &udp_main;
   u16 *n;
 
+  /* Needed because listeners are not tracked as local endpoints */
+  if (__atomic_sub_fetch (&um->transport_ports_refcnt[is_ip4][lcl_port], 1,
+                         __ATOMIC_RELAXED))
+    return;
+
   if (is_ip4)
     n = sparse_vec_validate (um->next_by_dst_port4, lcl_port);
   else
@@ -548,6 +556,9 @@ udp_enable_disable (vlib_main_t *vm, u8 is_en)
   udp_realloc_ports_sv (&um->next_by_dst_port4);
   udp_realloc_ports_sv (&um->next_by_dst_port6);
 
+  vec_validate (um->transport_ports_refcnt[0], 65535);
+  vec_validate (um->transport_ports_refcnt[1], 65535);
+
   return 0;
 }
 
index ab088bd..3dc116e 100644 (file)
@@ -147,6 +147,10 @@ typedef struct
   udp_worker_t *wrk;
   udp_connection_t *listener_pool;
 
+  /* Refcounts for ports consumed by udp transports to handle
+   * both passive and active opens using the same port */
+  u16 *transport_ports_refcnt[N_UDP_AF];
+
   u16 default_mtu;
   u16 msg_id_base;
   u8 csum_offload;