X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=test%2Ftest_gbp.py;h=cf9ad251d4b3eacf9c9ed964e887e2c3989adfcb;hb=fa0ac2c56;hp=68bbfe4a7c9e208ca8f0b9c72adc76eabe545e54;hpb=d40c3e652d487f0f165d5e595864c4ccd464de3b;p=vpp.git diff --git a/test/test_gbp.py b/test/test_gbp.py index 68bbfe4a7c9..cf9ad251d4b 100644 --- a/test/test_gbp.py +++ b/test/test_gbp.py @@ -1,22 +1,8 @@ #!/usr/bin/env python +from socket import AF_INET, AF_INET6 import unittest -from framework import VppTestCase, VppTestRunner -from vpp_object import VppObject -from vpp_neighbor import VppNeighbor -from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, \ - VppIpInterfaceAddress, VppIpInterfaceBind, find_route -from vpp_l2 import VppBridgeDomain, VppBridgeDomainPort, \ - VppBridgeDomainArpEntry, VppL2FibEntry, find_bridge_domain_port -from vpp_vxlan_gbp_tunnel import * -from vpp_sub_interface import VppDot1QSubint - -from vpp_ip import * -from vpp_mac import * -from vpp_papi_provider import L2_PORT_TYPE -from vpp_papi import VppEnum - from scapy.packet import Raw from scapy.layers.l2 import Ether, ARP, Dot1Q from scapy.layers.inet import IP, UDP @@ -24,18 +10,29 @@ from scapy.layers.inet6 import IPv6, ICMPv6ND_NS, ICMPv6NDOptSrcLLAddr, \ ICMPv6ND_NA from scapy.utils6 import in6_getnsma, in6_getnsmac from scapy.layers.vxlan import VXLAN - -from socket import AF_INET, AF_INET6 +from scapy.data import ETH_P_IP, ETH_P_IPV6 from scapy.utils import inet_pton, inet_ntop -from util import mactobinary + +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 +from vpp_l2 import VppBridgeDomain, VppBridgeDomainPort, \ + VppBridgeDomainArpEntry, VppL2FibEntry, find_bridge_domain_port +from vpp_sub_interface import VppDot1QSubint +from vpp_ip import VppIpAddress, VppIpPrefix +from vpp_papi import VppEnum, MACAddress from vpp_papi_provider import L2_VTR_OP +from vpp_vxlan_gbp_tunnel import find_vxlan_gbp_tunnel, INDEX_INVALID, \ + VppVxlanGbpTunnel def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None): if ip: vip = VppIpAddress(ip) if mac: - vmac = VppMacAddress(mac) + vmac = MACAddress(mac) eps = test.vapi.gbp_endpoint_dump() @@ -48,7 +45,7 @@ def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None): if vip == eip: return True if mac: - if vmac == ep.endpoint.mac: + if vmac.packed == ep.endpoint.mac: return True return False @@ -66,13 +63,9 @@ class VppGbpEndpoint(VppObject): GBP Endpoint """ - @property - def bin_mac(self): - return self.vmac.bytes - @property def mac(self): - return self.vmac.address + return str(self.vmac) @property def mac(self): @@ -118,9 +111,9 @@ class VppGbpEndpoint(VppObject): self._fip6 = VppIpAddress(fip6) if mac: - self.vmac = VppMacAddress(self.itf.remote_mac) + self.vmac = MACAddress(self.itf.remote_mac) else: - self.vmac = VppMacAddress("00:00:00:00:00:00") + self.vmac = MACAddress("00:00:00:00:00:00") self.flags = flags self.tun_src = VppIpAddress(tun_src) @@ -130,8 +123,8 @@ class VppGbpEndpoint(VppObject): res = self._test.vapi.gbp_endpoint_add( self.itf.sw_if_index, [self.ip4.encode(), self.ip6.encode()], - self.vmac.encode(), - self.epg.epg, + self.vmac.packed, + self.epg.sclass, self.flags, self.tun_src.encode(), self.tun_dst.encode()) @@ -148,7 +141,7 @@ class VppGbpEndpoint(VppObject): return "gbp-endpoint:[%d==%d:%s:%d]" % (self.handle, self.itf.sw_if_index, self.ip4.address, - self.epg.epg) + self.epg.sclass) def query_vpp_config(self): return find_gbp_endpoint(self._test, @@ -171,7 +164,7 @@ class VppGbpRecirc(VppObject): self._test.vapi.gbp_recirc_add_del( 1, self.recirc.sw_if_index, - self.epg.epg, + self.epg.sclass, self.is_ext) self._test.registry.register(self, self._test.logger) @@ -179,7 +172,7 @@ class VppGbpRecirc(VppObject): self._test.vapi.gbp_recirc_add_del( 0, self.recirc.sw_if_index, - self.epg.epg, + self.epg.sclass, self.is_ext) def __str__(self): @@ -196,6 +189,46 @@ class VppGbpRecirc(VppObject): return False +class VppGbpExtItf(VppObject): + """ + GBP ExtItfulation Interface + """ + + def __init__(self, test, itf, bd, rd): + self._test = test + self.itf = itf + self.bd = bd + self.rd = rd + + 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._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) + + def __str__(self): + return self.object_id() + + def object_id(self): + return "gbp-ext-itf:[%d]" % (self.itf.sw_if_index) + + def query_vpp_config(self): + rs = self._test.vapi.gbp_ext_itf_dump() + for r in rs: + if r.ext_itf.sw_if_index == self.itf.sw_if_index: + return True + return False + + class VppGbpSubnet(VppObject): """ GBP Subnet @@ -216,7 +249,7 @@ class VppGbpSubnet(VppObject): self.prefix.encode(), self.type, sw_if_index=self.sw_if_index if self.sw_if_index else 0xffffffff, - epg_id=self.epg if self.epg else 0xffff) + sclass=self.epg.sclass if self.epg else 0xffff) self._test.registry.register(self, self._test.logger) def remove_vpp_config(self): @@ -242,44 +275,58 @@ class VppGbpSubnet(VppObject): return False +class VppGbpEndpointRetention(object): + def __init__(self, remote_ep_timeout=0xffffffff): + self.remote_ep_timeout = remote_ep_timeout + + def encode(self): + return {'remote_ep_timeout': self.remote_ep_timeout} + + class VppGbpEndpointGroup(VppObject): """ GBP Endpoint Group """ - def __init__(self, test, epg, rd, bd, uplink, - bvi, bvi_ip4, bvi_ip6=None): + def __init__(self, test, vnid, sclass, rd, bd, uplink, + bvi, bvi_ip4, bvi_ip6=None, + retention=VppGbpEndpointRetention()): self._test = test self.uplink = uplink self.bvi = bvi self.bvi_ip4 = VppIpAddress(bvi_ip4) self.bvi_ip6 = VppIpAddress(bvi_ip6) - self.epg = epg + self.vnid = vnid self.bd = bd self.rd = rd + self.sclass = sclass + if 0 == self.sclass: + self.sclass = 0xffff + self.retention = retention def add_vpp_config(self): self._test.vapi.gbp_endpoint_group_add( - self.epg, + 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.uplink.sw_if_index if self.uplink else INDEX_INVALID, + self.retention.encode()) self._test.registry.register(self, self._test.logger) def remove_vpp_config(self): - self._test.vapi.gbp_endpoint_group_del( - self.epg) + self._test.vapi.gbp_endpoint_group_del(self.sclass) def __str__(self): return self.object_id() def object_id(self): - return "gbp-endpoint-group:[%d]" % (self.epg) + return "gbp-endpoint-group:[%d]" % (self.vnid) def query_vpp_config(self): epgs = self._test.vapi.gbp_endpoint_group_dump() for epg in epgs: - if epg.epg.epg_id == self.epg: + if epg.epg.vnid == self.vnid: return True return False @@ -289,10 +336,12 @@ class VppGbpBridgeDomain(VppObject): GBP Bridge Domain """ - def __init__(self, test, bd, bvi, uu_flood=None, learn=True): + def __init__(self, test, bd, bvi, uu_fwd=None, + bm_flood=None, learn=True): self._test = test self.bvi = bvi - self.uu_flood = uu_flood + self.uu_fwd = uu_fwd + self.bm_flood = bm_flood self.bd = bd e = VppEnum.vl_api_gbp_bridge_domain_flags_t @@ -306,7 +355,8 @@ class VppGbpBridgeDomain(VppObject): self.bd.bd_id, self.learn, self.bvi.sw_if_index, - self.uu_flood.sw_if_index if self.uu_flood else INDEX_INVALID) + 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) self._test.registry.register(self, self._test.logger) def remove_vpp_config(self): @@ -374,7 +424,7 @@ class VppGbpContractNextHop(): def encode(self): return {'ip': self.ip.encode(), - 'mac': self.mac.encode(), + 'mac': self.mac.packed, 'bd_id': self.bd.bd.bd_id, 'rd_id': self.rd.rd_id} @@ -403,12 +453,16 @@ class VppGbpContract(VppObject): GBP Contract """ - def __init__(self, test, src_epg, dst_epg, acl_index, rules=[]): + def __init__(self, test, src_epg, dst_epg, acl_index, + rules, allowed_ethertypes): self._test = test self.acl_index = acl_index self.src_epg = src_epg self.dst_epg = dst_epg self.rules = rules + self.allowed_ethertypes = allowed_ethertypes + while (len(self.allowed_ethertypes) < 16): + self.allowed_ethertypes.append(0) def add_vpp_config(self): rules = [] @@ -416,33 +470,35 @@ class VppGbpContract(VppObject): rules.append(r.encode()) self._test.vapi.gbp_contract_add_del( 1, - self.src_epg, - self.dst_epg, + self.src_epg.sclass, + self.dst_epg.sclass, self.acl_index, - rules) + rules, + self.allowed_ethertypes) self._test.registry.register(self, self._test.logger) def remove_vpp_config(self): self._test.vapi.gbp_contract_add_del( 0, - self.src_epg, - self.dst_epg, + self.src_epg.sclass, + self.dst_epg.sclass, self.acl_index, - []) + [], + self.allowed_ethertypes) def __str__(self): return self.object_id() def object_id(self): - return "gbp-contract:[%d:%s:%d]" % (self.src_epg, - self.dst_epg, + return "gbp-contract:[%d:%s:%d]" % (self.src_epg.sclass, + self.dst_epg.sclass, self.acl_index) def query_vpp_config(self): cs = self._test.vapi.gbp_contract_dump() for c in cs: - if c.contract.src_epg == self.src_epg \ - and c.contract.dst_epg == self.dst_epg: + if c.contract.sclass == self.src_epg.sclass \ + and c.contract.dclass == self.dst_epg.sclass: return True return False @@ -452,18 +508,20 @@ class VppGbpVxlanTunnel(VppInterface): GBP VXLAN tunnel """ - def __init__(self, test, vni, bd_rd_id, mode): + def __init__(self, test, vni, bd_rd_id, mode, src): super(VppGbpVxlanTunnel, self).__init__(test) self._test = test self.vni = vni self.bd_rd_id = bd_rd_id self.mode = mode + self.src = src def add_vpp_config(self): r = self._test.vapi.gbp_vxlan_tunnel_add( self.vni, self.bd_rd_id, - self.mode) + self.mode, + self.src) self.set_sw_if_index(r.sw_if_index) self._test.registry.register(self, self._test.logger) @@ -474,7 +532,7 @@ class VppGbpVxlanTunnel(VppInterface): return self.object_id() def object_id(self): - return "gbp-vxlan:%d" % (self.vni) + return "gbp-vxlan:%d" % (self.sw_if_index) def query_vpp_config(self): return find_gbp_vxlan(self._test, self.vni) @@ -490,8 +548,8 @@ class VppGbpAcl(VppObject): self.acl_index = 4294967295 def create_rule(self, is_ipv6=0, permit_deny=0, proto=-1, - s_prefix=0, s_ip='\x00\x00\x00\x00', sport_from=0, - sport_to=65535, d_prefix=0, d_ip='\x00\x00\x00\x00', + 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 @@ -514,7 +572,7 @@ class VppGbpAcl(VppObject): reply = self._test.vapi.acl_add_replace(self.acl_index, r=rules, - tag='GBPTest') + tag=b'GBPTest') self.acl_index = reply.acl_index return self.acl_index @@ -544,7 +602,7 @@ class TestGBP(VppTestCase): self.create_pg_interfaces(range(9)) self.create_loopback_interfaces(8) - self.router_mac = VppMacAddress("00:11:22:33:44:55") + self.router_mac = MACAddress("00:11:22:33:44:55") for i in self.pg_interfaces: i.admin_up() @@ -631,7 +689,7 @@ class TestGBP(VppTestCase): rx = self.send_and_expect(src, tx, dst) for r in rx: - self.assertEqual(r[Ether].src, self.router_mac.address) + self.assertEqual(r[Ether].src, str(self.router_mac)) self.assertEqual(r[Ether].dst, dst.remote_mac) self.assertEqual(r[IP].dst, dst_ip) self.assertEqual(r[IP].src, src_ip) @@ -641,7 +699,7 @@ class TestGBP(VppTestCase): rx = self.send_and_expect(src, tx, dst) for r in rx: - self.assertEqual(r[Ether].src, self.router_mac.address) + self.assertEqual(r[Ether].src, str(self.router_mac)) self.assertEqual(r[Ether].dst, dst.remote_mac) self.assertEqual(r[IPv6].dst, dst_ip) self.assertEqual(r[IPv6].src, src_ip) @@ -650,6 +708,8 @@ class TestGBP(VppTestCase): def test_gbp(self): """ Group Based Policy """ + ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t + # # Bridge Domains # @@ -691,36 +751,26 @@ class TestGBP(VppTestCase): # 3 EPGs, 2 of which share a BD. # 2 NAT EPGs, one for floating-IP subnets, the other for internet # - epgs = [VppGbpEndpointGroup(self, 220, rd0, gbd1, self.pg4, - self.loop0, - "10.0.0.128", - "2001:10::128"), - VppGbpEndpointGroup(self, 221, rd0, gbd1, self.pg5, - self.loop0, - "10.0.1.128", - "2001:10:1::128"), - VppGbpEndpointGroup(self, 222, rd0, gbd2, self.pg6, - self.loop1, - "10.0.2.128", - "2001:10:2::128"), - VppGbpEndpointGroup(self, 333, rd20, gbd20, self.pg7, - self.loop2, - "11.0.0.128", - "3001::128"), - VppGbpEndpointGroup(self, 444, rd20, gbd20, self.pg8, - self.loop2, - "11.0.0.129", - "3001::129")] - recircs = [VppGbpRecirc(self, epgs[0], - self.loop3), - VppGbpRecirc(self, epgs[1], - self.loop4), - VppGbpRecirc(self, epgs[2], - self.loop5), - VppGbpRecirc(self, epgs[3], - self.loop6, is_ext=True), - VppGbpRecirc(self, epgs[4], - self.loop7, is_ext=True)] + epgs = [VppGbpEndpointGroup(self, 220, 1220, rd0, gbd1, + self.pg4, self.loop0, + "10.0.0.128", "2001:10::128"), + VppGbpEndpointGroup(self, 221, 1221, rd0, gbd1, + self.pg5, self.loop0, + "10.0.1.128", "2001:10:1::128"), + VppGbpEndpointGroup(self, 222, 1222, rd0, gbd2, + self.pg6, self.loop1, + "10.0.2.128", "2001:10:2::128"), + VppGbpEndpointGroup(self, 333, 1333, rd20, gbd20, + self.pg7, self.loop2, + "11.0.0.128", "3001::128"), + VppGbpEndpointGroup(self, 444, 1444, rd20, gbd20, + self.pg8, self.loop2, + "11.0.0.129", "3001::129")] + recircs = [VppGbpRecirc(self, epgs[0], self.loop3), + VppGbpRecirc(self, epgs[1], self.loop4), + VppGbpRecirc(self, epgs[2], self.loop5), + VppGbpRecirc(self, epgs[3], self.loop6, is_ext=True), + VppGbpRecirc(self, epgs[4], self.loop7, is_ext=True)] epg_nat = epgs[3] recirc_nat = recircs[3] @@ -755,7 +805,7 @@ class TestGBP(VppTestCase): 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.bytes) + self.router_mac.packed) # The BVIs are NAT inside interfaces self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index, @@ -776,10 +826,10 @@ class TestGBP(VppTestCase): # add the BD ARP termination entry for BVI IP epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd, - self.router_mac.address, + str(self.router_mac), epg.bvi_ip4) epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd, - self.router_mac.address, + str(self.router_mac), epg.bvi_ip6) epg.bd_arp_ip4.add_vpp_config() epg.bd_arp_ip6.add_vpp_config() @@ -794,8 +844,6 @@ class TestGBP(VppTestCase): VppIpInterfaceBind(self, recirc.recirc, recirc.epg.rd.t6).add_vpp_config() - self.vapi.sw_interface_set_l2_emulation( - recirc.recirc.sw_if_index) self.vapi.nat44_interface_add_del_feature( recirc.recirc.sw_if_index, is_inside=0, @@ -937,13 +985,13 @@ class TestGBP(VppTestCase): # packets to non-local L3 destinations dropped # pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac, - dst=self.router_mac.address) / + dst=str(self.router_mac)) / IP(src=eps[0].ip4.address, dst="10.0.0.99") / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac, - dst=self.router_mac.address) / + dst=str(self.router_mac)) / IP(src=eps[0].ip4.address, dst="10.0.1.99") / UDP(sport=1234, dport=1234) / @@ -952,7 +1000,7 @@ class TestGBP(VppTestCase): self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * 65) pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac, - dst=self.router_mac.address) / + dst=str(self.router_mac)) / IPv6(src=eps[0].ip6.address, dst="2001:10::99") / UDP(sport=1234, dport=1234) / @@ -1080,7 +1128,7 @@ class TestGBP(VppTestCase): UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac, - dst=self.router_mac.address) / + dst=str(self.router_mac)) / IP(src=eps[0].ip4.address, dst=eps[3].ip4.address) / UDP(sport=1234, dport=1234) / @@ -1099,13 +1147,14 @@ class TestGBP(VppTestCase): rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17) acl_index = acl.add_vpp_config([rule, rule2]) c1 = VppGbpContract( - self, 220, 221, acl_index, + self, epgs[0], epgs[1], acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, []), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - [])]) + [])], + [ETH_P_IP, ETH_P_IPV6]) c1.add_vpp_config() self.send_and_expect_bridged(eps[0].itf, @@ -1118,14 +1167,14 @@ class TestGBP(VppTestCase): # contract for the return direction # c2 = VppGbpContract( - self, 221, 220, acl_index, + self, epgs[1], epgs[0], acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, []), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - [])]) - + [])], + [ETH_P_IP, ETH_P_IPV6]) c2.add_vpp_config() self.send_and_expect_bridged(eps[0].itf, @@ -1135,6 +1184,15 @@ class TestGBP(VppTestCase): pkt_inter_epg_221_to_220 * 65, eps[0].itf) + # + # the contract does not allow non-IP + # + pkt_non_ip_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac, + dst=self.pg2.remote_mac) / + ARP()) + self.send_and_assert_no_replies(eps[0].itf, + pkt_non_ip_inter_epg_220_to_221 * 17) + # # check that inter group is still disabled for the groups # not in the contract. @@ -1146,14 +1204,14 @@ class TestGBP(VppTestCase): # A uni-directional contract from EPG 220 -> 222 'L3 routed' # c3 = VppGbpContract( - self, 220, 222, acl_index, + self, epgs[0], epgs[2], acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, []), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - [])]) - + [])], + [ETH_P_IP, ETH_P_IPV6]) c3.add_vpp_config() self.logger.info(self.vapi.cli("sh gbp contract")) @@ -1161,7 +1219,7 @@ class TestGBP(VppTestCase): self.send_and_expect_routed(eps[0].itf, pkt_inter_epg_220_to_222 * 65, eps[3].itf, - self.router_mac.address) + str(self.router_mac)) # # remove both contracts, traffic stops in both directions @@ -1188,33 +1246,33 @@ class TestGBP(VppTestCase): self, rd0, "0.0.0.0", 0, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL, sw_if_index=recirc_nat.recirc.sw_if_index, - epg=epg_nat.epg) + epg=epg_nat) se2 = VppGbpSubnet( self, rd0, "11.0.0.0", 8, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL, sw_if_index=recirc_nat.recirc.sw_if_index, - epg=epg_nat.epg) + epg=epg_nat) se16 = VppGbpSubnet( self, rd0, "::", 0, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL, sw_if_index=recirc_nat.recirc.sw_if_index, - epg=epg_nat.epg) + epg=epg_nat) # in the NAT RD an external subnet via the NAT EPG's uplink se3 = VppGbpSubnet( self, rd20, "0.0.0.0", 0, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL, sw_if_index=epg_nat.uplink.sw_if_index, - epg=epg_nat.epg) + epg=epg_nat) se36 = VppGbpSubnet( self, rd20, "::", 0, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL, sw_if_index=epg_nat.uplink.sw_if_index, - epg=epg_nat.epg) + epg=epg_nat) se4 = VppGbpSubnet( self, rd20, "11.0.0.0", 8, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL, sw_if_index=epg_nat.uplink.sw_if_index, - epg=epg_nat.epg) + epg=epg_nat) se1.add_vpp_config() se2.add_vpp_config() se16.add_vpp_config() @@ -1232,7 +1290,7 @@ class TestGBP(VppTestCase): # From an EP to an outside addess: IN2OUT # pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac, - dst=self.router_mac.address) / + dst=str(self.router_mac)) / IP(src=eps[0].ip4.address, dst="1.1.1.1") / UDP(sport=1234, dport=1234) / @@ -1251,14 +1309,14 @@ class TestGBP(VppTestCase): acl_index2 = acl2.add_vpp_config([rule, rule2]) c4 = VppGbpContract( - self, 220, 333, acl_index2, + self, epgs[0], epgs[3], acl_index2, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, []), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - [])]) - + [])], + [ETH_P_IP, ETH_P_IPV6]) c4.add_vpp_config() self.send_and_expect_natted(eps[0].itf, @@ -1267,7 +1325,7 @@ class TestGBP(VppTestCase): eps[0].fip4.address) pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac, - dst=self.router_mac.address) / + dst=str(self.router_mac)) / IPv6(src=eps[0].ip6.address, dst="6001::1") / UDP(sport=1234, dport=1234) / @@ -1281,7 +1339,7 @@ class TestGBP(VppTestCase): # # From a global address to an EP: OUT2IN # - pkt_inter_epg_220_from_global = (Ether(src=self.router_mac.address, + pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac), dst=self.pg0.remote_mac) / IP(dst=eps[0].fip4.address, src="1.1.1.1") / @@ -1292,14 +1350,14 @@ class TestGBP(VppTestCase): pkt_inter_epg_220_from_global * 65) c5 = VppGbpContract( - self, 333, 220, acl_index2, + self, epgs[3], epgs[0], acl_index2, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, []), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - [])]) - + [])], + [ETH_P_IP, ETH_P_IPV6]) c5.add_vpp_config() self.send_and_expect_unnatted(self.pg7, @@ -1307,7 +1365,7 @@ class TestGBP(VppTestCase): eps[0].itf, eps[0].ip4.address) - pkt_inter_epg_220_from_global = (Ether(src=self.router_mac.address, + pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac), dst=self.pg0.remote_mac) / IPv6(dst=eps[0].fip6.address, src="6001::1") / @@ -1324,7 +1382,7 @@ class TestGBP(VppTestCase): # IN2OUT2IN # pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac, - dst=self.router_mac.address) / + dst=str(self.router_mac)) / IP(src=eps[0].ip4.address, dst=eps[1].fip4.address) / UDP(sport=1234, dport=1234) / @@ -1337,7 +1395,7 @@ class TestGBP(VppTestCase): eps[1].ip4.address) pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac, - dst=self.router_mac.address) / + dst=str(self.router_mac)) / IPv6(src=eps[0].ip6.address, dst=eps[1].fip6.address) / UDP(sport=1234, dport=1234) / @@ -1375,8 +1433,6 @@ class TestGBP(VppTestCase): is_add=0) for recirc in recircs: - self.vapi.sw_interface_set_l2_emulation( - recirc.recirc.sw_if_index, enable=0) self.vapi.nat44_interface_add_del_feature( recirc.recirc.sw_if_index, is_inside=0, @@ -1386,9 +1442,20 @@ class TestGBP(VppTestCase): is_inside=0, is_add=0) + def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None, + n_tries=100, s_time=1): + while (n_tries): + if not find_gbp_endpoint(self, sw_if_index, ip, mac): + return True + n_tries = n_tries - 1 + self.sleep(s_time) + self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac)) + return False + def test_gbp_learn_l2(self): """ GBP L2 Endpoint Learning """ + ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t learnt = [{'mac': '00:00:11:11:11:01', 'ip': '10.0.0.1', 'ip6': '2001:10::2'}, @@ -1396,12 +1463,6 @@ class TestGBP(VppTestCase): 'ip': '10.0.0.2', 'ip6': '2001:10::3'}] - # - # lower the inactive threshold so these tests pass in a - # reasonable amount of time - # - self.vapi.gbp_endpoint_learn_set_inactive_threshold(1) - # # IP tables # @@ -1427,12 +1488,20 @@ class TestGBP(VppTestCase): self.pg4.config_ip4() self.pg4.resolve_arp() + # + # Add a mcast destination VXLAN-GBP tunnel for B&M traffic + # + tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4, + "239.1.1.1", 88, + mcast_itf=self.pg4) + tun_bm.add_vpp_config() + # # a GBP bridge domain with a BVI and a UU-flood interface # bd1 = VppBridgeDomain(self, 1) bd1.add_vpp_config() - gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3) + gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3, tun_bm) gbd1.add_vpp_config() self.logger.info(self.vapi.cli("sh bridge 1 detail")) @@ -1445,15 +1514,17 @@ class TestGBP(VppTestCase): # # The Endpoint-group in which we are learning endpoints # - epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1, + epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1, None, self.loop0, "10.0.0.128", - "2001:10::128") + "2001:10::128", + VppGbpEndpointRetention(2)) epg_220.add_vpp_config() - epg_330 = VppGbpEndpointGroup(self, 330, rd1, gbd1, + epg_330 = VppGbpEndpointGroup(self, 330, 113, rd1, gbd1, None, self.loop1, "10.0.1.128", - "2001:11::128") + "2001:11::128", + VppGbpEndpointRetention(2)) epg_330.add_vpp_config() # @@ -1462,7 +1533,8 @@ class TestGBP(VppTestCase): # vx_tun_l2_1 = VppGbpVxlanTunnel( self, 99, bd1.bd_id, - VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2) + VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2, + self.pg2.local_ip4) vx_tun_l2_1.add_vpp_config() # @@ -1504,6 +1576,9 @@ class TestGBP(VppTestCase): # epg is not learnt, becasue the EPG is unknwon self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1) + # + # Learn new EPs from IP packets + # for ii, l in enumerate(learnt): # a packet with an sclass from a knwon EPG # arriving on an unknown TEP @@ -1512,7 +1587,7 @@ class TestGBP(VppTestCase): IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) / UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=220, flags=0x88) / + VXLAN(vni=99, gpid=112, flags=0x88) / Ether(src=l['mac'], dst=ep.mac) / IP(src=l['ip'], dst=ep.ip4.address) / UDP(sport=1234, dport=1234) / @@ -1541,22 +1616,105 @@ class TestGBP(VppTestCase): self.logger.info(self.vapi.cli("show gbp endpoint")) self.logger.info(self.vapi.cli("show gbp vxlan")) - self.logger.info(self.vapi.cli("show vxlan-gbp tunnel")) + self.logger.info(self.vapi.cli("show ip mfib")) # # If we sleep for the threshold time, the learnt endpoints should # age out # - self.sleep(2) for l in learnt: - self.assertFalse(find_gbp_endpoint(self, - tep1_sw_if_index, - mac=l['mac'])) + self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, + mac=l['mac']) + + # + # Learn new EPs from GARP packets received on the BD's mcast tunnel + # + for ii, l in enumerate(learnt): + # a packet with an sclass from a knwon EPG + # arriving on an unknown TEP + p = (Ether(src=self.pg2.remote_mac, + dst=self.pg2.local_mac) / + IP(src=self.pg2.remote_hosts[1].ip4, + dst="239.1.1.1") / + UDP(sport=1234, dport=48879) / + VXLAN(vni=88, gpid=112, flags=0x88) / + Ether(src=l['mac'], dst="ff:ff:ff:ff:ff:ff") / + ARP(op="who-has", + psrc=l['ip'], pdst=l['ip'], + hwsrc=l['mac'], hwdst="ff:ff:ff:ff:ff:ff")) + + rx = self.send_and_expect(self.pg4, [p], self.pg0) + + # the new TEP + tep1_sw_if_index = find_vxlan_gbp_tunnel( + self, + self.pg2.local_ip4, + self.pg2.remote_hosts[1].ip4, + 99) + self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index) + + # + # the EP is learnt via the learnt TEP + # both from its MAC and its IP + # + self.assertTrue(find_gbp_endpoint(self, + vx_tun_l2_1.sw_if_index, + mac=l['mac'])) + self.assertTrue(find_gbp_endpoint(self, + vx_tun_l2_1.sw_if_index, + ip=l['ip'])) + + # + # wait for the learnt endpoints to age out + # + for l in learnt: + self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, + mac=l['mac']) + + # + # Learn new EPs from L2 packets + # + for ii, l in enumerate(learnt): + # a packet with an sclass from a knwon EPG + # arriving on an unknown TEP + p = (Ether(src=self.pg2.remote_mac, + dst=self.pg2.local_mac) / + IP(src=self.pg2.remote_hosts[1].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) / + Raw('\xa5' * 100)) + + rx = self.send_and_expect(self.pg2, [p], self.pg0) + + # the new TEP + tep1_sw_if_index = find_vxlan_gbp_tunnel( + self, + self.pg2.local_ip4, + self.pg2.remote_hosts[1].ip4, + 99) + self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index) + + # + # the EP is learnt via the learnt TEP + # both from its MAC and its IP + # + self.assertTrue(find_gbp_endpoint(self, + vx_tun_l2_1.sw_if_index, + mac=l['mac'])) self.logger.info(self.vapi.cli("show gbp endpoint")) self.logger.info(self.vapi.cli("show gbp vxlan")) self.logger.info(self.vapi.cli("show vxlan-gbp tunnel")) + # + # wait for the learnt endpoints to age out + # + for l in learnt: + self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, + mac=l['mac']) + # # repeat. the do not learn bit is set so the EPs are not learnt # @@ -1567,7 +1725,7 @@ class TestGBP(VppTestCase): IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) / UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=220, flags=0x88, gpflags="D") / + VXLAN(vni=99, gpid=112, flags=0x88, gpflags="D") / Ether(src=l['mac'], dst=ep.mac) / IP(src=l['ip'], dst=ep.ip4.address) / UDP(sport=1234, dport=1234) / @@ -1590,7 +1748,7 @@ class TestGBP(VppTestCase): IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) / UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=220, flags=0x88) / + VXLAN(vni=99, gpid=112, flags=0x88) / Ether(src=l['mac'], dst=ep.mac) / IP(src=l['ip'], dst=ep.ip4.address) / UDP(sport=1234, dport=1234) / @@ -1619,18 +1777,16 @@ class TestGBP(VppTestCase): self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4) self.assertEqual(rx[UDP].dport, 48879) # the UDP source port is a random value for hashing - self.assertEqual(rx[VXLAN].gpid, 220) + 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.sleep(2) for l in learnt: - self.assertFalse(find_gbp_endpoint(self, - vx_tun_l2_1.sw_if_index, - mac=l['mac'])) + self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, + mac=l['mac']) # # repeat in the other EPG @@ -1644,7 +1800,7 @@ class TestGBP(VppTestCase): IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) / UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=330, flags=0x88, gpflags='A') / + VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') / Ether(src=l['mac'], dst=ep.mac) / IP(src=l['ip'], dst=ep.ip4.address) / UDP(sport=1234, dport=1234) / @@ -1677,7 +1833,7 @@ class TestGBP(VppTestCase): IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) / UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=330, flags=0x88, gpflags='A') / + VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') / Ether(src=l['mac'], dst=ep.mac) / IP(src=l['ip'], dst=ep.ip4.address) / UDP(sport=1234, dport=1234) / @@ -1697,14 +1853,14 @@ class TestGBP(VppTestCase): rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17) acl_index = acl.add_vpp_config([rule, rule2]) c1 = VppGbpContract( - self, 220, 330, acl_index, + self, epg_220, epg_330, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, []), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - [])]) - + [])], + [ETH_P_IP, ETH_P_IPV6]) c1.add_vpp_config() for l in learnt: @@ -1724,18 +1880,7 @@ class TestGBP(VppTestCase): IP(dst="10.0.0.133", src=ep.ip4.address) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) - rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_flood) - - # - # Add a mcast destination VXLAN-GBP tunnel for B&M traffic - # - tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4, - "239.1.1.1", 88, - mcast_itf=self.pg4) - tun_bm.add_vpp_config() - bp_bm = VppBridgeDomainPort(self, bd1, tun_bm, - port_type=L2_PORT_TYPE.NORMAL) - bp_bm.add_vpp_config() + rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_fwd) self.logger.info(self.vapi.cli("sh bridge 1 detail")) @@ -1745,6 +1890,18 @@ class TestGBP(VppTestCase): Raw('\xa5' * 100)) rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf) + for rx in rxs: + self.assertEqual(rx[IP].src, self.pg4.local_ip4) + self.assertEqual(rx[IP].dst, "239.1.1.1") + self.assertEqual(rx[UDP].dport, 48879) + # the UDP source port is a random value for hashing + self.assertEqual(rx[VXLAN].gpid, 112) + self.assertEqual(rx[VXLAN].vni, 88) + self.assertTrue(rx[VXLAN].flags.G) + self.assertTrue(rx[VXLAN].flags.Instance) + self.assertFalse(rx[VXLAN].gpflags.A) + self.assertFalse(rx[VXLAN].gpflags.D) + # # Check v6 Endpoints # @@ -1755,7 +1912,7 @@ class TestGBP(VppTestCase): IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) / UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=330, flags=0x88, gpflags='A') / + VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') / Ether(src=l['mac'], dst=ep.mac) / IPv6(src=l['ip6'], dst=ep.ip6.address) / UDP(sport=1234, dport=1234) / @@ -1775,11 +1932,9 @@ class TestGBP(VppTestCase): # # clean up # - self.sleep(2) for l in learnt: - self.assertFalse(find_gbp_endpoint(self, - vx_tun_l2_1.sw_if_index, - mac=l['mac'])) + self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, + mac=l['mac']) self.pg2.unconfig_ip4() self.pg3.unconfig_ip4() @@ -1791,6 +1946,7 @@ class TestGBP(VppTestCase): def test_gbp_learn_vlan_l2(self): """ GBP L2 Endpoint w/ VLANs""" + ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t learnt = [{'mac': '00:00:11:11:11:01', 'ip': '10.0.0.1', 'ip6': '2001:10::2'}, @@ -1798,12 +1954,6 @@ class TestGBP(VppTestCase): 'ip': '10.0.0.2', 'ip6': '2001:10::3'}] - # - # lower the inactive threshold so these tests pass in a - # reasonable amount of time - # - self.vapi.gbp_endpoint_learn_set_inactive_threshold(1) - # # IP tables # @@ -1830,9 +1980,9 @@ class TestGBP(VppTestCase): # vlan_11 = VppDot1QSubint(self, self.pg0, 11) vlan_11.admin_up() - self.vapi.sw_interface_set_l2_tag_rewrite(vlan_11.sw_if_index, - L2_VTR_OP.L2_POP_1, - 11) + self.vapi.l2_interface_vlan_tag_rewrite( + sw_if_index=vlan_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1, + push_dot1q=11) bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4, self.pg3.remote_ip4, 116) @@ -1859,10 +2009,11 @@ class TestGBP(VppTestCase): # # The Endpoint-group in which we are learning endpoints # - epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1, + epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1, None, self.loop0, "10.0.0.128", - "2001:10::128") + "2001:10::128", + VppGbpEndpointRetention(2)) epg_220.add_vpp_config() # @@ -1871,7 +2022,8 @@ class TestGBP(VppTestCase): # vx_tun_l2_1 = VppGbpVxlanTunnel( self, 99, bd1.bd_id, - VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2) + VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2, + self.pg2.local_ip4) vx_tun_l2_1.add_vpp_config() # @@ -1897,7 +2049,7 @@ class TestGBP(VppTestCase): IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) / UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=220, flags=0x88) / + VXLAN(vni=99, gpid=441, flags=0x88) / Ether(src=l['mac'], dst=ep.mac) / IP(src=l['ip'], dst=ep.ip4.address) / UDP(sport=1234, dport=1234) / @@ -1945,7 +2097,7 @@ class TestGBP(VppTestCase): self.assertEqual(rx[IP].dst, self.pg3.remote_ip4) self.assertEqual(rx[UDP].dport, 48879) # the UDP source port is a random value for hashing - self.assertEqual(rx[VXLAN].gpid, 220) + self.assertEqual(rx[VXLAN].gpid, 441) self.assertEqual(rx[VXLAN].vni, 116) self.assertTrue(rx[VXLAN].flags.G) self.assertTrue(rx[VXLAN].flags.Instance) @@ -1960,6 +2112,7 @@ class TestGBP(VppTestCase): self.vapi.cli("set logging class gbp 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" @@ -1970,12 +2123,6 @@ class TestGBP(VppTestCase): 'ip': '10.0.1.3', 'ip6': '2001:10::3'}] - # - # lower the inactive threshold so these tests pass in a - # reasonable amount of time - # - self.vapi.gbp_endpoint_learn_set_inactive_threshold(1) - # # IP tables # @@ -1994,7 +2141,7 @@ class TestGBP(VppTestCase): rd1 = VppGbpRouteDomain(self, 2, t4, t6, tun_ip4_uu, tun_ip6_uu) rd1.add_vpp_config() - self.loop0.set_mac(self.router_mac.address) + self.loop0.set_mac(self.router_mac) # # Bind the BVI to the RD @@ -2038,10 +2185,11 @@ class TestGBP(VppTestCase): # # The Endpoint-group in which we are learning endpoints # - epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1, + epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1, None, self.loop0, "10.0.0.128", - "2001:10::128") + "2001:10::128", + VppGbpEndpointRetention(2)) epg_220.add_vpp_config() # @@ -2050,7 +2198,8 @@ class TestGBP(VppTestCase): # vx_tun_l3 = VppGbpVxlanTunnel( self, 101, rd1.rd_id, - VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3) + VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3, + self.pg2.local_ip4) vx_tun_l3.add_vpp_config() # @@ -2074,7 +2223,7 @@ class TestGBP(VppTestCase): IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) / UDP(sport=1234, dport=48879) / - VXLAN(vni=101, gpid=220, flags=0x88) / + 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) / UDP(sport=1234, dport=1234) / @@ -2111,7 +2260,7 @@ class TestGBP(VppTestCase): self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4) self.assertEqual(rx[UDP].dport, 48879) # the UDP source port is a random value for hashing - self.assertEqual(rx[VXLAN].gpid, 220) + self.assertEqual(rx[VXLAN].gpid, 441) self.assertEqual(rx[VXLAN].vni, 101) self.assertTrue(rx[VXLAN].flags.G) self.assertTrue(rx[VXLAN].flags.Instance) @@ -2125,7 +2274,6 @@ class TestGBP(VppTestCase): self.assertEqual(inner[IP].src, ep.ip4.address) self.assertEqual(inner[IP].dst, l['ip']) - self.sleep(2) for l in learnt: self.assertFalse(find_gbp_endpoint(self, tep1_sw_if_index, @@ -2142,7 +2290,7 @@ class TestGBP(VppTestCase): IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) / UDP(sport=1234, dport=48879) / - VXLAN(vni=101, gpid=220, flags=0x88) / + 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) / UDP(sport=1234, dport=1234) / @@ -2185,7 +2333,7 @@ class TestGBP(VppTestCase): self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4) self.assertEqual(rx[UDP].dport, 48879) # the UDP source port is a random value for hashing - self.assertEqual(rx[VXLAN].gpid, 220) + self.assertEqual(rx[VXLAN].gpid, 441) self.assertEqual(rx[VXLAN].vni, 101) self.assertTrue(rx[VXLAN].flags.G) self.assertTrue(rx[VXLAN].flags.Instance) @@ -2200,11 +2348,8 @@ class TestGBP(VppTestCase): self.assertEqual(inner[IPv6].dst, l['ip6']) self.logger.info(self.vapi.cli("sh gbp endpoint")) - self.sleep(2) for l in learnt: - self.assertFalse(find_gbp_endpoint(self, - tep1_sw_if_index, - ip=l['ip'])) + self.wait_for_ep_timeout(ip=l['ip']) # # Static sends to unknown EP with no route @@ -2218,7 +2363,7 @@ class TestGBP(VppTestCase): # # Add a route to static EP's v4 and v6 subnet - # packets should be send on the v4/v6 uu=fwd interface resp. + # packets should be sent on the v4/v6 uu=fwd interface resp. # se_10_24 = VppGbpSubnet( self, rd1, "10.0.0.0", 24, @@ -2236,7 +2381,7 @@ class TestGBP(VppTestCase): self.assertEqual(rx[IP].dst, self.pg4.remote_ip4) self.assertEqual(rx[UDP].dport, 48879) # the UDP source port is a random value for hashing - self.assertEqual(rx[VXLAN].gpid, 220) + self.assertEqual(rx[VXLAN].gpid, 441) self.assertEqual(rx[VXLAN].vni, 114) self.assertTrue(rx[VXLAN].flags.G) self.assertTrue(rx[VXLAN].flags.Instance) @@ -2252,10 +2397,10 @@ class TestGBP(VppTestCase): # arriving on an unknown TEP p = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[1].ip4, + IP(src=self.pg2.remote_hosts[2].ip4, dst=self.pg2.local_ip4) / UDP(sport=1234, dport=48879) / - VXLAN(vni=101, gpid=220, flags=0x88) / + 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) / UDP(sport=1234, dport=1234) / @@ -2267,7 +2412,7 @@ class TestGBP(VppTestCase): tep1_sw_if_index = find_vxlan_gbp_tunnel( self, self.pg2.local_ip4, - self.pg2.remote_hosts[1].ip4, + self.pg2.remote_hosts[2].ip4, vx_tun_l3.vni) self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index) @@ -2283,7 +2428,7 @@ class TestGBP(VppTestCase): epg_220, None, "10.0.0.88", "11.0.0.88", "2001:10::88", "3001::88", - VppEnum.vl_api_gbp_endpoint_flags_t.REMOTE, + ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE, self.pg2.local_ip4, self.pg2.remote_hosts[1].ip4, mac=None) @@ -2296,7 +2441,7 @@ class TestGBP(VppTestCase): epg_220, None, learnt[0]['ip'], "11.0.0.101", learnt[0]['ip6'], "3001::101", - VppEnum.vl_api_gbp_endpoint_flags_t.REMOTE, + ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE, self.pg2.local_ip4, self.pg2.remote_hosts[1].ip4, mac=None) @@ -2327,7 +2472,7 @@ class TestGBP(VppTestCase): self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4) self.assertEqual(rx[UDP].dport, 48879) # the UDP source port is a random value for hashing - self.assertEqual(rx[VXLAN].gpid, 220) + self.assertEqual(rx[VXLAN].gpid, 441) self.assertEqual(rx[VXLAN].vni, 101) self.assertTrue(rx[VXLAN].flags.G) self.assertTrue(rx[VXLAN].flags.Instance) @@ -2348,30 +2493,29 @@ class TestGBP(VppTestCase): rep_88.remove_vpp_config() rep_2.remove_vpp_config() - self.logger.info(self.vapi.cli("show gbp endpoint")) - - self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address)) + self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4.address)) p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(src=ep.ip4.address, dst=rep_88.ip4.address) / + IP(src=ep.ip4.address, dst=rep_2.ip4.address) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) - rxs = self.send_and_expect(self.pg0, [p], self.pg4) + rxs = self.send_and_expect(self.pg0, [p], self.pg2) - self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4.address)) + self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address)) p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(src=ep.ip4.address, dst=rep_2.ip4.address) / + IP(src=ep.ip4.address, dst=rep_88.ip4.address) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) - rxs = self.send_and_expect(self.pg0, [p], self.pg2) + rxs = self.send_and_expect(self.pg0, [p], self.pg4) # # to appease the testcase we cannot have the registered EP stll # present (because it's DP learnt) when the TC ends so wait until # it is removed # - self.sleep(2) + self.wait_for_ep_timeout(ip=rep_88.ip4.address) + self.wait_for_ep_timeout(ip=rep_2.ip4.address) # # shutdown with learnt endpoint present @@ -2381,7 +2525,7 @@ class TestGBP(VppTestCase): IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) / UDP(sport=1234, dport=48879) / - VXLAN(vni=101, gpid=220, flags=0x88) / + 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) / UDP(sport=1234, dport=1234) / @@ -2407,6 +2551,7 @@ class TestGBP(VppTestCase): self.vapi.cli("set logging class gbp 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" @@ -2417,12 +2562,6 @@ class TestGBP(VppTestCase): 'ip': '10.0.1.3', 'ip6': '2001:10::3'}] - # - # lower the inactive threshold so these tests pass in a - # reasonable amount of time - # - self.vapi.gbp_endpoint_learn_set_inactive_threshold(1) - # # IP tables # @@ -2434,7 +2573,7 @@ class TestGBP(VppTestCase): rd1 = VppGbpRouteDomain(self, 2, t4, t6) rd1.add_vpp_config() - self.loop0.set_mac(self.router_mac.address) + self.loop0.set_mac(self.router_mac) # # Bind the BVI to the RD @@ -2474,20 +2613,23 @@ class TestGBP(VppTestCase): # # The Endpoint-groups in which we are learning endpoints # - epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1, + epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1, None, gbd1.bvi, "10.0.0.128", - "2001:10::128") + "2001:10::128", + VppGbpEndpointRetention(2)) epg_220.add_vpp_config() - epg_221 = VppGbpEndpointGroup(self, 221, rd1, gbd2, + epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2, None, gbd2.bvi, "10.0.1.128", - "2001:11::128") + "2001:11::128", + VppGbpEndpointRetention(2)) epg_221.add_vpp_config() - epg_222 = VppGbpEndpointGroup(self, 222, rd1, gbd1, + epg_222 = VppGbpEndpointGroup(self, 222, 442, rd1, gbd1, None, gbd1.bvi, "10.0.2.128", - "2001:12::128") + "2001:12::128", + VppGbpEndpointRetention(2)) epg_222.add_vpp_config() # @@ -2512,15 +2654,17 @@ class TestGBP(VppTestCase): # # EPGs in which the service endpoints exist # - epg_320 = VppGbpEndpointGroup(self, 320, rd1, gbd3, + epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3, None, gbd1.bvi, "12.0.0.128", - "4001:10::128") + "4001:10::128", + VppGbpEndpointRetention(2)) epg_320.add_vpp_config() - epg_321 = VppGbpEndpointGroup(self, 321, rd1, gbd4, + epg_321 = VppGbpEndpointGroup(self, 321, 551, rd1, gbd4, None, gbd2.bvi, "12.0.1.128", - "4001:11::128") + "4001:11::128", + VppGbpEndpointRetention(2)) epg_321.add_vpp_config() # @@ -2604,7 +2748,7 @@ class TestGBP(VppTestCase): # test the src-ip hash mode # c1 = VppGbpContract( - self, 220, 222, acl_index, + self, epg_220, epg_222, 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, @@ -2618,11 +2762,12 @@ class TestGBP(VppTestCase): [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd, sep3.ip6, sep3.epg.rd), VppGbpContractNextHop(sep4.vmac, sep4.epg.bd, - sep4.ip6, sep4.epg.rd)])]) + sep4.ip6, sep4.epg.rd)])], + [ETH_P_IP, ETH_P_IPV6]) c1.add_vpp_config() c2 = VppGbpContract( - self, 222, 220, acl_index, + self, epg_222, epg_220, 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, @@ -2636,7 +2781,8 @@ class TestGBP(VppTestCase): [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd, sep3.ip6, sep3.epg.rd), VppGbpContractNextHop(sep4.vmac, sep4.epg.bd, - sep4.ip6, sep4.epg.rd)])]) + sep4.ip6, sep4.epg.rd)])], + [ETH_P_IP, ETH_P_IPV6]) c2.add_vpp_config() # @@ -2734,7 +2880,7 @@ class TestGBP(VppTestCase): # test the symmetric hash mode # c1 = VppGbpContract( - self, 220, 222, acl_index, + self, epg_220, epg_222, 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, @@ -2748,11 +2894,12 @@ class TestGBP(VppTestCase): [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd, sep3.ip6, sep3.epg.rd), VppGbpContractNextHop(sep4.vmac, sep4.epg.bd, - sep4.ip6, sep4.epg.rd)])]) + sep4.ip6, sep4.epg.rd)])], + [ETH_P_IP, ETH_P_IPV6]) c1.add_vpp_config() c2 = VppGbpContract( - self, 222, 220, acl_index, + self, epg_222, epg_220, 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, @@ -2766,7 +2913,8 @@ class TestGBP(VppTestCase): [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd, sep3.ip6, sep3.epg.rd), VppGbpContractNextHop(sep4.vmac, sep4.epg.bd, - sep4.ip6, sep4.epg.rd)])]) + sep4.ip6, sep4.epg.rd)])], + [ETH_P_IP, ETH_P_IPV6]) c2.add_vpp_config() # @@ -2798,39 +2946,40 @@ class TestGBP(VppTestCase): # an L3 switch packet between local EPs in different EPGs # different dest ports on each so the are LB hashed differently # - p4 = [(Ether(src=ep1.mac, dst=self.router_mac.address) / + p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) / IP(src=ep1.ip4.address, dst=ep2.ip4.address) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)), - (Ether(src=ep2.mac, dst=self.router_mac.address) / + (Ether(src=ep2.mac, dst=str(self.router_mac)) / IP(src=ep2.ip4.address, dst=ep1.ip4.address) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))] - p6 = [(Ether(src=ep1.mac, dst=self.router_mac.address) / + p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) / IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)), - (Ether(src=ep2.mac, dst=self.router_mac.address) / + (Ether(src=ep2.mac, dst=str(self.router_mac)) / IPv6(src=ep2.ip6.address, dst=ep1.ip6.address) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))] c3 = VppGbpContract( - self, 220, 221, acl_index, - [VppGbpContractRule( + self, epg_220, epg_221, 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), + VppGbpContractNextHop(sep2.vmac, sep2.epg.bd, + sep2.ip4, sep2.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.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_REDIRECT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, - [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd, - sep3.ip6, sep3.epg.rd), - VppGbpContractNextHop(sep4.vmac, sep4.epg.bd, - sep4.ip6, sep4.epg.rd)])]) + [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]) c3.add_vpp_config() rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf) @@ -2846,17 +2995,19 @@ class TestGBP(VppTestCase): # vx_tun_l3 = VppGbpVxlanTunnel( self, 444, rd1.rd_id, - VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3) + VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3, + self.pg2.local_ip4) vx_tun_l3.add_vpp_config() c4 = VppGbpContract( - self, 221, 220, acl_index, + self, epg_221, epg_220, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, []), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - [])]) + [])], + [ETH_P_IP, ETH_P_IPV6]) c4.add_vpp_config() p = (Ether(src=self.pg7.remote_mac, @@ -2864,8 +3015,8 @@ class TestGBP(VppTestCase): IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) / UDP(sport=1234, dport=48879) / - VXLAN(vni=444, gpid=221, flags=0x88) / - Ether(src="00:22:22:22:22:33", dst=self.router_mac.address) / + 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) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) @@ -2882,8 +3033,8 @@ class TestGBP(VppTestCase): IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) / UDP(sport=1234, dport=48879) / - VXLAN(vni=444, gpid=221, flags=0x88) / - Ether(src="00:22:22:22:22:33", dst=self.router_mac.address) / + 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) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) @@ -2898,11 +3049,11 @@ class TestGBP(VppTestCase): # # L3 switch from local to remote EP # - p4 = [(Ether(src=ep1.mac, dst=self.router_mac.address) / + p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) / IP(src=ep1.ip4.address, dst="10.0.0.88") / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))] - p6 = [(Ether(src=ep1.mac, dst=self.router_mac.address) / + p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) / IPv6(src=ep1.ip6.address, dst="2001:10::88") / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))] @@ -2927,7 +3078,7 @@ class TestGBP(VppTestCase): # test the dst-ip hash mode # c5 = VppGbpContract( - self, 220, 221, acl_index, + self, epg_220, epg_221, 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, @@ -2941,7 +3092,8 @@ class TestGBP(VppTestCase): [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd, sep3.ip6, sep3.epg.rd), VppGbpContractNextHop(sep4.vmac, sep4.epg.bd, - sep4.ip6, sep4.epg.rd)])]) + sep4.ip6, sep4.epg.rd)])], + [ETH_P_IP, ETH_P_IPV6]) c5.add_vpp_config() rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf) @@ -2960,6 +3112,209 @@ class TestGBP(VppTestCase): self.assertEqual(rx[IPv6].src, ep1.ip6.address) self.assertEqual(rx[IPv6].dst, "2001:10::88") + # + # cleanup + # + 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 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, t4, t6) + rd1.add_vpp_config() + + self.loop0.set_mac(self.router_mac) + + # + # Bind the BVI to the RD + # + VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config() + 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, 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)) + 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() + + # ... which are L3-out subnets + l3o_1 = VppGbpSubnet( + self, rd1, "10.0.0.0", 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, + epg=epg_220) + l3o_1.add_vpp_config() + + # + # an external interface attached to the outside world and the + # external BD + # + vlan_100 = VppDot1QSubint(self, self.pg0, 100) + vlan_100.admin_up() + ext_itf = VppGbpExtItf(self, vlan_100, bd1, rd1) + ext_itf.add_vpp_config() + + # + # an unicast vxlan-gbp for inter-RD traffic + # + vx_tun_l3 = VppGbpVxlanTunnel( + self, 444, rd1.rd_id, + VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3, + self.pg2.local_ip4) + vx_tun_l3.add_vpp_config() + + # + # packets destined to unknown addresses in the BVI's subnet + # are ARP'd for + # + p4 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / + Dot1Q(vlan=100) / + IP(src="10.0.0.1", dst="10.0.0.88") / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 100)) + p6 = (Ether(src=self.pg0.remote_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)) + + rxs = self.send_and_expect(self.pg0, p4 * 1, 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, "239.1.1.1") + self.assertEqual(rx[VXLAN].vni, 88) + self.assertTrue(rx[VXLAN].flags.G) + self.assertTrue(rx[VXLAN].flags.Instance) + # policy was applied to the original IP packet + self.assertEqual(rx[VXLAN].gpid, 113) + self.assertTrue(rx[VXLAN].gpflags.A) + self.assertFalse(rx[VXLAN].gpflags.D) + + inner = rx[VXLAN].payload + + self.assertTrue(inner.haslayer(ARP)) + + # + # An external Endpoint + # + eep = VppGbpEndpoint(self, vlan_100, + epg_220, None, + "10.0.0.1", "11.0.0.1", + "2001:10::1", "3001::1", + ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL) + eep.add_vpp_config() + + # + # A remote endpoint + # + rep = VppGbpEndpoint(self, vx_tun_l3, + epg_220, None, + "10.0.0.101", "11.0.0.101", + "2001:10::101", "3001::101", + ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE, + self.pg7.local_ip4, + self.pg7.remote_ip4, + mac=None) + rep.add_vpp_config() + + # + # remote to external + # + 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=444, gpid=113, flags=0x88) / + 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)) + + rxs = self.send_and_expect(self.pg7, p * 1, self.pg0) + + # + # A subnet reachable through the external EP + # + ip_220 = VppIpRoute(self, "10.220.0.0", 24, + [VppRoutePath(eep.ip4.address, + eep.epg.bvi.sw_if_index)], + table_id=t4.table_id) + ip_220.add_vpp_config() + + l3o_220 = VppGbpSubnet( + self, rd1, "10.220.0.0", 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, + epg=epg_220) + l3o_220.add_vpp_config() + + 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=444, gpid=113, flags=0x88) / + 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)) + + rxs = self.send_and_expect(self.pg7, p * 1, self.pg0) + + # + # cleanup + # + self.pg7.unconfig_ip4() + if __name__ == '__main__': unittest.main(testRunner=VppTestRunner)