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