#!/usr/bin/env python3 from __future__ import print_function """ACL plugin - MACIP tests """ import binascii import ipaddress import random from socket import inet_ntop, inet_pton, AF_INET, AF_INET6 from struct import pack, unpack import re import unittest from ipaddress import ip_network, IPv4Network, IPv6Network import scapy.compat from scapy.packet import Raw from scapy.layers.l2 import Ether from scapy.layers.inet import IP, UDP from scapy.layers.inet6 import IPv6 from framework import VppTestCase, VppTestRunner from vpp_lo_interface import VppLoInterface from vpp_l2 import L2_PORT_TYPE from vpp_sub_interface import ( L2_VTR_OP, VppSubInterface, VppDot1QSubint, VppDot1ADSubint, ) from vpp_acl import ( AclRule, VppAcl, VppAclInterface, VppEtypeWhitelist, VppMacipAclInterface, VppMacipAcl, MacipRule, ) from vpp_papi import MACAddress class MethodHolder(VppTestCase): DEBUG = False BRIDGED = True ROUTED = False IS_IP4 = False IS_IP6 = True DOT1AD = "dot1ad" DOT1Q = "dot1q" PERMIT_TAGS = True DENY_TAGS = False # rule types DENY = 0 PERMIT = 1 # ACL types EXACT_IP = 1 SUBNET_IP = 2 WILD_IP = 3 EXACT_MAC = 1 WILD_MAC = 2 OUI_MAC = 3 ACLS = [] @classmethod def setUpClass(cls): """ Perform standard class setup (defined by class method setUpClass in class VppTestCase) before running the test case, set test case related variables and configure VPP. """ super(MethodHolder, cls).setUpClass() cls.pg_if_packet_sizes = [64, 512, 1518, 9018] # packet sizes cls.bd_id = 111 cls.remote_hosts_count = 200 try: # create 4 pg interfaces, 1 loopback interface cls.create_pg_interfaces(range(4)) cls.create_loopback_interfaces(1) # create 2 subinterfaces cls.subifs = [ VppDot1QSubint(cls, cls.pg1, 10), VppDot1ADSubint(cls, cls.pg2, 20, 300, 400), VppDot1QSubint(cls, cls.pg3, 30), VppDot1ADSubint(cls, cls.pg3, 40, 600, 700), ] cls.subifs[0].set_vtr(L2_VTR_OP.L2_POP_1, inner=10, push1q=1) cls.subifs[1].set_vtr(L2_VTR_OP.L2_POP_2, outer=300, inner=400, push1q=1) cls.subifs[2].set_vtr(L2_VTR_OP.L2_POP_1, inner=30, push1q=1) cls.subifs[3].set_vtr(L2_VTR_OP.L2_POP_2, outer=600, inner=700, push1q=1) cls.interfaces = list(cls.pg_interfaces) cls.interfaces.extend(cls.lo_interfaces) cls.interfaces.extend(cls.subifs) for i in cls.interfaces: i.admin_up() # Create BD with MAC learning enabled and put interfaces to this BD cls.vapi.sw_interface_set_l2_bridge( rx_sw_if_index=cls.loop0.sw_if_index, bd_id=cls.bd_id, port_type=L2_PORT_TYPE.BVI, ) cls.vapi.sw_interface_set_l2_bridge( rx_sw_if_index=cls.pg0.sw_if_index, bd_id=cls.bd_id ) cls.vapi.sw_interface_set_l2_bridge( rx_sw_if_index=cls.pg1.sw_if_index, bd_id=cls.bd_id ) cls.vapi.sw_interface_set_l2_bridge( rx_sw_if_index=cls.subifs[0].sw_if_index, bd_id=cls.bd_id ) cls.vapi.sw_interface_set_l2_bridge( rx_sw_if_index=cls.subifs[1].sw_if_index, bd_id=cls.bd_id ) # Configure IPv4/6 addresses on loop interface and routed interface cls.loop0.config_ip4() cls.loop0.config_ip6() cls.pg2.config_ip4() cls.pg2.config_ip6() cls.pg3.config_ip4() cls.pg3.config_ip6() # Configure MAC address binding to IPv4 neighbors on loop0 cls.loop0.generate_remote_hosts(cls.remote_hosts_count) # Modify host mac addresses to have different OUI parts for i in range(2, cls.remote_hosts_count + 2): mac = cls.loop0.remote_hosts[i - 2]._mac.split(":") mac[2] = format(int(mac[2], 16) + i, "02x") cls.loop0.remote_hosts[i - 2]._mac = ":".join(mac) cls.loop0.configure_ipv4_neighbors() cls.loop0.configure_ipv6_neighbors() # configure MAC address on pg3 cls.pg3.resolve_arp() cls.pg3.resolve_ndp() # configure MAC address on subifs for i in cls.subifs: i.config_ip4() i.resolve_arp() i.config_ip6() # configure MAC address on pg2 cls.pg2.resolve_arp() cls.pg2.resolve_ndp() # Loopback BVI interface has remote hosts # one half of hosts are behind pg0 second behind pg1,pg2,pg3 subifs cls.pg0.remote_hosts = cls.loop0.remote_hosts[:100] cls.subifs[0].remote_hosts = cls.loop0.remote_hosts[100:125] cls.subifs[1].remote_hosts = cls.loop0.remote_hosts[125:150] cls.subifs[2].remote_hosts = cls.loop0.remote_hosts[150:175] cls.subifs[3].remote_hosts = cls.loop0.remote_hosts[175:] except Exception: super(MethodHolder, cls).tearDownClass() raise @classmethod def tearDownClass(cls): super(MethodHolder, cls).tearDownClass() def setUp(self): super(MethodHolder, self).setUp() self.reset_packet_infos() def show_commands_at_teardown(self): self.logger.info(self.vapi.ppcli("show interface address")) self.logger.info(self.vapi.ppcli("show hardware")) self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl")) self.logger.info(self.vapi.ppcli("sh acl-plugin macip interface")) self.logger.info(self.vapi.ppcli("sh classify tables verbose")) self.logger.info(self.vapi.ppcli("sh acl-plugin acl")) self.logger.info(self.vapi.ppcli("sh acl-plugin interface")) self.logger.info(self.vapi.ppcli("sh acl-plugin tables")) # print(self.vapi.ppcli("show interface address")) # print(self.vapi.ppcli("show hardware")) # print(self.vapi.ppcli("sh acl-plugin macip interface")) # print(self.vapi.ppcli("sh acl-plugin macip acl")) def macip_acl_dump_debug(self): acls = self.vapi.macip_acl_dump() if self.DEBUG: for acl in acls: # print("ACL #"+str(acl.acl_index)) for r in acl.r: rule = "ACTION" if r.is_permit == 1: rule = "PERMIT" elif r.is_permit == 0: rule = "DENY " """ print(" IP6" if r.is_ipv6 else " IP4", rule, binascii.hexlify(r.src_mac), binascii.hexlify(r.src_mac_mask), unpack('<16B', r.src_ip_addr), r.src_ip_prefix_len) """ return acls def create_rules( self, mac_type=EXACT_MAC, ip_type=EXACT_IP, acl_count=1, rules_count=None ): acls = [] if rules_count is None: rules_count = [1] src_mac = int("220000dead00", 16) for acl in range(2, (acl_count + 1) * 2): rules = [] host = random.choice(self.loop0.remote_hosts) is_ip6 = acl % 2 ip4 = host.ip4.split(".") ip6 = list(unpack("<16B", inet_pton(AF_INET6, host.ip6))) if ip_type == self.EXACT_IP: prefix_len4 = 32 prefix_len6 = 128 elif ip_type == self.WILD_IP: ip4 = [0, 0, 0, 0] ip6 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] prefix_len4 = 0 prefix_len6 = 0 rules_count[int((acl / 2) - 1)] = 1 else: prefix_len4 = 24 prefix_len6 = 64 if mac_type == self.EXACT_MAC: mask = "ff:ff:ff:ff:ff:ff" elif mac_type == self.WILD_MAC: mask = "00:00:00:00:00:00" elif mac_type == self.OUI_MAC: mask = "ff:ff:ff:00:00:00" else: mask = "ff:ff:ff:ff:ff:00" ip = ip6 if is_ip6 else ip4 ip_len = prefix_len6 if is_ip6 else prefix_len4 for i in range(0, (rules_count[int((acl / 2) - 1)])): src_mac += 16777217 if mac_type == self.WILD_MAC: mac = "00:00:00:00:00:00" elif mac_type == self.OUI_MAC: mac = ( ":".join(re.findall("..", "{:02x}".format(src_mac))[:3]) + ":00:00:00" ) else: mac = ":".join(re.findall("..", "{:02x}".format(src_mac))) if ip_type == self.EXACT_IP: ip4[3] = random.randint(100, 200) ip6[15] = random.randint(100, 200) elif ip_type == self.SUBNET_IP: ip4[2] = random.randint(100, 200) ip4[3] = 0 ip6[7] = random.randint(100, 200) ip6[15] = 0 ip_pack = b"" for j in range(0, len(ip)): ip_pack += pack(" 0: continue if is_permit: macip_rule = MacipRule( is_permit=is_permit, src_prefix=ip_network((ip_rule, prefix_len)), src_mac=MACAddress(mac_rule).packed, src_mac_mask=MACAddress(mac_mask).packed, ) macip_rules.append(macip_rule) # deny all other packets if not (mac_type == self.WILD_MAC and ip_type == self.WILD_IP): network = IPv6Network((0, 0)) if is_ip6 else IPv4Network((0, 0)) macip_rule = MacipRule( is_permit=0, src_prefix=network, src_mac=MACAddress("00:00:00:00:00:00").packed, src_mac_mask=MACAddress("00:00:00:00:00:00").packed, ) macip_rules.append(macip_rule) network = IPv6Network((0, 0)) if is_ip6 else IPv4Network((0, 0)) acl_rule = AclRule( is_permit=0, src_prefix=network, dst_prefix=network, sport_from=0, sport_to=0, dport_from=0, dport_to=0, ) acl_rules.append(acl_rule) return {"stream": packets, "macip_rules": macip_rules, "acl_rules": acl_rules} def verify_capture(self, stream, capture, is_ip6): """ :param stream: :param capture: :param is_ip6: :return: """ # p_l3 = IPv6 if is_ip6 else IP # if self.DEBUG: # for p in stream: # print(p[Ether].src, p[Ether].dst, p[p_l3].src, p[p_l3].dst) # # acls = self.macip_acl_dump_debug() # TODO : verify # for acl in acls: # for r in acl.r: # print(binascii.hexlify(r.src_mac), \ # binascii.hexlify(r.src_mac_mask),\ # unpack('<16B', r.src_ip_addr), \ # r.src_ip_prefix_len) # # for p in capture: # print(p[Ether].src, p[Ether].dst, p[p_l3].src, p[p_l3].dst # data = p[Raw].load.split(':',1)[1]) # print(p[p_l3].src, data) def run_traffic( self, mac_type, ip_type, traffic, is_ip6, packets, do_not_expected_capture=False, tags=None, apply_rules=True, isMACIP=True, permit_tags=PERMIT_TAGS, try_replace=False, ): self.reset_packet_infos() if tags is None: tx_if = self.pg0 if traffic == self.BRIDGED else self.pg3 rx_if = self.pg3 if traffic == self.BRIDGED else self.pg0 src_if = self.pg3 dst_if = self.loop0 else: if tags == self.DOT1Q: if traffic == self.BRIDGED: tx_if = self.subifs[0] rx_if = self.pg0 src_if = self.subifs[0] dst_if = self.loop0 else: tx_if = self.subifs[2] rx_if = self.pg0 src_if = self.subifs[2] dst_if = self.loop0 elif tags == self.DOT1AD: if traffic == self.BRIDGED: tx_if = self.subifs[1] rx_if = self.pg0 src_if = self.subifs[1] dst_if = self.loop0 else: tx_if = self.subifs[3] rx_if = self.pg0 src_if = self.subifs[3] dst_if = self.loop0 else: return test_dict = self.create_stream( mac_type, ip_type, packets, src_if, dst_if, traffic, is_ip6, tags=permit_tags, ) if apply_rules: if isMACIP: self.acl = VppMacipAcl(self, rules=test_dict["macip_rules"]) else: self.acl = VppAcl(self, rules=test_dict["acl_rules"]) self.acl.add_vpp_config() if isMACIP: self.acl_if = VppMacipAclInterface( self, sw_if_index=tx_if.sw_if_index, acls=[self.acl] ) self.acl_if.add_vpp_config() dump = self.acl_if.dump() self.assertTrue(dump) self.assertEqual(dump[0].acls[0], self.acl.acl_index) else: self.acl_if = VppAclInterface( self, sw_if_index=tx_if.sw_if_index, n_input=1, acls=[self.acl] ) self.acl_if.add_vpp_config() else: if hasattr(self, "acl_if"): self.acl_if.remove_vpp_config() if try_replace and hasattr(self, "acl"): if isMACIP: self.acl.modify_vpp_config(test_dict["macip_rules"]) else: self.acl.modify_vpp_config(test_dict["acl_rules"]) if not isinstance(src_if, VppSubInterface): tx_if.add_stream(test_dict["stream"]) else: tx_if.parent.add_stream(test_dict["stream"]) self.pg_enable_capture(self.pg_interfaces) self.pg_start() if do_not_expected_capture: rx_if.get_capture(0) else: if ( traffic == self.BRIDGED and mac_type == self.WILD_MAC and ip_type == self.WILD_IP ): capture = rx_if.get_capture(packets) else: capture = rx_if.get_capture( self.get_packet_count_for_if_idx(dst_if.sw_if_index) ) self.verify_capture(test_dict["stream"], capture, is_ip6) if not isMACIP: if hasattr(self, "acl_if"): self.acl_if.remove_vpp_config() if hasattr(self, "acl"): self.acl.remove_vpp_config() def run_test_acls( self, mac_type, ip_type, acl_count, rules_count, traffic=None, ip=None ): self.apply_macip_rules( self.create_rules(mac_type, ip_type, acl_count, rules_count) ) self.verify_macip_acls(acl_count, rules_count) if traffic is not None: self.run_traffic(self.EXACT_MAC, self.EXACT_IP, traffic, ip, 9) class TestMACIP_IP4(MethodHolder): """MACIP with IP4 traffic""" @classmethod def setUpClass(cls): super(TestMACIP_IP4, cls).setUpClass() @classmethod def tearDownClass(cls): super(TestMACIP_IP4, cls).tearDownClass() def test_acl_bridged_ip4_exactMAC_exactIP(self): """IP4 MACIP exactMAC|exactIP ACL bridged traffic""" self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP4, 9) def test_acl_bridged_ip4_exactMAC_subnetIP(self): """IP4 MACIP exactMAC|subnetIP ACL bridged traffic""" self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP4, 9) def test_acl_bridged_ip4_exactMAC_wildIP(self): """IP4 MACIP exactMAC|wildIP ACL bridged traffic""" self.run_traffic(self.EXACT_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP4, 9) def test_acl_bridged_ip4_ouiMAC_exactIP(self): """IP4 MACIP ouiMAC|exactIP ACL bridged traffic""" self.run_traffic(self.OUI_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP4, 3) def test_acl_bridged_ip4_ouiMAC_subnetIP(self): """IP4 MACIP ouiMAC|subnetIP ACL bridged traffic""" self.run_traffic(self.OUI_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP4, 9) def test_acl_bridged_ip4_ouiMAC_wildIP(self): """IP4 MACIP ouiMAC|wildIP ACL bridged traffic""" self.run_traffic(self.OUI_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP4, 9) def test_ac_bridgedl_ip4_wildMAC_exactIP(self): """IP4 MACIP wildcardMAC|exactIP ACL bridged traffic""" self.run_traffic(self.WILD_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP4, 9) def test_acl_bridged_ip4_wildMAC_subnetIP(self): """IP4 MACIP wildcardMAC|subnetIP ACL bridged traffic""" self.run_traffic(self.WILD_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP4, 9) def test_acl_bridged_ip4_wildMAC_wildIP(self): """IP4 MACIP wildcardMAC|wildIP ACL bridged traffic""" self.run_traffic(self.WILD_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP4, 9) def test_acl_routed_ip4_exactMAC_exactIP(self): """IP4 MACIP exactMAC|exactIP ACL routed traffic""" self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP4, 9) def test_acl_routed_ip4_exactMAC_subnetIP(self): """IP4 MACIP exactMAC|subnetIP ACL routed traffic""" self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP4, 9) def test_acl_routed_ip4_exactMAC_wildIP(self): """IP4 MACIP exactMAC|wildIP ACL routed traffic""" self.run_traffic(self.EXACT_MAC, self.WILD_IP, self.ROUTED, self.IS_IP4, 9) def test_acl_routed_ip4_ouiMAC_exactIP(self): """IP4 MACIP ouiMAC|exactIP ACL routed traffic""" self.run_traffic(self.OUI_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP4, 9) def test_acl_routed_ip4_ouiMAC_subnetIP(self): """IP4 MACIP ouiMAC|subnetIP ACL routed traffic""" self.run_traffic(self.OUI_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP4, 9) def test_acl_routed_ip4_ouiMAC_wildIP(self): """IP4 MACIP ouiMAC|wildIP ACL routed traffic""" self.run_traffic(self.OUI_MAC, self.WILD_IP, self.ROUTED, self.IS_IP4, 9) def test_acl_routed_ip4_wildMAC_exactIP(self): """IP4 MACIP wildcardMAC|exactIP ACL routed traffic""" self.run_traffic(self.WILD_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP4, 9) def test_acl_routed_ip4_wildMAC_subnetIP(self): """IP4 MACIP wildcardMAC|subnetIP ACL routed traffic""" self.run_traffic(self.WILD_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP4, 9) def test_acl_routed_ip4_wildMAC_wildIP(self): """IP4 MACIP wildcardMAC|wildIP ACL""" self.run_traffic(self.WILD_MAC, self.WILD_IP, self.ROUTED, self.IS_IP4, 9) def test_acl_replace_traffic_ip4(self): """MACIP replace ACL with IP4 traffic""" self.run_traffic( self.OUI_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP4, 9, try_replace=True ) self.run_traffic( self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP4, 9, try_replace=True, ) class TestMACIP_IP6(MethodHolder): """MACIP with IP6 traffic""" @classmethod def setUpClass(cls): super(TestMACIP_IP6, cls).setUpClass() @classmethod def tearDownClass(cls): super(TestMACIP_IP6, cls).tearDownClass() def test_acl_bridged_ip6_exactMAC_exactIP(self): """IP6 MACIP exactMAC|exactIP ACL bridged traffic""" self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP6, 9) def test_acl_bridged_ip6_exactMAC_subnetIP(self): """IP6 MACIP exactMAC|subnetIP ACL bridged traffic""" self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP6, 9) def test_acl_bridged_ip6_exactMAC_wildIP(self): """IP6 MACIP exactMAC|wildIP ACL bridged traffic""" self.run_traffic(self.EXACT_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP6, 9) def test_acl_bridged_ip6_ouiMAC_exactIP(self): """IP6 MACIP oui_MAC|exactIP ACL bridged traffic""" self.run_traffic(self.OUI_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP6, 9) def test_acl_bridged_ip6_ouiMAC_subnetIP(self): """IP6 MACIP ouiMAC|subnetIP ACL bridged traffic""" self.run_traffic(self.OUI_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP6, 9) def test_acl_bridged_ip6_ouiMAC_wildIP(self): """IP6 MACIP ouiMAC|wildIP ACL bridged traffic""" self.run_traffic(self.OUI_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP6, 9) def test_acl_bridged_ip6_wildMAC_exactIP(self): """IP6 MACIP wildcardMAC|exactIP ACL bridged traffic""" self.run_traffic(self.WILD_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP6, 9) def test_acl_bridged_ip6_wildMAC_subnetIP(self): """IP6 MACIP wildcardMAC|subnetIP ACL bridged traffic""" self.run_traffic(self.WILD_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP6, 9) def test_acl_bridged_ip6_wildMAC_wildIP(self): """IP6 MACIP wildcardMAC|wildIP ACL bridged traffic""" self.run_traffic(self.WILD_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP6, 9) def test_acl_routed_ip6_exactMAC_exactIP(self): """IP6 MACIP exactMAC|exactIP ACL routed traffic""" self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP6, 9) def test_acl_routed_ip6_exactMAC_subnetIP(self): """IP6 MACIP exactMAC|subnetIP ACL routed traffic""" self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP6, 9) def test_acl_routed_ip6_exactMAC_wildIP(self): """IP6 MACIP exactMAC|wildIP ACL routed traffic""" self.run_traffic(self.EXACT_MAC, self.WILD_IP, self.ROUTED, self.IS_IP6, 9) def test_acl_routed_ip6_ouiMAC_exactIP(self): """IP6 MACIP ouiMAC|exactIP ACL routed traffic""" self.run_traffic(self.OUI_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP6, 9) def test_acl_routed_ip6_ouiMAC_subnetIP(self): """IP6 MACIP ouiMAC|subnetIP ACL routed traffic""" self.run_traffic(self.OUI_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP6, 9) def test_acl_routed_ip6_ouiMAC_wildIP(self): """IP6 MACIP ouiMAC|wildIP ACL routed traffic""" self.run_traffic(self.OUI_MAC, self.WILD_IP, self.ROUTED, self.IS_IP6, 9) def test_acl_routed_ip6_wildMAC_exactIP(self): """IP6 MACIP wildcardMAC|exactIP ACL routed traffic""" self.run_traffic(self.WILD_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP6, 9) def test_acl_routed_ip6_wildMAC_subnetIP(self): """IP6 MACIP wildcardMAC|subnetIP ACL routed traffic""" self.run_traffic(self.WILD_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP6, 9) def test_acl_routed_ip6_wildMAC_wildIP(self): """IP6 MACIP wildcardMAC|wildIP ACL""" self.run_traffic(self.WILD_MAC, self.WILD_IP, self.ROUTED, self.IS_IP6, 9) def test_acl_replace_traffic_ip6(self): """MACIP replace ACL with IP6 traffic""" self.run_traffic( self.OUI_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP6, 9, try_replace=True ) self.run_traffic( self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP6, 9, try_replace=True, ) class TestMACIP(MethodHolder): """MACIP Tests""" @classmethod def setUpClass(cls): super(TestMACIP, cls).setUpClass() @classmethod def tearDownClass(cls): super(TestMACIP, cls).tearDownClass() def test_acl_1_2(self): """MACIP ACL with 2 entries""" self.run_test_acls(self.EXACT_MAC, self.WILD_IP, 1, [2]) def test_acl_1_5(self): """MACIP ACL with 5 entries""" self.run_test_acls(self.EXACT_MAC, self.SUBNET_IP, 1, [5]) def test_acl_1_10(self): """MACIP ACL with 10 entries""" self.run_test_acls(self.EXACT_MAC, self.EXACT_IP, 1, [10]) def test_acl_1_20(self): """MACIP ACL with 20 entries""" self.run_test_acls(self.OUI_MAC, self.WILD_IP, 1, [20]) def test_acl_1_50(self): """MACIP ACL with 50 entries""" self.run_test_acls(self.OUI_MAC, self.SUBNET_IP, 1, [50]) def test_acl_1_100(self): """MACIP ACL with 100 entries""" self.run_test_acls(self.OUI_MAC, self.EXACT_IP, 1, [100]) def test_acl_2_X(self): """MACIP 2 ACLs each with 100+ entries""" self.run_test_acls(self.OUI_MAC, self.SUBNET_IP, 2, [100, 200]) def test_acl_10_X(self): """MACIP 10 ACLs each with 100+ entries""" self.run_test_acls( self.EXACT_MAC, self.EXACT_IP, 10, [100, 120, 140, 160, 180, 200, 210, 220, 230, 240], ) def test_acl_10_X_traffic_ip4(self): """MACIP 10 ACLs each with 100+ entries with IP4 traffic""" self.run_test_acls( self.EXACT_MAC, self.EXACT_IP, 10, [100, 120, 140, 160, 180, 200, 210, 220, 230, 240], self.BRIDGED, self.IS_IP4, ) def test_acl_10_X_traffic_ip6(self): """MACIP 10 ACLs each with 100+ entries with IP6 traffic""" self.run_test_acls( self.EXACT_MAC, self.EXACT_IP, 10, [100, 120, 140, 160, 180, 200, 210, 220, 230, 240], self.BRIDGED, self.IS_IP6, ) def test_acl_replace(self): """MACIP replace ACL""" r1 = self.create_rules(acl_count=3, rules_count=[2, 2, 2]) r2 = self.create_rules(mac_type=self.OUI_MAC, ip_type=self.SUBNET_IP) macip_acls = self.apply_macip_rules(r1) acls_before = self.macip_acl_dump_debug() # replace acls #2, #3 with new macip_acls[2].modify_vpp_config(r2[0]) macip_acls[3].modify_vpp_config(r2[1]) acls_after = self.macip_acl_dump_debug() # verify changes self.assertEqual(len(acls_before), len(acls_after)) for acl1, acl2 in zip( acls_before[:2] + acls_before[4:], acls_after[:2] + acls_after[4:] ): self.assertEqual(len(acl1), len(acl2)) self.assertEqual(len(acl1.r), len(acl2.r)) for r1, r2 in zip(acl1.r, acl2.r): self.assertEqual(len(acl1.r), len(acl2.r)) self.assertEqual(acl1.r, acl2.r) for acl1, acl2 in zip(acls_before[2:4], acls_after[2:4]): self.assertEqual(len(acl1), len(acl2)) self.assertNotEqual(len(acl1.r), len(acl2.r)) for r1, r2 in zip(acl1.r, acl2.r): self.assertNotEqual(len(acl1.r), len(acl2.r)) self.assertNotEqual(acl1.r, acl2.r) def test_delete_intf(self): """MACIP ACL delete intf with acl""" intf_count = len(self.interfaces) + 1 intf = [] macip_alcs = self.apply_macip_rules( self.create_rules(acl_count=3, rules_count=[3, 5, 4]) ) intf.append(VppLoInterface(self)) intf.append(VppLoInterface(self)) sw_if_index0 = intf[0].sw_if_index macip_acl_if0 = VppMacipAclInterface( self, sw_if_index=sw_if_index0, acls=[macip_alcs[1]] ) macip_acl_if0.add_vpp_config() reply = self.vapi.macip_acl_interface_get() self.assertEqual(reply.count, intf_count + 1) self.assertEqual(reply.acls[sw_if_index0], 1) sw_if_index1 = intf[1].sw_if_index macip_acl_if1 = VppMacipAclInterface( self, sw_if_index=sw_if_index1, acls=[macip_alcs[0]] ) macip_acl_if1.add_vpp_config() reply = self.vapi.macip_acl_interface_get() self.assertEqual(reply.count, intf_count + 2) self.assertEqual(reply.acls[sw_if_index1], 0) intf[0].remove_vpp_config() reply = self.vapi.macip_acl_interface_get() self.assertEqual(reply.count, intf_count + 2) self.assertEqual(reply.acls[sw_if_index0], 4294967295) self.assertEqual(reply.acls[sw_if_index1], 0) intf.append(VppLoInterface(self)) intf.append(VppLoInterface(self)) sw_if_index2 = intf[2].sw_if_index sw_if_index3 = intf[3].sw_if_index macip_acl_if2 = VppMacipAclInterface( self, sw_if_index=sw_if_index2, acls=[macip_alcs[1]] ) macip_acl_if2.add_vpp_config() macip_acl_if3 = VppMacipAclInterface( self, sw_if_index=sw_if_index3, acls=[macip_alcs[1]] ) macip_acl_if3.add_vpp_config() reply = self.vapi.macip_acl_interface_get() self.assertEqual(reply.count, intf_count + 3) self.assertEqual(reply.acls[sw_if_index1], 0) self.assertEqual(reply.acls[sw_if_index2], 1) self.assertEqual(reply.acls[sw_if_index3], 1) self.logger.info("MACIP ACL on multiple interfaces:") self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl")) self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl index 1234")) self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl index 1")) self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl index 0")) self.logger.info(self.vapi.ppcli("sh acl-plugin macip interface")) intf[2].remove_vpp_config() intf[1].remove_vpp_config() reply = self.vapi.macip_acl_interface_get() self.assertEqual(reply.count, intf_count + 3) self.assertEqual(reply.acls[sw_if_index0], 4294967295) self.assertEqual(reply.acls[sw_if_index1], 4294967295) self.assertEqual(reply.acls[sw_if_index2], 4294967295) self.assertEqual(reply.acls[sw_if_index3], 1) intf[3].remove_vpp_config() reply = self.vapi.macip_acl_interface_get() self.assertEqual(len([x for x in reply.acls if x != 4294967295]), 0) class TestACL_dot1q_bridged(MethodHolder): """ACL on dot1q bridged subinterfaces Tests""" @classmethod def setUpClass(cls): super(TestACL_dot1q_bridged, cls).setUpClass() @classmethod def tearDownClass(cls): super(TestACL_dot1q_bridged, cls).tearDownClass() def test_acl_bridged_ip4_subif_dot1q(self): """IP4 ACL SubIf Dot1Q bridged traffic""" self.run_traffic( self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP4, 9, tags=self.DOT1Q, isMACIP=False, ) def test_acl_bridged_ip6_subif_dot1q(self): """IP6 ACL SubIf Dot1Q bridged traffic""" self.run_traffic( self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP6, 9, tags=self.DOT1Q, isMACIP=False, ) class TestACL_dot1ad_bridged(MethodHolder): """ACL on dot1ad bridged subinterfaces Tests""" @classmethod def setUpClass(cls): super(TestACL_dot1ad_bridged, cls).setUpClass() @classmethod def tearDownClass(cls): super(TestACL_dot1ad_bridged, cls).tearDownClass() def test_acl_bridged_ip4_subif_dot1ad(self): """IP4 ACL SubIf Dot1AD bridged traffic""" self.run_traffic( self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP4, 9, tags=self.DOT1AD, isMACIP=False, ) def test_acl_bridged_ip6_subif_dot1ad(self): """IP6 ACL SubIf Dot1AD bridged traffic""" self.run_traffic( self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP6, 9, tags=self.DOT1AD, isMACIP=False, ) class TestACL_dot1q_routed(MethodHolder): """ACL on dot1q routed subinterfaces Tests""" @classmethod def setUpClass(cls): super(TestACL_dot1q_routed, cls).setUpClass() @classmethod def tearDownClass(cls): super(TestACL_dot1q_routed, cls).tearDownClass() def test_acl_routed_ip4_subif_dot1q(self): """IP4 ACL SubIf Dot1Q routed traffic""" self.run_traffic( self.EXACT_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP4, 9, tags=self.DOT1Q, isMACIP=False, ) def test_acl_routed_ip6_subif_dot1q(self): """IP6 ACL SubIf Dot1Q routed traffic""" self.run_traffic( self.EXACT_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP6, 9, tags=self.DOT1Q, isMACIP=False, ) def test_acl_routed_ip4_subif_dot1q_deny_by_tags(self): """IP4 ACL SubIf wrong tags Dot1Q routed traffic""" self.run_traffic( self.EXACT_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP4, 9, True, tags=self.DOT1Q, isMACIP=False, permit_tags=self.DENY_TAGS, ) def test_acl_routed_ip6_subif_dot1q_deny_by_tags(self): """IP6 ACL SubIf wrong tags Dot1Q routed traffic""" self.run_traffic( self.EXACT_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP6, 9, True, tags=self.DOT1Q, isMACIP=False, permit_tags=self.DENY_TAGS, ) class TestACL_dot1ad_routed(MethodHolder): """ACL on dot1ad routed subinterfaces Tests""" @classmethod def setUpClass(cls): super(TestACL_dot1ad_routed, cls).setUpClass() @classmethod def tearDownClass(cls): super(TestACL_dot1ad_routed, cls).tearDownClass() def test_acl_routed_ip6_subif_dot1ad(self): """IP6 ACL SubIf Dot1AD routed traffic""" self.run_traffic( self.EXACT_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP6, 9, tags=self.DOT1AD, isMACIP=False, ) def test_acl_routed_ip4_subif_dot1ad(self): """IP4 ACL SubIf Dot1AD routed traffic""" self.run_traffic( self.EXACT_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP4, 9, tags=self.DOT1AD, isMACIP=False, ) def test_acl_routed_ip6_subif_dot1ad_deny_by_tags(self): """IP6 ACL SubIf wrong tags Dot1AD routed traffic""" self.run_traffic( self.EXACT_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP6, 9, True, tags=self.DOT1AD, isMACIP=False, permit_tags=self.DENY_TAGS, ) def test_acl_routed_ip4_subif_dot1ad_deny_by_tags(self): """IP4 ACL SubIf wrong tags Dot1AD routed traffic""" self.run_traffic( self.EXACT_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP4, 9, True, tags=self.DOT1AD, isMACIP=False, permit_tags=self.DENY_TAGS, ) if __name__ == "__main__": unittest.main(testRunner=VppTestRunner)