session: support drop action in rules table 11/9211/2
authorFlorin Coras <fcoras@cisco.com>
Fri, 3 Nov 2017 04:31:46 +0000 (21:31 -0700)
committerDamjan Marion <dmarion.lists@gmail.com>
Fri, 3 Nov 2017 08:19:41 +0000 (08:19 +0000)
Change-Id: Ided2980373ed5329c68f958f61be893428bccd31
Signed-off-by: Florin Coras <fcoras@cisco.com>
src/vnet/session/mma_template.c
src/vnet/session/session_lookup.c
src/vnet/session/session_rules_table.h
src/vnet/session/session_test.c

index a838669..6efb2ff 100644 (file)
@@ -99,11 +99,11 @@ RT (mma_rules_table_lookup) (RTT (mma_rules_table) * srt,
   ASSERT (rp);
 
   if (!RT (rule_is_match_for_key) (key, rp))
-    return ~0;
+    return SESSION_RULES_TABLE_INVALID_INDEX;
   for (i = 0; i < vec_len (rp->next_indices); i++)
     {
       rv = RT (mma_rules_table_lookup) (srt, key, rp->next_indices[i]);
-      if (rv != ~0)
+      if (rv != SESSION_RULES_TABLE_INVALID_INDEX)
        return (rv);
     }
   return (rp->action_index);
@@ -123,11 +123,11 @@ RT (mma_rules_table_lookup_rule) (RTT (mma_rules_table) * srt,
   ASSERT (rp);
 
   if (!RT (rule_is_match_for_key) (key, rp))
-    return ~0;
+    return SESSION_RULES_TABLE_INVALID_INDEX;
   for (i = 0; i < vec_len (rp->next_indices); i++)
     {
       rv = RT (mma_rules_table_lookup_rule) (srt, key, rp->next_indices[i]);
-      if (rv != ~0)
+      if (rv != SESSION_RULES_TABLE_INVALID_INDEX)
        return (rv);
     }
   return rule_index;
@@ -218,7 +218,7 @@ RT (mma_rules_table_del_rule) (RTT (mma_rules_table) * srt,
   rp = RT (mma_rules_table_get_rule) (srt, rule_index);
 
   if (!RT (rule_is_match_for_key) (&rule->match, rp))
-    return ~0;
+    return SESSION_RULES_TABLE_INVALID_INDEX;
   if (RT (rule_is_exact_match) (rule, rp))
     {
       if (rule_index == srt->root_index)
@@ -257,7 +257,7 @@ RT (mma_rules_table_del_rule) (RTT (mma_rules_table) * srt,
       else if (rv == 0)
        return rv;
     }
-  return ~0;
+  return SESSION_RULES_TABLE_INVALID_INDEX;
 }
 
 /*
index 58af2bc..c55712e 100644 (file)
@@ -339,6 +339,14 @@ session_lookup_del_session (stream_session_t * s)
   return session_lookup_del_connection (ts);
 }
 
+static u32
+session_lookup_action_to_session (u32 action_index)
+{
+  if (action_index != SESSION_RULES_TABLE_ACTION_DROP)
+    return action_index;
+  return SESSION_INVALID_INDEX;
+}
+
 static stream_session_t *
 session_lookup_app_listen_session (u32 app_index, u8 fib_proto,
                                   u8 transport_proto)
@@ -356,11 +364,12 @@ session_lookup_rules_table4 (session_rules_table_t * srt, u8 proto,
                             ip4_address_t * lcl, u16 lcl_port,
                             ip4_address_t * rmt, u16 rmt_port)
 {
-  u32 action_index;
+  u32 action_index, session_index;
   action_index = session_rules_table_lookup4 (srt, proto, lcl, rmt, lcl_port,
                                              rmt_port);
+  session_index = session_lookup_action_to_session (action_index);
   /* Nothing sophisticated for now, action index is app index */
-  return session_lookup_app_listen_session (action_index, FIB_PROTOCOL_IP4,
+  return session_lookup_app_listen_session (session_index, FIB_PROTOCOL_IP4,
                                            proto);
 }
 
@@ -369,10 +378,11 @@ session_lookup_rules_table6 (session_rules_table_t * srt, u8 proto,
                             ip6_address_t * lcl, u16 lcl_port,
                             ip6_address_t * rmt, u16 rmt_port)
 {
-  u32 action_index;
+  u32 action_index, session_index;
   action_index = session_rules_table_lookup6 (srt, proto, lcl, rmt, lcl_port,
                                              rmt_port);
-  return session_lookup_app_listen_session (action_index, FIB_PROTOCOL_IP6,
+  session_index = session_lookup_action_to_session (action_index);
+  return session_lookup_app_listen_session (session_index, FIB_PROTOCOL_IP6,
                                            proto);
 }
 
@@ -384,7 +394,7 @@ session_lookup_session_endpoint (u32 table_index, session_endpoint_t * sep)
   session_kv6_t kv6;
   ip4_address_t lcl4;
   ip6_address_t lcl6;
-  u32 si;
+  u32 ai;
   int rv;
 
   st = session_table_get (table_index);
@@ -399,11 +409,11 @@ session_lookup_session_endpoint (u32 table_index, session_endpoint_t * sep)
        return kv4.value;
 
       memset (&lcl4, 0, sizeof (lcl4));
-      si =
-       session_rules_table_lookup4 (&st->session_rules, sep->transport_proto,
-                                    &lcl4, &sep->ip.ip4, 0, sep->port);
-      if (si != SESSION_RULES_TABLE_INVALID_INDEX)
-       return si;
+      ai = session_rules_table_lookup4 (&st->session_rules,
+                                       sep->transport_proto, &lcl4,
+                                       &sep->ip.ip4, 0, sep->port);
+      if (ai != SESSION_RULES_TABLE_INVALID_INDEX)
+       return session_lookup_action_to_session (ai);
     }
   else
     {
@@ -414,11 +424,11 @@ session_lookup_session_endpoint (u32 table_index, session_endpoint_t * sep)
        return kv6.value;
 
       memset (&lcl6, 0, sizeof (lcl6));
-      si =
-       session_rules_table_lookup6 (&st->session_rules, sep->transport_proto,
-                                    &lcl6, &sep->ip.ip6, 0, sep->port);
-      if (si != SESSION_RULES_TABLE_INVALID_INDEX)
-       return si;
+      ai = session_rules_table_lookup6 (&st->session_rules,
+                                       sep->transport_proto, &lcl6,
+                                       &sep->ip.ip6, 0, sep->port);
+      if (ai != SESSION_RULES_TABLE_INVALID_INDEX)
+       return session_lookup_action_to_session (ai);
     }
   return SESSION_INVALID_HANDLE;
 }
@@ -475,7 +485,7 @@ session_lookup_local_session_endpoint (u32 table_index,
   session_kv6_t kv6;
   ip4_address_t lcl4;
   ip6_address_t lcl6;
-  u32 si;
+  u32 ai;
   int rv;
 
   st = session_table_get (table_index);
@@ -499,11 +509,11 @@ session_lookup_local_session_endpoint (u32 table_index,
        return (u32) kv4.value;
 
       memset (&lcl4, 0, sizeof (lcl4));
-      si =
-       session_rules_table_lookup4 (&st->session_rules, sep->transport_proto,
-                                    &lcl4, &sep->ip.ip4, 0, sep->port);
-      if (si != SESSION_RULES_TABLE_INVALID_INDEX)
-       return si;
+      ai = session_rules_table_lookup4 (&st->session_rules,
+                                       sep->transport_proto, &lcl4,
+                                       &sep->ip.ip4, 0, sep->port);
+      if (ai != SESSION_RULES_TABLE_INVALID_INDEX)
+       return session_lookup_action_to_session (ai);
     }
   else
     {
@@ -522,11 +532,11 @@ session_lookup_local_session_endpoint (u32 table_index,
        return (u32) kv6.value;
 
       memset (&lcl6, 0, sizeof (lcl6));
-      si =
-       session_rules_table_lookup6 (&st->session_rules, sep->transport_proto,
-                                    &lcl6, &sep->ip.ip6, 0, sep->port);
-      if (si != SESSION_RULES_TABLE_INVALID_INDEX)
-       return si;
+      ai = session_rules_table_lookup6 (&st->session_rules,
+                                       sep->transport_proto, &lcl6,
+                                       &sep->ip.ip6, 0, sep->port);
+      if (ai != SESSION_RULES_TABLE_INVALID_INDEX)
+       return session_lookup_action_to_session (ai);
     }
   return SESSION_INVALID_INDEX;
 }
@@ -1115,8 +1125,8 @@ vnet_session_rule_add_del (session_rule_add_del_args_t * args)
   if (args->scope & SESSION_RULE_SCOPE_LOCAL)
     {
       st = app_namespace_get_local_table (app_ns);
-      error =
-       session_rules_table_add_del (&st->session_rules, &args->table_args);
+      error = session_rules_table_add_del (&st->session_rules,
+                                          &args->table_args);
     }
   return error;
 }
index e9d573a..27b0f88 100644 (file)
@@ -65,6 +65,8 @@ typedef struct _session_rules_table_add_del_args
   u8 is_add;
 } session_rule_table_add_del_args_t;
 
+#define SESSION_RULES_TABLE_ACTION_DROP (((u32)~0) - 1)
+
 typedef struct _session_rules_table_t
 {
   /**
index 4b47754..a3e76c2 100644 (file)
@@ -732,6 +732,19 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
   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;
+
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (input, "verbose"))
+       verbose = 1;
+      else
+       {
+         vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
+                          input);
+         return -1;
+       }
+    }
 
   server_sep.is_ip4 = 1;
   server_sep.port = dummy_port;
@@ -834,7 +847,7 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
                                      &rmt_pref.fp_addr.ip4, lcl_port + 1,
                                      rmt_port, TRANSPORT_PROTO_TCP, 0);
   SESSION_TEST ((tc == 0),
-               "optimized lookup for wrong lcl port + 1 should not" " work");
+               "optimized lookup for wrong lcl port + 1 should not work");
 
   /*
    * Add 1.2.3.4/16 * 5.6.7.8/16 4321
@@ -853,13 +866,52 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
   SESSION_TEST ((app_index != server_index), "local session endpoint lookup "
                "should not work (constrained lcl ip)");
 
+  /*
+   * Add drop rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -2 (drop)
+   */
+  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_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",
+               args.table_args.action_index);
+
+  if (verbose)
+    {
+      session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
+                                      TRANSPORT_PROTO_TCP);
+      session_lookup_dump_local_rules_table (0, FIB_PROTOCOL_IP4,
+                                            TRANSPORT_PROTO_TCP);
+    }
+
+  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 fail (drop rule)");
+
   /*
    * Add local scope rule for 0/0 * 5.6.7.8/16 4321 action server_index
    */
+  args.table_args.lcl_port = 0;
   args.table_args.lcl.fp_len = 0;
+  args.table_args.rmt.fp_len = 16;
+  args.table_args.action_index = server_index;
   error = vnet_session_rule_add_del (&args);
   SESSION_TEST ((error == 0), "Add * * 5.6.7.8/16 4321 action %d",
                args.table_args.action_index);
+
+  if (verbose)
+    {
+      session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
+                                      TRANSPORT_PROTO_TCP);
+      session_lookup_dump_local_rules_table (0, FIB_PROTOCOL_IP4,
+                                            TRANSPORT_PROTO_TCP);
+    }
+
   app_index = session_lookup_local_session_endpoint (local_ns_index, &sep);
   SESSION_TEST ((app_index == server_index), "local session endpoint lookup "
                "should work");
@@ -892,7 +944,21 @@ 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);
-  SESSION_TEST ((tc == 0), "optimized lookup should not work (del)");
+  SESSION_TEST ((tc == 0),
+               "optimized lookup should not work (del + negative)");
+
+  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 drop");
+  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), "optimized lookup should not work (no-rule)");
   return 0;
 }