GBP V2

update the GBP plugin to implement the full NAT feature set of opflex agent

Change-Id: Ic06a039c889445ed0b9087fa1f292634192b0f8d
Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
diff --git a/src/vnet/buffer.h b/src/vnet/buffer.h
index 02688e2..86f7538 100644
--- a/src/vnet/buffer.h
+++ b/src/vnet/buffer.h
@@ -387,6 +387,12 @@
 
   u8 __unused[2];
 
+  /* Group Based Policy */
+  struct
+  {
+    u32 src_epg;
+  } gbp;
+
   union
   {
     struct
@@ -396,7 +402,7 @@
       u16 *trajectory_trace;
 #endif
     };
-    u32 unused[11];
+    u32 unused[10];
   };
 } vnet_buffer_opaque2_t;
 
diff --git a/src/vnet/ethernet/arp.c b/src/vnet/ethernet/arp.c
index 925fb2c..9114d7a 100644
--- a/src/vnet/ethernet/arp.c
+++ b/src/vnet/ethernet/arp.c
@@ -2498,11 +2498,22 @@
 }
 
 void
-send_ip4_garp (vlib_main_t * vm, vnet_hw_interface_t * hi)
+send_ip4_garp (vlib_main_t * vm, const vnet_hw_interface_t * hi)
+{
+  ip4_main_t *i4m = &ip4_main;
+  ip4_address_t *ip4_addr =
+    ip4_interface_first_address (i4m, hi->sw_if_index, 0);
+
+  send_ip4_garp_w_addr (vm, ip4_addr, hi);
+}
+
+void
+send_ip4_garp_w_addr (vlib_main_t * vm,
+		      const ip4_address_t * ip4_addr,
+		      const vnet_hw_interface_t * hi)
 {
   ip4_main_t *i4m = &ip4_main;
   u32 sw_if_index = hi->sw_if_index;
-  ip4_address_t *ip4_addr = ip4_interface_first_address (i4m, sw_if_index, 0);
 
   if (ip4_addr)
     {
diff --git a/src/vnet/ethernet/arp_packet.h b/src/vnet/ethernet/arp_packet.h
index 661f33f..4b7b048 100644
--- a/src/vnet/ethernet/arp_packet.h
+++ b/src/vnet/ethernet/arp_packet.h
@@ -167,7 +167,10 @@
 ethernet_arp_ip4_entry_t *ip4_neighbor_entries (u32 sw_if_index);
 u8 *format_ethernet_arp_ip4_entry (u8 * s, va_list * va);
 
-void send_ip4_garp (vlib_main_t * vm, vnet_hw_interface_t * hi);
+void send_ip4_garp (vlib_main_t * vm, const vnet_hw_interface_t * hi);
+void send_ip4_garp_w_addr (vlib_main_t * vm,
+			   const ip4_address_t * ip4_addr,
+			   const vnet_hw_interface_t * hi);
 
 #endif /* included_ethernet_arp_packet_h */
 
diff --git a/src/vnet/fib/fib_table.c b/src/vnet/fib/fib_table.c
index 324a35f..d0bc336 100644
--- a/src/vnet/fib/fib_table.c
+++ b/src/vnet/fib/fib_table.c
@@ -1034,6 +1034,17 @@
 }
 
 u32
+fib_table_get_table_id (u32 fib_index,
+                        fib_protocol_t proto)
+{
+    fib_table_t *fib_table;
+
+    fib_table = fib_table_get(fib_index, proto);
+
+    return ((NULL != fib_table ? fib_table->ft_table_id : ~0));
+}
+
+u32
 fib_table_find (fib_protocol_t proto,
 		u32 table_id)
 {
diff --git a/src/vnet/fib/fib_table.h b/src/vnet/fib/fib_table.h
index ffad3c4..8b86f8d 100644
--- a/src/vnet/fib/fib_table.h
+++ b/src/vnet/fib/fib_table.h
@@ -645,6 +645,21 @@
 
 /**
  * @brief
+ *  Get the Table-ID of the FIB from protocol and index
+ *
+ * @param fib_index
+ *  The FIB index
+ *
+ * @paran proto
+ *  The protocol of the FIB (and thus the entries therein)
+ *
+ * @return fib_index
+ *  The tableID of the FIB
+ */
+extern u32 fib_table_get_table_id(u32 fib_index, fib_protocol_t proto);
+
+/**
+ * @brief
  *  Get the index of the FIB for a Table-ID. This DOES NOT create the
  * FIB if it does not exist.
  *
diff --git a/src/vnet/ip/ip6.h b/src/vnet/ip/ip6.h
index 959d72c..359c461 100644
--- a/src/vnet/ip/ip6.h
+++ b/src/vnet/ip/ip6.h
@@ -404,7 +404,10 @@
 		      ethernet_header_t * eth,
 		      ip6_header_t * ip, u32 sw_if_index, u16 bd_index);
 
-void send_ip6_na (vlib_main_t * vm, vnet_hw_interface_t * hi);
+void send_ip6_na (vlib_main_t * vm, const vnet_hw_interface_t * hi);
+void send_ip6_na_w_addr (vlib_main_t * vm,
+			 const ip6_address_t * addr,
+			 const vnet_hw_interface_t * hi);
 
 u8 *format_ip6_forward_next_trace (u8 * s, va_list * args);
 
diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c
index 0df29c6..fee4356 100644
--- a/src/vnet/ip/ip6_neighbor.c
+++ b/src/vnet/ip/ip6_neighbor.c
@@ -4670,11 +4670,23 @@
 }
 
 void
-send_ip6_na (vlib_main_t * vm, vnet_hw_interface_t * hi)
+send_ip6_na (vlib_main_t * vm, const vnet_hw_interface_t * hi)
 {
   ip6_main_t *i6m = &ip6_main;
   u32 sw_if_index = hi->sw_if_index;
   ip6_address_t *ip6_addr = ip6_interface_first_address (i6m, sw_if_index);
+
+  send_ip6_na_w_addr (vm, ip6_addr, hi);
+}
+
+void
+send_ip6_na_w_addr (vlib_main_t * vm,
+		    const ip6_address_t * ip6_addr,
+		    const vnet_hw_interface_t * hi)
+{
+  ip6_main_t *i6m = &ip6_main;
+  u32 sw_if_index = hi->sw_if_index;
+
   if (ip6_addr)
     {
       clib_warning
diff --git a/src/vnet/l2/l2_input.c b/src/vnet/l2/l2_input.c
index d8a0a6b..69de281 100644
--- a/src/vnet/l2/l2_input.c
+++ b/src/vnet/l2/l2_input.c
@@ -176,7 +176,8 @@
       u8 protocol = ((ip6_header_t *) l3h0)->protocol;
 
       /* Disable bridge forwarding (flooding will execute instead if not xconnect) */
-      feat_mask &= ~(L2INPUT_FEAT_FWD | L2INPUT_FEAT_UU_FLOOD);
+      feat_mask &= ~(L2INPUT_FEAT_FWD |
+		     L2INPUT_FEAT_UU_FLOOD | L2INPUT_FEAT_GBP_FWD);
 
       /* Disable ARP-term for non-ARP and non-ICMP6 packet */
       if (ethertype != ETHERNET_TYPE_ARP &&
diff --git a/src/vnet/l2/l2_input.h b/src/vnet/l2/l2_input.h
index dc9d954..5d67f25 100644
--- a/src/vnet/l2/l2_input.h
+++ b/src/vnet/l2/l2_input.h
@@ -109,10 +109,13 @@
  _(FLOOD,         "l2-flood")                   \
  _(ARP_TERM,      "arp-term-l2bd")              \
  _(UU_FLOOD,      "l2-flood")                   \
+ _(GBP_FWD,       "gbp-fwd")                    \
  _(FWD,           "l2-fwd")                     \
  _(RW,            "l2-rw")                      \
  _(LEARN,         "l2-learn")                   \
  _(L2_EMULATION,  "l2-emulation")               \
+ _(GBP_NULL_CLASSIFY, "gbp-null-classify")      \
+ _(GBP_SRC_CLASSIFY,  "gbp-src-classify")       \
  _(VTR,           "l2-input-vtr")               \
  _(VPATH,         "vpath-input-l2")             \
  _(ACL,           "l2-input-acl")               \
diff --git a/src/vnet/l2/l2_output.h b/src/vnet/l2/l2_output.h
index 3b6e480..6b00d01 100644
--- a/src/vnet/l2/l2_output.h
+++ b/src/vnet/l2/l2_output.h
@@ -85,6 +85,7 @@
 #define foreach_l2output_feat \
  _(OUTPUT,            "interface-output")           \
  _(SPAN,              "span-l2-output")             \
+ _(GBP_POLICY,        "gbp-policy")                 \
  _(CFM,               "feature-bitmap-drop")        \
  _(QOS,               "feature-bitmap-drop")        \
  _(ACL,               "l2-output-acl")              \