session: support for cl port reuse
Adds support for connectionless listener port reuse. Until now, cl
listeners had fifos allocated to them and therefore only one app worker
could ever listen, i.e., a session cannot have multiple fifos.
To circumvent the limitation, this separates the fifos from the listener
by allocating new cl sessions for each app worker that reuses the app
listener. Flows are hashed to app worker cl sessions but, for now, this
is not a consistent/fixed hash.
Type: improvement
Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: Ic6533cd47f2765903669f88c288bd592fb17a19e
diff --git a/src/vnet/udp/udp_input.c b/src/vnet/udp/udp_input.c
index 66f6229..9cabfdf 100644
--- a/src/vnet/udp/udp_input.c
+++ b/src/vnet/udp/udp_input.c
@@ -136,39 +136,46 @@
int wrote0;
if (!(uc0->flags & UDP_CONN_F_CONNECTED))
- clib_spinlock_lock (&uc0->rx_lock);
+ {
+ clib_spinlock_lock (&uc0->rx_lock);
+
+ wrote0 = session_enqueue_dgram_connection_cl (
+ s0, hdr0, b, TRANSPORT_PROTO_UDP, queue_event);
+
+ clib_spinlock_unlock (&uc0->rx_lock);
+
+ /* Expect cl udp enqueue to fail because fifo enqueue */
+ if (PREDICT_FALSE (wrote0 == 0))
+ *error0 = UDP_ERROR_FIFO_FULL;
+
+ return;
+ }
if (svm_fifo_max_enqueue_prod (s0->rx_fifo)
< hdr0->data_length + sizeof (session_dgram_hdr_t))
{
*error0 = UDP_ERROR_FIFO_FULL;
- goto unlock_rx_lock;
+ return;
}
/* If session is owned by another thread and rx event needed,
* enqueue event now while we still have the peeker lock */
if (s0->thread_index != thread_index)
{
- wrote0 = session_enqueue_dgram_connection_cl (
+ wrote0 = session_enqueue_dgram_connection2 (
s0, hdr0, b, TRANSPORT_PROTO_UDP,
- /* queue event */ queue_event && !svm_fifo_has_event (s0->rx_fifo));
+ queue_event && !svm_fifo_has_event (s0->rx_fifo));
}
else
{
- wrote0 = session_enqueue_dgram_connection (s0, hdr0, b,
- TRANSPORT_PROTO_UDP,
- queue_event);
+ wrote0 = session_enqueue_dgram_connection (
+ s0, hdr0, b, TRANSPORT_PROTO_UDP, queue_event);
}
/* In some rare cases, session_enqueue_dgram_connection can fail because a
* chunk cannot be allocated in the RX FIFO */
if (PREDICT_FALSE (wrote0 == 0))
*error0 = UDP_ERROR_FIFO_NOMEM;
-
-unlock_rx_lock:
-
- if (!(uc0->flags & UDP_CONN_F_CONNECTED))
- clib_spinlock_unlock (&uc0->rx_lock);
}
always_inline session_t *