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