6 from scapy.packet import Raw
7 from scapy.layers.l2 import Ether, Dot1Q, GRE
8 from scapy.layers.inet import IP, UDP
9 from scapy.layers.inet6 import IPv6
10 from scapy.volatile import RandMAC, RandIP
12 from framework import tag_fixme_vpp_workers
13 from framework import VppTestCase, VppTestRunner
14 from vpp_sub_interface import L2_VTR_OP, VppDot1QSubint
15 from vpp_gre_interface import VppGreInterface
16 from vpp_teib import VppTeib
17 from vpp_ip import DpoProto
18 from vpp_ip_route import (
25 from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
26 from util import ppp, ppc
27 from vpp_papi import VppEnum
30 @tag_fixme_vpp_workers
31 class TestGREInputNodes(VppTestCase):
32 """GRE Input Nodes Test Case"""
35 super(TestGREInputNodes, self).setUp()
37 # create 3 pg interfaces - set one in a non-default table.
38 self.create_pg_interfaces(range(1))
40 for i in self.pg_interfaces:
45 for i in self.pg_interfaces:
48 super(TestGREInputNodes, self).tearDown()
50 def test_gre_input_node(self):
51 """GRE gre input nodes not registerd unless configured"""
53 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
54 / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
58 self.pg0.add_stream(pkt)
60 # no tunnel created, gre-input not registered
61 err = self.statistics.get_counter("/err/ip4-local/unknown_protocol")[0]
62 self.assertEqual(err, 1)
66 gre_if = VppGreInterface(self, self.pg0.local_ip4, "1.1.1.2")
67 gre_if.add_vpp_config()
69 self.pg0.add_stream(pkt)
71 # tunnel created, gre-input registered
72 err = self.statistics.get_counter("/err/ip4-local/unknown_protocol")[0]
73 # expect no new errors
74 self.assertEqual(err, err_count)
77 class TestGRE(VppTestCase):
82 super(TestGRE, cls).setUpClass()
85 def tearDownClass(cls):
86 super(TestGRE, cls).tearDownClass()
89 super(TestGRE, self).setUp()
91 # create 3 pg interfaces - set one in a non-default table.
92 self.create_pg_interfaces(range(5))
94 self.tbl = VppIpTable(self, 1)
95 self.tbl.add_vpp_config()
96 self.pg1.set_table_ip4(1)
98 for i in self.pg_interfaces:
101 self.pg0.config_ip4()
102 self.pg0.resolve_arp()
103 self.pg1.config_ip4()
104 self.pg1.resolve_arp()
105 self.pg2.config_ip6()
106 self.pg2.resolve_ndp()
107 self.pg3.config_ip4()
108 self.pg3.resolve_arp()
109 self.pg4.config_ip4()
110 self.pg4.resolve_arp()
113 for i in self.pg_interfaces:
117 self.pg1.set_table_ip4(0)
118 super(TestGRE, self).tearDown()
120 def create_stream_ip4(self, src_if, src_ip, dst_ip, dscp=0, ecn=0):
122 tos = (dscp << 2) | ecn
123 for i in range(0, 257):
124 info = self.create_packet_info(src_if, src_if)
125 payload = self.info_to_payload(info)
127 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
128 / IP(src=src_ip, dst=dst_ip, tos=tos)
129 / UDP(sport=1234, dport=1234)
136 def create_stream_ip6(self, src_if, src_ip, dst_ip, dscp=0, ecn=0):
138 tc = (dscp << 2) | ecn
139 for i in range(0, 257):
140 info = self.create_packet_info(src_if, src_if)
141 payload = self.info_to_payload(info)
143 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
144 / IPv6(src=src_ip, dst=dst_ip, tc=tc)
145 / UDP(sport=1234, dport=1234)
152 def create_tunnel_stream_4o4(self, src_if, tunnel_src, tunnel_dst, src_ip, dst_ip):
154 for i in range(0, 257):
155 info = self.create_packet_info(src_if, src_if)
156 payload = self.info_to_payload(info)
158 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
159 / IP(src=tunnel_src, dst=tunnel_dst)
161 / IP(src=src_ip, dst=dst_ip)
162 / UDP(sport=1234, dport=1234)
169 def create_tunnel_stream_6o4(self, src_if, tunnel_src, tunnel_dst, src_ip, dst_ip):
171 for i in range(0, 257):
172 info = self.create_packet_info(src_if, src_if)
173 payload = self.info_to_payload(info)
175 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
176 / IP(src=tunnel_src, dst=tunnel_dst)
178 / IPv6(src=src_ip, dst=dst_ip)
179 / UDP(sport=1234, dport=1234)
186 def create_tunnel_stream_6o6(self, src_if, tunnel_src, tunnel_dst, src_ip, dst_ip):
188 for i in range(0, 257):
189 info = self.create_packet_info(src_if, src_if)
190 payload = self.info_to_payload(info)
192 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
193 / IPv6(src=tunnel_src, dst=tunnel_dst)
195 / IPv6(src=src_ip, dst=dst_ip)
196 / UDP(sport=1234, dport=1234)
203 def create_tunnel_stream_l2o4(self, src_if, tunnel_src, tunnel_dst):
205 for i in range(0, 257):
206 info = self.create_packet_info(src_if, src_if)
207 payload = self.info_to_payload(info)
209 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
210 / IP(src=tunnel_src, dst=tunnel_dst)
212 / Ether(dst=RandMAC("*:*:*:*:*:*"), src=RandMAC("*:*:*:*:*:*"))
213 / IP(src=scapy.compat.raw(RandIP()), dst=scapy.compat.raw(RandIP()))
214 / UDP(sport=1234, dport=1234)
221 def create_tunnel_stream_vlano4(self, src_if, tunnel_src, tunnel_dst, vlan):
223 for i in range(0, 257):
224 info = self.create_packet_info(src_if, src_if)
225 payload = self.info_to_payload(info)
227 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
228 / IP(src=tunnel_src, dst=tunnel_dst)
230 / Ether(dst=RandMAC("*:*:*:*:*:*"), src=RandMAC("*:*:*:*:*:*"))
232 / IP(src=scapy.compat.raw(RandIP()), dst=scapy.compat.raw(RandIP()))
233 / UDP(sport=1234, dport=1234)
240 def verify_tunneled_4o4(
241 self, src_if, capture, sent, tunnel_src, tunnel_dst, dscp=0, ecn=0
243 self.assertEqual(len(capture), len(sent))
244 tos = (dscp << 2) | ecn
246 for i in range(len(capture)):
254 self.assertEqual(rx_ip.src, tunnel_src)
255 self.assertEqual(rx_ip.dst, tunnel_dst)
256 self.assertEqual(rx_ip.tos, tos)
257 self.assertEqual(rx_ip.len, len(rx_ip))
262 self.assertEqual(rx_ip.src, tx_ip.src)
263 self.assertEqual(rx_ip.dst, tx_ip.dst)
264 # IP processing post pop has decremented the TTL
265 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
268 self.logger.error(ppp("Rx:", rx))
269 self.logger.error(ppp("Tx:", tx))
272 def verify_tunneled_6o6(
273 self, src_if, capture, sent, tunnel_src, tunnel_dst, dscp=0, ecn=0
275 self.assertEqual(len(capture), len(sent))
276 tc = (dscp << 2) | ecn
278 for i in range(len(capture)):
286 self.assertEqual(rx_ip.src, tunnel_src)
287 self.assertEqual(rx_ip.dst, tunnel_dst)
288 self.assertEqual(rx_ip.tc, tc)
290 rx_gre = GRE(scapy.compat.raw(rx_ip[IPv6].payload))
292 self.assertEqual(rx_ip.plen, len(rx_gre))
296 self.assertEqual(rx_ip.src, tx_ip.src)
297 self.assertEqual(rx_ip.dst, tx_ip.dst)
300 self.logger.error(ppp("Rx:", rx))
301 self.logger.error(ppp("Tx:", tx))
304 def verify_tunneled_4o6(self, src_if, capture, sent, tunnel_src, tunnel_dst):
305 self.assertEqual(len(capture), len(sent))
307 for i in range(len(capture)):
314 self.assertEqual(rx_ip.src, tunnel_src)
315 self.assertEqual(rx_ip.dst, tunnel_dst)
317 rx_gre = GRE(scapy.compat.raw(rx_ip[IPv6].payload))
319 self.assertEqual(rx_ip.plen, len(rx_gre))
324 self.assertEqual(rx_ip.src, tx_ip.src)
325 self.assertEqual(rx_ip.dst, tx_ip.dst)
328 self.logger.error(ppp("Rx:", rx))
329 self.logger.error(ppp("Tx:", tx))
332 def verify_tunneled_6o4(self, src_if, capture, sent, tunnel_src, tunnel_dst):
333 self.assertEqual(len(capture), len(sent))
335 for i in range(len(capture)):
342 self.assertEqual(rx_ip.src, tunnel_src)
343 self.assertEqual(rx_ip.dst, tunnel_dst)
344 self.assertEqual(rx_ip.len, len(rx_ip))
346 rx_gre = GRE(scapy.compat.raw(rx_ip[IP].payload))
350 self.assertEqual(rx_ip.src, tx_ip.src)
351 self.assertEqual(rx_ip.dst, tx_ip.dst)
354 self.logger.error(ppp("Rx:", rx))
355 self.logger.error(ppp("Tx:", tx))
358 def verify_tunneled_l2o4(self, src_if, capture, sent, tunnel_src, tunnel_dst):
359 self.assertEqual(len(capture), len(sent))
361 for i in range(len(capture)):
369 self.assertEqual(rx_ip.src, tunnel_src)
370 self.assertEqual(rx_ip.dst, tunnel_dst)
371 self.assertEqual(rx_ip.len, len(rx_ip))
374 rx_l2 = rx_gre[Ether]
377 tx_l2 = tx_gre[Ether]
380 self.assertEqual(rx_ip.src, tx_ip.src)
381 self.assertEqual(rx_ip.dst, tx_ip.dst)
382 # bridged, not L3 forwarded, so no TTL decrement
383 self.assertEqual(rx_ip.ttl, tx_ip.ttl)
386 self.logger.error(ppp("Rx:", rx))
387 self.logger.error(ppp("Tx:", tx))
390 def verify_tunneled_vlano4(
391 self, src_if, capture, sent, tunnel_src, tunnel_dst, vlan
394 self.assertEqual(len(capture), len(sent))
396 ppc("Unexpected packets captured:", capture)
399 for i in range(len(capture)):
407 self.assertEqual(rx_ip.src, tunnel_src)
408 self.assertEqual(rx_ip.dst, tunnel_dst)
411 rx_l2 = rx_gre[Ether]
412 rx_vlan = rx_l2[Dot1Q]
415 self.assertEqual(rx_vlan.vlan, vlan)
418 tx_l2 = tx_gre[Ether]
421 self.assertEqual(rx_ip.src, tx_ip.src)
422 self.assertEqual(rx_ip.dst, tx_ip.dst)
423 # bridged, not L3 forwarded, so no TTL decrement
424 self.assertEqual(rx_ip.ttl, tx_ip.ttl)
427 self.logger.error(ppp("Rx:", rx))
428 self.logger.error(ppp("Tx:", tx))
431 def verify_decapped_4o4(self, src_if, capture, sent):
432 self.assertEqual(len(capture), len(sent))
434 for i in range(len(capture)):
444 self.assertEqual(rx_ip.src, tx_ip.src)
445 self.assertEqual(rx_ip.dst, tx_ip.dst)
446 # IP processing post pop has decremented the TTL
447 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
450 self.logger.error(ppp("Rx:", rx))
451 self.logger.error(ppp("Tx:", tx))
454 def verify_decapped_6o4(self, src_if, capture, sent):
455 self.assertEqual(len(capture), len(sent))
457 for i in range(len(capture)):
467 self.assertEqual(rx_ip.src, tx_ip.src)
468 self.assertEqual(rx_ip.dst, tx_ip.dst)
469 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
472 self.logger.error(ppp("Rx:", rx))
473 self.logger.error(ppp("Tx:", tx))
476 def verify_decapped_6o6(self, src_if, capture, sent):
477 self.assertEqual(len(capture), len(sent))
479 for i in range(len(capture)):
489 self.assertEqual(rx_ip.src, tx_ip.src)
490 self.assertEqual(rx_ip.dst, tx_ip.dst)
491 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
494 self.logger.error(ppp("Rx:", rx))
495 self.logger.error(ppp("Tx:", tx))
499 """GRE IPv4 tunnel Tests"""
502 # Create an L3 GRE tunnel.
504 # - assign an IP Addres
505 # - Add a route via the tunnel
507 gre_if = VppGreInterface(self, self.pg0.local_ip4, "1.1.1.2")
508 gre_if.add_vpp_config()
511 # The double create (create the same tunnel twice) should fail,
512 # and we should still be able to use the original
515 gre_if.add_vpp_config()
519 self.fail("Double GRE tunnel add does not fail")
524 route_via_tun = VppIpRoute(
525 self, "4.4.4.4", 32, [VppRoutePath("0.0.0.0", gre_if.sw_if_index)]
528 route_via_tun.add_vpp_config()
531 # Send a packet stream that is routed into the tunnel
532 # - they are all dropped since the tunnel's destintation IP
533 # is unresolved - or resolves via the default route - which
536 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "4.4.4.4")
538 self.send_and_assert_no_replies(self.pg0, tx)
541 # Add a route that resolves the tunnel's destination
543 route_tun_dst = VppIpRoute(
547 [VppRoutePath(self.pg0.remote_ip4, self.pg0.sw_if_index)],
549 route_tun_dst.add_vpp_config()
552 # Send a packet stream that is routed into the tunnel
553 # - packets are GRE encapped
555 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "4.4.4.4")
556 rx = self.send_and_expect(self.pg0, tx, self.pg0)
557 self.verify_tunneled_4o4(self.pg0, rx, tx, self.pg0.local_ip4, "1.1.1.2")
560 # Send tunneled packets that match the created tunnel and
561 # are decapped and forwarded
563 tx = self.create_tunnel_stream_4o4(
570 rx = self.send_and_expect(self.pg0, tx, self.pg0)
571 self.verify_decapped_4o4(self.pg0, rx, tx)
574 # Send tunneled packets that do not match the tunnel's src
576 self.vapi.cli("clear trace")
577 tx = self.create_tunnel_stream_4o4(
584 self.send_and_assert_no_replies(
585 self.pg0, tx, remark="GRE packets forwarded despite no SRC address match"
589 # Configure IPv6 on the PG interface so we can route IPv6
592 self.pg0.config_ip6()
593 self.pg0.resolve_ndp()
596 # Send IPv6 tunnel encapslated packets
597 # - dropped since IPv6 is not enabled on the tunnel
599 tx = self.create_tunnel_stream_6o4(
606 self.send_and_assert_no_replies(
609 "IPv6 GRE packets forwarded despite IPv6 not enabled on tunnel",
613 # Enable IPv6 on the tunnel
618 # Send IPv6 tunnel encapslated packets
619 # - forwarded since IPv6 is enabled on the tunnel
621 tx = self.create_tunnel_stream_6o4(
628 rx = self.send_and_expect(self.pg0, tx, self.pg0)
629 self.verify_decapped_6o4(self.pg0, rx, tx)
632 # Send v6 packets for v4 encap
634 route6_via_tun = VppIpRoute(
638 [VppRoutePath("::", gre_if.sw_if_index, proto=DpoProto.DPO_PROTO_IP6)],
640 route6_via_tun.add_vpp_config()
642 tx = self.create_stream_ip6(self.pg0, "2001::2", "2001::1")
643 rx = self.send_and_expect(self.pg0, tx, self.pg0)
645 self.verify_tunneled_6o4(self.pg0, rx, tx, self.pg0.local_ip4, "1.1.1.2")
648 # add a labelled route through the tunnel
650 label_via_tun = VppIpRoute(
654 [VppRoutePath("0.0.0.0", gre_if.sw_if_index, labels=[VppMplsLabel(33)])],
656 label_via_tun.add_vpp_config()
658 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "5.4.3.2")
659 rx = self.send_and_expect(self.pg0, tx, self.pg0)
660 self.verify_tunneled_4o4(self.pg0, rx, tx, self.pg0.local_ip4, "1.1.1.2")
663 # an MPLS tunnel over the GRE tunnel add a route through
666 mpls_tun = VppMPLSTunnelInterface(
672 labels=[VppMplsLabel(44), VppMplsLabel(46)],
676 mpls_tun.add_vpp_config()
679 label_via_mpls = VppIpRoute(
683 [VppRoutePath("0.0.0.0", mpls_tun.sw_if_index, labels=[VppMplsLabel(33)])],
685 label_via_mpls.add_vpp_config()
687 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "5.4.3.1")
688 rx = self.send_and_expect(self.pg0, tx, self.pg0)
689 self.verify_tunneled_4o4(self.pg0, rx, tx, self.pg0.local_ip4, "1.1.1.2")
691 mpls_tun_l2 = VppMPLSTunnelInterface(
697 labels=[VppMplsLabel(44), VppMplsLabel(46)],
702 mpls_tun_l2.add_vpp_config()
703 mpls_tun_l2.admin_up()
708 route_tun_dst.remove_vpp_config()
709 route_via_tun.remove_vpp_config()
710 route6_via_tun.remove_vpp_config()
711 label_via_mpls.remove_vpp_config()
712 label_via_tun.remove_vpp_config()
713 mpls_tun.remove_vpp_config()
714 mpls_tun_l2.remove_vpp_config()
715 gre_if.remove_vpp_config()
717 self.pg0.unconfig_ip6()
720 """GRE IPv6 tunnel Tests"""
722 self.pg1.config_ip6()
723 self.pg1.resolve_ndp()
726 # Create an L3 GRE tunnel.
728 # - assign an IP Address
729 # - Add a route via the tunnel
731 gre_if = VppGreInterface(self, self.pg2.local_ip6, "1002::1")
732 gre_if.add_vpp_config()
736 route_via_tun = VppIpRoute(
737 self, "4004::1", 128, [VppRoutePath("0::0", gre_if.sw_if_index)]
740 route_via_tun.add_vpp_config()
743 # Send a packet stream that is routed into the tunnel
744 # - they are all dropped since the tunnel's destintation IP
745 # is unresolved - or resolves via the default route - which
748 tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
749 self.send_and_assert_no_replies(
750 self.pg2, tx, "GRE packets forwarded without DIP resolved"
754 # Add a route that resolves the tunnel's destination
756 route_tun_dst = VppIpRoute(
760 [VppRoutePath(self.pg2.remote_ip6, self.pg2.sw_if_index)],
762 route_tun_dst.add_vpp_config()
765 # Send a packet stream that is routed into the tunnel
766 # - packets are GRE encapped
768 tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
769 rx = self.send_and_expect(self.pg2, tx, self.pg2)
770 self.verify_tunneled_6o6(self.pg2, rx, tx, self.pg2.local_ip6, "1002::1")
773 # Test decap. decapped packets go out pg1
775 tx = self.create_tunnel_stream_6o6(
776 self.pg2, "1002::1", self.pg2.local_ip6, "2001::1", self.pg1.remote_ip6
778 rx = self.send_and_expect(self.pg2, tx, self.pg1)
781 # RX'd packet is UDP over IPv6, test the GRE header is gone.
783 self.assertFalse(rx[0].haslayer(GRE))
784 self.assertEqual(rx[0][IPv6].dst, self.pg1.remote_ip6)
789 route4_via_tun = VppIpRoute(
790 self, "1.1.1.1", 32, [VppRoutePath("0.0.0.0", gre_if.sw_if_index)]
792 route4_via_tun.add_vpp_config()
794 tx = self.create_stream_ip4(self.pg0, "1.1.1.2", "1.1.1.1")
795 rx = self.send_and_expect(self.pg0, tx, self.pg2)
797 self.verify_tunneled_4o6(self.pg0, rx, tx, self.pg2.local_ip6, "1002::1")
802 route_tun_dst.remove_vpp_config()
803 route_via_tun.remove_vpp_config()
804 route4_via_tun.remove_vpp_config()
805 gre_if.remove_vpp_config()
807 self.pg2.unconfig_ip6()
808 self.pg1.unconfig_ip6()
810 def test_gre_vrf(self):
811 """GRE tunnel VRF Tests"""
813 e = VppEnum.vl_api_tunnel_encap_decap_flags_t
816 # Create an L3 GRE tunnel whose destination is in the non-default
817 # table. The underlay is thus non-default - the overlay is still
820 # - assign an IP Addres
822 gre_if = VppGreInterface(
828 e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP
829 | e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN
833 gre_if.add_vpp_config()
838 # Add a route via the tunnel - in the overlay
840 route_via_tun = VppIpRoute(
841 self, "9.9.9.9", 32, [VppRoutePath("0.0.0.0", gre_if.sw_if_index)]
843 route_via_tun.add_vpp_config()
846 # Add a route that resolves the tunnel's destination - in the
849 route_tun_dst = VppIpRoute(
854 paths=[VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)],
856 route_tun_dst.add_vpp_config()
859 # Send a packet stream that is routed into the tunnel
860 # packets are sent in on pg0 which is in the default table
861 # - packets are GRE encapped
863 self.vapi.cli("clear trace")
864 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "9.9.9.9", dscp=5, ecn=3)
865 rx = self.send_and_expect(self.pg0, tx, self.pg1)
866 self.verify_tunneled_4o4(
867 self.pg1, rx, tx, self.pg1.local_ip4, "2.2.2.2", dscp=5, ecn=3
871 # Send tunneled packets that match the created tunnel and
872 # are decapped and forwarded. This tests the decap lookup
873 # does not happen in the encap table
875 self.vapi.cli("clear trace")
876 tx = self.create_tunnel_stream_4o4(
883 rx = self.send_and_expect(self.pg1, tx, self.pg0)
884 self.verify_decapped_4o4(self.pg0, rx, tx)
887 # Send tunneled packets that match the created tunnel
888 # but arrive on an interface that is not in the tunnel's
889 # encap VRF, these are dropped.
890 # IP enable the interface so they aren't dropped due to
891 # IP not being enabled.
893 self.pg2.config_ip4()
894 self.vapi.cli("clear trace")
895 tx = self.create_tunnel_stream_4o4(
902 rx = self.send_and_assert_no_replies(
903 self.pg2, tx, "GRE decap packets in wrong VRF"
906 self.pg2.unconfig_ip4()
911 route_tun_dst.remove_vpp_config()
912 route_via_tun.remove_vpp_config()
913 gre_if.remove_vpp_config()
915 def test_gre_l2(self):
916 """GRE tunnel L2 Tests"""
919 # Add routes to resolve the tunnel destinations
921 route_tun1_dst = VppIpRoute(
925 [VppRoutePath(self.pg0.remote_ip4, self.pg0.sw_if_index)],
927 route_tun2_dst = VppIpRoute(
931 [VppRoutePath(self.pg0.remote_ip4, self.pg0.sw_if_index)],
934 route_tun1_dst.add_vpp_config()
935 route_tun2_dst.add_vpp_config()
938 # Create 2 L2 GRE tunnels and x-connect them
940 gre_if1 = VppGreInterface(
944 type=(VppEnum.vl_api_gre_tunnel_type_t.GRE_API_TUNNEL_TYPE_TEB),
946 gre_if2 = VppGreInterface(
950 type=(VppEnum.vl_api_gre_tunnel_type_t.GRE_API_TUNNEL_TYPE_TEB),
952 gre_if1.add_vpp_config()
953 gre_if2.add_vpp_config()
958 self.vapi.sw_interface_set_l2_xconnect(
959 gre_if1.sw_if_index, gre_if2.sw_if_index, enable=1
961 self.vapi.sw_interface_set_l2_xconnect(
962 gre_if2.sw_if_index, gre_if1.sw_if_index, enable=1
966 # Send in tunnel encapped L2. expect out tunnel encapped L2
969 tx = self.create_tunnel_stream_l2o4(self.pg0, "2.2.2.2", self.pg0.local_ip4)
970 rx = self.send_and_expect(self.pg0, tx, self.pg0)
971 self.verify_tunneled_l2o4(self.pg0, rx, tx, self.pg0.local_ip4, "2.2.2.3")
973 tx = self.create_tunnel_stream_l2o4(self.pg0, "2.2.2.3", self.pg0.local_ip4)
974 rx = self.send_and_expect(self.pg0, tx, self.pg0)
975 self.verify_tunneled_l2o4(self.pg0, rx, tx, self.pg0.local_ip4, "2.2.2.2")
977 self.vapi.sw_interface_set_l2_xconnect(
978 gre_if1.sw_if_index, gre_if2.sw_if_index, enable=0
980 self.vapi.sw_interface_set_l2_xconnect(
981 gre_if2.sw_if_index, gre_if1.sw_if_index, enable=0
985 # Create a VLAN sub-interfaces on the GRE TEB interfaces
986 # then x-connect them
988 gre_if_11 = VppDot1QSubint(self, gre_if1, 11)
989 gre_if_12 = VppDot1QSubint(self, gre_if2, 12)
991 # gre_if_11.add_vpp_config()
992 # gre_if_12.add_vpp_config()
997 self.vapi.sw_interface_set_l2_xconnect(
998 gre_if_11.sw_if_index, gre_if_12.sw_if_index, enable=1
1000 self.vapi.sw_interface_set_l2_xconnect(
1001 gre_if_12.sw_if_index, gre_if_11.sw_if_index, enable=1
1005 # Configure both to pop thier respective VLAN tags,
1006 # so that during the x-coonect they will subsequently push
1008 self.vapi.l2_interface_vlan_tag_rewrite(
1009 sw_if_index=gre_if_12.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1, push_dot1q=12
1011 self.vapi.l2_interface_vlan_tag_rewrite(
1012 sw_if_index=gre_if_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1, push_dot1q=11
1016 # Send traffic in both directiond - expect the VLAN tags to
1019 tx = self.create_tunnel_stream_vlano4(
1020 self.pg0, "2.2.2.2", self.pg0.local_ip4, 11
1022 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1023 self.verify_tunneled_vlano4(self.pg0, rx, tx, self.pg0.local_ip4, "2.2.2.3", 12)
1025 tx = self.create_tunnel_stream_vlano4(
1026 self.pg0, "2.2.2.3", self.pg0.local_ip4, 12
1028 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1029 self.verify_tunneled_vlano4(self.pg0, rx, tx, self.pg0.local_ip4, "2.2.2.2", 11)
1032 # Cleanup Test resources
1034 gre_if_11.remove_vpp_config()
1035 gre_if_12.remove_vpp_config()
1036 gre_if1.remove_vpp_config()
1037 gre_if2.remove_vpp_config()
1038 route_tun1_dst.add_vpp_config()
1039 route_tun2_dst.add_vpp_config()
1041 def test_gre_loop(self):
1042 """GRE tunnel loop Tests"""
1045 # Create an L3 GRE tunnel.
1047 # - assign an IP Addres
1049 gre_if = VppGreInterface(self, self.pg0.local_ip4, "1.1.1.2")
1050 gre_if.add_vpp_config()
1055 # add a route to the tunnel's destination that points
1056 # through the tunnel, hence forming a loop in the forwarding
1059 route_dst = VppIpRoute(
1060 self, "1.1.1.2", 32, [VppRoutePath("0.0.0.0", gre_if.sw_if_index)]
1062 route_dst.add_vpp_config()
1065 # packets to the tunnels destination should be dropped
1067 tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "1.1.1.2")
1068 self.send_and_assert_no_replies(self.pg2, tx)
1070 self.logger.info(self.vapi.ppcli("sh adj 7"))
1075 route_dst.modify([VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)])
1076 route_dst.add_vpp_config()
1078 rx = self.send_and_expect(self.pg0, tx, self.pg1)
1081 # a good route throught the tunnel to check it restacked
1083 route_via_tun_2 = VppIpRoute(
1084 self, "2.2.2.2", 32, [VppRoutePath("0.0.0.0", gre_if.sw_if_index)]
1086 route_via_tun_2.add_vpp_config()
1088 tx = self.create_stream_ip4(self.pg0, "2.2.2.3", "2.2.2.2")
1089 rx = self.send_and_expect(self.pg0, tx, self.pg1)
1090 self.verify_tunneled_4o4(self.pg1, rx, tx, self.pg0.local_ip4, "1.1.1.2")
1095 route_via_tun_2.remove_vpp_config()
1096 gre_if.remove_vpp_config()
1098 def test_mgre(self):
1099 """mGRE IPv4 tunnel Tests"""
1101 for itf in self.pg_interfaces[3:]:
1103 # one underlay nh for each overlay/tunnel peer
1105 itf.generate_remote_hosts(4)
1106 itf.configure_ipv4_neighbors()
1109 # Create an L3 GRE tunnel.
1111 # - assign an IP Addres
1112 # - Add a route via the tunnel
1114 gre_if = VppGreInterface(
1118 mode=(VppEnum.vl_api_tunnel_mode_t.TUNNEL_API_MODE_MP),
1120 gre_if.add_vpp_config()
1123 gre_if.generate_remote_hosts(4)
1125 self.logger.info(self.vapi.cli("sh adj"))
1126 self.logger.info(self.vapi.cli("sh ip fib"))
1129 # ensure we don't match to the tunnel if the source address
1132 tx = self.create_tunnel_stream_4o4(
1137 self.pg0.remote_ip4,
1139 self.send_and_assert_no_replies(self.pg0, tx)
1144 for ii in range(1, 4):
1145 route_addr = "4.4.4.%d" % ii
1146 tx_e = self.create_stream_ip4(self.pg0, "5.5.5.5", route_addr)
1149 # route traffic via the peer
1151 route_via_tun = VppIpRoute(
1155 [VppRoutePath(gre_if._remote_hosts[ii].ip4, gre_if.sw_if_index)],
1157 route_via_tun.add_vpp_config()
1159 # all packets dropped at this point
1160 rx = self.send_and_assert_no_replies(self.pg0, tx_e)
1164 rx = self.send_and_assert_no_replies(self.pg0, tx_e)
1167 # Add a TEIB entry resolves the peer
1172 gre_if._remote_hosts[ii].ip4,
1173 itf._remote_hosts[ii].ip4,
1175 teib.add_vpp_config()
1178 # Send a packet stream that is routed into the tunnel
1179 # - packets are GRE encapped
1181 rx = self.send_and_expect(self.pg0, tx_e, itf)
1182 self.verify_tunneled_4o4(
1183 self.pg0, rx, tx_e, itf.local_ip4, itf._remote_hosts[ii].ip4
1186 tx_i = self.create_tunnel_stream_4o4(
1188 itf._remote_hosts[ii].ip4,
1191 self.pg0.remote_ip4,
1193 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1194 self.verify_decapped_4o4(self.pg0, rx, tx_i)
1197 # delete and re-add the TEIB
1199 teib.remove_vpp_config()
1200 self.send_and_assert_no_replies(self.pg0, tx_e)
1201 self.send_and_assert_no_replies(self.pg0, tx_i)
1203 teib.add_vpp_config()
1204 rx = self.send_and_expect(self.pg0, tx_e, itf)
1205 self.verify_tunneled_4o4(
1206 self.pg0, rx, tx_e, itf.local_ip4, itf._remote_hosts[ii].ip4
1208 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1209 self.verify_decapped_4o4(self.pg0, rx, tx_i)
1212 # bounce the interface state and try packets again
1216 rx = self.send_and_expect(self.pg0, tx_e, itf)
1217 self.verify_tunneled_4o4(
1218 self.pg0, rx, tx_e, itf.local_ip4, itf._remote_hosts[ii].ip4
1220 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1221 self.verify_decapped_4o4(self.pg0, rx, tx_i)
1224 gre_if.unconfig_ip4()
1226 def test_mgre6(self):
1227 """mGRE IPv6 tunnel Tests"""
1229 self.pg0.config_ip6()
1230 self.pg0.resolve_ndp()
1232 e = VppEnum.vl_api_tunnel_encap_decap_flags_t
1234 for itf in self.pg_interfaces[3:]:
1236 # one underlay nh for each overlay/tunnel peer
1239 itf.generate_remote_hosts(4)
1240 itf.configure_ipv6_neighbors()
1243 # Create an L3 GRE tunnel.
1245 # - assign an IP Addres
1246 # - Add a route via the tunnel
1248 gre_if = VppGreInterface(
1252 mode=(VppEnum.vl_api_tunnel_mode_t.TUNNEL_API_MODE_MP),
1253 flags=e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP,
1256 gre_if.add_vpp_config()
1259 gre_if.generate_remote_hosts(4)
1264 for ii in range(1, 4):
1265 route_addr = "4::%d" % ii
1268 # Add a TEIB entry resolves the peer
1273 gre_if._remote_hosts[ii].ip6,
1274 itf._remote_hosts[ii].ip6,
1276 teib.add_vpp_config()
1279 # route traffic via the peer
1281 route_via_tun = VppIpRoute(
1285 [VppRoutePath(gre_if._remote_hosts[ii].ip6, gre_if.sw_if_index)],
1287 route_via_tun.add_vpp_config()
1290 # Send a packet stream that is routed into the tunnel
1291 # - packets are GRE encapped
1293 tx_e = self.create_stream_ip6(
1294 self.pg0, "5::5", route_addr, dscp=2, ecn=1
1296 rx = self.send_and_expect(self.pg0, tx_e, itf)
1297 self.verify_tunneled_6o6(
1298 self.pg0, rx, tx_e, itf.local_ip6, itf._remote_hosts[ii].ip6, dscp=2
1300 tx_i = self.create_tunnel_stream_6o6(
1302 itf._remote_hosts[ii].ip6,
1305 self.pg0.remote_ip6,
1307 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1308 self.verify_decapped_6o6(self.pg0, rx, tx_i)
1311 # delete and re-add the TEIB
1313 teib.remove_vpp_config()
1314 self.send_and_assert_no_replies(self.pg0, tx_e)
1316 teib.add_vpp_config()
1317 rx = self.send_and_expect(self.pg0, tx_e, itf)
1318 self.verify_tunneled_6o6(
1319 self.pg0, rx, tx_e, itf.local_ip6, itf._remote_hosts[ii].ip6, dscp=2
1321 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1322 self.verify_decapped_6o6(self.pg0, rx, tx_i)
1325 gre_if.unconfig_ip4()
1327 self.pg0.unconfig_ip6()
1330 if __name__ == "__main__":
1331 unittest.main(testRunner=VppTestRunner)