GRE: fix 4o6 and 6o4 adj stacking
[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         self.pg0.add_stream(tx)
446
447         self.pg_enable_capture(self.pg_interfaces)
448         self.pg_start()
449
450         self.pg0.assert_nothing_captured(
451             remark="GRE packets forwarded without DIP resolved")
452
453         #
454         # Add a route that resolves the tunnel's destination
455         #
456         route_tun_dst = VppIpRoute(self, "1.1.1.2", 32,
457                                    [VppRoutePath(self.pg0.remote_ip4,
458                                                  self.pg0.sw_if_index)])
459         route_tun_dst.add_vpp_config()
460
461         #
462         # Send a packet stream that is routed into the tunnel
463         #  - packets are GRE encapped
464         #
465         self.vapi.cli("clear trace")
466         tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "4.4.4.4")
467         self.pg0.add_stream(tx)
468
469         self.pg_enable_capture(self.pg_interfaces)
470         self.pg_start()
471
472         rx = self.pg0.get_capture(len(tx))
473         self.verify_tunneled_4o4(self.pg0, rx, tx,
474                                  self.pg0.local_ip4, "1.1.1.2")
475
476         #
477         # Send tunneled packets that match the created tunnel and
478         # are decapped and forwarded
479         #
480         self.vapi.cli("clear trace")
481         tx = self.create_tunnel_stream_4o4(self.pg0,
482                                            "1.1.1.2",
483                                            self.pg0.local_ip4,
484                                            self.pg0.local_ip4,
485                                            self.pg0.remote_ip4)
486         self.pg0.add_stream(tx)
487
488         self.pg_enable_capture(self.pg_interfaces)
489         self.pg_start()
490
491         rx = self.pg0.get_capture(len(tx))
492         self.verify_decapped_4o4(self.pg0, rx, tx)
493
494         #
495         # Send tunneled packets that do not match the tunnel's src
496         #
497         self.vapi.cli("clear trace")
498         tx = self.create_tunnel_stream_4o4(self.pg0,
499                                            "1.1.1.3",
500                                            self.pg0.local_ip4,
501                                            self.pg0.local_ip4,
502                                            self.pg0.remote_ip4)
503         self.pg0.add_stream(tx)
504
505         self.pg_enable_capture(self.pg_interfaces)
506         self.pg_start()
507
508         self.pg0.assert_nothing_captured(
509             remark="GRE packets forwarded despite no SRC address match")
510
511         #
512         # Configure IPv6 on the PG interface so we can route IPv6
513         # packets
514         #
515         self.pg0.config_ip6()
516         self.pg0.resolve_ndp()
517
518         #
519         # Send IPv6 tunnel encapslated packets
520         #  - dropped since IPv6 is not enabled on the tunnel
521         #
522         self.vapi.cli("clear trace")
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         self.pg0.add_stream(tx)
529
530         self.pg_enable_capture(self.pg_interfaces)
531         self.pg_start()
532
533         self.pg0.assert_nothing_captured(remark="IPv6 GRE packets forwarded "
534                                          "despite IPv6 not enabled on tunnel")
535
536         #
537         # Enable IPv6 on the tunnel
538         #
539         gre_if.config_ip6()
540
541         #
542         # Send IPv6 tunnel encapslated packets
543         #  - forwarded since IPv6 is enabled on the tunnel
544         #
545         self.vapi.cli("clear trace")
546         tx = self.create_tunnel_stream_6o4(self.pg0,
547                                            "1.1.1.2",
548                                            self.pg0.local_ip4,
549                                            self.pg0.local_ip6,
550                                            self.pg0.remote_ip6)
551         self.pg0.add_stream(tx)
552
553         self.pg_enable_capture(self.pg_interfaces)
554         self.pg_start()
555
556         rx = self.pg0.get_capture(len(tx))
557         self.verify_decapped_6o4(self.pg0, rx, tx)
558
559         #
560         # Send v6 packets for v4 encap
561         #
562         route6_via_tun = VppIpRoute(
563             self, "2001::1", 128,
564             [VppRoutePath("::",
565                           gre_if.sw_if_index,
566                           proto=DpoProto.DPO_PROTO_IP6)],
567             is_ip6=1)
568         route6_via_tun.add_vpp_config()
569
570         tx = self.create_stream_ip6(self.pg0, "2001::2", "2001::1")
571         rx = self.send_and_expect(self.pg0, tx, self.pg0)
572
573         self.verify_tunneled_6o4(self.pg0, rx, tx,
574                                  self.pg0.local_ip4, "1.1.1.2")
575
576         #
577         # test case cleanup
578         #
579         route_tun_dst.remove_vpp_config()
580         route_via_tun.remove_vpp_config()
581         route6_via_tun.remove_vpp_config()
582         gre_if.remove_vpp_config()
583
584         self.pg0.unconfig_ip6()
585
586     def test_gre6(self):
587         """ GRE IPv6 tunnel Tests """
588
589         self.pg1.config_ip6()
590         self.pg1.resolve_ndp()
591
592         #
593         # Create an L3 GRE tunnel.
594         #  - set it admin up
595         #  - assign an IP Address
596         #  - Add a route via the tunnel
597         #
598         gre_if = VppGre6Interface(self,
599                                   self.pg2.local_ip6,
600                                   "1002::1")
601         gre_if.add_vpp_config()
602         gre_if.admin_up()
603         gre_if.config_ip6()
604
605         route_via_tun = VppIpRoute(
606             self, "4004::1", 128,
607             [VppRoutePath("0::0",
608                           gre_if.sw_if_index,
609                           proto=DpoProto.DPO_PROTO_IP6)],
610             is_ip6=1)
611
612         route_via_tun.add_vpp_config()
613
614         #
615         # Send a packet stream that is routed into the tunnel
616         #  - they are all dropped since the tunnel's desintation IP
617         #    is unresolved - or resolves via the default route - which
618         #    which is a drop.
619         #
620         tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
621         self.pg2.add_stream(tx)
622
623         self.pg_enable_capture(self.pg_interfaces)
624         self.pg_start()
625
626         self.pg2.assert_nothing_captured(
627             remark="GRE packets forwarded without DIP resolved")
628
629         #
630         # Add a route that resolves the tunnel's destination
631         #
632         route_tun_dst = VppIpRoute(
633             self, "1002::1", 128,
634             [VppRoutePath(self.pg2.remote_ip6,
635                           self.pg2.sw_if_index,
636                           proto=DpoProto.DPO_PROTO_IP6)],
637             is_ip6=1)
638         route_tun_dst.add_vpp_config()
639
640         #
641         # Send a packet stream that is routed into the tunnel
642         #  - packets are GRE encapped
643         #
644         self.vapi.cli("clear trace")
645         tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
646         self.pg2.add_stream(tx)
647
648         self.pg_enable_capture(self.pg_interfaces)
649         self.pg_start()
650
651         rx = self.pg2.get_capture(len(tx))
652         self.verify_tunneled_6o6(self.pg2, rx, tx,
653                                  self.pg2.local_ip6, "1002::1")
654
655         #
656         # Test decap. decapped packets go out pg1
657         #
658         tx = self.create_tunnel_stream_6o6(self.pg2,
659                                            "1002::1",
660                                            self.pg2.local_ip6,
661                                            "2001::1",
662                                            self.pg1.remote_ip6)
663         self.vapi.cli("clear trace")
664         self.pg2.add_stream(tx)
665
666         self.pg_enable_capture(self.pg_interfaces)
667         self.pg_start()
668         rx = self.pg1.get_capture(len(tx))
669
670         #
671         # RX'd packet is UDP over IPv6, test the GRE header is gone.
672         #
673         self.assertFalse(rx[0].haslayer(GRE))
674         self.assertEqual(rx[0][IPv6].dst, self.pg1.remote_ip6)
675
676         #
677         # Send v4 over v6
678         #
679         route4_via_tun = VppIpRoute(self, "1.1.1.1", 32,
680                                     [VppRoutePath("0.0.0.0",
681                                                   gre_if.sw_if_index)])
682         route4_via_tun.add_vpp_config()
683
684         tx = self.create_stream_ip4(self.pg0, "1.1.1.2", "1.1.1.1")
685         rx = self.send_and_expect(self.pg0, tx, self.pg2)
686
687         self.verify_tunneled_4o6(self.pg0, rx, tx,
688                                  self.pg2.local_ip6, "1002::1")
689
690         #
691         # test case cleanup
692         #
693         route_tun_dst.remove_vpp_config()
694         route_via_tun.remove_vpp_config()
695         route4_via_tun.remove_vpp_config()
696         gre_if.remove_vpp_config()
697
698         self.pg2.unconfig_ip6()
699         self.pg1.unconfig_ip6()
700
701     def test_gre_vrf(self):
702         """ GRE tunnel VRF Tests """
703
704         #
705         # Create an L3 GRE tunnel whose destination is in the non-default
706         # table. The underlay is thus non-default - the overlay is still
707         # the default.
708         #  - set it admin up
709         #  - assign an IP Addres
710         #
711         gre_if = VppGreInterface(self, self.pg1.local_ip4,
712                                  "2.2.2.2",
713                                  outer_fib_id=1)
714         gre_if.add_vpp_config()
715         gre_if.admin_up()
716         gre_if.config_ip4()
717
718         #
719         # Add a route via the tunnel - in the overlay
720         #
721         route_via_tun = VppIpRoute(self, "9.9.9.9", 32,
722                                    [VppRoutePath("0.0.0.0",
723                                                  gre_if.sw_if_index)])
724         route_via_tun.add_vpp_config()
725
726         #
727         # Add a route that resolves the tunnel's destination - in the
728         # underlay table
729         #
730         route_tun_dst = VppIpRoute(self, "2.2.2.2", 32, table_id=1,
731                                    paths=[VppRoutePath(self.pg1.remote_ip4,
732                                                        self.pg1.sw_if_index)])
733         route_tun_dst.add_vpp_config()
734
735         #
736         # Send a packet stream that is routed into the tunnel
737         # packets are sent in on pg0 which is in the default table
738         #  - packets are GRE encapped
739         #
740         self.vapi.cli("clear trace")
741         tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "9.9.9.9")
742         self.pg0.add_stream(tx)
743
744         self.pg_enable_capture(self.pg_interfaces)
745         self.pg_start()
746
747         rx = self.pg1.get_capture(len(tx))
748         self.verify_tunneled_4o4(self.pg1, rx, tx,
749                                  self.pg1.local_ip4, "2.2.2.2")
750
751         #
752         # Send tunneled packets that match the created tunnel and
753         # are decapped and forwarded. This tests the decap lookup
754         # does not happen in the encap table
755         #
756         self.vapi.cli("clear trace")
757         tx = self.create_tunnel_stream_4o4(self.pg1,
758                                            "2.2.2.2",
759                                            self.pg1.local_ip4,
760                                            self.pg0.local_ip4,
761                                            self.pg0.remote_ip4)
762         self.pg1.add_stream(tx)
763
764         self.pg_enable_capture(self.pg_interfaces)
765         self.pg_start()
766
767         rx = self.pg0.get_capture(len(tx))
768         self.verify_decapped_4o4(self.pg0, rx, tx)
769
770         #
771         # Send tunneled packets that match the created tunnel and
772         # but arrive on an interface that is not in the tunnel's
773         # encap VRF, these are dropped
774         #
775         self.vapi.cli("clear trace")
776         tx = self.create_tunnel_stream_4o4(self.pg2,
777                                            "2.2.2.2",
778                                            self.pg1.local_ip4,
779                                            self.pg0.local_ip4,
780                                            self.pg0.remote_ip4)
781         self.pg1.add_stream(tx)
782
783         self.pg_enable_capture(self.pg_interfaces)
784         self.pg_start()
785
786         self.pg0.assert_nothing_captured(
787             remark="GRE decap packets in wrong VRF")
788
789         #
790         # test case cleanup
791         #
792         route_tun_dst.remove_vpp_config()
793         route_via_tun.remove_vpp_config()
794         gre_if.remove_vpp_config()
795
796     def test_gre_l2(self):
797         """ GRE tunnel L2 Tests """
798
799         #
800         # Add routes to resolve the tunnel destinations
801         #
802         route_tun1_dst = VppIpRoute(self, "2.2.2.2", 32,
803                                     [VppRoutePath(self.pg0.remote_ip4,
804                                                   self.pg0.sw_if_index)])
805         route_tun2_dst = VppIpRoute(self, "2.2.2.3", 32,
806                                     [VppRoutePath(self.pg0.remote_ip4,
807                                                   self.pg0.sw_if_index)])
808
809         route_tun1_dst.add_vpp_config()
810         route_tun2_dst.add_vpp_config()
811
812         #
813         # Create 2 L2 GRE tunnels and x-connect them
814         #
815         gre_if1 = VppGreInterface(self, self.pg0.local_ip4,
816                                   "2.2.2.2",
817                                   type=GreTunnelTypes.TT_TEB)
818         gre_if2 = VppGreInterface(self, self.pg0.local_ip4,
819                                   "2.2.2.3",
820                                   type=GreTunnelTypes.TT_TEB)
821         gre_if1.add_vpp_config()
822         gre_if2.add_vpp_config()
823
824         gre_if1.admin_up()
825         gre_if2.admin_up()
826
827         self.vapi.sw_interface_set_l2_xconnect(gre_if1.sw_if_index,
828                                                gre_if2.sw_if_index,
829                                                enable=1)
830         self.vapi.sw_interface_set_l2_xconnect(gre_if2.sw_if_index,
831                                                gre_if1.sw_if_index,
832                                                enable=1)
833
834         #
835         # Send in tunnel encapped L2. expect out tunnel encapped L2
836         # in both directions
837         #
838         self.vapi.cli("clear trace")
839         tx = self.create_tunnel_stream_l2o4(self.pg0,
840                                             "2.2.2.2",
841                                             self.pg0.local_ip4)
842         self.pg0.add_stream(tx)
843
844         self.pg_enable_capture(self.pg_interfaces)
845         self.pg_start()
846
847         rx = self.pg0.get_capture(len(tx))
848         self.verify_tunneled_l2o4(self.pg0, rx, tx,
849                                   self.pg0.local_ip4,
850                                   "2.2.2.3")
851
852         self.vapi.cli("clear trace")
853         tx = self.create_tunnel_stream_l2o4(self.pg0,
854                                             "2.2.2.3",
855                                             self.pg0.local_ip4)
856         self.pg0.add_stream(tx)
857
858         self.pg_enable_capture(self.pg_interfaces)
859         self.pg_start()
860
861         rx = self.pg0.get_capture(len(tx))
862         self.verify_tunneled_l2o4(self.pg0, rx, tx,
863                                   self.pg0.local_ip4,
864                                   "2.2.2.2")
865
866         self.vapi.sw_interface_set_l2_xconnect(gre_if1.sw_if_index,
867                                                gre_if2.sw_if_index,
868                                                enable=0)
869         self.vapi.sw_interface_set_l2_xconnect(gre_if2.sw_if_index,
870                                                gre_if1.sw_if_index,
871                                                enable=0)
872
873         #
874         # Create a VLAN sub-interfaces on the GRE TEB interfaces
875         # then x-connect them
876         #
877         gre_if_11 = VppDot1QSubint(self, gre_if1, 11)
878         gre_if_12 = VppDot1QSubint(self, gre_if2, 12)
879
880         # gre_if_11.add_vpp_config()
881         # gre_if_12.add_vpp_config()
882
883         gre_if_11.admin_up()
884         gre_if_12.admin_up()
885
886         self.vapi.sw_interface_set_l2_xconnect(gre_if_11.sw_if_index,
887                                                gre_if_12.sw_if_index,
888                                                enable=1)
889         self.vapi.sw_interface_set_l2_xconnect(gre_if_12.sw_if_index,
890                                                gre_if_11.sw_if_index,
891                                                enable=1)
892
893         #
894         # Configure both to pop thier respective VLAN tags,
895         # so that during the x-coonect they will subsequently push
896         #
897         self.vapi.sw_interface_set_l2_tag_rewrite(gre_if_12.sw_if_index,
898                                                   L2_VTR_OP.L2_POP_1,
899                                                   12)
900         self.vapi.sw_interface_set_l2_tag_rewrite(gre_if_11.sw_if_index,
901                                                   L2_VTR_OP.L2_POP_1,
902                                                   11)
903
904         #
905         # Send traffic in both directiond - expect the VLAN tags to
906         # be swapped.
907         #
908         self.vapi.cli("clear trace")
909         tx = self.create_tunnel_stream_vlano4(self.pg0,
910                                               "2.2.2.2",
911                                               self.pg0.local_ip4,
912                                               11)
913         self.pg0.add_stream(tx)
914
915         self.pg_enable_capture(self.pg_interfaces)
916         self.pg_start()
917
918         rx = self.pg0.get_capture(len(tx))
919         self.verify_tunneled_vlano4(self.pg0, rx, tx,
920                                     self.pg0.local_ip4,
921                                     "2.2.2.3",
922                                     12)
923
924         self.vapi.cli("clear trace")
925         tx = self.create_tunnel_stream_vlano4(self.pg0,
926                                               "2.2.2.3",
927                                               self.pg0.local_ip4,
928                                               12)
929         self.pg0.add_stream(tx)
930
931         self.pg_enable_capture(self.pg_interfaces)
932         self.pg_start()
933
934         rx = self.pg0.get_capture(len(tx))
935         self.verify_tunneled_vlano4(self.pg0, rx, tx,
936                                     self.pg0.local_ip4,
937                                     "2.2.2.2",
938                                     11)
939
940         #
941         # Cleanup Test resources
942         #
943         gre_if_11.remove_vpp_config()
944         gre_if_12.remove_vpp_config()
945         gre_if1.remove_vpp_config()
946         gre_if2.remove_vpp_config()
947         route_tun1_dst.add_vpp_config()
948         route_tun2_dst.add_vpp_config()
949
950
951 if __name__ == '__main__':
952     unittest.main(testRunner=VppTestRunner)