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, \
19 from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
20 from util import ppp, ppc
21 from vpp_papi import VppEnum
24 class TestGREInputNodes(VppTestCase):
25 """ GRE Input Nodes Test Case """
28 super(TestGREInputNodes, self).setUp()
30 # create 3 pg interfaces - set one in a non-default table.
31 self.create_pg_interfaces(range(1))
33 for i in self.pg_interfaces:
38 for i in self.pg_interfaces:
41 super(TestGREInputNodes, self).tearDown()
43 def test_gre_input_node(self):
44 """ GRE gre input nodes not registerd unless configured """
45 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
46 IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
49 self.pg0.add_stream(pkt)
51 # no tunnel created, gre-input not registered
52 err = self.statistics.get_counter(
53 '/err/ip4-local/unknown ip protocol')[0]
54 self.assertEqual(err, 1)
58 gre_if = VppGreInterface(self, self.pg0.local_ip4, "1.1.1.2")
59 gre_if.add_vpp_config()
61 self.pg0.add_stream(pkt)
63 # tunnel created, gre-input registered
64 err = self.statistics.get_counter(
65 '/err/ip4-local/unknown ip protocol')[0]
66 # expect no new errors
67 self.assertEqual(err, err_count)
70 class TestGRE(VppTestCase):
75 super(TestGRE, cls).setUpClass()
78 def tearDownClass(cls):
79 super(TestGRE, cls).tearDownClass()
82 super(TestGRE, self).setUp()
84 # create 3 pg interfaces - set one in a non-default table.
85 self.create_pg_interfaces(range(5))
87 self.tbl = VppIpTable(self, 1)
88 self.tbl.add_vpp_config()
89 self.pg1.set_table_ip4(1)
91 for i in self.pg_interfaces:
95 self.pg0.resolve_arp()
97 self.pg1.resolve_arp()
99 self.pg2.resolve_ndp()
100 self.pg3.config_ip4()
101 self.pg3.resolve_arp()
102 self.pg4.config_ip4()
103 self.pg4.resolve_arp()
106 for i in self.pg_interfaces:
110 self.pg1.set_table_ip4(0)
111 super(TestGRE, self).tearDown()
113 def create_stream_ip4(self, src_if, src_ip, dst_ip, dscp=0, ecn=0):
115 tos = (dscp << 2) | ecn
116 for i in range(0, 257):
117 info = self.create_packet_info(src_if, src_if)
118 payload = self.info_to_payload(info)
119 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
120 IP(src=src_ip, dst=dst_ip, tos=tos) /
121 UDP(sport=1234, dport=1234) /
127 def create_stream_ip6(self, src_if, src_ip, dst_ip, dscp=0, ecn=0):
129 tc = (dscp << 2) | ecn
130 for i in range(0, 257):
131 info = self.create_packet_info(src_if, src_if)
132 payload = self.info_to_payload(info)
133 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
134 IPv6(src=src_ip, dst=dst_ip, tc=tc) /
135 UDP(sport=1234, dport=1234) /
141 def create_tunnel_stream_4o4(self, src_if,
142 tunnel_src, tunnel_dst,
145 for i in range(0, 257):
146 info = self.create_packet_info(src_if, src_if)
147 payload = self.info_to_payload(info)
148 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
149 IP(src=tunnel_src, dst=tunnel_dst) /
151 IP(src=src_ip, dst=dst_ip) /
152 UDP(sport=1234, dport=1234) /
158 def create_tunnel_stream_6o4(self, src_if,
159 tunnel_src, tunnel_dst,
162 for i in range(0, 257):
163 info = self.create_packet_info(src_if, src_if)
164 payload = self.info_to_payload(info)
165 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
166 IP(src=tunnel_src, dst=tunnel_dst) /
168 IPv6(src=src_ip, dst=dst_ip) /
169 UDP(sport=1234, dport=1234) /
175 def create_tunnel_stream_6o6(self, src_if,
176 tunnel_src, tunnel_dst,
179 for i in range(0, 257):
180 info = self.create_packet_info(src_if, src_if)
181 payload = self.info_to_payload(info)
182 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
183 IPv6(src=tunnel_src, dst=tunnel_dst) /
185 IPv6(src=src_ip, dst=dst_ip) /
186 UDP(sport=1234, dport=1234) /
192 def create_tunnel_stream_l2o4(self, src_if,
193 tunnel_src, tunnel_dst):
195 for i in range(0, 257):
196 info = self.create_packet_info(src_if, src_if)
197 payload = self.info_to_payload(info)
198 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
199 IP(src=tunnel_src, dst=tunnel_dst) /
201 Ether(dst=RandMAC('*:*:*:*:*:*'),
202 src=RandMAC('*:*:*:*:*:*')) /
203 IP(src=scapy.compat.raw(RandIP()),
204 dst=scapy.compat.raw(RandIP())) /
205 UDP(sport=1234, dport=1234) /
211 def create_tunnel_stream_vlano4(self, src_if,
212 tunnel_src, tunnel_dst, vlan):
214 for i in range(0, 257):
215 info = self.create_packet_info(src_if, src_if)
216 payload = self.info_to_payload(info)
217 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
218 IP(src=tunnel_src, dst=tunnel_dst) /
220 Ether(dst=RandMAC('*:*:*:*:*:*'),
221 src=RandMAC('*:*:*:*:*:*')) /
223 IP(src=scapy.compat.raw(RandIP()),
224 dst=scapy.compat.raw(RandIP())) /
225 UDP(sport=1234, dport=1234) /
231 def verify_tunneled_4o4(self, src_if, capture, sent,
232 tunnel_src, tunnel_dst,
235 self.assertEqual(len(capture), len(sent))
236 tos = (dscp << 2) | ecn
238 for i in range(len(capture)):
246 self.assertEqual(rx_ip.src, tunnel_src)
247 self.assertEqual(rx_ip.dst, tunnel_dst)
248 self.assertEqual(rx_ip.tos, tos)
249 self.assertEqual(rx_ip.len, len(rx_ip))
254 self.assertEqual(rx_ip.src, tx_ip.src)
255 self.assertEqual(rx_ip.dst, tx_ip.dst)
256 # IP processing post pop has decremented the TTL
257 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
260 self.logger.error(ppp("Rx:", rx))
261 self.logger.error(ppp("Tx:", tx))
264 def verify_tunneled_6o6(self, src_if, capture, sent,
265 tunnel_src, tunnel_dst,
268 self.assertEqual(len(capture), len(sent))
269 tc = (dscp << 2) | ecn
271 for i in range(len(capture)):
279 self.assertEqual(rx_ip.src, tunnel_src)
280 self.assertEqual(rx_ip.dst, tunnel_dst)
281 self.assertEqual(rx_ip.tc, tc)
283 rx_gre = GRE(scapy.compat.raw(rx_ip[IPv6].payload))
285 self.assertEqual(rx_ip.plen, len(rx_gre))
289 self.assertEqual(rx_ip.src, tx_ip.src)
290 self.assertEqual(rx_ip.dst, tx_ip.dst)
293 self.logger.error(ppp("Rx:", rx))
294 self.logger.error(ppp("Tx:", tx))
297 def verify_tunneled_4o6(self, src_if, capture, sent,
298 tunnel_src, tunnel_dst):
300 self.assertEqual(len(capture), len(sent))
302 for i in range(len(capture)):
309 self.assertEqual(rx_ip.src, tunnel_src)
310 self.assertEqual(rx_ip.dst, tunnel_dst)
312 rx_gre = GRE(scapy.compat.raw(rx_ip[IPv6].payload))
314 self.assertEqual(rx_ip.plen, len(rx_gre))
319 self.assertEqual(rx_ip.src, tx_ip.src)
320 self.assertEqual(rx_ip.dst, tx_ip.dst)
323 self.logger.error(ppp("Rx:", rx))
324 self.logger.error(ppp("Tx:", tx))
327 def verify_tunneled_6o4(self, src_if, capture, sent,
328 tunnel_src, tunnel_dst):
330 self.assertEqual(len(capture), len(sent))
332 for i in range(len(capture)):
339 self.assertEqual(rx_ip.src, tunnel_src)
340 self.assertEqual(rx_ip.dst, tunnel_dst)
341 self.assertEqual(rx_ip.len, len(rx_ip))
343 rx_gre = GRE(scapy.compat.raw(rx_ip[IP].payload))
347 self.assertEqual(rx_ip.src, tx_ip.src)
348 self.assertEqual(rx_ip.dst, tx_ip.dst)
351 self.logger.error(ppp("Rx:", rx))
352 self.logger.error(ppp("Tx:", tx))
355 def verify_tunneled_l2o4(self, src_if, capture, sent,
356 tunnel_src, tunnel_dst):
357 self.assertEqual(len(capture), len(sent))
359 for i in range(len(capture)):
367 self.assertEqual(rx_ip.src, tunnel_src)
368 self.assertEqual(rx_ip.dst, tunnel_dst)
369 self.assertEqual(rx_ip.len, len(rx_ip))
372 rx_l2 = rx_gre[Ether]
375 tx_l2 = tx_gre[Ether]
378 self.assertEqual(rx_ip.src, tx_ip.src)
379 self.assertEqual(rx_ip.dst, tx_ip.dst)
380 # bridged, not L3 forwarded, so no TTL decrement
381 self.assertEqual(rx_ip.ttl, tx_ip.ttl)
384 self.logger.error(ppp("Rx:", rx))
385 self.logger.error(ppp("Tx:", tx))
388 def verify_tunneled_vlano4(self, src_if, capture, sent,
389 tunnel_src, tunnel_dst, vlan):
391 self.assertEqual(len(capture), len(sent))
393 ppc("Unexpected packets captured:", capture)
396 for i in range(len(capture)):
404 self.assertEqual(rx_ip.src, tunnel_src)
405 self.assertEqual(rx_ip.dst, tunnel_dst)
408 rx_l2 = rx_gre[Ether]
409 rx_vlan = rx_l2[Dot1Q]
412 self.assertEqual(rx_vlan.vlan, vlan)
415 tx_l2 = tx_gre[Ether]
418 self.assertEqual(rx_ip.src, tx_ip.src)
419 self.assertEqual(rx_ip.dst, tx_ip.dst)
420 # bridged, not L3 forwarded, so no TTL decrement
421 self.assertEqual(rx_ip.ttl, tx_ip.ttl)
424 self.logger.error(ppp("Rx:", rx))
425 self.logger.error(ppp("Tx:", tx))
428 def verify_decapped_4o4(self, src_if, capture, sent):
429 self.assertEqual(len(capture), len(sent))
431 for i in range(len(capture)):
441 self.assertEqual(rx_ip.src, tx_ip.src)
442 self.assertEqual(rx_ip.dst, tx_ip.dst)
443 # IP processing post pop has decremented the TTL
444 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
447 self.logger.error(ppp("Rx:", rx))
448 self.logger.error(ppp("Tx:", tx))
451 def verify_decapped_6o4(self, src_if, capture, sent):
452 self.assertEqual(len(capture), len(sent))
454 for i in range(len(capture)):
464 self.assertEqual(rx_ip.src, tx_ip.src)
465 self.assertEqual(rx_ip.dst, tx_ip.dst)
466 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
469 self.logger.error(ppp("Rx:", rx))
470 self.logger.error(ppp("Tx:", tx))
473 def verify_decapped_6o6(self, src_if, capture, sent):
474 self.assertEqual(len(capture), len(sent))
476 for i in range(len(capture)):
486 self.assertEqual(rx_ip.src, tx_ip.src)
487 self.assertEqual(rx_ip.dst, tx_ip.dst)
488 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
491 self.logger.error(ppp("Rx:", rx))
492 self.logger.error(ppp("Tx:", tx))
496 """ GRE IPv4 tunnel Tests """
499 # Create an L3 GRE tunnel.
501 # - assign an IP Addres
502 # - Add a route via the tunnel
504 gre_if = VppGreInterface(self,
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(self, "4.4.4.4", 32,
524 [VppRoutePath("0.0.0.0",
525 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(self, "1.1.1.2", 32,
543 [VppRoutePath(self.pg0.remote_ip4,
544 self.pg0.sw_if_index)])
545 route_tun_dst.add_vpp_config()
548 # Send a packet stream that is routed into the tunnel
549 # - packets are GRE encapped
551 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "4.4.4.4")
552 rx = self.send_and_expect(self.pg0, tx, self.pg0)
553 self.verify_tunneled_4o4(self.pg0, rx, tx,
554 self.pg0.local_ip4, "1.1.1.2")
557 # Send tunneled packets that match the created tunnel and
558 # are decapped and forwarded
560 tx = self.create_tunnel_stream_4o4(self.pg0,
565 rx = self.send_and_expect(self.pg0, tx, self.pg0)
566 self.verify_decapped_4o4(self.pg0, rx, tx)
569 # Send tunneled packets that do not match the tunnel's src
571 self.vapi.cli("clear trace")
572 tx = self.create_tunnel_stream_4o4(self.pg0,
577 self.send_and_assert_no_replies(
579 remark="GRE packets forwarded despite no SRC address match")
582 # Configure IPv6 on the PG interface so we can route IPv6
585 self.pg0.config_ip6()
586 self.pg0.resolve_ndp()
589 # Send IPv6 tunnel encapslated packets
590 # - dropped since IPv6 is not enabled on the tunnel
592 tx = self.create_tunnel_stream_6o4(self.pg0,
597 self.send_and_assert_no_replies(self.pg0, tx,
598 "IPv6 GRE packets forwarded "
599 "despite IPv6 not enabled on tunnel")
602 # Enable IPv6 on the tunnel
607 # Send IPv6 tunnel encapslated packets
608 # - forwarded since IPv6 is enabled on the tunnel
610 tx = self.create_tunnel_stream_6o4(self.pg0,
615 rx = self.send_and_expect(self.pg0, tx, self.pg0)
616 self.verify_decapped_6o4(self.pg0, rx, tx)
619 # Send v6 packets for v4 encap
621 route6_via_tun = VppIpRoute(
622 self, "2001::1", 128,
625 proto=DpoProto.DPO_PROTO_IP6)])
626 route6_via_tun.add_vpp_config()
628 tx = self.create_stream_ip6(self.pg0, "2001::2", "2001::1")
629 rx = self.send_and_expect(self.pg0, tx, self.pg0)
631 self.verify_tunneled_6o4(self.pg0, rx, tx,
632 self.pg0.local_ip4, "1.1.1.2")
635 # add a labelled route through the tunnel
637 label_via_tun = VppIpRoute(self, "5.4.3.2", 32,
638 [VppRoutePath("0.0.0.0",
640 labels=[VppMplsLabel(33)])])
641 label_via_tun.add_vpp_config()
643 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "5.4.3.2")
644 rx = self.send_and_expect(self.pg0, tx, self.pg0)
645 self.verify_tunneled_4o4(self.pg0, rx, tx,
646 self.pg0.local_ip4, "1.1.1.2")
649 # an MPLS tunnel over the GRE tunnel add a route through
652 mpls_tun = VppMPLSTunnelInterface(
654 [VppRoutePath("0.0.0.0",
656 labels=[VppMplsLabel(44),
658 mpls_tun.add_vpp_config()
661 label_via_mpls = VppIpRoute(self, "5.4.3.1", 32,
662 [VppRoutePath("0.0.0.0",
663 mpls_tun.sw_if_index,
664 labels=[VppMplsLabel(33)])])
665 label_via_mpls.add_vpp_config()
667 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "5.4.3.1")
668 rx = self.send_and_expect(self.pg0, tx, self.pg0)
669 self.verify_tunneled_4o4(self.pg0, rx, tx,
670 self.pg0.local_ip4, "1.1.1.2")
672 mpls_tun_l2 = VppMPLSTunnelInterface(
674 [VppRoutePath("0.0.0.0",
676 labels=[VppMplsLabel(44),
679 mpls_tun_l2.add_vpp_config()
680 mpls_tun_l2.admin_up()
685 route_tun_dst.remove_vpp_config()
686 route_via_tun.remove_vpp_config()
687 route6_via_tun.remove_vpp_config()
688 label_via_mpls.remove_vpp_config()
689 label_via_tun.remove_vpp_config()
690 mpls_tun.remove_vpp_config()
691 mpls_tun_l2.remove_vpp_config()
692 gre_if.remove_vpp_config()
694 self.pg0.unconfig_ip6()
697 """ GRE IPv6 tunnel Tests """
699 self.pg1.config_ip6()
700 self.pg1.resolve_ndp()
703 # Create an L3 GRE tunnel.
705 # - assign an IP Address
706 # - Add a route via the tunnel
708 gre_if = VppGreInterface(self,
711 gre_if.add_vpp_config()
715 route_via_tun = VppIpRoute(self, "4004::1", 128,
716 [VppRoutePath("0::0",
717 gre_if.sw_if_index)])
719 route_via_tun.add_vpp_config()
722 # Send a packet stream that is routed into the tunnel
723 # - they are all dropped since the tunnel's destintation IP
724 # is unresolved - or resolves via the default route - which
727 tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
728 self.send_and_assert_no_replies(
730 "GRE packets forwarded without DIP resolved")
733 # Add a route that resolves the tunnel's destination
735 route_tun_dst = VppIpRoute(self, "1002::1", 128,
736 [VppRoutePath(self.pg2.remote_ip6,
737 self.pg2.sw_if_index)])
738 route_tun_dst.add_vpp_config()
741 # Send a packet stream that is routed into the tunnel
742 # - packets are GRE encapped
744 tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
745 rx = self.send_and_expect(self.pg2, tx, self.pg2)
746 self.verify_tunneled_6o6(self.pg2, rx, tx,
747 self.pg2.local_ip6, "1002::1")
750 # Test decap. decapped packets go out pg1
752 tx = self.create_tunnel_stream_6o6(self.pg2,
757 rx = self.send_and_expect(self.pg2, tx, self.pg1)
760 # RX'd packet is UDP over IPv6, test the GRE header is gone.
762 self.assertFalse(rx[0].haslayer(GRE))
763 self.assertEqual(rx[0][IPv6].dst, self.pg1.remote_ip6)
768 route4_via_tun = VppIpRoute(self, "1.1.1.1", 32,
769 [VppRoutePath("0.0.0.0",
770 gre_if.sw_if_index)])
771 route4_via_tun.add_vpp_config()
773 tx = self.create_stream_ip4(self.pg0, "1.1.1.2", "1.1.1.1")
774 rx = self.send_and_expect(self.pg0, tx, self.pg2)
776 self.verify_tunneled_4o6(self.pg0, rx, tx,
777 self.pg2.local_ip6, "1002::1")
782 route_tun_dst.remove_vpp_config()
783 route_via_tun.remove_vpp_config()
784 route4_via_tun.remove_vpp_config()
785 gre_if.remove_vpp_config()
787 self.pg2.unconfig_ip6()
788 self.pg1.unconfig_ip6()
790 def test_gre_vrf(self):
791 """ GRE tunnel VRF Tests """
793 e = VppEnum.vl_api_tunnel_encap_decap_flags_t
796 # Create an L3 GRE tunnel whose destination is in the non-default
797 # table. The underlay is thus non-default - the overlay is still
800 # - assign an IP Addres
802 gre_if = VppGreInterface(
803 self, self.pg1.local_ip4,
806 flags=(e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP |
807 e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN))
809 gre_if.add_vpp_config()
814 # Add a route via the tunnel - in the overlay
816 route_via_tun = VppIpRoute(self, "9.9.9.9", 32,
817 [VppRoutePath("0.0.0.0",
818 gre_if.sw_if_index)])
819 route_via_tun.add_vpp_config()
822 # Add a route that resolves the tunnel's destination - in the
825 route_tun_dst = VppIpRoute(self, "2.2.2.2", 32, table_id=1,
826 paths=[VppRoutePath(self.pg1.remote_ip4,
827 self.pg1.sw_if_index)])
828 route_tun_dst.add_vpp_config()
831 # Send a packet stream that is routed into the tunnel
832 # packets are sent in on pg0 which is in the default table
833 # - packets are GRE encapped
835 self.vapi.cli("clear trace")
836 tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "9.9.9.9",
838 rx = self.send_and_expect(self.pg0, tx, self.pg1)
839 self.verify_tunneled_4o4(self.pg1, rx, tx,
840 self.pg1.local_ip4, "2.2.2.2",
844 # Send tunneled packets that match the created tunnel and
845 # are decapped and forwarded. This tests the decap lookup
846 # does not happen in the encap table
848 self.vapi.cli("clear trace")
849 tx = self.create_tunnel_stream_4o4(self.pg1,
854 rx = self.send_and_expect(self.pg1, tx, self.pg0)
855 self.verify_decapped_4o4(self.pg0, rx, tx)
858 # Send tunneled packets that match the created tunnel
859 # but arrive on an interface that is not in the tunnel's
860 # encap VRF, these are dropped.
861 # IP enable the interface so they aren't dropped due to
862 # IP not being enabled.
864 self.pg2.config_ip4()
865 self.vapi.cli("clear trace")
866 tx = self.create_tunnel_stream_4o4(self.pg2,
871 rx = self.send_and_assert_no_replies(
873 "GRE decap packets in wrong VRF")
875 self.pg2.unconfig_ip4()
880 route_tun_dst.remove_vpp_config()
881 route_via_tun.remove_vpp_config()
882 gre_if.remove_vpp_config()
884 def test_gre_l2(self):
885 """ GRE tunnel L2 Tests """
888 # Add routes to resolve the tunnel destinations
890 route_tun1_dst = VppIpRoute(self, "2.2.2.2", 32,
891 [VppRoutePath(self.pg0.remote_ip4,
892 self.pg0.sw_if_index)])
893 route_tun2_dst = VppIpRoute(self, "2.2.2.3", 32,
894 [VppRoutePath(self.pg0.remote_ip4,
895 self.pg0.sw_if_index)])
897 route_tun1_dst.add_vpp_config()
898 route_tun2_dst.add_vpp_config()
901 # Create 2 L2 GRE tunnels and x-connect them
903 gre_if1 = VppGreInterface(self, self.pg0.local_ip4,
905 type=(VppEnum.vl_api_gre_tunnel_type_t.
906 GRE_API_TUNNEL_TYPE_TEB))
907 gre_if2 = VppGreInterface(self, self.pg0.local_ip4,
909 type=(VppEnum.vl_api_gre_tunnel_type_t.
910 GRE_API_TUNNEL_TYPE_TEB))
911 gre_if1.add_vpp_config()
912 gre_if2.add_vpp_config()
917 self.vapi.sw_interface_set_l2_xconnect(gre_if1.sw_if_index,
920 self.vapi.sw_interface_set_l2_xconnect(gre_if2.sw_if_index,
925 # Send in tunnel encapped L2. expect out tunnel encapped L2
928 tx = self.create_tunnel_stream_l2o4(self.pg0,
931 rx = self.send_and_expect(self.pg0, tx, self.pg0)
932 self.verify_tunneled_l2o4(self.pg0, rx, tx,
936 tx = self.create_tunnel_stream_l2o4(self.pg0,
939 rx = self.send_and_expect(self.pg0, tx, self.pg0)
940 self.verify_tunneled_l2o4(self.pg0, rx, tx,
944 self.vapi.sw_interface_set_l2_xconnect(gre_if1.sw_if_index,
947 self.vapi.sw_interface_set_l2_xconnect(gre_if2.sw_if_index,
952 # Create a VLAN sub-interfaces on the GRE TEB interfaces
953 # then x-connect them
955 gre_if_11 = VppDot1QSubint(self, gre_if1, 11)
956 gre_if_12 = VppDot1QSubint(self, gre_if2, 12)
958 # gre_if_11.add_vpp_config()
959 # gre_if_12.add_vpp_config()
964 self.vapi.sw_interface_set_l2_xconnect(gre_if_11.sw_if_index,
965 gre_if_12.sw_if_index,
967 self.vapi.sw_interface_set_l2_xconnect(gre_if_12.sw_if_index,
968 gre_if_11.sw_if_index,
972 # Configure both to pop thier respective VLAN tags,
973 # so that during the x-coonect they will subsequently push
975 self.vapi.l2_interface_vlan_tag_rewrite(
976 sw_if_index=gre_if_12.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
978 self.vapi.l2_interface_vlan_tag_rewrite(
979 sw_if_index=gre_if_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
983 # Send traffic in both directiond - expect the VLAN tags to
986 tx = self.create_tunnel_stream_vlano4(self.pg0,
990 rx = self.send_and_expect(self.pg0, tx, self.pg0)
991 self.verify_tunneled_vlano4(self.pg0, rx, tx,
996 tx = self.create_tunnel_stream_vlano4(self.pg0,
1000 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1001 self.verify_tunneled_vlano4(self.pg0, rx, tx,
1007 # Cleanup Test resources
1009 gre_if_11.remove_vpp_config()
1010 gre_if_12.remove_vpp_config()
1011 gre_if1.remove_vpp_config()
1012 gre_if2.remove_vpp_config()
1013 route_tun1_dst.add_vpp_config()
1014 route_tun2_dst.add_vpp_config()
1016 def test_gre_loop(self):
1017 """ GRE tunnel loop Tests """
1020 # Create an L3 GRE tunnel.
1022 # - assign an IP Addres
1024 gre_if = VppGreInterface(self,
1027 gre_if.add_vpp_config()
1032 # add a route to the tunnel's destination that points
1033 # through the tunnel, hence forming a loop in the forwarding
1036 route_dst = VppIpRoute(self, "1.1.1.2", 32,
1037 [VppRoutePath("0.0.0.0",
1038 gre_if.sw_if_index)])
1039 route_dst.add_vpp_config()
1042 # packets to the tunnels destination should be dropped
1044 tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "1.1.1.2")
1045 self.send_and_assert_no_replies(self.pg2, tx)
1047 self.logger.info(self.vapi.ppcli("sh adj 7"))
1052 route_dst.modify([VppRoutePath(self.pg1.remote_ip4,
1053 self.pg1.sw_if_index)])
1054 route_dst.add_vpp_config()
1056 rx = self.send_and_expect(self.pg0, tx, self.pg1)
1059 # a good route throught the tunnel to check it restacked
1061 route_via_tun_2 = VppIpRoute(self, "2.2.2.2", 32,
1062 [VppRoutePath("0.0.0.0",
1063 gre_if.sw_if_index)])
1064 route_via_tun_2.add_vpp_config()
1066 tx = self.create_stream_ip4(self.pg0, "2.2.2.3", "2.2.2.2")
1067 rx = self.send_and_expect(self.pg0, tx, self.pg1)
1068 self.verify_tunneled_4o4(self.pg1, rx, tx,
1069 self.pg0.local_ip4, "1.1.1.2")
1074 route_via_tun_2.remove_vpp_config()
1075 gre_if.remove_vpp_config()
1077 def test_mgre(self):
1078 """ mGRE IPv4 tunnel Tests """
1080 for itf in self.pg_interfaces[3:]:
1082 # one underlay nh for each overlay/tunnel peer
1084 itf.generate_remote_hosts(4)
1085 itf.configure_ipv4_neighbors()
1088 # Create an L3 GRE tunnel.
1090 # - assign an IP Addres
1091 # - Add a route via the tunnel
1093 gre_if = VppGreInterface(self,
1096 mode=(VppEnum.vl_api_tunnel_mode_t.
1097 TUNNEL_API_MODE_MP))
1098 gre_if.add_vpp_config()
1101 gre_if.generate_remote_hosts(4)
1103 self.logger.info(self.vapi.cli("sh adj"))
1104 self.logger.info(self.vapi.cli("sh ip fib"))
1107 # ensure we don't match to the tunnel if the source address
1110 tx = self.create_tunnel_stream_4o4(self.pg0,
1114 self.pg0.remote_ip4)
1115 self.send_and_assert_no_replies(self.pg0, tx)
1120 for ii in range(1, 4):
1121 route_addr = "4.4.4.%d" % ii
1124 # route traffic via the peer
1126 route_via_tun = VppIpRoute(
1127 self, route_addr, 32,
1128 [VppRoutePath(gre_if._remote_hosts[ii].ip4,
1129 gre_if.sw_if_index)])
1130 route_via_tun.add_vpp_config()
1133 # Add a TEIB entry resolves the peer
1135 teib = VppTeib(self, gre_if,
1136 gre_if._remote_hosts[ii].ip4,
1137 itf._remote_hosts[ii].ip4)
1138 teib.add_vpp_config()
1141 # Send a packet stream that is routed into the tunnel
1142 # - packets are GRE encapped
1144 tx_e = self.create_stream_ip4(self.pg0, "5.5.5.5", route_addr)
1145 rx = self.send_and_expect(self.pg0, tx_e, itf)
1146 self.verify_tunneled_4o4(self.pg0, rx, tx_e,
1148 itf._remote_hosts[ii].ip4)
1150 tx_i = self.create_tunnel_stream_4o4(self.pg0,
1151 itf._remote_hosts[ii].ip4,
1154 self.pg0.remote_ip4)
1155 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1156 self.verify_decapped_4o4(self.pg0, rx, tx_i)
1159 # delete and re-add the TEIB
1161 teib.remove_vpp_config()
1162 self.send_and_assert_no_replies(self.pg0, tx_e)
1163 self.send_and_assert_no_replies(self.pg0, tx_i)
1165 teib.add_vpp_config()
1166 rx = self.send_and_expect(self.pg0, tx_e, itf)
1167 self.verify_tunneled_4o4(self.pg0, rx, tx_e,
1169 itf._remote_hosts[ii].ip4)
1170 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1171 self.verify_decapped_4o4(self.pg0, rx, tx_i)
1174 gre_if.unconfig_ip4()
1176 def test_mgre6(self):
1177 """ mGRE IPv6 tunnel Tests """
1179 self.pg0.config_ip6()
1180 self.pg0.resolve_ndp()
1182 e = VppEnum.vl_api_tunnel_encap_decap_flags_t
1184 for itf in self.pg_interfaces[3:]:
1186 # one underlay nh for each overlay/tunnel peer
1189 itf.generate_remote_hosts(4)
1190 itf.configure_ipv6_neighbors()
1193 # Create an L3 GRE tunnel.
1195 # - assign an IP Addres
1196 # - Add a route via the tunnel
1198 gre_if = VppGreInterface(
1202 mode=(VppEnum.vl_api_tunnel_mode_t.
1203 TUNNEL_API_MODE_MP),
1204 flags=e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP)
1206 gre_if.add_vpp_config()
1209 gre_if.generate_remote_hosts(4)
1214 for ii in range(1, 4):
1215 route_addr = "4::%d" % ii
1218 # Add a TEIB entry resolves the peer
1220 teib = VppTeib(self, gre_if,
1221 gre_if._remote_hosts[ii].ip6,
1222 itf._remote_hosts[ii].ip6)
1223 teib.add_vpp_config()
1226 # route traffic via the peer
1228 route_via_tun = VppIpRoute(
1229 self, route_addr, 128,
1230 [VppRoutePath(gre_if._remote_hosts[ii].ip6,
1231 gre_if.sw_if_index)])
1232 route_via_tun.add_vpp_config()
1235 # Send a packet stream that is routed into the tunnel
1236 # - packets are GRE encapped
1238 tx_e = self.create_stream_ip6(self.pg0, "5::5", route_addr,
1240 rx = self.send_and_expect(self.pg0, tx_e, itf)
1241 self.verify_tunneled_6o6(self.pg0, rx, tx_e,
1243 itf._remote_hosts[ii].ip6,
1245 tx_i = self.create_tunnel_stream_6o6(self.pg0,
1246 itf._remote_hosts[ii].ip6,
1249 self.pg0.remote_ip6)
1250 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1251 self.verify_decapped_6o6(self.pg0, rx, tx_i)
1254 # delete and re-add the TEIB
1256 teib.remove_vpp_config()
1257 self.send_and_assert_no_replies(self.pg0, tx_e)
1259 teib.add_vpp_config()
1260 rx = self.send_and_expect(self.pg0, tx_e, itf)
1261 self.verify_tunneled_6o6(self.pg0, rx, tx_e,
1263 itf._remote_hosts[ii].ip6,
1265 rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
1266 self.verify_decapped_6o6(self.pg0, rx, tx_i)
1269 gre_if.unconfig_ip4()
1271 self.pg0.unconfig_ip6()
1274 if __name__ == '__main__':
1275 unittest.main(testRunner=VppTestRunner)