GRE over IPv6
[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
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(self, "4004::1", 128,
520                                    [VppRoutePath("0::0",
521                                                  gre_if.sw_if_index,
522                                                  is_ip6=1)],
523                                    is_ip6=1)
524
525         route_via_tun.add_vpp_config()
526
527         #
528         # Send a packet stream that is routed into the tunnel
529         #  - they are all dropped since the tunnel's desintation IP
530         #    is unresolved - or resolves via the default route - which
531         #    which is a drop.
532         #
533         tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
534         self.pg2.add_stream(tx)
535
536         self.pg_enable_capture(self.pg_interfaces)
537         self.pg_start()
538
539         self.pg2.assert_nothing_captured(
540             remark="GRE packets forwarded without DIP resolved")
541
542         #
543         # Add a route that resolves the tunnel's destination
544         #
545         route_tun_dst = VppIpRoute(self, "1002::1", 128,
546                                    [VppRoutePath(self.pg2.remote_ip6,
547                                                  self.pg2.sw_if_index,
548                                                  is_ip6=1)],
549                                    is_ip6=1)
550         route_tun_dst.add_vpp_config()
551
552         #
553         # Send a packet stream that is routed into the tunnel
554         #  - packets are GRE encapped
555         #
556         self.vapi.cli("clear trace")
557         tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
558         self.pg2.add_stream(tx)
559
560         self.pg_enable_capture(self.pg_interfaces)
561         self.pg_start()
562
563         rx = self.pg2.get_capture(len(tx))
564         self.verify_tunneled_6o6(self.pg2, rx, tx,
565                                  self.pg2.local_ip6, "1002::1")
566
567         #
568         # test case cleanup
569         #
570         route_tun_dst.remove_vpp_config()
571         route_via_tun.remove_vpp_config()
572         gre_if.remove_vpp_config()
573
574         self.pg2.unconfig_ip6()
575
576     def test_gre_vrf(self):
577         """ GRE tunnel VRF Tests """
578
579         #
580         # Create an L3 GRE tunnel whose destination is in the non-default
581         # table. The underlay is thus non-default - the overlay is still
582         # the default.
583         #  - set it admin up
584         #  - assign an IP Addres
585         #
586         gre_if = VppGreInterface(self, self.pg1.local_ip4,
587                                  "2.2.2.2",
588                                  outer_fib_id=1)
589         gre_if.add_vpp_config()
590         gre_if.admin_up()
591         gre_if.config_ip4()
592
593         #
594         # Add a route via the tunnel - in the overlay
595         #
596         route_via_tun = VppIpRoute(self, "9.9.9.9", 32,
597                                    [VppRoutePath("0.0.0.0",
598                                                  gre_if.sw_if_index)])
599         route_via_tun.add_vpp_config()
600
601         #
602         # Add a route that resolves the tunnel's destination - in the
603         # underlay table
604         #
605         route_tun_dst = VppIpRoute(self, "2.2.2.2", 32, table_id=1,
606                                    paths=[VppRoutePath(self.pg1.remote_ip4,
607                                                        self.pg1.sw_if_index)])
608         route_tun_dst.add_vpp_config()
609
610         #
611         # Send a packet stream that is routed into the tunnel
612         # packets are sent in on pg0 which is in the default table
613         #  - packets are GRE encapped
614         #
615         self.vapi.cli("clear trace")
616         tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "9.9.9.9")
617         self.pg0.add_stream(tx)
618
619         self.pg_enable_capture(self.pg_interfaces)
620         self.pg_start()
621
622         rx = self.pg1.get_capture(len(tx))
623         self.verify_tunneled_4o4(self.pg1, rx, tx,
624                                  self.pg1.local_ip4, "2.2.2.2")
625
626         #
627         # Send tunneled packets that match the created tunnel and
628         # are decapped and forwarded. This tests the decap lookup
629         # does not happen in the encap table
630         #
631         self.vapi.cli("clear trace")
632         tx = self.create_tunnel_stream_4o4(self.pg1,
633                                            "2.2.2.2",
634                                            self.pg1.local_ip4,
635                                            self.pg0.local_ip4,
636                                            self.pg0.remote_ip4)
637         self.pg1.add_stream(tx)
638
639         self.pg_enable_capture(self.pg_interfaces)
640         self.pg_start()
641
642         rx = self.pg0.get_capture(len(tx))
643         self.verify_decapped_4o4(self.pg0, rx, tx)
644
645         #
646         # test case cleanup
647         #
648         route_tun_dst.remove_vpp_config()
649         route_via_tun.remove_vpp_config()
650         gre_if.remove_vpp_config()
651
652     def test_gre_l2(self):
653         """ GRE tunnel L2 Tests """
654
655         #
656         # Add routes to resolve the tunnel destinations
657         #
658         route_tun1_dst = VppIpRoute(self, "2.2.2.2", 32,
659                                     [VppRoutePath(self.pg0.remote_ip4,
660                                                   self.pg0.sw_if_index)])
661         route_tun2_dst = VppIpRoute(self, "2.2.2.3", 32,
662                                     [VppRoutePath(self.pg0.remote_ip4,
663                                                   self.pg0.sw_if_index)])
664
665         route_tun1_dst.add_vpp_config()
666         route_tun2_dst.add_vpp_config()
667
668         #
669         # Create 2 L2 GRE tunnels and x-connect them
670         #
671         gre_if1 = VppGreInterface(self, self.pg0.local_ip4,
672                                   "2.2.2.2",
673                                   is_teb=1)
674         gre_if2 = VppGreInterface(self, self.pg0.local_ip4,
675                                   "2.2.2.3",
676                                   is_teb=1)
677         gre_if1.add_vpp_config()
678         gre_if2.add_vpp_config()
679
680         gre_if1.admin_up()
681         gre_if2.admin_up()
682
683         self.vapi.sw_interface_set_l2_xconnect(gre_if1.sw_if_index,
684                                                gre_if2.sw_if_index,
685                                                enable=1)
686         self.vapi.sw_interface_set_l2_xconnect(gre_if2.sw_if_index,
687                                                gre_if1.sw_if_index,
688                                                enable=1)
689
690         #
691         # Send in tunnel encapped L2. expect out tunnel encapped L2
692         # in both directions
693         #
694         self.vapi.cli("clear trace")
695         tx = self.create_tunnel_stream_l2o4(self.pg0,
696                                             "2.2.2.2",
697                                             self.pg0.local_ip4)
698         self.pg0.add_stream(tx)
699
700         self.pg_enable_capture(self.pg_interfaces)
701         self.pg_start()
702
703         rx = self.pg0.get_capture(len(tx))
704         self.verify_tunneled_l2o4(self.pg0, rx, tx,
705                                   self.pg0.local_ip4,
706                                   "2.2.2.3")
707
708         self.vapi.cli("clear trace")
709         tx = self.create_tunnel_stream_l2o4(self.pg0,
710                                             "2.2.2.3",
711                                             self.pg0.local_ip4)
712         self.pg0.add_stream(tx)
713
714         self.pg_enable_capture(self.pg_interfaces)
715         self.pg_start()
716
717         rx = self.pg0.get_capture(len(tx))
718         self.verify_tunneled_l2o4(self.pg0, rx, tx,
719                                   self.pg0.local_ip4,
720                                   "2.2.2.2")
721
722         self.vapi.sw_interface_set_l2_xconnect(gre_if1.sw_if_index,
723                                                gre_if2.sw_if_index,
724                                                enable=0)
725         self.vapi.sw_interface_set_l2_xconnect(gre_if2.sw_if_index,
726                                                gre_if1.sw_if_index,
727                                                enable=0)
728
729         #
730         # Create a VLAN sub-interfaces on the GRE TEB interfaces
731         # then x-connect them
732         #
733         gre_if_11 = VppDot1QSubint(self, gre_if1, 11)
734         gre_if_12 = VppDot1QSubint(self, gre_if2, 12)
735
736         # gre_if_11.add_vpp_config()
737         # gre_if_12.add_vpp_config()
738
739         gre_if_11.admin_up()
740         gre_if_12.admin_up()
741
742         self.vapi.sw_interface_set_l2_xconnect(gre_if_11.sw_if_index,
743                                                gre_if_12.sw_if_index,
744                                                enable=1)
745         self.vapi.sw_interface_set_l2_xconnect(gre_if_12.sw_if_index,
746                                                gre_if_11.sw_if_index,
747                                                enable=1)
748
749         #
750         # Configure both to pop thier respective VLAN tags,
751         # so that during the x-coonect they will subsequently push
752         #
753         self.vapi.sw_interface_set_l2_tag_rewrite(gre_if_12.sw_if_index,
754                                                   L2_VTR_OP.L2_POP_1,
755                                                   12)
756         self.vapi.sw_interface_set_l2_tag_rewrite(gre_if_11.sw_if_index,
757                                                   L2_VTR_OP.L2_POP_1,
758                                                   11)
759
760         #
761         # Send traffic in both directiond - expect the VLAN tags to
762         # be swapped.
763         #
764         self.vapi.cli("clear trace")
765         tx = self.create_tunnel_stream_vlano4(self.pg0,
766                                               "2.2.2.2",
767                                               self.pg0.local_ip4,
768                                               11)
769         self.pg0.add_stream(tx)
770
771         self.pg_enable_capture(self.pg_interfaces)
772         self.pg_start()
773
774         rx = self.pg0.get_capture(len(tx))
775         self.verify_tunneled_vlano4(self.pg0, rx, tx,
776                                     self.pg0.local_ip4,
777                                     "2.2.2.3",
778                                     12)
779
780         self.vapi.cli("clear trace")
781         tx = self.create_tunnel_stream_vlano4(self.pg0,
782                                               "2.2.2.3",
783                                               self.pg0.local_ip4,
784                                               12)
785         self.pg0.add_stream(tx)
786
787         self.pg_enable_capture(self.pg_interfaces)
788         self.pg_start()
789
790         rx = self.pg0.get_capture(len(tx))
791         self.verify_tunneled_vlano4(self.pg0, rx, tx,
792                                     self.pg0.local_ip4,
793                                     "2.2.2.2",
794                                     11)
795
796         #
797         # Cleanup Test resources
798         #
799         gre_if_11.remove_vpp_config()
800         gre_if_12.remove_vpp_config()
801         gre_if1.remove_vpp_config()
802         gre_if2.remove_vpp_config()
803         route_tun1_dst.add_vpp_config()
804         route_tun2_dst.add_vpp_config()
805
806
807 if __name__ == '__main__':
808     unittest.main(testRunner=VppTestRunner)