blob: 743c855b943e6a778b8a23b176ced22d398442e7 [file] [log] [blame]
Jakub Grajciarb1be2a02018-09-19 13:36:16 +02001import unittest
2
3from scapy.layers.l2 import Ether
4from scapy.layers.inet import IP, ICMP
5
Dave Wallace8800f732023-08-31 00:47:44 -04006from framework import VppTestCase
7from asfframework import (
8 tag_run_solo,
9 tag_fixme_debian11,
10 is_distro_debian11,
11 VppTestRunner,
12)
13from remote_test import RemoteClass, RemoteVppTestCase
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020014from vpp_memif import remove_all_memif_vpp_config, VppSocketFilename, VppMemif
Neale Ranns097fa662018-05-01 05:17:55 -070015from vpp_ip_route import VppIpRoute, VppRoutePath
Jakub Grajciar546f9552019-08-21 10:51:21 +020016from vpp_papi import VppEnum
Dmitry Valter34fa0ce2024-03-11 10:38:46 +000017from config import config
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020018
19
Andrew Yourtchenko06f32812021-01-14 10:19:08 +000020@tag_run_solo
Dave Wallace670724c2022-09-20 21:52:18 -040021@tag_fixme_debian11
Dmitry Valter34fa0ce2024-03-11 10:38:46 +000022@unittest.skipIf("memif" in config.excluded_plugins, "Exclude Memif plugin tests")
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020023class TestMemif(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020024 """Memif Test Case"""
25
Klement Sekera558ceab2021-04-08 19:37:41 +020026 remote_class = RemoteVppTestCase
27
28 @classmethod
29 def get_cpus_required(cls):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020030 return super().get_cpus_required() + cls.remote_class.get_cpus_required()
Klement Sekera558ceab2021-04-08 19:37:41 +020031
32 @classmethod
33 def assign_cpus(cls, cpus):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020034 remote_cpus = cpus[: cls.remote_class.get_cpus_required()]
35 my_cpus = cpus[cls.remote_class.get_cpus_required() :]
Klement Sekera558ceab2021-04-08 19:37:41 +020036 cls.remote_class.assign_cpus(remote_cpus)
37 super().assign_cpus(my_cpus)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020038
39 @classmethod
40 def setUpClass(cls):
41 # fork new process before client connects to VPP
Klement Sekera558ceab2021-04-08 19:37:41 +020042 cls.remote_test = RemoteClass(cls.remote_class)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020043 cls.remote_test.start_remote()
44 cls.remote_test.set_request_timeout(10)
45 super(TestMemif, cls).setUpClass()
Dave Wallace670724c2022-09-20 21:52:18 -040046 if is_distro_debian11 == True and not hasattr(cls, "vpp"):
47 cls.remote_test.quit_remote()
48 return
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020049 cls.remote_test.setUpClass(cls.tempdir)
50 cls.create_pg_interfaces(range(1))
51 for pg in cls.pg_interfaces:
52 pg.config_ip4()
53 pg.admin_up()
54 pg.resolve_arp()
55
56 @classmethod
57 def tearDownClass(cls):
58 cls.remote_test.tearDownClass()
59 cls.remote_test.quit_remote()
60 for pg in cls.pg_interfaces:
61 pg.unconfig_ip4()
62 pg.set_table_ip4(0)
63 pg.admin_down()
64 super(TestMemif, cls).tearDownClass()
65
66 def tearDown(self):
67 remove_all_memif_vpp_config(self)
68 remove_all_memif_vpp_config(self.remote_test)
69 super(TestMemif, self).tearDown()
70
71 def _check_socket_filename(self, dump, socket_id, filename):
72 for d in dump:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020073 if (d.socket_id == socket_id) and (d.socket_filename == filename):
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020074 return True
75 return False
76
77 def test_memif_socket_filename_add_del(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020078 """Memif socket filename add/del"""
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020079
80 # dump default socket filename
81 dump = self.vapi.memif_socket_filename_dump()
82 self.assertTrue(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020083 self._check_socket_filename(dump, 0, "%s/memif.sock" % self.tempdir)
84 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020085
86 memif_sockets = []
87 # existing path
88 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020089 VppSocketFilename(self, 1, "%s/memif1.sock" % self.tempdir)
90 )
Jakub Grajciar99743912018-10-09 12:28:21 +020091 # default path (test tempdir)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020092 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020093 VppSocketFilename(self, 2, "memif2.sock", add_default_folder=True)
94 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020095 # create new folder in default folder
96 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020097 VppSocketFilename(self, 3, "sock/memif3.sock", add_default_folder=True)
98 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020099
100 for sock in memif_sockets:
101 sock.add_vpp_config()
102 dump = sock.query_vpp_config()
103 self.assertTrue(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200104 self._check_socket_filename(dump, sock.socket_id, sock.socket_filename)
105 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200106
107 for sock in memif_sockets:
108 sock.remove_vpp_config()
109
110 dump = self.vapi.memif_socket_filename_dump()
111 self.assertTrue(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200112 self._check_socket_filename(dump, 0, "%s/memif.sock" % self.tempdir)
113 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200114
115 def _create_delete_test_one_interface(self, memif):
116 memif.add_vpp_config()
117
118 dump = memif.query_vpp_config()
119
120 self.assertTrue(dump)
121 self.assertEqual(dump.sw_if_index, memif.sw_if_index)
122 self.assertEqual(dump.role, memif.role)
123 self.assertEqual(dump.mode, memif.mode)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200124 if memif.socket_id is not None:
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200125 self.assertEqual(dump.socket_id, memif.socket_id)
126
127 memif.remove_vpp_config()
128
129 dump = memif.query_vpp_config()
130
131 self.assertFalse(dump)
132
133 def _connect_test_one_interface(self, memif):
134 self.assertTrue(memif.wait_for_link_up(5))
135 dump = memif.query_vpp_config()
136
Jakub Grajciar546f9552019-08-21 10:51:21 +0200137 if memif.role == VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE:
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200138 self.assertEqual(dump.ring_size, memif.ring_size)
139 self.assertEqual(dump.buffer_size, memif.buffer_size)
140 else:
141 self.assertEqual(dump.ring_size, 1)
142 self.assertEqual(dump.buffer_size, 0)
143
144 def _connect_test_interface_pair(self, memif0, memif1):
145 memif0.add_vpp_config()
146 memif1.add_vpp_config()
147
148 memif0.admin_up()
149 memif1.admin_up()
150
151 self._connect_test_one_interface(memif0)
152 self._connect_test_one_interface(memif1)
153
154 memif0.remove_vpp_config()
155 memif1.remove_vpp_config()
156
157 def test_memif_create_delete(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200158 """Memif create/delete interface"""
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200159
Jakub Grajciar546f9552019-08-21 10:51:21 +0200160 memif = VppMemif(
161 self,
162 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200163 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
164 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200165 self._create_delete_test_one_interface(memif)
Jakub Grajciar546f9552019-08-21 10:51:21 +0200166 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200167 self._create_delete_test_one_interface(memif)
168
169 def test_memif_create_custom_socket(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200170 """Memif create with non-default socket filename"""
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200171
172 memif_sockets = []
173 # existing path
174 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200175 VppSocketFilename(self, 1, "%s/memif1.sock" % self.tempdir)
176 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200177 # default path (test tempdir)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200178 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200179 VppSocketFilename(self, 2, "memif2.sock", add_default_folder=True)
180 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200181 # create new folder in default folder
182 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200183 VppSocketFilename(self, 3, "sock/memif3.sock", add_default_folder=True)
184 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200185
Jakub Grajciar546f9552019-08-21 10:51:21 +0200186 memif = VppMemif(
187 self,
188 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200189 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
190 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200191
192 for sock in memif_sockets:
193 sock.add_vpp_config()
194 memif.socket_id = sock.socket_id
Jakub Grajciar546f9552019-08-21 10:51:21 +0200195 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200196 self._create_delete_test_one_interface(memif)
Jakub Grajciar546f9552019-08-21 10:51:21 +0200197 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200198 self._create_delete_test_one_interface(memif)
199
200 def test_memif_connect(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200201 """Memif connect"""
Jakub Grajciar546f9552019-08-21 10:51:21 +0200202 memif = VppMemif(
203 self,
204 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
205 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
206 ring_size=1024,
207 buffer_size=2048,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200208 secret="abc",
209 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200210
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200211 remote_socket = VppSocketFilename(
212 self.remote_test, 1, "%s/memif.sock" % self.tempdir
213 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200214 remote_socket.add_vpp_config()
215
Jakub Grajciar546f9552019-08-21 10:51:21 +0200216 remote_memif = VppMemif(
217 self.remote_test,
218 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
219 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
220 socket_id=1,
221 ring_size=1024,
222 buffer_size=2048,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200223 secret="abc",
224 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200225
226 self._connect_test_interface_pair(memif, remote_memif)
227
Jakub Grajciar546f9552019-08-21 10:51:21 +0200228 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
229 remote_memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200230
231 self._connect_test_interface_pair(memif, remote_memif)
232
233 def _create_icmp(self, pg, memif, num):
234 pkts = []
235 for i in range(num):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200236 pkt = (
237 Ether(dst=pg.local_mac, src=pg.remote_mac)
238 / IP(src=pg.remote_ip4, dst=str(memif.ip_prefix.network_address))
239 / ICMP(id=memif.if_id, type="echo-request", seq=i)
240 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200241 pkts.append(pkt)
242 return pkts
243
244 def _verify_icmp(self, pg, memif, rx, seq):
245 ip = rx[IP]
Neale Rannsefd7bc22019-11-11 08:32:34 +0000246 self.assertEqual(ip.src, str(memif.ip_prefix.network_address))
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200247 self.assertEqual(ip.dst, pg.remote_ip4)
248 self.assertEqual(ip.proto, 1)
249 icmp = rx[ICMP]
250 self.assertEqual(icmp.type, 0) # echo-reply
251 self.assertEqual(icmp.id, memif.if_id)
252 self.assertEqual(icmp.seq, seq)
253
254 def test_memif_ping(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200255 """Memif ping"""
Neale Ranns097fa662018-05-01 05:17:55 -0700256
Jakub Grajciar546f9552019-08-21 10:51:21 +0200257 memif = VppMemif(
258 self,
259 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200260 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
261 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200262
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200263 remote_socket = VppSocketFilename(
264 self.remote_test, 1, "%s/memif.sock" % self.tempdir
265 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200266 remote_socket.add_vpp_config()
267
Jakub Grajciar546f9552019-08-21 10:51:21 +0200268 remote_memif = VppMemif(
269 self.remote_test,
270 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
271 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200272 socket_id=1,
273 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200274
275 memif.add_vpp_config()
276 memif.config_ip4()
277 memif.admin_up()
278
279 remote_memif.add_vpp_config()
280 remote_memif.config_ip4()
281 remote_memif.admin_up()
282
283 self.assertTrue(memif.wait_for_link_up(5))
284 self.assertTrue(remote_memif.wait_for_link_up(5))
285
286 # add routing to remote vpp
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200287 route = VppIpRoute(
288 self.remote_test,
289 self.pg0._local_ip4_subnet,
290 24,
291 [VppRoutePath(memif.ip_prefix.network_address, 0xFFFFFFFF)],
292 register=False,
293 )
Jakub Grajciar7db35de2019-06-25 10:22:11 +0200294
295 route.add_vpp_config()
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200296
297 # create ICMP echo-request from local pg to remote memif
298 packet_num = 10
299 pkts = self._create_icmp(self.pg0, remote_memif, packet_num)
300
301 self.pg0.add_stream(pkts)
302 self.pg_enable_capture(self.pg_interfaces)
303 self.pg_start()
304 capture = self.pg0.get_capture(packet_num, timeout=2)
305 seq = 0
306 for c in capture:
307 self._verify_icmp(self.pg0, remote_memif, c, seq)
308 seq += 1
309
Jakub Grajciar7db35de2019-06-25 10:22:11 +0200310 route.remove_vpp_config()
311
Daniel Béreš90c397c2021-11-03 08:55:04 +0000312 def test_memif_admin_up_down_up(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200313 """Memif admin up/down/up"""
Daniel Béreš90c397c2021-11-03 08:55:04 +0000314 memif = VppMemif(
315 self,
316 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
317 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
318 ring_size=1024,
319 buffer_size=2048,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200320 secret="abc",
321 )
Daniel Béreš90c397c2021-11-03 08:55:04 +0000322
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200323 remote_socket = VppSocketFilename(
324 self.remote_test, 1, "%s/memif.sock" % self.tempdir
325 )
Daniel Béreš90c397c2021-11-03 08:55:04 +0000326 remote_socket.add_vpp_config()
327
328 remote_memif = VppMemif(
329 self.remote_test,
330 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
331 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
332 socket_id=1,
333 ring_size=1024,
334 buffer_size=2048,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200335 secret="abc",
336 )
Daniel Béreš90c397c2021-11-03 08:55:04 +0000337
338 memif.add_vpp_config()
339 remote_memif.add_vpp_config()
340
341 memif.admin_up()
342 remote_memif.admin_up()
343 memif.admin_down()
344 remote_memif.admin_down()
345 memif.admin_up()
346 remote_memif.admin_up()
347
348 self._connect_test_one_interface(memif)
349 self._connect_test_one_interface(remote_memif)
350
351 memif.remove_vpp_config()
352 remote_memif.remove_vpp_config()
353 remote_socket.remove_vpp_config()
354
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200355
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200356if __name__ == "__main__":
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200357 unittest.main(testRunner=VppTestRunner)