summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Lo <loj@cisco.com>2017-03-10 17:15:22 -0500
committerDave Barach <openvpp@barachs.net>2017-03-13 14:35:01 +0000
commit1904c47d5f79f8e9dcc6c9ae2043e7d6be8bd6d8 (patch)
tree29e82e2299067be4779a91fde37393ba6cb357d9
parent59dda065bb92d1588824483ed5e7cf9adb228d3a (diff)
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 <loj@cisco.com> Signed-off-by: Klement Sekera <ksekera@cisco.com>
-rwxr-xr-xsrc/vnet/ethernet/node.c23
-rw-r--r--test/test_bfd.py11
-rw-r--r--test/test_flowperpkt.py2
3 files changed, 28 insertions, 8 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);
diff --git a/test/test_bfd.py b/test/test_bfd.py
index 5460a2b5589..4e3f688b462 100644
--- a/test/test_bfd.py
+++ b/test/test_bfd.py
@@ -1090,6 +1090,9 @@ class BFD4TestCase(VppTestCase):
self.assertNotEqual(p[IP].src, self.loopback0.local_ip4,
"BFD ECHO src IP equal to loopback IP")
self.logger.debug(ppp("Looping back packet:", p))
+ self.assert_equal(p[Ether].dst, self.pg0.remote_mac,
+ "ECHO packet destination MAC address")
+ p[Ether].dst = self.pg0.local_mac
self.pg0.add_stream(p)
self.pg_start()
elif p.haslayer(BFD):
@@ -1159,6 +1162,7 @@ class BFD4TestCase(VppTestCase):
self.logger.debug(ppp("Got packet:", p))
if p[UDP].dport == BFD.udp_dport_echo:
self.logger.debug(ppp("Looping back packet:", p))
+ p[Ether].dst = self.pg0.local_mac
self.pg0.add_stream(p)
self.pg_start()
break
@@ -1190,6 +1194,7 @@ class BFD4TestCase(VppTestCase):
self.logger.debug(ppp("Got packet:", p))
if p[UDP].dport == BFD.udp_dport_echo:
self.logger.debug(ppp("Looping back packet:", p))
+ p[Ether].dst = self.pg0.local_mac
self.pg0.add_stream(p)
self.pg_start()
break
@@ -1230,6 +1235,7 @@ class BFD4TestCase(VppTestCase):
else:
self.logger.debug(ppp("Got followup echo packet:", p))
self.logger.debug(ppp("Looping back first echo packet:", p))
+ echo_packet[Ether].dst = self.pg0.local_mac
self.pg0.add_stream(echo_packet)
self.pg_start()
elif p.haslayer(BFD):
@@ -1278,6 +1284,7 @@ class BFD4TestCase(VppTestCase):
timeout_at = time.time() + self.vpp_session.detect_mult * \
self.test_session.required_min_echo_rx / USEC_IN_SEC
p[BFD_vpp_echo].checksum = getrandbits(64)
+ p[Ether].dst = self.pg0.local_mac
self.logger.debug(ppp("Looping back modified echo packet:", p))
self.pg0.add_stream(p)
self.pg_start()
@@ -1523,7 +1530,6 @@ class BFD6TestCase(VppTestCase):
self.assert_equal(udp_sport_tx, udp_sport_rx, "UDP source port (== "
"ECHO packet identifier for test purposes)")
- @unittest.skipUnless(running_extended_tests(), "part of extended tests")
def test_echo(self):
""" echo function used """
bfd_session_up(self)
@@ -1554,6 +1560,9 @@ class BFD6TestCase(VppTestCase):
self.assertNotEqual(p[IPv6].src, self.loopback0.local_ip6,
"BFD ECHO src IP equal to loopback IP")
self.logger.debug(ppp("Looping back packet:", p))
+ self.assert_equal(p[Ether].dst, self.pg0.remote_mac,
+ "ECHO packet destination MAC address")
+ p[Ether].dst = self.pg0.local_mac
self.pg0.add_stream(p)
self.pg_start()
elif p.haslayer(BFD):
diff --git a/test/test_flowperpkt.py b/test/test_flowperpkt.py
index f16bfb7eb5b..b13d0c63a1b 100644
--- a/test/test_flowperpkt.py
+++ b/test/test_flowperpkt.py
@@ -43,7 +43,7 @@ class TestFlowperpkt(VppTestCase):
for size in packet_sizes:
info = self.create_packet_info(src_if, dst_if)
payload = self.info_to_payload(info)
- p = (Ether(src=src_if.local_mac, dst=dst_if.remote_mac) /
+ p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4) /
UDP(sport=1234, dport=4321) /
Raw(payload))