From b474380f82b75d9640f9bf6ee78c891a6794dbfb Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Wed, 5 Sep 2018 09:13:57 -0700 Subject: L2 BD: introduce a BD interface on which to send UU packets Change-Id: I21ad6b04c19c8735d057174b1f260a59f2812241 Signed-off-by: Neale Ranns --- test/test_acl_plugin_l2l3.py | 4 +- test/test_acl_plugin_macip.py | 4 +- test/test_dvr.py | 8 +-- test/test_gbp.py | 9 ++-- test/test_ip4_irb.py | 4 +- test/test_l2_flood.py | 111 +++++++++++++++++++++++++++++++++++++++++- test/vpp_papi_provider.py | 24 +++++++-- 7 files changed, 149 insertions(+), 15 deletions(-) (limited to 'test') diff --git a/test/test_acl_plugin_l2l3.py b/test/test_acl_plugin_l2l3.py index 26b562e8ad0..66d053ff584 100644 --- a/test/test_acl_plugin_l2l3.py +++ b/test/test_acl_plugin_l2l3.py @@ -36,6 +36,7 @@ from scapy.layers.inet6 import ICMPv6EchoReply, IPv6ExtHdrRouting from scapy.layers.inet6 import IPv6ExtHdrFragment from framework import VppTestCase, VppTestRunner +from vpp_papi_provider import L2_PORT_TYPE import time @@ -70,7 +71,8 @@ class TestIpIrb(VppTestCase): # Create BD with MAC learning enabled and put interfaces to this BD cls.vapi.sw_interface_set_l2_bridge( - cls.loop0.sw_if_index, bd_id=cls.bd_id, bvi=1) + cls.loop0.sw_if_index, bd_id=cls.bd_id, + port_type=L2_PORT_TYPE.BVI) cls.vapi.sw_interface_set_l2_bridge( cls.pg0.sw_if_index, bd_id=cls.bd_id) cls.vapi.sw_interface_set_l2_bridge( diff --git a/test/test_acl_plugin_macip.py b/test/test_acl_plugin_macip.py index f35db55fb7e..611bc73e312 100644 --- a/test/test_acl_plugin_macip.py +++ b/test/test_acl_plugin_macip.py @@ -16,6 +16,7 @@ from framework import VppTestCase, VppTestRunner, running_extended_tests from vpp_lo_interface import VppLoInterface from vpp_papi_provider import L2_VTR_OP from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint +from vpp_papi_provider import L2_PORT_TYPE class MethodHolder(VppTestCase): @@ -90,7 +91,8 @@ class MethodHolder(VppTestCase): # Create BD with MAC learning enabled and put interfaces to this BD cls.vapi.sw_interface_set_l2_bridge( - cls.loop0.sw_if_index, bd_id=cls.bd_id, bvi=1) + cls.loop0.sw_if_index, bd_id=cls.bd_id, + port_type=L2_PORT_TYPE.BVI) cls.vapi.sw_interface_set_l2_bridge( cls.pg0.sw_if_index, bd_id=cls.bd_id) cls.vapi.sw_interface_set_l2_bridge( diff --git a/test/test_dvr.py b/test/test_dvr.py index 9d8675832ea..7a744baf76c 100644 --- a/test/test_dvr.py +++ b/test/test_dvr.py @@ -4,7 +4,7 @@ import unittest from framework import VppTestCase, VppTestRunner from vpp_sub_interface import VppDot1QSubint from vpp_ip_route import VppIpRoute, VppRoutePath -from vpp_papi_provider import L2_VTR_OP +from vpp_papi_provider import L2_VTR_OP, L2_PORT_TYPE from scapy.packet import Raw from scapy.layers.l2 import Ether, Dot1Q @@ -88,7 +88,8 @@ class TestDVR(VppTestCase): self.vapi.sw_interface_set_l2_bridge(self.pg1.sw_if_index, 1) self.vapi.sw_interface_set_l2_bridge(sub_if_on_pg2.sw_if_index, 1) self.vapi.sw_interface_set_l2_bridge(sub_if_on_pg3.sw_if_index, 1) - self.vapi.sw_interface_set_l2_bridge(self.loop0.sw_if_index, 1, bvi=1) + self.vapi.sw_interface_set_l2_bridge(self.loop0.sw_if_index, 1, + port_type=L2_PORT_TYPE.BVI) self.vapi.sw_interface_set_l2_tag_rewrite(sub_if_on_pg2.sw_if_index, L2_VTR_OP.L2_POP_1, @@ -208,7 +209,8 @@ class TestDVR(VppTestCase): self.vapi.sw_interface_set_l2_bridge(sub_if_on_pg3.sw_if_index, 1, enable=0) self.vapi.sw_interface_set_l2_bridge(self.loop0.sw_if_index, - 1, bvi=1, enable=0) + 1, port_type=L2_PORT_TYPE.BVI, + enable=0) # # Do a FIB dump to make sure the paths are correctly reported as DVR diff --git a/test/test_gbp.py b/test/test_gbp.py index 0d5dd154be7..132bd247dd1 100644 --- a/test/test_gbp.py +++ b/test/test_gbp.py @@ -9,6 +9,7 @@ from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable from vpp_ip import * from vpp_mac import * +from vpp_papi_provider import L2_PORT_TYPE from scapy.packet import Raw from scapy.layers.l2 import Ether, ARP @@ -585,9 +586,11 @@ class TestGBP(VppTestCase): # epg[1] shares the same BVI to epg[0] if epg != epgs[1] and epg != epgs[4]: # BVI in BD - self.vapi.sw_interface_set_l2_bridge(epg.bvi.sw_if_index, - epg.bd, - bvi=1) + self.vapi.sw_interface_set_l2_bridge( + epg.bvi.sw_if_index, + epg.bd, + port_type=L2_PORT_TYPE.BVI) + # BVI L2 FIB entry self.vapi.l2fib_add_del(self.router_mac, epg.bd, diff --git a/test/test_ip4_irb.py b/test/test_ip4_irb.py index 6aad60a7609..cf7d89e4f6e 100644 --- a/test/test_ip4_irb.py +++ b/test/test_ip4_irb.py @@ -32,6 +32,7 @@ from scapy.layers.inet import IP, UDP from framework import VppTestCase, VppTestRunner from util import mactobinary +from vpp_papi_provider import L2_PORT_TYPE class TestIpIrb(VppTestCase): @@ -65,7 +66,8 @@ class TestIpIrb(VppTestCase): # Create BD with MAC learning enabled and put interfaces to this BD cls.vapi.sw_interface_set_l2_bridge( - cls.loop0.sw_if_index, bd_id=cls.bd_id, bvi=1) + cls.loop0.sw_if_index, bd_id=cls.bd_id, + port_type=L2_PORT_TYPE.BVI) cls.vapi.sw_interface_set_l2_bridge( cls.pg0.sw_if_index, bd_id=cls.bd_id) cls.vapi.sw_interface_set_l2_bridge( diff --git a/test/test_l2_flood.py b/test/test_l2_flood.py index a8b6b10f11a..50a692e57e8 100644 --- a/test/test_l2_flood.py +++ b/test/test_l2_flood.py @@ -5,6 +5,7 @@ import socket from framework import VppTestCase, VppTestRunner from vpp_ip_route import VppIpRoute, VppRoutePath +from vpp_papi_provider import L2_PORT_TYPE, BRIDGE_FLAGS from scapy.packet import Raw from scapy.layers.l2 import Ether @@ -58,7 +59,8 @@ class TestL2Flood(VppTestCase): for i in self.pg_interfaces[8:12]: self.vapi.sw_interface_set_l2_bridge(i.sw_if_index, 1, 2) for i in self.lo_interfaces: - self.vapi.sw_interface_set_l2_bridge(i.sw_if_index, 1, 2, bvi=1) + self.vapi.sw_interface_set_l2_bridge(i.sw_if_index, 1, 2, + port_type=L2_PORT_TYPE.BVI) p = (Ether(dst="ff:ff:ff:ff:ff:ff", src="00:00:de:ad:be:ef") / @@ -137,7 +139,112 @@ class TestL2Flood(VppTestCase): self.vapi.sw_interface_set_l2_bridge(i.sw_if_index, 1, enable=0) for i in self.lo_interfaces: self.vapi.sw_interface_set_l2_bridge(i.sw_if_index, 1, 2, - bvi=1, enable=0) + port_type=L2_PORT_TYPE.BVI, + enable=0) + + self.vapi.bridge_domain_add_del(1, is_add=0) + + def test_uu_fwd(self): + """ UU Flood """ + + # + # Create a single bridge Domain + # + self.vapi.bridge_domain_add_del(1, uu_flood=1) + + # + # add each interface to the BD. 3 interfaces per split horizon group + # + for i in self.pg_interfaces[0:4]: + self.vapi.sw_interface_set_l2_bridge(i.sw_if_index, 1, 0) + + # + # an unknown unicast packet + # + 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('\xa5' * 100)) + + # + # input on pg0, expected copies on pg1->4 + # + self.pg0.add_stream(p_uu*65) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + + for i in self.pg_interfaces[1:4]: + rx0 = i.get_capture(65, timeout=1) + + # + # use pg8 as the uu-fwd interface + # + self.vapi.sw_interface_set_l2_bridge(self.pg8.sw_if_index, 1, 0, + port_type=L2_PORT_TYPE.UU_FWD) + + # + # expect the UU packet on the uu-fwd interface and not be flooded + # + self.pg0.add_stream(p_uu*65) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + + rx0 = self.pg8.get_capture(65, timeout=1) + + for i in self.pg_interfaces[0:4]: + i.assert_nothing_captured(remark="UU not flooded") + + # + # remove the uu-fwd interface and expect UU to be flooded again + # + self.vapi.sw_interface_set_l2_bridge(self.pg8.sw_if_index, 1, 0, + port_type=L2_PORT_TYPE.UU_FWD, + enable=0) + + self.pg0.add_stream(p_uu*65) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + + for i in self.pg_interfaces[1:4]: + rx0 = i.get_capture(65, timeout=1) + + # + # change the BD config to not support UU-flood + # + self.vapi.bridge_flags(1, 0, BRIDGE_FLAGS.UU_FLOOD) + + self.send_and_assert_no_replies(self.pg0, p_uu) + + # + # re-add the uu-fwd interface + # + self.vapi.sw_interface_set_l2_bridge(self.pg8.sw_if_index, 1, 0, + port_type=L2_PORT_TYPE.UU_FWD) + self.logger.info(self.vapi.cli("sh bridge 1 detail")) + + self.pg0.add_stream(p_uu*65) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + + rx0 = self.pg8.get_capture(65, timeout=1) + + for i in self.pg_interfaces[0:4]: + i.assert_nothing_captured(remark="UU not flooded") + + # + # remove the uu-fwd interface + # + self.vapi.sw_interface_set_l2_bridge(self.pg8.sw_if_index, 1, 0, + port_type=L2_PORT_TYPE.UU_FWD, + enable=0) + self.send_and_assert_no_replies(self.pg0, p_uu) + + # + # cleanup + # + for i in self.pg_interfaces[:4]: + self.vapi.sw_interface_set_l2_bridge(i.sw_if_index, 1, enable=0) self.vapi.bridge_domain_add_del(1, is_add=0) diff --git a/test/vpp_papi_provider.py b/test/vpp_papi_provider.py index 0c98f7ae1a0..ee45a5fb4cd 100644 --- a/test/vpp_papi_provider.py +++ b/test/vpp_papi_provider.py @@ -43,6 +43,21 @@ class QOS_SOURCE: IP = 3 +class L2_PORT_TYPE: + NORMAL = 0 + BVI = 1 + UU_FWD = 2 + + +class BRIDGE_FLAGS: + NONE = 0 + LEARN = 1 + FWD = 2 + FLOOD = 4 + UU_FLOOD = 8 + ARP_TERM = 16 + + class UnexpectedApiReturnValueError(Exception): """ exception raised when the API return value is unexpected """ pass @@ -627,7 +642,8 @@ class VppPapiProvider(object): return self.api(self.papi.l2fib_flush_all, {}) def sw_interface_set_l2_bridge(self, sw_if_index, bd_id, - shg=0, bvi=0, enable=1): + shg=0, port_type=L2_PORT_TYPE.NORMAL, + enable=1): """Add/remove interface to/from bridge domain. :param int sw_if_index: Software interface index of the interface. @@ -641,7 +657,7 @@ class VppPapiProvider(object): {'rx_sw_if_index': sw_if_index, 'bd_id': bd_id, 'shg': shg, - 'bvi': bvi, + 'port_type': port_type, 'enable': enable}) def bridge_flags(self, bd_id, is_set, feature_bitmap): @@ -650,7 +666,7 @@ class VppPapiProvider(object): :param int bd_id: Bridge domain ID. :param int is_set: Set to 1 to enable, set to 0 to disable the feature. - :param int feature_bitmap: Bitmap value of the feature to be set: + :param int flags: Bitmap value of the feature to be set: - learn (1 << 0), - forward (1 << 1), - flood (1 << 2), @@ -660,7 +676,7 @@ class VppPapiProvider(object): return self.api(self.papi.bridge_flags, {'bd_id': bd_id, 'is_set': is_set, - 'feature_bitmap': feature_bitmap}) + 'flags': feature_bitmap}) def bridge_domain_dump(self, bd_id=0): """ -- cgit 1.2.3-korg