2019-10-31 13:31:07 -05:00
|
|
|
#!/usr/bin/env python3
|
2018-07-20 01:16:04 -07:00
|
|
|
|
|
|
|
import unittest
|
|
|
|
|
2023-08-31 00:47:44 -04:00
|
|
|
from framework import VppTestCase
|
|
|
|
from asfframework import VppTestRunner
|
2018-07-20 01:16:04 -07:00
|
|
|
from vpp_ip_route import VppIpRoute, VppRoutePath
|
2018-10-10 07:22:51 -07:00
|
|
|
from vpp_l2 import L2_PORT_TYPE, BRIDGE_FLAGS
|
2018-07-20 01:16:04 -07:00
|
|
|
|
|
|
|
from scapy.packet import Raw
|
|
|
|
from scapy.layers.l2 import Ether
|
|
|
|
from scapy.layers.inet import IP, UDP
|
|
|
|
|
2019-05-14 13:25:49 -04:00
|
|
|
NUM_PKTS = 67
|
|
|
|
|
2018-07-20 01:16:04 -07:00
|
|
|
|
|
|
|
class TestL2Flood(VppTestCase):
|
2022-04-26 19:02:15 +02:00
|
|
|
"""L2-flood"""
|
2018-07-20 01:16:04 -07:00
|
|
|
|
2019-03-12 19:23:27 -07:00
|
|
|
@classmethod
|
|
|
|
def setUpClass(cls):
|
|
|
|
super(TestL2Flood, cls).setUpClass()
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def tearDownClass(cls):
|
|
|
|
super(TestL2Flood, cls).tearDownClass()
|
|
|
|
|
2018-07-20 01:16:04 -07:00
|
|
|
def setUp(self):
|
|
|
|
super(TestL2Flood, self).setUp()
|
|
|
|
|
|
|
|
# 12 l2 interface and one l3
|
|
|
|
self.create_pg_interfaces(range(13))
|
2019-03-15 02:16:20 -07:00
|
|
|
self.create_bvi_interfaces(1)
|
2018-07-20 01:16:04 -07:00
|
|
|
|
|
|
|
for i in self.pg_interfaces:
|
|
|
|
i.admin_up()
|
2019-03-15 02:16:20 -07:00
|
|
|
for i in self.bvi_interfaces:
|
2018-07-20 01:16:04 -07:00
|
|
|
i.admin_up()
|
|
|
|
|
|
|
|
self.pg12.config_ip4()
|
|
|
|
self.pg12.resolve_arp()
|
2019-03-15 02:16:20 -07:00
|
|
|
self.bvi0.config_ip4()
|
2018-07-20 01:16:04 -07:00
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
self.pg12.unconfig_ip4()
|
2019-03-15 02:16:20 -07:00
|
|
|
self.bvi0.unconfig_ip4()
|
2018-07-20 01:16:04 -07:00
|
|
|
|
|
|
|
for i in self.pg_interfaces:
|
|
|
|
i.admin_down()
|
2019-03-15 02:16:20 -07:00
|
|
|
for i in self.bvi_interfaces:
|
2018-07-20 01:16:04 -07:00
|
|
|
i.admin_down()
|
|
|
|
super(TestL2Flood, self).tearDown()
|
|
|
|
|
|
|
|
def test_flood(self):
|
2022-04-26 19:02:15 +02:00
|
|
|
"""L2 Flood Tests"""
|
2018-07-20 01:16:04 -07:00
|
|
|
|
|
|
|
#
|
|
|
|
# Create a single bridge Domain
|
|
|
|
#
|
2022-09-16 13:20:07 +02:00
|
|
|
self.vapi.bridge_domain_add_del_v2(
|
|
|
|
bd_id=1, is_add=1, flood=1, uu_flood=1, forward=1, learn=1
|
|
|
|
)
|
2018-07-20 01:16:04 -07:00
|
|
|
|
|
|
|
#
|
|
|
|
# add each interface to the BD. 3 interfaces per split horizon group
|
|
|
|
#
|
|
|
|
for i in self.pg_interfaces[0:4]:
|
2022-04-26 19:02:15 +02:00
|
|
|
self.vapi.sw_interface_set_l2_bridge(
|
|
|
|
rx_sw_if_index=i.sw_if_index, bd_id=1, shg=0
|
|
|
|
)
|
2018-07-20 01:16:04 -07:00
|
|
|
for i in self.pg_interfaces[4:8]:
|
2022-04-26 19:02:15 +02:00
|
|
|
self.vapi.sw_interface_set_l2_bridge(
|
|
|
|
rx_sw_if_index=i.sw_if_index, bd_id=1, shg=1
|
|
|
|
)
|
2018-07-20 01:16:04 -07:00
|
|
|
for i in self.pg_interfaces[8:12]:
|
2022-04-26 19:02:15 +02:00
|
|
|
self.vapi.sw_interface_set_l2_bridge(
|
|
|
|
rx_sw_if_index=i.sw_if_index, bd_id=1, shg=2
|
|
|
|
)
|
2019-03-15 02:16:20 -07:00
|
|
|
for i in self.bvi_interfaces:
|
2022-04-26 19:02:15 +02:00
|
|
|
self.vapi.sw_interface_set_l2_bridge(
|
|
|
|
rx_sw_if_index=i.sw_if_index, bd_id=1, shg=2, port_type=L2_PORT_TYPE.BVI
|
|
|
|
)
|
2018-07-20 01:16:04 -07:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
p = (
|
|
|
|
Ether(dst="ff:ff:ff:ff:ff:ff", src="00:00:de:ad:be:ef")
|
|
|
|
/ IP(src="10.10.10.10", dst="1.1.1.1")
|
|
|
|
/ UDP(sport=1234, dport=1234)
|
|
|
|
/ Raw(b"\xa5" * 100)
|
|
|
|
)
|
2018-07-20 01:16:04 -07:00
|
|
|
|
|
|
|
#
|
|
|
|
# input on pg0 expect copies on pg1->11
|
|
|
|
# this is in SHG=0 so its flooded to all, expect the pg0 since that's
|
|
|
|
# the ingress link
|
|
|
|
#
|
2022-04-26 19:02:15 +02:00
|
|
|
self.pg0.add_stream(p * NUM_PKTS)
|
2018-07-20 01:16:04 -07:00
|
|
|
self.pg_enable_capture(self.pg_interfaces)
|
|
|
|
self.pg_start()
|
|
|
|
|
|
|
|
for i in self.pg_interfaces[1:12]:
|
2019-05-14 13:25:49 -04:00
|
|
|
rx0 = i.get_capture(NUM_PKTS, timeout=1)
|
2018-07-20 01:16:04 -07:00
|
|
|
|
|
|
|
#
|
|
|
|
# input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0)
|
|
|
|
# and pg8->11 (SHG=2)
|
|
|
|
#
|
2022-04-26 19:02:15 +02:00
|
|
|
self.pg4.add_stream(p * NUM_PKTS)
|
2018-07-20 01:16:04 -07:00
|
|
|
self.pg_enable_capture(self.pg_interfaces)
|
|
|
|
self.pg_start()
|
|
|
|
|
|
|
|
for i in self.pg_interfaces[:4]:
|
2019-05-14 13:25:49 -04:00
|
|
|
rx0 = i.get_capture(NUM_PKTS, timeout=1)
|
2018-07-20 01:16:04 -07:00
|
|
|
for i in self.pg_interfaces[8:12]:
|
2019-05-14 13:25:49 -04:00
|
|
|
rx0 = i.get_capture(NUM_PKTS, timeout=1)
|
2018-07-20 01:16:04 -07:00
|
|
|
for i in self.pg_interfaces[4:8]:
|
|
|
|
i.assert_nothing_captured(remark="Different SH group")
|
|
|
|
|
|
|
|
#
|
|
|
|
# An IP route so the packet that hits the BVI is sent out of pg12
|
|
|
|
#
|
2022-04-26 19:02:15 +02:00
|
|
|
ip_route = VppIpRoute(
|
|
|
|
self,
|
|
|
|
"1.1.1.1",
|
|
|
|
32,
|
|
|
|
[VppRoutePath(self.pg12.remote_ip4, self.pg12.sw_if_index)],
|
|
|
|
)
|
2018-07-20 01:16:04 -07:00
|
|
|
ip_route.add_vpp_config()
|
|
|
|
|
|
|
|
self.logger.info(self.vapi.cli("sh bridge 1 detail"))
|
|
|
|
|
|
|
|
#
|
|
|
|
# input on pg0 expect copies on pg1->12
|
|
|
|
# this is in SHG=0 so its flooded to all, expect the pg0 since that's
|
|
|
|
# the ingress link
|
|
|
|
#
|
2022-04-26 19:02:15 +02:00
|
|
|
self.pg0.add_stream(p * NUM_PKTS)
|
2018-07-20 01:16:04 -07:00
|
|
|
self.pg_enable_capture(self.pg_interfaces)
|
|
|
|
self.pg_start()
|
|
|
|
|
|
|
|
for i in self.pg_interfaces[1:]:
|
2019-05-14 13:25:49 -04:00
|
|
|
rx0 = i.get_capture(NUM_PKTS, timeout=1)
|
2018-07-20 01:16:04 -07:00
|
|
|
|
|
|
|
#
|
|
|
|
# input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0)
|
|
|
|
# and pg8->12 (SHG=2)
|
|
|
|
#
|
2022-04-26 19:02:15 +02:00
|
|
|
self.pg4.add_stream(p * NUM_PKTS)
|
2018-07-20 01:16:04 -07:00
|
|
|
self.pg_enable_capture(self.pg_interfaces)
|
|
|
|
self.pg_start()
|
|
|
|
|
|
|
|
for i in self.pg_interfaces[:4]:
|
2019-05-14 13:25:49 -04:00
|
|
|
rx0 = i.get_capture(NUM_PKTS, timeout=1)
|
2018-07-20 01:16:04 -07:00
|
|
|
for i in self.pg_interfaces[8:13]:
|
2019-05-14 13:25:49 -04:00
|
|
|
rx0 = i.get_capture(NUM_PKTS, timeout=1)
|
2018-07-20 01:16:04 -07:00
|
|
|
for i in self.pg_interfaces[4:8]:
|
|
|
|
i.assert_nothing_captured(remark="Different SH group")
|
|
|
|
|
|
|
|
#
|
|
|
|
# cleanup
|
|
|
|
#
|
|
|
|
for i in self.pg_interfaces[:12]:
|
2022-04-26 19:02:15 +02:00
|
|
|
self.vapi.sw_interface_set_l2_bridge(
|
|
|
|
rx_sw_if_index=i.sw_if_index, bd_id=1, enable=0
|
|
|
|
)
|
2019-03-15 02:16:20 -07:00
|
|
|
for i in self.bvi_interfaces:
|
2022-04-26 19:02:15 +02:00
|
|
|
self.vapi.sw_interface_set_l2_bridge(
|
|
|
|
rx_sw_if_index=i.sw_if_index,
|
|
|
|
bd_id=1,
|
|
|
|
shg=2,
|
|
|
|
port_type=L2_PORT_TYPE.BVI,
|
|
|
|
enable=0,
|
|
|
|
)
|
2018-09-05 09:13:57 -07:00
|
|
|
|
2022-09-16 13:20:07 +02:00
|
|
|
self.vapi.bridge_domain_add_del_v2(bd_id=1, is_add=0)
|
2018-09-05 09:13:57 -07:00
|
|
|
|
2018-10-02 07:27:02 -07:00
|
|
|
def test_flood_one(self):
|
2022-04-26 19:02:15 +02:00
|
|
|
"""L2 no-Flood Test"""
|
2018-10-02 07:27:02 -07:00
|
|
|
|
|
|
|
#
|
|
|
|
# Create a single bridge Domain
|
|
|
|
#
|
2022-09-16 13:20:07 +02:00
|
|
|
self.vapi.bridge_domain_add_del_v2(
|
|
|
|
bd_id=1, is_add=1, flood=1, uu_flood=1, forward=1, learn=1
|
|
|
|
)
|
2018-10-02 07:27:02 -07:00
|
|
|
|
|
|
|
#
|
|
|
|
# add 2 interfaces to the BD. this means a flood goes to only
|
|
|
|
# one member
|
|
|
|
#
|
|
|
|
for i in self.pg_interfaces[:2]:
|
2022-04-26 19:02:15 +02:00
|
|
|
self.vapi.sw_interface_set_l2_bridge(
|
|
|
|
rx_sw_if_index=i.sw_if_index, bd_id=1, shg=0
|
|
|
|
)
|
2018-10-02 07:27:02 -07:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
p = (
|
|
|
|
Ether(dst="ff:ff:ff:ff:ff:ff", src="00:00:de:ad:be:ef")
|
|
|
|
/ IP(src="10.10.10.10", dst="1.1.1.1")
|
|
|
|
/ UDP(sport=1234, dport=1234)
|
|
|
|
/ Raw(b"\xa5" * 100)
|
|
|
|
)
|
2018-10-02 07:27:02 -07:00
|
|
|
|
|
|
|
#
|
|
|
|
# input on pg0 expect copies on pg1
|
|
|
|
#
|
2022-04-26 19:02:15 +02:00
|
|
|
self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg1)
|
2018-10-02 07:27:02 -07:00
|
|
|
|
|
|
|
#
|
|
|
|
# cleanup
|
|
|
|
#
|
|
|
|
for i in self.pg_interfaces[:2]:
|
2022-04-26 19:02:15 +02:00
|
|
|
self.vapi.sw_interface_set_l2_bridge(
|
|
|
|
rx_sw_if_index=i.sw_if_index, bd_id=1, enable=0
|
|
|
|
)
|
2022-09-16 13:20:07 +02:00
|
|
|
self.vapi.bridge_domain_add_del_v2(bd_id=1, is_add=0)
|
2018-10-02 07:27:02 -07:00
|
|
|
|
2018-09-05 09:13:57 -07:00
|
|
|
def test_uu_fwd(self):
|
2022-04-26 19:02:15 +02:00
|
|
|
"""UU Flood"""
|
2018-09-05 09:13:57 -07:00
|
|
|
|
|
|
|
#
|
|
|
|
# Create a single bridge Domain
|
|
|
|
#
|
2022-09-16 13:20:07 +02:00
|
|
|
self.vapi.bridge_domain_add_del_v2(
|
|
|
|
bd_id=1, is_add=1, uu_flood=1, flood=1, forward=1, learn=1
|
|
|
|
)
|
2018-09-05 09:13:57 -07:00
|
|
|
|
|
|
|
#
|
|
|
|
# add each interface to the BD. 3 interfaces per split horizon group
|
|
|
|
#
|
|
|
|
for i in self.pg_interfaces[0:4]:
|
2022-04-26 19:02:15 +02:00
|
|
|
self.vapi.sw_interface_set_l2_bridge(
|
|
|
|
rx_sw_if_index=i.sw_if_index, bd_id=1, shg=0
|
|
|
|
)
|
2018-09-05 09:13:57 -07:00
|
|
|
|
|
|
|
#
|
2019-03-27 11:25:48 -07:00
|
|
|
# an unknown unicast and broadcast packets
|
2018-09-05 09:13:57 -07:00
|
|
|
#
|
2022-04-26 19:02:15 +02:00
|
|
|
p_uu = (
|
|
|
|
Ether(dst="00:00:00:c1:5c:00", src="00:00:de:ad:be:ef")
|
|
|
|
/ IP(src="10.10.10.10", dst="1.1.1.1")
|
|
|
|
/ UDP(sport=1234, dport=1234)
|
|
|
|
/ Raw(b"\xa5" * 100)
|
|
|
|
)
|
|
|
|
p_bm = (
|
|
|
|
Ether(dst="ff:ff:ff:ff:ff:ff", src="00:00:de:ad:be:ef")
|
|
|
|
/ IP(src="10.10.10.10", dst="1.1.1.1")
|
|
|
|
/ UDP(sport=1234, dport=1234)
|
|
|
|
/ Raw(b"\xa5" * 100)
|
|
|
|
)
|
2018-09-05 09:13:57 -07:00
|
|
|
|
|
|
|
#
|
|
|
|
# input on pg0, expected copies on pg1->4
|
|
|
|
#
|
2022-04-26 19:02:15 +02:00
|
|
|
self.pg0.add_stream(p_uu * NUM_PKTS)
|
2018-09-05 09:13:57 -07:00
|
|
|
self.pg_enable_capture(self.pg_interfaces)
|
|
|
|
self.pg_start()
|
|
|
|
|
2018-10-10 15:55:01 +00:00
|
|
|
for i in self.pg_interfaces[1:4]:
|
2019-05-14 13:25:49 -04:00
|
|
|
rx0 = i.get_capture(NUM_PKTS, timeout=1)
|
2018-10-10 15:55:01 +00:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
self.pg0.add_stream(p_bm * NUM_PKTS)
|
2018-10-10 15:55:01 +00:00
|
|
|
self.pg_enable_capture(self.pg_interfaces)
|
|
|
|
self.pg_start()
|
|
|
|
|
2018-09-05 09:13:57 -07:00
|
|
|
for i in self.pg_interfaces[1:4]:
|
2019-05-14 13:25:49 -04:00
|
|
|
rx0 = i.get_capture(NUM_PKTS, timeout=1)
|
2018-09-05 09:13:57 -07:00
|
|
|
|
|
|
|
#
|
|
|
|
# use pg8 as the uu-fwd interface
|
|
|
|
#
|
2019-03-11 19:23:25 +01:00
|
|
|
self.vapi.sw_interface_set_l2_bridge(
|
2022-04-26 19:02:15 +02:00
|
|
|
rx_sw_if_index=self.pg8.sw_if_index,
|
|
|
|
bd_id=1,
|
|
|
|
shg=0,
|
|
|
|
port_type=L2_PORT_TYPE.UU_FWD,
|
|
|
|
)
|
2018-09-05 09:13:57 -07:00
|
|
|
|
|
|
|
#
|
|
|
|
# expect the UU packet on the uu-fwd interface and not be flooded
|
|
|
|
#
|
2022-04-26 19:02:15 +02:00
|
|
|
self.pg0.add_stream(p_uu * NUM_PKTS)
|
2018-09-05 09:13:57 -07:00
|
|
|
self.pg_enable_capture(self.pg_interfaces)
|
|
|
|
self.pg_start()
|
|
|
|
|
2019-05-14 13:25:49 -04:00
|
|
|
rx0 = self.pg8.get_capture(NUM_PKTS, timeout=1)
|
2018-09-05 09:13:57 -07:00
|
|
|
|
|
|
|
for i in self.pg_interfaces[0:4]:
|
|
|
|
i.assert_nothing_captured(remark="UU not flooded")
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
self.pg0.add_stream(p_bm * NUM_PKTS)
|
2018-10-10 15:55:01 +00:00
|
|
|
self.pg_enable_capture(self.pg_interfaces)
|
|
|
|
self.pg_start()
|
|
|
|
|
|
|
|
for i in self.pg_interfaces[1:4]:
|
2019-05-14 13:25:49 -04:00
|
|
|
rx0 = i.get_capture(NUM_PKTS, timeout=1)
|
2018-10-10 15:55:01 +00:00
|
|
|
|
2018-09-05 09:13:57 -07:00
|
|
|
#
|
|
|
|
# remove the uu-fwd interface and expect UU to be flooded again
|
|
|
|
#
|
2019-03-11 19:23:25 +01:00
|
|
|
self.vapi.sw_interface_set_l2_bridge(
|
2022-04-26 19:02:15 +02:00
|
|
|
rx_sw_if_index=self.pg8.sw_if_index,
|
|
|
|
bd_id=1,
|
|
|
|
shg=0,
|
|
|
|
port_type=L2_PORT_TYPE.UU_FWD,
|
|
|
|
enable=0,
|
|
|
|
)
|
|
|
|
|
|
|
|
self.pg0.add_stream(p_uu * NUM_PKTS)
|
2018-09-05 09:13:57 -07:00
|
|
|
self.pg_enable_capture(self.pg_interfaces)
|
|
|
|
self.pg_start()
|
|
|
|
|
|
|
|
for i in self.pg_interfaces[1:4]:
|
2019-05-14 13:25:49 -04:00
|
|
|
rx0 = i.get_capture(NUM_PKTS, timeout=1)
|
2018-09-05 09:13:57 -07:00
|
|
|
|
|
|
|
#
|
|
|
|
# change the BD config to not support UU-flood
|
|
|
|
#
|
2019-03-11 19:23:25 +01:00
|
|
|
self.vapi.bridge_flags(bd_id=1, is_set=0, flags=BRIDGE_FLAGS.UU_FLOOD)
|
2018-09-05 09:13:57 -07:00
|
|
|
|
|
|
|
self.send_and_assert_no_replies(self.pg0, p_uu)
|
|
|
|
|
|
|
|
#
|
|
|
|
# re-add the uu-fwd interface
|
|
|
|
#
|
2019-03-11 19:23:25 +01:00
|
|
|
self.vapi.sw_interface_set_l2_bridge(
|
2022-04-26 19:02:15 +02:00
|
|
|
rx_sw_if_index=self.pg8.sw_if_index,
|
|
|
|
bd_id=1,
|
|
|
|
shg=0,
|
|
|
|
port_type=L2_PORT_TYPE.UU_FWD,
|
|
|
|
)
|
2018-09-05 09:13:57 -07:00
|
|
|
self.logger.info(self.vapi.cli("sh bridge 1 detail"))
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
self.pg0.add_stream(p_uu * NUM_PKTS)
|
2018-09-05 09:13:57 -07:00
|
|
|
self.pg_enable_capture(self.pg_interfaces)
|
|
|
|
self.pg_start()
|
|
|
|
|
2019-05-14 13:25:49 -04:00
|
|
|
rx0 = self.pg8.get_capture(NUM_PKTS, timeout=1)
|
2018-09-05 09:13:57 -07:00
|
|
|
|
|
|
|
for i in self.pg_interfaces[0:4]:
|
|
|
|
i.assert_nothing_captured(remark="UU not flooded")
|
|
|
|
|
|
|
|
#
|
|
|
|
# remove the uu-fwd interface
|
|
|
|
#
|
2019-03-11 19:23:25 +01:00
|
|
|
self.vapi.sw_interface_set_l2_bridge(
|
2022-04-26 19:02:15 +02:00
|
|
|
rx_sw_if_index=self.pg8.sw_if_index,
|
|
|
|
bd_id=1,
|
|
|
|
shg=0,
|
|
|
|
port_type=L2_PORT_TYPE.UU_FWD,
|
|
|
|
enable=0,
|
|
|
|
)
|
2018-09-05 09:13:57 -07:00
|
|
|
self.send_and_assert_no_replies(self.pg0, p_uu)
|
|
|
|
|
|
|
|
#
|
|
|
|
# cleanup
|
|
|
|
#
|
|
|
|
for i in self.pg_interfaces[:4]:
|
2022-04-26 19:02:15 +02:00
|
|
|
self.vapi.sw_interface_set_l2_bridge(
|
|
|
|
rx_sw_if_index=i.sw_if_index, bd_id=1, enable=0
|
|
|
|
)
|
2018-07-20 01:16:04 -07:00
|
|
|
|
2022-09-16 13:20:07 +02:00
|
|
|
self.vapi.bridge_domain_add_del_v2(bd_id=1, is_add=0)
|
2018-07-20 01:16:04 -07:00
|
|
|
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
if __name__ == "__main__":
|
2018-07-20 01:16:04 -07:00
|
|
|
unittest.main(testRunner=VppTestRunner)
|