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 VppTestCase
13 from asfframework import VppTestRunner, tag_fixme_vpp_workers
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 (
24 from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
25 from util import ppp, ppc
26 from vpp_papi import VppEnum
29 @tag_fixme_vpp_workers
30 class TestGREInputNodes(VppTestCase):
31 """GRE Input Nodes Test Case"""
34 super(TestGREInputNodes, self).setUp()
36 # create 3 pg interfaces - set one in a non-default table.
37 self.create_pg_interfaces(range(1))
39 for i in self.pg_interfaces:
44 for i in self.pg_interfaces:
47 super(TestGREInputNodes, self).tearDown()
49 def test_gre_input_node(self):
50 """GRE gre input nodes not registerd unless configured"""
52 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
53 / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
57 self.pg0.add_stream(pkt)
59 # no tunnel created, gre-input not registered
60 err = self.statistics.get_counter("/err/ip4-local/unknown_protocol")[0]
61 self.assertEqual(err, 1)
65 gre_if = VppGreInterface(self, self.pg0.local_ip4, "1.1.1.2")
66 gre_if.add_vpp_config()
68 self.pg0.add_stream(pkt)
70 # tunnel created, gre-input registered
71 err = self.statistics.get_counter("/err/ip4-local/unknown_protocol")[0]
72 # expect no new errors
73 self.assertEqual(err, err_count)
76 class TestGRE(VppTestCase):
81 super(TestGRE, cls).setUpClass()
84 def tearDownClass(cls):
85 super(TestGRE, cls).tearDownClass()
88 super(TestGRE, self).setUp()
90 # create 3 pg interfaces - set one in a non-default table.
91 self.create_pg_interfaces(range(5))
93 self.tbl = VppIpTable(self, 1)
94 self.tbl.add_vpp_config()
95 self.pg1.set_table_ip4(1)
97 for i in self.pg_interfaces:
100 self.pg0.config_ip4()
101 self.pg0.resolve_arp()
102 self.pg1.config_ip4()
103 self.pg1.resolve_arp()
104 self.pg2.config_ip6()
105 self.pg2.resolve_ndp()
106 self.pg3.config_ip4()
107 self.pg3.resolve_arp()
108 self.pg4.config_ip4()
109 self.pg4.resolve_arp()
112 for i in self.pg_interfaces:
116 self.pg1.set_table_ip4(0)
117 super(TestGRE, self).tearDown()
119 def create_stream_ip4(self, src_if, src_ip, dst_ip, dscp=0, ecn=0):
121 tos = (dscp << 2) | ecn
122 for i in range(0, 257):
123 info = self.create_packet_info(src_if, src_if)
124 payload = self.info_to_payload(info)
126 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
127 / IP(src=src_ip, dst=dst_ip, tos=tos)
128 / UDP(sport=1234, dport=1234)
135 def create_stream_ip6(self, src_if, src_ip, dst_ip, dscp=0, ecn=0):
137 tc = (dscp << 2) | ecn
138 for i in range(0, 257):
139 info = self.create_packet_info(src_if, src_if)
140 payload = self.info_to_payload(info)
142 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
143 / IPv6(src=src_ip, dst=dst_ip, tc=tc)
144 / UDP(sport=1234, dport=1234)
151 def create_tunnel_stream_4o4(self, src_if, tunnel_src, tunnel_dst, src_ip, dst_ip):
153 for i in range(0, 257):
154 info = self.create_packet_info(src_if, src_if)
155 payload = self.info_to_payload(info)
157 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
158 / IP(src=tunnel_src, dst=tunnel_dst)
160 / IP(src=src_ip, dst=dst_ip)
161 / UDP(sport=1234, dport=1234)
168 def create_tunnel_stream_6o4(self, src_if, tunnel_src, tunnel_dst, src_ip, dst_ip):
170 for i in range(0, 257):
171 info = self.create_packet_info(src_if, src_if)
172 payload = self.info_to_payload(info)
174 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
175 / IP(src=tunnel_src, dst=tunnel_dst)
177 / IPv6(src=src_ip, dst=dst_ip)
178 / UDP(sport=1234, dport=1234)
185 def create_tunnel_stream_6o6(self, src_if, tunnel_src, tunnel_dst, src_ip, dst_ip):
187 for i in range(0, 257):
188 info = self.create_packet_info(src_if, src_if)
189 payload = self.info_to_payload(info)
191 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
192 / IPv6(src=tunnel_src, dst=tunnel_dst)
194 / IPv6(src=src_ip, dst=dst_ip)
195 / UDP(sport=1234, dport=1234)
202 def create_tunnel_stream_l2o4(self, src_if, tunnel_src, tunnel_dst):
204 for i in range(0, 257):
205 info = self.create_packet_info(src_if, src_if)
206 payload = self.info_to_payload(info)
208 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
209 / IP(src=tunnel_src, dst=tunnel_dst)
211 / Ether(dst=RandMAC("*:*:*:*:*:*"), src=RandMAC("*:*:*:*:*:*"))
212 / IP(src=scapy.compat.raw(RandIP()), dst=scapy.compat.raw(RandIP()))
213 / UDP(sport=1234, dport=1234)
220 def create_tunnel_stream_vlano4(self, src_if, tunnel_src, tunnel_dst, vlan):
222 for i in range(0, 257):
223 info = self.create_packet_info(src_if, src_if)
224 payload = self.info_to_payload(info)
226 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
227 / IP(src=tunnel_src, dst=tunnel_dst)
229 / Ether(dst=RandMAC("*:*:*:*:*:*"), src=RandMAC("*:*:*:*:*:*"))
231 / IP(src=scapy.compat.raw(RandIP()), dst=scapy.compat.raw(RandIP()))
232 / UDP(sport=1234, dport=1234)
239 def verify_tunneled_4o4(
240 self, src_if, capture, sent, tunnel_src, tunnel_dst, dscp=0, ecn=0
242 self.assertEqual(len(capture), len(sent))
243 tos = (dscp << 2) | ecn
245 for i in range(len(capture)):
253 self.assertEqual(rx_ip.src, tunnel_src)
254 self.assertEqual(rx_ip.dst, tunnel_dst)
255 self.assertEqual(rx_ip.tos, tos)
256 self.assertEqual(rx_ip.len, len(rx_ip))
261 self.assertEqual(rx_ip.src, tx_ip.src)
262 self.assertEqual(rx_ip.dst, tx_ip.dst)
263 # IP processing post pop has decremented the TTL
264 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
267 self.logger.error(ppp("Rx:", rx))
268 self.logger.error(ppp("Tx:", tx))
271 def verify_tunneled_6o6(
272 self, src_if, capture, sent, tunnel_src, tunnel_dst, dscp=0, ecn=0
274 self.assertEqual(len(capture), len(sent))
275 tc = (dscp << 2) | ecn
277 for i in range(len(capture)):
285 self.assertEqual(rx_ip.src, tunnel_src)
286 self.assertEqual(rx_ip.dst, tunnel_dst)
287 self.assertEqual(rx_ip.tc, tc)
289 rx_gre = GRE(scapy.compat.raw(rx_ip[IPv6].payload))
291 self.assertEqual(rx_ip.plen, len(rx_gre))
295 self.assertEqual(rx_ip.src, tx_ip.src)
296 self.assertEqual(rx_ip.dst, tx_ip.dst)
299 self.logger.error(ppp("Rx:", rx))
300 self.logger.error(ppp("Tx:", tx))
303 def verify_tunneled_4o6(self, src_if, capture, sent, tunnel_src, tunnel_dst):
304 self.assertEqual(len(capture), len(sent))
306 for i in range(len(capture)):
313 self.assertEqual(rx_ip.src, tunnel_src)
314 self.assertEqual(rx_ip.dst, tunnel_dst)
316 rx_gre = GRE(scapy.compat.raw(rx_ip[IPv6].payload))
318 self.assertEqual(rx_ip.plen, len(rx_gre))
323 self.assertEqual(rx_ip.src, tx_ip.src)
324 self.assertEqual(rx_ip.dst, tx_ip.dst)
327 self.logger.error(ppp("Rx:", rx))
328 self.logger.error(ppp("Tx:", tx))
331 def verify_tunneled_6o4(self, src_if, capture, sent, tunnel_src, tunnel_dst):
332 self.assertEqual(len(capture), len(sent))
334 for i in range(len(capture)):
341 self.assertEqual(rx_ip.src, tunnel_src)
342 self.assertEqual(rx_ip.dst, tunnel_dst)
343 self.assertEqual(rx_ip.len, len(rx_ip))
345 rx_gre = GRE(scapy.compat.raw(rx_ip[IP].payload))
349 self.assertEqual(rx_ip.src, tx_ip.src)
350 self.assertEqual(rx_ip.dst, tx_ip.dst)
353 self.logger.error(ppp("Rx:", rx))
354 self.logger.error(ppp("Tx:", tx))
357 def verify_tunneled_l2o4(self, src_if, capture, sent, tunnel_src, tunnel_dst):
358 self.assertEqual(len(capture), len(sent))
360 for i in range(len(capture)):
368 self.assertEqual(rx_ip.src, tunnel_src)
369 self.assertEqual(rx_ip.dst, tunnel_dst)
370 self.assertEqual(rx_ip.len, len(rx_ip))
373 rx_l2 = rx_gre[Ether]
376 tx_l2 = tx_gre[Ether]
379 self.assertEqual(rx_ip.src, tx_ip.src)
380 self.assertEqual(rx_ip.dst, tx_ip.dst)
381 # bridged, not L3 forwarded, so no TTL decrement
382 self.assertEqual(rx_ip.ttl, tx_ip.ttl)
385 self.logger.error(ppp("Rx:", rx))
386 self.logger.error(ppp("Tx:", tx))
389 def verify_tunneled_vlano4(
390 self, src_if, capture, sent, tunnel_src, tunnel_dst, vlan
393 self.assertEqual(len(capture), len(sent))
395 ppc("Unexpected packets captured:", capture)
398 for i in range(len(capture)):
406 self.assertEqual(rx_ip.src, tunnel_src)
407 self.assertEqual(rx_ip.dst, tunnel_dst)
410 rx_l2 = rx_gre[Ether]
411 rx_vlan = rx_l2[Dot1Q]
414 self.assertEqual(rx_vlan.vlan, vlan)
417 tx_l2 = tx_gre[Ether]
420 self.assertEqual(rx_ip.src, tx_ip.src)
421 self.assertEqual(rx_ip.dst, tx_ip.dst)
422 # bridged, not L3 forwarded, so no TTL decrement
423 self.assertEqual(rx_ip.ttl, tx_ip.ttl)
426 self.logger.error(ppp("Rx:", rx))
427 self.logger.error(ppp("Tx:", tx))
430 def verify_decapped_4o4(self, src_if, capture, sent):
431 self.assertEqual(len(capture), len(sent))
433 for i in range(len(capture)):
443 self.assertEqual(rx_ip.src, tx_ip.src)
444 self.assertEqual(rx_ip.dst, tx_ip.dst)
445 # IP processing post pop has decremented the TTL
446 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
449 self.logger.error(ppp("Rx:", rx))
450 self.logger.error(ppp("Tx:", tx))
453 def verify_decapped_6o4(self, src_if, capture, sent):
454 self.assertEqual(len(capture), len(sent))
456 for i in range(len(capture)):
466 self.assertEqual(rx_ip.src, tx_ip.src)
467 self.assertEqual(rx_ip.dst, tx_ip.dst)
468 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
471 self.logger.error(ppp("Rx:", rx))
472 self.logger.error(ppp("Tx:", tx))
475 def verify_decapped_6o6(self, src_if, capture, sent):
476 self.assertEqual(len(capture), len(sent))
478 for i in range(len(capture)):
488 self.assertEqual(rx_ip.src, tx_ip.src)
489 self.assertEqual(rx_ip.dst, tx_ip.dst)
490 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
493 self.logger.error(ppp("Rx:", rx))
494 self.logger.error(ppp("Tx:", tx))
498 """GRE IPv4 tunnel Tests"""
501 # Create an L3 GRE tunnel.
503 # - assign an IP Addres
504 # - Add a route via the tunnel
506 gre_if = VppGreInterface(self, self.pg0.local_ip4, "1.1.1.2")
507 gre_if.add_vpp_config()
510 # The double create (create the same tunnel twice) should fail,
511 # and we should still be able to use the original
514 gre_if.add_vpp_config()
518 self.fail("Double GRE tunnel add does not fail")
523 route_via_tun = VppIpRoute(
524 self, "4.4.4.4", 32, [VppRoutePath("0.0.0.0", gre_if.sw_if_index)]
527 route_via_tun.add_vpp_config()
530 # Send a packet stream that is routed into the tunnel
531 # - they are all dropped since the tunnel's destintation IP
532 # is unresolved - or resolves via the default route - which
535 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "4.4.4.4")
537 self.send_and_assert_no_replies(self.pg0, tx)
540 # Add a route that resolves the tunnel's destination
542 route_tun_dst = VppIpRoute(
546 [VppRoutePath(self.pg0.remote_ip4, self.pg0.sw_if_index)],
548 route_tun_dst.add_vpp_config()
551 # Send a packet stream that is routed into the tunnel
552 # - packets are GRE encapped
554 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "4.4.4.4")
555 rx = self.send_and_expect(self.pg0, tx, self.pg0)
556 self.verify_tunneled_4o4(self.pg0, rx, tx, self.pg0.local_ip4, "1.1.1.2")
559 # Send tunneled packets that match the created tunnel and
560 # are decapped and forwarded
562 tx = self.create_tunnel_stream_4o4(
569 rx = self.send_and_expect(self.pg0, tx, self.pg0)
570 self.verify_decapped_4o4(self.pg0, rx, tx)
573 # Send tunneled packets that do not match the tunnel's src
575 self.vapi.cli("clear trace")
576 tx = self.create_tunnel_stream_4o4(
583 self.send_and_assert_no_replies(
584 self.pg0, tx, remark="GRE packets forwarded despite no SRC address match"
588 # Configure IPv6 on the PG interface so we can route IPv6
591 self.pg0.config_ip6()
592 self.pg0.resolve_ndp()
595 # Send IPv6 tunnel encapslated packets
596 # - dropped since IPv6 is not enabled on the tunnel
598 tx = self.create_tunnel_stream_6o4(
605 self.send_and_assert_no_replies(
608 "IPv6 GRE packets forwarded despite IPv6 not enabled on tunnel",
612 # Enable IPv6 on the tunnel
617 # Send IPv6 tunnel encapslated packets
618 # - forwarded since IPv6 is enabled on the tunnel
620 tx = self.create_tunnel_stream_6o4(
627 rx = self.send_and_expect(self.pg0, tx, self.pg0)
628 self.verify_decapped_6o4(self.pg0, rx, tx)
631 # Send v6 packets for v4 encap
633 route6_via_tun = VppIpRoute(
637 [VppRoutePath("::", gre_if.sw_if_index, proto=DpoProto.DPO_PROTO_IP6)],
639 route6_via_tun.add_vpp_config()
641 tx = self.create_stream_ip6(self.pg0, "2001::2", "2001::1")
642 rx = self.send_and_expect(self.pg0, tx, self.pg0)
644 self.verify_tunneled_6o4(self.pg0, rx, tx, self.pg0.local_ip4, "1.1.1.2")
647 # add a labelled route through the tunnel
649 label_via_tun = VppIpRoute(
653 [VppRoutePath("0.0.0.0", gre_if.sw_if_index, labels=[VppMplsLabel(33)])],
655 label_via_tun.add_vpp_config()
657 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "5.4.3.2")
658 rx = self.send_and_expect(self.pg0, tx, self.pg0)
659 self.verify_tunneled_4o4(self.pg0, rx, tx, self.pg0.local_ip4, "1.1.1.2")
662 # an MPLS tunnel over the GRE tunnel add a route through
665 mpls_tun = VppMPLSTunnelInterface(
671 labels=[VppMplsLabel(44), VppMplsLabel(46)],
675 mpls_tun.add_vpp_config()
678 label_via_mpls = VppIpRoute(
682 [VppRoutePath("0.0.0.0", mpls_tun.sw_if_index, labels=[VppMplsLabel(33)])],
684 label_via_mpls.add_vpp_config()
686 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "5.4.3.1")
687 rx = self.send_and_expect(self.pg0, tx, self.pg0)
688 self.verify_tunneled_4o4(self.pg0, rx, tx, self.pg0.local_ip4, "1.1.1.2")
690 mpls_tun_l2 = VppMPLSTunnelInterface(
696 labels=[VppMplsLabel(44), VppMplsLabel(46)],
701 mpls_tun_l2.add_vpp_config()
702 mpls_tun_l2.admin_up()
707 route_tun_dst.remove_vpp_config()
708 route_via_tun.remove_vpp_config()
709 route6_via_tun.remove_vpp_config()
710 label_via_mpls.remove_vpp_config()
711 label_via_tun.remove_vpp_config()
712 mpls_tun.remove_vpp_config()
713 mpls_tun_l2.remove_vpp_config()
714 gre_if.remove_vpp_config()
716 self.pg0.unconfig_ip6()
719 """GRE IPv6 tunnel Tests"""
721 self.pg1.config_ip6()
722 self.pg1.resolve_ndp()
725 # Create an L3 GRE tunnel.
727 # - assign an IP Address
728 # - Add a route via the tunnel
730 gre_if = VppGreInterface(self, self.pg2.local_ip6, "1002::1")
731 gre_if.add_vpp_config()
735 route_via_tun = VppIpRoute(
736 self, "4004::1", 128, [VppRoutePath("0::0", gre_if.sw_if_index)]
739 route_via_tun.add_vpp_config()
742 # Send a packet stream that is routed into the tunnel
743 # - they are all dropped since the tunnel's destintation IP
744 # is unresolved - or resolves via the default route - which
747 tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
748 self.send_and_assert_no_replies(
749 self.pg2, tx, "GRE packets forwarded without DIP resolved"
753 # Add a route that resolves the tunnel's destination
755 route_tun_dst = VppIpRoute(
759 [VppRoutePath(self.pg2.remote_ip6, self.pg2.sw_if_index)],
761 route_tun_dst.add_vpp_config()
764 # Send a packet stream that is routed into the tunnel
765 # - packets are GRE encapped
767 tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
768 rx = self.send_and_expect(self.pg2, tx, self.pg2)
769 self.verify_tunneled_6o6(self.pg2, rx, tx, self.pg2.local_ip6, "1002::1")
772 # Test decap. decapped packets go out pg1
774 tx = self.create_tunnel_stream_6o6(
775 self.pg2, "1002::1", self.pg2.local_ip6, "2001::1", self.pg1.remote_ip6
777 rx = self.send_and_expect(self.pg2, tx, self.pg1)
780 # RX'd packet is UDP over IPv6, test the GRE header is gone.
782 self.assertFalse(rx[0].haslayer(GRE))
783 self.assertEqual(rx[0][IPv6].dst, self.pg1.remote_ip6)
788 route4_via_tun = VppIpRoute(
789 self, "1.1.1.1", 32, [VppRoutePath("0.0.0.0", gre_if.sw_if_index)]
791 route4_via_tun.add_vpp_config()
793 tx = self.create_stream_ip4(self.pg0, "1.1.1.2", "1.1.1.1")
794 rx = self.send_and_expect(self.pg0, tx, self.pg2)
796 self.verify_tunneled_4o6(self.pg0, rx, tx, self.pg2.local_ip6, "1002::1")
801 route_tun_dst.remove_vpp_config()
802 route_via_tun.remove_vpp_config()
803 route4_via_tun.remove_vpp_config()
804 gre_if.remove_vpp_config()
806 self.pg2.unconfig_ip6()
807 self.pg1.unconfig_ip6()
809 def test_gre_vrf(self):
810 """GRE tunnel VRF Tests"""
812 e = VppEnum.vl_api_tunnel_encap_decap_flags_t
815 # Create an L3 GRE tunnel whose destination is in the non-default
816 # table. The underlay is thus non-default - the overlay is still
819 # - assign an IP Addres
821 gre_if = VppGreInterface(
827 e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP
828 | e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN
832 gre_if.add_vpp_config()
837 # Add a route via the tunnel - in the overlay
839 route_via_tun = VppIpRoute(
840 self, "9.9.9.9", 32, [VppRoutePath("0.0.0.0", gre_if.sw_if_index)]
842 route_via_tun.add_vpp_config()
845 # Add a route that resolves the tunnel's destination - in the
848 route_tun_dst = VppIpRoute(
853 paths=[VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)],
855 route_tun_dst.add_vpp_config()
858 # Send a packet stream that is routed into the tunnel
859 # packets are sent in on pg0 which is in the default table
860 # - packets are GRE encapped
862 self.vapi.cli("clear trace")
863 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "9.9.9.9", dscp=5, ecn=3)
864 rx = self.send_and_expect(self.pg0, tx, self.pg1)
865 self.verify_tunneled_4o4(
866 self.pg1, rx, tx, self.pg1.local_ip4, "2.2.2.2", dscp=5, ecn=3
870 # Send tunneled packets that match the created tunnel and
871 # are decapped and forwarded. This tests the decap lookup
872 # does not happen in the encap table
874 self.vapi.cli("clear trace")
875 tx = self.create_tunnel_stream_4o4(
882 rx = self.send_and_expect(self.pg1, tx, self.pg0)
883 self.verify_decapped_4o4(self.pg0, rx, tx)
886 # Send tunneled packets that match the created tunnel
887 # but arrive on an interface that is not in the tunnel's
888 # encap VRF, these are dropped.
889 # IP enable the interface so they aren't dropped due to
890 # IP not being enabled.
892 self.pg2.config_ip4()
893 self.vapi.cli("clear trace")
894 tx = self.create_tunnel_stream_4o4(
901 rx = self.send_and_assert_no_replies(
902 self.pg2, tx, "GRE decap packets in wrong VRF"
905 self.pg2.unconfig_ip4()
910 route_tun_dst.remove_vpp_config()
911 route_via_tun.remove_vpp_config()
912 gre_if.remove_vpp_config()
914 def test_gre_l2(self):
915 """GRE tunnel L2 Tests"""
918 # Add routes to resolve the tunnel destinations
920 route_tun1_dst = VppIpRoute(
924 [VppRoutePath(self.pg0.remote_ip4, self.pg0.sw_if_index)],
926 route_tun2_dst = VppIpRoute(
930 [VppRoutePath(self.pg0.remote_ip4, self.pg0.sw_if_index)],
933 route_tun1_dst.add_vpp_config()
934 route_tun2_dst.add_vpp_config()
937 # Create 2 L2 GRE tunnels and x-connect them
939 gre_if1 = VppGreInterface(
943 type=(VppEnum.vl_api_gre_tunnel_type_t.GRE_API_TUNNEL_TYPE_TEB),
945 gre_if2 = VppGreInterface(
949 type=(VppEnum.vl_api_gre_tunnel_type_t.GRE_API_TUNNEL_TYPE_TEB),
951 gre_if1.add_vpp_config()
952 gre_if2.add_vpp_config()
957 self.vapi.sw_interface_set_l2_xconnect(
958 gre_if1.sw_if_index, gre_if2.sw_if_index, enable=1
960 self.vapi.sw_interface_set_l2_xconnect(
961 gre_if2.sw_if_index, gre_if1.sw_if_index, enable=1
965 # Send in tunnel encapped L2. expect out tunnel encapped L2
968 tx = self.create_tunnel_stream_l2o4(self.pg0, "2.2.2.2", self.pg0.local_ip4)
969 rx = self.send_and_expect(self.pg0, tx, self.pg0)
970 self.verify_tunneled_l2o4(self.pg0, rx, tx, self.pg0.local_ip4, "2.2.2.3")
972 tx = self.create_tunnel_stream_l2o4(self.pg0, "2.2.2.3", self.pg0.local_ip4)
973 rx = self.send_and_expect(self.pg0, tx, self.pg0)
974 self.verify_tunneled_l2o4(self.pg0, rx, tx, self.pg0.local_ip4, "2.2.2.2")
976 self.vapi.sw_interface_set_l2_xconnect(
977 gre_if1.sw_if_index, gre_if2.sw_if_index, enable=0
979 self.vapi.sw_interface_set_l2_xconnect(
980 gre_if2.sw_if_index, gre_if1.sw_if_index, enable=0
984 # Create a VLAN sub-interfaces on the GRE TEB interfaces
985 # then x-connect them
987 gre_if_11 = VppDot1QSubint(self, gre_if1, 11)
988 gre_if_12 = VppDot1QSubint(self, gre_if2, 12)
990 # gre_if_11.add_vpp_config()
991 # gre_if_12.add_vpp_config()
996 self.vapi.sw_interface_set_l2_xconnect(
997 gre_if_11.sw_if_index, gre_if_12.sw_if_index, enable=1
999 self.vapi.sw_interface_set_l2_xconnect(
1000 gre_if_12.sw_if_index, gre_if_11.sw_if_index, enable=1
1004 # Configure both to pop thier respective VLAN tags,
1005 # so that during the x-coonect they will subsequently push
1007 self.vapi.l2_interface_vlan_tag_rewrite(
1008 sw_if_index=gre_if_12.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1, push_dot1q=12
1010 self.vapi.l2_interface_vlan_tag_rewrite(
1011 sw_if_index=gre_if_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1, push_dot1q=11
1015 # Send traffic in both directiond - expect the VLAN tags to
1018 tx = self.create_tunnel_stream_vlano4(
1019 self.pg0, "2.2.2.2", self.pg0.local_ip4, 11
1021 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1022 self.verify_tunneled_vlano4(self.pg0, rx, tx, self.pg0.local_ip4, "2.2.2.3", 12)
1024 tx = self.create_tunnel_stream_vlano4(
1025 self.pg0, "2.2.2.3", self.pg0.local_ip4, 12
1027 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1028 self.verify_tunneled_vlano4(self.pg0, rx, tx, self.pg0.local_ip4, "2.2.2.2", 11)
1031 # Cleanup Test resources
1033 gre_if_11.remove_vpp_config()
1034 gre_if_12.remove_vpp_config()
1035 gre_if1.remove_vpp_config()
1036 gre_if2.remove_vpp_config()
1037 route_tun1_dst.add_vpp_config()
1038 route_tun2_dst.add_vpp_config()
1040 def test_gre_loop(self):
1041 """GRE tunnel loop Tests"""
1044 # Create an L3 GRE tunnel.
1046 # - assign an IP Addres
1048 gre_if = VppGreInterface(self, self.pg0.local_ip4, "1.1.1.2")
1049 gre_if.add_vpp_config()
1054 # add a route to the tunnel's destination that points
1055 # through the tunnel, hence forming a loop in the forwarding
1058 route_dst = VppIpRoute(
1059 self, "1.1.1.2", 32, [VppRoutePath("0.0.0.0", gre_if.sw_if_index)]
1061 route_dst.add_vpp_config()
1064 # packets to the tunnels destination should be dropped
1066 tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "1.1.1.2")
1067 self.send_and_assert_no_replies(self.pg2, tx)
1069 self.logger.info(self.vapi.ppcli("sh adj 7"))
1074 route_dst.modify([VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)])
1075 route_dst.add_vpp_config()
1077 rx = self.send_and_expect(self.pg0, tx, self.pg1)
1080 # a good route throught the tunnel to check it restacked
1082 route_via_tun_2 = VppIpRoute(
1083 self, "2.2.2.2", 32, [VppRoutePath("0.0.0.0", gre_if.sw_if_index)]
1085 route_via_tun_2.add_vpp_config()
1087 tx = self.create_stream_ip4(self.pg0, "2.2.2.3", "2.2.2.2")
1088 rx = self.send_and_expect(self.pg0, tx, self.pg1)
1089 self.verify_tunneled_4o4(self.pg1, rx, tx, self.pg0.local_ip4, "1.1.1.2")
1094 route_via_tun_2.remove_vpp_config()
1095 gre_if.remove_vpp_config()
1097 def test_mgre(self):
1098 """mGRE IPv4 tunnel Tests"""
1100 for itf in self.pg_interfaces[3:]:
1102 # one underlay nh for each overlay/tunnel peer
1104 itf.generate_remote_hosts(4)
1105 itf.configure_ipv4_neighbors()
1108 # Create an L3 GRE tunnel.
1110 # - assign an IP Addres
1111 # - Add a route via the tunnel
1113 gre_if = VppGreInterface(
1117 mode=(VppEnum.vl_api_tunnel_mode_t.TUNNEL_API_MODE_MP),
1119 gre_if.add_vpp_config()
1122 gre_if.generate_remote_hosts(4)
1124 self.logger.info(self.vapi.cli("sh adj"))
1125 self.logger.info(self.vapi.cli("sh ip fib"))
1128 # ensure we don't match to the tunnel if the source address
1131 tx = self.create_tunnel_stream_4o4(
1136 self.pg0.remote_ip4,
1138 self.send_and_assert_no_replies(self.pg0, tx)
1143 for ii in range(1, 4):
1144 route_addr = "4.4.4.%d" % ii
1145 tx_e = self.create_stream_ip4(self.pg0, "5.5.5.5", route_addr)
1148 # route traffic via the peer
1150 route_via_tun = VppIpRoute(
1154 [VppRoutePath(gre_if._remote_hosts[ii].ip4, gre_if.sw_if_index)],
1156 route_via_tun.add_vpp_config()
1158 # all packets dropped at this point
1159 rx = self.send_and_assert_no_replies(self.pg0, tx_e)
1163 rx = self.send_and_assert_no_replies(self.pg0, tx_e)
1166 # Add a TEIB entry resolves the peer
1171 gre_if._remote_hosts[ii].ip4,
1172 itf._remote_hosts[ii].ip4,
1174 teib.add_vpp_config()
1177 # Send a packet stream that is routed into the tunnel
1178 # - packets are GRE encapped
1180 rx = self.send_and_expect(self.pg0, tx_e, itf)
1181 self.verify_tunneled_4o4(
1182 self.pg0, rx, tx_e, itf.local_ip4, itf._remote_hosts[ii].ip4
1185 tx_i = self.create_tunnel_stream_4o4(
1187 itf._remote_hosts[ii].ip4,
1190 self.pg0.remote_ip4,
1192 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1193 self.verify_decapped_4o4(self.pg0, rx, tx_i)
1196 # delete and re-add the TEIB
1198 teib.remove_vpp_config()
1199 self.send_and_assert_no_replies(self.pg0, tx_e)
1200 self.send_and_assert_no_replies(self.pg0, tx_i)
1202 teib.add_vpp_config()
1203 rx = self.send_and_expect(self.pg0, tx_e, itf)
1204 self.verify_tunneled_4o4(
1205 self.pg0, rx, tx_e, itf.local_ip4, itf._remote_hosts[ii].ip4
1207 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1208 self.verify_decapped_4o4(self.pg0, rx, tx_i)
1211 # bounce the interface state and try packets again
1215 rx = self.send_and_expect(self.pg0, tx_e, itf)
1216 self.verify_tunneled_4o4(
1217 self.pg0, rx, tx_e, itf.local_ip4, itf._remote_hosts[ii].ip4
1219 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1220 self.verify_decapped_4o4(self.pg0, rx, tx_i)
1223 gre_if.unconfig_ip4()
1225 def test_mgre6(self):
1226 """mGRE IPv6 tunnel Tests"""
1228 self.pg0.config_ip6()
1229 self.pg0.resolve_ndp()
1231 e = VppEnum.vl_api_tunnel_encap_decap_flags_t
1233 for itf in self.pg_interfaces[3:]:
1235 # one underlay nh for each overlay/tunnel peer
1238 itf.generate_remote_hosts(4)
1239 itf.configure_ipv6_neighbors()
1242 # Create an L3 GRE tunnel.
1244 # - assign an IP Addres
1245 # - Add a route via the tunnel
1247 gre_if = VppGreInterface(
1251 mode=(VppEnum.vl_api_tunnel_mode_t.TUNNEL_API_MODE_MP),
1252 flags=e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP,
1255 gre_if.add_vpp_config()
1258 gre_if.generate_remote_hosts(4)
1263 for ii in range(1, 4):
1264 route_addr = "4::%d" % ii
1267 # Add a TEIB entry resolves the peer
1272 gre_if._remote_hosts[ii].ip6,
1273 itf._remote_hosts[ii].ip6,
1275 teib.add_vpp_config()
1278 # route traffic via the peer
1280 route_via_tun = VppIpRoute(
1284 [VppRoutePath(gre_if._remote_hosts[ii].ip6, gre_if.sw_if_index)],
1286 route_via_tun.add_vpp_config()
1289 # Send a packet stream that is routed into the tunnel
1290 # - packets are GRE encapped
1292 tx_e = self.create_stream_ip6(
1293 self.pg0, "5::5", route_addr, dscp=2, ecn=1
1295 rx = self.send_and_expect(self.pg0, tx_e, itf)
1296 self.verify_tunneled_6o6(
1297 self.pg0, rx, tx_e, itf.local_ip6, itf._remote_hosts[ii].ip6, dscp=2
1299 tx_i = self.create_tunnel_stream_6o6(
1301 itf._remote_hosts[ii].ip6,
1304 self.pg0.remote_ip6,
1306 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1307 self.verify_decapped_6o6(self.pg0, rx, tx_i)
1310 # delete and re-add the TEIB
1312 teib.remove_vpp_config()
1313 self.send_and_assert_no_replies(self.pg0, tx_e)
1315 teib.add_vpp_config()
1316 rx = self.send_and_expect(self.pg0, tx_e, itf)
1317 self.verify_tunneled_6o6(
1318 self.pg0, rx, tx_e, itf.local_ip6, itf._remote_hosts[ii].ip6, dscp=2
1320 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1321 self.verify_decapped_6o6(self.pg0, rx, tx_i)
1324 gre_if.unconfig_ip4()
1326 self.pg0.unconfig_ip6()
1329 if __name__ == "__main__":
1330 unittest.main(testRunner=VppTestRunner)