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