aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2025-02-05 15:45:50 -0500
committerDave Wallace <dwallacelf@gmail.com>2025-02-07 15:12:59 +0000
commit9af015750c96a7af85771bf76c443c2ee6d5ff0f (patch)
tree16430d90a246d40148d02bde7f09470f953ed1a7
parenta88b1d7e2dc77fdacef5f0cf4cf6794a9b86ffe0 (diff)
session: do not match listeners when looking for lcl portv25.02-rc2stable/2502
Also optimize lookup to avoid session rules table matching. Type: fix Change-Id: I5b62c870edd9f7486e7de1417816fffa30d03a3e Signed-off-by: Florin Coras <fcoras@cisco.com> (cherry picked from commit 09341c6bbef28c03c1b026ff78808b000bf7d79d)
-rw-r--r--src/vnet/session/session_lookup.c65
-rw-r--r--src/vnet/session/session_lookup.h3
-rw-r--r--src/vnet/session/transport.c10
3 files changed, 73 insertions, 5 deletions
diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c
index 28a1feb1ed8..7678b0e0761 100644
--- a/src/vnet/session/session_lookup.c
+++ b/src/vnet/session/session_lookup.c
@@ -1380,6 +1380,71 @@ session_lookup_connection (u32 fib_index, ip46_address_t * lcl,
lcl_port, rmt_port, proto);
}
+/**
+ * Lookup exact match 6-tuple amongst established and half-open sessions
+ *
+ * Does not look into session rules table and does not try to find a listener.
+ */
+transport_connection_t *
+session_lookup_6tuple (u32 fib_index, ip46_address_t *lcl, ip46_address_t *rmt,
+ u16 lcl_port, u16 rmt_port, u8 proto, u8 is_ip4)
+{
+ session_table_t *st;
+ session_t *s;
+ int rv;
+
+ if (is_ip4)
+ {
+ session_kv4_t kv4;
+
+ st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index);
+ if (PREDICT_FALSE (!st))
+ return 0;
+
+ /*
+ * Lookup session amongst established ones
+ */
+ make_v4_ss_kv (&kv4, &lcl->ip4, &rmt->ip4, lcl_port, rmt_port, proto);
+ rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
+ if (rv == 0)
+ {
+ s = session_get_from_handle (kv4.value);
+ return transport_get_connection (proto, s->connection_index,
+ s->thread_index);
+ }
+
+ /*
+ * Try half-open connections
+ */
+ rv = clib_bihash_search_inline_16_8 (&st->v4_half_open_hash, &kv4);
+ if (rv == 0)
+ return transport_get_half_open (proto, kv4.value & 0xFFFFFFFF);
+ }
+ else
+ {
+ session_kv6_t kv6;
+
+ st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
+ if (PREDICT_FALSE (!st))
+ return 0;
+
+ make_v6_ss_kv (&kv6, &lcl->ip6, &rmt->ip6, lcl_port, rmt_port, proto);
+ rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
+ if (rv == 0)
+ {
+ s = session_get_from_handle (kv6.value);
+ return transport_get_connection (proto, s->connection_index,
+ s->thread_index);
+ }
+
+ /* Try half-open connections */
+ rv = clib_bihash_search_inline_48_8 (&st->v6_half_open_hash, &kv6);
+ if (rv == 0)
+ return transport_get_half_open (proto, kv6.value & 0xFFFFFFFF);
+ }
+ return 0;
+}
+
session_error_t
vnet_session_rule_add_del (session_rule_add_del_args_t *args)
{
diff --git a/src/vnet/session/session_lookup.h b/src/vnet/session/session_lookup.h
index 9f56af20a87..8f9ff7ee9bc 100644
--- a/src/vnet/session/session_lookup.h
+++ b/src/vnet/session/session_lookup.h
@@ -72,6 +72,9 @@ transport_connection_t *session_lookup_connection (u32 fib_index,
ip46_address_t * rmt,
u16 lcl_port, u16 rmt_port,
u8 proto, u8 is_ip4);
+transport_connection_t *
+session_lookup_6tuple (u32 fib_index, ip46_address_t *lcl, ip46_address_t *rmt,
+ u16 lcl_port, u16 rmt_port, u8 proto, u8 is_ip4);
session_t *session_lookup_listener4 (u32 fib_index, ip4_address_t * lcl,
u16 lcl_port, u8 proto, u8 use_wildcard);
session_t *session_lookup_listener6 (u32 fib_index, ip6_address_t * lcl,
diff --git a/src/vnet/session/transport.c b/src/vnet/session/transport.c
index e8c9490decb..c58d5900650 100644
--- a/src/vnet/session/transport.c
+++ b/src/vnet/session/transport.c
@@ -657,8 +657,8 @@ transport_alloc_local_port (u8 proto, ip46_address_t *lcl_addr,
break;
/* IP:port pair already in use, check if 6-tuple available */
- if (session_lookup_connection (rmt->fib_index, lcl_addr, &rmt->ip, port,
- rmt->port, proto, rmt->is_ip4))
+ if (session_lookup_6tuple (rmt->fib_index, lcl_addr, &rmt->ip, port,
+ rmt->port, proto, rmt->is_ip4))
continue;
/* 6-tuple is available so increment lcl endpoint refcount */
@@ -787,9 +787,9 @@ transport_alloc_local_endpoint (u8 proto, transport_endpoint_cfg_t * rmt_cfg,
return 0;
/* IP:port pair already in use, check if 6-tuple available */
- if (session_lookup_connection (rmt->fib_index, lcl_addr, &rmt->ip,
- rmt_cfg->peer.port, rmt->port, proto,
- rmt->is_ip4))
+ if (session_lookup_6tuple (rmt->fib_index, lcl_addr, &rmt->ip,
+ rmt_cfg->peer.port, rmt->port, proto,
+ rmt->is_ip4))
return SESSION_E_PORTINUSE;
/* 6-tuple is available so increment lcl endpoint refcount */