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
244 self.assertEqual(len(capture), len(sent))
245 tos = (dscp << 2) | ecn
247 for i in range(len(capture)):
255 self.assertEqual(rx_ip.src, tunnel_src)
256 self.assertEqual(rx_ip.dst, tunnel_dst)
257 self.assertEqual(rx_ip.tos, tos)
258 self.assertEqual(rx_ip.len, len(rx_ip))
263 self.assertEqual(rx_ip.src, tx_ip.src)
264 self.assertEqual(rx_ip.dst, tx_ip.dst)
265 # IP processing post pop has decremented the TTL
266 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
269 self.logger.error(ppp("Rx:", rx))
270 self.logger.error(ppp("Tx:", tx))
273 def verify_tunneled_6o6(
274 self, src_if, capture, sent, tunnel_src, tunnel_dst, dscp=0, ecn=0
277 self.assertEqual(len(capture), len(sent))
278 tc = (dscp << 2) | ecn
280 for i in range(len(capture)):
288 self.assertEqual(rx_ip.src, tunnel_src)
289 self.assertEqual(rx_ip.dst, tunnel_dst)
290 self.assertEqual(rx_ip.tc, tc)
292 rx_gre = GRE(scapy.compat.raw(rx_ip[IPv6].payload))
294 self.assertEqual(rx_ip.plen, len(rx_gre))
298 self.assertEqual(rx_ip.src, tx_ip.src)
299 self.assertEqual(rx_ip.dst, tx_ip.dst)
302 self.logger.error(ppp("Rx:", rx))
303 self.logger.error(ppp("Tx:", tx))
306 def verify_tunneled_4o6(self, src_if, capture, sent, tunnel_src, tunnel_dst):
308 self.assertEqual(len(capture), len(sent))
310 for i in range(len(capture)):
317 self.assertEqual(rx_ip.src, tunnel_src)
318 self.assertEqual(rx_ip.dst, tunnel_dst)
320 rx_gre = GRE(scapy.compat.raw(rx_ip[IPv6].payload))
322 self.assertEqual(rx_ip.plen, len(rx_gre))
327 self.assertEqual(rx_ip.src, tx_ip.src)
328 self.assertEqual(rx_ip.dst, tx_ip.dst)
331 self.logger.error(ppp("Rx:", rx))
332 self.logger.error(ppp("Tx:", tx))
335 def verify_tunneled_6o4(self, src_if, capture, sent, tunnel_src, tunnel_dst):
337 self.assertEqual(len(capture), len(sent))
339 for i in range(len(capture)):
346 self.assertEqual(rx_ip.src, tunnel_src)
347 self.assertEqual(rx_ip.dst, tunnel_dst)
348 self.assertEqual(rx_ip.len, len(rx_ip))
350 rx_gre = GRE(scapy.compat.raw(rx_ip[IP].payload))
354 self.assertEqual(rx_ip.src, tx_ip.src)
355 self.assertEqual(rx_ip.dst, tx_ip.dst)
358 self.logger.error(ppp("Rx:", rx))
359 self.logger.error(ppp("Tx:", tx))
362 def verify_tunneled_l2o4(self, src_if, capture, sent, tunnel_src, tunnel_dst):
363 self.assertEqual(len(capture), len(sent))
365 for i in range(len(capture)):
373 self.assertEqual(rx_ip.src, tunnel_src)
374 self.assertEqual(rx_ip.dst, tunnel_dst)
375 self.assertEqual(rx_ip.len, len(rx_ip))
378 rx_l2 = rx_gre[Ether]
381 tx_l2 = tx_gre[Ether]
384 self.assertEqual(rx_ip.src, tx_ip.src)
385 self.assertEqual(rx_ip.dst, tx_ip.dst)
386 # bridged, not L3 forwarded, so no TTL decrement
387 self.assertEqual(rx_ip.ttl, tx_ip.ttl)
390 self.logger.error(ppp("Rx:", rx))
391 self.logger.error(ppp("Tx:", tx))
394 def verify_tunneled_vlano4(
395 self, src_if, capture, sent, tunnel_src, tunnel_dst, vlan
398 self.assertEqual(len(capture), len(sent))
400 ppc("Unexpected packets captured:", capture)
403 for i in range(len(capture)):
411 self.assertEqual(rx_ip.src, tunnel_src)
412 self.assertEqual(rx_ip.dst, tunnel_dst)
415 rx_l2 = rx_gre[Ether]
416 rx_vlan = rx_l2[Dot1Q]
419 self.assertEqual(rx_vlan.vlan, vlan)
422 tx_l2 = tx_gre[Ether]
425 self.assertEqual(rx_ip.src, tx_ip.src)
426 self.assertEqual(rx_ip.dst, tx_ip.dst)
427 # bridged, not L3 forwarded, so no TTL decrement
428 self.assertEqual(rx_ip.ttl, tx_ip.ttl)
431 self.logger.error(ppp("Rx:", rx))
432 self.logger.error(ppp("Tx:", tx))
435 def verify_decapped_4o4(self, src_if, capture, sent):
436 self.assertEqual(len(capture), len(sent))
438 for i in range(len(capture)):
448 self.assertEqual(rx_ip.src, tx_ip.src)
449 self.assertEqual(rx_ip.dst, tx_ip.dst)
450 # IP processing post pop has decremented the TTL
451 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
454 self.logger.error(ppp("Rx:", rx))
455 self.logger.error(ppp("Tx:", tx))
458 def verify_decapped_6o4(self, src_if, capture, sent):
459 self.assertEqual(len(capture), len(sent))
461 for i in range(len(capture)):
471 self.assertEqual(rx_ip.src, tx_ip.src)
472 self.assertEqual(rx_ip.dst, tx_ip.dst)
473 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
476 self.logger.error(ppp("Rx:", rx))
477 self.logger.error(ppp("Tx:", tx))
480 def verify_decapped_6o6(self, src_if, capture, sent):
481 self.assertEqual(len(capture), len(sent))
483 for i in range(len(capture)):
493 self.assertEqual(rx_ip.src, tx_ip.src)
494 self.assertEqual(rx_ip.dst, tx_ip.dst)
495 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
498 self.logger.error(ppp("Rx:", rx))
499 self.logger.error(ppp("Tx:", tx))
503 """GRE IPv4 tunnel Tests"""
506 # Create an L3 GRE tunnel.
508 # - assign an IP Addres
509 # - Add a route via the tunnel
511 gre_if = VppGreInterface(self, self.pg0.local_ip4, "1.1.1.2")
512 gre_if.add_vpp_config()
515 # The double create (create the same tunnel twice) should fail,
516 # and we should still be able to use the original
519 gre_if.add_vpp_config()
523 self.fail("Double GRE tunnel add does not fail")
528 route_via_tun = VppIpRoute(
529 self, "4.4.4.4", 32, [VppRoutePath("0.0.0.0", gre_if.sw_if_index)]
532 route_via_tun.add_vpp_config()
535 # Send a packet stream that is routed into the tunnel
536 # - they are all dropped since the tunnel's destintation IP
537 # is unresolved - or resolves via the default route - which
540 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "4.4.4.4")
542 self.send_and_assert_no_replies(self.pg0, tx)
545 # Add a route that resolves the tunnel's destination
547 route_tun_dst = VppIpRoute(
551 [VppRoutePath(self.pg0.remote_ip4, self.pg0.sw_if_index)],
553 route_tun_dst.add_vpp_config()
556 # Send a packet stream that is routed into the tunnel
557 # - packets are GRE encapped
559 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "4.4.4.4")
560 rx = self.send_and_expect(self.pg0, tx, self.pg0)
561 self.verify_tunneled_4o4(self.pg0, rx, tx, self.pg0.local_ip4, "1.1.1.2")
564 # Send tunneled packets that match the created tunnel and
565 # are decapped and forwarded
567 tx = self.create_tunnel_stream_4o4(
574 rx = self.send_and_expect(self.pg0, tx, self.pg0)
575 self.verify_decapped_4o4(self.pg0, rx, tx)
578 # Send tunneled packets that do not match the tunnel's src
580 self.vapi.cli("clear trace")
581 tx = self.create_tunnel_stream_4o4(
588 self.send_and_assert_no_replies(
589 self.pg0, tx, remark="GRE packets forwarded despite no SRC address match"
593 # Configure IPv6 on the PG interface so we can route IPv6
596 self.pg0.config_ip6()
597 self.pg0.resolve_ndp()
600 # Send IPv6 tunnel encapslated packets
601 # - dropped since IPv6 is not enabled on the tunnel
603 tx = self.create_tunnel_stream_6o4(
610 self.send_and_assert_no_replies(
613 "IPv6 GRE packets forwarded despite IPv6 not enabled on tunnel",
617 # Enable IPv6 on the tunnel
622 # Send IPv6 tunnel encapslated packets
623 # - forwarded since IPv6 is enabled on the tunnel
625 tx = self.create_tunnel_stream_6o4(
632 rx = self.send_and_expect(self.pg0, tx, self.pg0)
633 self.verify_decapped_6o4(self.pg0, rx, tx)
636 # Send v6 packets for v4 encap
638 route6_via_tun = VppIpRoute(
642 [VppRoutePath("::", gre_if.sw_if_index, proto=DpoProto.DPO_PROTO_IP6)],
644 route6_via_tun.add_vpp_config()
646 tx = self.create_stream_ip6(self.pg0, "2001::2", "2001::1")
647 rx = self.send_and_expect(self.pg0, tx, self.pg0)
649 self.verify_tunneled_6o4(self.pg0, rx, tx, self.pg0.local_ip4, "1.1.1.2")
652 # add a labelled route through the tunnel
654 label_via_tun = VppIpRoute(
658 [VppRoutePath("0.0.0.0", gre_if.sw_if_index, labels=[VppMplsLabel(33)])],
660 label_via_tun.add_vpp_config()
662 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "5.4.3.2")
663 rx = self.send_and_expect(self.pg0, tx, self.pg0)
664 self.verify_tunneled_4o4(self.pg0, rx, tx, self.pg0.local_ip4, "1.1.1.2")
667 # an MPLS tunnel over the GRE tunnel add a route through
670 mpls_tun = VppMPLSTunnelInterface(
676 labels=[VppMplsLabel(44), VppMplsLabel(46)],
680 mpls_tun.add_vpp_config()
683 label_via_mpls = VppIpRoute(
687 [VppRoutePath("0.0.0.0", mpls_tun.sw_if_index, labels=[VppMplsLabel(33)])],
689 label_via_mpls.add_vpp_config()
691 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "5.4.3.1")
692 rx = self.send_and_expect(self.pg0, tx, self.pg0)
693 self.verify_tunneled_4o4(self.pg0, rx, tx, self.pg0.local_ip4, "1.1.1.2")
695 mpls_tun_l2 = VppMPLSTunnelInterface(
701 labels=[VppMplsLabel(44), VppMplsLabel(46)],
706 mpls_tun_l2.add_vpp_config()
707 mpls_tun_l2.admin_up()
712 route_tun_dst.remove_vpp_config()
713 route_via_tun.remove_vpp_config()
714 route6_via_tun.remove_vpp_config()
715 label_via_mpls.remove_vpp_config()
716 label_via_tun.remove_vpp_config()
717 mpls_tun.remove_vpp_config()
718 mpls_tun_l2.remove_vpp_config()
719 gre_if.remove_vpp_config()
721 self.pg0.unconfig_ip6()
724 """GRE IPv6 tunnel Tests"""
726 self.pg1.config_ip6()
727 self.pg1.resolve_ndp()
730 # Create an L3 GRE tunnel.
732 # - assign an IP Address
733 # - Add a route via the tunnel
735 gre_if = VppGreInterface(self, self.pg2.local_ip6, "1002::1")
736 gre_if.add_vpp_config()
740 route_via_tun = VppIpRoute(
741 self, "4004::1", 128, [VppRoutePath("0::0", gre_if.sw_if_index)]
744 route_via_tun.add_vpp_config()
747 # Send a packet stream that is routed into the tunnel
748 # - they are all dropped since the tunnel's destintation IP
749 # is unresolved - or resolves via the default route - which
752 tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
753 self.send_and_assert_no_replies(
754 self.pg2, tx, "GRE packets forwarded without DIP resolved"
758 # Add a route that resolves the tunnel's destination
760 route_tun_dst = VppIpRoute(
764 [VppRoutePath(self.pg2.remote_ip6, self.pg2.sw_if_index)],
766 route_tun_dst.add_vpp_config()
769 # Send a packet stream that is routed into the tunnel
770 # - packets are GRE encapped
772 tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
773 rx = self.send_and_expect(self.pg2, tx, self.pg2)
774 self.verify_tunneled_6o6(self.pg2, rx, tx, self.pg2.local_ip6, "1002::1")
777 # Test decap. decapped packets go out pg1
779 tx = self.create_tunnel_stream_6o6(
780 self.pg2, "1002::1", self.pg2.local_ip6, "2001::1", self.pg1.remote_ip6
782 rx = self.send_and_expect(self.pg2, tx, self.pg1)
785 # RX'd packet is UDP over IPv6, test the GRE header is gone.
787 self.assertFalse(rx[0].haslayer(GRE))
788 self.assertEqual(rx[0][IPv6].dst, self.pg1.remote_ip6)
793 route4_via_tun = VppIpRoute(
794 self, "1.1.1.1", 32, [VppRoutePath("0.0.0.0", gre_if.sw_if_index)]
796 route4_via_tun.add_vpp_config()
798 tx = self.create_stream_ip4(self.pg0, "1.1.1.2", "1.1.1.1")
799 rx = self.send_and_expect(self.pg0, tx, self.pg2)
801 self.verify_tunneled_4o6(self.pg0, rx, tx, self.pg2.local_ip6, "1002::1")
806 route_tun_dst.remove_vpp_config()
807 route_via_tun.remove_vpp_config()
808 route4_via_tun.remove_vpp_config()
809 gre_if.remove_vpp_config()
811 self.pg2.unconfig_ip6()
812 self.pg1.unconfig_ip6()
814 def test_gre_vrf(self):
815 """GRE tunnel VRF Tests"""
817 e = VppEnum.vl_api_tunnel_encap_decap_flags_t
820 # Create an L3 GRE tunnel whose destination is in the non-default
821 # table. The underlay is thus non-default - the overlay is still
824 # - assign an IP Addres
826 gre_if = VppGreInterface(
832 e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP
833 | e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN
837 gre_if.add_vpp_config()
842 # Add a route via the tunnel - in the overlay
844 route_via_tun = VppIpRoute(
845 self, "9.9.9.9", 32, [VppRoutePath("0.0.0.0", gre_if.sw_if_index)]
847 route_via_tun.add_vpp_config()
850 # Add a route that resolves the tunnel's destination - in the
853 route_tun_dst = VppIpRoute(
858 paths=[VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)],
860 route_tun_dst.add_vpp_config()
863 # Send a packet stream that is routed into the tunnel
864 # packets are sent in on pg0 which is in the default table
865 # - packets are GRE encapped
867 self.vapi.cli("clear trace")
868 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "9.9.9.9", dscp=5, ecn=3)
869 rx = self.send_and_expect(self.pg0, tx, self.pg1)
870 self.verify_tunneled_4o4(
871 self.pg1, rx, tx, self.pg1.local_ip4, "2.2.2.2", dscp=5, ecn=3
875 # Send tunneled packets that match the created tunnel and
876 # are decapped and forwarded. This tests the decap lookup
877 # does not happen in the encap table
879 self.vapi.cli("clear trace")
880 tx = self.create_tunnel_stream_4o4(
887 rx = self.send_and_expect(self.pg1, tx, self.pg0)
888 self.verify_decapped_4o4(self.pg0, rx, tx)
891 # Send tunneled packets that match the created tunnel
892 # but arrive on an interface that is not in the tunnel's
893 # encap VRF, these are dropped.
894 # IP enable the interface so they aren't dropped due to
895 # IP not being enabled.
897 self.pg2.config_ip4()
898 self.vapi.cli("clear trace")
899 tx = self.create_tunnel_stream_4o4(
906 rx = self.send_and_assert_no_replies(
907 self.pg2, tx, "GRE decap packets in wrong VRF"
910 self.pg2.unconfig_ip4()
915 route_tun_dst.remove_vpp_config()
916 route_via_tun.remove_vpp_config()
917 gre_if.remove_vpp_config()
919 def test_gre_l2(self):
920 """GRE tunnel L2 Tests"""
923 # Add routes to resolve the tunnel destinations
925 route_tun1_dst = VppIpRoute(
929 [VppRoutePath(self.pg0.remote_ip4, self.pg0.sw_if_index)],
931 route_tun2_dst = VppIpRoute(
935 [VppRoutePath(self.pg0.remote_ip4, self.pg0.sw_if_index)],
938 route_tun1_dst.add_vpp_config()
939 route_tun2_dst.add_vpp_config()
942 # Create 2 L2 GRE tunnels and x-connect them
944 gre_if1 = VppGreInterface(
948 type=(VppEnum.vl_api_gre_tunnel_type_t.GRE_API_TUNNEL_TYPE_TEB),
950 gre_if2 = VppGreInterface(
954 type=(VppEnum.vl_api_gre_tunnel_type_t.GRE_API_TUNNEL_TYPE_TEB),
956 gre_if1.add_vpp_config()
957 gre_if2.add_vpp_config()
962 self.vapi.sw_interface_set_l2_xconnect(
963 gre_if1.sw_if_index, gre_if2.sw_if_index, enable=1
965 self.vapi.sw_interface_set_l2_xconnect(
966 gre_if2.sw_if_index, gre_if1.sw_if_index, enable=1
970 # Send in tunnel encapped L2. expect out tunnel encapped L2
973 tx = self.create_tunnel_stream_l2o4(self.pg0, "2.2.2.2", 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.3")
977 tx = self.create_tunnel_stream_l2o4(self.pg0, "2.2.2.3", self.pg0.local_ip4)
978 rx = self.send_and_expect(self.pg0, tx, self.pg0)
979 self.verify_tunneled_l2o4(self.pg0, rx, tx, self.pg0.local_ip4, "2.2.2.2")
981 self.vapi.sw_interface_set_l2_xconnect(
982 gre_if1.sw_if_index, gre_if2.sw_if_index, enable=0
984 self.vapi.sw_interface_set_l2_xconnect(
985 gre_if2.sw_if_index, gre_if1.sw_if_index, enable=0
989 # Create a VLAN sub-interfaces on the GRE TEB interfaces
990 # then x-connect them
992 gre_if_11 = VppDot1QSubint(self, gre_if1, 11)
993 gre_if_12 = VppDot1QSubint(self, gre_if2, 12)
995 # gre_if_11.add_vpp_config()
996 # gre_if_12.add_vpp_config()
1001 self.vapi.sw_interface_set_l2_xconnect(
1002 gre_if_11.sw_if_index, gre_if_12.sw_if_index, enable=1
1004 self.vapi.sw_interface_set_l2_xconnect(
1005 gre_if_12.sw_if_index, gre_if_11.sw_if_index, enable=1
1009 # Configure both to pop thier respective VLAN tags,
1010 # so that during the x-coonect they will subsequently push
1012 self.vapi.l2_interface_vlan_tag_rewrite(
1013 sw_if_index=gre_if_12.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1, push_dot1q=12
1015 self.vapi.l2_interface_vlan_tag_rewrite(
1016 sw_if_index=gre_if_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1, push_dot1q=11
1020 # Send traffic in both directiond - expect the VLAN tags to
1023 tx = self.create_tunnel_stream_vlano4(
1024 self.pg0, "2.2.2.2", self.pg0.local_ip4, 11
1026 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1027 self.verify_tunneled_vlano4(self.pg0, rx, tx, self.pg0.local_ip4, "2.2.2.3", 12)
1029 tx = self.create_tunnel_stream_vlano4(
1030 self.pg0, "2.2.2.3", self.pg0.local_ip4, 12
1032 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1033 self.verify_tunneled_vlano4(self.pg0, rx, tx, self.pg0.local_ip4, "2.2.2.2", 11)
1036 # Cleanup Test resources
1038 gre_if_11.remove_vpp_config()
1039 gre_if_12.remove_vpp_config()
1040 gre_if1.remove_vpp_config()
1041 gre_if2.remove_vpp_config()
1042 route_tun1_dst.add_vpp_config()
1043 route_tun2_dst.add_vpp_config()
1045 def test_gre_loop(self):
1046 """GRE tunnel loop Tests"""
1049 # Create an L3 GRE tunnel.
1051 # - assign an IP Addres
1053 gre_if = VppGreInterface(self, self.pg0.local_ip4, "1.1.1.2")
1054 gre_if.add_vpp_config()
1059 # add a route to the tunnel's destination that points
1060 # through the tunnel, hence forming a loop in the forwarding
1063 route_dst = VppIpRoute(
1064 self, "1.1.1.2", 32, [VppRoutePath("0.0.0.0", gre_if.sw_if_index)]
1066 route_dst.add_vpp_config()
1069 # packets to the tunnels destination should be dropped
1071 tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "1.1.1.2")
1072 self.send_and_assert_no_replies(self.pg2, tx)
1074 self.logger.info(self.vapi.ppcli("sh adj 7"))
1079 route_dst.modify([VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)])
1080 route_dst.add_vpp_config()
1082 rx = self.send_and_expect(self.pg0, tx, self.pg1)
1085 # a good route throught the tunnel to check it restacked
1087 route_via_tun_2 = VppIpRoute(
1088 self, "2.2.2.2", 32, [VppRoutePath("0.0.0.0", gre_if.sw_if_index)]
1090 route_via_tun_2.add_vpp_config()
1092 tx = self.create_stream_ip4(self.pg0, "2.2.2.3", "2.2.2.2")
1093 rx = self.send_and_expect(self.pg0, tx, self.pg1)
1094 self.verify_tunneled_4o4(self.pg1, rx, tx, self.pg0.local_ip4, "1.1.1.2")
1099 route_via_tun_2.remove_vpp_config()
1100 gre_if.remove_vpp_config()
1102 def test_mgre(self):
1103 """mGRE IPv4 tunnel Tests"""
1105 for itf in self.pg_interfaces[3:]:
1107 # one underlay nh for each overlay/tunnel peer
1109 itf.generate_remote_hosts(4)
1110 itf.configure_ipv4_neighbors()
1113 # Create an L3 GRE tunnel.
1115 # - assign an IP Addres
1116 # - Add a route via the tunnel
1118 gre_if = VppGreInterface(
1122 mode=(VppEnum.vl_api_tunnel_mode_t.TUNNEL_API_MODE_MP),
1124 gre_if.add_vpp_config()
1127 gre_if.generate_remote_hosts(4)
1129 self.logger.info(self.vapi.cli("sh adj"))
1130 self.logger.info(self.vapi.cli("sh ip fib"))
1133 # ensure we don't match to the tunnel if the source address
1136 tx = self.create_tunnel_stream_4o4(
1141 self.pg0.remote_ip4,
1143 self.send_and_assert_no_replies(self.pg0, tx)
1148 for ii in range(1, 4):
1149 route_addr = "4.4.4.%d" % ii
1150 tx_e = self.create_stream_ip4(self.pg0, "5.5.5.5", route_addr)
1153 # route traffic via the peer
1155 route_via_tun = VppIpRoute(
1159 [VppRoutePath(gre_if._remote_hosts[ii].ip4, gre_if.sw_if_index)],
1161 route_via_tun.add_vpp_config()
1163 # all packets dropped at this point
1164 rx = self.send_and_assert_no_replies(self.pg0, tx_e)
1168 rx = self.send_and_assert_no_replies(self.pg0, tx_e)
1171 # Add a TEIB entry resolves the peer
1176 gre_if._remote_hosts[ii].ip4,
1177 itf._remote_hosts[ii].ip4,
1179 teib.add_vpp_config()
1182 # Send a packet stream that is routed into the tunnel
1183 # - packets are GRE encapped
1185 rx = self.send_and_expect(self.pg0, tx_e, itf)
1186 self.verify_tunneled_4o4(
1187 self.pg0, rx, tx_e, itf.local_ip4, itf._remote_hosts[ii].ip4
1190 tx_i = self.create_tunnel_stream_4o4(
1192 itf._remote_hosts[ii].ip4,
1195 self.pg0.remote_ip4,
1197 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1198 self.verify_decapped_4o4(self.pg0, rx, tx_i)
1201 # delete and re-add the TEIB
1203 teib.remove_vpp_config()
1204 self.send_and_assert_no_replies(self.pg0, tx_e)
1205 self.send_and_assert_no_replies(self.pg0, tx_i)
1207 teib.add_vpp_config()
1208 rx = self.send_and_expect(self.pg0, tx_e, itf)
1209 self.verify_tunneled_4o4(
1210 self.pg0, rx, tx_e, itf.local_ip4, itf._remote_hosts[ii].ip4
1212 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1213 self.verify_decapped_4o4(self.pg0, rx, tx_i)
1216 # bounce the interface state and try packets again
1220 rx = self.send_and_expect(self.pg0, tx_e, itf)
1221 self.verify_tunneled_4o4(
1222 self.pg0, rx, tx_e, itf.local_ip4, itf._remote_hosts[ii].ip4
1224 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1225 self.verify_decapped_4o4(self.pg0, rx, tx_i)
1228 gre_if.unconfig_ip4()
1230 def test_mgre6(self):
1231 """mGRE IPv6 tunnel Tests"""
1233 self.pg0.config_ip6()
1234 self.pg0.resolve_ndp()
1236 e = VppEnum.vl_api_tunnel_encap_decap_flags_t
1238 for itf in self.pg_interfaces[3:]:
1240 # one underlay nh for each overlay/tunnel peer
1243 itf.generate_remote_hosts(4)
1244 itf.configure_ipv6_neighbors()
1247 # Create an L3 GRE tunnel.
1249 # - assign an IP Addres
1250 # - Add a route via the tunnel
1252 gre_if = VppGreInterface(
1256 mode=(VppEnum.vl_api_tunnel_mode_t.TUNNEL_API_MODE_MP),
1257 flags=e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP,
1260 gre_if.add_vpp_config()
1263 gre_if.generate_remote_hosts(4)
1268 for ii in range(1, 4):
1269 route_addr = "4::%d" % ii
1272 # Add a TEIB entry resolves the peer
1277 gre_if._remote_hosts[ii].ip6,
1278 itf._remote_hosts[ii].ip6,
1280 teib.add_vpp_config()
1283 # route traffic via the peer
1285 route_via_tun = VppIpRoute(
1289 [VppRoutePath(gre_if._remote_hosts[ii].ip6, gre_if.sw_if_index)],
1291 route_via_tun.add_vpp_config()
1294 # Send a packet stream that is routed into the tunnel
1295 # - packets are GRE encapped
1297 tx_e = self.create_stream_ip6(
1298 self.pg0, "5::5", route_addr, dscp=2, ecn=1
1300 rx = self.send_and_expect(self.pg0, tx_e, itf)
1301 self.verify_tunneled_6o6(
1302 self.pg0, rx, tx_e, itf.local_ip6, itf._remote_hosts[ii].ip6, dscp=2
1304 tx_i = self.create_tunnel_stream_6o6(
1306 itf._remote_hosts[ii].ip6,
1309 self.pg0.remote_ip6,
1311 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1312 self.verify_decapped_6o6(self.pg0, rx, tx_i)
1315 # delete and re-add the TEIB
1317 teib.remove_vpp_config()
1318 self.send_and_assert_no_replies(self.pg0, tx_e)
1320 teib.add_vpp_config()
1321 rx = self.send_and_expect(self.pg0, tx_e, itf)
1322 self.verify_tunneled_6o6(
1323 self.pg0, rx, tx_e, itf.local_ip6, itf._remote_hosts[ii].ip6, dscp=2
1325 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1326 self.verify_decapped_6o6(self.pg0, rx, tx_i)
1329 gre_if.unconfig_ip4()
1331 self.pg0.unconfig_ip6()
1334 if __name__ == "__main__":
1335 unittest.main(testRunner=VppTestRunner)