FIB recusrion loop checks traverse midchain adjacencies
[vpp.git] / test / test_gre.py
1 #!/usr/bin/env python
2
3 import unittest
4 from logging import *
5
6 from framework import VppTestCase, VppTestRunner
7 from vpp_sub_interface import VppDot1QSubint
8 from vpp_gre_interface import VppGreInterface, VppGre6Interface
9 from vpp_ip import DpoProto
10 from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable
11 from vpp_papi_provider import L2_VTR_OP
12
13 from scapy.packet import Raw
14 from scapy.layers.l2 import Ether, Dot1Q, GRE
15 from scapy.layers.inet import IP, UDP
16 from scapy.layers.inet6 import IPv6
17 from scapy.volatile import RandMAC, RandIP
18
19 from util import ppp, ppc
20
21
22 class GreTunnelTypes:
23     TT_L3 = 0
24     TT_TEB = 1
25     TT_ERSPAN = 2
26
27
28 class TestGRE(VppTestCase):
29     """ GRE Test Case """
30
31     @classmethod
32     def setUpClass(cls):
33         super(TestGRE, cls).setUpClass()
34
35     def setUp(self):
36         super(TestGRE, self).setUp()
37
38         # create 3 pg interfaces - set one in a non-default table.
39         self.create_pg_interfaces(range(3))
40
41         self.tbl = VppIpTable(self, 1)
42         self.tbl.add_vpp_config()
43         self.pg1.set_table_ip4(1)
44
45         for i in self.pg_interfaces:
46             i.admin_up()
47
48         self.pg0.config_ip4()
49         self.pg0.resolve_arp()
50         self.pg1.config_ip4()
51         self.pg1.resolve_arp()
52         self.pg2.config_ip6()
53         self.pg2.resolve_ndp()
54
55     def tearDown(self):
56         for i in self.pg_interfaces:
57             i.unconfig_ip4()
58             i.unconfig_ip6()
59             i.admin_down()
60         self.pg1.set_table_ip4(0)
61         super(TestGRE, self).tearDown()
62
63     def create_stream_ip4(self, src_if, src_ip, dst_ip):
64         pkts = []
65         for i in range(0, 257):
66             info = self.create_packet_info(src_if, src_if)
67             payload = self.info_to_payload(info)
68             p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
69                  IP(src=src_ip, dst=dst_ip) /
70                  UDP(sport=1234, dport=1234) /
71                  Raw(payload))
72             info.data = p.copy()
73             pkts.append(p)
74         return pkts
75
76     def create_stream_ip6(self, src_if, src_ip, dst_ip):
77         pkts = []
78         for i in range(0, 257):
79             info = self.create_packet_info(src_if, src_if)
80             payload = self.info_to_payload(info)
81             p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
82                  IPv6(src=src_ip, dst=dst_ip) /
83                  UDP(sport=1234, dport=1234) /
84                  Raw(payload))
85             info.data = p.copy()
86             pkts.append(p)
87         return pkts
88
89     def create_tunnel_stream_4o4(self, src_if,
90                                  tunnel_src, tunnel_dst,
91                                  src_ip, dst_ip):
92         pkts = []
93         for i in range(0, 257):
94             info = self.create_packet_info(src_if, src_if)
95             payload = self.info_to_payload(info)
96             p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
97                  IP(src=tunnel_src, dst=tunnel_dst) /
98                  GRE() /
99                  IP(src=src_ip, dst=dst_ip) /
100                  UDP(sport=1234, dport=1234) /
101                  Raw(payload))
102             info.data = p.copy()
103             pkts.append(p)
104         return pkts
105
106     def create_tunnel_stream_6o4(self, src_if,
107                                  tunnel_src, tunnel_dst,
108                                  src_ip, dst_ip):
109         pkts = []
110         for i in range(0, 257):
111             info = self.create_packet_info(src_if, src_if)
112             payload = self.info_to_payload(info)
113             p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
114                  IP(src=tunnel_src, dst=tunnel_dst) /
115                  GRE() /
116                  IPv6(src=src_ip, dst=dst_ip) /
117                  UDP(sport=1234, dport=1234) /
118                  Raw(payload))
119             info.data = p.copy()
120             pkts.append(p)
121         return pkts
122
123     def create_tunnel_stream_6o6(self, src_if,
124                                  tunnel_src, tunnel_dst,
125                                  src_ip, dst_ip):
126         pkts = []
127         for i in range(0, 257):
128             info = self.create_packet_info(src_if, src_if)
129             payload = self.info_to_payload(info)
130             p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
131                  IPv6(src=tunnel_src, dst=tunnel_dst) /
132                  GRE() /
133                  IPv6(src=src_ip, dst=dst_ip) /
134                  UDP(sport=1234, dport=1234) /
135                  Raw(payload))
136             info.data = p.copy()
137             pkts.append(p)
138         return pkts
139
140     def create_tunnel_stream_l2o4(self, src_if,
141                                   tunnel_src, tunnel_dst):
142         pkts = []
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) /
148                  GRE() /
149                  Ether(dst=RandMAC('*:*:*:*:*:*'),
150                        src=RandMAC('*:*:*:*:*:*')) /
151                  IP(src=str(RandIP()), dst=str(RandIP())) /
152                  UDP(sport=1234, dport=1234) /
153                  Raw(payload))
154             info.data = p.copy()
155             pkts.append(p)
156         return pkts
157
158     def create_tunnel_stream_vlano4(self, src_if,
159                                     tunnel_src, tunnel_dst, vlan):
160         pkts = []
161         for i in range(0, 257):
162             info = self.create_packet_info(src_if, src_if)
163             payload = self.info_to_payload(info)
164             p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
165                  IP(src=tunnel_src, dst=tunnel_dst) /
166                  GRE() /
167                  Ether(dst=RandMAC('*:*:*:*:*:*'),
168                        src=RandMAC('*:*:*:*:*:*')) /
169                  Dot1Q(vlan=vlan) /
170                  IP(src=str(RandIP()), dst=str(RandIP())) /
171                  UDP(sport=1234, dport=1234) /
172                  Raw(payload))
173             info.data = p.copy()
174             pkts.append(p)
175         return pkts
176
177     def verify_tunneled_4o4(self, src_if, capture, sent,
178                             tunnel_src, tunnel_dst):
179
180         self.assertEqual(len(capture), len(sent))
181
182         for i in range(len(capture)):
183             try:
184                 tx = sent[i]
185                 rx = capture[i]
186
187                 tx_ip = tx[IP]
188                 rx_ip = rx[IP]
189
190                 self.assertEqual(rx_ip.src, tunnel_src)
191                 self.assertEqual(rx_ip.dst, tunnel_dst)
192
193                 rx_gre = rx[GRE]
194                 rx_ip = rx_gre[IP]
195
196                 self.assertEqual(rx_ip.src, tx_ip.src)
197                 self.assertEqual(rx_ip.dst, tx_ip.dst)
198                 # IP processing post pop has decremented the TTL
199                 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
200
201             except:
202                 self.logger.error(ppp("Rx:", rx))
203                 self.logger.error(ppp("Tx:", tx))
204                 raise
205
206     def verify_tunneled_6o6(self, src_if, capture, sent,
207                             tunnel_src, tunnel_dst):
208
209         self.assertEqual(len(capture), len(sent))
210
211         for i in range(len(capture)):
212             try:
213                 tx = sent[i]
214                 rx = capture[i]
215
216                 tx_ip = tx[IPv6]
217                 rx_ip = rx[IPv6]
218
219                 self.assertEqual(rx_ip.src, tunnel_src)
220                 self.assertEqual(rx_ip.dst, tunnel_dst)
221
222                 rx_gre = GRE(str(rx_ip[IPv6].payload))
223                 rx_ip = rx_gre[IPv6]
224
225                 self.assertEqual(rx_ip.src, tx_ip.src)
226                 self.assertEqual(rx_ip.dst, tx_ip.dst)
227
228             except:
229                 self.logger.error(ppp("Rx:", rx))
230                 self.logger.error(ppp("Tx:", tx))
231                 raise
232
233     def verify_tunneled_4o6(self, src_if, capture, sent,
234                             tunnel_src, tunnel_dst):
235
236         self.assertEqual(len(capture), len(sent))
237
238         for i in range(len(capture)):
239             try:
240                 tx = sent[i]
241                 rx = capture[i]
242
243                 rx_ip = rx[IPv6]
244
245                 self.assertEqual(rx_ip.src, tunnel_src)
246                 self.assertEqual(rx_ip.dst, tunnel_dst)
247
248                 rx_gre = GRE(str(rx_ip[IPv6].payload))
249                 tx_ip = tx[IP]
250                 rx_ip = rx_gre[IP]
251
252                 self.assertEqual(rx_ip.src, tx_ip.src)
253                 self.assertEqual(rx_ip.dst, tx_ip.dst)
254
255             except:
256                 self.logger.error(ppp("Rx:", rx))
257                 self.logger.error(ppp("Tx:", tx))
258                 raise
259
260     def verify_tunneled_6o4(self, src_if, capture, sent,
261                             tunnel_src, tunnel_dst):
262
263         self.assertEqual(len(capture), len(sent))
264
265         for i in range(len(capture)):
266             try:
267                 tx = sent[i]
268                 rx = capture[i]
269
270                 rx_ip = rx[IP]
271
272                 self.assertEqual(rx_ip.src, tunnel_src)
273                 self.assertEqual(rx_ip.dst, tunnel_dst)
274
275                 rx_gre = GRE(str(rx_ip[IP].payload))
276                 rx_ip = rx_gre[IPv6]
277                 tx_ip = tx[IPv6]
278
279                 self.assertEqual(rx_ip.src, tx_ip.src)
280                 self.assertEqual(rx_ip.dst, tx_ip.dst)
281
282             except:
283                 self.logger.error(ppp("Rx:", rx))
284                 self.logger.error(ppp("Tx:", tx))
285                 raise
286
287     def verify_tunneled_l2o4(self, src_if, capture, sent,
288                              tunnel_src, tunnel_dst):
289         self.assertEqual(len(capture), len(sent))
290
291         for i in range(len(capture)):
292             try:
293                 tx = sent[i]
294                 rx = capture[i]
295
296                 tx_ip = tx[IP]
297                 rx_ip = rx[IP]
298
299                 self.assertEqual(rx_ip.src, tunnel_src)
300                 self.assertEqual(rx_ip.dst, tunnel_dst)
301
302                 rx_gre = rx[GRE]
303                 rx_l2 = rx_gre[Ether]
304                 rx_ip = rx_l2[IP]
305                 tx_gre = tx[GRE]
306                 tx_l2 = tx_gre[Ether]
307                 tx_ip = tx_l2[IP]
308
309                 self.assertEqual(rx_ip.src, tx_ip.src)
310                 self.assertEqual(rx_ip.dst, tx_ip.dst)
311                 # bridged, not L3 forwarded, so no TTL decrement
312                 self.assertEqual(rx_ip.ttl, tx_ip.ttl)
313
314             except:
315                 self.logger.error(ppp("Rx:", rx))
316                 self.logger.error(ppp("Tx:", tx))
317                 raise
318
319     def verify_tunneled_vlano4(self, src_if, capture, sent,
320                                tunnel_src, tunnel_dst, vlan):
321         try:
322             self.assertEqual(len(capture), len(sent))
323         except:
324             ppc("Unexpected packets captured:", capture)
325             raise
326
327         for i in range(len(capture)):
328             try:
329                 tx = sent[i]
330                 rx = capture[i]
331
332                 tx_ip = tx[IP]
333                 rx_ip = rx[IP]
334
335                 self.assertEqual(rx_ip.src, tunnel_src)
336                 self.assertEqual(rx_ip.dst, tunnel_dst)
337
338                 rx_gre = rx[GRE]
339                 rx_l2 = rx_gre[Ether]
340                 rx_vlan = rx_l2[Dot1Q]
341                 rx_ip = rx_l2[IP]
342
343                 self.assertEqual(rx_vlan.vlan, vlan)
344
345                 tx_gre = tx[GRE]
346                 tx_l2 = tx_gre[Ether]
347                 tx_ip = tx_l2[IP]
348
349                 self.assertEqual(rx_ip.src, tx_ip.src)
350                 self.assertEqual(rx_ip.dst, tx_ip.dst)
351                 # bridged, not L3 forwarded, so no TTL decrement
352                 self.assertEqual(rx_ip.ttl, tx_ip.ttl)
353
354             except:
355                 self.logger.error(ppp("Rx:", rx))
356                 self.logger.error(ppp("Tx:", tx))
357                 raise
358
359     def verify_decapped_4o4(self, src_if, capture, sent):
360         self.assertEqual(len(capture), len(sent))
361
362         for i in range(len(capture)):
363             try:
364                 tx = sent[i]
365                 rx = capture[i]
366
367                 tx_ip = tx[IP]
368                 rx_ip = rx[IP]
369                 tx_gre = tx[GRE]
370                 tx_ip = tx_gre[IP]
371
372                 self.assertEqual(rx_ip.src, tx_ip.src)
373                 self.assertEqual(rx_ip.dst, tx_ip.dst)
374                 # IP processing post pop has decremented the TTL
375                 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
376
377             except:
378                 self.logger.error(ppp("Rx:", rx))
379                 self.logger.error(ppp("Tx:", tx))
380                 raise
381
382     def verify_decapped_6o4(self, src_if, capture, sent):
383         self.assertEqual(len(capture), len(sent))
384
385         for i in range(len(capture)):
386             try:
387                 tx = sent[i]
388                 rx = capture[i]
389
390                 tx_ip = tx[IP]
391                 rx_ip = rx[IPv6]
392                 tx_gre = tx[GRE]
393                 tx_ip = tx_gre[IPv6]
394
395                 self.assertEqual(rx_ip.src, tx_ip.src)
396                 self.assertEqual(rx_ip.dst, tx_ip.dst)
397                 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
398
399             except:
400                 self.logger.error(ppp("Rx:", rx))
401                 self.logger.error(ppp("Tx:", tx))
402                 raise
403
404     def test_gre(self):
405         """ GRE IPv4 tunnel Tests """
406
407         #
408         # Create an L3 GRE tunnel.
409         #  - set it admin up
410         #  - assign an IP Addres
411         #  - Add a route via the tunnel
412         #
413         gre_if = VppGreInterface(self,
414                                  self.pg0.local_ip4,
415                                  "1.1.1.2")
416         gre_if.add_vpp_config()
417
418         #
419         # The double create (create the same tunnel twice) should fail,
420         # and we should still be able to use the original
421         #
422         try:
423             gre_if.add_vpp_config()
424         except Exception:
425             pass
426         else:
427             self.fail("Double GRE tunnel add does not fail")
428
429         gre_if.admin_up()
430         gre_if.config_ip4()
431
432         route_via_tun = VppIpRoute(self, "4.4.4.4", 32,
433                                    [VppRoutePath("0.0.0.0",
434                                                  gre_if.sw_if_index)])
435
436         route_via_tun.add_vpp_config()
437
438         #
439         # Send a packet stream that is routed into the tunnel
440         #  - they are all dropped since the tunnel's desintation IP
441         #    is unresolved - or resolves via the default route - which
442         #    which is a drop.
443         #
444         tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "4.4.4.4")
445
446         self.send_and_assert_no_replies(self.pg0, tx)
447
448         #
449         # Add a route that resolves the tunnel's destination
450         #
451         route_tun_dst = VppIpRoute(self, "1.1.1.2", 32,
452                                    [VppRoutePath(self.pg0.remote_ip4,
453                                                  self.pg0.sw_if_index)])
454         route_tun_dst.add_vpp_config()
455
456         #
457         # Send a packet stream that is routed into the tunnel
458         #  - packets are GRE encapped
459         #
460         tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "4.4.4.4")
461         rx = self.send_and_expect(self.pg0, tx, self.pg0)
462         self.verify_tunneled_4o4(self.pg0, rx, tx,
463                                  self.pg0.local_ip4, "1.1.1.2")
464
465         #
466         # Send tunneled packets that match the created tunnel and
467         # are decapped and forwarded
468         #
469         tx = self.create_tunnel_stream_4o4(self.pg0,
470                                            "1.1.1.2",
471                                            self.pg0.local_ip4,
472                                            self.pg0.local_ip4,
473                                            self.pg0.remote_ip4)
474         rx = self.send_and_expect(self.pg0, tx, self.pg0)
475         self.verify_decapped_4o4(self.pg0, rx, tx)
476
477         #
478         # Send tunneled packets that do not match the tunnel's src
479         #
480         self.vapi.cli("clear trace")
481         tx = self.create_tunnel_stream_4o4(self.pg0,
482                                            "1.1.1.3",
483                                            self.pg0.local_ip4,
484                                            self.pg0.local_ip4,
485                                            self.pg0.remote_ip4)
486         self.send_and_assert_no_replies(
487             self.pg0, tx,
488             remark="GRE packets forwarded despite no SRC address match")
489
490         #
491         # Configure IPv6 on the PG interface so we can route IPv6
492         # packets
493         #
494         self.pg0.config_ip6()
495         self.pg0.resolve_ndp()
496
497         #
498         # Send IPv6 tunnel encapslated packets
499         #  - dropped since IPv6 is not enabled on the tunnel
500         #
501         tx = self.create_tunnel_stream_6o4(self.pg0,
502                                            "1.1.1.2",
503                                            self.pg0.local_ip4,
504                                            self.pg0.local_ip6,
505                                            self.pg0.remote_ip6)
506         self.send_and_assert_no_replies(self.pg0, tx,
507                                         "IPv6 GRE packets forwarded "
508                                         "despite IPv6 not enabled on tunnel")
509
510         #
511         # Enable IPv6 on the tunnel
512         #
513         gre_if.config_ip6()
514
515         #
516         # Send IPv6 tunnel encapslated packets
517         #  - forwarded since IPv6 is enabled on the tunnel
518         #
519         tx = self.create_tunnel_stream_6o4(self.pg0,
520                                            "1.1.1.2",
521                                            self.pg0.local_ip4,
522                                            self.pg0.local_ip6,
523                                            self.pg0.remote_ip6)
524         rx = self.send_and_expect(self.pg0, tx, self.pg0)
525         self.verify_decapped_6o4(self.pg0, rx, tx)
526
527         #
528         # Send v6 packets for v4 encap
529         #
530         route6_via_tun = VppIpRoute(
531             self, "2001::1", 128,
532             [VppRoutePath("::",
533                           gre_if.sw_if_index,
534                           proto=DpoProto.DPO_PROTO_IP6)],
535             is_ip6=1)
536         route6_via_tun.add_vpp_config()
537
538         tx = self.create_stream_ip6(self.pg0, "2001::2", "2001::1")
539         rx = self.send_and_expect(self.pg0, tx, self.pg0)
540
541         self.verify_tunneled_6o4(self.pg0, rx, tx,
542                                  self.pg0.local_ip4, "1.1.1.2")
543
544         #
545         # test case cleanup
546         #
547         route_tun_dst.remove_vpp_config()
548         route_via_tun.remove_vpp_config()
549         route6_via_tun.remove_vpp_config()
550         gre_if.remove_vpp_config()
551
552         self.pg0.unconfig_ip6()
553
554     def test_gre6(self):
555         """ GRE IPv6 tunnel Tests """
556
557         self.pg1.config_ip6()
558         self.pg1.resolve_ndp()
559
560         #
561         # Create an L3 GRE tunnel.
562         #  - set it admin up
563         #  - assign an IP Address
564         #  - Add a route via the tunnel
565         #
566         gre_if = VppGre6Interface(self,
567                                   self.pg2.local_ip6,
568                                   "1002::1")
569         gre_if.add_vpp_config()
570         gre_if.admin_up()
571         gre_if.config_ip6()
572
573         route_via_tun = VppIpRoute(
574             self, "4004::1", 128,
575             [VppRoutePath("0::0",
576                           gre_if.sw_if_index,
577                           proto=DpoProto.DPO_PROTO_IP6)],
578             is_ip6=1)
579
580         route_via_tun.add_vpp_config()
581
582         #
583         # Send a packet stream that is routed into the tunnel
584         #  - they are all dropped since the tunnel's desintation IP
585         #    is unresolved - or resolves via the default route - which
586         #    which is a drop.
587         #
588         tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
589         self.send_and_assert_no_replies(
590             self.pg2, tx,
591             "GRE packets forwarded without DIP resolved")
592
593         #
594         # Add a route that resolves the tunnel's destination
595         #
596         route_tun_dst = VppIpRoute(
597             self, "1002::1", 128,
598             [VppRoutePath(self.pg2.remote_ip6,
599                           self.pg2.sw_if_index,
600                           proto=DpoProto.DPO_PROTO_IP6)],
601             is_ip6=1)
602         route_tun_dst.add_vpp_config()
603
604         #
605         # Send a packet stream that is routed into the tunnel
606         #  - packets are GRE encapped
607         #
608         tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
609         rx = self.send_and_expect(self.pg2, tx, self.pg2)
610         self.verify_tunneled_6o6(self.pg2, rx, tx,
611                                  self.pg2.local_ip6, "1002::1")
612
613         #
614         # Test decap. decapped packets go out pg1
615         #
616         tx = self.create_tunnel_stream_6o6(self.pg2,
617                                            "1002::1",
618                                            self.pg2.local_ip6,
619                                            "2001::1",
620                                            self.pg1.remote_ip6)
621         rx = self.send_and_expect(self.pg2, tx, self.pg1)
622
623         #
624         # RX'd packet is UDP over IPv6, test the GRE header is gone.
625         #
626         self.assertFalse(rx[0].haslayer(GRE))
627         self.assertEqual(rx[0][IPv6].dst, self.pg1.remote_ip6)
628
629         #
630         # Send v4 over v6
631         #
632         route4_via_tun = VppIpRoute(self, "1.1.1.1", 32,
633                                     [VppRoutePath("0.0.0.0",
634                                                   gre_if.sw_if_index)])
635         route4_via_tun.add_vpp_config()
636
637         tx = self.create_stream_ip4(self.pg0, "1.1.1.2", "1.1.1.1")
638         rx = self.send_and_expect(self.pg0, tx, self.pg2)
639
640         self.verify_tunneled_4o6(self.pg0, rx, tx,
641                                  self.pg2.local_ip6, "1002::1")
642
643         #
644         # test case cleanup
645         #
646         route_tun_dst.remove_vpp_config()
647         route_via_tun.remove_vpp_config()
648         route4_via_tun.remove_vpp_config()
649         gre_if.remove_vpp_config()
650
651         self.pg2.unconfig_ip6()
652         self.pg1.unconfig_ip6()
653
654     def test_gre_vrf(self):
655         """ GRE tunnel VRF Tests """
656
657         #
658         # Create an L3 GRE tunnel whose destination is in the non-default
659         # table. The underlay is thus non-default - the overlay is still
660         # the default.
661         #  - set it admin up
662         #  - assign an IP Addres
663         #
664         gre_if = VppGreInterface(self, self.pg1.local_ip4,
665                                  "2.2.2.2",
666                                  outer_fib_id=1)
667         gre_if.add_vpp_config()
668         gre_if.admin_up()
669         gre_if.config_ip4()
670
671         #
672         # Add a route via the tunnel - in the overlay
673         #
674         route_via_tun = VppIpRoute(self, "9.9.9.9", 32,
675                                    [VppRoutePath("0.0.0.0",
676                                                  gre_if.sw_if_index)])
677         route_via_tun.add_vpp_config()
678
679         #
680         # Add a route that resolves the tunnel's destination - in the
681         # underlay table
682         #
683         route_tun_dst = VppIpRoute(self, "2.2.2.2", 32, table_id=1,
684                                    paths=[VppRoutePath(self.pg1.remote_ip4,
685                                                        self.pg1.sw_if_index)])
686         route_tun_dst.add_vpp_config()
687
688         #
689         # Send a packet stream that is routed into the tunnel
690         # packets are sent in on pg0 which is in the default table
691         #  - packets are GRE encapped
692         #
693         self.vapi.cli("clear trace")
694         tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "9.9.9.9")
695         rx = self.send_and_expect(self.pg0, tx, self.pg1)
696         self.verify_tunneled_4o4(self.pg1, rx, tx,
697                                  self.pg1.local_ip4, "2.2.2.2")
698
699         #
700         # Send tunneled packets that match the created tunnel and
701         # are decapped and forwarded. This tests the decap lookup
702         # does not happen in the encap table
703         #
704         self.vapi.cli("clear trace")
705         tx = self.create_tunnel_stream_4o4(self.pg1,
706                                            "2.2.2.2",
707                                            self.pg1.local_ip4,
708                                            self.pg0.local_ip4,
709                                            self.pg0.remote_ip4)
710         rx = self.send_and_expect(self.pg1, tx, self.pg0)
711         self.verify_decapped_4o4(self.pg0, rx, tx)
712
713         #
714         # Send tunneled packets that match the created tunnel
715         # but arrive on an interface that is not in the tunnel's
716         # encap VRF, these are dropped.
717         # IP enable the interface so they aren't dropped due to
718         # IP not being enabled.
719         #
720         self.pg2.config_ip4()
721         self.vapi.cli("clear trace")
722         tx = self.create_tunnel_stream_4o4(self.pg2,
723                                            "2.2.2.2",
724                                            self.pg1.local_ip4,
725                                            self.pg0.local_ip4,
726                                            self.pg0.remote_ip4)
727         rx = self.send_and_assert_no_replies(
728             self.pg2, tx,
729             "GRE decap packets in wrong VRF")
730
731         self.pg2.unconfig_ip4()
732
733         #
734         # test case cleanup
735         #
736         route_tun_dst.remove_vpp_config()
737         route_via_tun.remove_vpp_config()
738         gre_if.remove_vpp_config()
739
740     def test_gre_l2(self):
741         """ GRE tunnel L2 Tests """
742
743         #
744         # Add routes to resolve the tunnel destinations
745         #
746         route_tun1_dst = VppIpRoute(self, "2.2.2.2", 32,
747                                     [VppRoutePath(self.pg0.remote_ip4,
748                                                   self.pg0.sw_if_index)])
749         route_tun2_dst = VppIpRoute(self, "2.2.2.3", 32,
750                                     [VppRoutePath(self.pg0.remote_ip4,
751                                                   self.pg0.sw_if_index)])
752
753         route_tun1_dst.add_vpp_config()
754         route_tun2_dst.add_vpp_config()
755
756         #
757         # Create 2 L2 GRE tunnels and x-connect them
758         #
759         gre_if1 = VppGreInterface(self, self.pg0.local_ip4,
760                                   "2.2.2.2",
761                                   type=GreTunnelTypes.TT_TEB)
762         gre_if2 = VppGreInterface(self, self.pg0.local_ip4,
763                                   "2.2.2.3",
764                                   type=GreTunnelTypes.TT_TEB)
765         gre_if1.add_vpp_config()
766         gre_if2.add_vpp_config()
767
768         gre_if1.admin_up()
769         gre_if2.admin_up()
770
771         self.vapi.sw_interface_set_l2_xconnect(gre_if1.sw_if_index,
772                                                gre_if2.sw_if_index,
773                                                enable=1)
774         self.vapi.sw_interface_set_l2_xconnect(gre_if2.sw_if_index,
775                                                gre_if1.sw_if_index,
776                                                enable=1)
777
778         #
779         # Send in tunnel encapped L2. expect out tunnel encapped L2
780         # in both directions
781         #
782         tx = self.create_tunnel_stream_l2o4(self.pg0,
783                                             "2.2.2.2",
784                                             self.pg0.local_ip4)
785         rx = self.send_and_expect(self.pg0, tx, self.pg0)
786         self.verify_tunneled_l2o4(self.pg0, rx, tx,
787                                   self.pg0.local_ip4,
788                                   "2.2.2.3")
789
790         tx = self.create_tunnel_stream_l2o4(self.pg0,
791                                             "2.2.2.3",
792                                             self.pg0.local_ip4)
793         rx = self.send_and_expect(self.pg0, tx, self.pg0)
794         self.verify_tunneled_l2o4(self.pg0, rx, tx,
795                                   self.pg0.local_ip4,
796                                   "2.2.2.2")
797
798         self.vapi.sw_interface_set_l2_xconnect(gre_if1.sw_if_index,
799                                                gre_if2.sw_if_index,
800                                                enable=0)
801         self.vapi.sw_interface_set_l2_xconnect(gre_if2.sw_if_index,
802                                                gre_if1.sw_if_index,
803                                                enable=0)
804
805         #
806         # Create a VLAN sub-interfaces on the GRE TEB interfaces
807         # then x-connect them
808         #
809         gre_if_11 = VppDot1QSubint(self, gre_if1, 11)
810         gre_if_12 = VppDot1QSubint(self, gre_if2, 12)
811
812         # gre_if_11.add_vpp_config()
813         # gre_if_12.add_vpp_config()
814
815         gre_if_11.admin_up()
816         gre_if_12.admin_up()
817
818         self.vapi.sw_interface_set_l2_xconnect(gre_if_11.sw_if_index,
819                                                gre_if_12.sw_if_index,
820                                                enable=1)
821         self.vapi.sw_interface_set_l2_xconnect(gre_if_12.sw_if_index,
822                                                gre_if_11.sw_if_index,
823                                                enable=1)
824
825         #
826         # Configure both to pop thier respective VLAN tags,
827         # so that during the x-coonect they will subsequently push
828         #
829         self.vapi.sw_interface_set_l2_tag_rewrite(gre_if_12.sw_if_index,
830                                                   L2_VTR_OP.L2_POP_1,
831                                                   12)
832         self.vapi.sw_interface_set_l2_tag_rewrite(gre_if_11.sw_if_index,
833                                                   L2_VTR_OP.L2_POP_1,
834                                                   11)
835
836         #
837         # Send traffic in both directiond - expect the VLAN tags to
838         # be swapped.
839         #
840         tx = self.create_tunnel_stream_vlano4(self.pg0,
841                                               "2.2.2.2",
842                                               self.pg0.local_ip4,
843                                               11)
844         rx = self.send_and_expect(self.pg0, tx, self.pg0)
845         self.verify_tunneled_vlano4(self.pg0, rx, tx,
846                                     self.pg0.local_ip4,
847                                     "2.2.2.3",
848                                     12)
849
850         tx = self.create_tunnel_stream_vlano4(self.pg0,
851                                               "2.2.2.3",
852                                               self.pg0.local_ip4,
853                                               12)
854         rx = self.send_and_expect(self.pg0, tx, self.pg0)
855         self.verify_tunneled_vlano4(self.pg0, rx, tx,
856                                     self.pg0.local_ip4,
857                                     "2.2.2.2",
858                                     11)
859
860         #
861         # Cleanup Test resources
862         #
863         gre_if_11.remove_vpp_config()
864         gre_if_12.remove_vpp_config()
865         gre_if1.remove_vpp_config()
866         gre_if2.remove_vpp_config()
867         route_tun1_dst.add_vpp_config()
868         route_tun2_dst.add_vpp_config()
869
870     def test_gre_loop(self):
871         """ GRE tunnel loop Tests """
872
873         #
874         # Create an L3 GRE tunnel.
875         #  - set it admin up
876         #  - assign an IP Addres
877         #
878         gre_if = VppGreInterface(self,
879                                  self.pg0.local_ip4,
880                                  "1.1.1.2")
881         gre_if.add_vpp_config()
882         gre_if.admin_up()
883         gre_if.config_ip4()
884
885         #
886         # add a route to the tunnel's destination that points
887         # through the tunnel, hence forming a loop in the forwarding
888         # graph
889         #
890         route_dst = VppIpRoute(self, "1.1.1.2", 32,
891                                [VppRoutePath("0.0.0.0",
892                                              gre_if.sw_if_index)])
893         route_dst.add_vpp_config()
894
895         #
896         # packets to the tunnels destination should be dropped
897         #
898         tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "1.1.1.2")
899         self.send_and_assert_no_replies(self.pg2, tx)
900
901         self.logger.info(self.vapi.ppcli("sh adj 7"))
902
903         #
904         # break the loop
905         #
906         route_dst.modify([VppRoutePath(self.pg1.remote_ip4,
907                                        self.pg1.sw_if_index)])
908         route_dst.add_vpp_config()
909
910         rx = self.send_and_expect(self.pg0, tx, self.pg1)
911
912         #
913         # a good route throught the tunnel to check it restacked
914         #
915         route_via_tun_2 = VppIpRoute(self, "2.2.2.2", 32,
916                                      [VppRoutePath("0.0.0.0",
917                                                    gre_if.sw_if_index)])
918         route_via_tun_2.add_vpp_config()
919
920         tx = self.create_stream_ip4(self.pg0, "2.2.2.3", "2.2.2.2")
921         rx = self.send_and_expect(self.pg0, tx, self.pg1)
922         self.verify_tunneled_4o4(self.pg1, rx, tx,
923                                  self.pg0.local_ip4, "1.1.1.2")
924
925         #
926         # cleanup
927         #
928         route_via_tun_2.remove_vpp_config()
929         gre_if.remove_vpp_config()
930
931
932 if __name__ == '__main__':
933     unittest.main(testRunner=VppTestRunner)