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