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