session: zero out ips in local endpoint lookup only if local 53/10853/4
authorFlorin Coras <fcoras@cisco.com>
Tue, 27 Feb 2018 18:05:57 +0000 (10:05 -0800)
committerDave Wallace <dwallacelf@gmail.com>
Thu, 1 Mar 2018 02:55:32 +0000 (02:55 +0000)
Change-Id: I3425b1533b3d31210166e7b3798685464ad1c489
Signed-off-by: Florin Coras <fcoras@cisco.com>
src/vnet/ip/ip.c
src/vnet/ip/ip.h
src/vnet/session/session_lookup.c

index b6825c3..65eb50e 100644 (file)
@@ -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
  */
index 2dfa979..747b438 100644 (file)
@@ -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);
index 9ce0b1a..3a80286 100644 (file)
@@ -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;
 }