summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Lo <loj@cisco.com>2016-06-04 00:02:37 -0400
committerJohn Lo <loj@cisco.com>2016-06-04 00:02:37 -0400
commit19042148849d2a71a79277f73aafbbd1b9478466 (patch)
tree82a713b4ee0a008f010fb3eacf5b60143584f01a
parent2671f1188d41313a6b54f5bd3d83973850f34934 (diff)
VPP-113: BVI shall filter unicast DMAC for L2 to L3 forwading
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>
-rw-r--r--vnet/vnet/ethernet/ethernet.h8
-rw-r--r--vnet/vnet/ethernet/node.c8
-rw-r--r--vnet/vnet/l2/l2_bvi.h13
-rw-r--r--vnet/vnet/l2/l2_flood.c6
-rw-r--r--vnet/vnet/l2/l2_fwd.c6
5 files changed, 26 insertions, 15 deletions
diff --git a/vnet/vnet/ethernet/ethernet.h b/vnet/vnet/ethernet/ethernet.h
index f519f4f3190..97c66e7593a 100644
--- a/vnet/vnet/ethernet/ethernet.h
+++ b/vnet/vnet/ethernet/ethernet.h
@@ -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)
{
diff --git a/vnet/vnet/ethernet/node.c b/vnet/vnet/ethernet/node.c
index e8902fd7410..1f5151aead6 100644
--- a/vnet/vnet/ethernet/node.c
+++ b/vnet/vnet/ethernet/node.c
@@ -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,
diff --git a/vnet/vnet/l2/l2_bvi.h b/vnet/vnet/l2/l2_bvi.h
index b3b20d63104..54b7606e06a 100644
--- a/vnet/vnet/l2/l2_bvi.h
+++ b/vnet/vnet/l2/l2_bvi.h
@@ -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;
diff --git a/vnet/vnet/l2/l2_flood.c b/vnet/vnet/l2/l2_flood.c
index ca8c171c245..d6411e1727d 100644
--- a/vnet/vnet/l2/l2_flood.c
+++ b/vnet/vnet/l2/l2_flood.c
@@ -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];
diff --git a/vnet/vnet/l2/l2_fwd.c b/vnet/vnet/l2/l2_fwd.c
index 88a6b69c340..fd1f8dfe535 100644
--- a/vnet/vnet/l2/l2_fwd.c
+++ b/vnet/vnet/l2/l2_fwd.c
@@ -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];