From 1904c47d5f79f8e9dcc6c9ae2043e7d6be8bd6d8 Mon Sep 17 00:00:00 2001 From: John Lo Date: Fri, 10 Mar 2017 17:15:22 -0500 Subject: Add MAC address check in ethernet-input node if interface in L3 mode Interface can be in promiscuous mode if more than one of its sub- interface is in L2 mode. In promiscuous mode, L3 interface need to verify DMAC of packet to match that of the interface and drop if not. This check was done on sub-interface only and now also added to main interface path. Fix incorrect MAC addresses in the flow-per-pkt plugin test, which caused it to fail. Fix MAC address usage in BFD tests. Change-Id: I12a17ec05c7ab298ad10d400c90d082c97eca521 Signed-off-by: John Lo Signed-off-by: Klement Sekera --- src/vnet/ethernet/node.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'src/vnet/ethernet/node.c') diff --git a/src/vnet/ethernet/node.c b/src/vnet/ethernet/node.c index 6d57da31..b699e381 100755 --- a/src/vnet/ethernet/node.c +++ b/src/vnet/ethernet/node.c @@ -294,6 +294,7 @@ ethernet_input_inline (vlib_main_t * vm, u32 cpu_index = os_get_cpu_number (); u32 cached_sw_if_index = ~0; u32 cached_is_l2 = 0; /* shut up gcc */ + vnet_hw_interface_t *hi = NULL; /* used for main interface only */ if (variant != ETHERNET_INPUT_VARIANT_ETHERNET) error_node = vlib_node_get_runtime (vm, ethernet_input_node.index); @@ -386,11 +387,12 @@ ethernet_input_inline (vlib_main_t * vm, if (PREDICT_FALSE (sw_if_index0 != sw_if_index1)) goto slowpath; + /* Now sw_if_index0 == sw_if_index1 */ if (PREDICT_FALSE (cached_sw_if_index != sw_if_index0)) { cached_sw_if_index = sw_if_index0; - hi0 = vnet_get_sup_hw_interface (vnm, sw_if_index0); - intf0 = vec_elt_at_index (em->main_intfs, hi0->hw_if_index); + hi = vnet_get_sup_hw_interface (vnm, sw_if_index0); + intf0 = vec_elt_at_index (em->main_intfs, hi->hw_if_index); subint0 = &intf0->untagged_subint; cached_is_l2 = is_l20 = subint0->flags & SUBINT_CONFIG_L2; } @@ -409,6 +411,12 @@ ethernet_input_inline (vlib_main_t * vm, } else { + if (!ethernet_address_cast (e0->dst_address) && + !eth_mac_equal ((u8 *) e0, hi->hw_address)) + error0 = ETHERNET_ERROR_L3_MAC_MISMATCH; + if (!ethernet_address_cast (e1->dst_address) && + !eth_mac_equal ((u8 *) e1, hi->hw_address)) + error1 = ETHERNET_ERROR_L3_MAC_MISMATCH; determine_next_node (em, variant, 0, type0, b0, &error0, &next0); vlib_buffer_advance (b0, sizeof (ethernet_header_t)); @@ -540,10 +548,10 @@ ethernet_input_inline (vlib_main_t * vm, determine_next_node (em, variant, is_l21, type1, b1, &error1, &next1); + ship_it01: b0->error = error_node->errors[error0]; b1->error = error_node->errors[error1]; - ship_it01: // verify speculative enqueue vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, @@ -603,8 +611,8 @@ ethernet_input_inline (vlib_main_t * vm, if (PREDICT_FALSE (cached_sw_if_index != sw_if_index0)) { cached_sw_if_index = sw_if_index0; - hi0 = vnet_get_sup_hw_interface (vnm, sw_if_index0); - intf0 = vec_elt_at_index (em->main_intfs, hi0->hw_if_index); + hi = vnet_get_sup_hw_interface (vnm, sw_if_index0); + intf0 = vec_elt_at_index (em->main_intfs, hi->hw_if_index); subint0 = &intf0->untagged_subint; cached_is_l2 = is_l20 = subint0->flags & SUBINT_CONFIG_L2; } @@ -619,6 +627,9 @@ ethernet_input_inline (vlib_main_t * vm, } else { + if (!ethernet_address_cast (e0->dst_address) && + !eth_mac_equal ((u8 *) e0, hi->hw_address)) + error0 = ETHERNET_ERROR_L3_MAC_MISMATCH; determine_next_node (em, variant, 0, type0, b0, &error0, &next0); vlib_buffer_advance (b0, sizeof (ethernet_header_t)); @@ -705,10 +716,10 @@ ethernet_input_inline (vlib_main_t * vm, determine_next_node (em, variant, is_l20, type0, b0, &error0, &next0); + ship_it0: b0->error = error_node->errors[error0]; // verify speculative enqueue - ship_it0: vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, n_left_to_next, bi0, next0); -- cgit 1.2.3-korg