session/tcp: filtering improvements 86/9486/4
authorFlorin Coras <fcoras@cisco.com>
Mon, 20 Nov 2017 02:06:58 +0000 (18:06 -0800)
committerDave Wallace <dwallacelf@gmail.com>
Mon, 20 Nov 2017 16:15:34 +0000 (16:15 +0000)
- make allow action explicit (-3)
- add session lookup is_filtered return flag that is set if lookup hit a
  deny filter
- change tcp logic to drop filtered packets when punting is enabled

Change-Id: Ic38f294424663a4e108439b7571511f46f8e0be1
Signed-off-by: Florin Coras <fcoras@cisco.com>
src/vnet/session/application_namespace.c
src/vnet/session/session_lookup.c
src/vnet/session/session_lookup.h
src/vnet/session/session_rules_table.h
src/vnet/session/session_test.c
src/vnet/tcp/tcp_error.def
src/vnet/tcp/tcp_input.c
src/vnet/tcp/tcp_test.c

index eaf09e8..21c1cbc 100644 (file)
@@ -248,7 +248,8 @@ u8 *
 format_app_namespace (u8 * s, va_list * args)
 {
   app_namespace_t *app_ns = va_arg (*args, app_namespace_t *);
-  s = format (s, "%-20v%-20lu%-20u", app_ns->ns_id, app_ns->ns_secret,
+  s = format (s, "%-20v%-10u%-20lu%-20u", app_ns->ns_id,
+             app_namespace_index (app_ns), app_ns->ns_secret,
              app_ns->sw_if_index);
   return s;
 }
@@ -301,9 +302,10 @@ show_app_ns_fn (vlib_main_t * vm, unformat_input_t * main_input,
       goto done;
     }
 
-  vlib_cli_output (vm, "%-20s%-20s%-20s", "Namespace", "Secret",
-                  "sw_if_index");
 do_ns_list:
+  vlib_cli_output (vm, "%-20s%-10s%-20s%-20s", "Namespace", "Index", "Secret",
+                  "sw_if_index");
+
   /* *INDENT-OFF* */
   pool_foreach (app_ns, app_namespace_pool, ({
     vlib_cli_output (vm, "%U", format_app_namespace, app_ns);
index 30e3913..2e4e96a 100644 (file)
@@ -378,12 +378,28 @@ session_lookup_del_session (stream_session_t * s)
   return session_lookup_del_connection (ts);
 }
 
+static u8
+session_lookup_action_index_is_valid (u32 action_index)
+{
+  if (action_index == SESSION_RULES_TABLE_ACTION_ALLOW
+      || action_index == SESSION_RULES_TABLE_INVALID_INDEX)
+    return 0;
+  return 1;
+}
+
 static u32
-session_lookup_action_to_session_index (u32 action_index)
+session_lookup_action_to_app_index (u32 action_index)
 {
-  if (action_index != SESSION_RULES_TABLE_ACTION_DROP)
-    return action_index;
-  return SESSION_INVALID_INDEX;
+  switch (action_index)
+    {
+    case SESSION_RULES_TABLE_ACTION_DROP:
+      return APP_DROP_INDEX;
+    case SESSION_RULES_TABLE_ACTION_ALLOW:
+    case SESSION_RULES_TABLE_INVALID_INDEX:
+      return APP_INVALID_INDEX;
+    default:
+      return action_index;
+    }
 }
 
 static stream_session_t *
@@ -391,7 +407,7 @@ session_lookup_app_listen_session (u32 app_index, u8 fib_proto,
                                   u8 transport_proto)
 {
   application_t *app;
-  app = application_get (app_index);
+  app = application_get_if_valid (app_index);
   if (!app)
     return 0;
 
@@ -402,10 +418,10 @@ static stream_session_t *
 session_lookup_action_to_session (u32 action_index, u8 fib_proto,
                                  u8 transport_proto)
 {
-  u32 session_index;
-  session_index = session_lookup_action_to_session_index (action_index);
+  u32 app_index;
+  app_index = session_lookup_action_to_app_index (action_index);
   /* Nothing sophisticated for now, action index is app index */
-  return session_lookup_app_listen_session (session_index, fib_proto,
+  return session_lookup_app_listen_session (app_index, fib_proto,
                                            transport_proto);
 }
 
@@ -415,26 +431,26 @@ session_lookup_rules_table_session4 (session_table_t * st, u8 proto,
                                     ip4_address_t * rmt, u16 rmt_port)
 {
   session_rules_table_t *srt = &st->session_rules[proto];
-  u32 action_index, session_index;
+  u32 action_index, app_index;
   action_index = session_rules_table_lookup4 (srt, lcl, rmt, lcl_port,
                                              rmt_port);
-  session_index = session_lookup_action_to_session_index (action_index);
+  app_index = session_lookup_action_to_app_index (action_index);
   /* Nothing sophisticated for now, action index is app index */
-  return session_lookup_app_listen_session (session_index, FIB_PROTOCOL_IP4,
+  return session_lookup_app_listen_session (app_index, FIB_PROTOCOL_IP4,
                                            proto);
 }
 
 stream_session_t *
-session_lookup_rules_table6 (session_table_t * st, u8 proto,
-                            ip6_address_t * lcl, u16 lcl_port,
-                            ip6_address_t * rmt, u16 rmt_port)
+session_lookup_rules_table_session6 (session_table_t * st, u8 proto,
+                                    ip6_address_t * lcl, u16 lcl_port,
+                                    ip6_address_t * rmt, u16 rmt_port)
 {
   session_rules_table_t *srt = &st->session_rules[proto];
-  u32 action_index, session_index;
+  u32 action_index, app_index;
   action_index = session_rules_table_lookup6 (srt, lcl, rmt, lcl_port,
                                              rmt_port);
-  session_index = session_lookup_action_to_session_index (action_index);
-  return session_lookup_app_listen_session (session_index, FIB_PROTOCOL_IP6,
+  app_index = session_lookup_action_to_app_index (action_index);
+  return session_lookup_app_listen_session (app_index, FIB_PROTOCOL_IP6,
                                            proto);
 }
 
@@ -477,8 +493,8 @@ session_lookup_endpoint_listener (u32 table_index, session_endpoint_t * sep,
          srt = &st->session_rules[sep->transport_proto];
          ai = session_rules_table_lookup4 (srt, &lcl4, &sep->ip.ip4, 0,
                                            sep->port);
-         if (ai != SESSION_RULES_TABLE_INVALID_INDEX)
-           return session_lookup_action_to_session_index (ai);
+         if (session_lookup_action_index_is_valid (ai))
+           return session_lookup_action_to_app_index (ai);
        }
     }
   else
@@ -497,8 +513,8 @@ session_lookup_endpoint_listener (u32 table_index, session_endpoint_t * sep,
          srt = &st->session_rules[sep->transport_proto];
          ai = session_rules_table_lookup6 (srt, &lcl6, &sep->ip.ip6, 0,
                                            sep->port);
-         if (ai != SESSION_RULES_TABLE_INVALID_INDEX)
-           return session_lookup_action_to_session_index (ai);
+         if (session_lookup_action_index_is_valid (ai))
+           return session_lookup_action_to_app_index (ai);
        }
     }
   return SESSION_INVALID_HANDLE;
@@ -545,10 +561,8 @@ session_lookup_local_endpoint (u32 table_index, session_endpoint_t * sep)
       srt = &st->session_rules[sep->transport_proto];
       ai = session_rules_table_lookup4 (srt, &lcl4, &sep->ip.ip4, 0,
                                        sep->port);
-      if (ai == SESSION_RULES_TABLE_ACTION_DROP)
-       return APP_DROP_INDEX;
-      if (ai != SESSION_RULES_TABLE_ACTION_NONE)
-       return session_lookup_action_to_session_index (ai);
+      if (session_lookup_action_index_is_valid (ai))
+       return session_lookup_action_to_app_index (ai);
 
       /*
        * Check if session endpoint is a listener
@@ -585,10 +599,8 @@ session_lookup_local_endpoint (u32 table_index, session_endpoint_t * sep)
       srt = &st->session_rules[sep->transport_proto];
       ai = session_rules_table_lookup6 (srt, &lcl6, &sep->ip.ip6, 0,
                                        sep->port);
-      if (ai == SESSION_RULES_TABLE_ACTION_DROP)
-       return APP_DROP_INDEX;
-      if (ai != SESSION_RULES_TABLE_INVALID_INDEX)
-       return session_lookup_action_to_session_index (ai);
+      if (session_lookup_action_index_is_valid (ai))
+       return session_lookup_action_to_app_index (ai);
 
       make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port,
                           sep->transport_proto);
@@ -828,13 +840,15 @@ session_lookup_half_open_connection (u64 handle, u8 proto, u8 is_ip4)
  * @param rmt_port     remote port
  * @param proto                transport protocol (e.g., tcp, udp)
  * @param thread_index thread index for request
+ * @param is_filtered  return flag that indicates if connection was filtered.
  *
  * @return pointer to transport connection, if one is found, 0 otherwise
  */
 transport_connection_t *
 session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl,
                               ip4_address_t * rmt, u16 lcl_port,
-                              u16 rmt_port, u8 proto, u32 thread_index)
+                              u16 rmt_port, u8 proto, u32 thread_index,
+                              u8 * is_filtered)
 {
   session_table_t *st;
   session_kv4_t kv4;
@@ -874,14 +888,14 @@ session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl,
    */
   action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl,
                                              rmt, lcl_port, rmt_port);
-  if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
-    return 0;
-  if (action_index != SESSION_RULES_TABLE_ACTION_NONE)
+  if (session_lookup_action_index_is_valid (action_index))
     {
-      s = session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4,
-                                           proto);
-      if (s)
+      if ((*is_filtered = (action_index == SESSION_RULES_TABLE_ACTION_DROP)))
+       return 0;
+      if ((s = session_lookup_action_to_session (action_index,
+                                                FIB_PROTOCOL_IP4, proto)))
        return tp_vfts[s->session_type].get_listener (s->connection_index);
+      return 0;
     }
 
   /*
@@ -952,14 +966,14 @@ session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl,
    */
   action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl,
                                              rmt, lcl_port, rmt_port);
-  if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
-    return 0;
-  if (action_index != SESSION_RULES_TABLE_ACTION_NONE)
+  if (session_lookup_action_index_is_valid (action_index))
     {
-      s = session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4,
-                                           proto);
-      if (s)
+      if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
+       return 0;
+      if ((s = session_lookup_action_to_session (action_index,
+                                                FIB_PROTOCOL_IP4, proto)))
        return tp_vfts[s->session_type].get_listener (s->connection_index);
+      return 0;
     }
 
   /*
@@ -1012,13 +1026,12 @@ session_lookup_safe4 (u32 fib_index, ip4_address_t * lcl, ip4_address_t * rmt,
    */
   action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl,
                                              rmt, lcl_port, rmt_port);
-  if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
-    return 0;
-  if (action_index != SESSION_RULES_TABLE_ACTION_NONE)
+  if (session_lookup_action_index_is_valid (action_index))
     {
-      if ((s = session_lookup_action_to_session (action_index,
-                                                FIB_PROTOCOL_IP4, proto)))
-       return s;
+      if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
+       return 0;
+      return session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4,
+                                              proto);
     }
 
   /*
@@ -1058,7 +1071,8 @@ session_lookup_safe4 (u32 fib_index, ip4_address_t * lcl, ip4_address_t * rmt,
 transport_connection_t *
 session_lookup_connection_wt6 (u32 fib_index, ip6_address_t * lcl,
                               ip6_address_t * rmt, u16 lcl_port,
-                              u16 rmt_port, u8 proto, u32 thread_index)
+                              u16 rmt_port, u8 proto, u32 thread_index,
+                              u8 * is_filtered)
 {
   session_table_t *st;
   stream_session_t *s;
@@ -1091,14 +1105,14 @@ session_lookup_connection_wt6 (u32 fib_index, ip6_address_t * lcl,
   /* Check the session rules table */
   action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
                                              rmt, lcl_port, rmt_port);
-  if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
-    return 0;
-  if (action_index != SESSION_RULES_TABLE_ACTION_NONE)
+  if (session_lookup_action_index_is_valid (action_index))
     {
-      s = session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4,
-                                           proto);
-      if (s)
+      if ((*is_filtered = (action_index == SESSION_RULES_TABLE_ACTION_DROP)))
+       return 0;
+      if ((s = session_lookup_action_to_session (action_index,
+                                                FIB_PROTOCOL_IP6, proto)))
        return tp_vfts[s->session_type].get_listener (s->connection_index);
+      return 0;
     }
 
   /* If nothing is found, check if any listener is available */
@@ -1160,14 +1174,14 @@ session_lookup_connection6 (u32 fib_index, ip6_address_t * lcl,
   /* Check the session rules table */
   action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
                                              rmt, lcl_port, rmt_port);
-  if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
-    return 0;
-  if (action_index != SESSION_RULES_TABLE_ACTION_NONE)
+  if (session_lookup_action_index_is_valid (action_index))
     {
-      s = session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4,
-                                           proto);
-      if (s)
+      if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
+       return 0;
+      if ((s = session_lookup_action_to_session (action_index,
+                                                FIB_PROTOCOL_IP6, proto)))
        return tp_vfts[s->session_type].get_listener (s->connection_index);
+      return 0;
     }
 
   /* If nothing is found, check if any listener is available */
@@ -1213,14 +1227,12 @@ session_lookup_safe6 (u32 fib_index, ip6_address_t * lcl, ip6_address_t * rmt,
   /* Check the session rules table */
   action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
                                              rmt, lcl_port, rmt_port);
-  if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
-    return 0;
-  if (action_index != SESSION_RULES_TABLE_ACTION_NONE)
+  if (session_lookup_action_index_is_valid (action_index))
     {
-      if ((s =
-          session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4,
-                                            proto)))
-       return s;
+      if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
+       return 0;
+      return session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP6,
+                                              proto);
     }
 
   /* If nothing is found, check if any listener is available */
@@ -1639,8 +1651,8 @@ show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input,
 VLIB_CLI_COMMAND (show_session_rules_command, static) =
 {
   .path = "show session rules",
-  .short_help = "show session rules [appns <id> proto <proto> <lcl-ip/plen>"
-      " <lcl-port> <rmt-ip/plen> <rmt-port>]",
+  .short_help = "show session rules [<proto> appns <id> <lcl-ip/plen> "
+      "<lcl-port> <rmt-ip/plen> <rmt-port> scope <scope>]",
   .function = show_session_rules_command_fn,
 };
 /* *INDENT-ON* */
index 00ef19f..1bdf6d1 100644 (file)
@@ -32,7 +32,8 @@ transport_connection_t *session_lookup_connection_wt4 (u32 fib_index,
                                                       ip4_address_t * rmt,
                                                       u16 lcl_port,
                                                       u16 rmt_port, u8 proto,
-                                                      u32 thread_index);
+                                                      u32 thread_index,
+                                                      u8 * is_filtered);
 transport_connection_t *session_lookup_connection4 (u32 fib_index,
                                                    ip4_address_t * lcl,
                                                    ip4_address_t * rmt,
@@ -43,7 +44,8 @@ transport_connection_t *session_lookup_connection_wt6 (u32 fib_index,
                                                       ip6_address_t * rmt,
                                                       u16 lcl_port,
                                                       u16 rmt_port, u8 proto,
-                                                      u32 thread_index);
+                                                      u32 thread_index,
+                                                      u8 * is_filtered);
 transport_connection_t *session_lookup_connection6 (u32 fib_index,
                                                    ip6_address_t * lcl,
                                                    ip6_address_t * rmt,
index ecd2d9b..9088afc 100644 (file)
@@ -56,8 +56,8 @@ typedef CLIB_PACKED (struct
 
 #define SESSION_RULE_TAG_MAX_LEN 64
 #define SESSION_RULES_TABLE_INVALID_INDEX MMA_TABLE_INVALID_INDEX
-#define SESSION_RULES_TABLE_ACTION_DROP (((u32)~0) - 1)
-#define SESSION_RULES_TABLE_ACTION_NONE SESSION_RULES_TABLE_INVALID_INDEX
+#define SESSION_RULES_TABLE_ACTION_DROP (MMA_TABLE_INVALID_INDEX - 1)
+#define SESSION_RULES_TABLE_ACTION_ALLOW (MMA_TABLE_INVALID_INDEX - 2)
 
 typedef struct _session_rules_table_add_del_args
 {
index 8194a31..58d0d28 100644 (file)
@@ -496,7 +496,8 @@ session_test_namespace (vlib_main_t * vm, unformat_input_t * input)
    * Cleanup
    */
   vec_free (ns_id);
-  vnet_delete_loopback_interface (sw_if_index);
+  /* fails in multi core scenarions .. */
+  /* vnet_delete_loopback_interface (sw_if_index); */
   return 0;
 }
 
@@ -780,11 +781,11 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
   transport_connection_t *tc;
   u32 dummy_port = 1111;
   clib_error_t *error = 0;
-  u8 segment_name[128];
+  u8 segment_name[128], is_filtered = 0;
   stream_session_t *listener, *s;
   app_namespace_t *default_ns = app_namespace_get_default ();
   u32 local_ns_index = default_ns->local_table_index;
-  int verbose = 0;
+  int verbose = 0, rv;
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
@@ -852,7 +853,8 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
 
   tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
                                      &rmt_pref.fp_addr.ip4, lcl_port,
-                                     rmt_port, TRANSPORT_PROTO_TCP, 0);
+                                     rmt_port, TRANSPORT_PROTO_TCP, 0,
+                                     &is_filtered);
   SESSION_TEST ((tc == 0), "optimized lookup should not work (port)");
 
   /*
@@ -878,7 +880,8 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
                "optimized lookup should return the listener");
   tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
                                      &rmt_pref.fp_addr.ip4, lcl_port,
-                                     rmt_port, TRANSPORT_PROTO_TCP, 0);
+                                     rmt_port, TRANSPORT_PROTO_TCP, 0,
+                                     &is_filtered);
   SESSION_TEST ((tc->c_index == listener->connection_index),
                "lookup should return the listener");
   s = session_lookup_safe4 (0, &lcl_pref.fp_addr.ip4, &rmt_pref.fp_addr.ip4,
@@ -897,7 +900,8 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
 
   tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
                                      &rmt_pref.fp_addr.ip4, lcl_port + 1,
-                                     rmt_port, TRANSPORT_PROTO_TCP, 0);
+                                     rmt_port, TRANSPORT_PROTO_TCP, 0,
+                                     &is_filtered);
   SESSION_TEST ((tc == 0),
                "optimized lookup for wrong lcl port + 1 should not work");
 
@@ -911,7 +915,8 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
                args.table_args.action_index);
   tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
                                      &rmt_pref.fp_addr.ip4, lcl_port + 1,
-                                     rmt_port, TRANSPORT_PROTO_TCP, 0);
+                                     rmt_port, TRANSPORT_PROTO_TCP, 0,
+                                     &is_filtered);
   SESSION_TEST ((tc->c_index == listener->connection_index),
                "optimized lookup for lcl port + 1 should work");
   app_index = session_lookup_local_endpoint (local_ns_index, &sep);
@@ -923,12 +928,12 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
    */
   args.table_args.lcl_port = 1234;
   args.table_args.lcl.fp_addr.ip4 = lcl_ip;
-  args.table_args.lcl.fp_len = 32;
+  args.table_args.lcl.fp_len = 30;
   args.table_args.rmt.fp_addr.ip4 = rmt_ip;
-  args.table_args.rmt.fp_len = 32;
+  args.table_args.rmt.fp_len = 30;
   args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
   error = vnet_session_rule_add_del (&args);
-  SESSION_TEST ((error == 0), "Add 1.2.3.4/32 1234 5.6.7.8/32 4321 action %d",
+  SESSION_TEST ((error == 0), "Add 1.2.3.4/30 1234 5.6.7.8/30 4321 action %d",
                args.table_args.action_index);
 
   if (verbose)
@@ -941,26 +946,97 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
 
   tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
                                      &rmt_pref.fp_addr.ip4, lcl_port,
-                                     rmt_port, TRANSPORT_PROTO_TCP, 0);
+                                     rmt_port, TRANSPORT_PROTO_TCP, 0,
+                                     &is_filtered);
   SESSION_TEST ((tc == 0), "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 "
                "should fail (deny rule)");
+  SESSION_TEST ((is_filtered == 1), "lookup should be filtered (deny)");
+
   app_index = session_lookup_local_endpoint (local_ns_index, &sep);
   SESSION_TEST ((app_index == APP_DROP_INDEX), "lookup for 1.2.3.4/32 1234 "
                "5.6.7.8/16 4321 in local table should return deny");
-  tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
-                                     &rmt_pref.fp_addr.ip4, lcl_port,
-                                     rmt_port, TRANSPORT_PROTO_TCP, 0);
-  SESSION_TEST ((tc == 0),
-               "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 should not work");
+
   tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
                                      &rmt_pref.fp_addr.ip4, lcl_port + 1,
-                                     rmt_port, TRANSPORT_PROTO_TCP, 0);
+                                     rmt_port, TRANSPORT_PROTO_TCP, 0,
+                                     &is_filtered);
   SESSION_TEST ((tc->c_index == listener->connection_index),
                "lookup 1.2.3.4/32 123*5* 5.6.7.8/16 4321 should work");
 
+  /*
+   * "Mask" deny rule with more specific allow:
+   * Add allow rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -3 (allow)
+   */
+  args.table_args.is_add = 1;
+  args.table_args.lcl_port = 1234;
+  args.table_args.lcl.fp_addr.ip4 = lcl_ip;
+  args.table_args.lcl.fp_len = 32;
+  args.table_args.rmt.fp_addr.ip4 = rmt_ip;
+  args.table_args.rmt.fp_len = 32;
+  args.table_args.action_index = SESSION_RULES_TABLE_ACTION_ALLOW;
+  error = vnet_session_rule_add_del (&args);
+  SESSION_TEST ((error == 0), "Add masking rule 1.2.3.4/30 1234 5.6.7.8/32 "
+               "4321 action %d", args.table_args.action_index);
+
+  is_filtered = 0;
+  tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
+                                     &rmt_pref.fp_addr.ip4, lcl_port,
+                                     rmt_port, TRANSPORT_PROTO_TCP, 0,
+                                     &is_filtered);
+  SESSION_TEST ((tc == 0), "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 "
+               "should fail (allow without app)");
+  SESSION_TEST ((is_filtered == 0), "lookup should NOT be filtered");
+
+  app_index = session_lookup_local_endpoint (local_ns_index, &sep);
+  SESSION_TEST ((app_index == APP_INVALID_INDEX), "lookup for 1.2.3.4/32 1234"
+               " 5.6.7.8/16 4321 in local table should return invalid");
+
+  if (verbose)
+    {
+      vlib_cli_output (vm, "Local rules");
+      session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
+                                            TRANSPORT_PROTO_TCP);
+    }
+
+  sep.ip.ip4.as_u32 += 1 << 24;
+  app_index = session_lookup_local_endpoint (local_ns_index, &sep);
+  SESSION_TEST ((app_index == APP_DROP_INDEX), "lookup for 1.2.3.4/32 1234"
+               " 5.6.7.9/16 4321 in local table should return invalid");
+
+  vnet_connect_args_t connect_args = {
+    .sep = sep,
+    .app_index = attach_args.app_index,
+    .api_context = 0,
+  };
+
+  /* Try connecting */
+  error = vnet_connect (&connect_args);
+  SESSION_TEST ((error != 0), "connect should fail");
+  rv = clib_error_get_code (error);
+  SESSION_TEST ((rv == VNET_API_ERROR_APP_CONNECT_FILTERED),
+               "connect should be filtered");
+
+  sep.ip.ip4.as_u32 -= 1 << 24;
+
+
+
+  /*
+   * Delete masking rule: 1.2.3.4/32 1234 5.6.7.8/32 4321 allow
+   */
+  args.table_args.is_add = 0;
+  args.table_args.lcl_port = 1234;
+  args.table_args.lcl.fp_addr.ip4 = lcl_ip;
+  args.table_args.lcl.fp_len = 32;
+  args.table_args.rmt.fp_addr.ip4 = rmt_ip;
+  args.table_args.rmt.fp_len = 32;
+  error = vnet_session_rule_add_del (&args);
+  SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 allow");
+
+
   /*
    * Add local scope rule for 0/0 * 5.6.7.8/16 4321 action server_index
    */
+  args.table_args.is_add = 1;
   args.table_args.lcl_port = 0;
   args.table_args.lcl.fp_len = 0;
   args.table_args.rmt.fp_len = 16;
@@ -979,7 +1055,7 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
 
   app_index = session_lookup_local_endpoint (local_ns_index, &sep);
   SESSION_TEST ((app_index == APP_DROP_INDEX),
-               "local session endpoint lookup " "should return deny");
+               "local session endpoint lookup should return deny");
 
   /*
    * Delete 1.2.3.4/32 1234 5.6.7.8/32 4321 deny
@@ -987,9 +1063,9 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
   args.table_args.is_add = 0;
   args.table_args.lcl_port = 1234;
   args.table_args.lcl.fp_addr.ip4 = lcl_ip;
-  args.table_args.lcl.fp_len = 32;
+  args.table_args.lcl.fp_len = 30;
   args.table_args.rmt.fp_addr.ip4 = rmt_ip;
-  args.table_args.rmt.fp_len = 32;
+  args.table_args.rmt.fp_len = 30;
   error = vnet_session_rule_add_del (&args);
   SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny");
 
@@ -1028,7 +1104,8 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
   SESSION_TEST ((error == 0), "Del 1.2.3.4/16 * 5.6.7.8/16 4321");
   tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
                                      &rmt_pref.fp_addr.ip4, lcl_port + 1,
-                                     rmt_port, TRANSPORT_PROTO_TCP, 0);
+                                     rmt_port, TRANSPORT_PROTO_TCP, 0,
+                                     &is_filtered);
   SESSION_TEST ((tc == 0),
                "lookup 1.2.3.4/32 123*5* 5.6.7.8/16 4321 should not "
                "work (del)");
@@ -1044,14 +1121,16 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
   SESSION_TEST ((error == 0), "Del 1.2.3.4/16 1234 5.6.7.8/16 4321");
   tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
                                      &rmt_pref.fp_addr.ip4, lcl_port,
-                                     rmt_port, TRANSPORT_PROTO_TCP, 0);
+                                     rmt_port, TRANSPORT_PROTO_TCP, 0,
+                                     &is_filtered);
   SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should "
                "not work (del + deny)");
 
   SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny");
   tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
                                      &rmt_pref.fp_addr.ip4, lcl_port,
-                                     rmt_port, TRANSPORT_PROTO_TCP, 0);
+                                     rmt_port, TRANSPORT_PROTO_TCP, 0,
+                                     &is_filtered);
   SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should"
                " not work (no-rule)");
 
@@ -1079,7 +1158,8 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
     }
   tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
                                      &rmt_pref.fp_addr.ip4, lcl_port,
-                                     rmt_port, TRANSPORT_PROTO_TCP, 0);
+                                     rmt_port, TRANSPORT_PROTO_TCP, 0,
+                                     &is_filtered);
   SESSION_TEST ((tc->c_index == listener->connection_index),
                "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should work");
 
@@ -1097,7 +1177,8 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
                "tag test_rule");
   tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
                                      &rmt_pref.fp_addr.ip4, lcl_port,
-                                     rmt_port, TRANSPORT_PROTO_TCP, 0);
+                                     rmt_port, TRANSPORT_PROTO_TCP, 0,
+                                     &is_filtered);
   SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should not"
                " work (del)");
   vec_free (args.table_args.tag);
@@ -1118,7 +1199,7 @@ session_test_proxy (vlib_main_t * vm, unformat_input_t * input)
   u32 server_index, app_index;
   u32 dummy_server_api_index = ~0, sw_if_index = 0;
   clib_error_t *error = 0;
-  u8 segment_name[128], intf_mac[6], sst;
+  u8 segment_name[128], intf_mac[6], sst, is_filtered = 0;
   stream_session_t *s;
   transport_connection_t *tc;
   u16 lcl_port = 1234, rmt_port = 4321;
@@ -1202,7 +1283,7 @@ session_test_proxy (vlib_main_t * vm, unformat_input_t * input)
     }
 
   tc = session_lookup_connection_wt4 (0, &lcl_ip, &rmt_ip, lcl_port, rmt_port,
-                                     TRANSPORT_PROTO_TCP, 0);
+                                     TRANSPORT_PROTO_TCP, 0, &is_filtered);
   SESSION_TEST ((tc != 0), "lookup 1.2.3.4 1234 5.6.7.8 4321 should be "
                "successful");
   sst = session_type_from_proto_and_ip (TRANSPORT_PROTO_TCP, 1);
@@ -1211,7 +1292,7 @@ session_test_proxy (vlib_main_t * vm, unformat_input_t * input)
                " server");
 
   tc = session_lookup_connection_wt4 (0, &rmt_ip, &rmt_ip, lcl_port, rmt_port,
-                                     TRANSPORT_PROTO_TCP, 0);
+                                     TRANSPORT_PROTO_TCP, 0, &is_filtered);
   SESSION_TEST ((tc == 0), "lookup 5.6.7.8 1234 5.6.7.8 4321 should"
                " not work");
 
@@ -1237,7 +1318,8 @@ session_test_proxy (vlib_main_t * vm, unformat_input_t * input)
   app_index = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
   SESSION_TEST ((app_index == SESSION_RULES_TABLE_INVALID_INDEX),
                "local session endpoint lookup should not work after detach");
-  unformat_free (&tmp_input);
+  if (verbose)
+    unformat_free (&tmp_input);
   return 0;
 }
 
index a179717..5bff5ee 100644 (file)
@@ -40,4 +40,5 @@ tcp_error (INVALID_CONNECTION, "Invalid connection")
 tcp_error (NO_WND, "No window")
 tcp_error (CONNECTION_CLOSED, "Connection closed")
 tcp_error (CREATE_EXISTS, "Connection already exists")
-tcp_error (PUNT, "Packets punted")
\ No newline at end of file
+tcp_error (PUNT, "Packets punted")
+tcp_error (FILTERED, "Packets filtered")
\ No newline at end of file
index 6d7beba..d3db7ef 100644 (file)
@@ -1902,6 +1902,7 @@ tcp_lookup_connection (u32 fib_index, vlib_buffer_t * b, u8 thread_index,
   tcp_header_t *tcp;
   transport_connection_t *tconn;
   tcp_connection_t *tc;
+  u8 is_filtered = 0;
   if (is_ip4)
     {
       ip4_header_t *ip4;
@@ -1913,7 +1914,7 @@ tcp_lookup_connection (u32 fib_index, vlib_buffer_t * b, u8 thread_index,
                                             tcp->dst_port,
                                             tcp->src_port,
                                             TRANSPORT_PROTO_TCP,
-                                            thread_index);
+                                            thread_index, &is_filtered);
       tc = tcp_get_connection_from_transport (tconn);
       ASSERT (tcp_lookup_is_valid (tc, tcp));
     }
@@ -1928,7 +1929,7 @@ tcp_lookup_connection (u32 fib_index, vlib_buffer_t * b, u8 thread_index,
                                             tcp->dst_port,
                                             tcp->src_port,
                                             TRANSPORT_PROTO_TCP,
-                                            thread_index);
+                                            thread_index, &is_filtered);
       tc = tcp_get_connection_from_transport (tconn);
       ASSERT (tcp_lookup_is_valid (tc, tcp));
     }
@@ -2939,7 +2940,7 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
          ip4_header_t *ip40;
          ip6_header_t *ip60;
          u32 error0 = TCP_ERROR_NO_LISTENER, next0 = TCP_INPUT_NEXT_DROP;
-         u8 flags0;
+         u8 flags0, is_filtered = 0;
 
          bi0 = from[0];
          to_next[0] = bi0;
@@ -2968,9 +2969,8 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
                                                     tcp0->dst_port,
                                                     tcp0->src_port,
                                                     TRANSPORT_PROTO_TCP,
-                                                    my_thread_index);
-             tc0 = tcp_get_connection_from_transport (tconn);
-             ASSERT (tcp_lookup_is_valid (tc0, tcp0));
+                                                    my_thread_index,
+                                                    &is_filtered);
            }
          else
            {
@@ -2986,9 +2986,8 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
                                                     tcp0->dst_port,
                                                     tcp0->src_port,
                                                     TRANSPORT_PROTO_TCP,
-                                                    my_thread_index);
-             tc0 = tcp_get_connection_from_transport (tconn);
-             ASSERT (tcp_lookup_is_valid (tc0, tcp0));
+                                                    my_thread_index,
+                                                    &is_filtered);
            }
 
          /* Length check */
@@ -2999,8 +2998,11 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
            }
 
          /* Session exists */
-         if (PREDICT_TRUE (0 != tc0))
+         if (PREDICT_TRUE (0 != tconn))
            {
+             tc0 = tcp_get_connection_from_transport (tconn);
+             ASSERT (tcp_lookup_is_valid (tc0, tcp0));
+
              /* Save connection index */
              vnet_buffer (b0)->tcp.connection_index = tc0->c_c_index;
              vnet_buffer (b0)->tcp.seq_number =
@@ -3032,8 +3034,13 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
            }
          else
            {
-             if ((is_ip4 && tm->punt_unknown4) ||
-                 (!is_ip4 && tm->punt_unknown6))
+             if (is_filtered)
+               {
+                 next0 = TCP_INPUT_NEXT_DROP;
+                 error0 = TCP_ERROR_FILTERED;
+               }
+             else if ((is_ip4 && tm->punt_unknown4) ||
+                      (!is_ip4 && tm->punt_unknown6))
                {
                  next0 = TCP_INPUT_NEXT_PUNT;
                  error0 = TCP_ERROR_PUNT;
@@ -3044,6 +3051,7 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
                  next0 = TCP_INPUT_NEXT_RESET;
                  error0 = TCP_ERROR_NO_LISTENER;
                }
+             tc0 = 0;
            }
 
        done:
@@ -3051,8 +3059,8 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
 
          if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
            {
-             tcp_rx_trace_t *t0 =
-               vlib_add_trace (vm, node, b0, sizeof (*t0));
+             tcp_rx_trace_t *t0;
+             t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
              tcp_set_rx_trace_data (t0, tc0, tcp0, b0, is_ip4);
            }
          vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
index 021f416..e3cdb1b 100644 (file)
@@ -1558,7 +1558,7 @@ tcp_test_lookup (vlib_main_t * vm, unformat_input_t * input)
   transport_connection_t _tc1, *tc1 = &_tc1, _tc2, *tc2 = &_tc2, *tconn;
   tcp_connection_t *tc;
   stream_session_t *s;
-  u8 cmp = 0;
+  u8 cmp = 0, is_filtered = 0;
 
   pool_get (smm->sessions[0], s);
   memset (s, 0, sizeof (*s));
@@ -1601,7 +1601,7 @@ tcp_test_lookup (vlib_main_t * vm, unformat_input_t * input)
   tconn = session_lookup_connection_wt4 (0, &tc1->lcl_ip.ip4,
                                         &tc1->rmt_ip.ip4,
                                         tc1->lcl_port, tc1->rmt_port,
-                                        tc1->proto, 0);
+                                        tc1->proto, 0, &is_filtered);
   cmp = (memcmp (&tconn->rmt_ip, &tc1->rmt_ip, sizeof (tc1->rmt_ip)) == 0);
   TCP_TEST ((cmp), "rmt ip is identical %d", cmp);
   TCP_TEST ((tconn->lcl_port == tc1->lcl_port),
@@ -1614,7 +1614,7 @@ tcp_test_lookup (vlib_main_t * vm, unformat_input_t * input)
   tconn = session_lookup_connection_wt4 (0, &tc2->lcl_ip.ip4,
                                         &tc2->rmt_ip.ip4,
                                         tc2->lcl_port, tc2->rmt_port,
-                                        tc2->proto, 0);
+                                        tc2->proto, 0, &is_filtered);
   TCP_TEST ((tconn == 0), "lookup result should be null");
 
   /*
@@ -1624,12 +1624,12 @@ tcp_test_lookup (vlib_main_t * vm, unformat_input_t * input)
   tconn = session_lookup_connection_wt4 (0, &tc1->lcl_ip.ip4,
                                         &tc1->rmt_ip.ip4,
                                         tc1->lcl_port, tc1->rmt_port,
-                                        tc1->proto, 0);
+                                        tc1->proto, 0, &is_filtered);
   TCP_TEST ((tconn == 0), "lookup result should be null");
   tconn = session_lookup_connection_wt4 (0, &tc2->lcl_ip.ip4,
                                         &tc2->rmt_ip.ip4,
                                         tc2->lcl_port, tc2->rmt_port,
-                                        tc2->proto, 0);
+                                        tc2->proto, 0, &is_filtered);
   TCP_TEST ((tconn == 0), "lookup result should be null");
 
   /*
@@ -1639,7 +1639,7 @@ tcp_test_lookup (vlib_main_t * vm, unformat_input_t * input)
   tconn = session_lookup_connection_wt4 (0, &tc2->lcl_ip.ip4,
                                         &tc2->rmt_ip.ip4,
                                         tc2->lcl_port, tc2->rmt_port,
-                                        tc2->proto, 0);
+                                        tc2->proto, 0, &is_filtered);
   TCP_TEST ((tconn == 0), "lookup result should be null");
 
   return 0;