diff options
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/ip/ip.c | 12 | ||||
-rw-r--r-- | src/vnet/ip/ip.h | 2 | ||||
-rw-r--r-- | src/vnet/session/session_lookup.c | 90 |
3 files changed, 75 insertions, 29 deletions
diff --git a/src/vnet/ip/ip.c b/src/vnet/ip/ip.c index b6825c30709..65eb50e9c4a 100644 --- a/src/vnet/ip/ip.c +++ b/src/vnet/ip/ip.c @@ -34,6 +34,18 @@ ip_is_local_host (ip46_address_t * ip46_address, u8 is_ip4) return (ip46_address->as_u64[0] == 0 && ip46_address->as_u64[1] == 1); } +u8 +ip4_is_local_host (ip4_address_t * ip4_address) +{ + return (ip4_address->as_u8[0] == 127); +} + +u8 +ip6_is_local_host (ip6_address_t * ip6_address) +{ + return (ip6_address->as_u64[0] == 0 && ip6_address->as_u64[1] == 1); +} + /** * Checks that an ip is local to the requested fib */ diff --git a/src/vnet/ip/ip.h b/src/vnet/ip/ip.h index 2dfa979e70c..747b4385816 100644 --- a/src/vnet/ip/ip.h +++ b/src/vnet/ip/ip.h @@ -194,6 +194,8 @@ int ip_table_bind (fib_protocol_t fproto, u32 sw_if_index, u8 ip_is_zero (ip46_address_t * ip46_address, u8 is_ip4); u8 ip_is_local_host (ip46_address_t * ip46_address, u8 is_ip4); +u8 ip4_is_local_host (ip4_address_t * ip4_address); +u8 ip6_is_local_host (ip6_address_t * ip6_address); u8 ip_is_local (u32 fib_index, ip46_address_t * ip46_address, u8 is_ip4); u8 ip_interface_has_address (u32 sw_if_index, ip46_address_t * ip, u8 is_ip4); void ip_copy (ip46_address_t * dst, ip46_address_t * src, u8 is_ip4); diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c index 9ce0b1a22eb..3a80286a9cb 100644 --- a/src/vnet/session/session_lookup.c +++ b/src/vnet/session/session_lookup.c @@ -581,10 +581,17 @@ session_lookup_local_endpoint (u32 table_index, session_endpoint_t * sep) * Zero out the ip. Logic is that connect to local ips, say * 127.0.0.1:port, can match 0.0.0.0:port */ - kv4.key[0] = 0; - rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4); - if (rv == 0) - return kv4.value; + if (ip4_is_local_host (&sep->ip.ip4)) + { + kv4.key[0] = 0; + rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4); + if (rv == 0) + return kv4.value; + } + else + { + kv4.key[0] = 0; + } /* * Zero out the port and check if we have proxy @@ -615,10 +622,18 @@ session_lookup_local_endpoint (u32 table_index, session_endpoint_t * sep) /* * Zero out the ip. Same logic as above. */ - kv6.key[0] = kv6.key[1] = 0; - rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6); - if (rv == 0) - return kv6.value; + + if (ip6_is_local_host (&sep->ip.ip6)) + { + kv6.key[0] = kv6.key[1] = 0; + rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6); + if (rv == 0) + return kv6.value; + } + else + { + kv6.key[0] = kv6.key[1] = 0; + } /* * Zero out the port. Same logic as above. @@ -631,9 +646,9 @@ session_lookup_local_endpoint (u32 table_index, session_endpoint_t * sep) return SESSION_INVALID_HANDLE; } -static stream_session_t * +static inline stream_session_t * session_lookup_listener4_i (session_table_t * st, ip4_address_t * lcl, - u16 lcl_port, u8 proto) + u16 lcl_port, u8 proto, u8 use_wildcard) { session_kv4_t kv4; int rv; @@ -651,10 +666,17 @@ session_lookup_listener4_i (session_table_t * st, ip4_address_t * lcl, /* * 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 (session_type, (u32) kv4.value); + if (use_wildcard) + { + kv4.key[0] = 0; + rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4); + if (rv == 0) + return session_manager_get_listener (session_type, (u32) kv4.value); + } + else + { + kv4.key[0] = 0; + } /* * Zero out port and check if we have a proxy set up for our ip @@ -675,12 +697,12 @@ session_lookup_listener4 (u32 fib_index, ip4_address_t * lcl, u16 lcl_port, st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index); if (!st) return 0; - return session_lookup_listener4_i (st, lcl, lcl_port, proto); + return session_lookup_listener4_i (st, lcl, lcl_port, proto, 0); } static stream_session_t * session_lookup_listener6_i (session_table_t * st, ip6_address_t * lcl, - u16 lcl_port, u8 proto) + u16 lcl_port, u8 proto, u8 ip_wildcard) { session_kv6_t kv6; int rv; @@ -693,10 +715,17 @@ session_lookup_listener6_i (session_table_t * st, ip6_address_t * lcl, return session_manager_get_listener (session_type, (u32) kv6.value); /* Zero out the lcl ip */ - kv6.key[0] = kv6.key[1] = 0; - rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6); - if (rv == 0) - return session_manager_get_listener (session_type, (u32) kv6.value); + if (ip_wildcard) + { + kv6.key[0] = kv6.key[1] = 0; + rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6); + if (rv == 0) + return session_manager_get_listener (session_type, (u32) kv6.value); + } + else + { + kv6.key[0] = kv6.key[1] = 0; + } make_v6_proxy_kv (&kv6, lcl, proto); rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6); @@ -713,9 +742,12 @@ session_lookup_listener6 (u32 fib_index, ip6_address_t * lcl, u16 lcl_port, st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index); if (!st) return 0; - return session_lookup_listener6_i (st, lcl, lcl_port, proto); + return session_lookup_listener6_i (st, lcl, lcl_port, proto, 1); } +/** + * Lookup listener, exact or proxy (inaddr_any:0) match + */ stream_session_t * session_lookup_listener (u32 table_index, session_endpoint_t * sep) { @@ -725,10 +757,10 @@ session_lookup_listener (u32 table_index, session_endpoint_t * sep) return 0; if (sep->is_ip4) return session_lookup_listener4_i (st, &sep->ip.ip4, sep->port, - sep->transport_proto); + sep->transport_proto, 0); else return session_lookup_listener6_i (st, &sep->ip.ip6, sep->port, - sep->transport_proto); + sep->transport_proto, 0); return 0; } @@ -906,7 +938,7 @@ session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl, /* * If nothing is found, check if any listener is available */ - s = session_lookup_listener4_i (st, lcl, lcl_port, proto); + s = session_lookup_listener4_i (st, lcl, lcl_port, proto, 1); if (s) return tp_vfts[proto].get_listener (s->connection_index); @@ -981,7 +1013,7 @@ session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl, /* * If nothing is found, check if any listener is available */ - s = session_lookup_listener4_i (st, lcl, lcl_port, proto); + s = session_lookup_listener4_i (st, lcl, lcl_port, proto, 1); if (s) return tp_vfts[proto].get_listener (s->connection_index); @@ -1039,7 +1071,7 @@ session_lookup_safe4 (u32 fib_index, ip4_address_t * lcl, ip4_address_t * rmt, /* * If nothing is found, check if any listener is available */ - if ((s = session_lookup_listener4_i (st, lcl, lcl_port, proto))) + if ((s = session_lookup_listener4_i (st, lcl, lcl_port, proto, 1))) return s; return 0; @@ -1115,7 +1147,7 @@ session_lookup_connection_wt6 (u32 fib_index, ip6_address_t * lcl, } /* If nothing is found, check if any listener is available */ - s = session_lookup_listener6_i (st, lcl, lcl_port, proto); + s = session_lookup_listener6_i (st, lcl, lcl_port, proto, 1); if (s) return tp_vfts[proto].get_listener (s->connection_index); @@ -1181,7 +1213,7 @@ session_lookup_connection6 (u32 fib_index, ip6_address_t * lcl, } /* If nothing is found, check if any listener is available */ - s = session_lookup_listener6 (fib_index, lcl, lcl_port, proto); + s = session_lookup_listener6_i (st, lcl, lcl_port, proto, 1); if (s) return tp_vfts[proto].get_listener (s->connection_index); @@ -1232,7 +1264,7 @@ session_lookup_safe6 (u32 fib_index, ip6_address_t * lcl, ip6_address_t * rmt, } /* If nothing is found, check if any listener is available */ - if ((s = session_lookup_listener6_i (st, lcl, lcl_port, proto))) + if ((s = session_lookup_listener6_i (st, lcl, lcl_port, proto, 1))) return s; return 0; } |