blob: 904343f2775c4d7cb03279520b218797d9606a1a [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
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020017
18
Andrew Yourtchenko06f32812021-01-14 10:19:08 +000019@tag_run_solo
Dave Wallace670724c2022-09-20 21:52:18 -040020@tag_fixme_debian11
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020021class TestMemif(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020022 """Memif Test Case"""
23
Klement Sekera558ceab2021-04-08 19:37:41 +020024 remote_class = RemoteVppTestCase
25
26 @classmethod
27 def get_cpus_required(cls):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020028 return super().get_cpus_required() + cls.remote_class.get_cpus_required()
Klement Sekera558ceab2021-04-08 19:37:41 +020029
30 @classmethod
31 def assign_cpus(cls, cpus):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020032 remote_cpus = cpus[: cls.remote_class.get_cpus_required()]
33 my_cpus = cpus[cls.remote_class.get_cpus_required() :]
Klement Sekera558ceab2021-04-08 19:37:41 +020034 cls.remote_class.assign_cpus(remote_cpus)
35 super().assign_cpus(my_cpus)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020036
37 @classmethod
38 def setUpClass(cls):
39 # fork new process before client connects to VPP
Klement Sekera558ceab2021-04-08 19:37:41 +020040 cls.remote_test = RemoteClass(cls.remote_class)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020041 cls.remote_test.start_remote()
42 cls.remote_test.set_request_timeout(10)
43 super(TestMemif, cls).setUpClass()
Dave Wallace670724c2022-09-20 21:52:18 -040044 if is_distro_debian11 == True and not hasattr(cls, "vpp"):
45 cls.remote_test.quit_remote()
46 return
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020047 cls.remote_test.setUpClass(cls.tempdir)
48 cls.create_pg_interfaces(range(1))
49 for pg in cls.pg_interfaces:
50 pg.config_ip4()
51 pg.admin_up()
52 pg.resolve_arp()
53
54 @classmethod
55 def tearDownClass(cls):
56 cls.remote_test.tearDownClass()
57 cls.remote_test.quit_remote()
58 for pg in cls.pg_interfaces:
59 pg.unconfig_ip4()
60 pg.set_table_ip4(0)
61 pg.admin_down()
62 super(TestMemif, cls).tearDownClass()
63
64 def tearDown(self):
65 remove_all_memif_vpp_config(self)
66 remove_all_memif_vpp_config(self.remote_test)
67 super(TestMemif, self).tearDown()
68
69 def _check_socket_filename(self, dump, socket_id, filename):
70 for d in dump:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020071 if (d.socket_id == socket_id) and (d.socket_filename == filename):
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020072 return True
73 return False
74
75 def test_memif_socket_filename_add_del(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020076 """Memif socket filename add/del"""
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020077
78 # dump default socket filename
79 dump = self.vapi.memif_socket_filename_dump()
80 self.assertTrue(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020081 self._check_socket_filename(dump, 0, "%s/memif.sock" % self.tempdir)
82 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020083
84 memif_sockets = []
85 # existing path
86 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020087 VppSocketFilename(self, 1, "%s/memif1.sock" % self.tempdir)
88 )
Jakub Grajciar99743912018-10-09 12:28:21 +020089 # default path (test tempdir)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020090 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020091 VppSocketFilename(self, 2, "memif2.sock", add_default_folder=True)
92 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020093 # create new folder in default folder
94 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020095 VppSocketFilename(self, 3, "sock/memif3.sock", add_default_folder=True)
96 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020097
98 for sock in memif_sockets:
99 sock.add_vpp_config()
100 dump = sock.query_vpp_config()
101 self.assertTrue(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200102 self._check_socket_filename(dump, sock.socket_id, sock.socket_filename)
103 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200104
105 for sock in memif_sockets:
106 sock.remove_vpp_config()
107
108 dump = self.vapi.memif_socket_filename_dump()
109 self.assertTrue(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200110 self._check_socket_filename(dump, 0, "%s/memif.sock" % self.tempdir)
111 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200112
113 def _create_delete_test_one_interface(self, memif):
114 memif.add_vpp_config()
115
116 dump = memif.query_vpp_config()
117
118 self.assertTrue(dump)
119 self.assertEqual(dump.sw_if_index, memif.sw_if_index)
120 self.assertEqual(dump.role, memif.role)
121 self.assertEqual(dump.mode, memif.mode)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200122 if memif.socket_id is not None:
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200123 self.assertEqual(dump.socket_id, memif.socket_id)
124
125 memif.remove_vpp_config()
126
127 dump = memif.query_vpp_config()
128
129 self.assertFalse(dump)
130
131 def _connect_test_one_interface(self, memif):
132 self.assertTrue(memif.wait_for_link_up(5))
133 dump = memif.query_vpp_config()
134
Jakub Grajciar546f9552019-08-21 10:51:21 +0200135 if memif.role == VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE:
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200136 self.assertEqual(dump.ring_size, memif.ring_size)
137 self.assertEqual(dump.buffer_size, memif.buffer_size)
138 else:
139 self.assertEqual(dump.ring_size, 1)
140 self.assertEqual(dump.buffer_size, 0)
141
142 def _connect_test_interface_pair(self, memif0, memif1):
143 memif0.add_vpp_config()
144 memif1.add_vpp_config()
145
146 memif0.admin_up()
147 memif1.admin_up()
148
149 self._connect_test_one_interface(memif0)
150 self._connect_test_one_interface(memif1)
151
152 memif0.remove_vpp_config()
153 memif1.remove_vpp_config()
154
155 def test_memif_create_delete(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200156 """Memif create/delete interface"""
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200157
Jakub Grajciar546f9552019-08-21 10:51:21 +0200158 memif = VppMemif(
159 self,
160 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200161 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
162 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200163 self._create_delete_test_one_interface(memif)
Jakub Grajciar546f9552019-08-21 10:51:21 +0200164 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200165 self._create_delete_test_one_interface(memif)
166
167 def test_memif_create_custom_socket(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200168 """Memif create with non-default socket filename"""
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200169
170 memif_sockets = []
171 # existing path
172 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200173 VppSocketFilename(self, 1, "%s/memif1.sock" % self.tempdir)
174 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200175 # default path (test tempdir)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200176 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200177 VppSocketFilename(self, 2, "memif2.sock", add_default_folder=True)
178 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200179 # create new folder in default folder
180 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200181 VppSocketFilename(self, 3, "sock/memif3.sock", add_default_folder=True)
182 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200183
Jakub Grajciar546f9552019-08-21 10:51:21 +0200184 memif = VppMemif(
185 self,
186 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200187 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
188 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200189
190 for sock in memif_sockets:
191 sock.add_vpp_config()
192 memif.socket_id = sock.socket_id
Jakub Grajciar546f9552019-08-21 10:51:21 +0200193 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200194 self._create_delete_test_one_interface(memif)
Jakub Grajciar546f9552019-08-21 10:51:21 +0200195 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200196 self._create_delete_test_one_interface(memif)
197
198 def test_memif_connect(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200199 """Memif connect"""
Jakub Grajciar546f9552019-08-21 10:51:21 +0200200 memif = VppMemif(
201 self,
202 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
203 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
204 ring_size=1024,
205 buffer_size=2048,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200206 secret="abc",
207 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200208
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200209 remote_socket = VppSocketFilename(
210 self.remote_test, 1, "%s/memif.sock" % self.tempdir
211 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200212 remote_socket.add_vpp_config()
213
Jakub Grajciar546f9552019-08-21 10:51:21 +0200214 remote_memif = VppMemif(
215 self.remote_test,
216 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
217 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
218 socket_id=1,
219 ring_size=1024,
220 buffer_size=2048,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200221 secret="abc",
222 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200223
224 self._connect_test_interface_pair(memif, remote_memif)
225
Jakub Grajciar546f9552019-08-21 10:51:21 +0200226 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
227 remote_memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200228
229 self._connect_test_interface_pair(memif, remote_memif)
230
231 def _create_icmp(self, pg, memif, num):
232 pkts = []
233 for i in range(num):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200234 pkt = (
235 Ether(dst=pg.local_mac, src=pg.remote_mac)
236 / IP(src=pg.remote_ip4, dst=str(memif.ip_prefix.network_address))
237 / ICMP(id=memif.if_id, type="echo-request", seq=i)
238 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200239 pkts.append(pkt)
240 return pkts
241
242 def _verify_icmp(self, pg, memif, rx, seq):
243 ip = rx[IP]
Neale Rannsefd7bc22019-11-11 08:32:34 +0000244 self.assertEqual(ip.src, str(memif.ip_prefix.network_address))
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200245 self.assertEqual(ip.dst, pg.remote_ip4)
246 self.assertEqual(ip.proto, 1)
247 icmp = rx[ICMP]
248 self.assertEqual(icmp.type, 0) # echo-reply
249 self.assertEqual(icmp.id, memif.if_id)
250 self.assertEqual(icmp.seq, seq)
251
252 def test_memif_ping(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200253 """Memif ping"""
Neale Ranns097fa662018-05-01 05:17:55 -0700254
Jakub Grajciar546f9552019-08-21 10:51:21 +0200255 memif = VppMemif(
256 self,
257 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200258 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
259 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200260
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200261 remote_socket = VppSocketFilename(
262 self.remote_test, 1, "%s/memif.sock" % self.tempdir
263 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200264 remote_socket.add_vpp_config()
265
Jakub Grajciar546f9552019-08-21 10:51:21 +0200266 remote_memif = VppMemif(
267 self.remote_test,
268 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
269 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200270 socket_id=1,
271 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200272
273 memif.add_vpp_config()
274 memif.config_ip4()
275 memif.admin_up()
276
277 remote_memif.add_vpp_config()
278 remote_memif.config_ip4()
279 remote_memif.admin_up()
280
281 self.assertTrue(memif.wait_for_link_up(5))
282 self.assertTrue(remote_memif.wait_for_link_up(5))
283
284 # add routing to remote vpp
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200285 route = VppIpRoute(
286 self.remote_test,
287 self.pg0._local_ip4_subnet,
288 24,
289 [VppRoutePath(memif.ip_prefix.network_address, 0xFFFFFFFF)],
290 register=False,
291 )
Jakub Grajciar7db35de2019-06-25 10:22:11 +0200292
293 route.add_vpp_config()
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200294
295 # create ICMP echo-request from local pg to remote memif
296 packet_num = 10
297 pkts = self._create_icmp(self.pg0, remote_memif, packet_num)
298
299 self.pg0.add_stream(pkts)
300 self.pg_enable_capture(self.pg_interfaces)
301 self.pg_start()
302 capture = self.pg0.get_capture(packet_num, timeout=2)
303 seq = 0
304 for c in capture:
305 self._verify_icmp(self.pg0, remote_memif, c, seq)
306 seq += 1
307
Jakub Grajciar7db35de2019-06-25 10:22:11 +0200308 route.remove_vpp_config()
309
Daniel Béreš90c397c2021-11-03 08:55:04 +0000310 def test_memif_admin_up_down_up(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200311 """Memif admin up/down/up"""
Daniel Béreš90c397c2021-11-03 08:55:04 +0000312 memif = VppMemif(
313 self,
314 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
315 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
316 ring_size=1024,
317 buffer_size=2048,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200318 secret="abc",
319 )
Daniel Béreš90c397c2021-11-03 08:55:04 +0000320
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200321 remote_socket = VppSocketFilename(
322 self.remote_test, 1, "%s/memif.sock" % self.tempdir
323 )
Daniel Béreš90c397c2021-11-03 08:55:04 +0000324 remote_socket.add_vpp_config()
325
326 remote_memif = VppMemif(
327 self.remote_test,
328 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
329 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
330 socket_id=1,
331 ring_size=1024,
332 buffer_size=2048,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200333 secret="abc",
334 )
Daniel Béreš90c397c2021-11-03 08:55:04 +0000335
336 memif.add_vpp_config()
337 remote_memif.add_vpp_config()
338
339 memif.admin_up()
340 remote_memif.admin_up()
341 memif.admin_down()
342 remote_memif.admin_down()
343 memif.admin_up()
344 remote_memif.admin_up()
345
346 self._connect_test_one_interface(memif)
347 self._connect_test_one_interface(remote_memif)
348
349 memif.remove_vpp_config()
350 remote_memif.remove_vpp_config()
351 remote_socket.remove_vpp_config()
352
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200353
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200354if __name__ == "__main__":
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200355 unittest.main(testRunner=VppTestRunner)