session: make local port allocator fib aware 87/40287/9
authorFlorin Coras <[email protected]>
Sat, 3 Feb 2024 02:25:04 +0000 (18:25 -0800)
committerDave Barach <[email protected]>
Fri, 24 Jan 2025 18:55:19 +0000 (18:55 +0000)
Allocate ports per fib.

Type: improvement

Change-Id: I9e1f113602485bfb09f71092eee58b9a433daa6a
Signed-off-by: Florin Coras <[email protected]>
src/vnet/session/transport.c
src/vnet/session/transport.h
src/vnet/tcp/tcp.c
src/vnet/udp/udp.c

index e8c9490..ac9b54f 100644 (file)
@@ -247,15 +247,15 @@ format_transport_state (u8 *s, va_list *args)
 }
 
 u32
-transport_endpoint_lookup (transport_endpoint_table_t * ht, u8 proto,
-                          ip46_address_t * ip, u16 port)
+transport_endpoint_lookup (transport_endpoint_table_t *ht, u8 proto,
+                          u32 fib_index, ip46_address_t *ip, u16 port)
 {
   clib_bihash_kv_24_8_t kv;
   int rv;
 
   kv.key[0] = ip->as_u64[0];
   kv.key[1] = ip->as_u64[1];
-  kv.key[2] = (u64) port << 8 | (u64) proto;
+  kv.key[2] = (u64) fib_index << 32 | (u64) port << 8 | (u64) proto;
 
   rv = clib_bihash_search_inline_24_8 (ht, &kv);
   if (rv == 0)
@@ -272,7 +272,7 @@ transport_endpoint_table_add (transport_endpoint_table_t * ht, u8 proto,
 
   kv.key[0] = te->ip.as_u64[0];
   kv.key[1] = te->ip.as_u64[1];
-  kv.key[2] = (u64) te->port << 8 | (u64) proto;
+  kv.key[2] = (u64) te->fib_index << 32 | (u64) te->port << 8 | (u64) proto;
   kv.value = value;
 
   clib_bihash_add_del_24_8 (ht, &kv, 1);
@@ -286,7 +286,7 @@ transport_endpoint_table_del (transport_endpoint_table_t * ht, u8 proto,
 
   kv.key[0] = te->ip.as_u64[0];
   kv.key[1] = te->ip.as_u64[1];
-  kv.key[2] = (u64) te->port << 8 | (u64) proto;
+  kv.key[2] = (u64) te->fib_index << 32 | (u64) te->port << 8 | (u64) proto;
 
   clib_bihash_add_del_24_8 (ht, &kv, 0);
 }
@@ -547,14 +547,15 @@ transport_program_endpoint_cleanup (u32 lepi)
 }
 
 int
-transport_release_local_endpoint (u8 proto, ip46_address_t *lcl_ip, u16 port)
+transport_release_local_endpoint (u8 proto, u32 fib_index,
+                                 ip46_address_t *lcl_ip, u16 port)
 {
   transport_main_t *tm = &tp_main;
   local_endpoint_t *lep;
   u32 lepi;
 
-  lepi = transport_endpoint_lookup (&tm->local_endpoints_table, proto, lcl_ip,
-                                   port);
+  lepi = transport_endpoint_lookup (&tm->local_endpoints_table, proto,
+                                   fib_index, lcl_ip, port);
   if (lepi == ENDPOINT_INVALID_INDEX)
     return -1;
 
@@ -574,7 +575,8 @@ transport_release_local_endpoint (u8 proto, ip46_address_t *lcl_ip, u16 port)
 }
 
 static int
-transport_endpoint_mark_used (u8 proto, ip46_address_t *ip, u16 port)
+transport_endpoint_mark_used (u8 proto, u32 fib_index, ip46_address_t *ip,
+                             u16 port)
 {
   transport_main_t *tm = &tp_main;
   local_endpoint_t *lep;
@@ -582,8 +584,8 @@ transport_endpoint_mark_used (u8 proto, ip46_address_t *ip, u16 port)
 
   ASSERT (vlib_get_thread_index () <= transport_cl_thread ());
 
-  tei =
-    transport_endpoint_lookup (&tm->local_endpoints_table, proto, ip, port);
+  tei = transport_endpoint_lookup (&tm->local_endpoints_table, proto,
+                                  fib_index, ip, port);
   if (tei != ENDPOINT_INVALID_INDEX)
     return SESSION_E_PORTINUSE;
 
@@ -601,7 +603,8 @@ transport_endpoint_mark_used (u8 proto, ip46_address_t *ip, u16 port)
 }
 
 void
-transport_share_local_endpoint (u8 proto, ip46_address_t * lcl_ip, u16 port)
+transport_share_local_endpoint (u8 proto, u32 fib_index,
+                               ip46_address_t *lcl_ip, u16 port)
 {
   transport_main_t *tm = &tp_main;
   local_endpoint_t *lep;
@@ -610,8 +613,8 @@ transport_share_local_endpoint (u8 proto, ip46_address_t * lcl_ip, u16 port)
   /* Active opens should call this only from a control thread, which are also
    * used to allocate and free ports. So, pool has only one writer and
    * potentially many readers. Listeners are allocated with barrier */
-  lepi = transport_endpoint_lookup (&tm->local_endpoints_table, proto, lcl_ip,
-                                   port);
+  lepi = transport_endpoint_lookup (&tm->local_endpoints_table, proto,
+                                   fib_index, lcl_ip, port);
   if (lepi != ENDPOINT_INVALID_INDEX)
     {
       lep = pool_elt_at_index (tm->local_endpoints, lepi);
@@ -653,7 +656,8 @@ transport_alloc_local_port (u8 proto, ip46_address_t *lcl_addr,
            }
        }
 
-      if (!transport_endpoint_mark_used (proto, lcl_addr, port))
+      if (!transport_endpoint_mark_used (proto, rmt->fib_index, lcl_addr,
+                                        port))
        break;
 
       /* IP:port pair already in use, check if 6-tuple available */
@@ -662,7 +666,7 @@ transport_alloc_local_port (u8 proto, ip46_address_t *lcl_addr,
        continue;
 
       /* 6-tuple is available so increment lcl endpoint refcount */
-      transport_share_local_endpoint (proto, lcl_addr, port);
+      transport_share_local_endpoint (proto, rmt->fib_index, lcl_addr, port);
 
       break;
     }
@@ -783,7 +787,8 @@ transport_alloc_local_endpoint (u8 proto, transport_endpoint_cfg_t * rmt_cfg,
     {
       *lcl_port = rmt_cfg->peer.port;
 
-      if (!transport_endpoint_mark_used (proto, lcl_addr, rmt_cfg->peer.port))
+      if (!transport_endpoint_mark_used (proto, rmt->fib_index, lcl_addr,
+                                        rmt_cfg->peer.port))
        return 0;
 
       /* IP:port pair already in use, check if 6-tuple available */
@@ -793,7 +798,8 @@ transport_alloc_local_endpoint (u8 proto, transport_endpoint_cfg_t * rmt_cfg,
        return SESSION_E_PORTINUSE;
 
       /* 6-tuple is available so increment lcl endpoint refcount */
-      transport_share_local_endpoint (proto, lcl_addr, rmt_cfg->peer.port);
+      transport_share_local_endpoint (proto, rmt->fib_index, lcl_addr,
+                                     rmt_cfg->peer.port);
 
       return 0;
     }
index 289bf47..c864be1 100644 (file)
@@ -248,10 +248,10 @@ int transport_alloc_local_port (u8 proto, ip46_address_t *ip,
                                transport_endpoint_cfg_t *rmt);
 int transport_alloc_local_endpoint (u8 proto, transport_endpoint_cfg_t *rmt,
                                    ip46_address_t *lcl_addr, u16 *lcl_port);
-void transport_share_local_endpoint (u8 proto, ip46_address_t * lcl_ip,
-                                    u16 port);
-int transport_release_local_endpoint (u8 proto, ip46_address_t *lcl_ip,
-                                     u16 port);
+void transport_share_local_endpoint (u8 proto, u32 fib_index,
+                                    ip46_address_t *lcl_ip, u16 port);
+int transport_release_local_endpoint (u8 proto, u32 fib_index,
+                                     ip46_address_t *lcl_ip, u16 port);
 u16 transport_port_alloc_max_tries ();
 void transport_clear_stats ();
 void transport_enable_disable (vlib_main_t * vm, u8 is_en);
index aea4955..8851fb9 100644 (file)
@@ -242,8 +242,8 @@ tcp_connection_cleanup (tcp_connection_t * tc)
 
   /* Cleanup local endpoint if this was an active connect */
   if (!(tc->cfg_flags & TCP_CFG_F_NO_ENDPOINT))
-    transport_release_local_endpoint (TRANSPORT_PROTO_TCP, &tc->c_lcl_ip,
-                                     tc->c_lcl_port);
+    transport_release_local_endpoint (TRANSPORT_PROTO_TCP, tc->c_fib_index,
+                                     &tc->c_lcl_ip, tc->c_lcl_port);
 
   /* Check if connection is not yet fully established */
   if (tc->state == TCP_STATE_SYN_SENT)
index 1fc055f..661a0f6 100644 (file)
@@ -99,8 +99,8 @@ udp_connection_free (udp_connection_t * uc)
 static void
 udp_connection_cleanup (udp_connection_t * uc)
 {
-  transport_release_local_endpoint (TRANSPORT_PROTO_UDP, &uc->c_lcl_ip,
-                                   uc->c_lcl_port);
+  transport_release_local_endpoint (TRANSPORT_PROTO_UDP, uc->c_fib_index,
+                                   &uc->c_lcl_ip, uc->c_lcl_port);
   udp_connection_unregister_port (uc->c_lcl_port, uc->c_is_ip4);
   udp_connection_free (uc);
 }
@@ -434,8 +434,8 @@ udp_open_connection (transport_endpoint_cfg_t * rmt)
       /* If specific source port was requested abort */
       if (rmt->peer.port)
        {
-         transport_release_local_endpoint (TRANSPORT_PROTO_UDP, &lcl_addr,
-                                           lcl_port);
+         transport_release_local_endpoint (
+           TRANSPORT_PROTO_UDP, rmt->fib_index, &lcl_addr, lcl_port);
          return SESSION_E_PORTINUSE;
        }
 
@@ -443,8 +443,8 @@ udp_open_connection (transport_endpoint_cfg_t * rmt)
       while (udp_connection_port_used_extern (clib_net_to_host_u16 (lcl_port),
                                              rmt->is_ip4))
        {
-         transport_release_local_endpoint (TRANSPORT_PROTO_UDP, &lcl_addr,
-                                           lcl_port);
+         transport_release_local_endpoint (
+           TRANSPORT_PROTO_UDP, rmt->fib_index, &lcl_addr, lcl_port);
          lcl_port =
            transport_alloc_local_port (TRANSPORT_PROTO_UDP, &lcl_addr, rmt);
          if ((int) lcl_port < 1)