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, VppTestRunner
13 from vpp_sub_interface import L2_VTR_OP, VppDot1QSubint
14 from vpp_gre_interface import VppGreInterface
15 from vpp_teib import VppTeib
16 from vpp_ip import DpoProto
17 from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, FibPathProto
18 from util import ppp, ppc
19 from vpp_papi import VppEnum
22 class TestGREInputNodes(VppTestCase):
23 """ GRE Input Nodes Test Case """
26 super(TestGREInputNodes, self).setUp()
28 # create 3 pg interfaces - set one in a non-default table.
29 self.create_pg_interfaces(range(1))
31 for i in self.pg_interfaces:
36 for i in self.pg_interfaces:
39 super(TestGREInputNodes, self).tearDown()
41 def test_gre_input_node(self):
42 """ GRE gre input nodes not registerd unless configured """
43 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
44 IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
47 self.pg0.add_stream(pkt)
49 # no tunnel created, gre-input not registered
50 err = self.statistics.get_counter(
51 '/err/ip4-local/unknown ip protocol')[0]
52 self.assertEqual(err, 1)
56 gre_if = VppGreInterface(self, self.pg0.local_ip4, "1.1.1.2")
57 gre_if.add_vpp_config()
59 self.pg0.add_stream(pkt)
61 # tunnel created, gre-input registered
62 err = self.statistics.get_counter(
63 '/err/ip4-local/unknown ip protocol')[0]
64 # expect no new errors
65 self.assertEqual(err, err_count)
68 class TestGRE(VppTestCase):
73 super(TestGRE, cls).setUpClass()
76 def tearDownClass(cls):
77 super(TestGRE, cls).tearDownClass()
80 super(TestGRE, self).setUp()
82 # create 3 pg interfaces - set one in a non-default table.
83 self.create_pg_interfaces(range(5))
85 self.tbl = VppIpTable(self, 1)
86 self.tbl.add_vpp_config()
87 self.pg1.set_table_ip4(1)
89 for i in self.pg_interfaces:
93 self.pg0.resolve_arp()
95 self.pg1.resolve_arp()
97 self.pg2.resolve_ndp()
99 self.pg3.resolve_arp()
100 self.pg4.config_ip4()
101 self.pg4.resolve_arp()
104 for i in self.pg_interfaces:
108 self.pg1.set_table_ip4(0)
109 super(TestGRE, self).tearDown()
111 def create_stream_ip4(self, src_if, src_ip, dst_ip, dscp=0, ecn=0):
113 tos = (dscp << 2) | ecn
114 for i in range(0, 257):
115 info = self.create_packet_info(src_if, src_if)
116 payload = self.info_to_payload(info)
117 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
118 IP(src=src_ip, dst=dst_ip, tos=tos) /
119 UDP(sport=1234, dport=1234) /
125 def create_stream_ip6(self, src_if, src_ip, dst_ip, dscp=0, ecn=0):
127 tc = (dscp << 2) | ecn
128 for i in range(0, 257):
129 info = self.create_packet_info(src_if, src_if)
130 payload = self.info_to_payload(info)
131 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
132 IPv6(src=src_ip, dst=dst_ip, tc=tc) /
133 UDP(sport=1234, dport=1234) /
139 def create_tunnel_stream_4o4(self, src_if,
140 tunnel_src, tunnel_dst,
143 for i in range(0, 257):
144 info = self.create_packet_info(src_if, src_if)
145 payload = self.info_to_payload(info)
146 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
147 IP(src=tunnel_src, dst=tunnel_dst) /
149 IP(src=src_ip, dst=dst_ip) /
150 UDP(sport=1234, dport=1234) /
156 def create_tunnel_stream_6o4(self, src_if,
157 tunnel_src, tunnel_dst,
160 for i in range(0, 257):
161 info = self.create_packet_info(src_if, src_if)
162 payload = self.info_to_payload(info)
163 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
164 IP(src=tunnel_src, dst=tunnel_dst) /
166 IPv6(src=src_ip, dst=dst_ip) /
167 UDP(sport=1234, dport=1234) /
173 def create_tunnel_stream_6o6(self, src_if,
174 tunnel_src, tunnel_dst,
177 for i in range(0, 257):
178 info = self.create_packet_info(src_if, src_if)
179 payload = self.info_to_payload(info)
180 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
181 IPv6(src=tunnel_src, dst=tunnel_dst) /
183 IPv6(src=src_ip, dst=dst_ip) /
184 UDP(sport=1234, dport=1234) /
190 def create_tunnel_stream_l2o4(self, src_if,
191 tunnel_src, tunnel_dst):
193 for i in range(0, 257):
194 info = self.create_packet_info(src_if, src_if)
195 payload = self.info_to_payload(info)
196 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
197 IP(src=tunnel_src, dst=tunnel_dst) /
199 Ether(dst=RandMAC('*:*:*:*:*:*'),
200 src=RandMAC('*:*:*:*:*:*')) /
201 IP(src=scapy.compat.raw(RandIP()),
202 dst=scapy.compat.raw(RandIP())) /
203 UDP(sport=1234, dport=1234) /
209 def create_tunnel_stream_vlano4(self, src_if,
210 tunnel_src, tunnel_dst, vlan):
212 for i in range(0, 257):
213 info = self.create_packet_info(src_if, src_if)
214 payload = self.info_to_payload(info)
215 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
216 IP(src=tunnel_src, dst=tunnel_dst) /
218 Ether(dst=RandMAC('*:*:*:*:*:*'),
219 src=RandMAC('*:*:*:*:*:*')) /
221 IP(src=scapy.compat.raw(RandIP()),
222 dst=scapy.compat.raw(RandIP())) /
223 UDP(sport=1234, dport=1234) /
229 def verify_tunneled_4o4(self, src_if, capture, sent,
230 tunnel_src, tunnel_dst,
233 self.assertEqual(len(capture), len(sent))
234 tos = (dscp << 2) | ecn
236 for i in range(len(capture)):
244 self.assertEqual(rx_ip.src, tunnel_src)
245 self.assertEqual(rx_ip.dst, tunnel_dst)
246 self.assertEqual(rx_ip.tos, tos)
247 self.assertEqual(rx_ip.len, len(rx_ip))
252 self.assertEqual(rx_ip.src, tx_ip.src)
253 self.assertEqual(rx_ip.dst, tx_ip.dst)
254 # IP processing post pop has decremented the TTL
255 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
258 self.logger.error(ppp("Rx:", rx))
259 self.logger.error(ppp("Tx:", tx))
262 def verify_tunneled_6o6(self, src_if, capture, sent,
263 tunnel_src, tunnel_dst,
266 self.assertEqual(len(capture), len(sent))
267 tc = (dscp << 2) | ecn
269 for i in range(len(capture)):
277 self.assertEqual(rx_ip.src, tunnel_src)
278 self.assertEqual(rx_ip.dst, tunnel_dst)
279 self.assertEqual(rx_ip.tc, tc)
281 rx_gre = GRE(scapy.compat.raw(rx_ip[IPv6].payload))
283 self.assertEqual(rx_ip.plen, len(rx_gre))
287 self.assertEqual(rx_ip.src, tx_ip.src)
288 self.assertEqual(rx_ip.dst, tx_ip.dst)
291 self.logger.error(ppp("Rx:", rx))
292 self.logger.error(ppp("Tx:", tx))
295 def verify_tunneled_4o6(self, src_if, capture, sent,
296 tunnel_src, tunnel_dst):
298 self.assertEqual(len(capture), len(sent))
300 for i in range(len(capture)):
307 self.assertEqual(rx_ip.src, tunnel_src)
308 self.assertEqual(rx_ip.dst, tunnel_dst)
310 rx_gre = GRE(scapy.compat.raw(rx_ip[IPv6].payload))
312 self.assertEqual(rx_ip.plen, len(rx_gre))
317 self.assertEqual(rx_ip.src, tx_ip.src)
318 self.assertEqual(rx_ip.dst, tx_ip.dst)
321 self.logger.error(ppp("Rx:", rx))
322 self.logger.error(ppp("Tx:", tx))
325 def verify_tunneled_6o4(self, src_if, capture, sent,
326 tunnel_src, tunnel_dst):
328 self.assertEqual(len(capture), len(sent))
330 for i in range(len(capture)):
337 self.assertEqual(rx_ip.src, tunnel_src)
338 self.assertEqual(rx_ip.dst, tunnel_dst)
339 self.assertEqual(rx_ip.len, len(rx_ip))
341 rx_gre = GRE(scapy.compat.raw(rx_ip[IP].payload))
345 self.assertEqual(rx_ip.src, tx_ip.src)
346 self.assertEqual(rx_ip.dst, tx_ip.dst)
349 self.logger.error(ppp("Rx:", rx))
350 self.logger.error(ppp("Tx:", tx))
353 def verify_tunneled_l2o4(self, src_if, capture, sent,
354 tunnel_src, tunnel_dst):
355 self.assertEqual(len(capture), len(sent))
357 for i in range(len(capture)):
365 self.assertEqual(rx_ip.src, tunnel_src)
366 self.assertEqual(rx_ip.dst, tunnel_dst)
367 self.assertEqual(rx_ip.len, len(rx_ip))
370 rx_l2 = rx_gre[Ether]
373 tx_l2 = tx_gre[Ether]
376 self.assertEqual(rx_ip.src, tx_ip.src)
377 self.assertEqual(rx_ip.dst, tx_ip.dst)
378 # bridged, not L3 forwarded, so no TTL decrement
379 self.assertEqual(rx_ip.ttl, tx_ip.ttl)
382 self.logger.error(ppp("Rx:", rx))
383 self.logger.error(ppp("Tx:", tx))
386 def verify_tunneled_vlano4(self, src_if, capture, sent,
387 tunnel_src, tunnel_dst, vlan):
389 self.assertEqual(len(capture), len(sent))
391 ppc("Unexpected packets captured:", capture)
394 for i in range(len(capture)):
402 self.assertEqual(rx_ip.src, tunnel_src)
403 self.assertEqual(rx_ip.dst, tunnel_dst)
406 rx_l2 = rx_gre[Ether]
407 rx_vlan = rx_l2[Dot1Q]
410 self.assertEqual(rx_vlan.vlan, vlan)
413 tx_l2 = tx_gre[Ether]
416 self.assertEqual(rx_ip.src, tx_ip.src)
417 self.assertEqual(rx_ip.dst, tx_ip.dst)
418 # bridged, not L3 forwarded, so no TTL decrement
419 self.assertEqual(rx_ip.ttl, tx_ip.ttl)
422 self.logger.error(ppp("Rx:", rx))
423 self.logger.error(ppp("Tx:", tx))
426 def verify_decapped_4o4(self, src_if, capture, sent):
427 self.assertEqual(len(capture), len(sent))
429 for i in range(len(capture)):
439 self.assertEqual(rx_ip.src, tx_ip.src)
440 self.assertEqual(rx_ip.dst, tx_ip.dst)
441 # IP processing post pop has decremented the TTL
442 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
445 self.logger.error(ppp("Rx:", rx))
446 self.logger.error(ppp("Tx:", tx))
449 def verify_decapped_6o4(self, src_if, capture, sent):
450 self.assertEqual(len(capture), len(sent))
452 for i in range(len(capture)):
462 self.assertEqual(rx_ip.src, tx_ip.src)
463 self.assertEqual(rx_ip.dst, tx_ip.dst)
464 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
467 self.logger.error(ppp("Rx:", rx))
468 self.logger.error(ppp("Tx:", tx))
471 def verify_decapped_6o6(self, src_if, capture, sent):
472 self.assertEqual(len(capture), len(sent))
474 for i in range(len(capture)):
484 self.assertEqual(rx_ip.src, tx_ip.src)
485 self.assertEqual(rx_ip.dst, tx_ip.dst)
486 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
489 self.logger.error(ppp("Rx:", rx))
490 self.logger.error(ppp("Tx:", tx))
494 """ GRE IPv4 tunnel Tests """
497 # Create an L3 GRE tunnel.
499 # - assign an IP Addres
500 # - Add a route via the tunnel
502 gre_if = VppGreInterface(self,
505 gre_if.add_vpp_config()
508 # The double create (create the same tunnel twice) should fail,
509 # and we should still be able to use the original
512 gre_if.add_vpp_config()
516 self.fail("Double GRE tunnel add does not fail")
521 route_via_tun = VppIpRoute(self, "4.4.4.4", 32,
522 [VppRoutePath("0.0.0.0",
523 gre_if.sw_if_index)])
525 route_via_tun.add_vpp_config()
528 # Send a packet stream that is routed into the tunnel
529 # - they are all dropped since the tunnel's destintation IP
530 # is unresolved - or resolves via the default route - which
533 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "4.4.4.4")
535 self.send_and_assert_no_replies(self.pg0, tx)
538 # Add a route that resolves the tunnel's destination
540 route_tun_dst = VppIpRoute(self, "1.1.1.2", 32,
541 [VppRoutePath(self.pg0.remote_ip4,
542 self.pg0.sw_if_index)])
543 route_tun_dst.add_vpp_config()
546 # Send a packet stream that is routed into the tunnel
547 # - packets are GRE encapped
549 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "4.4.4.4")
550 rx = self.send_and_expect(self.pg0, tx, self.pg0)
551 self.verify_tunneled_4o4(self.pg0, rx, tx,
552 self.pg0.local_ip4, "1.1.1.2")
555 # Send tunneled packets that match the created tunnel and
556 # are decapped and forwarded
558 tx = self.create_tunnel_stream_4o4(self.pg0,
563 rx = self.send_and_expect(self.pg0, tx, self.pg0)
564 self.verify_decapped_4o4(self.pg0, rx, tx)
567 # Send tunneled packets that do not match the tunnel's src
569 self.vapi.cli("clear trace")
570 tx = self.create_tunnel_stream_4o4(self.pg0,
575 self.send_and_assert_no_replies(
577 remark="GRE packets forwarded despite no SRC address match")
580 # Configure IPv6 on the PG interface so we can route IPv6
583 self.pg0.config_ip6()
584 self.pg0.resolve_ndp()
587 # Send IPv6 tunnel encapslated packets
588 # - dropped since IPv6 is not enabled on the tunnel
590 tx = self.create_tunnel_stream_6o4(self.pg0,
595 self.send_and_assert_no_replies(self.pg0, tx,
596 "IPv6 GRE packets forwarded "
597 "despite IPv6 not enabled on tunnel")
600 # Enable IPv6 on the tunnel
605 # Send IPv6 tunnel encapslated packets
606 # - forwarded since IPv6 is enabled on the tunnel
608 tx = self.create_tunnel_stream_6o4(self.pg0,
613 rx = self.send_and_expect(self.pg0, tx, self.pg0)
614 self.verify_decapped_6o4(self.pg0, rx, tx)
617 # Send v6 packets for v4 encap
619 route6_via_tun = VppIpRoute(
620 self, "2001::1", 128,
623 proto=DpoProto.DPO_PROTO_IP6)])
624 route6_via_tun.add_vpp_config()
626 tx = self.create_stream_ip6(self.pg0, "2001::2", "2001::1")
627 rx = self.send_and_expect(self.pg0, tx, self.pg0)
629 self.verify_tunneled_6o4(self.pg0, rx, tx,
630 self.pg0.local_ip4, "1.1.1.2")
635 route_tun_dst.remove_vpp_config()
636 route_via_tun.remove_vpp_config()
637 route6_via_tun.remove_vpp_config()
638 gre_if.remove_vpp_config()
640 self.pg0.unconfig_ip6()
643 """ GRE IPv6 tunnel Tests """
645 self.pg1.config_ip6()
646 self.pg1.resolve_ndp()
649 # Create an L3 GRE tunnel.
651 # - assign an IP Address
652 # - Add a route via the tunnel
654 gre_if = VppGreInterface(self,
657 gre_if.add_vpp_config()
661 route_via_tun = VppIpRoute(self, "4004::1", 128,
662 [VppRoutePath("0::0",
663 gre_if.sw_if_index)])
665 route_via_tun.add_vpp_config()
668 # Send a packet stream that is routed into the tunnel
669 # - they are all dropped since the tunnel's destintation IP
670 # is unresolved - or resolves via the default route - which
673 tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
674 self.send_and_assert_no_replies(
676 "GRE packets forwarded without DIP resolved")
679 # Add a route that resolves the tunnel's destination
681 route_tun_dst = VppIpRoute(self, "1002::1", 128,
682 [VppRoutePath(self.pg2.remote_ip6,
683 self.pg2.sw_if_index)])
684 route_tun_dst.add_vpp_config()
687 # Send a packet stream that is routed into the tunnel
688 # - packets are GRE encapped
690 tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
691 rx = self.send_and_expect(self.pg2, tx, self.pg2)
692 self.verify_tunneled_6o6(self.pg2, rx, tx,
693 self.pg2.local_ip6, "1002::1")
696 # Test decap. decapped packets go out pg1
698 tx = self.create_tunnel_stream_6o6(self.pg2,
703 rx = self.send_and_expect(self.pg2, tx, self.pg1)
706 # RX'd packet is UDP over IPv6, test the GRE header is gone.
708 self.assertFalse(rx[0].haslayer(GRE))
709 self.assertEqual(rx[0][IPv6].dst, self.pg1.remote_ip6)
714 route4_via_tun = VppIpRoute(self, "1.1.1.1", 32,
715 [VppRoutePath("0.0.0.0",
716 gre_if.sw_if_index)])
717 route4_via_tun.add_vpp_config()
719 tx = self.create_stream_ip4(self.pg0, "1.1.1.2", "1.1.1.1")
720 rx = self.send_and_expect(self.pg0, tx, self.pg2)
722 self.verify_tunneled_4o6(self.pg0, rx, tx,
723 self.pg2.local_ip6, "1002::1")
728 route_tun_dst.remove_vpp_config()
729 route_via_tun.remove_vpp_config()
730 route4_via_tun.remove_vpp_config()
731 gre_if.remove_vpp_config()
733 self.pg2.unconfig_ip6()
734 self.pg1.unconfig_ip6()
736 def test_gre_vrf(self):
737 """ GRE tunnel VRF Tests """
739 e = VppEnum.vl_api_tunnel_encap_decap_flags_t
742 # Create an L3 GRE tunnel whose destination is in the non-default
743 # table. The underlay is thus non-default - the overlay is still
746 # - assign an IP Addres
748 gre_if = VppGreInterface(
749 self, self.pg1.local_ip4,
752 flags=(e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP |
753 e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN))
755 gre_if.add_vpp_config()
760 # Add a route via the tunnel - in the overlay
762 route_via_tun = VppIpRoute(self, "9.9.9.9", 32,
763 [VppRoutePath("0.0.0.0",
764 gre_if.sw_if_index)])
765 route_via_tun.add_vpp_config()
768 # Add a route that resolves the tunnel's destination - in the
771 route_tun_dst = VppIpRoute(self, "2.2.2.2", 32, table_id=1,
772 paths=[VppRoutePath(self.pg1.remote_ip4,
773 self.pg1.sw_if_index)])
774 route_tun_dst.add_vpp_config()
777 # Send a packet stream that is routed into the tunnel
778 # packets are sent in on pg0 which is in the default table
779 # - packets are GRE encapped
781 self.vapi.cli("clear trace")
782 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "9.9.9.9",
784 rx = self.send_and_expect(self.pg0, tx, self.pg1)
785 self.verify_tunneled_4o4(self.pg1, rx, tx,
786 self.pg1.local_ip4, "2.2.2.2",
790 # Send tunneled packets that match the created tunnel and
791 # are decapped and forwarded. This tests the decap lookup
792 # does not happen in the encap table
794 self.vapi.cli("clear trace")
795 tx = self.create_tunnel_stream_4o4(self.pg1,
800 rx = self.send_and_expect(self.pg1, tx, self.pg0)
801 self.verify_decapped_4o4(self.pg0, rx, tx)
804 # Send tunneled packets that match the created tunnel
805 # but arrive on an interface that is not in the tunnel's
806 # encap VRF, these are dropped.
807 # IP enable the interface so they aren't dropped due to
808 # IP not being enabled.
810 self.pg2.config_ip4()
811 self.vapi.cli("clear trace")
812 tx = self.create_tunnel_stream_4o4(self.pg2,
817 rx = self.send_and_assert_no_replies(
819 "GRE decap packets in wrong VRF")
821 self.pg2.unconfig_ip4()
826 route_tun_dst.remove_vpp_config()
827 route_via_tun.remove_vpp_config()
828 gre_if.remove_vpp_config()
830 def test_gre_l2(self):
831 """ GRE tunnel L2 Tests """
834 # Add routes to resolve the tunnel destinations
836 route_tun1_dst = VppIpRoute(self, "2.2.2.2", 32,
837 [VppRoutePath(self.pg0.remote_ip4,
838 self.pg0.sw_if_index)])
839 route_tun2_dst = VppIpRoute(self, "2.2.2.3", 32,
840 [VppRoutePath(self.pg0.remote_ip4,
841 self.pg0.sw_if_index)])
843 route_tun1_dst.add_vpp_config()
844 route_tun2_dst.add_vpp_config()
847 # Create 2 L2 GRE tunnels and x-connect them
849 gre_if1 = VppGreInterface(self, self.pg0.local_ip4,
851 type=(VppEnum.vl_api_gre_tunnel_type_t.
852 GRE_API_TUNNEL_TYPE_TEB))
853 gre_if2 = VppGreInterface(self, self.pg0.local_ip4,
855 type=(VppEnum.vl_api_gre_tunnel_type_t.
856 GRE_API_TUNNEL_TYPE_TEB))
857 gre_if1.add_vpp_config()
858 gre_if2.add_vpp_config()
863 self.vapi.sw_interface_set_l2_xconnect(gre_if1.sw_if_index,
866 self.vapi.sw_interface_set_l2_xconnect(gre_if2.sw_if_index,
871 # Send in tunnel encapped L2. expect out tunnel encapped L2
874 tx = self.create_tunnel_stream_l2o4(self.pg0,
877 rx = self.send_and_expect(self.pg0, tx, self.pg0)
878 self.verify_tunneled_l2o4(self.pg0, rx, tx,
882 tx = self.create_tunnel_stream_l2o4(self.pg0,
885 rx = self.send_and_expect(self.pg0, tx, self.pg0)
886 self.verify_tunneled_l2o4(self.pg0, rx, tx,
890 self.vapi.sw_interface_set_l2_xconnect(gre_if1.sw_if_index,
893 self.vapi.sw_interface_set_l2_xconnect(gre_if2.sw_if_index,
898 # Create a VLAN sub-interfaces on the GRE TEB interfaces
899 # then x-connect them
901 gre_if_11 = VppDot1QSubint(self, gre_if1, 11)
902 gre_if_12 = VppDot1QSubint(self, gre_if2, 12)
904 # gre_if_11.add_vpp_config()
905 # gre_if_12.add_vpp_config()
910 self.vapi.sw_interface_set_l2_xconnect(gre_if_11.sw_if_index,
911 gre_if_12.sw_if_index,
913 self.vapi.sw_interface_set_l2_xconnect(gre_if_12.sw_if_index,
914 gre_if_11.sw_if_index,
918 # Configure both to pop thier respective VLAN tags,
919 # so that during the x-coonect they will subsequently push
921 self.vapi.l2_interface_vlan_tag_rewrite(
922 sw_if_index=gre_if_12.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
924 self.vapi.l2_interface_vlan_tag_rewrite(
925 sw_if_index=gre_if_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
929 # Send traffic in both directiond - expect the VLAN tags to
932 tx = self.create_tunnel_stream_vlano4(self.pg0,
936 rx = self.send_and_expect(self.pg0, tx, self.pg0)
937 self.verify_tunneled_vlano4(self.pg0, rx, tx,
942 tx = self.create_tunnel_stream_vlano4(self.pg0,
946 rx = self.send_and_expect(self.pg0, tx, self.pg0)
947 self.verify_tunneled_vlano4(self.pg0, rx, tx,
953 # Cleanup Test resources
955 gre_if_11.remove_vpp_config()
956 gre_if_12.remove_vpp_config()
957 gre_if1.remove_vpp_config()
958 gre_if2.remove_vpp_config()
959 route_tun1_dst.add_vpp_config()
960 route_tun2_dst.add_vpp_config()
962 def test_gre_loop(self):
963 """ GRE tunnel loop Tests """
966 # Create an L3 GRE tunnel.
968 # - assign an IP Addres
970 gre_if = VppGreInterface(self,
973 gre_if.add_vpp_config()
978 # add a route to the tunnel's destination that points
979 # through the tunnel, hence forming a loop in the forwarding
982 route_dst = VppIpRoute(self, "1.1.1.2", 32,
983 [VppRoutePath("0.0.0.0",
984 gre_if.sw_if_index)])
985 route_dst.add_vpp_config()
988 # packets to the tunnels destination should be dropped
990 tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "1.1.1.2")
991 self.send_and_assert_no_replies(self.pg2, tx)
993 self.logger.info(self.vapi.ppcli("sh adj 7"))
998 route_dst.modify([VppRoutePath(self.pg1.remote_ip4,
999 self.pg1.sw_if_index)])
1000 route_dst.add_vpp_config()
1002 rx = self.send_and_expect(self.pg0, tx, self.pg1)
1005 # a good route throught the tunnel to check it restacked
1007 route_via_tun_2 = VppIpRoute(self, "2.2.2.2", 32,
1008 [VppRoutePath("0.0.0.0",
1009 gre_if.sw_if_index)])
1010 route_via_tun_2.add_vpp_config()
1012 tx = self.create_stream_ip4(self.pg0, "2.2.2.3", "2.2.2.2")
1013 rx = self.send_and_expect(self.pg0, tx, self.pg1)
1014 self.verify_tunneled_4o4(self.pg1, rx, tx,
1015 self.pg0.local_ip4, "1.1.1.2")
1020 route_via_tun_2.remove_vpp_config()
1021 gre_if.remove_vpp_config()
1023 def test_mgre(self):
1024 """ mGRE IPv4 tunnel Tests """
1026 for itf in self.pg_interfaces[3:]:
1028 # one underlay nh for each overlay/tunnel peer
1030 itf.generate_remote_hosts(4)
1031 itf.configure_ipv4_neighbors()
1034 # Create an L3 GRE tunnel.
1036 # - assign an IP Addres
1037 # - Add a route via the tunnel
1039 gre_if = VppGreInterface(self,
1042 mode=(VppEnum.vl_api_tunnel_mode_t.
1043 TUNNEL_API_MODE_MP))
1044 gre_if.add_vpp_config()
1047 gre_if.generate_remote_hosts(4)
1049 self.logger.info(self.vapi.cli("sh adj"))
1050 self.logger.info(self.vapi.cli("sh ip fib"))
1053 # ensure we don't match to the tunnel if the source address
1056 tx = self.create_tunnel_stream_4o4(self.pg0,
1060 self.pg0.remote_ip4)
1061 self.send_and_assert_no_replies(self.pg0, tx)
1066 for ii in range(1, 4):
1067 route_addr = "4.4.4.%d" % ii
1070 # route traffic via the peer
1072 route_via_tun = VppIpRoute(
1073 self, route_addr, 32,
1074 [VppRoutePath(gre_if._remote_hosts[ii].ip4,
1075 gre_if.sw_if_index)])
1076 route_via_tun.add_vpp_config()
1079 # Add a TEIB entry resolves the peer
1081 teib = VppTeib(self, gre_if,
1082 gre_if._remote_hosts[ii].ip4,
1083 itf._remote_hosts[ii].ip4)
1084 teib.add_vpp_config()
1087 # Send a packet stream that is routed into the tunnel
1088 # - packets are GRE encapped
1090 tx_e = self.create_stream_ip4(self.pg0, "5.5.5.5", route_addr)
1091 rx = self.send_and_expect(self.pg0, tx_e, itf)
1092 self.verify_tunneled_4o4(self.pg0, rx, tx_e,
1094 itf._remote_hosts[ii].ip4)
1096 tx_i = self.create_tunnel_stream_4o4(self.pg0,
1097 itf._remote_hosts[ii].ip4,
1100 self.pg0.remote_ip4)
1101 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1102 self.verify_decapped_4o4(self.pg0, rx, tx_i)
1105 # delete and re-add the TEIB
1107 teib.remove_vpp_config()
1108 self.send_and_assert_no_replies(self.pg0, tx_e)
1109 self.send_and_assert_no_replies(self.pg0, tx_i)
1111 teib.add_vpp_config()
1112 rx = self.send_and_expect(self.pg0, tx_e, itf)
1113 self.verify_tunneled_4o4(self.pg0, rx, tx_e,
1115 itf._remote_hosts[ii].ip4)
1116 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1117 self.verify_decapped_4o4(self.pg0, rx, tx_i)
1120 gre_if.unconfig_ip4()
1122 def test_mgre6(self):
1123 """ mGRE IPv6 tunnel Tests """
1125 self.pg0.config_ip6()
1126 self.pg0.resolve_ndp()
1128 e = VppEnum.vl_api_tunnel_encap_decap_flags_t
1130 for itf in self.pg_interfaces[3:]:
1132 # one underlay nh for each overlay/tunnel peer
1135 itf.generate_remote_hosts(4)
1136 itf.configure_ipv6_neighbors()
1139 # Create an L3 GRE tunnel.
1141 # - assign an IP Addres
1142 # - Add a route via the tunnel
1144 gre_if = VppGreInterface(
1148 mode=(VppEnum.vl_api_tunnel_mode_t.
1149 TUNNEL_API_MODE_MP),
1150 flags=e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP)
1152 gre_if.add_vpp_config()
1155 gre_if.generate_remote_hosts(4)
1160 for ii in range(1, 4):
1161 route_addr = "4::%d" % ii
1164 # Add a TEIB entry resolves the peer
1166 teib = VppTeib(self, gre_if,
1167 gre_if._remote_hosts[ii].ip6,
1168 itf._remote_hosts[ii].ip6)
1169 teib.add_vpp_config()
1172 # route traffic via the peer
1174 route_via_tun = VppIpRoute(
1175 self, route_addr, 128,
1176 [VppRoutePath(gre_if._remote_hosts[ii].ip6,
1177 gre_if.sw_if_index)])
1178 route_via_tun.add_vpp_config()
1181 # Send a packet stream that is routed into the tunnel
1182 # - packets are GRE encapped
1184 tx_e = self.create_stream_ip6(self.pg0, "5::5", route_addr,
1186 rx = self.send_and_expect(self.pg0, tx_e, itf)
1187 self.verify_tunneled_6o6(self.pg0, rx, tx_e,
1189 itf._remote_hosts[ii].ip6,
1191 tx_i = self.create_tunnel_stream_6o6(self.pg0,
1192 itf._remote_hosts[ii].ip6,
1195 self.pg0.remote_ip6)
1196 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1197 self.verify_decapped_6o6(self.pg0, rx, tx_i)
1200 # delete and re-add the TEIB
1202 teib.remove_vpp_config()
1203 self.send_and_assert_no_replies(self.pg0, tx_e)
1205 teib.add_vpp_config()
1206 rx = self.send_and_expect(self.pg0, tx_e, itf)
1207 self.verify_tunneled_6o6(self.pg0, rx, tx_e,
1209 itf._remote_hosts[ii].ip6,
1211 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1212 self.verify_decapped_6o6(self.pg0, rx, tx_i)
1215 gre_if.unconfig_ip4()
1217 self.pg0.unconfig_ip6()
1220 if __name__ == '__main__':
1221 unittest.main(testRunner=VppTestRunner)