summaryrefslogtreecommitdiffstats
path: root/src/vnet/session/session_lookup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/session/session_lookup.c')
-rw-r--r--src/vnet/session/session_lookup.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c
index f4b26f6d931..30e39132d3a 100644
--- a/src/vnet/session/session_lookup.c
+++ b/src/vnet/session/session_lookup.c
@@ -113,6 +113,20 @@ make_v4_listener_kv (session_kv4_t * kv, ip4_address_t * lcl, u16 lcl_port,
}
always_inline void
+make_v4_proxy_kv (session_kv4_t * kv, ip4_address_t * lcl, u8 proto)
+{
+ v4_connection_key_t *key = (v4_connection_key_t *) kv->key;
+
+ key->src.as_u32 = lcl->as_u32;
+ key->dst.as_u32 = 0;
+ key->src_port = 0;
+ key->dst_port = 0;
+ key->proto = proto;
+
+ kv->value = ~0ULL;
+}
+
+always_inline void
make_v4_ss_kv_from_tc (session_kv4_t * kv, transport_connection_t * t)
{
make_v4_ss_kv (kv, &t->lcl_ip.ip4, &t->rmt_ip.ip4, t->lcl_port, t->rmt_port,
@@ -156,6 +170,23 @@ make_v6_listener_kv (session_kv6_t * kv, ip6_address_t * lcl, u16 lcl_port,
}
always_inline void
+make_v6_proxy_kv (session_kv6_t * kv, ip6_address_t * lcl, u8 proto)
+{
+ v6_connection_key_t *key = (v6_connection_key_t *) kv->key;
+
+ key->src.as_u64[0] = lcl->as_u64[0];
+ key->src.as_u64[1] = lcl->as_u64[1];
+ key->dst.as_u64[0] = 0;
+ key->dst.as_u64[1] = 0;
+ key->src_port = 0;
+ key->dst_port = 0;
+ key->proto = proto;
+ key->unused = 0;
+
+ kv->value = ~0ULL;
+}
+
+always_inline void
make_v6_ss_kv_from_tc (session_kv6_t * kv, transport_connection_t * t)
{
make_v6_ss_kv (kv, &t->lcl_ip.ip6, &t->rmt_ip.ip6, t->lcl_port, t->rmt_port,
@@ -536,6 +567,14 @@ session_lookup_local_endpoint (u32 table_index, session_endpoint_t * sep)
rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
if (rv == 0)
return (u32) kv4.value;
+
+ /*
+ * Zero out the port and check if we have proxy
+ */
+ kv4.key[1] = 0;
+ rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
+ if (rv == 0)
+ return (u32) kv4.value;
}
else
{
@@ -564,6 +603,14 @@ session_lookup_local_endpoint (u32 table_index, session_endpoint_t * sep)
rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
if (rv == 0)
return (u32) kv6.value;
+
+ /*
+ * Zero out the port. Same logic as above.
+ */
+ kv6.key[4] = kv6.key[5] = 0;
+ rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
+ if (rv == 0)
+ return (u32) kv6.value;
}
return APP_INVALID_INDEX;
}
@@ -575,17 +622,30 @@ session_lookup_listener4_i (session_table_t * st, ip4_address_t * lcl,
session_kv4_t kv4;
int rv;
+ /*
+ * First, try a fully formed listener
+ */
make_v4_listener_kv (&kv4, lcl, lcl_port, proto);
rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
if (rv == 0)
return session_manager_get_listener (proto, (u32) kv4.value);
- /* Zero out the lcl ip */
+ /*
+ * Zero out the lcl ip and check if any 0/0 port binds have been done
+ */
kv4.key[0] = 0;
rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
if (rv == 0)
return session_manager_get_listener (proto, (u32) kv4.value);
+ /*
+ * Zero out port and check if we have a proxy set up for our ip
+ */
+ make_v4_proxy_kv (&kv4, lcl, proto);
+ rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
+ if (rv == 0)
+ return session_manager_get_listener (proto, (u32) kv4.value);
+
return 0;
}
@@ -618,6 +678,10 @@ session_lookup_listener6_i (session_table_t * st, ip6_address_t * lcl,
if (rv == 0)
return session_manager_get_listener (proto, (u32) kv6.value);
+ make_v6_proxy_kv (&kv6, lcl, proto);
+ rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
+ if (rv == 0)
+ return session_manager_get_listener (proto, (u32) kv6.value);
return 0;
}