X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=blobdiff_plain;f=test%2Ftest_gbp.py;h=74eb424eb4fdf4383f7ce058cdafe126503222cb;hp=ec72981df16b45366fb7635c387a50201d297b9b;hb=8feeaff56;hpb=e1ade684eb5a7e5743abfda47488165452cc5b64 diff --git a/test/test_gbp.py b/test/test_gbp.py index ec72981df16..74eb424eb4f 100644 --- a/test/test_gbp.py +++ b/test/test_gbp.py @@ -5,7 +5,7 @@ import unittest from scapy.packet import Raw from scapy.layers.l2 import Ether, ARP, Dot1Q -from scapy.layers.inet import IP, UDP +from scapy.layers.inet import IP, UDP, ICMP from scapy.layers.inet6 import IPv6, ICMPv6ND_NS, ICMPv6NDOptSrcLLAddr, \ ICMPv6ND_NA from scapy.utils6 import in6_getnsma, in6_getnsmac @@ -19,13 +19,14 @@ 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 + VppBridgeDomainArpEntry, VppL2FibEntry, find_bridge_domain_port, VppL2Vtr 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 +from vpp_neighbor import VppNeighbor def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None): @@ -67,10 +68,6 @@ class VppGbpEndpoint(VppObject): def mac(self): return str(self.vmac) - @property - def mac(self): - return self.itf.remote_mac - @property def ip4(self): return self._ip4 @@ -124,7 +121,7 @@ class VppGbpEndpoint(VppObject): self.itf.sw_if_index, [self.ip4.encode(), self.ip6.encode()], self.vmac.packed, - self.epg.epg, + self.epg.sclass, self.flags, self.tun_src.encode(), self.tun_dst.encode()) @@ -141,7 +138,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, @@ -164,7 +161,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) @@ -172,7 +169,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): @@ -234,13 +231,13 @@ class VppGbpSubnet(VppObject): GBP Subnet """ def __init__(self, test, rd, address, address_len, - type, sw_if_index=None, epg=None): + type, sw_if_index=None, sclass=None): self._test = test self.rd_id = rd.rd_id self.prefix = VppIpPrefix(address, address_len) self.type = type self.sw_if_index = sw_if_index - self.epg = epg + self.sclass = sclass def add_vpp_config(self): self._test.vapi.gbp_subnet_add_del( @@ -249,7 +246,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.sclass if self.sclass else 0xffff) self._test.registry.register(self, self._test.logger) def remove_vpp_config(self): @@ -275,48 +272,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, sclass, 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 @@ -443,14 +450,16 @@ class VppGbpContract(VppObject): GBP Contract """ - def __init__(self, test, src_epg, dst_epg, acl_index, + def __init__(self, test, sclass, dclass, acl_index, rules, allowed_ethertypes): self._test = test self.acl_index = acl_index - self.src_epg = src_epg - self.dst_epg = dst_epg + self.sclass = sclass + self.dclass = dclass 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 = [] @@ -458,8 +467,8 @@ class VppGbpContract(VppObject): rules.append(r.encode()) self._test.vapi.gbp_contract_add_del( 1, - self.src_epg, - self.dst_epg, + self.sclass, + self.dclass, self.acl_index, rules, self.allowed_ethertypes) @@ -468,24 +477,25 @@ class VppGbpContract(VppObject): def remove_vpp_config(self): self._test.vapi.gbp_contract_add_del( 0, - self.src_epg, - self.dst_epg, + self.sclass, + self.dclass, 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.sclass, + self.dclass, 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.sclass \ + and c.contract.dclass == self.dclass: return True return False @@ -495,18 +505,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) @@ -517,7 +529,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) @@ -533,8 +545,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 @@ -557,7 +569,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 @@ -736,36 +748,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, 0, rd0, gbd1, self.pg4, - self.loop0, - "10.0.0.128", - "2001:10::128"), - VppGbpEndpointGroup(self, 221, 0, rd0, gbd1, self.pg5, - self.loop0, - "10.0.1.128", - "2001:10:1::128"), - VppGbpEndpointGroup(self, 222, 0, rd0, gbd2, self.pg6, - self.loop1, - "10.0.2.128", - "2001:10:2::128"), - VppGbpEndpointGroup(self, 333, 0, rd20, gbd20, self.pg7, - self.loop2, - "11.0.0.128", - "3001::128"), - VppGbpEndpointGroup(self, 444, 0, 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] @@ -1107,7 +1109,7 @@ class TestGBP(VppTestCase): self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1) # - # in the abscense of policy, endpoints in the different EPG + # in the absence of policy, endpoints in the different EPG # cannot communicate # pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac, @@ -1142,7 +1144,7 @@ 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].sclass, epgs[1].sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, []), @@ -1162,7 +1164,7 @@ class TestGBP(VppTestCase): # contract for the return direction # c2 = VppGbpContract( - self, 221, 220, acl_index, + self, epgs[1].sclass, epgs[0].sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, []), @@ -1199,7 +1201,7 @@ class TestGBP(VppTestCase): # A uni-directional contract from EPG 220 -> 222 'L3 routed' # c3 = VppGbpContract( - self, 220, 222, acl_index, + self, epgs[0].sclass, epgs[2].sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, []), @@ -1241,33 +1243,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) + sclass=epg_nat.sclass) 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) + sclass=epg_nat.sclass) 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) + sclass=epg_nat.sclass) # 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) + sclass=epg_nat.sclass) 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) + sclass=epg_nat.sclass) 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) + sclass=epg_nat.sclass) se1.add_vpp_config() se2.add_vpp_config() se16.add_vpp_config() @@ -1282,7 +1284,7 @@ class TestGBP(VppTestCase): eps[0].fip6)) # - # From an EP to an outside addess: IN2OUT + # From an EP to an outside address: IN2OUT # pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / @@ -1304,7 +1306,7 @@ class TestGBP(VppTestCase): acl_index2 = acl2.add_vpp_config([rule, rule2]) c4 = VppGbpContract( - self, 220, 333, acl_index2, + self, epgs[0].sclass, epgs[3].sclass, acl_index2, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, []), @@ -1345,7 +1347,7 @@ class TestGBP(VppTestCase): pkt_inter_epg_220_from_global * 65) c5 = VppGbpContract( - self, 333, 220, acl_index2, + self, epgs[3].sclass, epgs[0].sclass, acl_index2, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, []), @@ -1458,12 +1460,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(2) - # # IP tables # @@ -1518,21 +1514,24 @@ class TestGBP(VppTestCase): 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, 113, rd1, gbd1, None, self.loop1, "10.0.1.128", - "2001:11::128") + "2001:11::128", + VppGbpEndpointRetention(2)) epg_330.add_vpp_config() # # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint - # leanring enabled + # learning enabled # 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() # @@ -1547,7 +1546,7 @@ class TestGBP(VppTestCase): self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1)) - # a packet with an sclass from an unknwon EPG + # a packet with an sclass from an unknown EPG p = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) / IP(src=self.pg2.remote_hosts[0].ip4, @@ -1571,11 +1570,14 @@ class TestGBP(VppTestCase): self.pg2.remote_hosts[0].ip4, 99)) - # epg is not learnt, becasue the EPG is unknwon + # epg is not learnt, because 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 + # a packet with an sclass from a known EPG # arriving on an unknown TEP p = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) / @@ -1611,7 +1613,7 @@ 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 @@ -1621,11 +1623,100 @@ class TestGBP(VppTestCase): 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 known 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 known 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 # for l in learnt: - # a packet with an sclass from a knwon EPG + # 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[1].ip4, @@ -1648,7 +1739,7 @@ class TestGBP(VppTestCase): # repeat # for l in learnt: - # a packet with an sclass from a knwon EPG + # 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[1].ip4, @@ -1700,7 +1791,7 @@ class TestGBP(VppTestCase): # so the packet is cleared for delivery # for l in learnt: - # a packet with an sclass from a knwon EPG + # 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[1].ip4, @@ -1733,7 +1824,7 @@ class TestGBP(VppTestCase): # refresh the entries after the check for no replies above # for l in learnt: - # a packet with an sclass from a knwon EPG + # 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[1].ip4, @@ -1759,7 +1850,7 @@ 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.sclass, epg_330.sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, []), @@ -1812,7 +1903,7 @@ class TestGBP(VppTestCase): # Check v6 Endpoints # for l in learnt: - # a packet with an sclass from a knwon EPG + # 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[1].ip4, @@ -1860,12 +1951,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(2) - # # IP tables # @@ -1892,9 +1977,9 @@ class TestGBP(VppTestCase): # vlan_11 = VppDot1QSubint(self, self.pg0, 11) vlan_11.admin_up() - self.vapi.l2_interface_vlan_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) @@ -1924,16 +2009,18 @@ class TestGBP(VppTestCase): 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() # # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint - # leanring enabled + # learning enabled # 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() # @@ -1952,7 +2039,7 @@ class TestGBP(VppTestCase): # Send to the static EP # for ii, l in enumerate(learnt): - # a packet with an sclass from a knwon EPG + # a packet with an sclass from a known EPG # arriving on an unknown TEP p = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) / @@ -2033,12 +2120,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(2) - # # IP tables # @@ -2104,16 +2185,18 @@ class TestGBP(VppTestCase): 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() # # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint - # leanring enabled + # learning enabled # 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() # @@ -2130,7 +2213,7 @@ class TestGBP(VppTestCase): # learn some remote IPv4 EPs # for ii, l in enumerate(learnt): - # a packet with an sclass from a knwon EPG + # a packet with an sclass from a known EPG # arriving on an unknown TEP p = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) / @@ -2197,7 +2280,7 @@ class TestGBP(VppTestCase): # learn some remote IPv6 EPs # for ii, l in enumerate(learnt): - # a packet with an sclass from a knwon EPG + # a packet with an sclass from a known EPG # arriving on an unknown TEP p = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) / @@ -2307,7 +2390,7 @@ class TestGBP(VppTestCase): # learn some remote IPv4 EPs # for ii, l in enumerate(learnt): - # a packet with an sclass from a knwon EPG + # a packet with an sclass from a known EPG # arriving on an unknown TEP p = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) / @@ -2362,7 +2445,7 @@ class TestGBP(VppTestCase): rep_2.add_vpp_config() # - # Add a route to the leanred EP's v4 subnet + # Add a route to the learned EP's v4 subnet # packets should be send on the v4/v6 uu=fwd interface resp. # se_10_1_24 = VppGbpSubnet( @@ -2424,7 +2507,7 @@ class TestGBP(VppTestCase): rxs = self.send_and_expect(self.pg0, [p], self.pg4) # - # to appease the testcase we cannot have the registered EP stll + # to appease the testcase we cannot have the registered EP still # present (because it's DP learnt) when the TC ends so wait until # it is removed # @@ -2476,12 +2559,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(2) - # # IP tables # @@ -2536,17 +2613,20 @@ class TestGBP(VppTestCase): 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, 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, 442, rd1, gbd1, None, gbd1.bvi, "10.0.2.128", - "2001:12::128") + "2001:12::128", + VppGbpEndpointRetention(2)) epg_222.add_vpp_config() # @@ -2574,12 +2654,14 @@ class TestGBP(VppTestCase): 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, 551, rd1, gbd4, None, gbd2.bvi, "12.0.1.128", - "4001:11::128") + "4001:11::128", + VppGbpEndpointRetention(2)) epg_321.add_vpp_config() # @@ -2663,7 +2745,7 @@ class TestGBP(VppTestCase): # test the src-ip hash mode # c1 = VppGbpContract( - self, 220, 222, acl_index, + self, epg_220.sclass, epg_222.sclass, 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, @@ -2682,7 +2764,7 @@ class TestGBP(VppTestCase): c1.add_vpp_config() c2 = VppGbpContract( - self, 222, 220, acl_index, + self, epg_222.sclass, epg_220.sclass, 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, @@ -2795,7 +2877,7 @@ class TestGBP(VppTestCase): # test the symmetric hash mode # c1 = VppGbpContract( - self, 220, 222, acl_index, + self, epg_220.sclass, epg_222.sclass, 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, @@ -2814,7 +2896,7 @@ class TestGBP(VppTestCase): c1.add_vpp_config() c2 = VppGbpContract( - self, 222, 220, acl_index, + self, epg_222.sclass, epg_220.sclass, 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, @@ -2879,7 +2961,7 @@ class TestGBP(VppTestCase): Raw('\xa5' * 100))] c3 = VppGbpContract( - self, 220, 221, acl_index, + self, epg_220.sclass, epg_221.sclass, 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, @@ -2910,11 +2992,12 @@ 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.sclass, epg_220.sclass, acl_index, [VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, []), @@ -2992,7 +3075,7 @@ class TestGBP(VppTestCase): # test the dst-ip hash mode # c5 = VppGbpContract( - self, 220, 221, acl_index, + self, epg_220.sclass, epg_221.sclass, 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, @@ -3088,7 +3171,8 @@ class TestGBP(VppTestCase): epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1, None, gbd1.bvi, "10.0.0.128", - "2001:10::128") + "2001:10::128", + VppGbpEndpointRetention(2)) epg_220.add_vpp_config() # the BVIs have the subnets applied ... @@ -3101,7 +3185,7 @@ class TestGBP(VppTestCase): l3o_1 = VppGbpSubnet( self, rd1, "10.0.0.0", 24, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - epg=220) + sclass=113) l3o_1.add_vpp_config() # @@ -3110,7 +3194,12 @@ class TestGBP(VppTestCase): # vlan_100 = VppDot1QSubint(self, self.pg0, 100) vlan_100.admin_up() - ext_itf = VppGbpExtItf(self, vlan_100, bd1, rd1) + VppL2Vtr(self, vlan_100, L2_VTR_OP.L2_POP_1).add_vpp_config() + vlan_101 = VppDot1QSubint(self, self.pg0, 101) + vlan_101.admin_up() + VppL2Vtr(self, vlan_101, L2_VTR_OP.L2_POP_1).add_vpp_config() + + ext_itf = VppGbpExtItf(self, self.loop0, bd1, rd1) ext_itf.add_vpp_config() # @@ -3118,19 +3207,59 @@ 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() # - # packets destined to unkown addresses in the BVI's subnet + # External Endpoints + # + eep1 = 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) + eep1.add_vpp_config() + eep2 = VppGbpEndpoint(self, vlan_101, + epg_220, None, + "10.0.0.2", "11.0.0.2", + "2001:10::2", "3001::2", + ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL) + eep2.add_vpp_config() + + # + # A remote external 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() + + # + # ARP packet from External EPs are accepted and replied to + # + 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", + hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff")) + rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0) + + # + # 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)) / + p4 = (Ether(src=eep1.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)) / + 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) / @@ -3155,29 +3284,6 @@ class TestGBP(VppTestCase): 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 # @@ -3195,20 +3301,142 @@ class TestGBP(VppTestCase): rxs = self.send_and_expect(self.pg7, p * 1, self.pg0) # - # A subnet reachable through the external EP + # local EP pings router + # + p = (Ether(src=eep1.mac, dst=str(self.router_mac)) / + Dot1Q(vlan=100) / + IP(src=eep1.ip4.address, dst="10.0.0.128") / + ICMP(type='echo-request')) + + rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) + + for rx in rxs: + self.assertEqual(rx[Ether].src, str(self.router_mac)) + self.assertEqual(rx[Ether].dst, eep1.mac) + self.assertEqual(rx[Dot1Q].vlan, 100) + + # + # local EP pings other local EP + # + p = (Ether(src=eep1.mac, dst=eep2.mac) / + Dot1Q(vlan=100) / + IP(src=eep1.ip4.address, dst=eep2.ip4.address) / + ICMP(type='echo-request')) + + rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) + + for rx in rxs: + self.assertEqual(rx[Ether].src, eep1.mac) + self.assertEqual(rx[Ether].dst, eep2.mac) + self.assertEqual(rx[Dot1Q].vlan, 101) + + # + # A subnet reachable through the external EP1 # ip_220 = VppIpRoute(self, "10.220.0.0", 24, - [VppRoutePath(eep.ip4.address, - eep.epg.bvi.sw_if_index)], + [VppRoutePath(eep1.ip4.address, + eep1.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=220) + sclass=4220) l3o_220.add_vpp_config() + # + # A subnet reachable through the external EP2 + # + ip_221 = VppIpRoute(self, "10.221.0.0", 24, + [VppRoutePath(eep2.ip4.address, + eep2.epg.bvi.sw_if_index)], + table_id=t4.table_id) + ip_221.add_vpp_config() + + l3o_221 = VppGbpSubnet( + self, rd1, "10.221.0.0", 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, + sclass=4221) + l3o_221.add_vpp_config() + + # + # ping between hosts in remote subnets + # dropped without a contract + # + p = (Ether(src=eep1.mac, dst=str(self.router_mac)) / + Dot1Q(vlan=100) / + IP(src="10.220.0.1", dst="10.221.0.1") / + ICMP(type='echo-request')) + + rxs = self.send_and_assert_no_replies(self.pg0, p * 1) + + # + # 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]) + + c1 = VppGbpContract( + self, 4220, 4221, 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() + + # + # Contracts allowing ext-net 200 to talk with external EPs + # + c2 = VppGbpContract( + self, 4220, 113, 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() + c3 = VppGbpContract( + self, 113, 4220, 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() + + # + # ping between hosts in remote subnets + # + p = (Ether(src=eep1.mac, dst=str(self.router_mac)) / + Dot1Q(vlan=100) / + IP(src="10.220.0.1", dst="10.221.0.1") / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 100)) + + rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) + + for rx in rxs: + self.assertEqual(rx[Ether].src, str(self.router_mac)) + self.assertEqual(rx[Ether].dst, eep2.mac) + self.assertEqual(rx[Dot1Q].vlan, 101) + + # we did not learn these external hosts + self.assertFalse(find_gbp_endpoint(self, ip="10.220.0.1")) + self.assertFalse(find_gbp_endpoint(self, ip="10.221.0.1")) + + # + # from remote external EP to local external EP + # p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) / IP(src=self.pg7.remote_ip4, @@ -3222,10 +3450,153 @@ class TestGBP(VppTestCase): rxs = self.send_and_expect(self.pg7, p * 1, self.pg0) + # + # ping from an external host to the remote external EP + # + p = (Ether(src=eep1.mac, dst=str(self.router_mac)) / + Dot1Q(vlan=100) / + IP(src="10.220.0.1", dst=rep.ip4.address) / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 100)) + + rxs = self.send_and_expect(self.pg0, p * 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, self.pg7.remote_ip4) + self.assertEqual(rx[VXLAN].vni, 444) + self.assertTrue(rx[VXLAN].flags.G) + self.assertTrue(rx[VXLAN].flags.Instance) + # the sclass of the ext-net the packet came from + self.assertEqual(rx[VXLAN].gpid, 4220) + # policy was applied to the original IP packet + self.assertTrue(rx[VXLAN].gpflags.A) + # since it's an external host the reciever should not learn it + 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) + + # + # An external subnet reachable via the remote external EP + # + + # + # first the VXLAN-GBP tunnel over which it is reached + # + vx_tun_r = VppVxlanGbpTunnel( + self, self.pg7.local_ip4, + self.pg7.remote_ip4, 445, + mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t. + VXLAN_GBP_API_TUNNEL_MODE_L3)) + vx_tun_r.add_vpp_config() + VppIpInterfaceBind(self, vx_tun_r, t4).add_vpp_config() + + self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel")) + + # + # then the special adj to resolve through on that tunnel + # + n1 = VppNeighbor(self, + vx_tun_r.sw_if_index, + "00:0c:0c:0c:0c:0c", + self.pg7.remote_ip4) + n1.add_vpp_config() + + # + # the route via the adj above + # + ip_222 = VppIpRoute(self, "10.222.0.0", 24, + [VppRoutePath(self.pg7.remote_ip4, + vx_tun_r.sw_if_index)], + table_id=t4.table_id) + ip_222.add_vpp_config() + + l3o_222 = VppGbpSubnet( + self, rd1, "10.222.0.0", 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, + sclass=4222) + l3o_222.add_vpp_config() + + # + # ping between hosts in local and remote external subnets + # dropped without a contract + # + p = (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=1234, dport=1234) / + Raw('\xa5' * 100)) + + rxs = self.send_and_assert_no_replies(self.pg0, p * 1) + + # + # Add contracts ext-nets for 220 -> 222 + # + c4 = VppGbpContract( + self, 4220, 4222, 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() + + # + # ping from host in local to remote external subnets + # + p = (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=1234, dport=1234) / + Raw('\xa5' * 100)) + + rxs = self.send_and_expect(self.pg0, p * 3, 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, 445) + self.assertTrue(rx[VXLAN].flags.G) + self.assertTrue(rx[VXLAN].flags.Instance) + # the sclass of the ext-net the packet came from + self.assertEqual(rx[VXLAN].gpid, 4220) + # policy was applied to the original IP packet + self.assertTrue(rx[VXLAN].gpflags.A) + # since it's an external host the reciever should not learn it + self.assertTrue(rx[VXLAN].gpflags.D) + inner = rx[VXLAN].payload + self.assertEqual(inner[Ether].dst, "00:0c:0c:0c:0c:0c") + self.assertEqual(inner[IP].src, "10.220.0.1") + self.assertEqual(inner[IP].dst, "10.222.0.1") + + # + # ping from host in remote to local external subnets + # there's no contract for this, but the A bit is set. + # + 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=445, gpid=4222, flags=0x88, gpflags='A') / + 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)) + + rxs = self.send_and_expect(self.pg7, p * 3, self.pg0) + self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1")) + # # cleanup # self.pg7.unconfig_ip4() + vlan_100.set_vtr(L2_VTR_OP.L2_DISABLED) if __name__ == '__main__':