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