gre: don't register gre input nodes unless a gre tunnel is created
[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
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             is_ip6=1)
581         route6_via_tun.add_vpp_config()
582
583         tx = self.create_stream_ip6(self.pg0, "2001::2", "2001::1")
584         rx = self.send_and_expect(self.pg0, tx, self.pg0)
585
586         self.verify_tunneled_6o4(self.pg0, rx, tx,
587                                  self.pg0.local_ip4, "1.1.1.2")
588
589         #
590         # test case cleanup
591         #
592         route_tun_dst.remove_vpp_config()
593         route_via_tun.remove_vpp_config()
594         route6_via_tun.remove_vpp_config()
595         gre_if.remove_vpp_config()
596
597         self.pg0.unconfig_ip6()
598
599     def test_gre6(self):
600         """ GRE IPv6 tunnel Tests """
601
602         self.pg1.config_ip6()
603         self.pg1.resolve_ndp()
604
605         #
606         # Create an L3 GRE tunnel.
607         #  - set it admin up
608         #  - assign an IP Address
609         #  - Add a route via the tunnel
610         #
611         gre_if = VppGreInterface(self,
612                                  self.pg2.local_ip6,
613                                  "1002::1")
614         gre_if.add_vpp_config()
615         gre_if.admin_up()
616         gre_if.config_ip6()
617
618         route_via_tun = VppIpRoute(
619             self, "4004::1", 128,
620             [VppRoutePath("0::0",
621                           gre_if.sw_if_index,
622                           proto=DpoProto.DPO_PROTO_IP6)],
623             is_ip6=1)
624
625         route_via_tun.add_vpp_config()
626
627         #
628         # Send a packet stream that is routed into the tunnel
629         #  - they are all dropped since the tunnel's destintation IP
630         #    is unresolved - or resolves via the default route - which
631         #    which is a drop.
632         #
633         tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
634         self.send_and_assert_no_replies(
635             self.pg2, tx,
636             "GRE packets forwarded without DIP resolved")
637
638         #
639         # Add a route that resolves the tunnel's destination
640         #
641         route_tun_dst = VppIpRoute(
642             self, "1002::1", 128,
643             [VppRoutePath(self.pg2.remote_ip6,
644                           self.pg2.sw_if_index,
645                           proto=DpoProto.DPO_PROTO_IP6)],
646             is_ip6=1)
647         route_tun_dst.add_vpp_config()
648
649         #
650         # Send a packet stream that is routed into the tunnel
651         #  - packets are GRE encapped
652         #
653         tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
654         rx = self.send_and_expect(self.pg2, tx, self.pg2)
655         self.verify_tunneled_6o6(self.pg2, rx, tx,
656                                  self.pg2.local_ip6, "1002::1")
657
658         #
659         # Test decap. decapped packets go out pg1
660         #
661         tx = self.create_tunnel_stream_6o6(self.pg2,
662                                            "1002::1",
663                                            self.pg2.local_ip6,
664                                            "2001::1",
665                                            self.pg1.remote_ip6)
666         rx = self.send_and_expect(self.pg2, tx, self.pg1)
667
668         #
669         # RX'd packet is UDP over IPv6, test the GRE header is gone.
670         #
671         self.assertFalse(rx[0].haslayer(GRE))
672         self.assertEqual(rx[0][IPv6].dst, self.pg1.remote_ip6)
673
674         #
675         # Send v4 over v6
676         #
677         route4_via_tun = VppIpRoute(self, "1.1.1.1", 32,
678                                     [VppRoutePath("0.0.0.0",
679                                                   gre_if.sw_if_index)])
680         route4_via_tun.add_vpp_config()
681
682         tx = self.create_stream_ip4(self.pg0, "1.1.1.2", "1.1.1.1")
683         rx = self.send_and_expect(self.pg0, tx, self.pg2)
684
685         self.verify_tunneled_4o6(self.pg0, rx, tx,
686                                  self.pg2.local_ip6, "1002::1")
687
688         #
689         # test case cleanup
690         #
691         route_tun_dst.remove_vpp_config()
692         route_via_tun.remove_vpp_config()
693         route4_via_tun.remove_vpp_config()
694         gre_if.remove_vpp_config()
695
696         self.pg2.unconfig_ip6()
697         self.pg1.unconfig_ip6()
698
699     def test_gre_vrf(self):
700         """ GRE tunnel VRF Tests """
701
702         #
703         # Create an L3 GRE tunnel whose destination is in the non-default
704         # table. The underlay is thus non-default - the overlay is still
705         # the default.
706         #  - set it admin up
707         #  - assign an IP Addres
708         #
709         gre_if = VppGreInterface(self, self.pg1.local_ip4,
710                                  "2.2.2.2",
711                                  outer_fib_id=1)
712         gre_if.add_vpp_config()
713         gre_if.admin_up()
714         gre_if.config_ip4()
715
716         #
717         # Add a route via the tunnel - in the overlay
718         #
719         route_via_tun = VppIpRoute(self, "9.9.9.9", 32,
720                                    [VppRoutePath("0.0.0.0",
721                                                  gre_if.sw_if_index)])
722         route_via_tun.add_vpp_config()
723
724         #
725         # Add a route that resolves the tunnel's destination - in the
726         # underlay table
727         #
728         route_tun_dst = VppIpRoute(self, "2.2.2.2", 32, table_id=1,
729                                    paths=[VppRoutePath(self.pg1.remote_ip4,
730                                                        self.pg1.sw_if_index)])
731         route_tun_dst.add_vpp_config()
732
733         #
734         # Send a packet stream that is routed into the tunnel
735         # packets are sent in on pg0 which is in the default table
736         #  - packets are GRE encapped
737         #
738         self.vapi.cli("clear trace")
739         tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "9.9.9.9")
740         rx = self.send_and_expect(self.pg0, tx, self.pg1)
741         self.verify_tunneled_4o4(self.pg1, rx, tx,
742                                  self.pg1.local_ip4, "2.2.2.2")
743
744         #
745         # Send tunneled packets that match the created tunnel and
746         # are decapped and forwarded. This tests the decap lookup
747         # does not happen in the encap table
748         #
749         self.vapi.cli("clear trace")
750         tx = self.create_tunnel_stream_4o4(self.pg1,
751                                            "2.2.2.2",
752                                            self.pg1.local_ip4,
753                                            self.pg0.local_ip4,
754                                            self.pg0.remote_ip4)
755         rx = self.send_and_expect(self.pg1, tx, self.pg0)
756         self.verify_decapped_4o4(self.pg0, rx, tx)
757
758         #
759         # Send tunneled packets that match the created tunnel
760         # but arrive on an interface that is not in the tunnel's
761         # encap VRF, these are dropped.
762         # IP enable the interface so they aren't dropped due to
763         # IP not being enabled.
764         #
765         self.pg2.config_ip4()
766         self.vapi.cli("clear trace")
767         tx = self.create_tunnel_stream_4o4(self.pg2,
768                                            "2.2.2.2",
769                                            self.pg1.local_ip4,
770                                            self.pg0.local_ip4,
771                                            self.pg0.remote_ip4)
772         rx = self.send_and_assert_no_replies(
773             self.pg2, tx,
774             "GRE decap packets in wrong VRF")
775
776         self.pg2.unconfig_ip4()
777
778         #
779         # test case cleanup
780         #
781         route_tun_dst.remove_vpp_config()
782         route_via_tun.remove_vpp_config()
783         gre_if.remove_vpp_config()
784
785     def test_gre_l2(self):
786         """ GRE tunnel L2 Tests """
787
788         #
789         # Add routes to resolve the tunnel destinations
790         #
791         route_tun1_dst = VppIpRoute(self, "2.2.2.2", 32,
792                                     [VppRoutePath(self.pg0.remote_ip4,
793                                                   self.pg0.sw_if_index)])
794         route_tun2_dst = VppIpRoute(self, "2.2.2.3", 32,
795                                     [VppRoutePath(self.pg0.remote_ip4,
796                                                   self.pg0.sw_if_index)])
797
798         route_tun1_dst.add_vpp_config()
799         route_tun2_dst.add_vpp_config()
800
801         #
802         # Create 2 L2 GRE tunnels and x-connect them
803         #
804         gre_if1 = VppGreInterface(self, self.pg0.local_ip4,
805                                   "2.2.2.2",
806                                   type=(VppEnum.vl_api_gre_tunnel_type_t.
807                                         GRE_API_TUNNEL_TYPE_TEB))
808         gre_if2 = VppGreInterface(self, self.pg0.local_ip4,
809                                   "2.2.2.3",
810                                   type=(VppEnum.vl_api_gre_tunnel_type_t.
811                                         GRE_API_TUNNEL_TYPE_TEB))
812         gre_if1.add_vpp_config()
813         gre_if2.add_vpp_config()
814
815         gre_if1.admin_up()
816         gre_if2.admin_up()
817
818         self.vapi.sw_interface_set_l2_xconnect(gre_if1.sw_if_index,
819                                                gre_if2.sw_if_index,
820                                                enable=1)
821         self.vapi.sw_interface_set_l2_xconnect(gre_if2.sw_if_index,
822                                                gre_if1.sw_if_index,
823                                                enable=1)
824
825         #
826         # Send in tunnel encapped L2. expect out tunnel encapped L2
827         # in both directions
828         #
829         tx = self.create_tunnel_stream_l2o4(self.pg0,
830                                             "2.2.2.2",
831                                             self.pg0.local_ip4)
832         rx = self.send_and_expect(self.pg0, tx, self.pg0)
833         self.verify_tunneled_l2o4(self.pg0, rx, tx,
834                                   self.pg0.local_ip4,
835                                   "2.2.2.3")
836
837         tx = self.create_tunnel_stream_l2o4(self.pg0,
838                                             "2.2.2.3",
839                                             self.pg0.local_ip4)
840         rx = self.send_and_expect(self.pg0, tx, self.pg0)
841         self.verify_tunneled_l2o4(self.pg0, rx, tx,
842                                   self.pg0.local_ip4,
843                                   "2.2.2.2")
844
845         self.vapi.sw_interface_set_l2_xconnect(gre_if1.sw_if_index,
846                                                gre_if2.sw_if_index,
847                                                enable=0)
848         self.vapi.sw_interface_set_l2_xconnect(gre_if2.sw_if_index,
849                                                gre_if1.sw_if_index,
850                                                enable=0)
851
852         #
853         # Create a VLAN sub-interfaces on the GRE TEB interfaces
854         # then x-connect them
855         #
856         gre_if_11 = VppDot1QSubint(self, gre_if1, 11)
857         gre_if_12 = VppDot1QSubint(self, gre_if2, 12)
858
859         # gre_if_11.add_vpp_config()
860         # gre_if_12.add_vpp_config()
861
862         gre_if_11.admin_up()
863         gre_if_12.admin_up()
864
865         self.vapi.sw_interface_set_l2_xconnect(gre_if_11.sw_if_index,
866                                                gre_if_12.sw_if_index,
867                                                enable=1)
868         self.vapi.sw_interface_set_l2_xconnect(gre_if_12.sw_if_index,
869                                                gre_if_11.sw_if_index,
870                                                enable=1)
871
872         #
873         # Configure both to pop thier respective VLAN tags,
874         # so that during the x-coonect they will subsequently push
875         #
876         self.vapi.l2_interface_vlan_tag_rewrite(
877             sw_if_index=gre_if_12.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
878             push_dot1q=12)
879         self.vapi.l2_interface_vlan_tag_rewrite(
880             sw_if_index=gre_if_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
881             push_dot1q=11)
882
883         #
884         # Send traffic in both directiond - expect the VLAN tags to
885         # be swapped.
886         #
887         tx = self.create_tunnel_stream_vlano4(self.pg0,
888                                               "2.2.2.2",
889                                               self.pg0.local_ip4,
890                                               11)
891         rx = self.send_and_expect(self.pg0, tx, self.pg0)
892         self.verify_tunneled_vlano4(self.pg0, rx, tx,
893                                     self.pg0.local_ip4,
894                                     "2.2.2.3",
895                                     12)
896
897         tx = self.create_tunnel_stream_vlano4(self.pg0,
898                                               "2.2.2.3",
899                                               self.pg0.local_ip4,
900                                               12)
901         rx = self.send_and_expect(self.pg0, tx, self.pg0)
902         self.verify_tunneled_vlano4(self.pg0, rx, tx,
903                                     self.pg0.local_ip4,
904                                     "2.2.2.2",
905                                     11)
906
907         #
908         # Cleanup Test resources
909         #
910         gre_if_11.remove_vpp_config()
911         gre_if_12.remove_vpp_config()
912         gre_if1.remove_vpp_config()
913         gre_if2.remove_vpp_config()
914         route_tun1_dst.add_vpp_config()
915         route_tun2_dst.add_vpp_config()
916
917     def test_gre_loop(self):
918         """ GRE tunnel loop Tests """
919
920         #
921         # Create an L3 GRE tunnel.
922         #  - set it admin up
923         #  - assign an IP Addres
924         #
925         gre_if = VppGreInterface(self,
926                                  self.pg0.local_ip4,
927                                  "1.1.1.2")
928         gre_if.add_vpp_config()
929         gre_if.admin_up()
930         gre_if.config_ip4()
931
932         #
933         # add a route to the tunnel's destination that points
934         # through the tunnel, hence forming a loop in the forwarding
935         # graph
936         #
937         route_dst = VppIpRoute(self, "1.1.1.2", 32,
938                                [VppRoutePath("0.0.0.0",
939                                              gre_if.sw_if_index)])
940         route_dst.add_vpp_config()
941
942         #
943         # packets to the tunnels destination should be dropped
944         #
945         tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "1.1.1.2")
946         self.send_and_assert_no_replies(self.pg2, tx)
947
948         self.logger.info(self.vapi.ppcli("sh adj 7"))
949
950         #
951         # break the loop
952         #
953         route_dst.modify([VppRoutePath(self.pg1.remote_ip4,
954                                        self.pg1.sw_if_index)])
955         route_dst.add_vpp_config()
956
957         rx = self.send_and_expect(self.pg0, tx, self.pg1)
958
959         #
960         # a good route throught the tunnel to check it restacked
961         #
962         route_via_tun_2 = VppIpRoute(self, "2.2.2.2", 32,
963                                      [VppRoutePath("0.0.0.0",
964                                                    gre_if.sw_if_index)])
965         route_via_tun_2.add_vpp_config()
966
967         tx = self.create_stream_ip4(self.pg0, "2.2.2.3", "2.2.2.2")
968         rx = self.send_and_expect(self.pg0, tx, self.pg1)
969         self.verify_tunneled_4o4(self.pg1, rx, tx,
970                                  self.pg0.local_ip4, "1.1.1.2")
971
972         #
973         # cleanup
974         #
975         route_via_tun_2.remove_vpp_config()
976         gre_if.remove_vpp_config()
977
978
979 if __name__ == '__main__':
980     unittest.main(testRunner=VppTestRunner)