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