blob: 284e13591162b7a2c50ac774dcf099c0613fea79 [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Damjan Marionf56b77a2016-10-03 19:44:57 +02002
Eyal Baric4aaee12016-12-20 18:36:46 +02003import socket
Paul Vinciguerra2f156312020-05-02 22:34:40 -04004from util import ip4_range, reassemble4
Damjan Marionf56b77a2016-10-03 19:44:57 +02005import unittest
Dave Wallace8800f732023-08-31 00:47:44 -04006from framework import VppTestCase
7from asfframework import VppTestRunner
Damjan Marionf56b77a2016-10-03 19:44:57 +02008from template_bd import BridgeDomain
9
snaramre5d4b8912019-12-13 23:39:35 +000010from scapy.layers.l2 import Ether
Artem Glazychev23e5f092022-02-21 17:51:29 +070011from scapy.layers.l2 import ARP
Artem Glazychev839dcc02020-12-01 02:39:21 +070012from scapy.packet import Raw, bind_layers
Damjan Marionf56b77a2016-10-03 19:44:57 +020013from scapy.layers.inet import IP, UDP
Vladislav Grishenkof2fc97a2024-01-24 20:33:12 +050014from scapy.layers.inet6 import IPv6
Matej Klottondeb69842016-12-09 15:05:46 +010015from scapy.layers.vxlan import VXLAN
Vladislav Grishenkof2fc97a2024-01-24 20:33:12 +050016from scapy.contrib.mpls import MPLS
Paul Vinciguerra2f156312020-05-02 22:34:40 -040017
18import util
Neale Ranns097fa662018-05-01 05:17:55 -070019from vpp_ip_route import VppIpRoute, VppRoutePath
Jakub Grajciar7c0eb562020-03-02 13:55:31 +010020from vpp_vxlan_tunnel import VppVxlanTunnel
Neale Ranns097fa662018-05-01 05:17:55 -070021from vpp_ip import INVALID_INDEX
Artem Glazychev23e5f092022-02-21 17:51:29 +070022from vpp_neighbor import VppNeighbor
Damjan Marionf56b77a2016-10-03 19:44:57 +020023
24
Klement Sekeraf62ae122016-10-11 11:47:09 +020025class TestVxlan(BridgeDomain, VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020026 """VXLAN Test Case"""
Damjan Marionf56b77a2016-10-03 19:44:57 +020027
Damjan Marionf56b77a2016-10-03 19:44:57 +020028 def __init__(self, *args):
29 BridgeDomain.__init__(self)
Damjan Marionf56b77a2016-10-03 19:44:57 +020030 VppTestCase.__init__(self, *args)
31
Eyal Baric4aaee12016-12-20 18:36:46 +020032 def encapsulate(self, pkt, vni):
Klement Sekeraf62ae122016-10-11 11:47:09 +020033 """
34 Encapsulate the original payload frame by adding VXLAN header with its
35 UDP, IP and Ethernet fields
36 """
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020037 return (
38 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
39 / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
40 / UDP(sport=self.dport, dport=self.dport, chksum=0)
41 / VXLAN(vni=vni, flags=self.flags)
42 / pkt
43 )
Eyal Baric4aaee12016-12-20 18:36:46 +020044
Eyal Baricef1e2a2018-06-18 13:01:59 +030045 def ip_range(self, start, end):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020046 """range of remote ip's"""
Eyal Baricef1e2a2018-06-18 13:01:59 +030047 return ip4_range(self.pg0.remote_ip4, start, end)
48
Eyal Baric4aaee12016-12-20 18:36:46 +020049 def encap_mcast(self, pkt, src_ip, src_mac, vni):
50 """
51 Encapsulate the original payload frame by adding VXLAN header with its
52 UDP, IP and Ethernet fields
53 """
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020054 return (
55 Ether(src=src_mac, dst=self.mcast_mac)
56 / IP(src=src_ip, dst=self.mcast_ip4)
57 / UDP(sport=self.dport, dport=self.dport, chksum=0)
58 / VXLAN(vni=vni, flags=self.flags)
59 / pkt
60 )
Damjan Marionf56b77a2016-10-03 19:44:57 +020061
Damjan Marionf56b77a2016-10-03 19:44:57 +020062 def decapsulate(self, pkt):
Klement Sekeraf62ae122016-10-11 11:47:09 +020063 """
64 Decapsulate the original payload frame by removing VXLAN header
65 """
Matej Klottondeb69842016-12-09 15:05:46 +010066 # check if is set I flag
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020067 self.assertEqual(pkt[VXLAN].flags, int("0x8", 16))
Damjan Marionf56b77a2016-10-03 19:44:57 +020068 return pkt[VXLAN].payload
69
Klement Sekeraf62ae122016-10-11 11:47:09 +020070 # Method for checking VXLAN encapsulation.
Damjan Marionf56b77a2016-10-03 19:44:57 +020071 #
Eyal Bari6ae5ee72017-03-23 09:53:51 +020072 def check_encapsulation(self, pkt, vni, local_only=False, mcast_pkt=False):
Damjan Marionf56b77a2016-10-03 19:44:57 +020073 # TODO: add error messages
Klement Sekeraf62ae122016-10-11 11:47:09 +020074 # Verify source MAC is VPP_MAC and destination MAC is MY_MAC resolved
Damjan Marionf56b77a2016-10-03 19:44:57 +020075 # by VPP using ARP.
Klement Sekeraf62ae122016-10-11 11:47:09 +020076 self.assertEqual(pkt[Ether].src, self.pg0.local_mac)
Eyal Baric4aaee12016-12-20 18:36:46 +020077 if not local_only:
Eyal Bari6ae5ee72017-03-23 09:53:51 +020078 if not mcast_pkt:
79 self.assertEqual(pkt[Ether].dst, self.pg0.remote_mac)
80 else:
81 self.assertEqual(pkt[Ether].dst, type(self).mcast_mac)
Klement Sekeraf62ae122016-10-11 11:47:09 +020082 # Verify VXLAN tunnel source IP is VPP_IP and destination IP is MY_IP.
83 self.assertEqual(pkt[IP].src, self.pg0.local_ip4)
Eyal Baric4aaee12016-12-20 18:36:46 +020084 if not local_only:
Eyal Bari6ae5ee72017-03-23 09:53:51 +020085 if not mcast_pkt:
86 self.assertEqual(pkt[IP].dst, self.pg0.remote_ip4)
87 else:
88 self.assertEqual(pkt[IP].dst, type(self).mcast_ip4)
Klement Sekeraf62ae122016-10-11 11:47:09 +020089 # Verify UDP destination port is VXLAN 4789, source UDP port could be
Damjan Marionf56b77a2016-10-03 19:44:57 +020090 # arbitrary.
Artem Glazychev839dcc02020-12-01 02:39:21 +070091 self.assertEqual(pkt[UDP].dport, self.dport)
Vladimir Isaev698eb872020-05-21 16:34:17 +030092 # Verify UDP checksum
93 self.assert_udp_checksum_valid(pkt)
Eyal Baric4aaee12016-12-20 18:36:46 +020094 # Verify VNI
95 self.assertEqual(pkt[VXLAN].vni, vni)
96
Eyal Baric4aaee12016-12-20 18:36:46 +020097 @classmethod
Artem Glazychev839dcc02020-12-01 02:39:21 +070098 def create_vxlan_flood_test_bd(cls, vni, n_ucast_tunnels, port):
Eyal Baric4aaee12016-12-20 18:36:46 +020099 # Create 10 ucast vxlan tunnels under bd
100 ip_range_start = 10
Eyal Barid81da8c2017-01-11 13:39:54 +0200101 ip_range_end = ip_range_start + n_ucast_tunnels
Neale Ranns097fa662018-05-01 05:17:55 -0700102 next_hop_address = cls.pg0.remote_ip4
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200103 for dest_ip4 in ip4_range(next_hop_address, ip_range_start, ip_range_end):
Paul Vinciguerra2f156312020-05-02 22:34:40 -0400104 # add host route so dest_ip4 will not be resolved
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200105 rip = VppIpRoute(
106 cls,
107 dest_ip4,
108 32,
109 [VppRoutePath(next_hop_address, INVALID_INDEX)],
110 register=False,
111 )
Neale Ranns097fa662018-05-01 05:17:55 -0700112 rip.add_vpp_config()
Neale Ranns097fa662018-05-01 05:17:55 -0700113
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200114 r = VppVxlanTunnel(
115 cls,
116 src=cls.pg0.local_ip4,
117 src_port=port,
118 dst_port=port,
119 dst=dest_ip4,
120 vni=vni,
121 )
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100122 r.add_vpp_config()
Neale Ranns097fa662018-05-01 05:17:55 -0700123 cls.vapi.sw_interface_set_l2_bridge(r.sw_if_index, bd_id=vni)
Eyal Baric4aaee12016-12-20 18:36:46 +0200124
125 @classmethod
Artem Glazychev839dcc02020-12-01 02:39:21 +0700126 def add_del_shared_mcast_dst_load(cls, port, is_add):
Eyal Bari4bce2902017-01-16 12:02:46 +0200127 """
128 add or del tunnels sharing the same mcast dst
129 to test vxlan ref_count mechanism
130 """
Gabriel Ganne7e665d62017-11-17 09:18:53 +0100131 n_shared_dst_tunnels = 20
Eyal Bari4bce2902017-01-16 12:02:46 +0200132 vni_start = 10000
133 vni_end = vni_start + n_shared_dst_tunnels
134 for vni in range(vni_start, vni_end):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200135 r = VppVxlanTunnel(
136 cls,
137 src=cls.pg0.local_ip4,
138 src_port=port,
139 dst_port=port,
140 dst=cls.mcast_ip4,
141 mcast_sw_if_index=1,
142 vni=vni,
143 )
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100144 if is_add:
145 r.add_vpp_config()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200146 if r.sw_if_index == 0xFFFFFFFF:
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100147 raise ValueError("bad sw_if_index: ~0")
148 else:
149 r.remove_vpp_config()
Eyal Bari4bce2902017-01-16 12:02:46 +0200150
151 @classmethod
Artem Glazychev839dcc02020-12-01 02:39:21 +0700152 def add_shared_mcast_dst_load(cls, port):
153 cls.add_del_shared_mcast_dst_load(port=port, is_add=1)
Eyal Bari4bce2902017-01-16 12:02:46 +0200154
155 @classmethod
Artem Glazychev839dcc02020-12-01 02:39:21 +0700156 def del_shared_mcast_dst_load(cls, port):
157 cls.add_del_shared_mcast_dst_load(port=port, is_add=0)
Eyal Bari4bce2902017-01-16 12:02:46 +0200158
159 @classmethod
Artem Glazychev839dcc02020-12-01 02:39:21 +0700160 def add_del_mcast_tunnels_load(cls, port, is_add):
Eyal Bari4bce2902017-01-16 12:02:46 +0200161 """
162 add or del tunnels to test vxlan stability
163 """
164 n_distinct_dst_tunnels = 200
Eyal Baric4aaee12016-12-20 18:36:46 +0200165 ip_range_start = 10
Eyal Bari4bce2902017-01-16 12:02:46 +0200166 ip_range_end = ip_range_start + n_distinct_dst_tunnels
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200167 for dest_ip4 in ip4_range(cls.mcast_ip4, ip_range_start, ip_range_end):
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100168 vni = bytearray(socket.inet_pton(socket.AF_INET, dest_ip4))[3]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200169 r = VppVxlanTunnel(
170 cls,
171 src=cls.pg0.local_ip4,
172 src_port=port,
173 dst_port=port,
174 dst=dest_ip4,
175 mcast_sw_if_index=1,
176 vni=vni,
177 )
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100178 if is_add:
179 r.add_vpp_config()
180 else:
181 r.remove_vpp_config()
Eyal Baric4aaee12016-12-20 18:36:46 +0200182
183 @classmethod
Artem Glazychev839dcc02020-12-01 02:39:21 +0700184 def add_mcast_tunnels_load(cls, port):
185 cls.add_del_mcast_tunnels_load(port=port, is_add=1)
Eyal Baric4aaee12016-12-20 18:36:46 +0200186
187 @classmethod
Artem Glazychev839dcc02020-12-01 02:39:21 +0700188 def del_mcast_tunnels_load(cls, port):
189 cls.add_del_mcast_tunnels_load(port=port, is_add=0)
Damjan Marionf56b77a2016-10-03 19:44:57 +0200190
Klement Sekeraf62ae122016-10-11 11:47:09 +0200191 # Class method to start the VXLAN test case.
Damjan Marionf56b77a2016-10-03 19:44:57 +0200192 # Overrides setUpClass method in VppTestCase class.
193 # Python try..except statement is used to ensure that the tear down of
194 # the class will be executed even if exception is raised.
195 # @param cls The class pointer.
196 @classmethod
197 def setUpClass(cls):
198 super(TestVxlan, cls).setUpClass()
Damjan Marionf56b77a2016-10-03 19:44:57 +0200199
Klement Sekeraf62ae122016-10-11 11:47:09 +0200200 try:
Matej Klottondeb69842016-12-09 15:05:46 +0100201 cls.flags = 0x8
Klement Sekeraf62ae122016-10-11 11:47:09 +0200202
203 # Create 2 pg interfaces.
Eyal Baric4aaee12016-12-20 18:36:46 +0200204 cls.create_pg_interfaces(range(4))
205 for pg in cls.pg_interfaces:
206 pg.admin_up()
Klement Sekeraf62ae122016-10-11 11:47:09 +0200207
208 # Configure IPv4 addresses on VPP pg0.
209 cls.pg0.config_ip4()
210
211 # Resolve MAC address for VPP's IP address on pg0.
212 cls.pg0.resolve_arp()
213
Eyal Baric4aaee12016-12-20 18:36:46 +0200214 # Our Multicast address
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200215 cls.mcast_ip4 = "239.1.1.1"
Paul Vinciguerra2f156312020-05-02 22:34:40 -0400216 cls.mcast_mac = util.mcast_ip_to_mac(cls.mcast_ip4)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200217 except Exception:
Paul Vinciguerra2f156312020-05-02 22:34:40 -0400218 cls.tearDownClass()
Damjan Marionf56b77a2016-10-03 19:44:57 +0200219 raise
220
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -0700221 @classmethod
222 def tearDownClass(cls):
223 super(TestVxlan, cls).tearDownClass()
224
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100225 def setUp(self):
226 super(TestVxlan, self).setUp()
Artem Glazychev839dcc02020-12-01 02:39:21 +0700227
228 def createVxLANInterfaces(self, port=4789):
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100229 # Create VXLAN VTEP on VPP pg0, and put vxlan_tunnel0 and pg1
230 # into BD.
Artem Glazychev839dcc02020-12-01 02:39:21 +0700231 self.dport = port
232
Neale Ranns91fd9102020-04-03 07:46:28 +0000233 self.single_tunnel_vni = 0x12345
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100234 self.single_tunnel_bd = 1
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200235 r = VppVxlanTunnel(
236 self,
237 src=self.pg0.local_ip4,
238 dst=self.pg0.remote_ip4,
239 src_port=self.dport,
240 dst_port=self.dport,
241 vni=self.single_tunnel_vni,
242 )
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100243 r.add_vpp_config()
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100244 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200245 rx_sw_if_index=r.sw_if_index, bd_id=self.single_tunnel_bd
246 )
247 self.vapi.sw_interface_set_l2_bridge(
248 rx_sw_if_index=self.pg1.sw_if_index, bd_id=self.single_tunnel_bd
249 )
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100250
251 # Setup vni 2 to test multicast flooding
252 self.n_ucast_tunnels = 10
253 self.mcast_flood_bd = 2
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200254 self.create_vxlan_flood_test_bd(
255 self.mcast_flood_bd, self.n_ucast_tunnels, self.dport
256 )
257 r = VppVxlanTunnel(
258 self,
259 src=self.pg0.local_ip4,
260 dst=self.mcast_ip4,
261 src_port=self.dport,
262 dst_port=self.dport,
263 mcast_sw_if_index=1,
264 vni=self.mcast_flood_bd,
265 )
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100266 r.add_vpp_config()
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100267 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200268 rx_sw_if_index=r.sw_if_index, bd_id=self.mcast_flood_bd
269 )
270 self.vapi.sw_interface_set_l2_bridge(
271 rx_sw_if_index=self.pg2.sw_if_index, bd_id=self.mcast_flood_bd
272 )
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100273
274 # Add and delete mcast tunnels to check stability
Artem Glazychev839dcc02020-12-01 02:39:21 +0700275 self.add_shared_mcast_dst_load(self.dport)
276 self.add_mcast_tunnels_load(self.dport)
277 self.del_shared_mcast_dst_load(self.dport)
278 self.del_mcast_tunnels_load(self.dport)
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100279
280 # Setup vni 3 to test unicast flooding
281 self.ucast_flood_bd = 3
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200282 self.create_vxlan_flood_test_bd(
283 self.ucast_flood_bd, self.n_ucast_tunnels, self.dport
284 )
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100285 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200286 rx_sw_if_index=self.pg3.sw_if_index, bd_id=self.ucast_flood_bd
287 )
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100288
Artem Glazychev839dcc02020-12-01 02:39:21 +0700289 # Set scapy listen custom port for VxLAN
290 bind_layers(UDP, VXLAN, dport=self.dport)
Jakub Grajciar7c0eb562020-03-02 13:55:31 +0100291
Vladislav Grishenkof2fc97a2024-01-24 20:33:12 +0500292 def encap_packets(self):
293 def encap_frames(frame, n=10):
294 frames = []
295
296 # Provide IP flow hash difference.
297 for i in range(n):
298 p = frame.copy()
299 p[UDP].dport += i
300 frames.append(p)
301
302 self.pg1.add_stream(frames)
303
304 self.pg0.enable_capture()
305 self.pg_start()
306
307 # Pick received frames and check if they're correctly encapsulated.
308 out = self.pg0.get_capture(n)
309 sports = set()
310 for i in range(n):
311 pkt = out[i]
312 self.check_encapsulation(pkt, self.single_tunnel_vni)
313
314 payload = self.decapsulate(pkt)
315 self.assert_eq_pkts(payload, frames[i])
316
317 sports.add(pkt[UDP].sport)
318
319 # Check src port randomization presence, not concerned with the
320 # src ports split ratio, just as long as there are more then one.
321 self.assertGreaterEqual(len(sports), min(n, 2))
322
323 frame_ip4 = (
324 Ether(src="00:00:00:00:00:02", dst="00:00:00:00:00:01")
325 / IP(src="4.3.2.1", dst="1.2.3.4")
326 / UDP(sport=20000, dport=10000)
327 / Raw("\xa5" * 100)
328 )
329 encap_frames(frame_ip4)
330
331 frame_ip6 = (
332 Ether(src="00:00:00:00:00:02", dst="00:00:00:00:00:01")
333 / IPv6(src="2001:db8::4321", dst="2001:db8::1234")
334 / UDP(sport=20000, dport=10000)
335 / Raw("\xa5" * 100)
336 )
337 encap_frames(frame_ip6)
338
339 frame_mpls4 = (
340 Ether(src="00:00:00:00:00:02", dst="00:00:00:00:00:01")
341 / MPLS(label=44, ttl=64)
342 / IP(src="4.3.2.1", dst="1.2.3.4")
343 / UDP(sport=20000, dport=10000)
344 / Raw("\xa5" * 100)
345 )
346 encap_frames(frame_mpls4)
347
348 frame_mpls6 = (
349 Ether(src="00:00:00:00:00:02", dst="00:00:00:00:00:01")
350 / MPLS(label=44, ttl=64)
351 / IPv6(src="2001:db8::4321", dst="2001:db8::1234")
352 / UDP(sport=20000, dport=10000)
353 / Raw("\xa5" * 100)
354 )
355 encap_frames(frame_mpls6)
356
Artem Glazychev839dcc02020-12-01 02:39:21 +0700357 def encap_big_packet(self):
Ole Troanb3655e52018-08-16 22:08:49 +0200358 self.vapi.sw_interface_set_mtu(self.pg0.sw_if_index, [1500, 0, 0, 0])
359
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200360 frame = (
361 Ether(src="00:00:00:00:00:02", dst="00:00:00:00:00:01")
362 / IP(src="4.3.2.1", dst="1.2.3.4")
363 / UDP(sport=20000, dport=10000)
364 / Raw(b"\xa5" * 1450)
365 )
Ole Troanb3655e52018-08-16 22:08:49 +0200366
367 self.pg1.add_stream([frame])
368
369 self.pg0.enable_capture()
370
371 self.pg_start()
372
373 # Pick first received frame and check if it's correctly encapsulated.
374 out = self.pg0.get_capture(2)
375 ether = out[0]
Ole Troan7f991832018-12-06 17:35:12 +0100376 pkt = reassemble4(out)
Ole Troanb3655e52018-08-16 22:08:49 +0200377 pkt = ether / pkt
Neale Ranns91fd9102020-04-03 07:46:28 +0000378 self.check_encapsulation(pkt, self.single_tunnel_vni)
Ole Troanb3655e52018-08-16 22:08:49 +0200379
380 payload = self.decapsulate(pkt)
381 # TODO: Scapy bug?
382 # self.assert_eq_pkts(payload, frame)
383
Artem Glazychev839dcc02020-12-01 02:39:21 +0700384 """
385 Tests with default port (4789)
386 """
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200387
Artem Glazychev839dcc02020-12-01 02:39:21 +0700388 def test_decap(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200389 """Decapsulation test
Artem Glazychev839dcc02020-12-01 02:39:21 +0700390 from BridgeDoman
391 """
392 self.createVxLANInterfaces()
393 super(TestVxlan, self).test_decap()
394
395 def test_encap(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200396 """Encapsulation test
Artem Glazychev839dcc02020-12-01 02:39:21 +0700397 from BridgeDoman
398 """
399 self.createVxLANInterfaces()
Vladislav Grishenkof2fc97a2024-01-24 20:33:12 +0500400 self.encap_packets()
Artem Glazychev839dcc02020-12-01 02:39:21 +0700401
402 def test_encap_big_packet(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200403 """Encapsulation test send big frame from pg1
Artem Glazychev839dcc02020-12-01 02:39:21 +0700404 Verify receipt of encapsulated frames on pg0
405 """
406 self.createVxLANInterfaces()
407 self.encap_big_packet()
408
409 def test_ucast_flood(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200410 """Unicast flood test
Artem Glazychev839dcc02020-12-01 02:39:21 +0700411 from BridgeDoman
412 """
413 self.createVxLANInterfaces()
414 super(TestVxlan, self).test_ucast_flood()
415
416 def test_mcast_flood(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200417 """Multicast flood test
Artem Glazychev839dcc02020-12-01 02:39:21 +0700418 from BridgeDoman
419 """
420 self.createVxLANInterfaces()
421 super(TestVxlan, self).test_mcast_flood()
422
423 def test_mcast_rcv(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200424 """Multicast receive test
Artem Glazychev839dcc02020-12-01 02:39:21 +0700425 from BridgeDoman
426 """
427 self.createVxLANInterfaces()
428 super(TestVxlan, self).test_mcast_rcv()
429
430 """
431 Tests with custom port
432 """
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200433
Artem Glazychev839dcc02020-12-01 02:39:21 +0700434 def test_decap_custom_port(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200435 """Decapsulation test custom port
Artem Glazychev839dcc02020-12-01 02:39:21 +0700436 from BridgeDoman
437 """
438 self.createVxLANInterfaces(1111)
439 super(TestVxlan, self).test_decap()
440
441 def test_encap_custom_port(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200442 """Encapsulation test custom port
Artem Glazychev839dcc02020-12-01 02:39:21 +0700443 from BridgeDoman
444 """
445 self.createVxLANInterfaces(1111)
446 super(TestVxlan, self).test_encap()
447
448 def test_ucast_flood_custom_port(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200449 """Unicast flood test custom port
Artem Glazychev839dcc02020-12-01 02:39:21 +0700450 from BridgeDoman
451 """
452 self.createVxLANInterfaces(1111)
453 super(TestVxlan, self).test_ucast_flood()
454
455 def test_mcast_flood_custom_port(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200456 """Multicast flood test custom port
Artem Glazychev839dcc02020-12-01 02:39:21 +0700457 from BridgeDoman
458 """
459 self.createVxLANInterfaces(1111)
460 super(TestVxlan, self).test_mcast_flood()
461
462 def test_mcast_rcv_custom_port(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200463 """Multicast receive test custom port
Artem Glazychev839dcc02020-12-01 02:39:21 +0700464 from BridgeDoman
465 """
466 self.createVxLANInterfaces(1111)
467 super(TestVxlan, self).test_mcast_rcv()
468
Klement Sekeraf62ae122016-10-11 11:47:09 +0200469 # Method to define VPP actions before tear down of the test case.
Damjan Marionf56b77a2016-10-03 19:44:57 +0200470 # Overrides tearDown method in VppTestCase class.
471 # @param self The object pointer.
Artem Glazychev839dcc02020-12-01 02:39:21 +0700472
Damjan Marionf56b77a2016-10-03 19:44:57 +0200473 def tearDown(self):
474 super(TestVxlan, self).tearDown()
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -0700475
476 def show_commands_at_teardown(self):
477 self.logger.info(self.vapi.cli("show bridge-domain 1 detail"))
478 self.logger.info(self.vapi.cli("show bridge-domain 2 detail"))
479 self.logger.info(self.vapi.cli("show bridge-domain 3 detail"))
480 self.logger.info(self.vapi.cli("show vxlan tunnel"))
Damjan Marionf56b77a2016-10-03 19:44:57 +0200481
Matej Klottondeb69842016-12-09 15:05:46 +0100482
Neale Ranns1b5ca982020-12-16 13:06:58 +0000483class TestVxlan2(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200484 """VXLAN Test Case"""
485
Neale Ranns1b5ca982020-12-16 13:06:58 +0000486 def setUp(self):
487 super(TestVxlan2, self).setUp()
488
489 # Create 2 pg interfaces.
490 self.create_pg_interfaces(range(4))
491 for pg in self.pg_interfaces:
492 pg.admin_up()
493
494 # Configure IPv4 addresses on VPP pg0.
495 self.pg0.config_ip4()
496 self.pg0.resolve_arp()
497
498 def tearDown(self):
499 super(TestVxlan2, self).tearDown()
500
501 def test_xconnect(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200502 """VXLAN source address not local"""
Neale Ranns1b5ca982020-12-16 13:06:58 +0000503
504 #
505 # test the broken configuration of a VXLAN tunnel whose
506 # source address is not local ot the box. packets sent
507 # through the tunnel should be dropped
508 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200509 t = VppVxlanTunnel(self, src="10.0.0.5", dst=self.pg0.local_ip4, vni=1000)
Neale Ranns1b5ca982020-12-16 13:06:58 +0000510 t.add_vpp_config()
511 t.admin_up()
512
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200513 self.vapi.sw_interface_set_l2_xconnect(
514 t.sw_if_index, self.pg1.sw_if_index, enable=1
515 )
516 self.vapi.sw_interface_set_l2_xconnect(
517 self.pg1.sw_if_index, t.sw_if_index, enable=1
518 )
Neale Ranns1b5ca982020-12-16 13:06:58 +0000519
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200520 p = (
521 Ether(src="00:11:22:33:44:55", dst="00:00:00:11:22:33")
522 / IP(src="4.3.2.1", dst="1.2.3.4")
523 / UDP(sport=20000, dport=10000)
524 / Raw(b"\xa5" * 1450)
525 )
Neale Ranns1b5ca982020-12-16 13:06:58 +0000526
527 rx = self.send_and_assert_no_replies(self.pg1, [p])
528
529
Artem Glazychev23e5f092022-02-21 17:51:29 +0700530class TestVxlanL2Mode(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200531 """VXLAN Test Case"""
532
Artem Glazychev23e5f092022-02-21 17:51:29 +0700533 def setUp(self):
534 super(TestVxlanL2Mode, self).setUp()
535
536 # Create 2 pg interfaces.
537 self.create_pg_interfaces(range(2))
538 for pg in self.pg_interfaces:
539 pg.admin_up()
540
541 # Configure IPv4 addresses on VPP pg0.
542 self.pg0.config_ip4()
543 self.pg0.resolve_arp()
544
545 # Configure IPv4 addresses on VPP pg1.
546 self.pg1.config_ip4()
547
548 def tearDown(self):
549 super(TestVxlanL2Mode, self).tearDown()
550
551 def test_l2_mode(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200552 """VXLAN L2 mode"""
553 t = VppVxlanTunnel(
554 self, src=self.pg0.local_ip4, dst=self.pg0.remote_ip4, vni=1000, is_l3=False
555 )
Artem Glazychev23e5f092022-02-21 17:51:29 +0700556 t.add_vpp_config()
557 t.config_ip4()
558 t.admin_up()
559
560 dstIP = t.local_ip4[:-1] + "2"
561
562 # Create a packet to send
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200563 p = (
564 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
565 / IP(src=self.pg1.local_ip4, dst=dstIP)
566 / UDP(sport=555, dport=556)
567 / Raw(b"\x00" * 80)
568 )
Artem Glazychev23e5f092022-02-21 17:51:29 +0700569
570 # Expect ARP request
571 rx = self.send_and_expect(self.pg1, [p], self.pg0)
572 for p in rx:
573 self.assertEqual(p[Ether].dst, self.pg0.remote_mac)
574 self.assertEqual(p[Ether].src, self.pg0.local_mac)
575 self.assertEqual(p[ARP].op, 1)
576 self.assertEqual(p[ARP].pdst, dstIP)
577
578 # Resolve ARP
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200579 VppNeighbor(self, t.sw_if_index, self.pg1.remote_mac, dstIP).add_vpp_config()
Artem Glazychev23e5f092022-02-21 17:51:29 +0700580
581 # Send packets
582 NUM_PKTS = 128
Steven Luonge4238aa2024-04-19 09:49:20 -0700583 p.dst = self.pg1.local_mac
Artem Glazychev23e5f092022-02-21 17:51:29 +0700584 rx = self.send_and_expect(self.pg1, p * NUM_PKTS, self.pg0)
585 self.assertEqual(NUM_PKTS, len(rx))
586
587
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200588if __name__ == "__main__":
Damjan Marionf56b77a2016-10-03 19:44:57 +0200589 unittest.main(testRunner=VppTestRunner)