VPP-113: BVI shall filter unicast DMAC for L2 to L3 forwading 02/1402/1
authorJohn Lo <loj@cisco.com>
Sat, 4 Jun 2016 04:02:37 +0000 (00:02 -0400)
committerJohn Lo <loj@cisco.com>
Sat, 4 Jun 2016 04:02:37 +0000 (00:02 -0400)
As BVI receive a packet with unicast DMAC from the BD, including unknown
unicast flood packet, the packet should not be L3 forwarded unless its
DMAC matches the MAC of the BVI.

Change-Id: I46e18629c901062592c8ebe3a238c5cfdc1096b4
Signed-off-by: John Lo <loj@cisco.com>
vnet/vnet/ethernet/ethernet.h
vnet/vnet/ethernet/node.c
vnet/vnet/l2/l2_bvi.h
vnet/vnet/l2/l2_flood.c
vnet/vnet/l2/l2_fwd.c

index f519f4f..97c66e7 100644 (file)
@@ -472,6 +472,14 @@ eth_identify_subint (vnet_hw_interface_t * hi,
   return 1;
 }
 
+// Compare two ethernet macs. Return 1 if they are the same, 0 if different
+always_inline u32
+eth_mac_equal (u8 * mac1, u8 * mac2) {
+  return (*((u32 *)(mac1+0)) == *((u32 *)(mac2+0)) &&
+          *((u32 *)(mac1+2)) == *((u32 *)(mac2+2)));
+}
+
+
 always_inline ethernet_main_t * 
 vnet_get_ethernet_main (void)
 {
index e8902fd..1f5151a 100644 (file)
@@ -81,14 +81,6 @@ typedef enum {
 } ethernet_input_variant_t;
 
 
-// Compare two ethernet macs. Return 1 if they are the same, 0 if different
-static_always_inline u32
-eth_mac_equal (u8 * mac1, u8 * mac2) {
-  return (*((u32 *)(mac1+0)) == *((u32 *)(mac2+0)) &&
-          *((u32 *)(mac1+2)) == *((u32 *)(mac2+2)));
-}
-
-
 // Parse the ethernet header to extract vlan tags and innermost ethertype
 static_always_inline void
 parse_header (ethernet_input_variant_t variant,
index b3b20d6..54b7606 100644 (file)
@@ -25,7 +25,7 @@
 #include <vnet/l2/l2_input.h>
 
 #define TO_BVI_ERR_OK        0
-#define TO_BVI_ERR_TAGGED    1
+#define TO_BVI_ERR_BAD_MAC   1
 #define TO_BVI_ERR_ETHERTYPE 2
 
 // Send a packet from L2 processing to L3 via the BVI interface.
@@ -43,6 +43,17 @@ l2_to_bvi (vlib_main_t * vlib_main,
   u8 l2_len;
   u16 ethertype;
   u8 * l3h;
+  ethernet_header_t * e0;
+  vnet_hw_interface_t * hi;
+
+  e0 = vlib_buffer_get_current (b0);
+  hi = vnet_get_sup_hw_interface (vnet_main, bvi_sw_if_index);
+
+  // Perform L3 my-mac filter
+  if ((!ethernet_address_cast(e0->dst_address)) &&
+      (!eth_mac_equal((u8 *)e0, hi->hw_address))) {
+      return TO_BVI_ERR_BAD_MAC;
+  }
 
   // Save L2 header position which may be changed due to packet replication
   vnet_buffer (b0)->ethernet.start_of_ethernet_header = b0->current_data;
index ca8c171..d6411e1 100644 (file)
@@ -87,7 +87,7 @@ static vlib_node_registration_t l2flood_node;
 _(L2FLOOD,           "L2 flood packets")                       \
 _(REPL_FAIL,         "L2 replication failures")                        \
 _(NO_MEMBERS,        "L2 replication complete")                        \
-_(BVI_TAGGED,        "BVI packet with vlan tag")               \
+_(BVI_BAD_MAC,       "BVI L3 mac mismatch")                    \
 _(BVI_ETHERTYPE,     "BVI packet with unhandled ethertype")
 
 typedef enum {
@@ -247,8 +247,8 @@ l2flood_process (vlib_main_t * vm,
                     next0);
 
     if (PREDICT_FALSE(rc)) {
-      if (rc == TO_BVI_ERR_TAGGED) {
-        b0->error = node->errors[L2FLOOD_ERROR_BVI_TAGGED];
+      if (rc == TO_BVI_ERR_BAD_MAC) {
+        b0->error = node->errors[L2FLOOD_ERROR_BVI_BAD_MAC];
         *next0 = L2FLOOD_NEXT_DROP;
       } else if (rc == TO_BVI_ERR_ETHERTYPE) {
         b0->error = node->errors[L2FLOOD_ERROR_BVI_ETHERTYPE];
index 88a6b69..fd1f8df 100644 (file)
@@ -75,7 +75,7 @@ static vlib_node_registration_t l2fwd_node;
 _(L2FWD,         "L2 forward packets")                 \
 _(FLOOD,         "L2 forward misses")                  \
 _(HIT,           "L2 forward hits")                    \
-_(BVI_TAGGED,    "BVI packet with vlan tag")           \
+_(BVI_BAD_MAC,   "BVI L3 MAC mismatch")                \
 _(BVI_ETHERTYPE, "BVI packet with unhandled ethertype")        \
 _(FILTER_DROP,   "Filter Mac Drop")                    \
 _(REFLECT_DROP,  "Reflection Drop")
@@ -155,8 +155,8 @@ l2fwd_process (vlib_main_t * vm,
                       next0);
 
       if (PREDICT_FALSE(rc)) {
-        if (rc == TO_BVI_ERR_TAGGED) {
-          b0->error = node->errors[L2FWD_ERROR_BVI_TAGGED];
+        if (rc == TO_BVI_ERR_BAD_MAC) {
+          b0->error = node->errors[L2FWD_ERROR_BVI_BAD_MAC];
           *next0 = L2FWD_NEXT_DROP;
         } else if (rc == TO_BVI_ERR_ETHERTYPE) {
           b0->error = node->errors[L2FWD_ERROR_BVI_ETHERTYPE];