diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/vnet/ethernet/node.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/src/vnet/ethernet/node.c b/src/vnet/ethernet/node.c index 6d57da31708..b699e381f91 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); |