aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/session/session_lookup.c
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2017-11-09 19:30:17 -0800
committerDave Wallace <dwallacelf@gmail.com>2017-11-10 15:26:48 +0000
commitdbd44561538514f6cfce324419042f2ce69fe214 (patch)
tree28561c30020319e28d7a5f2f444e5cdea9693912 /src/vnet/session/session_lookup.c
parentbc3c12623c30cefefb974d3581179be7fb042af3 (diff)
session: use listener logic for proxy rules
This moves session proxy logic from session rules tables to table/logic used to manage session listeners in order to avoid overlap of semantically different rules. Change-Id: I463522cce91b92d942f6a2086fb14c3366b9f023 Signed-off-by: Florin Coras <fcoras@cisco.com>
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;
}