5 from framework import VppTestCase, VppTestRunner
6 from vpp_object import VppObject
7 from vpp_neighbor import VppNeighbor
8 from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, DpoProto
10 from scapy.packet import Raw
11 from scapy.layers.l2 import Ether, ARP
12 from scapy.layers.inet import IP, UDP
13 from scapy.layers.inet6 import IPv6, ICMPv6ND_NS, ICMPv6NDOptSrcLLAddr, \
15 from scapy.utils6 import in6_getnsma, in6_getnsmac
17 from socket import AF_INET, AF_INET6
18 from scapy.utils import inet_pton, inet_ntop
19 from util import mactobinary
22 class VppGbpEndpoint(VppObject):
29 return mactobinary(self.itf.remote_mac)
33 return self.itf.remote_mac
35 def __init__(self, test, itf, epg, recirc, ip, fip, is_ip6=False):
41 self.floating_ip = fip
44 self.proto = DpoProto.DPO_PROTO_IP6
49 self.proto = DpoProto.DPO_PROTO_IP4
53 self.ip_n = inet_pton(self.af, ip)
54 self.floating_ip_n = inet_pton(self.af, fip)
56 def add_vpp_config(self):
57 self._test.vapi.gbp_endpoint_add_del(
63 self._test.registry.register(self, self._test.logger)
65 def remove_vpp_config(self):
66 self._test.vapi.gbp_endpoint_add_del(
74 return self.object_id()
77 return "gbp-endpoint;[%d:%s:%d]" % (self.itf.sw_if_index,
81 def query_vpp_config(self):
82 eps = self._test.vapi.gbp_endpoint_dump()
85 if ep.endpoint.address == self.ip_n \
86 and ep.endpoint.sw_if_index == self.itf.sw_if_index:
89 if ep.endpoint.address[:4] == self.ip_n \
90 and ep.endpoint.sw_if_index == self.itf.sw_if_index:
95 class VppGbpRecirc(VppObject):
97 GDB Recirculation Interface
100 def __init__(self, test, epg, recirc, is_ext=False):
106 def add_vpp_config(self):
107 self._test.vapi.gbp_recirc_add_del(
109 self.recirc.sw_if_index,
112 self._test.registry.register(self, self._test.logger)
114 def remove_vpp_config(self):
115 self._test.vapi.gbp_recirc_add_del(
117 self.recirc.sw_if_index,
122 return self.object_id()
125 return "gbp-recirc;[%d]" % (self.recirc.sw_if_index)
127 def query_vpp_config(self):
128 rs = self._test.vapi.gbp_recirc_dump()
130 if r.recirc.sw_if_index == self.recirc.sw_if_index:
135 class VppGbpSubnet(VppObject):
140 def __init__(self, test, table_id, address, address_len,
141 is_internal=True, is_ip6=False,
142 sw_if_index=None, epg=None):
144 self.table_id = table_id
145 self.address = address
146 self.address_len = address_len
149 self.address_n = inet_pton(AF_INET6, address)
151 self.address_n = inet_pton(AF_INET, address)
152 self.is_internal = is_internal
153 self.sw_if_index = sw_if_index
156 def add_vpp_config(self):
157 self._test.vapi.gbp_subnet_add_del(
163 sw_if_index=self.sw_if_index if self.sw_if_index else 0xffffffff,
164 epg_id=self.epg if self.epg else 0xffffffff,
166 self._test.registry.register(self, self._test.logger)
168 def remove_vpp_config(self):
169 self._test.vapi.gbp_subnet_add_del(
178 return self.object_id()
181 return "gbp-subnet;[%d:%s/%d]" % (self.table_id,
185 def query_vpp_config(self):
186 ss = self._test.vapi.gbp_subnet_dump()
188 if s.subnet.table_id == self.table_id and \
189 s.subnet.address_length == self.address_len and \
190 s.subnet.is_ip6 == self.is_ip6:
192 if s.subnet.address == self.address_n:
195 if s.subnet.address[:4] == self.address_n:
200 class VppGbpEndpointGroup(VppObject):
205 def __init__(self, test, epg, rd, bd, uplink,
206 bvi, bvi_ip4, bvi_ip6=None):
210 self.bvi_ip4 = bvi_ip4
211 self.bvi_ip4_n = inet_pton(AF_INET, bvi_ip4)
212 self.bvi_ip6 = bvi_ip6
213 self.bvi_ip6_n = inet_pton(AF_INET6, bvi_ip6)
218 def add_vpp_config(self):
219 self._test.vapi.gbp_endpoint_group_add_del(
225 self.uplink.sw_if_index)
226 self._test.registry.register(self, self._test.logger)
228 def remove_vpp_config(self):
229 self._test.vapi.gbp_endpoint_group_add_del(
235 self.uplink.sw_if_index)
238 return self.object_id()
241 return "gbp-endpoint-group;[%d]" % (self.epg)
243 def query_vpp_config(self):
244 epgs = self._test.vapi.gbp_endpoint_group_dump()
246 if epg.epg.epg_id == self.epg:
251 class VppGbpContract(VppObject):
256 def __init__(self, test, src_epg, dst_epg, acl_index):
258 self.acl_index = acl_index
259 self.src_epg = src_epg
260 self.dst_epg = dst_epg
262 def add_vpp_config(self):
263 self._test.vapi.gbp_contract_add_del(
268 self._test.registry.register(self, self._test.logger)
270 def remove_vpp_config(self):
271 self._test.vapi.gbp_contract_add_del(
278 return self.object_id()
281 return "gbp-contract;[%d:%s:%d]" % (self.src_epg,
285 def query_vpp_config(self):
286 cs = self._test.vapi.gbp_contract_dump()
288 if c.contract.src_epg == self.src_epg \
289 and c.contract.dst_epg == self.dst_epg:
294 class TestGBP(VppTestCase):
295 """ GBP Test Case """
298 super(TestGBP, self).setUp()
300 self.create_pg_interfaces(range(9))
301 self.create_loopback_interfaces(9)
303 self.router_mac = "00:11:22:33:44:55"
305 for i in self.pg_interfaces:
307 for i in self.lo_interfaces:
309 self.vapi.sw_interface_set_mac_address(
311 mactobinary(self.router_mac))
314 for i in self.pg_interfaces:
317 super(TestGBP, self).tearDown()
319 def send_and_expect_bridged(self, src, tx, dst):
320 rx = self.send_and_expect(src, tx, dst)
323 self.assertEqual(r[Ether].src, tx[0][Ether].src)
324 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
325 self.assertEqual(r[IP].src, tx[0][IP].src)
326 self.assertEqual(r[IP].dst, tx[0][IP].dst)
329 def send_and_expect_bridged6(self, src, tx, dst):
330 rx = self.send_and_expect(src, tx, dst)
333 self.assertEqual(r[Ether].src, tx[0][Ether].src)
334 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
335 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
336 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
339 def send_and_expect_routed(self, src, tx, dst, src_mac):
340 rx = self.send_and_expect(src, tx, dst)
343 self.assertEqual(r[Ether].src, src_mac)
344 self.assertEqual(r[Ether].dst, dst.remote_mac)
345 self.assertEqual(r[IP].src, tx[0][IP].src)
346 self.assertEqual(r[IP].dst, tx[0][IP].dst)
349 def send_and_expect_natted(self, src, tx, dst, src_ip):
350 rx = self.send_and_expect(src, tx, dst)
353 self.assertEqual(r[Ether].src, tx[0][Ether].src)
354 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
355 self.assertEqual(r[IP].src, src_ip)
356 self.assertEqual(r[IP].dst, tx[0][IP].dst)
359 def send_and_expect_natted6(self, src, tx, dst, src_ip):
360 rx = self.send_and_expect(src, tx, dst)
363 self.assertEqual(r[Ether].src, tx[0][Ether].src)
364 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
365 self.assertEqual(r[IPv6].src, src_ip)
366 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
369 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
370 rx = self.send_and_expect(src, tx, dst)
373 self.assertEqual(r[Ether].src, tx[0][Ether].src)
374 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
375 self.assertEqual(r[IP].dst, dst_ip)
376 self.assertEqual(r[IP].src, tx[0][IP].src)
379 def send_and_expect_unnatted6(self, src, tx, dst, dst_ip):
380 rx = self.send_and_expect(src, tx, dst)
383 self.assertEqual(r[Ether].src, tx[0][Ether].src)
384 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
385 self.assertEqual(r[IPv6].dst, dst_ip)
386 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
389 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
390 rx = self.send_and_expect(src, tx, dst)
393 self.assertEqual(r[Ether].src, self.router_mac)
394 self.assertEqual(r[Ether].dst, dst.remote_mac)
395 self.assertEqual(r[IP].dst, dst_ip)
396 self.assertEqual(r[IP].src, src_ip)
399 def send_and_expect_double_natted6(self, src, tx, dst, src_ip, dst_ip):
400 rx = self.send_and_expect(src, tx, dst)
403 self.assertEqual(r[Ether].src, self.router_mac)
404 self.assertEqual(r[Ether].dst, dst.remote_mac)
405 self.assertEqual(r[IPv6].dst, dst_ip)
406 self.assertEqual(r[IPv6].src, src_ip)
410 """ Group Based Policy """
412 nat_table = VppIpTable(self, 20)
413 nat_table.add_vpp_config()
414 nat_table = VppIpTable(self, 20, is_ip6=True)
415 nat_table.add_vpp_config()
420 self.vapi.bridge_domain_add_del(1, flood=1, uu_flood=1, forward=1,
421 learn=0, arp_term=1, is_add=1)
422 self.vapi.bridge_domain_add_del(2, flood=1, uu_flood=1, forward=1,
423 learn=0, arp_term=1, is_add=1)
424 self.vapi.bridge_domain_add_del(20, flood=1, uu_flood=1, forward=1,
425 learn=0, arp_term=1, is_add=1)
428 # 3 EPGs, 2 of which share a BD.
432 epgs.append(VppGbpEndpointGroup(self, 220, 0, 1, self.pg4,
436 recircs.append(VppGbpRecirc(self, epgs[0],
438 epgs.append(VppGbpEndpointGroup(self, 221, 0, 1, self.pg5,
442 recircs.append(VppGbpRecirc(self, epgs[1],
444 epgs.append(VppGbpEndpointGroup(self, 222, 0, 2, self.pg6,
448 recircs.append(VppGbpRecirc(self, epgs[2],
452 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
454 epgs.append(VppGbpEndpointGroup(self, 333, 20, 20, self.pg7,
458 recircs.append(VppGbpRecirc(self, epgs[3],
459 self.loop6, is_ext=True))
460 epgs.append(VppGbpEndpointGroup(self, 444, 20, 20, self.pg8,
464 recircs.append(VppGbpRecirc(self, epgs[4],
465 self.loop8, is_ext=True))
468 recirc_nat = recircs[3]
471 # 4 end-points, 2 in the same subnet, 3 in the same BD
474 eps.append(VppGbpEndpoint(self, self.pg0,
478 eps.append(VppGbpEndpoint(self, self.pg1,
482 eps.append(VppGbpEndpoint(self, self.pg2,
486 eps.append(VppGbpEndpoint(self, self.pg3,
490 eps.append(VppGbpEndpoint(self, self.pg0,
495 eps.append(VppGbpEndpoint(self, self.pg1,
500 eps.append(VppGbpEndpoint(self, self.pg2,
505 eps.append(VppGbpEndpoint(self, self.pg3,
512 # Config related to each of the EPGs
515 # IP config on the BVI interfaces
516 if epg != epgs[1] and epg != epgs[4]:
517 epg.bvi.set_table_ip4(epg.rd)
518 epg.bvi.set_table_ip6(epg.rd)
520 # The BVIs are NAT inside interfaces
521 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
524 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
528 self.vapi.sw_interface_add_del_address(epg.bvi.sw_if_index,
531 self.vapi.sw_interface_add_del_address(epg.bvi.sw_if_index,
536 # EPG uplink interfaces in the BD
537 epg.uplink.set_table_ip4(epg.rd)
538 epg.uplink.set_table_ip6(epg.rd)
539 self.vapi.sw_interface_set_l2_bridge(epg.uplink.sw_if_index,
542 # add the BD ARP termination entry for BVI IP
543 self.vapi.bd_ip_mac_add_del(bd_id=epg.bd,
544 mac=mactobinary(self.router_mac),
548 self.vapi.bd_ip_mac_add_del(bd_id=epg.bd,
549 mac=mactobinary(self.router_mac),
554 # epg[1] shares the same BVI to epg[0]
555 if epg != epgs[1] and epg != epgs[4]:
557 self.vapi.sw_interface_set_l2_bridge(epg.bvi.sw_if_index,
561 self.vapi.l2fib_add_del(self.router_mac,
569 for recirc in recircs:
570 # EPG's ingress recirculation interface maps to its RD
571 recirc.recirc.set_table_ip4(recirc.epg.rd)
572 recirc.recirc.set_table_ip6(recirc.epg.rd)
574 # in the bridge to allow DVR. L2 emulation to punt to L3
575 self.vapi.sw_interface_set_l2_bridge(recirc.recirc.sw_if_index,
577 self.vapi.sw_interface_set_l2_emulation(
578 recirc.recirc.sw_if_index)
580 self.vapi.nat44_interface_add_del_feature(
581 recirc.recirc.sw_if_index,
584 self.vapi.nat66_add_del_interface(
585 recirc.recirc.sw_if_index,
589 recirc.add_vpp_config()
594 self.pg_enable_capture(self.pg_interfaces)
597 # routes to the endpoints. We need these since there are no
598 # adj-fibs due to the fact the the BVI address has /32 and
599 # the subnet is not attached.
601 r = VppIpRoute(self, ep.ip, ep.ip_len,
603 ep.epg.bvi.sw_if_index,
610 # ARP entries for the endpoints
612 a = VppNeighbor(self,
613 ep.epg.bvi.sw_if_index,
619 # add each EP itf to the its BD
620 self.vapi.sw_interface_set_l2_bridge(ep.itf.sw_if_index,
623 # add the BD ARP termination entry
624 self.vapi.bd_ip_mac_add_del(bd_id=ep.epg.bd,
631 self.vapi.l2fib_add_del(ep.mac,
636 # Add static mappings for each EP from the 10/8 to 11/8 network
638 self.vapi.nat44_add_del_static_mapping(ep.ip_n,
643 self.vapi.nat66_add_del_static_mapping(ep.ip_n,
650 # ... results in a Gratuitous ARP/ND on the EPG's uplink
651 rx = ep.epg.uplink.get_capture(1, timeout=0.2)
654 self.assertTrue(rx[0].haslayer(ICMPv6ND_NA))
655 self.assertEqual(rx[0][ICMPv6ND_NA].tgt, ep.ip)
657 self.assertTrue(rx[0].haslayer(ARP))
658 self.assertEqual(rx[0][ARP].psrc, ep.ip)
659 self.assertEqual(rx[0][ARP].pdst, ep.ip)
661 # add the BD ARP termination entry for floating IP
662 self.vapi.bd_ip_mac_add_del(bd_id=epg_nat.bd,
668 # floating IPs route via EPG recirc
669 r = VppIpRoute(self, ep.floating_ip, ep.ip_len,
670 [VppRoutePath(ep.floating_ip,
671 ep.recirc.recirc.sw_if_index,
679 # L2 FIB entries in the NAT EPG BD to bridge the packets from
680 # the outside direct to the internal EPG
681 self.vapi.l2fib_add_del(ep.mac,
683 ep.recirc.recirc.sw_if_index,
687 # ARP packets for unknown IP are flooded
689 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
690 src=self.pg0.remote_mac) /
692 hwdst="ff:ff:ff:ff:ff:ff",
693 hwsrc=self.pg0.remote_mac,
694 pdst=epgs[0].bvi_ip4,
697 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
700 # ARP/ND packets get a response
702 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
703 src=self.pg0.remote_mac) /
705 hwdst="ff:ff:ff:ff:ff:ff",
706 hwsrc=self.pg0.remote_mac,
707 pdst=epgs[0].bvi_ip4,
710 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
712 nsma = in6_getnsma(inet_pton(AF_INET6, eps[4].ip))
713 d = inet_ntop(AF_INET6, nsma)
714 pkt_nd = (Ether(dst=in6_getnsmac(nsma)) /
715 IPv6(dst=d, src=eps[4].ip) /
716 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6) /
717 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
718 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
721 # broadcast packets are flooded
723 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
724 src=self.pg0.remote_mac) /
725 IP(src=eps[0].ip, dst="232.1.1.1") /
726 UDP(sport=1234, dport=1234) /
729 self.vapi.cli("clear trace")
730 self.pg0.add_stream(pkt_bcast)
732 self.pg_enable_capture(self.pg_interfaces)
735 rxd = eps[1].itf.get_capture(1)
736 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
737 rxd = epgs[0].uplink.get_capture(1)
738 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
741 # packets to non-local L3 destinations dropped
743 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
744 dst=self.router_mac) /
745 IP(src=eps[0].ip, dst="10.0.0.99") /
746 UDP(sport=1234, dport=1234) /
748 pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
749 dst=self.router_mac) /
750 IP(src=eps[0].ip, dst="10.0.1.99") /
751 UDP(sport=1234, dport=1234) /
754 self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * 65)
756 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
757 dst=self.router_mac) /
758 IPv6(src=eps[4].ip, dst="2001:10::99") /
759 UDP(sport=1234, dport=1234) /
761 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * 65)
764 # Add the subnet routes
766 s41 = VppGbpSubnet(self, 0, "10.0.0.0", 24)
767 s42 = VppGbpSubnet(self, 0, "10.0.1.0", 24)
768 s43 = VppGbpSubnet(self, 0, "10.0.2.0", 24)
772 s61 = VppGbpSubnet(self, 0, "2001:10::1", 64, is_ip6=True)
773 s62 = VppGbpSubnet(self, 0, "2001:10:1::1", 64, is_ip6=True)
774 s63 = VppGbpSubnet(self, 0, "2001:10:2::1", 64, is_ip6=True)
779 self.send_and_expect_bridged(self.pg0,
780 pkt_intra_epg_220_ip4 * 65,
782 self.send_and_expect_bridged(self.pg3,
783 pkt_inter_epg_222_ip4 * 65,
785 self.send_and_expect_bridged6(self.pg3,
786 pkt_inter_epg_222_ip6 * 65,
789 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
790 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
791 self.logger.info(self.vapi.cli("sh gbp endpoint"))
792 self.logger.info(self.vapi.cli("sh gbp recirc"))
793 self.logger.info(self.vapi.cli("sh int"))
794 self.logger.info(self.vapi.cli("sh int addr"))
795 self.logger.info(self.vapi.cli("sh int feat loop6"))
796 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
797 self.logger.info(self.vapi.cli("sh int feat loop3"))
800 # Packet destined to unknown unicast is sent on the epg uplink ...
802 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
803 dst="00:00:00:33:44:55") /
804 IP(src=eps[0].ip, dst="10.0.0.99") /
805 UDP(sport=1234, dport=1234) /
808 self.send_and_expect_bridged(self.pg0,
809 pkt_intra_epg_220_to_uplink * 65,
811 # ... and nowhere else
812 self.pg1.get_capture(0, timeout=0.1)
813 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
815 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
816 dst="00:00:00:33:44:66") /
817 IP(src=eps[0].ip, dst="10.0.0.99") /
818 UDP(sport=1234, dport=1234) /
821 self.send_and_expect_bridged(self.pg2,
822 pkt_intra_epg_221_to_uplink * 65,
826 # Packets from the uplink are forwarded in the absence of a contract
828 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
829 dst=self.pg0.remote_mac) /
830 IP(src=eps[0].ip, dst="10.0.0.99") /
831 UDP(sport=1234, dport=1234) /
834 self.send_and_expect_bridged(self.pg4,
835 pkt_intra_epg_220_from_uplink * 65,
839 # in the absence of policy, endpoints in the same EPG
842 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
843 dst=self.pg1.remote_mac) /
844 IP(src=eps[0].ip, dst=eps[1].ip) /
845 UDP(sport=1234, dport=1234) /
848 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
851 # in the abscense of policy, endpoints in the different EPG
854 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
855 dst=self.pg2.remote_mac) /
856 IP(src=eps[0].ip, dst=eps[2].ip) /
857 UDP(sport=1234, dport=1234) /
859 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
860 dst=self.pg0.remote_mac) /
861 IP(src=eps[2].ip, dst=eps[0].ip) /
862 UDP(sport=1234, dport=1234) /
864 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
865 dst=self.router_mac) /
866 IP(src=eps[0].ip, dst=eps[3].ip) /
867 UDP(sport=1234, dport=1234) /
870 self.send_and_assert_no_replies(self.pg0,
871 pkt_inter_epg_220_to_221 * 65)
872 self.send_and_assert_no_replies(self.pg0,
873 pkt_inter_epg_220_to_222 * 65)
876 # A uni-directional contract from EPG 220 -> 221
878 c1 = VppGbpContract(self, 220, 221, 0)
881 self.send_and_expect_bridged(self.pg0,
882 pkt_inter_epg_220_to_221 * 65,
884 self.send_and_assert_no_replies(self.pg0,
885 pkt_inter_epg_220_to_222 * 65)
888 # contract for the return direction
890 c2 = VppGbpContract(self, 221, 220, 0)
893 self.send_and_expect_bridged(self.pg0,
894 pkt_inter_epg_220_to_221 * 65,
896 self.send_and_expect_bridged(self.pg2,
897 pkt_inter_epg_221_to_220 * 65,
901 # check that inter group is still disabled for the groups
902 # not in the contract.
904 self.send_and_assert_no_replies(self.pg0,
905 pkt_inter_epg_220_to_222 * 65)
908 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
910 c3 = VppGbpContract(self, 220, 222, 0)
913 self.logger.info(self.vapi.cli("sh gbp contract"))
915 self.send_and_expect_routed(self.pg0,
916 pkt_inter_epg_220_to_222 * 65,
921 # remove both contracts, traffic stops in both directions
923 c2.remove_vpp_config()
924 c1.remove_vpp_config()
925 c3.remove_vpp_config()
927 self.send_and_assert_no_replies(self.pg2,
928 pkt_inter_epg_221_to_220 * 65)
929 self.send_and_assert_no_replies(self.pg0,
930 pkt_inter_epg_220_to_221 * 65)
931 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
934 # EPs to the outside world
937 # in the EP's RD an external subnet via the NAT EPG's recirc
938 se1 = VppGbpSubnet(self, 0, "0.0.0.0", 0,
940 sw_if_index=recirc_nat.recirc.sw_if_index,
943 se2 = VppGbpSubnet(self, 0, "11.0.0.0", 8,
945 sw_if_index=recirc_nat.recirc.sw_if_index,
948 se16 = VppGbpSubnet(self, 0, "::", 0,
950 sw_if_index=recirc_nat.recirc.sw_if_index,
953 se16.add_vpp_config()
954 # in the NAT RD an external subnet via the NAT EPG's uplink
955 se3 = VppGbpSubnet(self, 20, "0.0.0.0", 0,
957 sw_if_index=epg_nat.uplink.sw_if_index,
959 se36 = VppGbpSubnet(self, 20, "::", 0,
961 sw_if_index=epg_nat.uplink.sw_if_index,
964 se4 = VppGbpSubnet(self, 20, "11.0.0.0", 8,
966 sw_if_index=epg_nat.uplink.sw_if_index,
969 se36.add_vpp_config()
972 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
973 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
974 self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
975 self.logger.info(self.vapi.cli("sh ip6 fib %s" %
979 # From an EP to an outside addess: IN2OUT
981 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
982 dst=self.router_mac) /
983 IP(src=eps[0].ip, dst="1.1.1.1") /
984 UDP(sport=1234, dport=1234) /
988 self.send_and_assert_no_replies(self.pg0,
989 pkt_inter_epg_220_to_global * 65)
991 c4 = VppGbpContract(self, 220, 333, 0)
994 self.send_and_expect_natted(self.pg0,
995 pkt_inter_epg_220_to_global * 65,
999 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
1000 dst=self.router_mac) /
1001 IPv6(src=eps[4].ip, dst="6001::1") /
1002 UDP(sport=1234, dport=1234) /
1005 self.send_and_expect_natted6(self.pg0,
1006 pkt_inter_epg_220_to_global * 65,
1011 # From a global address to an EP: OUT2IN
1013 pkt_inter_epg_220_from_global = (Ether(src=self.router_mac,
1014 dst=self.pg0.remote_mac) /
1015 IP(dst=eps[0].floating_ip,
1017 UDP(sport=1234, dport=1234) /
1020 self.send_and_assert_no_replies(self.pg7,
1021 pkt_inter_epg_220_from_global * 65)
1023 c5 = VppGbpContract(self, 333, 220, 0)
1026 self.send_and_expect_unnatted(self.pg7,
1027 pkt_inter_epg_220_from_global * 65,
1031 pkt_inter_epg_220_from_global = (Ether(src=self.router_mac,
1032 dst=self.pg0.remote_mac) /
1033 IPv6(dst=eps[4].floating_ip,
1035 UDP(sport=1234, dport=1234) /
1038 self.send_and_expect_unnatted6(self.pg7,
1039 pkt_inter_epg_220_from_global * 65,
1044 # From a local VM to another local VM using resp. public addresses:
1047 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
1048 dst=self.router_mac) /
1050 dst=eps[1].floating_ip) /
1051 UDP(sport=1234, dport=1234) /
1054 self.send_and_expect_double_natted(eps[0].itf,
1055 pkt_intra_epg_220_global * 65,
1060 pkt_intra_epg_220_global = (Ether(src=self.pg4.remote_mac,
1061 dst=self.router_mac) /
1063 dst=eps[5].floating_ip) /
1064 UDP(sport=1234, dport=1234) /
1067 self.send_and_expect_double_natted6(eps[4].itf,
1068 pkt_intra_epg_220_global * 65,
1077 # del static mappings for each EP from the 10/8 to 11/8 network
1078 if ep.af == AF_INET:
1079 self.vapi.nat44_add_del_static_mapping(ep.ip_n,
1085 self.vapi.nat66_add_del_static_mapping(ep.ip_n,
1091 # IP config on the BVI interfaces
1092 self.vapi.sw_interface_add_del_address(epg.bvi.sw_if_index,
1096 self.vapi.sw_interface_add_del_address(epg.bvi.sw_if_index,
1101 self.logger.info(self.vapi.cli("sh int addr"))
1103 epg.uplink.set_table_ip4(0)
1104 epg.uplink.set_table_ip6(0)
1106 if epg != epgs[0] and epg != epgs[3]:
1107 epg.bvi.set_table_ip4(0)
1108 epg.bvi.set_table_ip6(0)
1110 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
1113 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
1117 for recirc in recircs:
1118 recirc.recirc.set_table_ip4(0)
1119 recirc.recirc.set_table_ip6(0)
1121 self.vapi.nat44_interface_add_del_feature(
1122 recirc.recirc.sw_if_index,
1125 self.vapi.nat66_add_del_interface(
1126 recirc.recirc.sw_if_index,
1131 if __name__ == '__main__':
1132 unittest.main(testRunner=VppTestRunner)