aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/udp/udp.c11
-rw-r--r--src/vnet/udp/udp.h4
2 files changed, 15 insertions, 0 deletions
diff --git a/src/vnet/udp/udp.c b/src/vnet/udp/udp.c
index e095a66dcf2..4553701dced 100644
--- a/src/vnet/udp/udp.c
+++ b/src/vnet/udp/udp.c
@@ -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;
}
diff --git a/src/vnet/udp/udp.h b/src/vnet/udp/udp.h
index ab088bd6a70..3dc116ee4d7 100644
--- a/src/vnet/udp/udp.h
+++ b/src/vnet/udp/udp.h
@@ -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;