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
51 self.proto = DpoProto.DPO_PROTO_IP4
55 self.ip_n = inet_pton(self.af, ip)
56 self.floating_ip_n = inet_pton(self.af, fip)
58 def add_vpp_config(self):
59 self._test.vapi.gbp_endpoint_add_del(
65 self._test.registry.register(self, self._test.logger)
67 def remove_vpp_config(self):
68 self._test.vapi.gbp_endpoint_add_del(
76 return self.object_id()
79 return "gbp-endpoint;[%d:%s:%d]" % (self.itf.sw_if_index,
83 def query_vpp_config(self):
84 eps = self._test.vapi.gbp_endpoint_dump()
87 if ep.endpoint.address == self.ip_n \
88 and ep.endpoint.sw_if_index == self.itf.sw_if_index:
91 if ep.endpoint.address[:4] == self.ip_n \
92 and ep.endpoint.sw_if_index == self.itf.sw_if_index:
97 class VppGbpRecirc(VppObject):
99 GDB Recirculation Interface
102 def __init__(self, test, epg, recirc, is_ext=False):
108 def add_vpp_config(self):
109 self._test.vapi.gbp_recirc_add_del(
111 self.recirc.sw_if_index,
114 self._test.registry.register(self, self._test.logger)
116 def remove_vpp_config(self):
117 self._test.vapi.gbp_recirc_add_del(
119 self.recirc.sw_if_index,
124 return self.object_id()
127 return "gbp-recirc;[%d]" % (self.recirc.sw_if_index)
129 def query_vpp_config(self):
130 rs = self._test.vapi.gbp_recirc_dump()
132 if r.recirc.sw_if_index == self.recirc.sw_if_index:
137 class VppGbpSubnet(VppObject):
142 def __init__(self, test, table_id, address, address_len,
143 is_internal=True, is_ip6=False,
144 sw_if_index=None, epg=None):
146 self.table_id = table_id
147 self.address = address
148 self.address_len = address_len
151 self.address_n = inet_pton(AF_INET6, address)
153 self.address_n = inet_pton(AF_INET, address)
154 self.is_internal = is_internal
155 self.sw_if_index = sw_if_index
158 def add_vpp_config(self):
159 self._test.vapi.gbp_subnet_add_del(
165 sw_if_index=self.sw_if_index if self.sw_if_index else 0xffffffff,
166 epg_id=self.epg if self.epg else 0xffffffff,
168 self._test.registry.register(self, self._test.logger)
170 def remove_vpp_config(self):
171 self._test.vapi.gbp_subnet_add_del(
180 return self.object_id()
183 return "gbp-subnet;[%d:%s/%d]" % (self.table_id,
187 def query_vpp_config(self):
188 ss = self._test.vapi.gbp_subnet_dump()
190 if s.subnet.table_id == self.table_id and \
191 s.subnet.address_length == self.address_len and \
192 s.subnet.is_ip6 == self.is_ip6:
194 if s.subnet.address == self.address_n:
197 if s.subnet.address[:4] == self.address_n:
202 class VppGbpEndpointGroup(VppObject):
207 def __init__(self, test, epg, rd, bd, uplink,
208 bvi, bvi_ip4, bvi_ip6=None):
212 self.bvi_ip4 = bvi_ip4
213 self.bvi_ip4_n = inet_pton(AF_INET, bvi_ip4)
214 self.bvi_ip6 = bvi_ip6
215 self.bvi_ip6_n = inet_pton(AF_INET6, bvi_ip6)
220 def add_vpp_config(self):
221 self._test.vapi.gbp_endpoint_group_add_del(
227 self.uplink.sw_if_index)
228 self._test.registry.register(self, self._test.logger)
230 def remove_vpp_config(self):
231 self._test.vapi.gbp_endpoint_group_add_del(
237 self.uplink.sw_if_index)
240 return self.object_id()
243 return "gbp-endpoint-group;[%d]" % (self.epg)
245 def query_vpp_config(self):
246 epgs = self._test.vapi.gbp_endpoint_group_dump()
248 if epg.epg.epg_id == self.epg:
253 class VppGbpContract(VppObject):
258 def __init__(self, test, src_epg, dst_epg, acl_index):
260 self.acl_index = acl_index
261 self.src_epg = src_epg
262 self.dst_epg = dst_epg
264 def add_vpp_config(self):
265 self._test.vapi.gbp_contract_add_del(
270 self._test.registry.register(self, self._test.logger)
272 def remove_vpp_config(self):
273 self._test.vapi.gbp_contract_add_del(
280 return self.object_id()
283 return "gbp-contract;[%d:%s:%d]" % (self.src_epg,
287 def query_vpp_config(self):
288 cs = self._test.vapi.gbp_contract_dump()
290 if c.contract.src_epg == self.src_epg \
291 and c.contract.dst_epg == self.dst_epg:
296 class TestGBP(VppTestCase):
297 """ GBP Test Case """
300 super(TestGBP, self).setUp()
302 self.create_pg_interfaces(range(9))
303 self.create_loopback_interfaces(range(9))
305 self.router_mac = "00:11:22:33:44:55"
307 for i in self.pg_interfaces:
309 for i in self.lo_interfaces:
311 self.vapi.sw_interface_set_mac_address(
313 mactobinary(self.router_mac))
316 for i in self.pg_interfaces:
319 super(TestGBP, self).tearDown()
321 def send_and_expect_bridged(self, src, tx, dst):
322 rx = self.send_and_expect(src, tx, dst)
325 self.assertEqual(r[Ether].src, tx[0][Ether].src)
326 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
327 self.assertEqual(r[IP].src, tx[0][IP].src)
328 self.assertEqual(r[IP].dst, tx[0][IP].dst)
331 def send_and_expect_bridged6(self, src, tx, dst):
332 rx = self.send_and_expect(src, tx, dst)
335 self.assertEqual(r[Ether].src, tx[0][Ether].src)
336 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
337 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
338 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
341 def send_and_expect_routed(self, src, tx, dst, src_mac):
342 rx = self.send_and_expect(src, tx, dst)
345 self.assertEqual(r[Ether].src, src_mac)
346 self.assertEqual(r[Ether].dst, dst.remote_mac)
347 self.assertEqual(r[IP].src, tx[0][IP].src)
348 self.assertEqual(r[IP].dst, tx[0][IP].dst)
351 def send_and_expect_natted(self, src, tx, dst, src_ip):
352 rx = self.send_and_expect(src, tx, dst)
355 self.assertEqual(r[Ether].src, tx[0][Ether].src)
356 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
357 self.assertEqual(r[IP].src, src_ip)
358 self.assertEqual(r[IP].dst, tx[0][IP].dst)
361 def send_and_expect_natted6(self, src, tx, dst, src_ip):
362 rx = self.send_and_expect(src, tx, dst)
365 self.assertEqual(r[Ether].src, tx[0][Ether].src)
366 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
367 self.assertEqual(r[IPv6].src, src_ip)
368 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
371 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
372 rx = self.send_and_expect(src, tx, dst)
375 self.assertEqual(r[Ether].src, tx[0][Ether].src)
376 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
377 self.assertEqual(r[IP].dst, dst_ip)
378 self.assertEqual(r[IP].src, tx[0][IP].src)
381 def send_and_expect_unnatted6(self, src, tx, dst, dst_ip):
382 rx = self.send_and_expect(src, tx, dst)
385 self.assertEqual(r[Ether].src, tx[0][Ether].src)
386 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
387 self.assertEqual(r[IPv6].dst, dst_ip)
388 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
391 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
392 rx = self.send_and_expect(src, tx, dst)
395 self.assertEqual(r[Ether].src, self.router_mac)
396 self.assertEqual(r[Ether].dst, dst.remote_mac)
397 self.assertEqual(r[IP].dst, dst_ip)
398 self.assertEqual(r[IP].src, src_ip)
401 def send_and_expect_double_natted6(self, src, tx, dst, src_ip, dst_ip):
402 rx = self.send_and_expect(src, tx, dst)
405 self.assertEqual(r[Ether].src, self.router_mac)
406 self.assertEqual(r[Ether].dst, dst.remote_mac)
407 self.assertEqual(r[IPv6].dst, dst_ip)
408 self.assertEqual(r[IPv6].src, src_ip)
412 """ Group Based Policy """
414 nat_table = VppIpTable(self, 20)
415 nat_table.add_vpp_config()
416 nat_table = VppIpTable(self, 20, is_ip6=True)
417 nat_table.add_vpp_config()
422 self.vapi.bridge_domain_add_del(1, flood=1, uu_flood=1, forward=1,
423 learn=0, arp_term=1, is_add=1)
424 self.vapi.bridge_domain_add_del(2, flood=1, uu_flood=1, forward=1,
425 learn=0, arp_term=1, is_add=1)
426 self.vapi.bridge_domain_add_del(20, flood=1, uu_flood=1, forward=1,
427 learn=0, arp_term=1, is_add=1)
430 # 3 EPGs, 2 of which share a BD.
434 epgs.append(VppGbpEndpointGroup(self, 220, 0, 1, self.pg4,
438 recircs.append(VppGbpRecirc(self, epgs[0],
440 epgs.append(VppGbpEndpointGroup(self, 221, 0, 1, self.pg5,
444 recircs.append(VppGbpRecirc(self, epgs[1],
446 epgs.append(VppGbpEndpointGroup(self, 222, 0, 2, self.pg6,
450 recircs.append(VppGbpRecirc(self, epgs[2],
454 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
456 epgs.append(VppGbpEndpointGroup(self, 333, 20, 20, self.pg7,
460 recircs.append(VppGbpRecirc(self, epgs[3],
461 self.loop6, is_ext=True))
462 epgs.append(VppGbpEndpointGroup(self, 444, 20, 20, self.pg8,
466 recircs.append(VppGbpRecirc(self, epgs[4],
467 self.loop8, is_ext=True))
470 recirc_nat = recircs[3]
473 # 4 end-points, 2 in the same subnet, 3 in the same BD
476 eps.append(VppGbpEndpoint(self, self.pg0,
480 eps.append(VppGbpEndpoint(self, self.pg1,
484 eps.append(VppGbpEndpoint(self, self.pg2,
488 eps.append(VppGbpEndpoint(self, self.pg3,
492 eps.append(VppGbpEndpoint(self, self.pg0,
497 eps.append(VppGbpEndpoint(self, self.pg1,
502 eps.append(VppGbpEndpoint(self, self.pg2,
507 eps.append(VppGbpEndpoint(self, self.pg3,
514 # Config related to each of the EPGs
517 # IP config on the BVI interfaces
518 if epg != epgs[1] and epg != epgs[4]:
519 epg.bvi.set_table_ip4(epg.rd)
520 epg.bvi.set_table_ip6(epg.rd)
522 # The BVIs are NAT inside interfaces
523 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
526 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
530 self.vapi.sw_interface_add_del_address(epg.bvi.sw_if_index,
533 self.vapi.sw_interface_add_del_address(epg.bvi.sw_if_index,
538 # EPG uplink interfaces in the BD
539 epg.uplink.set_table_ip4(epg.rd)
540 epg.uplink.set_table_ip6(epg.rd)
541 self.vapi.sw_interface_set_l2_bridge(epg.uplink.sw_if_index,
544 # add the BD ARP termination entry for BVI IP
545 self.vapi.bd_ip_mac_add_del(bd_id=epg.bd,
546 mac=mactobinary(self.router_mac),
550 self.vapi.bd_ip_mac_add_del(bd_id=epg.bd,
551 mac=mactobinary(self.router_mac),
556 # epg[1] shares the same BVI to epg[0]
557 if epg != epgs[1] and epg != epgs[4]:
559 self.vapi.sw_interface_set_l2_bridge(epg.bvi.sw_if_index,
563 self.vapi.l2fib_add_del(self.router_mac,
571 for recirc in recircs:
572 # EPG's ingress recirculation interface maps to its RD
573 recirc.recirc.set_table_ip4(recirc.epg.rd)
574 recirc.recirc.set_table_ip6(recirc.epg.rd)
576 # in the bridge to allow DVR. L2 emulation to punt to L3
577 self.vapi.sw_interface_set_l2_bridge(recirc.recirc.sw_if_index,
579 self.vapi.sw_interface_set_l2_emulation(
580 recirc.recirc.sw_if_index)
582 self.vapi.nat44_interface_add_del_feature(
583 recirc.recirc.sw_if_index,
586 self.vapi.nat66_add_del_interface(
587 recirc.recirc.sw_if_index,
591 recirc.add_vpp_config()
596 self.pg_enable_capture(self.pg_interfaces)
599 # routes to the endpoints. We need these since there are no
600 # adj-fibs due to the fact the the BVI address has /32 and
601 # the subnet is not attached.
603 r = VppIpRoute(self, ep.ip, ep.ip_len,
605 ep.epg.bvi.sw_if_index,
612 # ARP entries for the endpoints
614 a = VppNeighbor(self,
615 ep.epg.bvi.sw_if_index,
621 # add each EP itf to the its BD
622 self.vapi.sw_interface_set_l2_bridge(ep.itf.sw_if_index,
625 # add the BD ARP termination entry
626 self.vapi.bd_ip_mac_add_del(bd_id=ep.epg.bd,
633 self.vapi.l2fib_add_del(ep.mac,
638 # Add static mappings for each EP from the 10/8 to 11/8 network
640 self.vapi.nat44_add_del_static_mapping(ep.ip_n,
645 self.vapi.nat66_add_del_static_mapping(ep.ip_n,
652 # ... results in a Gratuitous ARP/ND on the EPG's uplink
653 rx = ep.epg.uplink.get_capture(1, timeout=0.2)
656 self.assertTrue(rx[0].haslayer(ICMPv6ND_NA))
657 self.assertEqual(rx[0][ICMPv6ND_NA].tgt, ep.ip)
659 self.assertTrue(rx[0].haslayer(ARP))
660 self.assertEqual(rx[0][ARP].psrc, ep.ip)
661 self.assertEqual(rx[0][ARP].pdst, ep.ip)
663 # add the BD ARP termination entry for floating IP
664 self.vapi.bd_ip_mac_add_del(bd_id=epg_nat.bd,
670 # floating IPs route via EPG recirc
671 r = VppIpRoute(self, ep.floating_ip, ep.ip_len,
672 [VppRoutePath(ep.floating_ip,
673 ep.recirc.recirc.sw_if_index,
681 # L2 FIB entries in the NAT EPG BD to bridge the packets from
682 # the outside direct to the internal EPG
683 self.vapi.l2fib_add_del(ep.mac,
685 ep.recirc.recirc.sw_if_index,
689 # ARP packets for unknown IP are flooded
691 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
692 src=self.pg0.remote_mac) /
694 hwdst="ff:ff:ff:ff:ff:ff",
695 hwsrc=self.pg0.remote_mac,
696 pdst=epgs[0].bvi_ip4,
699 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
702 # ARP/ND packets get a response
704 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
705 src=self.pg0.remote_mac) /
707 hwdst="ff:ff:ff:ff:ff:ff",
708 hwsrc=self.pg0.remote_mac,
709 pdst=epgs[0].bvi_ip4,
712 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
714 nsma = in6_getnsma(inet_pton(AF_INET6, eps[4].ip))
715 d = inet_ntop(AF_INET6, nsma)
716 pkt_nd = (Ether(dst=in6_getnsmac(nsma)) /
717 IPv6(dst=d, src=eps[4].ip) /
718 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6) /
719 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
720 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
723 # broadcast packets are flooded
725 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
726 src=self.pg0.remote_mac) /
727 IP(src=eps[0].ip, dst="232.1.1.1") /
728 UDP(sport=1234, dport=1234) /
731 self.vapi.cli("clear trace")
732 self.pg0.add_stream(pkt_bcast)
734 self.pg_enable_capture(self.pg_interfaces)
737 rxd = eps[1].itf.get_capture(1)
738 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
739 rxd = epgs[0].uplink.get_capture(1)
740 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
743 # packets to non-local L3 destinations dropped
745 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
746 dst=self.router_mac) /
747 IP(src=eps[0].ip, dst="10.0.0.99") /
748 UDP(sport=1234, dport=1234) /
750 pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
751 dst=self.router_mac) /
752 IP(src=eps[0].ip, dst="10.0.1.99") /
753 UDP(sport=1234, dport=1234) /
756 self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * 65)
758 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
759 dst=self.router_mac) /
760 IPv6(src=eps[4].ip, dst="2001:10::99") /
761 UDP(sport=1234, dport=1234) /
763 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * 65)
766 # Add the subnet routes
768 s41 = VppGbpSubnet(self, 0, "10.0.0.0", 24)
769 s42 = VppGbpSubnet(self, 0, "10.0.1.0", 24)
770 s43 = VppGbpSubnet(self, 0, "10.0.2.0", 24)
774 s61 = VppGbpSubnet(self, 0, "2001:10::1", 64, is_ip6=True)
775 s62 = VppGbpSubnet(self, 0, "2001:10:1::1", 64, is_ip6=True)
776 s63 = VppGbpSubnet(self, 0, "2001:10:2::1", 64, is_ip6=True)
781 self.send_and_expect_bridged(self.pg0,
782 pkt_intra_epg_220_ip4 * 65,
784 self.send_and_expect_bridged(self.pg3,
785 pkt_inter_epg_222_ip4 * 65,
787 self.send_and_expect_bridged6(self.pg3,
788 pkt_inter_epg_222_ip6 * 65,
791 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
792 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
793 self.logger.info(self.vapi.cli("sh gbp endpoint"))
794 self.logger.info(self.vapi.cli("sh gbp recirc"))
795 self.logger.info(self.vapi.cli("sh int"))
796 self.logger.info(self.vapi.cli("sh int addr"))
797 self.logger.info(self.vapi.cli("sh int feat loop6"))
798 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
799 self.logger.info(self.vapi.cli("sh int feat loop3"))
802 # Packet destined to unknown unicast is sent on the epg uplink ...
804 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
805 dst="00:00:00:33:44:55") /
806 IP(src=eps[0].ip, dst="10.0.0.99") /
807 UDP(sport=1234, dport=1234) /
810 self.send_and_expect_bridged(self.pg0,
811 pkt_intra_epg_220_to_uplink * 65,
813 # ... and nowhere else
814 self.pg1.get_capture(0, timeout=0.1)
815 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
817 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
818 dst="00:00:00:33:44:66") /
819 IP(src=eps[0].ip, dst="10.0.0.99") /
820 UDP(sport=1234, dport=1234) /
823 self.send_and_expect_bridged(self.pg2,
824 pkt_intra_epg_221_to_uplink * 65,
828 # Packets from the uplink are forwarded in the absence of a contract
830 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
831 dst=self.pg0.remote_mac) /
832 IP(src=eps[0].ip, dst="10.0.0.99") /
833 UDP(sport=1234, dport=1234) /
836 self.send_and_expect_bridged(self.pg4,
837 pkt_intra_epg_220_from_uplink * 65,
841 # in the absence of policy, endpoints in the same EPG
844 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
845 dst=self.pg1.remote_mac) /
846 IP(src=eps[0].ip, dst=eps[1].ip) /
847 UDP(sport=1234, dport=1234) /
850 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
853 # in the abscense of policy, endpoints in the different EPG
856 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
857 dst=self.pg2.remote_mac) /
858 IP(src=eps[0].ip, dst=eps[2].ip) /
859 UDP(sport=1234, dport=1234) /
861 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
862 dst=self.pg0.remote_mac) /
863 IP(src=eps[2].ip, dst=eps[0].ip) /
864 UDP(sport=1234, dport=1234) /
866 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
867 dst=self.router_mac) /
868 IP(src=eps[0].ip, dst=eps[3].ip) /
869 UDP(sport=1234, dport=1234) /
872 self.send_and_assert_no_replies(self.pg0,
873 pkt_inter_epg_220_to_221 * 65)
874 self.send_and_assert_no_replies(self.pg0,
875 pkt_inter_epg_220_to_222 * 65)
878 # A uni-directional contract from EPG 220 -> 221
880 c1 = VppGbpContract(self, 220, 221, 0)
883 self.send_and_expect_bridged(self.pg0,
884 pkt_inter_epg_220_to_221 * 65,
886 self.send_and_assert_no_replies(self.pg0,
887 pkt_inter_epg_220_to_222 * 65)
890 # contract for the return direction
892 c2 = VppGbpContract(self, 221, 220, 0)
895 self.send_and_expect_bridged(self.pg0,
896 pkt_inter_epg_220_to_221 * 65,
898 self.send_and_expect_bridged(self.pg2,
899 pkt_inter_epg_221_to_220 * 65,
903 # check that inter group is still disabled for the groups
904 # not in the contract.
906 self.send_and_assert_no_replies(self.pg0,
907 pkt_inter_epg_220_to_222 * 65)
910 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
912 c3 = VppGbpContract(self, 220, 222, 0)
915 self.logger.info(self.vapi.cli("sh gbp contract"))
917 self.send_and_expect_routed(self.pg0,
918 pkt_inter_epg_220_to_222 * 65,
923 # remove both contracts, traffic stops in both directions
925 c2.remove_vpp_config()
926 c1.remove_vpp_config()
927 c3.remove_vpp_config()
929 self.send_and_assert_no_replies(self.pg2,
930 pkt_inter_epg_221_to_220 * 65)
931 self.send_and_assert_no_replies(self.pg0,
932 pkt_inter_epg_220_to_221 * 65)
933 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
936 # EPs to the outside world
939 # in the EP's RD an external subnet via the NAT EPG's recirc
940 se1 = VppGbpSubnet(self, 0, "0.0.0.0", 0,
942 sw_if_index=recirc_nat.recirc.sw_if_index,
945 se2 = VppGbpSubnet(self, 0, "11.0.0.0", 8,
947 sw_if_index=recirc_nat.recirc.sw_if_index,
950 se16 = VppGbpSubnet(self, 0, "::", 0,
952 sw_if_index=recirc_nat.recirc.sw_if_index,
955 se16.add_vpp_config()
956 # in the NAT RD an external subnet via the NAT EPG's uplink
957 se3 = VppGbpSubnet(self, 20, "0.0.0.0", 0,
959 sw_if_index=epg_nat.uplink.sw_if_index,
961 se36 = VppGbpSubnet(self, 20, "::", 0,
963 sw_if_index=epg_nat.uplink.sw_if_index,
966 se4 = VppGbpSubnet(self, 20, "11.0.0.0", 8,
968 sw_if_index=epg_nat.uplink.sw_if_index,
971 se36.add_vpp_config()
974 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
975 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
976 self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
977 self.logger.info(self.vapi.cli("sh ip6 fib %s" %
981 # From an EP to an outside addess: IN2OUT
983 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
984 dst=self.router_mac) /
985 IP(src=eps[0].ip, dst="1.1.1.1") /
986 UDP(sport=1234, dport=1234) /
990 self.send_and_assert_no_replies(self.pg0,
991 pkt_inter_epg_220_to_global * 65)
993 c4 = VppGbpContract(self, 220, 333, 0)
996 self.send_and_expect_natted(self.pg0,
997 pkt_inter_epg_220_to_global * 65,
1001 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
1002 dst=self.router_mac) /
1003 IPv6(src=eps[4].ip, dst="6001::1") /
1004 UDP(sport=1234, dport=1234) /
1007 self.send_and_expect_natted6(self.pg0,
1008 pkt_inter_epg_220_to_global * 65,
1013 # From a global address to an EP: OUT2IN
1015 pkt_inter_epg_220_from_global = (Ether(src=self.router_mac,
1016 dst=self.pg0.remote_mac) /
1017 IP(dst=eps[0].floating_ip,
1019 UDP(sport=1234, dport=1234) /
1022 self.send_and_assert_no_replies(self.pg7,
1023 pkt_inter_epg_220_from_global * 65)
1025 c5 = VppGbpContract(self, 333, 220, 0)
1028 self.send_and_expect_unnatted(self.pg7,
1029 pkt_inter_epg_220_from_global * 65,
1033 pkt_inter_epg_220_from_global = (Ether(src=self.router_mac,
1034 dst=self.pg0.remote_mac) /
1035 IPv6(dst=eps[4].floating_ip,
1037 UDP(sport=1234, dport=1234) /
1040 self.send_and_expect_unnatted6(self.pg7,
1041 pkt_inter_epg_220_from_global * 65,
1046 # From a local VM to another local VM using resp. public addresses:
1049 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
1050 dst=self.router_mac) /
1052 dst=eps[1].floating_ip) /
1053 UDP(sport=1234, dport=1234) /
1056 self.send_and_expect_double_natted(eps[0].itf,
1057 pkt_intra_epg_220_global * 65,
1062 pkt_intra_epg_220_global = (Ether(src=self.pg4.remote_mac,
1063 dst=self.router_mac) /
1065 dst=eps[5].floating_ip) /
1066 UDP(sport=1234, dport=1234) /
1069 self.send_and_expect_double_natted6(eps[4].itf,
1070 pkt_intra_epg_220_global * 65,
1079 # del static mappings for each EP from the 10/8 to 11/8 network
1080 if ep.af == AF_INET:
1081 self.vapi.nat44_add_del_static_mapping(ep.ip_n,
1087 self.vapi.nat66_add_del_static_mapping(ep.ip_n,
1093 # IP config on the BVI interfaces
1094 self.vapi.sw_interface_add_del_address(epg.bvi.sw_if_index,
1098 self.vapi.sw_interface_add_del_address(epg.bvi.sw_if_index,
1103 self.logger.info(self.vapi.cli("sh int addr"))
1105 epg.uplink.set_table_ip4(0)
1106 epg.uplink.set_table_ip6(0)
1108 if epg != epgs[0] and epg != epgs[3]:
1109 epg.bvi.set_table_ip4(0)
1110 epg.bvi.set_table_ip6(0)
1112 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
1115 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
1119 for recirc in recircs:
1120 recirc.recirc.set_table_ip4(0)
1121 recirc.recirc.set_table_ip6(0)
1123 self.vapi.nat44_interface_add_del_feature(
1124 recirc.recirc.sw_if_index,
1127 self.vapi.nat66_add_del_interface(
1128 recirc.recirc.sw_if_index,
1133 if __name__ == '__main__':
1134 unittest.main(testRunner=VppTestRunner)