GBP: use sclass in the DP for policy
[vpp.git] / src / plugins / gbp / gbp_learn_node.c
index ebb1217..8c623e8 100644 (file)
@@ -22,6 +22,7 @@
 #include <vnet/l2/l2_input.h>
 #include <vnet/fib/fib_table.h>
 #include <vnet/vxlan-gbp/vxlan_gbp_packet.h>
+#include <vnet/ethernet/arp_packet.h>
 
 #define GBP_LEARN_DBG(...)                                      \
     vlib_log_debug (gbp_learn_main.gl_logger, __VA_ARGS__);
@@ -57,7 +58,7 @@ typedef struct gbp_learn_l2_t_
   mac_address_t mac;
   u32 sw_if_index;
   u32 bd_index;
-  epg_id_t epg;
+  sclass_t sclass;
   ip46_address_t outer_src;
   ip46_address_t outer_dst;
 } gbp_learn_l2_t;
@@ -70,12 +71,10 @@ gbp_learn_l2_cp (const gbp_learn_l2_t * gl2)
 
   GBP_LEARN_DBG ("L2 EP: %U %U, %d",
                 format_mac_address_t, &gl2->mac,
-                format_ip46_address, &gl2->ip, IP46_TYPE_ANY, gl2->epg);
+                format_ip46_address, &gl2->ip, IP46_TYPE_ANY, gl2->sclass);
 
-  vec_add1 (ips, gl2->ip);
-
-  ASSERT (!ip46_address_is_zero (&gl2->outer_src));
-  ASSERT (!ip46_address_is_zero (&gl2->outer_dst));
+  if (!ip46_address_is_zero (&gl2->ip))
+    vec_add1 (ips, gl2->ip);
 
   /*
    * flip the source and dst, since that's how it was received, this API
@@ -84,7 +83,7 @@ gbp_learn_l2_cp (const gbp_learn_l2_t * gl2)
   gbp_endpoint_update_and_lock (GBP_ENDPOINT_SRC_DP,
                                gl2->sw_if_index, ips,
                                &gl2->mac, INDEX_INVALID,
-                               INDEX_INVALID, gl2->epg,
+                               INDEX_INVALID, gl2->sclass,
                                (GBP_ENDPOINT_FLAG_LEARNT |
                                 GBP_ENDPOINT_FLAG_REMOTE),
                                &gl2->outer_dst, &gl2->outer_src, NULL);
@@ -93,36 +92,33 @@ gbp_learn_l2_cp (const gbp_learn_l2_t * gl2)
 
 static void
 gbp_learn_l2_ip4_dp (const u8 * mac, const ip4_address_t * ip,
-                    u32 bd_index, u32 sw_if_index, epg_id_t epg,
+                    u32 bd_index, u32 sw_if_index, sclass_t sclass,
                     const ip4_address_t * outer_src,
                     const ip4_address_t * outer_dst)
 {
   gbp_learn_l2_t gl2 = {
     .sw_if_index = sw_if_index,
     .bd_index = bd_index,
-    .epg = epg,
+    .sclass = sclass,
     .ip.ip4 = *ip,
     .outer_src.ip4 = *outer_src,
     .outer_dst.ip4 = *outer_dst,
   };
   mac_address_from_bytes (&gl2.mac, mac);
 
-  ASSERT (!ip46_address_is_zero (&gl2.outer_src));
-  ASSERT (!ip46_address_is_zero (&gl2.outer_dst));
-
   vl_api_rpc_call_main_thread (gbp_learn_l2_cp, (u8 *) & gl2, sizeof (gl2));
 }
 
 static void
 gbp_learn_l2_ip6_dp (const u8 * mac, const ip6_address_t * ip,
-                    u32 bd_index, u32 sw_if_index, epg_id_t epg,
+                    u32 bd_index, u32 sw_if_index, sclass_t sclass,
                     const ip4_address_t * outer_src,
                     const ip4_address_t * outer_dst)
 {
   gbp_learn_l2_t gl2 = {
     .sw_if_index = sw_if_index,
     .bd_index = bd_index,
-    .epg = epg,
+    .sclass = sclass,
     .ip.ip6 = *ip,
     .outer_src.ip4 = *outer_src,
     .outer_dst.ip4 = *outer_dst,
@@ -134,14 +130,14 @@ gbp_learn_l2_ip6_dp (const u8 * mac, const ip6_address_t * ip,
 
 static void
 gbp_learn_l2_dp (const u8 * mac, u32 bd_index, u32 sw_if_index,
-                epg_id_t epg,
+                sclass_t sclass,
                 const ip4_address_t * outer_src,
                 const ip4_address_t * outer_dst)
 {
   gbp_learn_l2_t gl2 = {
     .sw_if_index = sw_if_index,
     .bd_index = bd_index,
-    .epg = epg,
+    .sclass = sclass,
     .outer_src.ip4 = *outer_src,
     .outer_dst.ip4 = *outer_dst,
   };
@@ -160,7 +156,7 @@ typedef struct gbp_learn_l2_trace_t_
   u32 sw_if_index;
   u32 new;
   u32 throttled;
-  u32 epg;
+  u32 sclass;
   u32 d_bit;
   gbp_bridge_domain_flags_t gb_flags;
 } gbp_learn_l2_trace_t;
@@ -209,12 +205,13 @@ VLIB_NODE_FN (gbp_learn_l2_node) (vlib_main_t * vm,
       while (n_left_from > 0 && n_left_to_next > 0)
        {
          ip4_address_t outer_src, outer_dst;
-         u32 bi0, sw_if_index0, t0, epg0;
          const ethernet_header_t *eh0;
+         u32 bi0, sw_if_index0, t0;
          gbp_bridge_domain_t *gb0;
          gbp_learn_next_t next0;
          gbp_endpoint_t *ge0;
          vlib_buffer_t *b0;
+         sclass_t sclass0;
 
          next0 = GBP_LEARN_NEXT_DROP;
          bi0 = from[0];
@@ -228,7 +225,7 @@ VLIB_NODE_FN (gbp_learn_l2_node) (vlib_main_t * vm,
          sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
 
          eh0 = vlib_buffer_get_current (b0);
-         epg0 = vnet_buffer2 (b0)->gbp.src_epg;
+         sclass0 = vnet_buffer2 (b0)->gbp.sclass;
 
          next0 = vnet_l2_feature_next (b0, glm->gl_l2_input_feat_next,
                                        L2INPUT_FEAT_GBP_LEARN);
@@ -260,6 +257,12 @@ VLIB_NODE_FN (gbp_learn_l2_node) (vlib_main_t * vm,
                {
                  gbp_learn_get_outer (eh0, &outer_src, &outer_dst);
 
+                 if (outer_src.as_u32 == 0 || outer_dst.as_u32 == 0)
+                   {
+                     t0 = 2;
+                     goto trace;
+                   }
+
                  switch (clib_net_to_host_u16 (eh0->type))
                    {
                    case ETHERNET_TYPE_IP4:
@@ -271,7 +274,7 @@ VLIB_NODE_FN (gbp_learn_l2_node) (vlib_main_t * vm,
                        gbp_learn_l2_ip4_dp (eh0->src_address,
                                             &ip0->src_address,
                                             vnet_buffer (b0)->l2.bd_index,
-                                            sw_if_index0, epg0,
+                                            sw_if_index0, sclass0,
                                             &outer_src, &outer_dst);
 
                        break;
@@ -285,15 +288,28 @@ VLIB_NODE_FN (gbp_learn_l2_node) (vlib_main_t * vm,
                        gbp_learn_l2_ip6_dp (eh0->src_address,
                                             &ip0->src_address,
                                             vnet_buffer (b0)->l2.bd_index,
-                                            sw_if_index0, epg0,
+                                            sw_if_index0, sclass0,
                                             &outer_src, &outer_dst);
 
                        break;
                      }
+                   case ETHERNET_TYPE_ARP:
+                     {
+                       const ethernet_arp_header_t *arp0;
+
+                       arp0 = (ethernet_arp_header_t *) (eh0 + 1);
+
+                       gbp_learn_l2_ip4_dp (eh0->src_address,
+                                            &arp0->ip4_over_ethernet[0].ip4,
+                                            vnet_buffer (b0)->l2.bd_index,
+                                            sw_if_index0, sclass0,
+                                            &outer_src, &outer_dst);
+                       break;
+                     }
                    default:
                      gbp_learn_l2_dp (eh0->src_address,
                                       vnet_buffer (b0)->l2.bd_index,
-                                      sw_if_index0, epg0,
+                                      sw_if_index0, sclass0,
                                       &outer_src, &outer_dst);
                      break;
                    }
@@ -317,7 +333,7 @@ VLIB_NODE_FN (gbp_learn_l2_node) (vlib_main_t * vm,
              t->new = (NULL == ge0);
              t->throttled = t0;
              t->sw_if_index = sw_if_index0;
-             t->epg = epg0;
+             t->sclass = sclass0;
              t->gb_flags = gb0->gb_flags;
              t->d_bit = ! !(vnet_buffer2 (b0)->gbp.flags &
                             VXLAN_GBP_GPFLAGS_D);
@@ -343,10 +359,10 @@ format_gbp_learn_l2_trace (u8 * s, va_list * args)
   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
   gbp_learn_l2_trace_t *t = va_arg (*args, gbp_learn_l2_trace_t *);
 
-  s = format (s, "new:%d throttled:%d d-bit:%d mac:%U itf:%d epg:%d"
+  s = format (s, "new:%d throttled:%d d-bit:%d mac:%U itf:%d sclass:%d"
              " gb-flags:%U",
              t->new, t->throttled, t->d_bit,
-             format_mac_address_t, &t->mac, t->sw_if_index, t->epg,
+             format_mac_address_t, &t->mac, t->sw_if_index, t->sclass,
              format_gbp_bridge_domain_flags, t->gb_flags);
 
   return s;
@@ -375,7 +391,7 @@ typedef struct gbp_learn_l3_t_
   ip46_address_t ip;
   u32 fib_index;
   u32 sw_if_index;
-  epg_id_t epg;
+  sclass_t sclass;
   ip46_address_t outer_src;
   ip46_address_t outer_dst;
 } gbp_learn_l3_t;
@@ -386,13 +402,13 @@ gbp_learn_l3_cp (const gbp_learn_l3_t * gl3)
   ip46_address_t *ips = NULL;
 
   GBP_LEARN_DBG ("L3 EP: %U, %d", format_ip46_address, &gl3->ip,
-                IP46_TYPE_ANY, gl3->epg);
+                IP46_TYPE_ANY, gl3->sclass);
 
   vec_add1 (ips, gl3->ip);
 
   gbp_endpoint_update_and_lock (GBP_ENDPOINT_SRC_DP,
                                gl3->sw_if_index, ips, NULL,
-                               INDEX_INVALID, INDEX_INVALID, gl3->epg,
+                               INDEX_INVALID, INDEX_INVALID, gl3->sclass,
                                (GBP_ENDPOINT_FLAG_REMOTE |
                                 GBP_ENDPOINT_FLAG_LEARNT),
                                &gl3->outer_dst, &gl3->outer_src, NULL);
@@ -401,7 +417,7 @@ gbp_learn_l3_cp (const gbp_learn_l3_t * gl3)
 
 static void
 gbp_learn_ip4_dp (const ip4_address_t * ip,
-                 u32 fib_index, u32 sw_if_index, epg_id_t epg,
+                 u32 fib_index, u32 sw_if_index, sclass_t sclass,
                  const ip4_address_t * outer_src,
                  const ip4_address_t * outer_dst)
 {
@@ -412,7 +428,7 @@ gbp_learn_ip4_dp (const ip4_address_t * ip,
     },
     .sw_if_index = sw_if_index,
     .fib_index = fib_index,
-    .epg = epg,
+    .sclass = sclass,
     .outer_src.ip4 = *outer_src,
     .outer_dst.ip4 = *outer_dst,
   };
@@ -423,7 +439,7 @@ gbp_learn_ip4_dp (const ip4_address_t * ip,
 
 static void
 gbp_learn_ip6_dp (const ip6_address_t * ip,
-                 u32 fib_index, u32 sw_if_index, epg_id_t epg,
+                 u32 fib_index, u32 sw_if_index, sclass_t sclass,
                  const ip4_address_t * outer_src,
                  const ip4_address_t * outer_dst)
 {
@@ -434,7 +450,7 @@ gbp_learn_ip6_dp (const ip6_address_t * ip,
     },
     .sw_if_index = sw_if_index,
     .fib_index = fib_index,
-    .epg = epg,
+    .sclass = sclass,
     .outer_src.ip4 = *outer_src,
     .outer_dst.ip4 = *outer_dst,
   };
@@ -453,7 +469,7 @@ typedef struct gbp_learn_l3_trace_t_
   u32 sw_if_index;
   u32 new;
   u32 throttled;
-  u32 epg;
+  u32 sclass;
 } gbp_learn_l3_trace_t;
 
 static uword
@@ -482,14 +498,15 @@ gbp_learn_l3 (vlib_main_t * vm,
 
       while (n_left_from > 0 && n_left_to_next > 0)
        {
-         u32 bi0, sw_if_index0, t0, epg0, fib_index0;
          CLIB_UNUSED (const ip4_header_t *) ip4_0;
          CLIB_UNUSED (const ip6_header_t *) ip6_0;
+         u32 bi0, sw_if_index0, t0, fib_index0;
          ip4_address_t outer_src, outer_dst;
          ethernet_header_t *eth0;
          gbp_learn_next_t next0;
          gbp_endpoint_t *ge0;
          vlib_buffer_t *b0;
+         sclass_t sclass0;
 
          next0 = GBP_LEARN_NEXT_DROP;
          bi0 = from[0];
@@ -501,7 +518,7 @@ gbp_learn_l3 (vlib_main_t * vm,
 
          b0 = vlib_get_buffer (vm, bi0);
          sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
-         epg0 = vnet_buffer2 (b0)->gbp.src_epg;
+         sclass0 = vnet_buffer2 (b0)->gbp.sclass;
          ip6_0 = NULL;
          ip4_0 = NULL;
 
@@ -536,7 +553,7 @@ gbp_learn_l3 (vlib_main_t * vm,
                  if (!t0)
                    {
                      gbp_learn_ip6_dp (&ip6_0->src_address,
-                                       fib_index0, sw_if_index0, epg0,
+                                       fib_index0, sw_if_index0, sclass0,
                                        &outer_src, &outer_dst);
                    }
                }
@@ -567,7 +584,7 @@ gbp_learn_l3 (vlib_main_t * vm,
                  if (!t0)
                    {
                      gbp_learn_ip4_dp (&ip4_0->src_address,
-                                       fib_index0, sw_if_index0, epg0,
+                                       fib_index0, sw_if_index0, sclass0,
                                        &outer_src, &outer_dst);
                    }
                }
@@ -595,7 +612,7 @@ gbp_learn_l3 (vlib_main_t * vm,
              t->new = (NULL == ge0);
              t->throttled = t0;
              t->sw_if_index = sw_if_index0;
-             t->epg = epg0;
+             t->sclass = sclass0;
            }
 
          vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
@@ -617,10 +634,10 @@ format_gbp_learn_l3_trace (u8 * s, va_list * args)
   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
   gbp_learn_l3_trace_t *t = va_arg (*args, gbp_learn_l3_trace_t *);
 
-  s = format (s, "new:%d throttled:%d ip:%U itf:%d epg:%d",
+  s = format (s, "new:%d throttled:%d ip:%U itf:%d sclass:%d",
              t->new, t->throttled,
              format_ip46_address, &t->ip, IP46_TYPE_ANY, t->sw_if_index,
-             t->epg);
+             t->sclass);
 
   return s;
 }