X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=test%2Ftest_gbp.py;h=c30a729519dd72c72fcada09f2f90168f23d2544;hb=4d769c71a10bb99a1afc369e85d7d444e7b439f3;hp=9cf1817b29600bf35daed26481cfe9c3f2ab11dd;hpb=e28c87cd00644205e9bebca054029a8e655ed015;p=vpp.git diff --git a/test/test_gbp.py b/test/test_gbp.py index 9cf1817b296..c30a729519d 100644 --- a/test/test_gbp.py +++ b/test/test_gbp.py @@ -1,43 +1,60 @@ -#!/usr/bin/env python - -from socket import AF_INET, AF_INET6 +#!/usr/bin/env python3 +import typing +from socket import AF_INET6, inet_pton, inet_ntop import unittest +from ipaddress import ip_address, IPv4Network, IPv6Network from scapy.packet import Raw from scapy.layers.l2 import Ether, ARP, Dot1Q from scapy.layers.inet import IP, UDP, ICMP -from scapy.layers.inet6 import IPv6, ICMPv6ND_NS, ICMPv6NDOptSrcLLAddr, \ - ICMPv6ND_NA, ICMPv6EchoRequest +from scapy.layers.inet6 import ( + IPv6, + ICMPv6ND_NS, + ICMPv6NDOptSrcLLAddr, + ICMPv6ND_NA, + ICMPv6EchoRequest, +) from scapy.utils6 import in6_getnsma, in6_getnsmac from scapy.layers.vxlan import VXLAN -from scapy.data import ETH_P_IP, ETH_P_IPV6, ETH_P_ARP -from scapy.utils import inet_pton, inet_ntop +from scapy.data import ETH_P_IP, ETH_P_IPV6 +from framework import tag_fixme_vpp_workers from framework import VppTestCase, VppTestRunner from vpp_object import VppObject from vpp_interface import VppInterface -from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, \ - VppIpInterfaceAddress, VppIpInterfaceBind, find_route, FibPathProto, \ - FibPathType -from vpp_l2 import VppBridgeDomain, VppBridgeDomainPort, \ - VppBridgeDomainArpEntry, VppL2FibEntry, find_bridge_domain_port, VppL2Vtr +from vpp_ip_route import ( + VppIpRoute, + VppRoutePath, + VppIpTable, + VppIpInterfaceAddress, + VppIpInterfaceBind, + find_route, + FibPathProto, + FibPathType, +) +from vpp_l2 import ( + VppBridgeDomain, + VppBridgeDomainPort, + VppBridgeDomainArpEntry, + VppL2FibEntry, + find_bridge_domain_port, + VppL2Vtr, +) from vpp_sub_interface import L2_VTR_OP, VppDot1QSubint -from vpp_ip import VppIpAddress, VppIpPrefix, DpoProto +from vpp_ip import DpoProto, get_dpo_proto from vpp_papi import VppEnum, MACAddress from vpp_vxlan_gbp_tunnel import find_vxlan_gbp_tunnel, INDEX_INVALID, \ VppVxlanGbpTunnel from vpp_neighbor import VppNeighbor -try: - text_type = unicode -except NameError: - text_type = str +from vpp_acl import AclRule, VppAcl NUM_PKTS = 67 -def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None, tep=None): +def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None, + tep=None, sclass=None, flags=None): if ip: - vip = VppIpAddress(ip) + vip = ip if mac: vmac = MACAddress(mac) @@ -45,25 +62,32 @@ def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None, tep=None): for ep in eps: if tep: - src = VppIpAddress(tep[0]) - dst = VppIpAddress(tep[1]) - if src != ep.endpoint.tun.src or dst != ep.endpoint.tun.dst: + src = tep[0] + dst = tep[1] + if src != str(ep.endpoint.tun.src) or \ + dst != str(ep.endpoint.tun.dst): continue if sw_if_index: if ep.endpoint.sw_if_index != sw_if_index: continue + if sclass: + if ep.endpoint.sclass != sclass: + continue + if flags: + if flags != (flags & ep.endpoint.flags): + continue if ip: for eip in ep.endpoint.ips: - if vip == eip: + if vip == str(eip): return True if mac: - if vmac.packed == ep.endpoint.mac: + if vmac == ep.endpoint.mac: return True return False -def find_gbp_vxlan(test, vni): +def find_gbp_vxlan(test: VppTestCase, vni): ts = test.vapi.gbp_vxlan_tunnel_dump() for t in ts: if t.tunnel.vni == vni: @@ -111,13 +135,14 @@ class VppGbpEndpoint(VppObject): mac=True): self._test = test self.itf = itf + self.handle = None self.epg = epg self.recirc = recirc - self._ip4 = VppIpAddress(ip4) - self._fip4 = VppIpAddress(fip4) - self._ip6 = VppIpAddress(ip6) - self._fip6 = VppIpAddress(fip6) + self._ip4 = ip4 + self._fip4 = fip4 + self._ip6 = ip6 + self._fip6 = fip6 if mac: self.vmac = MACAddress(self.itf.remote_mac) @@ -125,34 +150,44 @@ class VppGbpEndpoint(VppObject): self.vmac = MACAddress("00:00:00:00:00:00") self.flags = flags - self.tun_src = VppIpAddress(tun_src) - self.tun_dst = VppIpAddress(tun_dst) + self.tun_src = tun_src + self.tun_dst = tun_dst + + def encode(self): + ips = [self.ip4, self.ip6] + return { + "sw_if_index": self.itf.sw_if_index, + "ips": ips, + "n_ips": len(ips), + "mac": self.vmac.packed, + "sclass": self.epg.sclass, + "flags": self.flags, + "tun": { + "src": self.tun_src, + "dst": self.tun_dst, + }, + } def add_vpp_config(self): res = self._test.vapi.gbp_endpoint_add( - self.itf.sw_if_index, - [self.ip4.encode(), self.ip6.encode()], - self.vmac.packed, - self.epg.sclass, - self.flags, - self.tun_src.encode(), - self.tun_dst.encode()) + endpoint=self.encode(), + ) self.handle = res.handle self._test.registry.register(self, self._test.logger) def remove_vpp_config(self): - self._test.vapi.gbp_endpoint_del(self.handle) + self._test.vapi.gbp_endpoint_del(handle=self.handle) def object_id(self): return "gbp-endpoint:[%d==%d:%s:%d]" % (self.handle, self.itf.sw_if_index, - self.ip4.address, + self.ip4, self.epg.sclass) def query_vpp_config(self): return find_gbp_endpoint(self._test, self.itf.sw_if_index, - self.ip4.address) + self.ip4) class VppGbpRecirc(VppObject): @@ -166,20 +201,25 @@ class VppGbpRecirc(VppObject): self.epg = epg self.is_ext = is_ext + def encode(self): + return { + "is_ext": self.is_ext, + "sw_if_index": self.recirc.sw_if_index, + "sclass": self.epg.sclass, + } + def add_vpp_config(self): self._test.vapi.gbp_recirc_add_del( 1, - self.recirc.sw_if_index, - self.epg.sclass, - self.is_ext) + recirc=self.encode(), + ) self._test.registry.register(self, self._test.logger) def remove_vpp_config(self): self._test.vapi.gbp_recirc_add_del( 0, - self.recirc.sw_if_index, - self.epg.sclass, - self.is_ext) + recirc=self.encode(), + ) def object_id(self): return "gbp-recirc:[%d]" % (self.recirc.sw_if_index) @@ -204,14 +244,26 @@ class VppGbpExtItf(VppObject): self.rd = rd self.flags = 1 if anon else 0 + def encode(self): + return { + "sw_if_index": self.itf.sw_if_index, + "bd_id": self.bd.bd_id, + "rd_id": self.rd.rd_id, + "flags": self.flags, + } + def add_vpp_config(self): self._test.vapi.gbp_ext_itf_add_del( - 1, self.itf.sw_if_index, self.bd.bd_id, self.rd.rd_id, self.flags) + 1, + ext_itf=self.encode(), + ) self._test.registry.register(self, self._test.logger) def remove_vpp_config(self): self._test.vapi.gbp_ext_itf_add_del( - 0, self.itf.sw_if_index, self.bd.bd_id, self.rd.rd_id, self.flags) + 0, + ext_itf=self.encode(), + ) def object_id(self): return "gbp-ext-itf:[%d]%s" % (self.itf.sw_if_index, @@ -231,30 +283,43 @@ class VppGbpSubnet(VppObject): """ def __init__(self, test, rd, address, address_len, - type, sw_if_index=None, sclass=None): + type, sw_if_index=0xffffffff, sclass=0xffff): + # TODO: replace hardcoded defaults when vpp_papi supports + # defaults in typedefs self._test = test self.rd_id = rd.rd_id - self.prefix = VppIpPrefix(address, address_len) + a = ip_address(address) + if 4 == a.version: + self.prefix = IPv4Network("%s/%d" % (address, address_len), + strict=False) + else: + self.prefix = IPv6Network("%s/%d" % (address, address_len), + strict=False) self.type = type self.sw_if_index = sw_if_index self.sclass = sclass + def encode(self): + return { + "type": self.type, + "sw_if_index": self.sw_if_index, + "sclass": self.sclass, + "prefix": self.prefix, + "rd_id": self.rd_id, + } + def add_vpp_config(self): self._test.vapi.gbp_subnet_add_del( - 1, - self.rd_id, - self.prefix.encode(), - self.type, - sw_if_index=self.sw_if_index if self.sw_if_index else 0xffffffff, - sclass=self.sclass if self.sclass else 0xffff) + is_add=1, + subnet=self.encode(), + ) self._test.registry.register(self, self._test.logger) def remove_vpp_config(self): self._test.vapi.gbp_subnet_add_del( - 0, - self.rd_id, - self.prefix.encode(), - self.type) + is_add=0, + subnet=self.encode() + ) def object_id(self): return "gbp-subnet:[%d-%s]" % (self.rd_id, self.prefix) @@ -288,33 +353,38 @@ class VppGbpEndpointGroup(VppObject): self._test = test self.uplink = uplink self.bvi = bvi - self.bvi_ip4 = VppIpAddress(bvi_ip4) - self.bvi_ip6 = VppIpAddress(bvi_ip6) + self.bvi_ip4 = bvi_ip4 + self.bvi_ip6 = bvi_ip6 self.vnid = vnid - self.bd = bd + self.bd = bd # VppGbpBridgeDomain self.rd = rd self.sclass = sclass if 0 == self.sclass: self.sclass = 0xffff self.retention = retention + def encode(self) -> dict: + return { + "uplink_sw_if_index": self.uplink.sw_if_index + if self.uplink else INDEX_INVALID, + "bd_id": self.bd.bd.bd_id, + "rd_id": self.rd.rd_id, + "vnid": self.vnid, + "sclass": self.sclass, + "retention": self.retention.encode(), + } + def add_vpp_config(self): - self._test.vapi.gbp_endpoint_group_add( - self.vnid, - self.sclass, - self.bd.bd.bd_id, - self.rd.rd_id, - self.uplink.sw_if_index if self.uplink else INDEX_INVALID, - self.retention.encode()) + self._test.vapi.gbp_endpoint_group_add(epg=self.encode()) self._test.registry.register(self, self._test.logger) def remove_vpp_config(self): - self._test.vapi.gbp_endpoint_group_del(self.sclass) + self._test.vapi.gbp_endpoint_group_del(sclass=self.sclass) - def object_id(self): + def object_id(self) -> str: return "gbp-endpoint-group:[%d]" % (self.vnid) - def query_vpp_config(self): + def query_vpp_config(self) -> bool: epgs = self._test.vapi.gbp_endpoint_group_dump() for epg in epgs: if epg.epg.vnid == self.vnid: @@ -327,7 +397,8 @@ class VppGbpBridgeDomain(VppObject): GBP Bridge Domain """ - def __init__(self, test, bd, rd, bvi, uu_fwd=None, + def __init__(self, test, bd, rd, bvi, + uu_fwd: typing.Optional[VppVxlanGbpTunnel] = None, bm_flood=None, learn=True, uu_drop=False, bm_drop=False, ucast_arp=False): @@ -350,23 +421,31 @@ class VppGbpBridgeDomain(VppObject): if ucast_arp: self.flags |= e.GBP_BD_API_FLAG_UCAST_ARP + def encode(self) -> dict: + return { + "flags": self.flags, + "bvi_sw_if_index": self.bvi.sw_if_index, + "uu_fwd_sw_if_index": self.uu_fwd.sw_if_index + if self.uu_fwd else INDEX_INVALID, + "bm_flood_sw_if_index": self.bm_flood.sw_if_index + if self.bm_flood else INDEX_INVALID, + "bd_id": self.bd.bd_id, + "rd_id": self.rd.rd_id, + } + def add_vpp_config(self): self._test.vapi.gbp_bridge_domain_add( - self.bd.bd_id, - self.rd.rd_id, - self.flags, - self.bvi.sw_if_index, - self.uu_fwd.sw_if_index if self.uu_fwd else INDEX_INVALID, - self.bm_flood.sw_if_index if self.bm_flood else INDEX_INVALID) + bd=self.encode(), + ) self._test.registry.register(self, self._test.logger) def remove_vpp_config(self): - self._test.vapi.gbp_bridge_domain_del(self.bd.bd_id) + self._test.vapi.gbp_bridge_domain_del(bd_id=self.bd.bd_id) - def object_id(self): + def object_id(self) -> str: return "gbp-bridge-domain:[%d]" % (self.bd.bd_id) - def query_vpp_config(self): + def query_vpp_config(self) -> bool: bds = self._test.vapi.gbp_bridge_domain_dump() for bd in bds: if bd.bd.bd_id == self.bd.bd_id: @@ -388,18 +467,27 @@ class VppGbpRouteDomain(VppObject): self.ip4_uu = ip4_uu self.ip6_uu = ip6_uu + def encode(self) -> dict: + return { + "rd_id": self.rd_id, + "scope": self.scope, + "ip4_table_id": self.t4.table_id, + "ip6_table_id": self.t6.table_id, + "ip4_uu_sw_if_index": self.ip4_uu.sw_if_index + if self.ip4_uu else INDEX_INVALID, + "ip6_uu_sw_if_index": self.ip6_uu.sw_if_index + if self.ip6_uu else INDEX_INVALID, + + } + def add_vpp_config(self): self._test.vapi.gbp_route_domain_add( - self.rd_id, - self.scope, - self.t4.table_id, - self.t6.table_id, - self.ip4_uu.sw_if_index if self.ip4_uu else INDEX_INVALID, - self.ip6_uu.sw_if_index if self.ip6_uu else INDEX_INVALID) + rd=self.encode(), + ) self._test.registry.register(self, self._test.logger) def remove_vpp_config(self): - self._test.vapi.gbp_route_domain_del(self.rd_id) + self._test.vapi.gbp_route_domain_del(rd_id=self.rd_id) def object_id(self): return "gbp-route-domain:[%d]" % (self.rd_id) @@ -412,27 +500,29 @@ class VppGbpRouteDomain(VppObject): return False -class VppGbpContractNextHop(): +class VppGbpContractNextHop: def __init__(self, mac, bd, ip, rd): self.mac = mac self.ip = ip self.bd = bd self.rd = rd - def encode(self): - return {'ip': self.ip.encode(), - 'mac': self.mac.packed, - 'bd_id': self.bd.bd.bd_id, - 'rd_id': self.rd.rd_id} + def encode(self) -> dict: + return { + "ip": self.ip, + "mac": self.mac.packed, + "bd_id": self.bd.bd.bd_id, + "rd_id": self.rd.rd_id, + } -class VppGbpContractRule(): +class VppGbpContractRule: def __init__(self, action, hash_mode, nhs=None): self.action = action self.hash_mode = hash_mode self.nhs = [] if nhs is None else nhs - def encode(self): + def encode(self) -> dict: nhs = [] for nh in self.nhs: nhs.append(nh.encode()) @@ -455,12 +545,8 @@ class VppGbpContract(VppObject): """ def __init__(self, test, scope, sclass, dclass, acl_index, - rules, allowed_ethertypes): + rules: list, allowed_ethertypes: list): self._test = test - if not isinstance(rules, list): - raise ValueError("'rules' must be a list.") - if not isinstance(allowed_ethertypes, list): - raise ValueError("'allowed_ethertypes' must be a list.") self.scope = scope self.acl_index = acl_index self.sclass = sclass @@ -470,36 +556,35 @@ class VppGbpContract(VppObject): while (len(self.allowed_ethertypes) < 16): self.allowed_ethertypes.append(0) - def add_vpp_config(self): + def encode(self) -> dict: rules = [] for r in self.rules: rules.append(r.encode()) + return { + 'acl_index': self.acl_index, + 'scope': self.scope, + 'sclass': self.sclass, + 'dclass': self.dclass, + 'n_rules': len(rules), + 'rules': rules, + 'n_ether_types': len(self.allowed_ethertypes), + 'allowed_ethertypes': self.allowed_ethertypes, + } + + def add_vpp_config(self): r = self._test.vapi.gbp_contract_add_del( is_add=1, - contract={ - 'acl_index': self.acl_index, - 'scope': self.scope, - 'sclass': self.sclass, - 'dclass': self.dclass, - 'n_rules': len(rules), - 'rules': rules, - 'n_ether_types': len(self.allowed_ethertypes), - 'allowed_ethertypes': self.allowed_ethertypes}) + contract=self.encode() + ) + self.stats_index = r.stats_index self._test.registry.register(self, self._test.logger) def remove_vpp_config(self): self._test.vapi.gbp_contract_add_del( is_add=0, - contract={ - 'acl_index': self.acl_index, - 'scope': self.scope, - 'sclass': self.sclass, - 'dclass': self.dclass, - 'n_rules': 0, - 'rules': [], - 'n_ether_types': len(self.allowed_ethertypes), - 'allowed_ethertypes': self.allowed_ethertypes}) + contract=self.encode(), + ) def object_id(self): return "gbp-contract:[%d:%d:%d:%d]" % (self.scope, @@ -538,17 +623,23 @@ class VppGbpVxlanTunnel(VppInterface): self.mode = mode self.src = src + def encode(self) -> dict: + return { + "vni": self.vni, + "mode": self.mode, + "bd_rd_id": self.bd_rd_id, + "src": self.src, + } + def add_vpp_config(self): r = self._test.vapi.gbp_vxlan_tunnel_add( - self.vni, - self.bd_rd_id, - self.mode, - self.src) + tunnel=self.encode(), + ) self.set_sw_if_index(r.sw_if_index) self._test.registry.register(self, self._test.logger) def remove_vpp_config(self): - self._test.vapi.gbp_vxlan_tunnel_del(self.vni) + self._test.vapi.gbp_vxlan_tunnel_del(vni=self.vni) def object_id(self): return "gbp-vxlan:%d" % (self.sw_if_index) @@ -557,65 +648,18 @@ class VppGbpVxlanTunnel(VppInterface): return find_gbp_vxlan(self._test, self.vni) -class VppGbpAcl(VppObject): - """ - GBP Acl - """ - - def __init__(self, test): - self._test = test - self.acl_index = 4294967295 - - def create_rule(self, is_ipv6=0, permit_deny=0, proto=-1, - s_prefix=0, s_ip=b'\x00\x00\x00\x00', sport_from=0, - sport_to=65535, d_prefix=0, d_ip=b'\x00\x00\x00\x00', - dport_from=0, dport_to=65535): - if proto == -1 or proto == 0: - sport_to = 0 - dport_to = sport_to - elif proto == 1 or proto == 58: - sport_to = 255 - dport_to = sport_to - rule = ({'is_permit': permit_deny, 'is_ipv6': is_ipv6, 'proto': proto, - 'srcport_or_icmptype_first': sport_from, - 'srcport_or_icmptype_last': sport_to, - 'src_ip_prefix_len': s_prefix, - 'src_ip_addr': s_ip, - 'dstport_or_icmpcode_first': dport_from, - 'dstport_or_icmpcode_last': dport_to, - 'dst_ip_prefix_len': d_prefix, - 'dst_ip_addr': d_ip}) - return rule - - def add_vpp_config(self, rules): - - reply = self._test.vapi.acl_add_replace(acl_index=self.acl_index, - r=rules, - tag=b'GBPTest') - self.acl_index = reply.acl_index - return self.acl_index - - def remove_vpp_config(self): - self._test.vapi.acl_del(self.acl_index) - - def object_id(self): - return "gbp-acl:[%d]" % (self.acl_index) - - def query_vpp_config(self): - cs = self._test.vapi.acl_dump() - for c in cs: - if c.acl_index == self.acl_index: - return True - return False - - +@tag_fixme_vpp_workers class TestGBP(VppTestCase): """ GBP Test Case """ @property - def config_flags(self): + def nat_config_flags(self): return VppEnum.vl_api_nat_config_flags_t + @property + def nat44_config_flags(self): + return VppEnum.vl_api_nat44_config_flags_t + @classmethod def setUpClass(cls): super(TestGBP, cls).setUpClass() @@ -648,6 +692,9 @@ class TestGBP(VppTestCase): for i in self.pg_interfaces: i.admin_down() super(TestGBP, self).tearDown() + for i in self.lo_interfaces: + i.remove_vpp_config() + self.lo_interfaces = [] self.vlan_102.remove_vpp_config() self.vlan_101.remove_vpp_config() self.vlan_100.remove_vpp_config() @@ -756,7 +803,6 @@ class TestGBP(VppTestCase): self.pg_send(src, tx) dst.get_capture(0, timeout=1) dst.assert_nothing_captured(remark="") - timeout = 0.1 def send_and_expect_arp(self, src, tx, dst): rx = self.send_and_expect(src, tx, dst) @@ -860,31 +906,36 @@ class TestGBP(VppTestCase): "10.0.2.1", "11.0.0.4", "2001:10:2::1", "3001::4")] + self.vapi.nat44_ed_plugin_enable_disable(enable=1) + self.vapi.nat66_plugin_enable_disable(enable=1) + # # Config related to each of the EPGs # for epg in epgs: # IP config on the BVI interfaces if epg != epgs[1] and epg != epgs[4]: - VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config() - VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config() - self.vapi.sw_interface_set_mac_address( - epg.bvi.sw_if_index, - self.router_mac.packed) + b4 = VppIpInterfaceBind(self, epg.bvi, + epg.rd.t4).add_vpp_config() + b6 = VppIpInterfaceBind(self, epg.bvi, + epg.rd.t6).add_vpp_config() + epg.bvi.set_mac(self.router_mac) # The BVIs are NAT inside interfaces - flags = self.config_flags.NAT_IS_INSIDE + flags = self.nat_config_flags.NAT_IS_INSIDE self.vapi.nat44_interface_add_del_feature( sw_if_index=epg.bvi.sw_if_index, flags=flags, is_add=1) self.vapi.nat66_add_del_interface( - is_add=1, flags=flags, - sw_if_index=epg.bvi.sw_if_index) + sw_if_index=epg.bvi.sw_if_index, + flags=flags, is_add=1) - if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32) - if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128) - if_ip4.add_vpp_config() - if_ip6.add_vpp_config() + if_ip4 = VppIpInterfaceAddress(self, epg.bvi, + epg.bvi_ip4, 32, + bind=b4).add_vpp_config() + if_ip6 = VppIpInterfaceAddress(self, epg.bvi, + epg.bvi_ip6, 128, + bind=b6).add_vpp_config() # EPG uplink interfaces in the RD VppIpInterfaceBind(self, epg.uplink, epg.rd.t4).add_vpp_config() @@ -893,10 +944,10 @@ class TestGBP(VppTestCase): # add the BD ARP termination entry for BVI IP epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd, str(self.router_mac), - epg.bvi_ip4.address) + epg.bvi_ip4) epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd, str(self.router_mac), - epg.bvi_ip6.address) + epg.bvi_ip6) epg.bd_arp_ip4.add_vpp_config() epg.bd_arp_ip6.add_vpp_config() @@ -913,8 +964,7 @@ class TestGBP(VppTestCase): self.vapi.nat44_interface_add_del_feature( sw_if_index=recirc.recirc.sw_if_index, is_add=1) self.vapi.nat66_add_del_interface( - is_add=1, - sw_if_index=recirc.recirc.sw_if_index) + sw_if_index=recirc.recirc.sw_if_index, is_add=1) recirc.add_vpp_config() @@ -933,19 +983,19 @@ class TestGBP(VppTestCase): # for (ip, fip) in zip(ep.ips, ep.fips): # Add static mappings for each EP from the 10/8 to 11/8 network - if ip.af == AF_INET: - flags = self.config_flags.NAT_IS_ADDR_ONLY + if ip_address(ip).version == 4: + flags = self.nat_config_flags.NAT_IS_ADDR_ONLY self.vapi.nat44_add_del_static_mapping( is_add=1, - local_ip_address=ip.bytes, - external_ip_address=fip.bytes, + local_ip_address=ip, + external_ip_address=fip, external_sw_if_index=0xFFFFFFFF, vrf_id=0, flags=flags) else: self.vapi.nat66_add_del_static_mapping( - local_ip_address=ip.bytes, - external_ip_address=fip.bytes, + local_ip_address=ip, + external_ip_address=fip, vrf_id=0, is_add=1) # VPP EP create ... @@ -954,32 +1004,32 @@ class TestGBP(VppTestCase): self.logger.info(self.vapi.cli("sh gbp endpoint")) # ... results in a Gratuitous ARP/ND on the EPG's uplink - rx = ep.epg.uplink.get_capture(len(ep.ips), timeout=0.2) + rx = ep.epg.uplink.get_capture(len(ep.ips) + 1, timeout=0.2) for ii, ip in enumerate(ep.ips): p = rx[ii] - if ip.is_ip6: + if ip_address(ip).version == 6: self.assertTrue(p.haslayer(ICMPv6ND_NA)) - self.assertEqual(p[ICMPv6ND_NA].tgt, ip.address) + self.assertEqual(p[ICMPv6ND_NA].tgt, ip) else: self.assertTrue(p.haslayer(ARP)) - self.assertEqual(p[ARP].psrc, ip.address) - self.assertEqual(p[ARP].pdst, ip.address) + self.assertEqual(p[ARP].psrc, ip) + self.assertEqual(p[ARP].pdst, ip) # add the BD ARP termination entry for floating IP for fip in ep.fips: ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac, - fip.address) + fip) ba.add_vpp_config() # floating IPs route via EPG recirc r = VppIpRoute( - self, fip.address, fip.length, - [VppRoutePath(fip.address, + self, fip, ip_address(fip).max_prefixlen, + [VppRoutePath(fip, ep.recirc.recirc.sw_if_index, type=FibPathType.FIB_PATH_TYPE_DVR, - proto=fip.dpo_proto)], + proto=get_dpo_proto(fip))], table_id=20) r.add_vpp_config() @@ -1016,17 +1066,17 @@ class TestGBP(VppTestCase): ARP(op="who-has", hwdst="ff:ff:ff:ff:ff:ff", hwsrc=self.pg0.remote_mac, - pdst=epgs[0].bvi_ip4.address, - psrc=eps[0].ip4.address)) + pdst=epgs[0].bvi_ip4, + psrc=eps[0].ip4)) self.send_and_expect(self.pg0, [pkt_arp], self.pg0) - nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6.address)) + nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6)) d = inet_ntop(AF_INET6, nsma) pkt_nd = (Ether(dst=in6_getnsmac(nsma), src=self.pg0.remote_mac) / - IPv6(dst=d, src=eps[0].ip6.address) / - ICMPv6ND_NS(tgt=epgs[0].bvi_ip6.address) / + IPv6(dst=d, src=eps[0].ip6) / + ICMPv6ND_NS(tgt=epgs[0].bvi_ip6) / ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac)) self.send_and_expect(self.pg0, [pkt_nd], self.pg0) @@ -1035,9 +1085,9 @@ class TestGBP(VppTestCase): # pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) / - IP(src=eps[0].ip4.address, dst="232.1.1.1") / + IP(src=eps[0].ip4, dst="232.1.1.1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.vapi.cli("clear trace") self.pg0.add_stream(pkt_bcast) @@ -1055,26 +1105,26 @@ class TestGBP(VppTestCase): # pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IP(src=eps[0].ip4.address, + IP(src=eps[0].ip4, dst="10.0.0.99") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IP(src=eps[0].ip4.address, + IP(src=eps[0].ip4, dst="10.0.1.99") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * NUM_PKTS) pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IPv6(src=eps[0].ip6.address, + IPv6(src=eps[0].ip6, dst="2001:10::99") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * NUM_PKTS) @@ -1132,10 +1182,10 @@ class TestGBP(VppTestCase): # pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac, dst="00:00:00:33:44:55") / - IP(src=eps[0].ip4.address, + IP(src=eps[0].ip4, dst="10.0.0.99") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect_bridged(eps[0].itf, pkt_intra_epg_220_to_uplink * NUM_PKTS, @@ -1146,10 +1196,10 @@ class TestGBP(VppTestCase): pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac, dst="00:00:00:33:44:66") / - IP(src=eps[0].ip4.address, + IP(src=eps[0].ip4, dst="10.0.0.99") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect_bridged(eps[2].itf, pkt_intra_epg_221_to_uplink * NUM_PKTS, @@ -1160,10 +1210,10 @@ class TestGBP(VppTestCase): # pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55", dst=self.pg0.remote_mac) / - IP(src=eps[0].ip4.address, + IP(src=eps[0].ip4, dst="10.0.0.99") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect_bridged(self.pg4, pkt_intra_epg_220_from_uplink * NUM_PKTS, @@ -1175,10 +1225,10 @@ class TestGBP(VppTestCase): # pkt_intra_epg = (Ether(src=self.pg0.remote_mac, dst=self.pg1.remote_mac) / - IP(src=eps[0].ip4.address, - dst=eps[1].ip4.address) / + IP(src=eps[0].ip4, + dst=eps[1].ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect_bridged(self.pg0, pkt_intra_epg * NUM_PKTS, @@ -1190,22 +1240,22 @@ class TestGBP(VppTestCase): # pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac, dst=self.pg2.remote_mac) / - IP(src=eps[0].ip4.address, - dst=eps[2].ip4.address) / + IP(src=eps[0].ip4, + dst=eps[2].ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac, dst=self.pg0.remote_mac) / - IP(src=eps[2].ip4.address, - dst=eps[0].ip4.address) / + IP(src=eps[2].ip4, + dst=eps[0].ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IP(src=eps[0].ip4.address, - dst=eps[3].ip4.address) / + IP(src=eps[0].ip4, + dst=eps[3].ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_assert_no_replies(eps[0].itf, pkt_inter_epg_220_to_221 * NUM_PKTS) @@ -1215,12 +1265,14 @@ class TestGBP(VppTestCase): # # A uni-directional contract from EPG 220 -> 221 # - acl = VppGbpAcl(self) - rule = acl.create_rule(permit_deny=1, proto=17) - rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17) - acl_index = acl.add_vpp_config([rule, rule2]) + rule = AclRule(is_permit=1, proto=17) + rule2 = AclRule(src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17) + acl = VppAcl(self, rules=[rule, rule2]) + acl.add_vpp_config() + c1 = VppGbpContract( - self, 400, epgs[0].sclass, epgs[1].sclass, acl_index, + self, 400, epgs[0].sclass, epgs[1].sclass, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -1242,7 +1294,7 @@ class TestGBP(VppTestCase): # contract for the return direction # c2 = VppGbpContract( - self, 400, epgs[1].sclass, epgs[0].sclass, acl_index, + self, 400, epgs[1].sclass, epgs[0].sclass, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -1286,7 +1338,7 @@ class TestGBP(VppTestCase): # A uni-directional contract from EPG 220 -> 222 'L3 routed' # c3 = VppGbpContract( - self, 400, epgs[0].sclass, epgs[2].sclass, acl_index, + self, 400, epgs[0].sclass, epgs[2].sclass, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -1304,7 +1356,6 @@ class TestGBP(VppTestCase): pkt_inter_epg_220_to_222 * NUM_PKTS, eps[3].itf, str(self.router_mac)) - # # remove both contracts, traffic stops in both directions # @@ -1375,25 +1426,23 @@ class TestGBP(VppTestCase): # pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IP(src=eps[0].ip4.address, + IP(src=eps[0].ip4, dst="1.1.1.1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) # no policy yet self.send_and_assert_no_replies(eps[0].itf, pkt_inter_epg_220_to_global * NUM_PKTS) + rule = AclRule(is_permit=1, proto=17, ports=1234) + rule2 = AclRule(is_permit=1, proto=17, ports=1234, + src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0))) + acl2 = VppAcl(self, rules=[rule, rule2]) + acl2.add_vpp_config() - acl2 = VppGbpAcl(self) - rule = acl2.create_rule(permit_deny=1, proto=17, sport_from=1234, - sport_to=1234, dport_from=1234, dport_to=1234) - rule2 = acl2.create_rule(is_ipv6=1, permit_deny=1, proto=17, - sport_from=1234, sport_to=1234, - dport_from=1234, dport_to=1234) - - acl_index2 = acl2.add_vpp_config([rule, rule2]) c4 = VppGbpContract( - self, 400, epgs[0].sclass, epgs[3].sclass, acl_index2, + self, 400, epgs[0].sclass, epgs[3].sclass, acl2.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -1408,35 +1457,34 @@ class TestGBP(VppTestCase): self.send_and_expect_natted(eps[0].itf, pkt_inter_epg_220_to_global * NUM_PKTS, self.pg7, - eps[0].fip4.address) + eps[0].fip4) pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IPv6(src=eps[0].ip6.address, + IPv6(src=eps[0].ip6, dst="6001::1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect_natted6(self.pg0, pkt_inter_epg_220_to_global * NUM_PKTS, self.pg7, - eps[0].fip6.address) - + eps[0].fip6) # # From a global address to an EP: OUT2IN # pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac), dst=self.pg0.remote_mac) / - IP(dst=eps[0].fip4.address, + IP(dst=eps[0].fip4, src="1.1.1.1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_assert_no_replies( self.pg7, pkt_inter_epg_220_from_global * NUM_PKTS) c5 = VppGbpContract( - self, 400, epgs[3].sclass, epgs[0].sclass, acl_index2, + self, 400, epgs[3].sclass, epgs[0].sclass, acl2.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -1451,20 +1499,20 @@ class TestGBP(VppTestCase): self.send_and_expect_unnatted(self.pg7, pkt_inter_epg_220_from_global * NUM_PKTS, eps[0].itf, - eps[0].ip4.address) + eps[0].ip4) pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac), dst=self.pg0.remote_mac) / - IPv6(dst=eps[0].fip6.address, + IPv6(dst=eps[0].fip6, src="6001::1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect_unnatted6( self.pg7, pkt_inter_epg_220_from_global * NUM_PKTS, eps[0].itf, - eps[0].ip6.address) + eps[0].ip6) # # From a local VM to another local VM using resp. public addresses: @@ -1472,77 +1520,50 @@ class TestGBP(VppTestCase): # pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IP(src=eps[0].ip4.address, - dst=eps[1].fip4.address) / + IP(src=eps[0].ip4, + dst=eps[1].fip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect_double_natted(eps[0].itf, pkt_intra_epg_220_global * NUM_PKTS, eps[1].itf, - eps[0].fip4.address, - eps[1].ip4.address) + eps[0].fip4, + eps[1].ip4) pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IPv6(src=eps[0].ip6.address, - dst=eps[1].fip6.address) / + IPv6(src=eps[0].ip6, + dst=eps[1].fip6) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect_double_natted6( eps[0].itf, pkt_intra_epg_220_global * NUM_PKTS, eps[1].itf, - eps[0].fip6.address, - eps[1].ip6.address) + eps[0].fip6, + eps[1].ip6) # # cleanup # - for ep in eps: - # del static mappings for each EP from the 10/8 to 11/8 network - flags = self.config_flags.NAT_IS_ADDR_ONLY - self.vapi.nat44_add_del_static_mapping( - is_add=0, - local_ip_address=ep.ip4.bytes, - external_ip_address=ep.fip4.bytes, - external_sw_if_index=0xFFFFFFFF, - vrf_id=0, - flags=flags) - self.vapi.nat66_add_del_static_mapping( - local_ip_address=ep.ip6.bytes, - external_ip_address=ep.fip6.bytes, - vrf_id=0, is_add=0) - - for epg in epgs: - # IP config on the BVI interfaces - if epg != epgs[0] and epg != epgs[3]: - flags = self.config_flags.NAT_IS_INSIDE - self.vapi.nat44_interface_add_del_feature( - sw_if_index=epg.bvi.sw_if_index, - flags=flags, - is_add=0) - self.vapi.nat66_add_del_interface( - is_add=0, flags=flags, - sw_if_index=epg.bvi.sw_if_index) - - for recirc in recircs: - self.vapi.nat44_interface_add_del_feature( - sw_if_index=recirc.recirc.sw_if_index, - is_add=0) - self.vapi.nat66_add_del_interface( - is_add=0, - sw_if_index=recirc.recirc.sw_if_index) + self.vapi.nat44_ed_plugin_enable_disable(enable=0) + self.vapi.nat66_plugin_enable_disable(enable=0) def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None, tep=None, n_tries=100, s_time=1): + # only learnt EP can timeout + ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t + flags = ep_flags.GBP_API_ENDPOINT_FLAG_LEARNT while (n_tries): - if not find_gbp_endpoint(self, sw_if_index, ip, mac, tep=tep): + if not find_gbp_endpoint(self, sw_if_index, ip, mac, tep=tep, + flags=flags): return True n_tries = n_tries - 1 self.sleep(s_time) - self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac)) + self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac, tep=tep, + flags=flags)) return False def test_gbp_learn_l2(self): @@ -1617,13 +1638,13 @@ class TestGBP(VppTestCase): None, self.loop0, "10.0.0.128", "2001:10::128", - VppGbpEndpointRetention(2)) + VppGbpEndpointRetention(4)) epg_220.add_vpp_config() epg_330 = VppGbpEndpointGroup(self, 330, 113, rd1, gbd1, None, self.loop1, "10.0.1.128", "2001:11::128", - VppGbpEndpointRetention(2)) + VppGbpEndpointRetention(4)) epg_330.add_vpp_config() # @@ -1646,7 +1667,7 @@ class TestGBP(VppTestCase): "2001:10::1", "3001::1") ep.add_vpp_config() - self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1)) + self.assertTrue(find_route(self, ep.ip4, 32, table_id=1)) # a packet with an sclass from an unknown EPG p = (Ether(src=self.pg2.remote_mac, @@ -1656,9 +1677,9 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=99, gpid=88, flags=0x88) / Ether(src=learnt[0]["mac"], dst=ep.mac) / - IP(src=learnt[0]["ip"], dst=ep.ip4.address) / + IP(src=learnt[0]["ip"], dst=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_assert_no_replies(self.pg2, p) @@ -1693,9 +1714,9 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=99, gpid=112, flags=0x88) / Ether(src=l['mac'], dst=ep.mac) / - IP(src=l['ip'], dst=ep.ip4.address) / + IP(src=l['ip'], dst=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rx = self.send_and_expect(self.pg2, [p], self.pg0) @@ -1793,7 +1814,7 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=99, gpid=112, flags=0x88) / Ether(src=l['mac'], dst=ep.mac) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rx = self.send_and_expect(self.pg2, [p], self.pg0) @@ -1836,9 +1857,9 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=99, gpid=112, flags=0x88, gpflags="D") / Ether(src=l['mac'], dst=ep.mac) / - IP(src=l['ip'], dst=ep.ip4.address) / + IP(src=l['ip'], dst=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) @@ -1861,9 +1882,9 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=99, gpid=112, flags=0xc8) / Ether(src=l['mac'], dst=ep.mac) / - IP(src=l['ip'], dst=ep.ip4.address) / + IP(src=l['ip'], dst=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) @@ -1877,9 +1898,9 @@ class TestGBP(VppTestCase): self.logger.info(self.vapi.cli("sh l2fib bd_id 1")) for l in learnt: p = (Ether(src=ep.mac, dst=l['mac']) / - IP(dst=l['ip'], src=ep.ip4.address) / + IP(dst=l['ip'], src=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, p * 17, self.pg2) @@ -1913,9 +1934,9 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') / Ether(src=l['mac'], dst=ep.mac) / - IP(src=l['ip'], dst=ep.ip4.address) / + IP(src=l['ip'], dst=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) @@ -1928,9 +1949,9 @@ class TestGBP(VppTestCase): # only test 1 EP as the others could timeout # p = (Ether(src=ep.mac, dst=l['mac']) / - IP(dst=learnt[0]['ip'], src=ep.ip4.address) / + IP(dst=learnt[0]['ip'], src=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_assert_no_replies(self.pg0, [p]) @@ -1946,9 +1967,9 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') / Ether(src=l['mac'], dst=ep.mac) / - IP(src=l['ip'], dst=ep.ip4.address) / + IP(src=l['ip'], dst=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) @@ -1959,12 +1980,14 @@ class TestGBP(VppTestCase): # # Add the contract so they can talk # - acl = VppGbpAcl(self) - rule = acl.create_rule(permit_deny=1, proto=17) - rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17) - acl_index = acl.add_vpp_config([rule, rule2]) + rule = AclRule(is_permit=1, proto=17) + rule2 = AclRule(src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17) + acl = VppAcl(self, rules=[rule, rule2]) + acl.add_vpp_config() + c1 = VppGbpContract( - self, 401, epg_220.sclass, epg_330.sclass, acl_index, + self, 401, epg_220.sclass, epg_330.sclass, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -1978,9 +2001,9 @@ class TestGBP(VppTestCase): for l in learnt: p = (Ether(src=ep.mac, dst=l['mac']) / - IP(dst=l['ip'], src=ep.ip4.address) / + IP(dst=l['ip'], src=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect(self.pg0, [p], self.pg2) @@ -1990,17 +2013,17 @@ class TestGBP(VppTestCase): self.logger.info(self.vapi.cli("sh gbp bridge")) self.logger.info(self.vapi.cli("sh bridge-domain 1 detail")) p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") / - IP(dst="10.0.0.133", src=ep.ip4.address) / + IP(dst="10.0.0.133", src=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_fwd) self.logger.info(self.vapi.cli("sh bridge 1 detail")) p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") / - IP(dst="10.0.0.133", src=ep.ip4.address) / + IP(dst="10.0.0.133", src=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf) for rx in rxs: @@ -2015,12 +2038,14 @@ class TestGBP(VppTestCase): self.assertFalse(rx[VXLAN].gpflags.A) self.assertFalse(rx[VXLAN].gpflags.D) - acl = VppGbpAcl(self) - rule = acl.create_rule(permit_deny=1, proto=17) - rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17) - acl_index = acl.add_vpp_config([rule, rule2]) + rule = AclRule(is_permit=1, proto=17) + rule2 = AclRule(src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17) + acl = VppAcl(self, rules=[rule, rule2]) + acl.add_vpp_config() + c2 = VppGbpContract( - self, 401, epg_330.sclass, epg_220.sclass, acl_index, + self, 401, epg_330.sclass, epg_220.sclass, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -2047,9 +2072,9 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=99, gpid=113, flags=0x88) / Ether(src=l['mac'], dst=ep.mac) / - IPv6(src=l['ip6'], dst=ep.ip6.address) / + IPv6(src=l['ip6'], dst=ep.ip6) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) @@ -2079,9 +2104,9 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=99, gpid=113, flags=0x88) / Ether(src=l['mac'], dst=ep.mac) / - IPv6(src=l['ip6'], dst=ep.ip6.address) / + IPv6(src=l['ip6'], dst=ep.ip6) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rx = self.send_and_expect(self.pg2, p * 1, self.pg0) rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) @@ -2089,6 +2114,7 @@ class TestGBP(VppTestCase): self.assertTrue(find_gbp_endpoint( self, vx_tun_l2_1.sw_if_index, + sclass=113, mac=l['mac'], tep=[self.pg2.local_ip4, self.pg2.remote_hosts[2].ip4])) @@ -2098,9 +2124,9 @@ class TestGBP(VppTestCase): # for l in learnt: p = (Ether(src=ep.mac, dst=l['mac']) / - IPv6(dst=l['ip6'], src=ep.ip6.address) / + IPv6(dst=l['ip6'], src=ep.ip6) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2) @@ -2117,6 +2143,65 @@ class TestGBP(VppTestCase): self.assertFalse(rx[VXLAN].gpflags.D) self.assertEqual(rx[IPv6].dst, l['ip6']) + # + # EP changes sclass + # + for l in learnt: + # a packet with an sclass from a known EPG + p = (Ether(src=self.pg2.remote_mac, + dst=self.pg2.local_mac) / + IP(src=self.pg2.remote_hosts[2].ip4, + dst=self.pg2.local_ip4) / + UDP(sport=1234, dport=48879) / + VXLAN(vni=99, gpid=112, flags=0x88) / + Ether(src=l['mac'], dst=ep.mac) / + IPv6(src=l['ip6'], dst=ep.ip6) / + UDP(sport=1234, dport=1234) / + Raw(b'\xa5' * 100)) + + rx = self.send_and_expect(self.pg2, p * 1, self.pg0) + rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) + + self.assertTrue(find_gbp_endpoint( + self, + vx_tun_l2_1.sw_if_index, + mac=l['mac'], + sclass=112, + tep=[self.pg2.local_ip4, + self.pg2.remote_hosts[2].ip4])) + + # + # check reachability and contract intra-epg + # + allow_intra_class = self.statistics.get_err_counter( + '/err/gbp-policy-mac/allow-intra-sclass') + + for l in learnt: + p = (Ether(src=ep.mac, dst=l['mac']) / + IPv6(dst=l['ip6'], src=ep.ip6) / + UDP(sport=1234, dport=1234) / + Raw(b'\xa5' * 100)) + + rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2) + + for rx in rxs: + self.assertEqual(rx[IP].src, self.pg2.local_ip4) + self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[2].ip4) + self.assertEqual(rx[UDP].dport, 48879) + self.assertEqual(rx[VXLAN].gpid, 112) + self.assertEqual(rx[VXLAN].vni, 99) + self.assertTrue(rx[VXLAN].flags.G) + self.assertTrue(rx[VXLAN].flags.Instance) + self.assertTrue(rx[VXLAN].gpflags.A) + self.assertFalse(rx[VXLAN].gpflags.D) + self.assertEqual(rx[IPv6].dst, l['ip6']) + + allow_intra_class += NUM_PKTS + + self.assert_error_counter_equal( + '/err/gbp-policy-mac/allow-intra-sclass', + allow_intra_class) + # # clean up # @@ -2195,21 +2280,23 @@ class TestGBP(VppTestCase): for epg in epgs: # IP config on the BVI interfaces if epg != epgs[1]: - VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config() - VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config() - self.vapi.sw_interface_set_mac_address( - epg.bvi.sw_if_index, - self.router_mac.packed) - - if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32) - if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128) - if_ip4.add_vpp_config() - if_ip6.add_vpp_config() + b4 = VppIpInterfaceBind(self, epg.bvi, + epg.rd.t4).add_vpp_config() + b6 = VppIpInterfaceBind(self, epg.bvi, + epg.rd.t6).add_vpp_config() + epg.bvi.set_mac(self.router_mac) + + if_ip4 = VppIpInterfaceAddress(self, epg.bvi, + epg.bvi_ip4, 32, + bind=b4).add_vpp_config() + if_ip6 = VppIpInterfaceAddress(self, epg.bvi, + epg.bvi_ip6, 128, + bind=b6).add_vpp_config() # add the BD ARP termination entry for BVI IP epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd, str(self.router_mac), - epg.bvi_ip4.address) + epg.bvi_ip4) epg.bd_arp_ip4.add_vpp_config() # EPG in VPP @@ -2230,10 +2317,10 @@ class TestGBP(VppTestCase): # pkt_intra_epg_220_to_220 = (Ether(src=self.pg0.remote_mac, dst=self.pg1.remote_mac) / - IP(src=eps[0].ip4.address, - dst=eps[1].ip4.address) / + IP(src=eps[0].ip4, + dst=eps[1].ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect_bridged(self.pg0, pkt_intra_epg_220_to_220 * 65, @@ -2241,10 +2328,10 @@ class TestGBP(VppTestCase): pkt_intra_epg_220_to_220 = (Ether(src=self.pg0.remote_mac, dst=self.pg1.remote_mac) / - IPv6(src=eps[0].ip6.address, - dst=eps[1].ip6.address) / + IPv6(src=eps[0].ip6, + dst=eps[1].ip6) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect_bridged6(self.pg0, pkt_intra_epg_220_to_220 * 65, @@ -2255,23 +2342,25 @@ class TestGBP(VppTestCase): # pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac, dst=self.pg2.remote_mac) / - IP(src=eps[0].ip4.address, - dst=eps[2].ip4.address) / + IP(src=eps[0].ip4, + dst=eps[2].ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_220_to_221) # # A uni-directional contract from EPG 220 -> 221 # - acl = VppGbpAcl(self) - rule = acl.create_rule(permit_deny=1, proto=17) - rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17) - rule3 = acl.create_rule(permit_deny=1, proto=1) - acl_index = acl.add_vpp_config([rule, rule2, rule3]) + rule = AclRule(is_permit=1, proto=17) + rule2 = AclRule(src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17) + rule3 = AclRule(is_permit=1, proto=1) + acl = VppAcl(self, rules=[rule, rule2, rule3]) + acl.add_vpp_config() + c1 = VppGbpContract( - self, 400, epgs[0].sclass, epgs[1].sclass, acl_index, + self, 400, epgs[0].sclass, epgs[1].sclass, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -2293,10 +2382,10 @@ class TestGBP(VppTestCase): pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IP(src=eps[0].ip4.address, - dst=eps[3].ip4.address) / + IP(src=eps[0].ip4, + dst=eps[3].ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_assert_no_replies(eps[0].itf, pkt_inter_epg_220_to_222 * 65) @@ -2305,16 +2394,16 @@ class TestGBP(VppTestCase): # pkt_router_ping_220_to_221 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IP(src=eps[0].ip4.address, - dst=epgs[1].bvi_ip4.address) / + IP(src=eps[0].ip4, + dst=epgs[1].bvi_ip4) / ICMP(type='echo-request')) self.send_and_expect(self.pg0, [pkt_router_ping_220_to_221], self.pg0) pkt_router_ping_220_to_221 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IPv6(src=eps[0].ip6.address, - dst=epgs[1].bvi_ip6.address) / + IPv6(src=eps[0].ip6, + dst=epgs[1].bvi_ip6) / ICMPv6EchoRequest()) self.send_and_expect(self.pg0, [pkt_router_ping_220_to_221], self.pg0) @@ -2323,7 +2412,7 @@ class TestGBP(VppTestCase): # contract for the return direction # c2 = VppGbpContract( - self, 400, epgs[1].sclass, epgs[0].sclass, acl_index, + self, 400, epgs[1].sclass, epgs[0].sclass, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -2340,29 +2429,29 @@ class TestGBP(VppTestCase): eps[2].itf) pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac, dst=self.pg0.remote_mac) / - IP(src=eps[2].ip4.address, - dst=eps[0].ip4.address) / + IP(src=eps[2].ip4, + dst=eps[0].ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect_bridged(eps[2].itf, pkt_inter_epg_221_to_220 * 65, eps[0].itf) pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac, dst=str(self.router_mac)) / - IP(src=eps[2].ip4.address, - dst=eps[0].ip4.address) / + IP(src=eps[2].ip4, + dst=eps[0].ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect_routed(eps[2].itf, pkt_inter_epg_221_to_220 * 65, eps[0].itf, str(self.router_mac)) pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac, dst=str(self.router_mac)) / - IPv6(src=eps[2].ip6.address, - dst=eps[0].ip6.address) / + IPv6(src=eps[2].ip6, + dst=eps[0].ip6) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect_routed6(eps[2].itf, pkt_inter_epg_221_to_220 * 65, eps[0].itf, @@ -2372,7 +2461,7 @@ class TestGBP(VppTestCase): # contract between 220 and 222 uni-direction # c3 = VppGbpContract( - self, 400, epgs[0].sclass, epgs[2].sclass, acl_index, + self, 400, epgs[0].sclass, epgs[2].sclass, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -2422,8 +2511,8 @@ class TestGBP(VppTestCase): self.logger.info(self.vapi.cli("sh gbp bridge")) # ... and has a /32 applied - ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32) - ip_addr.add_vpp_config() + ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, + "10.0.0.128", 32).add_vpp_config() # # The Endpoint-group @@ -2432,7 +2521,7 @@ class TestGBP(VppTestCase): None, self.loop0, "10.0.0.128", "2001:10::128", - VppGbpEndpointRetention(2)) + VppGbpEndpointRetention(3)) epg_220.add_vpp_config() ep = VppGbpEndpoint(self, self.pg0, @@ -2448,15 +2537,15 @@ class TestGBP(VppTestCase): self.logger.info(self.vapi.cli("sh bridge 1 detail")) self.logger.info(self.vapi.cli("sh gbp bridge")) p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") / - IP(dst="10.0.0.133", src=ep.ip4.address) / + IP(dst="10.0.0.133", src=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_assert_no_replies(ep.itf, [p_uu]) p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") / - IP(dst="10.0.0.133", src=ep.ip4.address) / + IP(dst="10.0.0.133", src=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_assert_no_replies(ep.itf, [p_bm]) self.pg3.unconfig_ip4() @@ -2503,8 +2592,8 @@ class TestGBP(VppTestCase): gbd1.add_vpp_config() # ... and has a /32 applied - ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32) - ip_addr.add_vpp_config() + ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, + "10.0.0.128", 32).add_vpp_config() # # The Endpoint-group @@ -2529,7 +2618,7 @@ class TestGBP(VppTestCase): self.logger.info(self.vapi.cli("sh gbp bridge")) p_arp = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") / ARP(op="who-has", - psrc=ep.ip4.address, pdst="10.0.0.99", + psrc=ep.ip4, pdst="10.0.0.99", hwsrc=ep.mac, hwdst="ff:ff:ff:ff:ff:ff")) self.send_and_expect(ep.itf, [p_arp], self.pg4) @@ -2596,8 +2685,8 @@ class TestGBP(VppTestCase): self.logger.info(self.vapi.cli("sh gbp bridge")) # ... and has a /32 applied - ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32) - ip_addr.add_vpp_config() + ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, + "10.0.0.128", 32).add_vpp_config() # # The Endpoint-group in which we are learning endpoints @@ -2606,7 +2695,7 @@ class TestGBP(VppTestCase): None, self.loop0, "10.0.0.128", "2001:10::128", - VppGbpEndpointRetention(2)) + VppGbpEndpointRetention(4)) epg_220.add_vpp_config() # @@ -2629,7 +2718,7 @@ class TestGBP(VppTestCase): "2001:10::1", "3001::1") ep.add_vpp_config() - self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1)) + self.assertTrue(find_route(self, ep.ip4, 32, table_id=1)) # # Send to the static EP @@ -2644,9 +2733,9 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=99, gpid=441, flags=0x88) / Ether(src=l['mac'], dst=ep.mac) / - IP(src=l['ip'], dst=ep.ip4.address) / + IP(src=l['ip'], dst=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg2, [p], self.pg0) @@ -2679,9 +2768,9 @@ class TestGBP(VppTestCase): for l in learnt: p = (Ether(src=ep.mac, dst=l['mac']) / Dot1Q(vlan=11) / - IP(dst=l['ip'], src=ep.ip4.address) / + IP(dst=l['ip'], src=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, p * 17, self.pg3) @@ -2739,8 +2828,8 @@ class TestGBP(VppTestCase): # # Bind the BVI to the RD # - VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config() - VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config() + b4 = VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config() + b6 = VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config() # # Pg2 hosts the vxlan tunnel @@ -2770,10 +2859,12 @@ class TestGBP(VppTestCase): self.logger.info(self.vapi.cli("sh gbp route")) # ... and has a /32 and /128 applied - ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32) - ip4_addr.add_vpp_config() - ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128) - ip6_addr.add_vpp_config() + ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, + "10.0.0.128", 32, + bind=b4).add_vpp_config() + ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, + "2001:10::128", 128, + bind=b6).add_vpp_config() # # The Endpoint-group in which we are learning endpoints @@ -2782,7 +2873,7 @@ class TestGBP(VppTestCase): None, self.loop0, "10.0.0.128", "2001:10::128", - VppGbpEndpointRetention(2)) + VppGbpEndpointRetention(4)) epg_220.add_vpp_config() # @@ -2817,9 +2908,9 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=101, gpid=441, flags=0x88) / Ether(src=l['mac'], dst="00:00:00:11:11:11") / - IP(src=l['ip'], dst=ep.ip4.address) / + IP(src=l['ip'], dst=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rx = self.send_and_expect(self.pg2, [p], self.pg0) @@ -2841,9 +2932,9 @@ class TestGBP(VppTestCase): # for l in learnt: p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(dst=l['ip'], src=ep.ip4.address) / + IP(dst=l['ip'], src=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, p * 1, self.pg2) @@ -2863,7 +2954,7 @@ class TestGBP(VppTestCase): self.assertEqual(inner[Ether].src, routed_src_mac) self.assertEqual(inner[Ether].dst, routed_dst_mac) - self.assertEqual(inner[IP].src, ep.ip4.address) + self.assertEqual(inner[IP].src, ep.ip4) self.assertEqual(inner[IP].dst, l['ip']) for l in learnt: @@ -2884,9 +2975,9 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=101, gpid=441, flags=0x88) / Ether(src=l['mac'], dst="00:00:00:11:11:11") / - IPv6(src=l['ip6'], dst=ep.ip6.address) / + IPv6(src=l['ip6'], dst=ep.ip6) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rx = self.send_and_expect(self.pg2, [p], self.pg0) @@ -2914,9 +3005,9 @@ class TestGBP(VppTestCase): # for l in learnt: p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IPv6(dst=l['ip6'], src=ep.ip6.address) / + IPv6(dst=l['ip6'], src=ep.ip6) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2) @@ -2936,7 +3027,7 @@ class TestGBP(VppTestCase): self.assertEqual(inner[Ether].src, routed_src_mac) self.assertEqual(inner[Ether].dst, routed_dst_mac) - self.assertEqual(inner[IPv6].src, ep.ip6.address) + self.assertEqual(inner[IPv6].src, ep.ip6) self.assertEqual(inner[IPv6].dst, l['ip6']) self.logger.info(self.vapi.cli("sh gbp endpoint")) @@ -2947,9 +3038,9 @@ class TestGBP(VppTestCase): # Static sends to unknown EP with no route # p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(dst="10.0.0.99", src=ep.ip4.address) / + IP(dst="10.0.0.99", src=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_assert_no_replies(self.pg0, [p]) @@ -2965,16 +3056,16 @@ class TestGBP(VppTestCase): # static pings router # p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(dst=epg_220.bvi_ip4.address, src=ep.ip4.address) / + IP(dst=epg_220.bvi_ip4, src=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg0) p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IPv6(dst=epg_220.bvi_ip6.address, src=ep.ip6.address) / + IPv6(dst=epg_220.bvi_ip6, src=ep.ip6) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg0) @@ -2982,9 +3073,9 @@ class TestGBP(VppTestCase): # packets to address in the subnet are sent on the uu-fwd # p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(dst="10.0.0.99", src=ep.ip4.address) / + IP(dst="10.0.0.99", src=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, [p], self.pg4) for rx in rxs: @@ -3013,9 +3104,9 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=101, gpid=441, flags=0x88) / Ether(src=l['mac'], dst="00:00:00:11:11:11") / - IP(src=l['ip'], dst=ep.ip4.address) / + IP(src=l['ip'], dst=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rx = self.send_and_expect(self.pg2, [p], self.pg0) @@ -3074,9 +3165,9 @@ class TestGBP(VppTestCase): ips = ["10.0.0.88", learnt[0]['ip']] for ip in ips: p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(dst=ip, src=ep.ip4.address) / + IP(dst=ip, src=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2) @@ -3096,7 +3187,7 @@ class TestGBP(VppTestCase): self.assertEqual(inner[Ether].src, routed_src_mac) self.assertEqual(inner[Ether].dst, routed_dst_mac) - self.assertEqual(inner[IP].src, ep.ip4.address) + self.assertEqual(inner[IP].src, ep.ip4) self.assertEqual(inner[IP].dst, ip) # @@ -3106,20 +3197,20 @@ class TestGBP(VppTestCase): rep_88.remove_vpp_config() rep_2.remove_vpp_config() - self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4.address)) + self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4)) p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(src=ep.ip4.address, dst=rep_2.ip4.address) / + IP(src=ep.ip4, dst=rep_2.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, [p], self.pg2) - self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address)) + self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4)) p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(src=ep.ip4.address, dst=rep_88.ip4.address) / + IP(src=ep.ip4, dst=rep_88.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, [p], self.pg4) # @@ -3127,8 +3218,8 @@ class TestGBP(VppTestCase): # present (because it's DP learnt) when the TC ends so wait until # it is removed # - self.wait_for_ep_timeout(ip=rep_88.ip4.address) - self.wait_for_ep_timeout(ip=rep_2.ip4.address) + self.wait_for_ep_timeout(ip=rep_88.ip4) + self.wait_for_ep_timeout(ip=rep_2.ip4) # # Same as above, learn a remote EP via CP and DP @@ -3151,21 +3242,21 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=101, gpid=441, flags=0x88) / Ether(src=l['mac'], dst="00:00:00:11:11:11") / - IP(src="10.0.1.4", dst=ep.ip4.address) / + IP(src="10.0.1.4", dst=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) self.assertTrue(find_gbp_endpoint(self, vx_tun_l3._sw_if_index, - ip=rep_3.ip4.address, + ip=rep_3.ip4, tep=[self.pg2.local_ip4, self.pg2.remote_hosts[2].ip4])) p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(dst="10.0.1.4", src=ep.ip4.address) / + IP(dst="10.0.1.4", src=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2) # host 2 is the DP learned TEP @@ -3173,7 +3264,7 @@ class TestGBP(VppTestCase): self.assertEqual(rx[IP].src, self.pg2.local_ip4) self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[2].ip4) - self.wait_for_ep_timeout(ip=rep_3.ip4.address, + self.wait_for_ep_timeout(ip=rep_3.ip4, tep=[self.pg2.local_ip4, self.pg2.remote_hosts[2].ip4]) @@ -3194,9 +3285,9 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=101, gpid=441, flags=0x88) / Ether(src=l['mac'], dst="00:00:00:11:11:11") / - IP(src=learnt[1]['ip'], dst=ep.ip4.address) / + IP(src=learnt[1]['ip'], dst=ep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rx = self.send_and_expect(self.pg2, [p], self.pg0) @@ -3245,8 +3336,8 @@ class TestGBP(VppTestCase): # # Bind the BVI to the RD # - VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config() - VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config() + b_ip4 = VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config() + b_ip6 = VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config() # # Pg7 hosts a BD's UU-fwd @@ -3268,14 +3359,16 @@ class TestGBP(VppTestCase): gbd2.add_vpp_config() # ... and has a /32 and /128 applied - ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32) - ip4_addr.add_vpp_config() - ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128) - ip6_addr.add_vpp_config() - ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi, "10.0.1.128", 32) - ip4_addr.add_vpp_config() - ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi, "2001:11::128", 128) - ip6_addr.add_vpp_config() + ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, + "10.0.0.128", 32, + bind=b_ip4).add_vpp_config() + ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, + "2001:10::128", 128, + bind=b_ip6).add_vpp_config() + ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi, + "10.0.1.128", 32).add_vpp_config() + ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi, + "2001:11::128", 128).add_vpp_config() # # The Endpoint-groups in which we are learning endpoints @@ -3284,19 +3377,19 @@ class TestGBP(VppTestCase): None, gbd1.bvi, "10.0.0.128", "2001:10::128", - VppGbpEndpointRetention(2)) + VppGbpEndpointRetention(60)) epg_220.add_vpp_config() epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2, None, gbd2.bvi, "10.0.1.128", "2001:11::128", - VppGbpEndpointRetention(2)) + VppGbpEndpointRetention(60)) epg_221.add_vpp_config() epg_222 = VppGbpEndpointGroup(self, 222, 442, rd1, gbd1, None, gbd1.bvi, "10.0.2.128", "2001:12::128", - VppGbpEndpointRetention(2)) + VppGbpEndpointRetention(60)) epg_222.add_vpp_config() # @@ -3327,13 +3420,13 @@ class TestGBP(VppTestCase): None, gbd1.bvi, "12.0.0.128", "4001:10::128", - VppGbpEndpointRetention(2)) + VppGbpEndpointRetention(60)) epg_320.add_vpp_config() epg_321 = VppGbpEndpointGroup(self, 321, 551, rd1, gbd4, None, gbd2.bvi, "12.0.1.128", "4001:11::128", - VppGbpEndpointRetention(2)) + VppGbpEndpointRetention(60)) epg_321.add_vpp_config() # @@ -3384,21 +3477,21 @@ class TestGBP(VppTestCase): # different dest ports on each so the are LB hashed differently # p4 = [(Ether(src=ep1.mac, dst=ep3.mac) / - IP(src=ep1.ip4.address, dst=ep3.ip4.address) / + IP(src=ep1.ip4, dst=ep3.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)), + Raw(b'\xa5' * 100)), (Ether(src=ep3.mac, dst=ep1.mac) / - IP(src=ep3.ip4.address, dst=ep1.ip4.address) / + IP(src=ep3.ip4, dst=ep1.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100))] + Raw(b'\xa5' * 100))] p6 = [(Ether(src=ep1.mac, dst=ep3.mac) / - IPv6(src=ep1.ip6.address, dst=ep3.ip6.address) / + IPv6(src=ep1.ip6, dst=ep3.ip6) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)), + Raw(b'\xa5' * 100)), (Ether(src=ep3.mac, dst=ep1.mac) / - IPv6(src=ep3.ip6.address, dst=ep1.ip6.address) / + IPv6(src=ep3.ip6, dst=ep1.ip6) / UDP(sport=1234, dport=1230) / - Raw('\xa5' * 100))] + Raw(b'\xa5' * 100))] # should be dropped since no contract yet self.send_and_assert_no_replies(self.pg0, [p4[0]]) @@ -3408,16 +3501,17 @@ class TestGBP(VppTestCase): # Add a contract with a rule to load-balance redirect via SEP1 and SEP2 # one of the next-hops is via an EP that is not known # - acl = VppGbpAcl(self) - rule4 = acl.create_rule(permit_deny=1, proto=17) - rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17) - acl_index = acl.add_vpp_config([rule4, rule6]) + rule4 = AclRule(is_permit=1, proto=17) + rule6 = AclRule(src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17) + acl = VppAcl(self, rules=[rule4, rule6]) + acl.add_vpp_config() # # test the src-ip hash mode # c1 = VppGbpContract( - self, 402, epg_220.sclass, epg_222.sclass, acl_index, + self, 402, epg_220.sclass, epg_222.sclass, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -3436,7 +3530,7 @@ class TestGBP(VppTestCase): c1.add_vpp_config() c2 = VppGbpContract( - self, 402, epg_222.sclass, epg_220.sclass, acl_index, + self, 402, epg_222.sclass, epg_220.sclass, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -3463,16 +3557,16 @@ class TestGBP(VppTestCase): for rx in rxs: self.assertEqual(rx[Ether].src, routed_src_mac) self.assertEqual(rx[Ether].dst, sep1.mac) - self.assertEqual(rx[IP].src, ep1.ip4.address) - self.assertEqual(rx[IP].dst, ep3.ip4.address) + self.assertEqual(rx[IP].src, ep1.ip4) + self.assertEqual(rx[IP].dst, ep3.ip4) rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep2.itf) for rx in rxs: self.assertEqual(rx[Ether].src, routed_src_mac) self.assertEqual(rx[Ether].dst, sep2.mac) - self.assertEqual(rx[IP].src, ep3.ip4.address) - self.assertEqual(rx[IP].dst, ep1.ip4.address) + self.assertEqual(rx[IP].src, ep3.ip4) + self.assertEqual(rx[IP].dst, ep1.ip4) rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7) @@ -3492,16 +3586,16 @@ class TestGBP(VppTestCase): self.assertEqual(inner[Ether].src, routed_src_mac) self.assertEqual(inner[Ether].dst, sep4.mac) - self.assertEqual(inner[IPv6].src, ep1.ip6.address) - self.assertEqual(inner[IPv6].dst, ep3.ip6.address) + self.assertEqual(inner[IPv6].src, ep1.ip6) + self.assertEqual(inner[IPv6].dst, ep3.ip6) rxs = self.send_and_expect(self.pg2, p6[1] * 17, sep3.itf) for rx in rxs: self.assertEqual(rx[Ether].src, routed_src_mac) self.assertEqual(rx[Ether].dst, sep3.mac) - self.assertEqual(rx[IPv6].src, ep3.ip6.address) - self.assertEqual(rx[IPv6].dst, ep1.ip6.address) + self.assertEqual(rx[IPv6].src, ep3.ip6) + self.assertEqual(rx[IPv6].dst, ep1.ip6) # # programme the unknown EP @@ -3513,8 +3607,8 @@ class TestGBP(VppTestCase): for rx in rxs: self.assertEqual(rx[Ether].src, routed_src_mac) self.assertEqual(rx[Ether].dst, sep4.mac) - self.assertEqual(rx[IPv6].src, ep1.ip6.address) - self.assertEqual(rx[IPv6].dst, ep3.ip6.address) + self.assertEqual(rx[IPv6].src, ep1.ip6) + self.assertEqual(rx[IPv6].dst, ep3.ip6) # # and revert back to unprogrammed @@ -3539,8 +3633,8 @@ class TestGBP(VppTestCase): self.assertEqual(inner[Ether].src, routed_src_mac) self.assertEqual(inner[Ether].dst, sep4.mac) - self.assertEqual(inner[IPv6].src, ep1.ip6.address) - self.assertEqual(inner[IPv6].dst, ep3.ip6.address) + self.assertEqual(inner[IPv6].src, ep1.ip6) + self.assertEqual(inner[IPv6].dst, ep3.ip6) c1.remove_vpp_config() c2.remove_vpp_config() @@ -3549,7 +3643,7 @@ class TestGBP(VppTestCase): # test the symmetric hash mode # c1 = VppGbpContract( - self, 402, epg_220.sclass, epg_222.sclass, acl_index, + self, 402, epg_220.sclass, epg_222.sclass, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, @@ -3568,7 +3662,7 @@ class TestGBP(VppTestCase): c1.add_vpp_config() c2 = VppGbpContract( - self, 402, epg_222.sclass, epg_220.sclass, acl_index, + self, 402, epg_222.sclass, epg_220.sclass, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, @@ -3595,16 +3689,16 @@ class TestGBP(VppTestCase): for rx in rxs: self.assertEqual(rx[Ether].src, routed_src_mac) self.assertEqual(rx[Ether].dst, sep1.mac) - self.assertEqual(rx[IP].src, ep1.ip4.address) - self.assertEqual(rx[IP].dst, ep3.ip4.address) + self.assertEqual(rx[IP].src, ep1.ip4) + self.assertEqual(rx[IP].dst, ep3.ip4) rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep1.itf) for rx in rxs: self.assertEqual(rx[Ether].src, routed_src_mac) self.assertEqual(rx[Ether].dst, sep1.mac) - self.assertEqual(rx[IP].src, ep3.ip4.address) - self.assertEqual(rx[IP].dst, ep1.ip4.address) + self.assertEqual(rx[IP].src, ep3.ip4) + self.assertEqual(rx[IP].dst, ep1.ip4) # # programme the unknown EP for the L3 tests @@ -3616,24 +3710,24 @@ class TestGBP(VppTestCase): # different dest ports on each so the are LB hashed differently # p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) / - IP(src=ep1.ip4.address, dst=ep2.ip4.address) / + IP(src=ep1.ip4, dst=ep2.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)), + Raw(b'\xa5' * 100)), (Ether(src=ep2.mac, dst=str(self.router_mac)) / - IP(src=ep2.ip4.address, dst=ep1.ip4.address) / + IP(src=ep2.ip4, dst=ep1.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100))] + Raw(b'\xa5' * 100))] p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) / - IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) / + IPv6(src=ep1.ip6, dst=ep2.ip6) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)), + Raw(b'\xa5' * 100)), (Ether(src=ep2.mac, dst=str(self.router_mac)) / - IPv6(src=ep2.ip6.address, dst=ep1.ip6.address) / + IPv6(src=ep2.ip6, dst=ep1.ip6) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100))] + Raw(b'\xa5' * 100))] c3 = VppGbpContract( - self, 402, epg_220.sclass, epg_221.sclass, acl_index, + self, 402, epg_220.sclass, epg_221.sclass, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, @@ -3656,11 +3750,12 @@ class TestGBP(VppTestCase): for rx in rxs: self.assertEqual(rx[Ether].src, routed_src_mac) self.assertEqual(rx[Ether].dst, sep1.mac) - self.assertEqual(rx[IP].src, ep1.ip4.address) - self.assertEqual(rx[IP].dst, ep2.ip4.address) + self.assertEqual(rx[IP].src, ep1.ip4) + self.assertEqual(rx[IP].dst, ep2.ip4) # # learn a remote EP in EPG 221 + # packets coming from unknown remote EPs will be leant & redirected # vx_tun_l3 = VppGbpVxlanTunnel( self, 444, rd1.rd_id, @@ -3669,15 +3764,21 @@ class TestGBP(VppTestCase): vx_tun_l3.add_vpp_config() c4 = VppGbpContract( - self, 402, epg_221.sclass, epg_220.sclass, acl_index, + self, 402, epg_221.sclass, epg_220.sclass, acl.acl_index, [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), + [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, + sep1.ip4, sep1.epg.rd), + VppGbpContractNextHop(sep2.vmac, sep2.epg.bd, + sep2.ip4, sep2.epg.rd)]), VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], + [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd, + sep3.ip6, sep3.epg.rd), + VppGbpContractNextHop(sep4.vmac, sep4.epg.bd, + sep4.ip6, sep4.epg.rd)])], [ETH_P_IP, ETH_P_IPV6]) c4.add_vpp_config() @@ -3688,11 +3789,18 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=444, gpid=441, flags=0x88) / Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) / - IP(src="10.0.0.88", dst=ep1.ip4.address) / + IP(src="10.0.0.88", dst=ep1.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) - rx = self.send_and_expect(self.pg7, [p], self.pg0) + # unknown remote EP to local EP redirected + rxs = self.send_and_expect(self.pg7, [p], sep1.itf) + + for rx in rxs: + self.assertEqual(rx[Ether].src, routed_src_mac) + self.assertEqual(rx[Ether].dst, sep1.mac) + self.assertEqual(rx[IP].src, "10.0.0.88") + self.assertEqual(rx[IP].dst, ep1.ip4) # endpoint learnt via the parent GBP-vxlan interface self.assertTrue(find_gbp_endpoint(self, @@ -3706,11 +3814,18 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=444, gpid=441, flags=0x88) / Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) / - IPv6(src="2001:10::88", dst=ep1.ip6.address) / + IPv6(src="2001:10::88", dst=ep1.ip6) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) - rx = self.send_and_expect(self.pg7, [p], self.pg0) + # unknown remote EP to local EP redirected (ipv6) + rxs = self.send_and_expect(self.pg7, [p], sep3.itf) + + for rx in rxs: + self.assertEqual(rx[Ether].src, routed_src_mac) + self.assertEqual(rx[Ether].dst, sep3.mac) + self.assertEqual(rx[IPv6].src, "2001:10::88") + self.assertEqual(rx[IPv6].dst, ep1.ip6) # endpoint learnt via the parent GBP-vxlan interface self.assertTrue(find_gbp_endpoint(self, @@ -3721,20 +3836,20 @@ class TestGBP(VppTestCase): # L3 switch from local to remote EP # p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) / - IP(src=ep1.ip4.address, dst="10.0.0.88") / + IP(src=ep1.ip4, dst="10.0.0.88") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100))] + Raw(b'\xa5' * 100))] p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) / - IPv6(src=ep1.ip6.address, dst="2001:10::88") / + IPv6(src=ep1.ip6, dst="2001:10::88") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100))] + Raw(b'\xa5' * 100))] rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf) for rx in rxs: self.assertEqual(rx[Ether].src, routed_src_mac) self.assertEqual(rx[Ether].dst, sep1.mac) - self.assertEqual(rx[IP].src, ep1.ip4.address) + self.assertEqual(rx[IP].src, ep1.ip4) self.assertEqual(rx[IP].dst, "10.0.0.88") rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf) @@ -3742,14 +3857,14 @@ class TestGBP(VppTestCase): for rx in rxs: self.assertEqual(rx[Ether].src, routed_src_mac) self.assertEqual(rx[Ether].dst, sep4.mac) - self.assertEqual(rx[IPv6].src, ep1.ip6.address) + self.assertEqual(rx[IPv6].src, ep1.ip6) self.assertEqual(rx[IPv6].dst, "2001:10::88") # # test the dst-ip hash mode # c5 = VppGbpContract( - self, 402, epg_220.sclass, epg_221.sclass, acl_index, + self, 402, epg_220.sclass, epg_221.sclass, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, @@ -3772,7 +3887,7 @@ class TestGBP(VppTestCase): for rx in rxs: self.assertEqual(rx[Ether].src, routed_src_mac) self.assertEqual(rx[Ether].dst, sep1.mac) - self.assertEqual(rx[IP].src, ep1.ip4.address) + self.assertEqual(rx[IP].src, ep1.ip4) self.assertEqual(rx[IP].dst, "10.0.0.88") rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep3.itf) @@ -3780,80 +3895,842 @@ class TestGBP(VppTestCase): for rx in rxs: self.assertEqual(rx[Ether].src, routed_src_mac) self.assertEqual(rx[Ether].dst, sep3.mac) - self.assertEqual(rx[IPv6].src, ep1.ip6.address) + self.assertEqual(rx[IPv6].src, ep1.ip6) self.assertEqual(rx[IPv6].dst, "2001:10::88") # - # cleanup + # a programmed remote SEP in EPG 320 # - self.pg7.unconfig_ip4() - def test_gbp_l3_out(self): - """ GBP L3 Out """ + # gbp vxlan tunnel for the remote SEP + vx_tun_l3_sep = VppGbpVxlanTunnel( + self, 555, rd1.rd_id, + VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3, + self.pg2.local_ip4) + vx_tun_l3_sep.add_vpp_config() - ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t - self.vapi.cli("set logging class gbp level debug") + # remote SEP + sep5 = VppGbpEndpoint(self, vx_tun_l3_sep, + epg_320, None, + "12.0.0.10", "13.0.0.10", + "4001:10::10", "5001:10::10", + ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE, + self.pg7.local_ip4, + self.pg7.remote_ip4, + mac=None) + sep5.add_vpp_config() + + # + # local l3out redirect tests + # + + # add local l3out + # the external bd + self.loop4.set_mac(self.router_mac) + b_lo4_ip4 = VppIpInterfaceBind(self, self.loop4, t4).add_vpp_config() + b_lo4_ip6 = VppIpInterfaceBind(self, self.loop4, t6).add_vpp_config() + ebd = VppBridgeDomain(self, 100) + ebd.add_vpp_config() + gebd = VppGbpBridgeDomain(self, ebd, rd1, self.loop4, None, None) + gebd.add_vpp_config() + # the external epg + eepg = VppGbpEndpointGroup(self, 888, 765, rd1, gebd, + None, gebd.bvi, + "10.1.0.128", + "2001:10:1::128", + VppGbpEndpointRetention(60)) + eepg.add_vpp_config() + # add subnets to BVI + VppIpInterfaceAddress( + self, + gebd.bvi, + "10.1.0.128", + 24, bind=b_lo4_ip4).add_vpp_config() + VppIpInterfaceAddress( + self, + gebd.bvi, + "2001:10:1::128", + 64, bind=b_lo4_ip6).add_vpp_config() + # ... which are L3-out subnets + VppGbpSubnet(self, rd1, "10.1.0.0", 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, + sclass=765).add_vpp_config() + VppGbpSubnet(self, rd1, "2001:10:1::128", 64, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, + sclass=765).add_vpp_config() + # external endpoints + VppL2Vtr(self, self.vlan_100, L2_VTR_OP.L2_POP_1).add_vpp_config() + eep1 = VppGbpEndpoint(self, self.vlan_100, eepg, None, "10.1.0.1", + "11.1.0.1", "2001:10:1::1", "3001:10:1::1", + ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL) + eep1.add_vpp_config() + VppL2Vtr(self, self.vlan_101, L2_VTR_OP.L2_POP_1).add_vpp_config() + eep2 = VppGbpEndpoint(self, self.vlan_101, eepg, None, "10.1.0.2", + "11.1.0.2", "2001:10:1::2", "3001:10:1::2", + ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL) + eep2.add_vpp_config() - routed_dst_mac = "00:0c:0c:0c:0c:0c" - routed_src_mac = "00:22:bd:f8:19:ff" + # external subnets reachable though eep1 and eep2 respectively + VppIpRoute(self, "10.220.0.0", 24, + [VppRoutePath(eep1.ip4, eep1.epg.bvi.sw_if_index)], + table_id=t4.table_id).add_vpp_config() + VppGbpSubnet(self, rd1, "10.220.0.0", 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, + sclass=4220).add_vpp_config() + VppIpRoute(self, "10:220::", 64, + [VppRoutePath(eep1.ip6, eep1.epg.bvi.sw_if_index)], + table_id=t6.table_id).add_vpp_config() + VppGbpSubnet(self, rd1, "10:220::", 64, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, + sclass=4220).add_vpp_config() + VppIpRoute(self, "10.221.0.0", 24, + [VppRoutePath(eep2.ip4, eep2.epg.bvi.sw_if_index)], + table_id=t4.table_id).add_vpp_config() + VppGbpSubnet(self, rd1, "10.221.0.0", 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, + sclass=4221).add_vpp_config() + VppIpRoute(self, "10:221::", 64, + [VppRoutePath(eep2.ip6, eep2.epg.bvi.sw_if_index)], + table_id=t6.table_id).add_vpp_config() + VppGbpSubnet(self, rd1, "10:221::", 64, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, + sclass=4221).add_vpp_config() + + # + # l3out redirect to remote (known, then unknown) SEP + # + + # packets from 1 external subnet to the other + p = [(Ether(src=eep1.mac, dst=self.router_mac) / + Dot1Q(vlan=100) / + IP(src="10.220.0.17", dst="10.221.0.65") / + UDP(sport=1234, dport=1234) / + Raw(b'\xa5' * 100)), + (Ether(src=eep1.mac, dst=self.router_mac) / + Dot1Q(vlan=100) / + IPv6(src="10:220::17", dst="10:221::65") / + UDP(sport=1234, dport=1234) / + Raw(b'\xa5' * 100))] - # - # IP tables - # - t4 = VppIpTable(self, 1) - t4.add_vpp_config() - t6 = VppIpTable(self, 1, True) - t6.add_vpp_config() + # packets should be dropped in absence of contract + self.send_and_assert_no_replies(self.pg0, p) - rd1 = VppGbpRouteDomain(self, 2, 55, t4, t6) - rd1.add_vpp_config() + # contract redirecting to sep5 + VppGbpContract( + self, 402, 4220, 4221, acl.acl_index, + [VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, + [VppGbpContractNextHop(sep5.vmac, sep5.epg.bd, + sep5.ip4, sep5.epg.rd)]), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, + [VppGbpContractNextHop(sep5.vmac, sep5.epg.bd, + sep5.ip6, sep5.epg.rd)])], + [ETH_P_IP, ETH_P_IPV6]).add_vpp_config() - self.loop0.set_mac(self.router_mac) + rxs = self.send_and_expect(self.pg0, p, self.pg7) - # - # Bind the BVI to the RD - # - VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config() - VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config() + for rx, tx in zip(rxs, p): + self.assertEqual(rx[Ether].src, self.pg7.local_mac) + self.assertEqual(rx[Ether].dst, self.pg7.remote_mac) + self.assertEqual(rx[IP].src, self.pg7.local_ip4) + self.assertEqual(rx[IP].dst, self.pg7.remote_ip4) + # this should use the programmed remote leaf TEP + self.assertEqual(rx[VXLAN].vni, 555) + self.assertEqual(rx[VXLAN].gpid, 4220) + self.assertTrue(rx[VXLAN].flags.G) + self.assertTrue(rx[VXLAN].flags.Instance) + # redirect policy has been applied + self.assertTrue(rx[VXLAN].gpflags.A) + self.assertTrue(rx[VXLAN].gpflags.D) + rxip = rx[VXLAN][Ether].payload + txip = tx[Dot1Q].payload + self.assertEqual(rxip.src, txip.src) + self.assertEqual(rxip.dst, txip.dst) - # - # Pg7 hosts a BD's BUM - # Pg1 some other l3 interface - # - self.pg7.config_ip4() - self.pg7.resolve_arp() + # remote SEP: it is now an unknown remote SEP and should go + # to spine proxy + sep5.remove_vpp_config() + + rxs = self.send_and_expect(self.pg0, p, self.pg7) + + for rx, tx in zip(rxs, p): + self.assertEqual(rx[Ether].src, self.pg7.local_mac) + self.assertEqual(rx[Ether].dst, self.pg7.remote_mac) + self.assertEqual(rx[IP].src, self.pg7.local_ip4) + self.assertEqual(rx[IP].dst, self.pg7.remote_ip4) + # this should use the spine proxy TEP + self.assertEqual(rx[VXLAN].vni, epg_320.bd.uu_fwd.vni) + self.assertEqual(rx[VXLAN].gpid, 4220) + self.assertTrue(rx[VXLAN].flags.G) + self.assertTrue(rx[VXLAN].flags.Instance) + # redirect policy has been applied + self.assertTrue(rx[VXLAN].gpflags.A) + self.assertTrue(rx[VXLAN].gpflags.D) + rxip = rx[VXLAN][Ether].payload + txip = tx[Dot1Q].payload + self.assertEqual(rxip.src, txip.src) + self.assertEqual(rxip.dst, txip.dst) # - # a multicast vxlan-gbp tunnel for broadcast in the BD + # l3out redirect to local SEP # - tun_bm = VppVxlanGbpTunnel(self, self.pg7.local_ip4, - "239.1.1.1", 88, - mcast_itf=self.pg7) - tun_bm.add_vpp_config() + + # change the contract between l3out to redirect to local SEPs + # instead of remote SEP + VppGbpContract( + self, 402, 4220, 4221, acl.acl_index, + [VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, + [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, + sep1.ip4, sep1.epg.rd)]), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, + [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, + sep1.ip6, sep1.epg.rd)])], + [ETH_P_IP, ETH_P_IPV6]).add_vpp_config() + + rxs = self.send_and_expect(self.pg0, p, sep1.itf) + for rx, tx in zip(rxs, p): + self.assertEqual(rx[Ether].src, routed_src_mac) + self.assertEqual(rx[Ether].dst, sep1.mac) + rxip = rx[Ether].payload + txip = tx[Ether].payload + self.assertEqual(rxip.src, txip.src) + self.assertEqual(rxip.dst, txip.dst) # - # a GBP external bridge domains for the EPs + # redirect remote EP to remote (known then unknown) SEP # - bd1 = VppBridgeDomain(self, 1) - bd1.add_vpp_config() - gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, None, tun_bm) - gbd1.add_vpp_config() - # + # remote SEP known again + sep5.add_vpp_config() + + # contract to redirect to learnt SEP + VppGbpContract( + self, 402, epg_221.sclass, epg_222.sclass, acl.acl_index, + [VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, + [VppGbpContractNextHop(sep5.vmac, sep5.epg.bd, + sep5.ip4, sep5.epg.rd)]), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, + [VppGbpContractNextHop(sep5.vmac, sep5.epg.bd, + sep5.ip6, sep5.epg.rd)])], + [ETH_P_IP, ETH_P_IPV6]).add_vpp_config() + + # packets from unknown EP 221 to known EP in EPG 222 + # should be redirected to known remote SEP + base = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) / + IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) / + UDP(sport=1234, dport=48879) / + VXLAN(vni=444, gpid=441, flags=0x88) / + Ether(src="00:22:22:22:22:44", dst=str(self.router_mac))) + p = [(base / + IP(src="10.0.1.100", dst=ep3.ip4) / + UDP(sport=1234, dport=1234) / + Raw(b'\xa5' * 100)), + (base / + IPv6(src="2001:10::100", dst=ep3.ip6) / + UDP(sport=1234, dport=1234) / + Raw(b'\xa5' * 100))] + + # unknown remote EP to local EP redirected to known remote SEP + rxs = self.send_and_expect(self.pg7, p, self.pg7) + + for rx, tx in zip(rxs, p): + self.assertEqual(rx[Ether].src, self.pg7.local_mac) + self.assertEqual(rx[Ether].dst, self.pg7.remote_mac) + self.assertEqual(rx[IP].src, self.pg7.local_ip4) + self.assertEqual(rx[IP].dst, self.pg7.remote_ip4) + # this should use the programmed remote leaf TEP + self.assertEqual(rx[VXLAN].vni, 555) + self.assertEqual(rx[VXLAN].gpid, epg_221.sclass) + self.assertTrue(rx[VXLAN].flags.G) + self.assertTrue(rx[VXLAN].flags.Instance) + # redirect policy has been applied + self.assertTrue(rx[VXLAN].gpflags.A) + self.assertFalse(rx[VXLAN].gpflags.D) + rxip = rx[VXLAN][Ether].payload + txip = tx[VXLAN][Ether].payload + self.assertEqual(rxip.src, txip.src) + self.assertEqual(rxip.dst, txip.dst) + + # endpoint learnt via the parent GBP-vxlan interface + self.assertTrue(find_gbp_endpoint(self, + vx_tun_l3._sw_if_index, + ip="10.0.1.100")) + self.assertTrue(find_gbp_endpoint(self, + vx_tun_l3._sw_if_index, + ip="2001:10::100")) + + # remote SEP: it is now an unknown remote SEP and should go + # to spine proxy + sep5.remove_vpp_config() + + # remote EP (coming from spine proxy) to local EP redirected to + # known remote SEP + rxs = self.send_and_expect(self.pg7, p, self.pg7) + + for rx, tx in zip(rxs, p): + self.assertEqual(rx[Ether].src, self.pg7.local_mac) + self.assertEqual(rx[Ether].dst, self.pg7.remote_mac) + self.assertEqual(rx[IP].src, self.pg7.local_ip4) + self.assertEqual(rx[IP].dst, self.pg7.remote_ip4) + # this should use the spine proxy TEP + self.assertEqual(rx[VXLAN].vni, epg_320.bd.uu_fwd.vni) + self.assertEqual(rx[VXLAN].gpid, epg_221.sclass) + self.assertTrue(rx[VXLAN].flags.G) + self.assertTrue(rx[VXLAN].flags.Instance) + # redirect policy has been applied + self.assertTrue(rx[VXLAN].gpflags.A) + self.assertFalse(rx[VXLAN].gpflags.D) + rxip = rx[VXLAN][Ether].payload + txip = tx[VXLAN][Ether].payload + self.assertEqual(rxip.src, txip.src) + self.assertEqual(rxip.dst, txip.dst) + + # + # cleanup + # + self.pg7.unconfig_ip4() + + def test_gbp_redirect_extended(self): + """ GBP Endpoint Redirect Extended """ + + self.vapi.cli("set logging class gbp level debug") + + ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t + routed_dst_mac = "00:0c:0c:0c:0c:0c" + routed_src_mac = "00:22:bd:f8:19:ff" + + learnt = [{'mac': '00:00:11:11:11:02', + 'ip': '10.0.1.2', + 'ip6': '2001:10::2'}, + {'mac': '00:00:11:11:11:03', + 'ip': '10.0.1.3', + 'ip6': '2001:10::3'}] + + # + # IP tables + # + t4 = VppIpTable(self, 1) + t4.add_vpp_config() + t6 = VppIpTable(self, 1, True) + t6.add_vpp_config() + + # create IPv4 and IPv6 RD UU VxLAN-GBP TEP and bind them to the right + # VRF + rd_uu4 = VppVxlanGbpTunnel( + self, + self.pg7.local_ip4, + self.pg7.remote_ip4, + 114, + mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t. + VXLAN_GBP_API_TUNNEL_MODE_L3)) + rd_uu4.add_vpp_config() + VppIpInterfaceBind(self, rd_uu4, t4).add_vpp_config() + + rd_uu6 = VppVxlanGbpTunnel( + self, + self.pg7.local_ip4, + self.pg7.remote_ip4, + 115, + mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t. + VXLAN_GBP_API_TUNNEL_MODE_L3)) + rd_uu6.add_vpp_config() + VppIpInterfaceBind(self, rd_uu6, t4).add_vpp_config() + + rd1 = VppGbpRouteDomain(self, 2, 402, t4, t6, rd_uu4, rd_uu6) + rd1.add_vpp_config() + + self.loop0.set_mac(self.router_mac) + self.loop1.set_mac(self.router_mac) + self.loop2.set_mac(self.router_mac) + + # + # Bind the BVI to the RD + # + b_lo0_ip4 = VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config() + b_lo0_ip6 = VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config() + b_lo1_ip4 = VppIpInterfaceBind(self, self.loop1, t4).add_vpp_config() + b_lo1_ip6 = VppIpInterfaceBind(self, self.loop1, t6).add_vpp_config() + b_lo2_ip4 = VppIpInterfaceBind(self, self.loop2, t4).add_vpp_config() + b_lo2_ip6 = VppIpInterfaceBind(self, self.loop2, t6).add_vpp_config() + + # + # Pg7 hosts a BD's UU-fwd + # + self.pg7.config_ip4() + self.pg7.resolve_arp() + + # + # a GBP bridge domains for the EPs + # + bd1 = VppBridgeDomain(self, 1) + bd1.add_vpp_config() + gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0) + gbd1.add_vpp_config() + + bd2 = VppBridgeDomain(self, 2) + bd2.add_vpp_config() + gbd2 = VppGbpBridgeDomain(self, bd2, rd1, self.loop1) + gbd2.add_vpp_config() + + # ... and has a /32 and /128 applied + ip4_addr1 = VppIpInterfaceAddress(self, gbd1.bvi, + "10.0.0.128", 32, + bind=b_lo0_ip4).add_vpp_config() + ip6_addr1 = VppIpInterfaceAddress(self, gbd1.bvi, + "2001:10::128", 128, + bind=b_lo0_ip6).add_vpp_config() + ip4_addr2 = VppIpInterfaceAddress(self, gbd2.bvi, + "10.0.1.128", 32, + bind=b_lo1_ip4).add_vpp_config() + ip6_addr2 = VppIpInterfaceAddress(self, gbd2.bvi, + "2001:11::128", 128, + bind=b_lo1_ip6).add_vpp_config() + + # + # The Endpoint-groups + # + epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1, + None, gbd1.bvi, + "10.0.0.128", + "2001:10::128", + VppGbpEndpointRetention(60)) + epg_220.add_vpp_config() + epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2, + None, gbd2.bvi, + "10.0.1.128", + "2001:11::128", + VppGbpEndpointRetention(60)) + epg_221.add_vpp_config() + + # + # a GBP bridge domains for the SEPs + # + bd_uu3 = VppVxlanGbpTunnel(self, self.pg7.local_ip4, + self.pg7.remote_ip4, 116) + bd_uu3.add_vpp_config() + + bd3 = VppBridgeDomain(self, 3) + bd3.add_vpp_config() + gbd3 = VppGbpBridgeDomain(self, bd3, rd1, self.loop2, + bd_uu3, learn=False) + gbd3.add_vpp_config() + + ip4_addr3 = VppIpInterfaceAddress(self, gbd3.bvi, + "12.0.0.128", 32, + bind=b_lo2_ip4).add_vpp_config() + ip6_addr3 = VppIpInterfaceAddress(self, gbd3.bvi, + "4001:10::128", 128, + bind=b_lo2_ip6).add_vpp_config() + + # + # self.logger.info(self.vapi.cli("show gbp bridge")) + # self.logger.info(self.vapi.cli("show vxlan-gbp tunnel")) + # self.logger.info(self.vapi.cli("show gbp vxlan")) + # self.logger.info(self.vapi.cli("show int addr")) + # + + # + # EPGs in which the service endpoints exist + # + epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3, + None, gbd3.bvi, + "12.0.0.128", + "4001:10::128", + VppGbpEndpointRetention(60)) + epg_320.add_vpp_config() + + # + # endpoints + # + ep1 = VppGbpEndpoint(self, self.pg0, + epg_220, None, + "10.0.0.1", "11.0.0.1", + "2001:10::1", "3001:10::1") + ep1.add_vpp_config() + ep2 = VppGbpEndpoint(self, self.pg1, + epg_221, None, + "10.0.1.1", "11.0.1.1", + "2001:11::1", "3001:11::1") + ep2.add_vpp_config() + + # + # service endpoints + # + sep1 = VppGbpEndpoint(self, self.pg3, + epg_320, None, + "12.0.0.1", "13.0.0.1", + "4001:10::1", "5001:10::1") + sep2 = VppGbpEndpoint(self, self.pg4, + epg_320, None, + "12.0.0.2", "13.0.0.2", + "4001:10::2", "5001:10::2") + + # sep1 and sep2 are not added to config yet + # they are unknown for now + + # + # add routes to EPG subnets + # + VppGbpSubnet(self, rd1, "10.0.0.0", 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT + ).add_vpp_config() + VppGbpSubnet(self, rd1, "10.0.1.0", 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT + ).add_vpp_config() + + # + # Local host to known local host in different BD + # with SFC contract (source and destination are in + # one node and service endpoint in another node) + # + p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) / + IP(src=ep1.ip4, dst=ep2.ip4) / + UDP(sport=1234, dport=1234) / + Raw(b'\xa5' * 100)), + (Ether(src=ep2.mac, dst=str(self.router_mac)) / + IP(src=ep2.ip4, dst=ep1.ip4) / + UDP(sport=1234, dport=1234) / + Raw(b'\xa5' * 100))] + p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) / + IPv6(src=ep1.ip6, dst=ep2.ip6) / + UDP(sport=1234, dport=1234) / + Raw(b'\xa5' * 100)), + (Ether(src=ep2.mac, dst=str(self.router_mac)) / + IPv6(src=ep2.ip6, dst=ep1.ip6) / + UDP(sport=1234, dport=1230) / + Raw(b'\xa5' * 100))] + + # should be dropped since no contract yet + self.send_and_assert_no_replies(self.pg0, [p4[0]]) + self.send_and_assert_no_replies(self.pg0, [p6[0]]) + + # + # Add a contract with a rule to load-balance redirect via SEP1 and SEP2 + # one of the next-hops is via an EP that is not known + # + rule4 = AclRule(is_permit=1, proto=17) + rule6 = AclRule(src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17) + acl = VppAcl(self, rules=[rule4, rule6]) + acl.add_vpp_config() + + # + # test the src-ip hash mode + # + c1 = VppGbpContract( + self, 402, epg_220.sclass, epg_221.sclass, acl.acl_index, + [VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, + [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, + sep1.ip4, sep1.epg.rd)]), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, + [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, + sep1.ip6, sep1.epg.rd)])], + [ETH_P_IP, ETH_P_IPV6]) + c1.add_vpp_config() + + c2 = VppGbpContract( + self, 402, epg_221.sclass, epg_220.sclass, acl.acl_index, + [VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, + [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, + sep1.ip4, sep1.epg.rd)]), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, + [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, + sep1.ip6, sep1.epg.rd)])], + [ETH_P_IP, ETH_P_IPV6]) + c2.add_vpp_config() + + # ep1 <--> ep2 redirected through sep1 + # sep1 is unknown + # packet is redirected to sep bd and then go through sep bd UU + + rxs = self.send_and_expect(self.pg0, p4[0] * 17, self.pg7) + + for rx in rxs: + self.assertEqual(rx[Ether].src, self.pg7.local_mac) + self.assertEqual(rx[Ether].dst, self.pg7.remote_mac) + self.assertEqual(rx[IP].src, self.pg7.local_ip4) + self.assertEqual(rx[IP].dst, self.pg7.remote_ip4) + self.assertEqual(rx[VXLAN].vni, 116) + self.assertTrue(rx[VXLAN].flags.G) + self.assertTrue(rx[VXLAN].flags.Instance) + # redirect policy has been applied + self.assertTrue(rx[VXLAN].gpflags.A) + self.assertFalse(rx[VXLAN].gpflags.D) + + inner = rx[VXLAN].payload + + self.assertEqual(inner[Ether].src, routed_src_mac) + self.assertEqual(inner[Ether].dst, sep1.mac) + self.assertEqual(inner[IP].src, ep1.ip4) + self.assertEqual(inner[IP].dst, ep2.ip4) + + rxs = self.send_and_expect(self.pg1, p4[1] * 17, self.pg7) + + for rx in rxs: + self.assertEqual(rx[Ether].src, self.pg7.local_mac) + self.assertEqual(rx[Ether].dst, self.pg7.remote_mac) + self.assertEqual(rx[IP].src, self.pg7.local_ip4) + self.assertEqual(rx[IP].dst, self.pg7.remote_ip4) + self.assertEqual(rx[VXLAN].vni, 116) + self.assertTrue(rx[VXLAN].flags.G) + self.assertTrue(rx[VXLAN].flags.Instance) + # redirect policy has been applied + self.assertTrue(rx[VXLAN].gpflags.A) + self.assertFalse(rx[VXLAN].gpflags.D) + + inner = rx[VXLAN].payload + + self.assertEqual(inner[Ether].src, routed_src_mac) + self.assertEqual(inner[Ether].dst, sep1.mac) + self.assertEqual(inner[IP].src, ep2.ip4) + self.assertEqual(inner[IP].dst, ep1.ip4) + + rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7) + + for rx in rxs: + self.assertEqual(rx[Ether].src, self.pg7.local_mac) + self.assertEqual(rx[Ether].dst, self.pg7.remote_mac) + self.assertEqual(rx[IP].src, self.pg7.local_ip4) + self.assertEqual(rx[IP].dst, self.pg7.remote_ip4) + self.assertEqual(rx[VXLAN].vni, 116) + self.assertTrue(rx[VXLAN].flags.G) + self.assertTrue(rx[VXLAN].flags.Instance) + # redirect policy has been applied + inner = rx[VXLAN].payload + + self.assertEqual(inner[Ether].src, routed_src_mac) + self.assertEqual(inner[Ether].dst, sep1.mac) + self.assertEqual(inner[IPv6].src, ep1.ip6) + self.assertEqual(inner[IPv6].dst, ep2.ip6) + + rxs = self.send_and_expect(self.pg1, p6[1] * 17, self.pg7) + + for rx in rxs: + self.assertEqual(rx[Ether].src, self.pg7.local_mac) + self.assertEqual(rx[Ether].dst, self.pg7.remote_mac) + self.assertEqual(rx[IP].src, self.pg7.local_ip4) + self.assertEqual(rx[IP].dst, self.pg7.remote_ip4) + self.assertEqual(rx[VXLAN].vni, 116) + self.assertTrue(rx[VXLAN].flags.G) + self.assertTrue(rx[VXLAN].flags.Instance) + # redirect policy has been applied + self.assertTrue(rx[VXLAN].gpflags.A) + self.assertFalse(rx[VXLAN].gpflags.D) + + inner = rx[VXLAN].payload + + self.assertEqual(inner[Ether].src, routed_src_mac) + self.assertEqual(inner[Ether].dst, sep1.mac) + self.assertEqual(inner[IPv6].src, ep2.ip6) + self.assertEqual(inner[IPv6].dst, ep1.ip6) + + # configure sep1: it is now local + # packets between ep1 and ep2 are redirected locally + sep1.add_vpp_config() + + rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf) + + for rx in rxs: + self.assertEqual(rx[Ether].src, routed_src_mac) + self.assertEqual(rx[Ether].dst, sep1.mac) + self.assertEqual(rx[IP].src, ep1.ip4) + self.assertEqual(rx[IP].dst, ep2.ip4) + + rxs = self.send_and_expect(self.pg1, p6[1] * 17, sep1.itf) + + for rx in rxs: + self.assertEqual(rx[Ether].src, routed_src_mac) + self.assertEqual(rx[Ether].dst, sep1.mac) + self.assertEqual(rx[IPv6].src, ep2.ip6) + self.assertEqual(rx[IPv6].dst, ep1.ip6) + + # packet coming from the l2 spine-proxy to sep1 + p = (Ether(src=self.pg7.remote_mac, + dst=self.pg7.local_mac) / + IP(src=self.pg7.remote_ip4, + dst=self.pg7.local_ip4) / + UDP(sport=1234, dport=48879) / + VXLAN(vni=116, gpid=440, gpflags=0x08, flags=0x88) / + Ether(src=str(self.router_mac), dst=sep1.mac) / + IP(src=ep1.ip4, dst=ep2.ip4) / + UDP(sport=1234, dport=1234) / + Raw(b'\xa5' * 100)) + + rxs = self.send_and_expect(self.pg7, [p] * 17, sep1.itf) + + for rx in rxs: + self.assertEqual(rx[Ether].src, str(self.router_mac)) + self.assertEqual(rx[Ether].dst, sep1.mac) + self.assertEqual(rx[IP].src, ep1.ip4) + self.assertEqual(rx[IP].dst, ep2.ip4) + + # contract for SEP to communicate with dst EP + c3 = VppGbpContract( + self, 402, epg_320.sclass, epg_221.sclass, acl.acl_index, + [VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC)], + [ETH_P_IP, ETH_P_IPV6]) + c3.add_vpp_config() + + # temporarily remove ep2, so that ep2 is remote & unknown + ep2.remove_vpp_config() + + # packet going back from sep1 to its original dest (ep2) + # as ep2 is now unknown (see above), it must go through + # the rd UU (packet is routed) + + p1 = (Ether(src=sep1.mac, dst=self.router_mac) / + IP(src=ep1.ip4, dst=ep2.ip4) / + UDP(sport=1234, dport=1234) / + Raw(b'\xa5' * 100)) + + rxs = self.send_and_expect(self.pg3, [p1] * 17, self.pg7) + + for rx in rxs: + self.assertEqual(rx[Ether].src, self.pg7.local_mac) + self.assertEqual(rx[Ether].dst, self.pg7.remote_mac) + self.assertEqual(rx[IP].src, self.pg7.local_ip4) + self.assertEqual(rx[IP].dst, self.pg7.remote_ip4) + self.assertEqual(rx[VXLAN].vni, 114) + self.assertTrue(rx[VXLAN].flags.G) + self.assertTrue(rx[VXLAN].flags.Instance) + # redirect policy has been applied + inner = rx[VXLAN].payload + self.assertEqual(inner[Ether].src, routed_src_mac) + self.assertEqual(inner[Ether].dst, routed_dst_mac) + self.assertEqual(inner[IP].src, ep1.ip4) + self.assertEqual(inner[IP].dst, ep2.ip4) + + self.logger.info(self.vapi.cli("show bridge 3 detail")) + sep1.remove_vpp_config() + + self.logger.info(self.vapi.cli("show bridge 1 detail")) + self.logger.info(self.vapi.cli("show bridge 2 detail")) + + # re-add ep2: it is local again :) + ep2.add_vpp_config() + + # packet coming back from the remote sep through rd UU + p2 = (Ether(src=self.pg7.remote_mac, + dst=self.pg7.local_mac) / + IP(src=self.pg7.remote_ip4, + dst=self.pg7.local_ip4) / + UDP(sport=1234, dport=48879) / + VXLAN(vni=114, gpid=441, gpflags=0x09, flags=0x88) / + Ether(src=str(self.router_mac), dst=self.router_mac) / + IP(src=ep1.ip4, dst=ep2.ip4) / + UDP(sport=1234, dport=1234) / + Raw(b'\xa5' * 100)) + + rxs = self.send_and_expect(self.pg7, [p2], self.pg1) + + for rx in rxs: + self.assertEqual(rx[Ether].src, str(self.router_mac)) + self.assertEqual(rx[Ether].dst, self.pg1.remote_mac) + self.assertEqual(rx[IP].src, ep1.ip4) + self.assertEqual(rx[IP].dst, ep2.ip4) + + # + # bd_uu2.add_vpp_config() + # + + # + # cleanup + # + c1.remove_vpp_config() + c2.remove_vpp_config() + c3.remove_vpp_config() + self.pg7.unconfig_ip4() + + def test_gbp_l3_out(self): + """ GBP L3 Out """ + + ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t + self.vapi.cli("set logging class gbp level debug") + + routed_dst_mac = "00:0c:0c:0c:0c:0c" + routed_src_mac = "00:22:bd:f8:19:ff" + + # + # IP tables + # + t4 = VppIpTable(self, 1) + t4.add_vpp_config() + t6 = VppIpTable(self, 1, True) + t6.add_vpp_config() + + rd1 = VppGbpRouteDomain(self, 2, 55, t4, t6) + rd1.add_vpp_config() + + self.loop0.set_mac(self.router_mac) + + # + # Bind the BVI to the RD + # + b_ip4 = VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config() + b_ip6 = VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config() + + # + # Pg7 hosts a BD's BUM + # Pg1 some other l3 interface + # + self.pg7.config_ip4() + self.pg7.resolve_arp() + + # + # a multicast vxlan-gbp tunnel for broadcast in the BD + # + tun_bm = VppVxlanGbpTunnel(self, self.pg7.local_ip4, + "239.1.1.1", 88, + mcast_itf=self.pg7) + tun_bm.add_vpp_config() + + # + # a GBP external bridge domains for the EPs + # + bd1 = VppBridgeDomain(self, 1) + bd1.add_vpp_config() + gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, None, tun_bm) + gbd1.add_vpp_config() + + # # The Endpoint-groups in which the external endpoints exist # epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1, None, gbd1.bvi, "10.0.0.128", "2001:10::128", - VppGbpEndpointRetention(2)) + VppGbpEndpointRetention(4)) epg_220.add_vpp_config() # the BVIs have the subnets applied ... - ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 24) - ip4_addr.add_vpp_config() - ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 64) - ip6_addr.add_vpp_config() + ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", + 24, bind=b_ip4).add_vpp_config() + ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", + 64, bind=b_ip6).add_vpp_config() # ... which are L3-out subnets l3o_1 = VppGbpSubnet( @@ -3932,7 +4809,7 @@ class TestGBP(VppTestCase): p_arp = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") / Dot1Q(vlan=100) / ARP(op="who-has", - psrc=eep1.ip4.address, pdst="10.0.0.128", + psrc=eep1.ip4, pdst="10.0.0.128", hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff")) rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0) @@ -3942,7 +4819,7 @@ class TestGBP(VppTestCase): p_arp = (Ether(src=eep3.mac, dst="ff:ff:ff:ff:ff:ff") / Dot1Q(vlan=102) / ARP(op="who-has", - psrc=eep3.ip4.address, pdst="10.0.0.128", + psrc=eep3.ip4, pdst="10.0.0.128", hwsrc=eep3.mac, hwdst="ff:ff:ff:ff:ff:ff")) rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0) @@ -3954,12 +4831,12 @@ class TestGBP(VppTestCase): Dot1Q(vlan=100) / IP(src="10.0.0.1", dst="10.0.0.88") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) p6 = (Ether(src=eep1.mac, dst=str(self.router_mac)) / Dot1Q(vlan=100) / IPv6(src="2001:10::1", dst="2001:10::88") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7) @@ -3992,7 +4869,7 @@ class TestGBP(VppTestCase): Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / IP(src="10.0.0.101", dst="10.0.0.1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg7, p * 1, self.pg0) @@ -4001,7 +4878,7 @@ class TestGBP(VppTestCase): # p = (Ether(src=eep1.mac, dst=str(self.router_mac)) / Dot1Q(vlan=100) / - IP(src=eep1.ip4.address, dst="10.0.0.128") / + IP(src=eep1.ip4, dst="10.0.0.128") / ICMP(type='echo-request')) rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) @@ -4016,7 +4893,7 @@ class TestGBP(VppTestCase): # p = (Ether(src=eep1.mac, dst=eep2.mac) / Dot1Q(vlan=100) / - IP(src=eep1.ip4.address, dst=eep2.ip4.address) / + IP(src=eep1.ip4, dst=eep2.ip4) / ICMP(type='echo-request')) rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) @@ -4031,7 +4908,7 @@ class TestGBP(VppTestCase): # p = (Ether(src=eep3.mac, dst=str(self.router_mac)) / Dot1Q(vlan=102) / - IP(src=eep3.ip4.address, dst="10.0.0.128") / + IP(src=eep3.ip4, dst="10.0.0.128") / ICMP(type='echo-request')) rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) @@ -4044,7 +4921,7 @@ class TestGBP(VppTestCase): # A ip4 subnet reachable through the external EP1 # ip_220 = VppIpRoute(self, "10.220.0.0", 24, - [VppRoutePath(eep1.ip4.address, + [VppRoutePath(eep1.ip4, eep1.epg.bvi.sw_if_index)], table_id=t4.table_id) ip_220.add_vpp_config() @@ -4059,7 +4936,7 @@ class TestGBP(VppTestCase): # An ip6 subnet reachable through the external EP1 # ip6_220 = VppIpRoute(self, "10:220::", 64, - [VppRoutePath(eep1.ip6.address, + [VppRoutePath(eep1.ip6, eep1.epg.bvi.sw_if_index)], table_id=t6.table_id) ip6_220.add_vpp_config() @@ -4074,7 +4951,7 @@ class TestGBP(VppTestCase): # A subnet reachable through the external EP2 # ip_221 = VppIpRoute(self, "10.221.0.0", 24, - [VppRoutePath(eep2.ip4.address, + [VppRoutePath(eep2.ip4, eep2.epg.bvi.sw_if_index)], table_id=t4.table_id) ip_221.add_vpp_config() @@ -4099,28 +4976,31 @@ class TestGBP(VppTestCase): # # contract for the external nets to communicate # - acl = VppGbpAcl(self) - rule4 = acl.create_rule(permit_deny=1, proto=17) - rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17) - acl_index = acl.add_vpp_config([rule4, rule6]) + rule4 = AclRule(is_permit=1, proto=17) + rule6 = AclRule(src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17) + acl = VppAcl(self, rules=[rule4, rule6]) + acl.add_vpp_config() # # A contract with the wrong scope is not matched # c_44 = VppGbpContract( - self, 44, 4220, 4221, acl_index, + self, 44, 4220, 4221, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, []), - VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - [])], + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [])], [ETH_P_IP, ETH_P_IPV6]) c_44.add_vpp_config() self.send_and_assert_no_replies(self.pg0, p * 1) c1 = VppGbpContract( - self, 55, 4220, 4221, acl_index, + self, 55, 4220, 4221, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -4136,7 +5016,7 @@ class TestGBP(VppTestCase): # Contracts allowing ext-net 200 to talk with external EPs # c2 = VppGbpContract( - self, 55, 4220, 113, acl_index, + self, 55, 4220, 113, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -4148,7 +5028,7 @@ class TestGBP(VppTestCase): [ETH_P_IP, ETH_P_IPV6]) c2.add_vpp_config() c3 = VppGbpContract( - self, 55, 113, 4220, acl_index, + self, 55, 113, 4220, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -4167,7 +5047,7 @@ class TestGBP(VppTestCase): Dot1Q(vlan=100) / IP(src="10.220.0.1", dst="10.221.0.1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) @@ -4192,7 +5072,7 @@ class TestGBP(VppTestCase): Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / IP(src="10.0.0.101", dst="10.220.0.1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg7, p * 1, self.pg0) @@ -4201,9 +5081,9 @@ class TestGBP(VppTestCase): # p = (Ether(src=eep1.mac, dst=str(self.router_mac)) / Dot1Q(vlan=100) / - IP(src="10.220.0.1", dst=rep.ip4.address) / + IP(src="10.220.0.1", dst=rep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, p * 1, self.pg7) @@ -4223,7 +5103,7 @@ class TestGBP(VppTestCase): self.assertTrue(rx[VXLAN].gpflags.D) inner = rx[VXLAN].payload self.assertEqual(inner[IP].src, "10.220.0.1") - self.assertEqual(inner[IP].dst, rep.ip4.address) + self.assertEqual(inner[IP].dst, rep.ip4) # # An external subnet reachable via the remote external EP @@ -4274,7 +5154,7 @@ class TestGBP(VppTestCase): Dot1Q(vlan=100) / IP(src="10.220.0.1", dst="10.222.0.1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_assert_no_replies(self.pg0, p * 1) @@ -4282,7 +5162,7 @@ class TestGBP(VppTestCase): # Add contracts ext-nets for 220 -> 222 # c4 = VppGbpContract( - self, 55, 4220, 4222, acl_index, + self, 55, 4220, 4222, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -4301,7 +5181,7 @@ class TestGBP(VppTestCase): Dot1Q(vlan=100) / IP(src="10.220.0.1", dst="10.222.0.1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, p * 3, self.pg7) @@ -4355,12 +5235,12 @@ class TestGBP(VppTestCase): Dot1Q(vlan=100) / IP(src="10.220.0.1", dst="10.222.0.1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)), + Raw(b'\xa5' * 100)), (Ether(src=eep1.mac, dst=str(self.router_mac)) / Dot1Q(vlan=100) / IP(src="10.220.0.1", dst="10.222.0.1") / UDP(sport=1222, dport=1235) / - Raw('\xa5' * 100))] + Raw(b'\xa5' * 100))] rxs = self.send_and_expect(self.pg0, p, self.pg7) @@ -4399,12 +5279,12 @@ class TestGBP(VppTestCase): Dot1Q(vlan=100) / IPv6(src="10:220::1", dst="10:222::1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)), + Raw(b'\xa5' * 100)), (Ether(src=eep1.mac, dst=str(self.router_mac)) / Dot1Q(vlan=100) / IPv6(src="10:220::1", dst="10:222::1") / UDP(sport=7777, dport=8881) / - Raw('\xa5' * 100))] + Raw(b'\xa5' * 100))] self.logger.info(self.vapi.cli("sh ip6 fib 10:222::1")) rxs = self.send_and_expect(self.pg0, p, self.pg7) @@ -4423,7 +5303,7 @@ class TestGBP(VppTestCase): Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / IP(src="10.222.0.1", dst="10.220.0.1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg7, p * 3, self.pg0) self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1")) @@ -4439,7 +5319,7 @@ class TestGBP(VppTestCase): Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / IP(src="10.222.0.1", dst="10.222.0.2") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_assert_no_replies(self.pg7, p * 3) @@ -4450,7 +5330,7 @@ class TestGBP(VppTestCase): Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / IPv6(src="10:222::1", dst="10:222::2") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_assert_no_replies(self.pg7, p * 3) @@ -4468,9 +5348,9 @@ class TestGBP(VppTestCase): # p = (Ether(src=lep1.mac, dst=str(self.router_mac)) / Dot1Q(vlan=144) / - IP(src=lep1.ip4.address, dst="10.220.0.1") / + IP(src=lep1.ip4, dst="10.220.0.1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) @@ -4484,9 +5364,9 @@ class TestGBP(VppTestCase): # p = (Ether(src=lep1.mac, dst=str(self.router_mac)) / Dot1Q(vlan=144) / - IPv6(src=lep1.ip6.address, dst="10:220::1") / + IPv6(src=lep1.ip6, dst="10:220::1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) @@ -4499,9 +5379,9 @@ class TestGBP(VppTestCase): # ip4 and ip6 subnets that load-balance # ip_20 = VppIpRoute(self, "10.20.0.0", 24, - [VppRoutePath(eep1.ip4.address, + [VppRoutePath(eep1.ip4, eep1.epg.bvi.sw_if_index), - VppRoutePath(eep2.ip4.address, + VppRoutePath(eep2.ip4, eep2.epg.bvi.sw_if_index)], table_id=t4.table_id) ip_20.add_vpp_config() @@ -4513,9 +5393,9 @@ class TestGBP(VppTestCase): l3o_20.add_vpp_config() ip6_20 = VppIpRoute(self, "10:20::", 64, - [VppRoutePath(eep1.ip6.address, + [VppRoutePath(eep1.ip6, eep1.epg.bvi.sw_if_index), - VppRoutePath(eep2.ip6.address, + VppRoutePath(eep2.ip6, eep2.epg.bvi.sw_if_index)], table_id=t6.table_id) ip6_20.add_vpp_config() @@ -4532,14 +5412,14 @@ class TestGBP(VppTestCase): # two ip6 packets whose port are chosen so they load-balance p = [(Ether(src=lep1.mac, dst=str(self.router_mac)) / Dot1Q(vlan=144) / - IPv6(src=lep1.ip6.address, dst="10:20::1") / + IPv6(src=lep1.ip6, dst="10:20::1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)), + Raw(b'\xa5' * 100)), (Ether(src=lep1.mac, dst=str(self.router_mac)) / Dot1Q(vlan=144) / - IPv6(src=lep1.ip6.address, dst="10:20::1") / + IPv6(src=lep1.ip6, dst="10:20::1") / UDP(sport=124, dport=1230) / - Raw('\xa5' * 100))] + Raw(b'\xa5' * 100))] rxs = self.send_and_expect(self.pg0, p, self.pg0, 2) @@ -4549,14 +5429,14 @@ class TestGBP(VppTestCase): # two ip4 packets whose port are chosen so they load-balance p = [(Ether(src=lep1.mac, dst=str(self.router_mac)) / Dot1Q(vlan=144) / - IP(src=lep1.ip4.address, dst="10.20.0.1") / + IP(src=lep1.ip4, dst="10.20.0.1") / UDP(sport=1235, dport=1235) / - Raw('\xa5' * 100)), + Raw(b'\xa5' * 100)), (Ether(src=lep1.mac, dst=str(self.router_mac)) / Dot1Q(vlan=144) / - IP(src=lep1.ip4.address, dst="10.20.0.1") / + IP(src=lep1.ip4, dst="10.20.0.1") / UDP(sport=124, dport=1230) / - Raw('\xa5' * 100))] + Raw(b'\xa5' * 100))] rxs = self.send_and_expect(self.pg0, p, self.pg0, 2) @@ -4596,8 +5476,8 @@ class TestGBP(VppTestCase): # # Bind the BVI to the RD # - VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config() - VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config() + bind_l0_ip4 = VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config() + bind_l0_ip6 = VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config() # # Pg7 hosts a BD's BUM @@ -4621,12 +5501,13 @@ class TestGBP(VppTestCase): None, gbd1.bvi, "10.0.0.128", "2001:10::128", - VppGbpEndpointRetention(2)) + VppGbpEndpointRetention(4)) epg_220.add_vpp_config() # the BVIs have the subnet applied ... - ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 24) - ip4_addr.add_vpp_config() + ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, + "10.0.0.128", 24, + bind=bind_l0_ip4).add_vpp_config() # ... which is an Anonymous L3-out subnets l3o_1 = VppGbpSubnet( @@ -4710,7 +5591,7 @@ class TestGBP(VppTestCase): Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / IP(src=str(rep.ip4), dst="10.0.0.100") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg7, p * 1, self.pg0) # @@ -4788,13 +5669,14 @@ class TestGBP(VppTestCase): # # contract for the external nets to communicate # - acl = VppGbpAcl(self) - rule4 = acl.create_rule(permit_deny=1, proto=17) - rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17) - acl_index = acl.add_vpp_config([rule4, rule6]) + rule4 = AclRule(is_permit=1, proto=17) + rule6 = AclRule(src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17) + acl = VppAcl(self, rules=[rule4, rule6]) + acl.add_vpp_config() c1 = VppGbpContract( - self, 55, 4220, 4221, acl_index, + self, 55, 4220, 4221, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -4810,7 +5692,7 @@ class TestGBP(VppTestCase): # Contracts allowing ext-net 200 to talk with external EPs # c2 = VppGbpContract( - self, 55, 4220, 113, acl_index, + self, 55, 4220, 113, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -4822,7 +5704,7 @@ class TestGBP(VppTestCase): [ETH_P_IP, ETH_P_IPV6]) c2.add_vpp_config() c3 = VppGbpContract( - self, 55, 113, 4220, acl_index, + self, 55, 113, 4220, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -4841,7 +5723,7 @@ class TestGBP(VppTestCase): Dot1Q(vlan=100) / IP(src="10.220.0.1", dst="10.221.0.1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) @@ -4864,9 +5746,9 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=48879) / VXLAN(vni=444, gpid=113, flags=0x88) / Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IP(src=rep.ip4.address, dst="10.220.0.1") / + IP(src=rep.ip4, dst="10.220.0.1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg7, p * 1, self.pg0) @@ -4875,9 +5757,9 @@ class TestGBP(VppTestCase): # p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) / Dot1Q(vlan=100) / - IP(src="10.220.0.1", dst=rep.ip4.address) / + IP(src="10.220.0.1", dst=rep.ip4) / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, p * 1, self.pg7) @@ -4897,7 +5779,7 @@ class TestGBP(VppTestCase): self.assertTrue(rx[VXLAN].gpflags.D) inner = rx[VXLAN].payload self.assertEqual(inner[IP].src, "10.220.0.1") - self.assertEqual(inner[IP].dst, rep.ip4.address) + self.assertEqual(inner[IP].dst, rep.ip4) # # An external subnet reachable via the remote external EP @@ -4949,7 +5831,7 @@ class TestGBP(VppTestCase): Dot1Q(vlan=100) / IP(src="10.220.0.1", dst="10.222.0.1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_assert_no_replies(self.pg0, p * 1) @@ -4957,7 +5839,7 @@ class TestGBP(VppTestCase): # Add contracts ext-nets for 220 -> 222 # c4 = VppGbpContract( - self, 55, 4220, 4222, acl_index, + self, 55, 4220, 4222, acl.acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, @@ -4976,7 +5858,7 @@ class TestGBP(VppTestCase): Dot1Q(vlan=100) / IP(src="10.220.0.1", dst="10.222.0.1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg0, p * 3, self.pg7) @@ -5010,7 +5892,7 @@ class TestGBP(VppTestCase): Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / IP(src="10.222.0.1", dst="10.220.0.1") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_expect(self.pg7, p * 3, self.pg0) self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1")) @@ -5026,7 +5908,7 @@ class TestGBP(VppTestCase): Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / IP(src="10.222.0.1", dst="10.222.0.2") / UDP(sport=1234, dport=1234) / - Raw('\xa5' * 100)) + Raw(b'\xa5' * 100)) rxs = self.send_and_assert_no_replies(self.pg7, p * 3) @@ -5036,6 +5918,8 @@ class TestGBP(VppTestCase): self.vlan_101.set_vtr(L2_VTR_OP.L2_DISABLED) self.vlan_100.set_vtr(L2_VTR_OP.L2_DISABLED) self.pg7.unconfig_ip4() + # make sure the programmed EP is no longer learnt from DP + self.wait_for_ep_timeout(sw_if_index=rep.itf.sw_if_index, ip=rep.ip4) if __name__ == '__main__':