session: add rule tags 34/9234/2
authorFlorin Coras <fcoras@cisco.com>
Mon, 6 Nov 2017 07:07:07 +0000 (23:07 -0800)
committerDave Barach <openvpp@barachs.net>
Mon, 6 Nov 2017 21:45:22 +0000 (21:45 +0000)
Change-Id: Id5ebb410f509ac4c83d60e48efd54e00035e5ce6
Signed-off-by: Florin Coras <fcoras@cisco.com>
14 files changed:
src/vat/api_format.c
src/vnet/session/application.c
src/vnet/session/mma_template.c
src/vnet/session/mma_template.h
src/vnet/session/session.api
src/vnet/session/session_api.c
src/vnet/session/session_lookup.c
src/vnet/session/session_lookup.h
src/vnet/session/session_rules_table.c
src/vnet/session/session_rules_table.h
src/vnet/session/session_table.c
src/vnet/session/session_table.h
src/vnet/session/session_test.c
src/vpp/api/custom_dump.c

index f27d51a..c972c19 100644 (file)
@@ -21560,19 +21560,21 @@ vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
 
   if (mp->is_ip4)
     {
-      print (vam->ofp, "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d",
+      print (vam->ofp,
+            "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
             mp->appns_index, mp->transport_proto, mp->scope,
             format_ip4_address, &mp->lcl_ip, mp->lcl_plen, mp->lcl_port,
             format_ip4_address, &mp->rmt_ip, mp->rmt_plen, mp->rmt_port,
-            mp->action_index);
+            mp->action_index, mp->tag);
     }
   else
     {
-      print (vam->ofp, "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d",
+      print (vam->ofp,
+            "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
             mp->appns_index, mp->transport_proto, mp->scope,
             format_ip6_address, &mp->lcl_ip, mp->lcl_plen, mp->lcl_port,
             format_ip6_address, &mp->rmt_ip, mp->rmt_plen, mp->rmt_port,
-            mp->action_index);
+            mp->action_index, mp->tag);
     }
 }
 
@@ -21606,6 +21608,7 @@ vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
                            clib_net_to_host_u16 (mp->rmt_port));
   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
+  vat_json_object_add_string_copy (node, "tag", mp->tag);
   if (mp->is_ip4)
     {
       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
@@ -21632,7 +21635,7 @@ api_session_rule_add_del (vat_main_t * vam)
   ip4_address_t lcl_ip4, rmt_ip4;
   ip6_address_t lcl_ip6, rmt_ip6;
   u8 is_ip4 = 1, conn_set = 0;
-  u8 is_add = 1;
+  u8 is_add = 1, *tag = 0;
   int ret;
 
   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
@@ -21649,6 +21652,8 @@ api_session_rule_add_del (vat_main_t * vam)
        ;
       else if (unformat (i, "scope %d", &scope))
        ;
+      else if (unformat (i, "tag %_%v%_", &tag))
+       ;
       else
        if (unformat
            (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
@@ -21688,8 +21693,10 @@ api_session_rule_add_del (vat_main_t * vam)
 
   mp->is_ip4 = is_ip4;
   mp->transport_proto = proto;
-  mp->lcl_plen = clib_host_to_net_u16 (lcl_plen);
-  mp->rmt_plen = clib_host_to_net_u16 (rmt_plen);
+  mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
+  mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
+  mp->lcl_plen = lcl_plen;
+  mp->rmt_plen = rmt_plen;
   mp->action_index = clib_host_to_net_u32 (action);
   mp->appns_index = clib_host_to_net_u32 (appns_index);
   mp->scope = scope;
@@ -21704,6 +21711,11 @@ api_session_rule_add_del (vat_main_t * vam)
       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
     }
+  if (tag)
+    {
+      clib_memcpy (mp->tag, tag, vec_len (tag));
+      vec_free (tag);
+    }
 
   S (mp);
   W (ret);
index c16b4da..9a519c7 100644 (file)
@@ -558,6 +558,7 @@ application_start_stop_proxy_fib_proto (application_t * app, u8 fib_proto,
 
   if (!ip_is_zero (&tc->lcl_ip, 1))
     {
+      memset (&args, 0, sizeof (args));
       memset (&lcl_pref, 0, sizeof (lcl_pref));
       ip_copy (&lcl_pref.fp_addr, &tc->lcl_ip, is_ip4);
       lcl_pref.fp_len = is_ip4 ? 32 : 128;
@@ -572,7 +573,7 @@ application_start_stop_proxy_fib_proto (application_t * app, u8 fib_proto,
       args.table_args.rmt_port = 0;
       args.table_args.action_index = app->index;
       args.table_args.is_add = is_start;
-      args.table_args.transport_proto = transport_proto;
+      args.transport_proto = transport_proto;
       args.appns_index = app->ns_index;
       args.scope = SESSION_RULE_SCOPE_GLOBAL;
       return vnet_session_rule_add_del (&args);
@@ -595,7 +596,7 @@ application_start_stop_proxy (application_t * app, u8 transport_proto,
       args.table_args.rmt_port = 0;
       args.table_args.action_index = app->index;
       args.table_args.is_add = is_start;
-      args.table_args.transport_proto = transport_proto;
+      args.transport_proto = transport_proto;
       args.appns_index = app->ns_index;
       args.scope = SESSION_RULE_SCOPE_LOCAL;
       vnet_session_rule_add_del (&args);
index 6efb2ff..248ced6 100644 (file)
@@ -94,16 +94,16 @@ RT (mma_rules_table_lookup) (RTT (mma_rules_table) * srt,
   u32 rv;
   int i;
 
-  ASSERT (rule_index != SESSION_RULES_TABLE_INVALID_INDEX);
+  ASSERT (rule_index != MMA_TABLE_INVALID_INDEX);
   rp = RT (mma_rules_table_get_rule) (srt, rule_index);
   ASSERT (rp);
 
   if (!RT (rule_is_match_for_key) (key, rp))
-    return SESSION_RULES_TABLE_INVALID_INDEX;
+    return MMA_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 != SESSION_RULES_TABLE_INVALID_INDEX)
+      if (rv != MMA_TABLE_INVALID_INDEX)
        return (rv);
     }
   return (rp->action_index);
@@ -118,16 +118,16 @@ RT (mma_rules_table_lookup_rule) (RTT (mma_rules_table) * srt,
   u32 rv;
   int i;
 
-  ASSERT (rule_index != SESSION_RULES_TABLE_INVALID_INDEX);
+  ASSERT (rule_index != MMA_TABLE_INVALID_INDEX);
   rp = RT (mma_rules_table_get_rule) (srt, rule_index);
   ASSERT (rp);
 
   if (!RT (rule_is_match_for_key) (key, rp))
-    return SESSION_RULES_TABLE_INVALID_INDEX;
+    return MMA_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 != SESSION_RULES_TABLE_INVALID_INDEX)
+      if (rv != MMA_TABLE_INVALID_INDEX)
        return (rv);
     }
   return rule_index;
@@ -214,15 +214,15 @@ RT (mma_rules_table_del_rule) (RTT (mma_rules_table) * srt,
   u32 rv;
   int i;
 
-  ASSERT (rule_index != SESSION_RULES_TABLE_INVALID_INDEX);
+  ASSERT (rule_index != MMA_TABLE_INVALID_INDEX);
   rp = RT (mma_rules_table_get_rule) (srt, rule_index);
 
   if (!RT (rule_is_match_for_key) (&rule->match, rp))
-    return SESSION_RULES_TABLE_INVALID_INDEX;
+    return MMA_TABLE_INVALID_INDEX;
   if (RT (rule_is_exact_match) (rule, rp))
     {
       if (rule_index == srt->root_index)
-       rp->action_index = SESSION_RULES_TABLE_INVALID_INDEX;
+       rp->action_index = MMA_TABLE_INVALID_INDEX;
       return 1;
     }
   for (i = 0; i < vec_len (rp->next_indices); i++)
@@ -257,7 +257,7 @@ RT (mma_rules_table_del_rule) (RTT (mma_rules_table) * srt,
       else if (rv == 0)
        return rv;
     }
-  return SESSION_RULES_TABLE_INVALID_INDEX;
+  return MMA_TABLE_INVALID_INDEX;
 }
 
 /*
index 8b6fd75..fd5e3ea 100644 (file)
@@ -30,7 +30,7 @@
 #define __rtt(a, b) _rtt(a,b)
 #define RTT(a) __rtt(a, MMA_RT_TYPE)
 
-#define SESSION_RULES_TABLE_INVALID_INDEX ((u32)~0)
+#define MMA_TABLE_INVALID_INDEX ((u32)~0)
 
 typedef struct
 {
@@ -79,7 +79,8 @@ RT (session_rule_free) (RTT (mma_rules_table) * srt, RTT (mma_rule) * rule);
 RTT (mma_rule) *
 RT (mma_table_get_rule) (RTT (mma_rules_table) * srt, u32 srt_index);
 u32
-RT (mma_table_rule_index) (RTT (mma_rules_table) * srt, RTT (mma_rule) * sr);
+RT (mma_rules_table_rule_index) (RTT (mma_rules_table) * srt,
+                                RTT (mma_rule) * sr);
 #endif /* SRC_VNET_SESSION_MMA_TEMPLATE_H_ */
 
 /*
index 8de0922..6ed75ef 100644 (file)
@@ -395,6 +395,7 @@ autoreply define session_rule_add_del {
   u8 is_add;
   u32 appns_index;
   u8 scope;
+  u8 tag[64];
 };
 
 /** \brief Dump session rules
@@ -439,6 +440,7 @@ define session_rules_details
   u32 action_index;
   u32 appns_index;
   u8 scope;
+  u8 tag[64];
 };
 
 /*
index 7ca87a5..fc0a257 100755 (executable)
@@ -792,6 +792,7 @@ vl_api_session_rule_add_del_t_handler (vl_api_session_rule_add_del_t * mp)
   u8 fib_proto;
   int rv = 0;
 
+  memset (&args, 0, sizeof (args));
   fib_proto = mp->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
 
   table_args->lcl.fp_len = mp->lcl_plen;
@@ -802,6 +803,8 @@ vl_api_session_rule_add_del_t_handler (vl_api_session_rule_add_del_t * mp)
   table_args->rmt_port = clib_net_to_host_u16 (mp->rmt_port);
   table_args->action_index = clib_net_to_host_u32 (mp->action_index);
   table_args->is_add = mp->is_add;
+  mp->tag[sizeof (mp->tag) - 1] = 0;
+  table_args->tag = format (0, "%s", mp->tag);
   args.appns_index = clib_net_to_host_u32 (mp->appns_index);
   args.scope = mp->scope;
 
@@ -815,12 +818,13 @@ vl_api_session_rule_add_del_t_handler (vl_api_session_rule_add_del_t * mp)
       rv = clib_error_get_code (error);
       clib_error_report (error);
     }
+  vec_free (table_args->tag);
   REPLY_MACRO (VL_API_SESSION_RULE_ADD_DEL_REPLY);
 }
 
 static void
 send_session_rule_details4 (mma_rule_16_t * rule, u8 is_local,
-                           u8 transport_proto, u32 appns_index,
+                           u8 transport_proto, u32 appns_index, u8 * tag,
                            unix_shared_memory_queue_t * q, u32 context)
 {
   vl_api_session_rules_details_t *rmp = 0;
@@ -846,13 +850,18 @@ send_session_rule_details4 (mma_rule_16_t * rule, u8 is_local,
     is_local ? SESSION_RULE_SCOPE_LOCAL : SESSION_RULE_SCOPE_GLOBAL;
   rmp->transport_proto = transport_proto;
   rmp->appns_index = clib_host_to_net_u32 (appns_index);
+  if (tag)
+    {
+      clib_memcpy (rmp->tag, tag, vec_len (tag));
+      rmp->tag[vec_len (tag)] = 0;
+    }
 
   vl_msg_api_send_shmem (q, (u8 *) & rmp);
 }
 
 static void
-send_session_rule_details6 (mma_rule_40_t * rule, u8 scope,
-                           u8 transport_proto, u32 appns_index,
+send_session_rule_details6 (mma_rule_40_t * rule, u8 is_local,
+                           u8 transport_proto, u32 appns_index, u8 * tag,
                            unix_shared_memory_queue_t * q, u32 context)
 {
   vl_api_session_rules_details_t *rmp = 0;
@@ -874,46 +883,55 @@ send_session_rule_details6 (mma_rule_40_t * rule, u8 scope,
   rmp->lcl_port = clib_host_to_net_u16 (match->lcl_port);
   rmp->rmt_port = clib_host_to_net_u16 (match->rmt_port);
   rmp->action_index = clib_host_to_net_u32 (rule->action_index);
-  rmp->scope = scope;
+  rmp->scope =
+    is_local ? SESSION_RULE_SCOPE_LOCAL : SESSION_RULE_SCOPE_GLOBAL;
   rmp->transport_proto = transport_proto;
   rmp->appns_index = clib_host_to_net_u32 (appns_index);
+  if (tag)
+    {
+      clib_memcpy (rmp->tag, tag, vec_len (tag));
+      rmp->tag[vec_len (tag)] = 0;
+    }
 
   vl_msg_api_send_shmem (q, (u8 *) & rmp);
 }
 
 static void
 send_session_rules_table_details (session_rules_table_t * srt, u8 fib_proto,
-                                 u8 is_local, u32 appns_index,
+                                 u8 tp, u8 is_local, u32 appns_index,
                                  unix_shared_memory_queue_t * q, u32 context)
 {
   mma_rule_16_t *rule16;
   mma_rule_40_t *rule40;
   mma_rules_table_16_t *srt16;
   mma_rules_table_40_t *srt40;
-  u8 tp;
+  u32 ri;
 
-  for (tp = 0; tp < TRANSPORT_N_PROTO; tp++)
+  if (is_local || fib_proto == FIB_PROTOCOL_IP4)
     {
-      if (is_local || fib_proto == FIB_PROTOCOL_IP4)
-       {
-          /* *INDENT-OFF* */
-          srt16 = &srt->session_rules_tables_16[tp];
-          pool_foreach (rule16, srt16->rules, ({
-            send_session_rule_details4 (rule16, is_local, tp,
-                                        appns_index, q, context);
-          }));
-          /* *INDENT-ON* */
-       }
-      if (is_local || fib_proto == FIB_PROTOCOL_IP6)
-       {
-          /* *INDENT-OFF* */
-          srt40 = &srt->session_rules_tables_40[tp];
-          pool_foreach (rule40, srt40->rules, ({
-            send_session_rule_details6 (rule40, is_local, tp,
-                                        appns_index, q, context);
-          }));
-          /* *INDENT-ON* */
-       }
+      u8 *tag = 0;
+      /* *INDENT-OFF* */
+      srt16 = &srt->session_rules_tables_16;
+      pool_foreach (rule16, srt16->rules, ({
+       ri = mma_rules_table_rule_index_16 (srt16, rule16);
+       tag = session_rules_table_rule_tag (srt, ri, 1);
+        send_session_rule_details4 (rule16, is_local, tp, appns_index, tag,
+                                    q, context);
+      }));
+      /* *INDENT-ON* */
+    }
+  if (is_local || fib_proto == FIB_PROTOCOL_IP6)
+    {
+      u8 *tag = 0;
+      /* *INDENT-OFF* */
+      srt40 = &srt->session_rules_tables_40;
+      pool_foreach (rule40, srt40->rules, ({
+       ri = mma_rules_table_rule_index_40 (srt40, rule40);
+       tag = session_rules_table_rule_tag (srt, ri, 1);
+        send_session_rule_details6 (rule40, is_local, tp, appns_index, tag,
+                                    q, context);
+      }));
+      /* *INDENT-ON* */
     }
 }
 
@@ -922,6 +940,7 @@ vl_api_session_rules_dump_t_handler (vl_api_one_map_server_dump_t * mp)
 {
   unix_shared_memory_queue_t *q = NULL;
   session_table_t *st;
+  u8 tp;
 
   q = vl_api_client_index_to_input_queue (mp->client_index);
   if (q == 0)
@@ -929,9 +948,13 @@ vl_api_session_rules_dump_t_handler (vl_api_one_map_server_dump_t * mp)
 
   /* *INDENT-OFF* */
   session_table_foreach (st, ({
-    send_session_rules_table_details (&st->session_rules, st->active_fib_proto,
-                                      st->is_local, st->appns_index, q,
-                                      mp->context);
+    for (tp = 0; tp < TRANSPORT_N_PROTO; tp++)
+      {
+        send_session_rules_table_details (&st->session_rules[tp],
+                                          st->active_fib_proto, tp,
+                                          st->is_local, st->appns_index, q,
+                                          mp->context);
+      }
   }));
   /* *INDENT-ON* */
 }
index d537b9c..6cdb839 100644 (file)
@@ -368,12 +368,13 @@ session_lookup_app_listen_session (u32 app_index, u8 fib_proto,
 }
 
 stream_session_t *
-session_lookup_rules_table4 (session_rules_table_t * srt, u8 proto,
+session_lookup_rules_table4 (session_table_t * st, u8 proto,
                             ip4_address_t * lcl, u16 lcl_port,
                             ip4_address_t * rmt, u16 rmt_port)
 {
+  session_rules_table_t *srt = &st->session_rules[proto];
   u32 action_index, session_index;
-  action_index = session_rules_table_lookup4 (srt, proto, lcl, rmt, lcl_port,
+  action_index = session_rules_table_lookup4 (srt, lcl, rmt, lcl_port,
                                              rmt_port);
   session_index = session_lookup_action_to_session (action_index);
   /* Nothing sophisticated for now, action index is app index */
@@ -382,12 +383,13 @@ session_lookup_rules_table4 (session_rules_table_t * srt, u8 proto,
 }
 
 stream_session_t *
-session_lookup_rules_table6 (session_rules_table_t * srt, u8 proto,
+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_rules_table_t *srt = &st->session_rules[proto];
   u32 action_index, session_index;
-  action_index = session_rules_table_lookup6 (srt, proto, lcl, rmt, lcl_port,
+  action_index = session_rules_table_lookup6 (srt, lcl, rmt, lcl_port,
                                              rmt_port);
   session_index = session_lookup_action_to_session (action_index);
   return session_lookup_app_listen_session (session_index, FIB_PROTOCOL_IP6,
@@ -397,6 +399,7 @@ session_lookup_rules_table6 (session_rules_table_t * srt, u8 proto,
 u64
 session_lookup_session_endpoint (u32 table_index, session_endpoint_t * sep)
 {
+  session_rules_table_t *srt;
   session_table_t *st;
   session_kv4_t kv4;
   session_kv6_t kv6;
@@ -417,9 +420,9 @@ session_lookup_session_endpoint (u32 table_index, session_endpoint_t * sep)
        return kv4.value;
 
       memset (&lcl4, 0, sizeof (lcl4));
-      ai = session_rules_table_lookup4 (&st->session_rules,
-                                       sep->transport_proto, &lcl4,
-                                       &sep->ip.ip4, 0, sep->port);
+      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 (ai);
     }
@@ -432,9 +435,9 @@ session_lookup_session_endpoint (u32 table_index, session_endpoint_t * sep)
        return kv6.value;
 
       memset (&lcl6, 0, sizeof (lcl6));
-      ai = session_rules_table_lookup6 (&st->session_rules,
-                                       sep->transport_proto, &lcl6,
-                                       &sep->ip.ip6, 0, sep->port);
+      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 (ai);
     }
@@ -466,8 +469,7 @@ session_lookup_global_session_endpoint (session_endpoint_t * sep)
       if (rv == 0)
        return session_get_from_handle (kv4.value);
       memset (&lcl4, 0, sizeof (lcl4));
-      return session_lookup_rules_table4 (&st->session_rules,
-                                         sep->transport_proto, &lcl4, 0,
+      return session_lookup_rules_table4 (st, sep->transport_proto, &lcl4, 0,
                                          &sep->ip.ip4, sep->port);
     }
   else
@@ -478,8 +480,7 @@ session_lookup_global_session_endpoint (session_endpoint_t * sep)
       if (rv == 0)
        return session_get_from_handle (kv6.value);
       memset (&lcl6, 0, sizeof (lcl6));
-      return session_lookup_rules_table6 (&st->session_rules,
-                                         sep->transport_proto, &lcl6, 0,
+      return session_lookup_rules_table6 (st, sep->transport_proto, &lcl6, 0,
                                          &sep->ip.ip6, sep->port);
     }
 }
@@ -488,6 +489,7 @@ u32
 session_lookup_local_session_endpoint (u32 table_index,
                                       session_endpoint_t * sep)
 {
+  session_rules_table_t *srt;
   session_table_t *st;
   session_kv4_t kv4;
   session_kv6_t kv6;
@@ -517,9 +519,9 @@ session_lookup_local_session_endpoint (u32 table_index,
        return (u32) kv4.value;
 
       memset (&lcl4, 0, sizeof (lcl4));
-      ai = session_rules_table_lookup4 (&st->session_rules,
-                                       sep->transport_proto, &lcl4,
-                                       &sep->ip.ip4, 0, sep->port);
+      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 (ai);
     }
@@ -540,9 +542,9 @@ session_lookup_local_session_endpoint (u32 table_index,
        return (u32) kv6.value;
 
       memset (&lcl6, 0, sizeof (lcl6));
-      ai = session_rules_table_lookup6 (&st->session_rules,
-                                       sep->transport_proto, &lcl6,
-                                       &sep->ip.ip6, 0, sep->port);
+      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 (ai);
     }
@@ -723,20 +725,20 @@ session_lookup_half_open_connection (u64 handle, u8 proto, u8 is_ip4)
   return 0;
 }
 
-transport_connection_t *
-session_lookup_rules_table_connection4 (session_rules_table_t * srt, u8 proto,
+static transport_connection_t *
+session_lookup_rules_table_connection4 (session_table_t * st, u8 proto,
                                        ip4_address_t * lcl, u16 lcl_port,
                                        ip4_address_t * rmt, u16 rmt_port)
 {
   stream_session_t *s;
-  s = session_lookup_rules_table4 (srt, proto, lcl, lcl_port, rmt, rmt_port);
+  s = session_lookup_rules_table4 (st, proto, lcl, lcl_port, rmt, rmt_port);
   if (s)
     return tp_vfts[s->session_type].get_listener (s->connection_index);
   return 0;
 }
 
-transport_connection_t *
-session_lookup_rules_table_connection6 (session_rules_table_t * srt, u8 proto,
+static transport_connection_t *
+session_lookup_rules_table_connection6 (session_table_t * srt, u8 proto,
                                        ip6_address_t * lcl, u16 lcl_port,
                                        ip6_address_t * rmt, u16 rmt_port)
 {
@@ -811,9 +813,8 @@ session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl,
     }
 
   /* Check the session rules table */
-  return session_lookup_rules_table_connection4 (&st->session_rules, proto,
-                                                lcl, lcl_port, rmt,
-                                                rmt_port);
+  return session_lookup_rules_table_connection4 (st, proto, lcl, lcl_port,
+                                                rmt, rmt_port);
 }
 
 /**
@@ -869,9 +870,8 @@ session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl,
       return tp_vfts[sst].get_half_open (kv4.value & 0xFFFFFFFF);
     }
   /* Check the session rules table */
-  return session_lookup_rules_table_connection4 (&st->session_rules, proto,
-                                                lcl, lcl_port, rmt,
-                                                rmt_port);
+  return session_lookup_rules_table_connection4 (st, proto, lcl, lcl_port,
+                                                rmt, rmt_port);
 }
 
 /**
@@ -909,7 +909,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)))
     return s;
-  return session_lookup_rules_table4 (&st->session_rules, proto, lcl,
+  return session_lookup_rules_table4 (st, proto, lcl,
                                      lcl_port, rmt, rmt_port);
 }
 
@@ -975,9 +975,8 @@ session_lookup_connection_wt6 (u32 fib_index, ip6_address_t * lcl,
       return tp_vfts[sst].get_half_open (kv6.value & 0xFFFFFFFF);
     }
 
-  return session_lookup_rules_table_connection6 (&st->session_rules, proto,
-                                                lcl, lcl_port, rmt,
-                                                rmt_port);
+  return session_lookup_rules_table_connection6 (st, proto, lcl, lcl_port,
+                                                rmt, rmt_port);
 }
 
 /**
@@ -1032,9 +1031,8 @@ session_lookup_connection6 (u32 fib_index, ip6_address_t * lcl,
       return tp_vfts[sst].get_half_open (kv6.value & 0xFFFFFFFF);
     }
 
-  return session_lookup_rules_table_connection6 (&st->session_rules, proto,
-                                                lcl, lcl_port, rmt,
-                                                rmt_port);
+  return session_lookup_rules_table_connection6 (st, proto, lcl, lcl_port,
+                                                rmt, rmt_port);
 }
 
 /**
@@ -1071,7 +1069,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)))
     return s;
-  return session_lookup_rules_table6 (&st->session_rules, proto, lcl,
+  return session_lookup_rules_table6 (st, proto, lcl,
                                      lcl_port, rmt, rmt_port);
 }
 
@@ -1110,6 +1108,7 @@ clib_error_t *
 vnet_session_rule_add_del (session_rule_add_del_args_t * args)
 {
   app_namespace_t *app_ns = app_namespace_get (args->appns_index);
+  session_rules_table_t *srt;
   session_table_t *st;
   u32 fib_index;
   u8 fib_proto;
@@ -1121,20 +1120,27 @@ vnet_session_rule_add_del (session_rule_add_del_args_t * args)
   if (args->scope > 3)
     return clib_error_return_code (0, VNET_API_ERROR_INVALID_VALUE, 0,
                                   "invalid scope");
+  if (args->transport_proto != TRANSPORT_PROTO_TCP
+      && args->transport_proto != TRANSPORT_PROTO_UDP)
+    return clib_error_return_code (0, VNET_API_ERROR_INVALID_VALUE, 0,
+                                  "invalid transport proto");
   if ((args->scope & SESSION_RULE_SCOPE_GLOBAL) || args->scope == 0)
     {
       fib_proto = args->table_args.rmt.fp_proto;
       fib_index = app_namespace_get_fib_index (app_ns, fib_proto);
       st = session_table_get_for_fib_index (fib_proto, fib_index);
-      if ((error = session_rules_table_add_del (&st->session_rules,
-                                               &args->table_args)))
-       return error;
+      srt = &st->session_rules[args->transport_proto];
+      if ((error = session_rules_table_add_del (srt, &args->table_args)))
+       {
+         clib_error_report (error);
+         return error;
+       }
     }
   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);
+      srt = &st->session_rules[args->transport_proto];
+      error = session_rules_table_add_del (srt, &args->table_args);
     }
   return error;
 }
@@ -1232,12 +1238,14 @@ static clib_error_t *
 session_rule_command_fn (vlib_main_t * vm, unformat_input_t * input,
                         vlib_cli_command_t * cmd)
 {
-  u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
+  u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen = 0, rmt_plen = 0;
   u32 appns_index, scope = 0;
   ip46_address_t lcl_ip, rmt_ip;
   u8 is_ip4 = 1, conn_set = 0;
   u8 fib_proto, is_add = 1, *ns_id = 0;
+  u8 *tag = 0;
   app_namespace_t *app_ns;
+  clib_error_t *error;
 
   memset (&lcl_ip, 0, sizeof (lcl_ip));
   memset (&rmt_ip, 0, sizeof (rmt_ip));
@@ -1275,19 +1283,42 @@ session_rule_command_fn (vlib_main_t * vm, unformat_input_t * input,
        }
       else if (unformat (input, "action %d", &action))
        ;
+      else if (unformat (input, "tag %_%v%_", &tag))
+       ;
       else
        return clib_error_return (0, "unknown input `%U'",
                                  format_unformat_error, input);
     }
 
-  if (proto == ~0 || !conn_set || action == ~0)
-    return clib_error_return (0, "proto, connection and action must be set");
+  if (proto == ~0)
+    {
+      vlib_cli_output (vm, "proto must be set");
+      return 0;
+    }
+  if (is_add && !conn_set && action == ~0)
+    {
+      vlib_cli_output (vm, "connection and action must be set for add");
+      return 0;
+    }
+  if (!is_add && !tag && !conn_set)
+    {
+      vlib_cli_output (vm, "connection or tag must be set for delete");
+      return 0;
+    }
+  if (vec_len (tag) > SESSION_RULE_TAG_MAX_LEN)
+    {
+      vlib_cli_output (vm, "tag too long (max u64)");
+      return 0;
+    }
 
   if (ns_id)
     {
       app_ns = app_namespace_get_from_id (ns_id);
       if (!app_ns)
-       return clib_error_return (0, "namespace %v does not exist", ns_id);
+       {
+         vlib_cli_output (vm, "namespace %v does not exist", ns_id);
+         return 0;
+       }
     }
   else
     {
@@ -1307,10 +1338,13 @@ session_rule_command_fn (vlib_main_t * vm, unformat_input_t * input,
     .table_args.rmt_port = rmt_port,
     .table_args.action_index = action,
     .table_args.is_add = is_add,
+    .table_args.tag = tag,
     .appns_index = appns_index,
     .scope = scope,
   };
-  return vnet_session_rule_add_del (&args);
+  error = vnet_session_rule_add_del (&args);
+  vec_free (tag);
+  return error;
 }
 
 /* *INDENT-OFF* */
@@ -1328,10 +1362,11 @@ session_lookup_dump_rules_table (u32 fib_index, u8 fib_proto,
                                 u8 transport_proto)
 {
   vlib_main_t *vm = vlib_get_main ();
+  session_rules_table_t *srt;
   session_table_t *st;
   st = session_table_get_for_fib_index (fib_index, fib_proto);
-  session_rules_table_cli_dump (vm, &st->session_rules, fib_proto,
-                               transport_proto);
+  srt = &st->session_rules[transport_proto];
+  session_rules_table_cli_dump (vm, srt, fib_proto);
 }
 
 void
@@ -1339,10 +1374,11 @@ session_lookup_dump_local_rules_table (u32 table_index, u8 fib_proto,
                                       u8 transport_proto)
 {
   vlib_main_t *vm = vlib_get_main ();
+  session_rules_table_t *srt;
   session_table_t *st;
   st = session_table_get (table_index);
-  session_rules_table_cli_dump (vm, &st->session_rules, fib_proto,
-                               transport_proto);
+  srt = &st->session_rules[transport_proto];
+  session_rules_table_cli_dump (vm, srt, fib_proto);
 }
 
 static clib_error_t *
@@ -1354,6 +1390,7 @@ show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input,
   ip46_address_t lcl_ip, rmt_ip;
   u8 is_ip4 = 1, show_one = 0;
   app_namespace_t *app_ns;
+  session_rules_table_t *srt;
   session_table_t *st;
   u8 *ns_id = 0, fib_proto;
 
@@ -1423,16 +1460,17 @@ show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input,
 
   if (show_one)
     {
-      session_rules_table_show_rule (vm, &st->session_rules, transport_proto,
-                                    &lcl_ip, lcl_port, &rmt_ip, rmt_port,
-                                    is_ip4);
+      srt = &st->session_rules[transport_proto];
+      session_rules_table_show_rule (vm, srt, &lcl_ip, lcl_port, &rmt_ip,
+                                    rmt_port, is_ip4);
       return 0;
     }
 
-  session_rules_table_cli_dump (vm, &st->session_rules, FIB_PROTOCOL_IP4,
-                               transport_proto);
-  session_rules_table_cli_dump (vm, &st->session_rules, FIB_PROTOCOL_IP6,
-                               transport_proto);
+  vlib_cli_output (vm, "%U rules table", format_transport_proto,
+                  transport_proto);
+  srt = &st->session_rules[transport_proto];
+  session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4);
+  session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP6);
 
   vec_free (ns_id);
   return 0;
index fa89727..246ab52 100644 (file)
@@ -113,6 +113,10 @@ typedef struct _session_rule_add_del_args
    * Rule scope flag.
    */
   u8 scope;
+  /**
+   * Transport protocol for the rule
+   */
+  u8 transport_proto;
 } session_rule_add_del_args_t;
 
 clib_error_t *vnet_session_rule_add_del (session_rule_add_del_args_t * args);
index 685871d..fa8a056 100644 (file)
 #include <vnet/session/session_rules_table.h>
 #include <vnet/session/transport.h>
 
+u32
+session_rule_tag_key_index (u32 ri, u8 is_ip4)
+{
+  return ((ri << 1) | is_ip4);
+}
+
+void
+session_rule_tag_key_index_parse (u32 rti_key, u32 * ri, u8 * is_ip4)
+{
+  *is_ip4 = rti_key & 1;
+  *ri = rti_key >> 1;
+}
+
+u8 *
+session_rules_table_rule_tag (session_rules_table_t * srt, u32 ri, u8 is_ip4)
+{
+  uword *tip;
+  session_rule_tag_t *rt;
+
+  tip =
+    hash_get (srt->tags_by_rules, session_rule_tag_key_index (ri, is_ip4));
+  if (tip)
+    {
+      rt = pool_elt_at_index (srt->rule_tags, *tip);
+      return rt->tag;
+    }
+  return 0;
+}
+
+void
+session_rules_table_add_del_tag (session_rules_table_t * srt, u8 * tag,
+                                u32 rule_index, u8 is_ip4, u8 is_add)
+{
+  uword *rip, *rtip;
+  session_rule_tag_t *rt;
+  u32 rti_key;
+
+  if (tag == 0)
+    return;
+  if (is_add)
+    {
+      pool_get (srt->rule_tags, rt);
+      rt->tag = vec_dup (tag);
+      hash_set_mem (srt->rules_by_tag, rt->tag, rule_index);
+      rti_key = session_rule_tag_key_index (rule_index, is_ip4);
+      hash_set (srt->tags_by_rules, rti_key, rt - srt->rule_tags);
+    }
+  else
+    {
+      rip = hash_get_mem (srt->rules_by_tag, tag);
+      if (!rip)
+       {
+         clib_warning ("tag has no rule associated");
+         return;
+       }
+      rti_key = session_rule_tag_key_index (*rip, is_ip4);
+      rtip = hash_get (srt->tags_by_rules, rti_key);
+      if (!rtip)
+       {
+         clib_warning ("rule has no tag associated");
+         return;
+       }
+      rt = pool_elt_at_index (srt->rule_tags, *rtip);
+      ASSERT (rt);
+      hash_unset_mem (srt->rules_by_tag, tag);
+      hash_unset (srt->tags_by_rules, rti_key);
+      pool_put (srt->rule_tags, rt);
+    }
+}
+
+u32
+session_rules_table_rule_for_tag (session_rules_table_t * srt, u8 * tag)
+{
+  uword *rp;
+  if (tag == 0)
+    return SESSION_RULES_TABLE_INVALID_INDEX;
+  rp = hash_get_mem (srt->rules_by_tag, tag);
+  return (rp == 0 ? SESSION_RULES_TABLE_INVALID_INDEX : *rp);
+}
+
 static void
 fib_pref_normalize (fib_prefix_t * pref)
 {
@@ -32,64 +112,76 @@ fib_pref_normalize (fib_prefix_t * pref)
 u8 *
 format_session_rule4 (u8 * s, va_list * args)
 {
-  mma_rules_table_16_t *srt = va_arg (*args, mma_rules_table_16_t *);
+  session_rules_table_t *srt = va_arg (*args, session_rules_table_t *);
   mma_rule_16_t *sr = va_arg (*args, mma_rule_16_t *);
   session_mask_or_match_4_t *mask, *match;
+  mma_rules_table_16_t *srt4;
+  u8 *tag = 0, *null_tag = format (0, "none");
+  u32 ri;
   int i;
 
+  srt4 = &srt->session_rules_tables_16;
+  ri = mma_rules_table_rule_index_16 (srt4, sr);
+  tag = session_rules_table_rule_tag (srt, ri, 1);
   match = (session_mask_or_match_4_t *) & sr->match;
   mask = (session_mask_or_match_4_t *) & sr->mask;
 
-  s = format (s, "[%d] rule: %U/%d %d %U/%d %d action: %d",
-             mma_rules_table_rule_index_16 (srt, sr), format_ip4_address,
-             &match->lcl_ip,
-             ip4_mask_to_preflen (&mask->lcl_ip),
-             match->lcl_port, format_ip4_address, &match->rmt_ip,
-             ip4_mask_to_preflen (&mask->rmt_ip),
-             match->rmt_port, sr->action_index);
+  s = format (s, "[%d] rule: %U/%d %d %U/%d %d action: %d tag: %v", ri,
+             format_ip4_address, &match->lcl_ip,
+             ip4_mask_to_preflen (&mask->lcl_ip), match->lcl_port,
+             format_ip4_address, &match->rmt_ip,
+             ip4_mask_to_preflen (&mask->rmt_ip), match->rmt_port,
+             sr->action_index, tag ? tag : null_tag);
   if (vec_len (sr->next_indices))
     {
       s = format (s, "\n    children: ");
       for (i = 0; i < vec_len (sr->next_indices); i++)
        s = format (s, "%d ", sr->next_indices[i]);
     }
+  vec_free (null_tag);
   return s;
 }
 
 u8 *
 format_session_rule6 (u8 * s, va_list * args)
 {
-  mma_rules_table_40_t *srt = va_arg (*args, mma_rules_table_40_t *);
+  session_rules_table_t *srt = va_arg (*args, session_rules_table_t *);
   mma_rule_40_t *sr = va_arg (*args, mma_rule_40_t *);
   session_mask_or_match_6_t *mask, *match;
+  mma_rules_table_40_t *srt6;
+  u8 *tag = 0, *null_tag = format (0, "none");
+  u32 ri;
   int i;
 
+  srt6 = &srt->session_rules_tables_40;
+  ri = mma_rules_table_rule_index_40 (srt6, sr);
+  tag = session_rules_table_rule_tag (srt, ri, 0);
   match = (session_mask_or_match_6_t *) & sr->match;
   mask = (session_mask_or_match_6_t *) & sr->mask;
 
-  s = format (s, "[%d] rule: %U/%d %d %U/%d %d action: %d",
-             mma_rules_table_rule_index_40 (srt, sr), format_ip6_address,
-             &match->lcl_ip, ip6_mask_to_preflen (&mask->lcl_ip),
-             match->lcl_port, format_ip6_address, &match->rmt_ip,
+  s = format (s, "[%d] rule: %U/%d %d %U/%d %d action: %d tag: %v", ri,
+             format_ip6_address, &match->lcl_ip,
+             ip6_mask_to_preflen (&mask->lcl_ip), match->lcl_port,
+             format_ip6_address, &match->rmt_ip,
              ip6_mask_to_preflen (&mask->rmt_ip), match->rmt_port,
-             sr->action_index);
+             sr->action_index, tag ? tag : null_tag);
   if (vec_len (sr->next_indices))
     {
       s = format (s, "\n    children: ");
       for (i = 0; i < vec_len (sr->next_indices); i++)
        s = format (s, "%d ", sr->next_indices[i]);
     }
+  vec_free (null_tag);
   return s;
 }
 
 void *
-session_rules_table_get (session_rules_table_t * srt, u8 transport_proto,
-                        u8 fib_proto)
+session_rules_table_get (session_rules_table_t * srt, u8 fib_proto)
 {
   if (fib_proto == FIB_PROTOCOL_IP4)
-    return &srt->session_rules_tables_16[transport_proto];
+    return &srt->session_rules_tables_16;
   else if (fib_proto == FIB_PROTOCOL_IP6)
-    return &srt->session_rules_tables_40[transport_proto];
+    return &srt->session_rules_tables_40;
   return 0;
 }
 
@@ -208,61 +300,105 @@ session_rules_table_alloc_rule_40 (mma_rules_table_40_t * srt,
   return rule;
 }
 
+/**
+ * Add/delete session rule
+ *
+ * @param srt table where rule should be added
+ * @param args rule arguments
+ *
+ * @return 0 if success, clib_error_t error otherwise
+ */
 clib_error_t *
 session_rules_table_add_del (session_rules_table_t * srt,
                             session_rule_table_add_del_args_t * args)
 {
   u8 fib_proto = args->rmt.fp_proto;
+  u32 ri_from_tag, ri;
+  int rv;
 
-  if (args->transport_proto != TRANSPORT_PROTO_TCP
-      && args->transport_proto != TRANSPORT_PROTO_UDP)
+  ri_from_tag = session_rules_table_rule_for_tag (srt, args->tag);
+  if (args->is_add && ri_from_tag != SESSION_RULES_TABLE_INVALID_INDEX)
     return clib_error_return_code (0, VNET_API_ERROR_INVALID_VALUE, 0,
-                                  "invalid transport proto");
+                                  "tag exists");
 
   if (fib_proto == FIB_PROTOCOL_IP4)
     {
       mma_rules_table_16_t *srt4;
-      srt4 = &srt->session_rules_tables_16[args->transport_proto];
+      srt4 = &srt->session_rules_tables_16;
       if (args->is_add)
        {
-         mma_rule_16_t *rule;
-         rule = session_rules_table_alloc_rule_16 (srt4, &args->lcl,
-                                                   args->lcl_port,
-                                                   &args->rmt,
-                                                   args->rmt_port);
-         rule->action_index = args->action_index;
-         mma_rules_table_add_rule_16 (srt4, rule);
+         mma_rule_16_t *rule4;
+         rule4 = session_rules_table_alloc_rule_16 (srt4, &args->lcl,
+                                                    args->lcl_port,
+                                                    &args->rmt,
+                                                    args->rmt_port);
+         rule4->action_index = args->action_index;
+         rv = mma_rules_table_add_rule_16 (srt4, rule4);
+         if (!rv)
+           {
+             ri = mma_rules_table_rule_index_16 (srt4, rule4);
+             session_rules_table_add_del_tag (srt, args->tag, ri, 1, 1);
+           }
        }
       else
        {
-         mma_rule_16_t rule;
-         memset (&rule, 0, sizeof (rule));
-         session_rules_table_init_rule_16 (&rule, &args->lcl, args->lcl_port,
-                                           &args->rmt, args->rmt_port);
-         mma_rules_table_del_rule_16 (srt4, &rule, srt4->root_index);
+         mma_rule_16_t *rule;
+         if (ri_from_tag != SESSION_RULES_TABLE_INVALID_INDEX)
+           {
+             rule = mma_rules_table_get_rule_16 (srt4, ri_from_tag);
+             mma_rules_table_del_rule_16 (srt4, rule, srt4->root_index);
+             session_rules_table_add_del_tag (srt, args->tag, 0, 1, 0);
+           }
+         else
+           {
+             mma_rule_16_t _rule;
+             rule = &_rule;
+             memset (rule, 0, sizeof (*rule));
+             session_rules_table_init_rule_16 (rule, &args->lcl,
+                                               args->lcl_port, &args->rmt,
+                                               args->rmt_port);
+             mma_rules_table_del_rule_16 (srt4, rule, srt4->root_index);
+           }
        }
     }
   else if (fib_proto == FIB_PROTOCOL_IP6)
     {
       mma_rules_table_40_t *srt6;
-      mma_rule_40_t *rule;
-      srt6 = &srt->session_rules_tables_40[args->transport_proto];
+      mma_rule_40_t *rule6;
+      srt6 = &srt->session_rules_tables_40;
       if (args->is_add)
        {
-         rule = session_rules_table_alloc_rule_40 (srt6, &args->lcl,
-                                                   args->lcl_port,
-                                                   &args->rmt,
-                                                   args->rmt_port);
-         rule->action_index = args->action_index;
-         mma_rules_table_add_rule_40 (srt6, rule);
+         rule6 = session_rules_table_alloc_rule_40 (srt6, &args->lcl,
+                                                    args->lcl_port,
+                                                    &args->rmt,
+                                                    args->rmt_port);
+         rule6->action_index = args->action_index;
+         rv = mma_rules_table_add_rule_40 (srt6, rule6);
+         if (!rv)
+           {
+             ri = mma_rules_table_rule_index_40 (srt6, rule6);
+             session_rules_table_add_del_tag (srt, args->tag, ri, 0, 1);
+           }
        }
       else
        {
-         mma_rule_40_t rule;
-         memset (&rule, 0, sizeof (rule));
-         session_rules_table_init_rule_40 (&rule, &args->lcl, args->lcl_port,
-                                           &args->rmt, args->rmt_port);
-         mma_rules_table_del_rule_40 (srt6, &rule, srt6->root_index);
+         mma_rule_40_t *rule;
+         if (ri_from_tag != SESSION_RULES_TABLE_INVALID_INDEX)
+           {
+             rule = mma_rules_table_get_rule_40 (srt6, ri_from_tag);
+             mma_rules_table_del_rule_40 (srt6, rule, srt6->root_index);
+             session_rules_table_add_del_tag (srt, args->tag, 0, 0, 0);
+           }
+         else
+           {
+             mma_rule_40_t _rule;
+             rule = &_rule;
+             memset (rule, 0, sizeof (*rule));
+             session_rules_table_init_rule_40 (rule, &args->lcl,
+                                               args->lcl_port, &args->rmt,
+                                               args->rmt_port);
+             mma_rules_table_del_rule_40 (srt6, rule, srt6->root_index);
+           }
        }
     }
   else
@@ -272,36 +408,34 @@ session_rules_table_add_del (session_rules_table_t * srt,
 }
 
 u32
-session_rules_table_lookup4 (session_rules_table_t * srt, u8 transport_proto,
+session_rules_table_lookup4 (session_rules_table_t * srt,
                             ip4_address_t * lcl_ip, ip4_address_t * rmt_ip,
                             u16 lcl_port, u16 rmt_port)
 {
-  mma_rules_table_16_t *srt4 = &srt->session_rules_tables_16[transport_proto];
+  mma_rules_table_16_t *srt4 = &srt->session_rules_tables_16;
   session_mask_or_match_4_t key = {
     .lcl_ip.as_u32 = lcl_ip->as_u32,
     .rmt_ip.as_u32 = rmt_ip->as_u32,
     .lcl_port = lcl_port,
     .rmt_port = rmt_port,
   };
-  return mma_rules_table_lookup_16 (srt4,
-                                   (mma_mask_or_match_16_t *) & key,
+  return mma_rules_table_lookup_16 (srt4, (mma_mask_or_match_16_t *) & key,
                                    srt4->root_index);
 }
 
 u32
-session_rules_table_lookup6 (session_rules_table_t * srt, u8 transport_proto,
+session_rules_table_lookup6 (session_rules_table_t * srt,
                             ip6_address_t * lcl_ip, ip6_address_t * rmt_ip,
                             u16 lcl_port, u16 rmt_port)
 {
-  mma_rules_table_40_t *srt6 = &srt->session_rules_tables_40[transport_proto];
+  mma_rules_table_40_t *srt6 = &srt->session_rules_tables_40;
   session_mask_or_match_6_t key = {
     .lcl_port = lcl_port,
     .rmt_port = rmt_port,
   };
   clib_memcpy (&key.lcl_ip, lcl_ip, sizeof (*lcl_ip));
   clib_memcpy (&key.rmt_ip, rmt_ip, sizeof (*rmt_ip));
-  return mma_rules_table_lookup_40 (srt6,
-                                   (mma_mask_or_match_40_t *) & key,
+  return mma_rules_table_lookup_40 (srt6, (mma_mask_or_match_40_t *) & key,
                                    srt6->root_index);
 }
 
@@ -313,36 +447,32 @@ session_rules_table_init (session_rules_table_t * srt)
   mma_rule_16_t *rule4;
   mma_rule_40_t *rule6;
   fib_prefix_t null_prefix;
-  int i;
 
   memset (&null_prefix, 0, sizeof (null_prefix));
 
-  for (i = 0; i < TRANSPORT_N_PROTO; i++)
-    {
-      srt4 = &srt->session_rules_tables_16[i];
-      rule4 = session_rules_table_alloc_rule_16 (srt4, &null_prefix, 0,
-                                                &null_prefix, 0);
-      rule4->action_index = SESSION_RULES_TABLE_INVALID_INDEX;
-      srt4->root_index = mma_rules_table_rule_index_16 (srt4, rule4);
-      srt4->rule_cmp_fn = rule_cmp_16;
-    }
-
-  for (i = 0; i < TRANSPORT_N_PROTO; i++)
-    {
-      srt6 = &srt->session_rules_tables_40[i];;
-      rule6 = session_rules_table_alloc_rule_40 (srt6, &null_prefix, 0,
-                                                &null_prefix, 0);
-      rule6->action_index = SESSION_RULES_TABLE_INVALID_INDEX;
-      srt6->root_index = mma_rules_table_rule_index_40 (srt6, rule6);
-      srt6->rule_cmp_fn = rule_cmp_40;
-    }
+  srt4 = &srt->session_rules_tables_16;
+  rule4 = session_rules_table_alloc_rule_16 (srt4, &null_prefix, 0,
+                                            &null_prefix, 0);
+  rule4->action_index = SESSION_RULES_TABLE_INVALID_INDEX;
+  srt4->root_index = mma_rules_table_rule_index_16 (srt4, rule4);
+  srt4->rule_cmp_fn = rule_cmp_16;
+
+  srt6 = &srt->session_rules_tables_40;
+  rule6 = session_rules_table_alloc_rule_40 (srt6, &null_prefix, 0,
+                                            &null_prefix, 0);
+  rule6->action_index = SESSION_RULES_TABLE_INVALID_INDEX;
+  srt6->root_index = mma_rules_table_rule_index_40 (srt6, rule6);
+  srt6->rule_cmp_fn = rule_cmp_40;
+
+  srt->rules_by_tag = hash_create_vec (0, sizeof (u8), sizeof (uword));
+  srt->tags_by_rules = hash_create (0, sizeof (uword));
 }
 
 void
 session_rules_table_show_rule (vlib_main_t * vm, session_rules_table_t * srt,
-                              u8 transport_proto, ip46_address_t * lcl_ip,
-                              u16 lcl_port, ip46_address_t * rmt_ip,
-                              u16 rmt_port, u8 is_ip4)
+                              ip46_address_t * lcl_ip, u16 lcl_port,
+                              ip46_address_t * rmt_ip, u16 rmt_port,
+                              u8 is_ip4)
 {
   mma_rules_table_16_t *srt4;
   mma_rules_table_40_t *srt6;
@@ -352,7 +482,7 @@ session_rules_table_show_rule (vlib_main_t * vm, session_rules_table_t * srt,
 
   if (is_ip4)
     {
-      srt4 = session_rules_table_get (srt, transport_proto, FIB_PROTOCOL_IP4);
+      srt4 = session_rules_table_get (srt, FIB_PROTOCOL_IP4);
       session_mask_or_match_4_t key = {
        .lcl_ip.as_u32 = lcl_ip->ip4.as_u32,
        .rmt_ip.as_u32 = rmt_ip->ip4.as_u32,
@@ -364,41 +494,39 @@ session_rules_table_show_rule (vlib_main_t * vm, session_rules_table_t * srt,
                                        (mma_mask_or_match_16_t *) & key,
                                        srt4->root_index);
       sr4 = mma_rules_table_get_rule_16 (srt4, ri);
-      vlib_cli_output (vm, "%U", format_session_rule4, srt4, sr4);
+      vlib_cli_output (vm, "%U", format_session_rule4, srt, sr4);
     }
   else
     {
-      srt6 = session_rules_table_get (srt, transport_proto, FIB_PROTOCOL_IP6);
+      srt6 = session_rules_table_get (srt, FIB_PROTOCOL_IP6);
       session_mask_or_match_6_t key = {
        .lcl_port = lcl_port,
        .rmt_port = rmt_port,
       };
       clib_memcpy (&key.lcl_ip, &lcl_ip->ip6, sizeof (lcl_ip->ip6));
       clib_memcpy (&key.rmt_ip, &rmt_ip->ip6, sizeof (rmt_ip->ip6));
-      ri =
-       mma_rules_table_lookup_rule_40 (srt6,
-                                       (mma_mask_or_match_40_t *) &
-                                       key, srt6->root_index);
+      ri = mma_rules_table_lookup_rule_40 (srt6,
+                                          (mma_mask_or_match_40_t *) & key,
+                                          srt6->root_index);
       sr6 = mma_rules_table_get_rule_40 (srt6, ri);
-      vlib_cli_output (vm, "%U", format_session_rule6, srt6, sr6);
+      vlib_cli_output (vm, "%U", format_session_rule6, srt, sr6);
     }
 }
 
 void
 session_rules_table_cli_dump (vlib_main_t * vm, session_rules_table_t * srt,
-                             u8 fib_proto, u8 transport_proto)
+                             u8 fib_proto)
 {
   if (fib_proto == FIB_PROTOCOL_IP4)
     {
       mma_rules_table_16_t *srt4;
       mma_rule_16_t *sr4;
-      srt4 = &srt->session_rules_tables_16[transport_proto];
-      vlib_cli_output (vm, "%U IP4 rules table", format_transport_proto,
-                      transport_proto);
+      srt4 = &srt->session_rules_tables_16;
+      vlib_cli_output (vm, "IP4 rules");
 
       /* *INDENT-OFF* */
       pool_foreach(sr4, srt4->rules, ({
-       vlib_cli_output (vm, "%U", format_session_rule4, srt4, sr4);
+       vlib_cli_output (vm, "%U", format_session_rule4, srt, sr4);
       }));
       /* *INDENT-ON* */
 
@@ -407,13 +535,12 @@ session_rules_table_cli_dump (vlib_main_t * vm, session_rules_table_t * srt,
     {
       mma_rules_table_40_t *srt6;
       mma_rule_40_t *sr6;
-      srt6 = &srt->session_rules_tables_40[transport_proto];
-      vlib_cli_output (vm, "\n%U IP6 rules table", format_transport_proto,
-                      transport_proto);
+      srt6 = &srt->session_rules_tables_40;
+      vlib_cli_output (vm, "IP6 rules");
 
       /* *INDENT-OFF* */
       pool_foreach(sr6, srt6->rules, ({
-        vlib_cli_output (vm, "%U", format_session_rule6, srt6, sr6);
+        vlib_cli_output (vm, "%U", format_session_rule6, srt, sr6);
       }));
       /* *INDENT-ON* */
 
index 27b0f88..9bab61e 100644 (file)
@@ -54,50 +54,67 @@ typedef CLIB_PACKED (struct
 }) session_mask_or_match_6_t;
 /* *INDENT-ON* */
 
+#define SESSION_RULE_TAG_MAX_LEN 64
+#define SESSION_RULES_TABLE_ACTION_DROP (((u32)~0) - 1)
+#define SESSION_RULES_TABLE_INVALID_INDEX MMA_TABLE_INVALID_INDEX
+
 typedef struct _session_rules_table_add_del_args
 {
-  u8 transport_proto;
   fib_prefix_t lcl;
   fib_prefix_t rmt;
   u16 lcl_port;
   u16 rmt_port;
   u32 action_index;
+  u8 *tag;
   u8 is_add;
 } session_rule_table_add_del_args_t;
 
-#define SESSION_RULES_TABLE_ACTION_DROP (((u32)~0) - 1)
+typedef struct _rule_tag
+{
+  u8 *tag;
+} session_rule_tag_t;
 
 typedef struct _session_rules_table_t
 {
   /**
-   * Per fib proto and transport proto session rules tables
+   * Per fib proto session rules tables
+   */
+  mma_rules_table_16_t session_rules_tables_16;
+  mma_rules_table_40_t session_rules_tables_40;
+  /**
+   * Hash table that maps tags to rules
+   */
+  uword *rules_by_tag;
+  /**
+   * Pool of rules tags
+   */
+  session_rule_tag_t *rule_tags;
+  /**
+   * Hash table that maps rule indices to tags
    */
-  mma_rules_table_16_t session_rules_tables_16[TRANSPORT_N_PROTO];
-  mma_rules_table_40_t session_rules_tables_40[TRANSPORT_N_PROTO];
+  uword *tags_by_rules;
 } session_rules_table_t;
 
-void *session_rules_table_get (session_rules_table_t * srt,
-                              u8 transport_proto, u8 fib_proto);
 u32 session_rules_table_lookup4 (session_rules_table_t * srt,
-                                u8 transport_proto, ip4_address_t * lcl_ip,
+                                ip4_address_t * lcl_ip,
                                 ip4_address_t * rmt_ip, u16 lcl_port,
                                 u16 rmt_port);
 u32 session_rules_table_lookup6 (session_rules_table_t * srt,
-                                u8 transport_proto, ip6_address_t * lcl_ip,
+                                ip6_address_t * lcl_ip,
                                 ip6_address_t * rmt_ip, u16 lcl_port,
                                 u16 rmt_port);
 void session_rules_table_cli_dump (vlib_main_t * vm,
-                                  session_rules_table_t * srt, u8 fib_proto,
-                                  u8 transport_proto);
+                                  session_rules_table_t * srt, u8 fib_proto);
 void session_rules_table_show_rule (vlib_main_t * vm,
                                    session_rules_table_t * srt,
-                                   u8 transport_proto,
                                    ip46_address_t * lcl_ip, u16 lcl_port,
                                    ip46_address_t * rmt_ip, u16 rmt_port,
                                    u8 is_ip4);
 clib_error_t *session_rules_table_add_del (session_rules_table_t * srt,
                                           session_rule_table_add_del_args_t *
                                           args);
+u8 *session_rules_table_rule_tag (session_rules_table_t * srt, u32 ri,
+                                 u8 is_ip4);
 void session_rules_table_init (session_rules_table_t * srt);
 #endif /* SRC_VNET_SESSION_SESSION_RULES_TABLE_H_ */
 /*
index f0bd338..5d160a4 100644 (file)
@@ -70,6 +70,7 @@ void
 session_table_init (session_table_t * slt, u8 fib_proto)
 {
   u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0;
+  int i;
 
 #define _(af,table,parm,value)                                                 \
   u32 configured_##af##_##table##_table_##parm = value;
@@ -101,7 +102,9 @@ session_table_init (session_table_t * slt, u8 fib_proto)
                             configured_v6_halfopen_table_buckets,
                             configured_v6_halfopen_table_memory);
     }
-  session_rules_table_init (&slt->session_rules);
+
+  for (i = 0; i < TRANSPORT_N_PROTO; i++)
+    session_rules_table_init (&slt->session_rules[i]);
 }
 
 typedef struct _ip4_session_table_walk_ctx_t
index 6cf8159..636ee44 100644 (file)
@@ -37,7 +37,7 @@ typedef struct _session_lookup_table
   /**
    * Per fib proto and transport proto session rules tables
    */
-  session_rules_table_t session_rules;
+  session_rules_table_t session_rules[TRANSPORT_N_PROTO];
 
   /** Flag that indicates if table has local scope */
   u8 is_local;
index a3e76c2..8d18619 100644 (file)
@@ -506,8 +506,7 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
                action_index - 1);
 
   res =
-    session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip,
-                                lcl_port, rmt_port);
+    session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
   SESSION_TEST ((res == 1),
                "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 1: %d",
                res);
@@ -561,8 +560,7 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
    * and  3.3.3.3 1234 7.7.7.7 4321
    */
   res =
-    session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip,
-                                lcl_port, rmt_port);
+    session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
   SESSION_TEST ((res == 3),
                "Lookup 1.2.3.4 1234 5.6.7.8 4321 action " "should be 3: %d",
                res);
@@ -570,15 +568,14 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
   lcl_lkup.as_u32 = clib_host_to_net_u32 (0x01020204);
   rmt_lkup.as_u32 = clib_host_to_net_u32 (0x05060709);
   res =
-    session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_lkup,
+    session_rules_table_lookup4 (srt, &lcl_lkup,
                                 &rmt_lkup, lcl_port, rmt_port);
   SESSION_TEST ((res == 1),
                "Lookup 1.2.2.4 1234 5.6.7.9 4321, action " "should be 1: %d",
                res);
 
   res =
-    session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip3, &rmt_ip3,
-                                lcl_port, rmt_port);
+    session_rules_table_lookup4 (srt, &lcl_ip3, &rmt_ip3, lcl_port, rmt_port);
   SESSION_TEST ((res == 6),
                "Lookup 3.3.3.3 1234 7.7.7.7 4321, action "
                "should be 6 (updated): %d", res);
@@ -598,13 +595,12 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
   SESSION_TEST ((error == 0), "Add 1.2.3.4/24 * 5.6.7.8/24 * action %d",
                action_index - 1);
   res =
-    session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip,
-                                lcl_port, rmt_port);
+    session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
   SESSION_TEST ((res == 7),
                "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should"
                " be 7 (lpm dst): %d", res);
   res =
-    session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip,
+    session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
                                 lcl_port + 1, rmt_port);
   SESSION_TEST ((res == 7),
                "Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 7: %d",
@@ -645,23 +641,21 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
                action_index - 1);
 
   if (verbose)
-    session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4,
-                                 TRANSPORT_PROTO_TCP);
+    session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4);
 
   res =
-    session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip,
-                                lcl_port, rmt_port);
+    session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
   SESSION_TEST ((res == 3),
                "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
                res);
   res =
-    session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip,
+    session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
                                 lcl_port + 1, rmt_port);
   SESSION_TEST ((res == 9),
                "Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 9: %d",
                res);
   res =
-    session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip,
+    session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
                                 lcl_port + 1, rmt_port + 1);
   SESSION_TEST ((res == 8),
                "Lookup 1.2.3.4 1235 5.6.7.8 4322, action should " "be 8: %d",
@@ -679,8 +673,7 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
   error = session_rules_table_add_del (srt, &args);
   SESSION_TEST ((error == 0), "Del 1.2.0.0/16 1234 5.6.0.0/16 4321");
   res =
-    session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip,
-                                lcl_port, rmt_port);
+    session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
   SESSION_TEST ((res == 3),
                "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
                res);
@@ -691,8 +684,7 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
   error = session_rules_table_add_del (srt, &args);
   SESSION_TEST ((error == 0), "Del 1.2.0.0/16 * 5.6.0.0/16 *");
   res =
-    session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip,
-                                lcl_port, rmt_port);
+    session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
   SESSION_TEST ((res == 3),
                "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
                res);
@@ -710,8 +702,7 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
   error = session_rules_table_add_del (srt, &args);
   SESSION_TEST ((error == 0), "Del 1.2.3.4/24 1234 5.6.7.5/24");
   res =
-    session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip,
-                                lcl_port, rmt_port);
+    session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
   SESSION_TEST ((res == 2), "Action should be 2: %d", res);
 
   return 0;
@@ -959,6 +950,32 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
                                      &rmt_pref.fp_addr.ip4, lcl_port,
                                      rmt_port, TRANSPORT_PROTO_TCP, 0);
   SESSION_TEST ((tc == 0), "optimized lookup should not work (no-rule)");
+
+  /*
+   * Test tags. Add/del rule with tag
+   */
+  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 = 16;
+  args.table_args.rmt.fp_addr.ip4 = rmt_ip;
+  args.table_args.rmt.fp_len = 16;
+  args.table_args.tag = format (0, "test_rule");
+  error = vnet_session_rule_add_del (&args);
+  SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 drop "
+               "tag test_rule");
+  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);
+    }
+  args.table_args.is_add = 0;
+  args.table_args.lcl_port += 1;
+  SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 drop "
+               "tag test_rule");
+
   return 0;
 }
 
index 1152fbb..4ec19e5 100644 (file)
@@ -3215,18 +3215,19 @@ static void *vl_api_session_rule_add_del_t_print
   u8 *s;
   char *proto = mp->transport_proto == 0 ? "tcp" : "udp";
   s = format (0, "SCRIPT: session_rule_add_del ");
+  mp->tag[sizeof (mp->tag) - 1] = 0;
   if (mp->is_ip4)
-    s = format (s, "appns %d scope %d %s %U/%d %d %U/%d %d action %u",
+    s = format (s, "appns %d scope %d %s %U/%d %d %U/%d %d action %u tag %s",
                mp->appns_index, mp->scope, proto, format_ip4_address,
                (ip4_address_t *) mp->lcl_ip, mp->lcl_plen,
                format_ip4_address, (ip4_address_t *) mp->rmt_ip,
-               mp->rmt_plen, mp->action_index);
+               mp->rmt_plen, mp->action_index, mp->tag);
   else
-    s = format (s, "appns %d scope %d %s %U/%d %d %U/%d %d action %u",
+    s = format (s, "appns %d scope %d %s %U/%d %d %U/%d %d action %u tag %s",
                mp->appns_index, mp->scope, proto, format_ip6_address,
                (ip6_address_t *) mp->lcl_ip, mp->lcl_plen,
                format_ip6_address, (ip6_address_t *) mp->rmt_ip,
-               mp->rmt_plen, mp->action_index);
+               mp->rmt_plen, mp->action_index, mp->tag);
   FINISH;
 }