7 from framework import VppTestCase, VppTestRunner
8 from vpp_object import VppObject
9 from vpp_neighbor import VppNeighbor
10 from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, DpoProto
12 from scapy.packet import Raw
13 from scapy.layers.l2 import Ether, ARP
14 from scapy.layers.inet import IP, UDP
15 from scapy.layers.inet6 import IPv6, ICMPv6ND_NS, ICMPv6NDOptSrcLLAddr, \
16 ICMPv6NDOptDstLLAddr, ICMPv6ND_NA
17 from scapy.utils6 import in6_getnsma, in6_getnsmac
19 from socket import AF_INET, AF_INET6
20 from scapy.utils import inet_pton, inet_ntop
21 from util import Host, mactobinary
24 class VppGbpEndpoint(VppObject):
31 return mactobinary(self.itf.remote_mac)
35 return self.itf.remote_mac
37 def __init__(self, test, itf, epg, recirc, ip, fip, is_ip6=False):
43 self.floating_ip = fip
46 self.proto = DpoProto.DPO_PROTO_IP6
49 self.proto = DpoProto.DPO_PROTO_IP4
51 self.ip_n = inet_pton(self.af, ip)
52 self.floating_ip_n = inet_pton(self.af, fip)
54 def add_vpp_config(self):
55 self._test.vapi.gbp_endpoint_add_del(
61 self._test.registry.register(self, self._test.logger)
63 def remove_vpp_config(self):
64 self._test.vapi.gbp_endpoint_add_del(
72 return self.object_id()
75 return "gbp-endpoint;[%d:%s:%d]" % (self.itf.sw_if_index,
79 def query_vpp_config(self):
80 eps = self._test.vapi.gbp_endpoint_dump()
83 if ep.endpoint.address == self.ip_n \
84 and ep.endpoint.sw_if_index == self.itf.sw_if_index:
87 if ep.endpoint.address[:4] == self.ip_n \
88 and ep.endpoint.sw_if_index == self.itf.sw_if_index:
93 class VppGbpRecirc(VppObject):
95 GDB Recirculation Interface
98 def __init__(self, test, epg, recirc, is_ext=False):
104 def add_vpp_config(self):
105 self._test.vapi.gbp_recirc_add_del(
107 self.recirc.sw_if_index,
110 self._test.registry.register(self, self._test.logger)
112 def remove_vpp_config(self):
113 self._test.vapi.gbp_recirc_add_del(
115 self.recirc.sw_if_index,
120 return self.object_id()
123 return "gbp-recirc;[%d]" % (self.recirc.sw_if_index)
125 def query_vpp_config(self):
126 rs = self._test.vapi.gbp_recirc_dump()
128 if r.recirc.sw_if_index == self.recirc.sw_if_index:
133 class VppGbpSubnet(VppObject):
138 def __init__(self, test, table_id, address, address_len,
139 is_internal=True, is_ip6=False,
140 sw_if_index=None, epg=None):
142 self.table_id = table_id
143 self.address = address
144 self.address_len = address_len
147 self.address_n = inet_pton(AF_INET6, address)
149 self.address_n = inet_pton(AF_INET, address)
150 self.is_internal = is_internal
151 self.sw_if_index = sw_if_index
154 def add_vpp_config(self):
155 self._test.vapi.gbp_subnet_add_del(
161 sw_if_index=self.sw_if_index if self.sw_if_index else 0xffffffff,
162 epg_id=self.epg if self.epg else 0xffffffff,
164 self._test.registry.register(self, self._test.logger)
166 def remove_vpp_config(self):
167 self._test.vapi.gbp_subnet_add_del(
176 return self.object_id()
179 return "gbp-subnet;[%d:%s/%d]" % (self.table_id,
183 def query_vpp_config(self):
184 ss = self._test.vapi.gbp_subnet_dump()
186 if s.subnet.table_id == self.table_id and \
187 s.subnet.address_length == self.address_len:
189 if s.subnet.address == self.address_n:
192 if s.subnet.address[:4] == self.address_n:
197 class VppGbpEndpointGroup(VppObject):
202 def __init__(self, test, epg, rd, bd, uplink,
203 bvi, bvi_ip4, bvi_ip6=None):
207 self.bvi_ip4 = bvi_ip4
208 self.bvi_ip4_n = inet_pton(AF_INET, bvi_ip4)
209 self.bvi_ip6 = bvi_ip6
210 self.bvi_ip6_n = inet_pton(AF_INET6, bvi_ip6)
215 def add_vpp_config(self):
216 self._test.vapi.gbp_endpoint_group_add_del(
222 self.uplink.sw_if_index)
223 self._test.registry.register(self, self._test.logger)
225 def remove_vpp_config(self):
226 self._test.vapi.gbp_endpoint_group_add_del(
232 self.uplink.sw_if_index)
235 return self.object_id()
238 return "gbp-endpoint-group;[%d]" % (self.epg)
240 def query_vpp_config(self):
241 epgs = self._test.vapi.gbp_endpoint_group_dump()
243 if epg.epg.epg_id == self.epg:
248 class VppGbpContract(VppObject):
253 def __init__(self, test, src_epg, dst_epg, acl_index):
255 self.acl_index = acl_index
256 self.src_epg = src_epg
257 self.dst_epg = dst_epg
259 def add_vpp_config(self):
260 self._test.vapi.gbp_contract_add_del(
265 self._test.registry.register(self, self._test.logger)
267 def remove_vpp_config(self):
268 self._test.vapi.gbp_contract_add_del(
275 return self.object_id()
278 return "gbp-contract;[%d:%s:%d]" % (self.src_epg,
282 def query_vpp_config(self):
283 cs = self._test.vapi.gbp_contract_dump()
285 if c.contract.src_epg == self.src_epg \
286 and c.contract.dst_epg == self.dst_epg:
291 class TestGBP(VppTestCase):
292 """ GBP Test Case """
295 super(TestGBP, self).setUp()
297 self.create_pg_interfaces(range(9))
298 self.create_loopback_interfaces(range(9))
300 self.router_mac = "00:11:22:33:44:55"
302 for i in self.pg_interfaces:
304 for i in self.lo_interfaces:
306 self.vapi.sw_interface_set_mac_address(
308 mactobinary(self.router_mac))
311 for i in self.pg_interfaces:
314 super(TestGBP, self).tearDown()
316 def send_and_expect_bridged(self, src, tx, dst):
317 rx = self.send_and_expect(src, tx, dst)
320 self.assertEqual(r[Ether].src, tx[0][Ether].src)
321 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
322 self.assertEqual(r[IP].src, tx[0][IP].src)
323 self.assertEqual(r[IP].dst, tx[0][IP].dst)
326 def send_and_expect_bridged6(self, src, tx, dst):
327 rx = self.send_and_expect(src, tx, dst)
330 self.assertEqual(r[Ether].src, tx[0][Ether].src)
331 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
332 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
333 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
336 def send_and_expect_routed(self, src, tx, dst, src_mac):
337 rx = self.send_and_expect(src, tx, dst)
340 self.assertEqual(r[Ether].src, src_mac)
341 self.assertEqual(r[Ether].dst, dst.remote_mac)
342 self.assertEqual(r[IP].src, tx[0][IP].src)
343 self.assertEqual(r[IP].dst, tx[0][IP].dst)
346 def send_and_expect_natted(self, src, tx, dst, src_ip):
347 rx = self.send_and_expect(src, tx, dst)
350 self.assertEqual(r[Ether].src, tx[0][Ether].src)
351 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
352 self.assertEqual(r[IP].src, src_ip)
353 self.assertEqual(r[IP].dst, tx[0][IP].dst)
356 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
357 rx = self.send_and_expect(src, tx, dst)
360 self.assertEqual(r[Ether].src, tx[0][Ether].src)
361 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
362 self.assertEqual(r[IP].dst, dst_ip)
363 self.assertEqual(r[IP].src, tx[0][IP].src)
366 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
367 rx = self.send_and_expect(src, tx, dst)
370 self.assertEqual(r[Ether].src, self.router_mac)
371 self.assertEqual(r[Ether].dst, dst.remote_mac)
372 self.assertEqual(r[IP].dst, dst_ip)
373 self.assertEqual(r[IP].src, src_ip)
377 """ Group Based Policy """
379 nat_table = VppIpTable(self, 20)
380 nat_table.add_vpp_config()
385 self.vapi.bridge_domain_add_del(1, flood=1, uu_flood=1, forward=1,
386 learn=0, arp_term=1, is_add=1)
387 self.vapi.bridge_domain_add_del(2, flood=1, uu_flood=1, forward=1,
388 learn=0, arp_term=1, is_add=1)
389 self.vapi.bridge_domain_add_del(20, flood=1, uu_flood=1, forward=1,
390 learn=0, arp_term=1, is_add=1)
393 # 3 EPGs, 2 of which share a BD.
397 epgs.append(VppGbpEndpointGroup(self, 220, 0, 1, self.pg4,
401 recircs.append(VppGbpRecirc(self, epgs[0],
403 epgs.append(VppGbpEndpointGroup(self, 221, 0, 1, self.pg5,
407 recircs.append(VppGbpRecirc(self, epgs[1],
409 epgs.append(VppGbpEndpointGroup(self, 222, 0, 2, self.pg6,
413 recircs.append(VppGbpRecirc(self, epgs[2],
417 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
419 epgs.append(VppGbpEndpointGroup(self, 333, 20, 20, self.pg7,
423 recircs.append(VppGbpRecirc(self, epgs[3],
424 self.loop6, is_ext=True))
425 epgs.append(VppGbpEndpointGroup(self, 444, 20, 20, self.pg8,
429 recircs.append(VppGbpRecirc(self, epgs[4],
430 self.loop8, is_ext=True))
433 recirc_nat = recircs[3]
436 # 4 end-points, 2 in the same subnet, 3 in the same BD
439 eps.append(VppGbpEndpoint(self, self.pg0,
443 eps.append(VppGbpEndpoint(self, self.pg1,
447 eps.append(VppGbpEndpoint(self, self.pg2,
451 eps.append(VppGbpEndpoint(self, self.pg3,
455 eps.append(VppGbpEndpoint(self, self.pg0,
460 eps.append(VppGbpEndpoint(self, self.pg1,
465 eps.append(VppGbpEndpoint(self, self.pg2,
470 eps.append(VppGbpEndpoint(self, self.pg3,
477 # Config related to each of the EPGs
480 # IP config on the BVI interfaces
481 if epg != epgs[1] and epg != epgs[4]:
482 epg.bvi.set_table_ip4(epg.rd)
483 epg.bvi.set_table_ip6(epg.rd)
485 # The BVIs are NAT inside interfaces
486 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
489 # self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
493 self.vapi.sw_interface_add_del_address(epg.bvi.sw_if_index,
496 self.vapi.sw_interface_add_del_address(epg.bvi.sw_if_index,
501 # EPG uplink interfaces in the BD
502 epg.uplink.set_table_ip4(epg.rd)
503 self.vapi.sw_interface_set_l2_bridge(epg.uplink.sw_if_index,
506 # add the BD ARP termination entry for BVI IP
507 self.vapi.bd_ip_mac_add_del(bd_id=epg.bd,
508 mac=mactobinary(self.router_mac),
512 self.vapi.bd_ip_mac_add_del(bd_id=epg.bd,
513 mac=mactobinary(self.router_mac),
518 # epg[1] shares the same BVI to epg[0]
519 if epg != epgs[1] and epg != epgs[4]:
521 self.vapi.sw_interface_set_l2_bridge(epg.bvi.sw_if_index,
525 self.vapi.l2fib_add_del(self.router_mac,
533 for recirc in recircs:
534 # EPG's ingress recirculation interface maps to its RD
535 recirc.recirc.set_table_ip4(recirc.epg.rd)
537 # in the bridge to allow DVR. L2 emulation to punt to L3
538 self.vapi.sw_interface_set_l2_bridge(recirc.recirc.sw_if_index,
540 self.vapi.sw_interface_set_l2_emulation(
541 recirc.recirc.sw_if_index)
544 # recirc interfaces on NAT EPGs are outside and an
546 self.vapi.nat44_interface_add_del_output_feature(
547 recirc.recirc.sw_if_index,
551 self.vapi.nat44_interface_add_del_feature(
552 recirc.recirc.sw_if_index,
555 # self.vapi.nat66_add_del_interface(
556 # recirc.recirc.sw_if_index,
560 recirc.add_vpp_config()
565 self.pg_enable_capture(self.pg_interfaces)
568 # routes to the endpoints. We need these since there are no
569 # adj-fibs due to the fact the the BVI address has /32 and
570 # the subnet is not attached.
572 r = VppIpRoute(self, ep.ip, 32,
574 ep.epg.bvi.sw_if_index,
581 # ARP entries for the endpoints
583 a = VppNeighbor(self,
584 ep.epg.bvi.sw_if_index,
590 # add each EP itf to the its BD
591 self.vapi.sw_interface_set_l2_bridge(ep.itf.sw_if_index,
594 # add the BD ARP termination entry
595 self.vapi.bd_ip_mac_add_del(bd_id=ep.epg.bd,
602 self.vapi.l2fib_add_del(ep.mac,
607 # Add static mappings for each EP from the 10/8 to 11/8 network
609 self.vapi.nat44_add_del_static_mapping(ep.ip_n,
614 # self.vapi.nat66_add_del_static_mapping(ep.ip_n,
621 # ... results in a Gratuitous ARP/ND on the EPG's uplink
622 rx = ep.epg.uplink.get_capture(1, timeout=0.2)
625 self.assertTrue(rx[0].haslayer(ICMPv6ND_NA))
626 self.assertEqual(rx[0][ICMPv6ND_NA].tgt, ep.ip)
628 self.assertTrue(rx[0].haslayer(ARP))
629 self.assertEqual(rx[0][ARP].psrc, ep.ip)
630 self.assertEqual(rx[0][ARP].pdst, ep.ip)
632 # add the BD ARP termination entry for floating IP
633 self.vapi.bd_ip_mac_add_del(bd_id=epg_nat.bd,
639 # floating IPs route via EPG recirc
640 r = VppIpRoute(self, ep.floating_ip, 32,
641 [VppRoutePath(ep.floating_ip,
642 ep.recirc.recirc.sw_if_index,
650 # L2 FIB entries in the NAT EPG BD to bridge the packets from
651 # the outside direct to the internal EPG
652 self.vapi.l2fib_add_del(ep.mac,
654 ep.recirc.recirc.sw_if_index,
658 # ARP packets for unknown IP are flooded
660 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
661 src=self.pg0.remote_mac) /
663 hwdst="ff:ff:ff:ff:ff:ff",
664 hwsrc=self.pg0.remote_mac,
665 pdst=epgs[0].bvi_ip4,
668 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
671 # ARP/ND packets get a response
673 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
674 src=self.pg0.remote_mac) /
676 hwdst="ff:ff:ff:ff:ff:ff",
677 hwsrc=self.pg0.remote_mac,
678 pdst=epgs[0].bvi_ip4,
681 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
683 nsma = in6_getnsma(inet_pton(AF_INET6, eps[4].ip))
684 d = inet_ntop(AF_INET6, nsma)
685 pkt_nd = (Ether(dst=in6_getnsmac(nsma)) /
686 IPv6(dst=d, src=eps[4].ip) /
687 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6) /
688 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
689 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
692 # broadcast packets are flooded
694 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
695 src=self.pg0.remote_mac) /
696 IP(src=eps[0].ip, dst="232.1.1.1") /
697 UDP(sport=1234, dport=1234) /
700 self.vapi.cli("clear trace")
701 self.pg0.add_stream(pkt_bcast)
703 self.pg_enable_capture(self.pg_interfaces)
706 rxd = eps[1].itf.get_capture(1)
707 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
708 rxd = epgs[0].uplink.get_capture(1)
709 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
712 # packets to non-local L3 destinations dropped
714 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
715 dst=self.router_mac) /
716 IP(src=eps[0].ip, dst="10.0.0.99") /
717 UDP(sport=1234, dport=1234) /
719 pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
720 dst=self.router_mac) /
721 IP(src=eps[0].ip, dst="10.0.1.99") /
722 UDP(sport=1234, dport=1234) /
725 self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * 65)
727 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
728 dst=self.router_mac) /
729 IPv6(src=eps[4].ip, dst="2001:10::99") /
730 UDP(sport=1234, dport=1234) /
732 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * 65)
735 # Add the subnet routes
737 s41 = VppGbpSubnet(self, 0, "10.0.0.0", 24)
738 s42 = VppGbpSubnet(self, 0, "10.0.1.0", 24)
739 s43 = VppGbpSubnet(self, 0, "10.0.2.0", 24)
743 s61 = VppGbpSubnet(self, 0, "2001:10::1", 64, is_ip6=True)
744 s62 = VppGbpSubnet(self, 0, "2001:10:1::1", 64, is_ip6=True)
745 s63 = VppGbpSubnet(self, 0, "2001:10:2::1", 64, is_ip6=True)
750 self.send_and_expect_bridged(self.pg0,
751 pkt_intra_epg_220_ip4 * 65,
753 self.send_and_expect_bridged(self.pg3,
754 pkt_inter_epg_222_ip4 * 65,
756 self.send_and_expect_bridged6(self.pg3,
757 pkt_inter_epg_222_ip6 * 65,
760 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
761 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
762 self.logger.info(self.vapi.cli("sh gbp endpoint"))
763 self.logger.info(self.vapi.cli("sh gbp recirc"))
764 self.logger.info(self.vapi.cli("sh int"))
765 self.logger.info(self.vapi.cli("sh int addr"))
766 self.logger.info(self.vapi.cli("sh int feat loop6"))
767 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
768 self.logger.info(self.vapi.cli("sh int feat loop3"))
771 # Packet destined to unknown unicast is sent on the epg uplink ...
773 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
774 dst="00:00:00:33:44:55") /
775 IP(src=eps[0].ip, dst="10.0.0.99") /
776 UDP(sport=1234, dport=1234) /
779 self.send_and_expect_bridged(self.pg0,
780 pkt_intra_epg_220_to_uplink * 65,
782 # ... and nowhere else
783 self.pg1.get_capture(0, timeout=0.1)
784 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
786 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
787 dst="00:00:00:33:44:66") /
788 IP(src=eps[0].ip, dst="10.0.0.99") /
789 UDP(sport=1234, dport=1234) /
792 self.send_and_expect_bridged(self.pg2,
793 pkt_intra_epg_221_to_uplink * 65,
797 # Packets from the uplink are forwarded in the absence of a contract
799 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
800 dst=self.pg0.remote_mac) /
801 IP(src=eps[0].ip, dst="10.0.0.99") /
802 UDP(sport=1234, dport=1234) /
805 self.send_and_expect_bridged(self.pg4,
806 pkt_intra_epg_220_from_uplink * 65,
810 # in the absence of policy, endpoints in the same EPG
813 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
814 dst=self.pg1.remote_mac) /
815 IP(src=eps[0].ip, dst=eps[1].ip) /
816 UDP(sport=1234, dport=1234) /
819 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
822 # in the abscense of policy, endpoints in the different EPG
825 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
826 dst=self.pg2.remote_mac) /
827 IP(src=eps[0].ip, dst=eps[2].ip) /
828 UDP(sport=1234, dport=1234) /
830 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
831 dst=self.pg0.remote_mac) /
832 IP(src=eps[2].ip, dst=eps[0].ip) /
833 UDP(sport=1234, dport=1234) /
835 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
836 dst=self.router_mac) /
837 IP(src=eps[0].ip, dst=eps[3].ip) /
838 UDP(sport=1234, dport=1234) /
841 self.send_and_assert_no_replies(self.pg0,
842 pkt_inter_epg_220_to_221 * 65)
843 self.send_and_assert_no_replies(self.pg0,
844 pkt_inter_epg_220_to_222 * 65)
847 # A uni-directional contract from EPG 220 -> 221
849 c1 = VppGbpContract(self, 220, 221, 0)
852 self.send_and_expect_bridged(self.pg0,
853 pkt_inter_epg_220_to_221 * 65,
855 self.send_and_assert_no_replies(self.pg0,
856 pkt_inter_epg_220_to_222 * 65)
859 # contract for the return direction
861 c2 = VppGbpContract(self, 221, 220, 0)
864 self.send_and_expect_bridged(self.pg0,
865 pkt_inter_epg_220_to_221 * 65,
867 self.send_and_expect_bridged(self.pg2,
868 pkt_inter_epg_221_to_220 * 65,
872 # check that inter group is still disabled for the groups
873 # not in the contract.
875 self.send_and_assert_no_replies(self.pg0,
876 pkt_inter_epg_220_to_222 * 65)
879 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
881 c3 = VppGbpContract(self, 220, 222, 0)
884 self.logger.info(self.vapi.cli("sh gbp contract"))
886 self.send_and_expect_routed(self.pg0,
887 pkt_inter_epg_220_to_222 * 65,
892 # remove both contracts, traffic stops in both directions
894 c2.remove_vpp_config()
895 c1.remove_vpp_config()
896 c3.remove_vpp_config()
898 self.send_and_assert_no_replies(self.pg2,
899 pkt_inter_epg_221_to_220 * 65)
900 self.send_and_assert_no_replies(self.pg0,
901 pkt_inter_epg_220_to_221 * 65)
902 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
905 # EPs to the outside world
908 # in the EP's RD an external subnet via the NAT EPG's recirc
909 se1 = VppGbpSubnet(self, 0, "0.0.0.0", 0,
911 sw_if_index=recirc_nat.recirc.sw_if_index,
914 se2 = VppGbpSubnet(self, 0, "11.0.0.0", 8,
916 sw_if_index=recirc_nat.recirc.sw_if_index,
919 # in the NAT RD an external subnet via the NAT EPG's uplink
920 se3 = VppGbpSubnet(self, 20, "0.0.0.0", 0,
922 sw_if_index=epg_nat.uplink.sw_if_index,
924 se4 = VppGbpSubnet(self, 20, "11.0.0.0", 8,
926 sw_if_index=epg_nat.uplink.sw_if_index,
931 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
932 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
934 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
935 dst=self.router_mac) /
936 IP(src=eps[0].ip, dst="1.1.1.1") /
937 UDP(sport=1234, dport=1234) /
941 self.send_and_assert_no_replies(self.pg0,
942 pkt_inter_epg_220_to_global * 65)
944 c4 = VppGbpContract(self, 220, 333, 0)
947 self.send_and_expect_natted(self.pg0,
948 pkt_inter_epg_220_to_global * 65,
952 pkt_inter_epg_220_from_global = (Ether(src=self.router_mac,
953 dst=self.pg0.remote_mac) /
954 IP(dst=eps[0].floating_ip,
956 UDP(sport=1234, dport=1234) /
959 self.send_and_assert_no_replies(self.pg7,
960 pkt_inter_epg_220_from_global * 65)
962 c5 = VppGbpContract(self, 333, 220, 0)
965 self.send_and_expect_unnatted(self.pg7,
966 pkt_inter_epg_220_from_global * 65,
970 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
971 dst=self.router_mac) /
973 dst=eps[1].floating_ip) /
974 UDP(sport=1234, dport=1234) /
977 self.send_and_expect_double_natted(self.pg0,
978 pkt_intra_epg_220_global * 65,
987 # del static mappings for each EP from the 10/8 to 11/8 network
989 self.vapi.nat44_add_del_static_mapping(ep.ip_n,
995 # self.vapi.nat66_add_del_static_mapping(ep.ip_n,
1001 # IP config on the BVI interfaces
1002 self.vapi.sw_interface_add_del_address(epg.bvi.sw_if_index,
1006 self.logger.info(self.vapi.cli("sh int addr"))
1008 epg.uplink.set_table_ip4(0)
1010 if epg != epgs[0] and epg != epgs[3]:
1011 epg.bvi.set_table_ip4(0)
1013 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
1016 # self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
1020 for recirc in recircs:
1021 recirc.recirc.set_table_ip4(0)
1024 self.vapi.nat44_interface_add_del_output_feature(
1025 recirc.recirc.sw_if_index,
1029 self.vapi.nat44_interface_add_del_feature(
1030 recirc.recirc.sw_if_index,
1033 # self.vapi.nat66_add_del_interface(
1034 # recirc.recirc.sw_if_index,
1039 if __name__ == '__main__':
1040 unittest.main(testRunner=VppTestRunner)