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