diff options
author | John Lo <loj@cisco.com> | 2016-06-04 00:02:37 -0400 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2016-06-05 13:48:31 +0000 |
commit | 7185c3bb682bf93922cd03d0d3b43e931491a907 (patch) | |
tree | 36f02a1c7992e4bc6f1ca0242c384effda083719 | |
parent | c68b4cbf3aa1ea9f7e0f09ff4725feb92170c10f (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.h | 8 | ||||
-rw-r--r-- | vnet/vnet/ethernet/node.c | 8 | ||||
-rw-r--r-- | vnet/vnet/l2/l2_bvi.h | 13 | ||||
-rw-r--r-- | vnet/vnet/l2/l2_flood.c | 6 | ||||
-rw-r--r-- | vnet/vnet/l2/l2_fwd.c | 6 |
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 226a66e9a43..57a699594fc 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 9f71677c16b..61554ac1244 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 5af83a7529c..d2c99ce2a5e 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]; |