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