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