blob: f0b602144425ec028849f07ef3741ff4b0f26426 [file] [log] [blame]
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -08001import socket
Jakub Grajciarb1be2a02018-09-19 13:36:16 +02002import unittest
3
4from scapy.layers.l2 import Ether
5from scapy.layers.inet import IP, ICMP
6
Klement Sekerab23ffd72021-05-31 16:08:53 +02007from framework import VppTestCase, VppTestRunner
Dave Wallace670724c2022-09-20 21:52:18 -04008from framework import tag_run_solo, tag_fixme_debian11, is_distro_debian11
Jakub Grajciarb1be2a02018-09-19 13:36:16 +02009from remote_test import RemoteClass, RemoteVppTestCase
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020010from vpp_memif import remove_all_memif_vpp_config, VppSocketFilename, VppMemif
Neale Ranns097fa662018-05-01 05:17:55 -070011from vpp_ip_route import VppIpRoute, VppRoutePath
Jakub Grajciar546f9552019-08-21 10:51:21 +020012from vpp_papi import VppEnum
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020013
14
Andrew Yourtchenko06f32812021-01-14 10:19:08 +000015@tag_run_solo
Dave Wallace670724c2022-09-20 21:52:18 -040016@tag_fixme_debian11
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020017class TestMemif(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020018 """Memif Test Case"""
19
Klement Sekera558ceab2021-04-08 19:37:41 +020020 remote_class = RemoteVppTestCase
21
22 @classmethod
23 def get_cpus_required(cls):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020024 return super().get_cpus_required() + cls.remote_class.get_cpus_required()
Klement Sekera558ceab2021-04-08 19:37:41 +020025
26 @classmethod
27 def assign_cpus(cls, cpus):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020028 remote_cpus = cpus[: cls.remote_class.get_cpus_required()]
29 my_cpus = cpus[cls.remote_class.get_cpus_required() :]
Klement Sekera558ceab2021-04-08 19:37:41 +020030 cls.remote_class.assign_cpus(remote_cpus)
31 super().assign_cpus(my_cpus)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020032
33 @classmethod
34 def setUpClass(cls):
35 # fork new process before client connects to VPP
Klement Sekera558ceab2021-04-08 19:37:41 +020036 cls.remote_test = RemoteClass(cls.remote_class)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020037 cls.remote_test.start_remote()
38 cls.remote_test.set_request_timeout(10)
39 super(TestMemif, cls).setUpClass()
Dave Wallace670724c2022-09-20 21:52:18 -040040 if is_distro_debian11 == True and not hasattr(cls, "vpp"):
41 cls.remote_test.quit_remote()
42 return
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020043 cls.remote_test.setUpClass(cls.tempdir)
44 cls.create_pg_interfaces(range(1))
45 for pg in cls.pg_interfaces:
46 pg.config_ip4()
47 pg.admin_up()
48 pg.resolve_arp()
49
50 @classmethod
51 def tearDownClass(cls):
52 cls.remote_test.tearDownClass()
53 cls.remote_test.quit_remote()
54 for pg in cls.pg_interfaces:
55 pg.unconfig_ip4()
56 pg.set_table_ip4(0)
57 pg.admin_down()
58 super(TestMemif, cls).tearDownClass()
59
60 def tearDown(self):
61 remove_all_memif_vpp_config(self)
62 remove_all_memif_vpp_config(self.remote_test)
63 super(TestMemif, self).tearDown()
64
65 def _check_socket_filename(self, dump, socket_id, filename):
66 for d in dump:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020067 if (d.socket_id == socket_id) and (d.socket_filename == filename):
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020068 return True
69 return False
70
71 def test_memif_socket_filename_add_del(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020072 """Memif socket filename add/del"""
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020073
74 # dump default socket filename
75 dump = self.vapi.memif_socket_filename_dump()
76 self.assertTrue(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020077 self._check_socket_filename(dump, 0, "%s/memif.sock" % self.tempdir)
78 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020079
80 memif_sockets = []
81 # existing path
82 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020083 VppSocketFilename(self, 1, "%s/memif1.sock" % self.tempdir)
84 )
Jakub Grajciar99743912018-10-09 12:28:21 +020085 # default path (test tempdir)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020086 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020087 VppSocketFilename(self, 2, "memif2.sock", add_default_folder=True)
88 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020089 # create new folder in default folder
90 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020091 VppSocketFilename(self, 3, "sock/memif3.sock", add_default_folder=True)
92 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020093
94 for sock in memif_sockets:
95 sock.add_vpp_config()
96 dump = sock.query_vpp_config()
97 self.assertTrue(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020098 self._check_socket_filename(dump, sock.socket_id, sock.socket_filename)
99 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200100
101 for sock in memif_sockets:
102 sock.remove_vpp_config()
103
104 dump = self.vapi.memif_socket_filename_dump()
105 self.assertTrue(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200106 self._check_socket_filename(dump, 0, "%s/memif.sock" % self.tempdir)
107 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200108
109 def _create_delete_test_one_interface(self, memif):
110 memif.add_vpp_config()
111
112 dump = memif.query_vpp_config()
113
114 self.assertTrue(dump)
115 self.assertEqual(dump.sw_if_index, memif.sw_if_index)
116 self.assertEqual(dump.role, memif.role)
117 self.assertEqual(dump.mode, memif.mode)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200118 if memif.socket_id is not None:
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200119 self.assertEqual(dump.socket_id, memif.socket_id)
120
121 memif.remove_vpp_config()
122
123 dump = memif.query_vpp_config()
124
125 self.assertFalse(dump)
126
127 def _connect_test_one_interface(self, memif):
128 self.assertTrue(memif.wait_for_link_up(5))
129 dump = memif.query_vpp_config()
130
Jakub Grajciar546f9552019-08-21 10:51:21 +0200131 if memif.role == VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE:
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200132 self.assertEqual(dump.ring_size, memif.ring_size)
133 self.assertEqual(dump.buffer_size, memif.buffer_size)
134 else:
135 self.assertEqual(dump.ring_size, 1)
136 self.assertEqual(dump.buffer_size, 0)
137
138 def _connect_test_interface_pair(self, memif0, memif1):
139 memif0.add_vpp_config()
140 memif1.add_vpp_config()
141
142 memif0.admin_up()
143 memif1.admin_up()
144
145 self._connect_test_one_interface(memif0)
146 self._connect_test_one_interface(memif1)
147
148 memif0.remove_vpp_config()
149 memif1.remove_vpp_config()
150
151 def test_memif_create_delete(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200152 """Memif create/delete interface"""
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200153
Jakub Grajciar546f9552019-08-21 10:51:21 +0200154 memif = VppMemif(
155 self,
156 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200157 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
158 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200159 self._create_delete_test_one_interface(memif)
Jakub Grajciar546f9552019-08-21 10:51:21 +0200160 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200161 self._create_delete_test_one_interface(memif)
162
163 def test_memif_create_custom_socket(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200164 """Memif create with non-default socket filename"""
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200165
166 memif_sockets = []
167 # existing path
168 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200169 VppSocketFilename(self, 1, "%s/memif1.sock" % self.tempdir)
170 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200171 # default path (test tempdir)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200172 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200173 VppSocketFilename(self, 2, "memif2.sock", add_default_folder=True)
174 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200175 # create new folder in default folder
176 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200177 VppSocketFilename(self, 3, "sock/memif3.sock", add_default_folder=True)
178 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200179
Jakub Grajciar546f9552019-08-21 10:51:21 +0200180 memif = VppMemif(
181 self,
182 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200183 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
184 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200185
186 for sock in memif_sockets:
187 sock.add_vpp_config()
188 memif.socket_id = sock.socket_id
Jakub Grajciar546f9552019-08-21 10:51:21 +0200189 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200190 self._create_delete_test_one_interface(memif)
Jakub Grajciar546f9552019-08-21 10:51:21 +0200191 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200192 self._create_delete_test_one_interface(memif)
193
194 def test_memif_connect(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200195 """Memif connect"""
Jakub Grajciar546f9552019-08-21 10:51:21 +0200196 memif = VppMemif(
197 self,
198 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
199 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
200 ring_size=1024,
201 buffer_size=2048,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200202 secret="abc",
203 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200204
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200205 remote_socket = VppSocketFilename(
206 self.remote_test, 1, "%s/memif.sock" % self.tempdir
207 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200208 remote_socket.add_vpp_config()
209
Jakub Grajciar546f9552019-08-21 10:51:21 +0200210 remote_memif = VppMemif(
211 self.remote_test,
212 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
213 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
214 socket_id=1,
215 ring_size=1024,
216 buffer_size=2048,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200217 secret="abc",
218 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200219
220 self._connect_test_interface_pair(memif, remote_memif)
221
Jakub Grajciar546f9552019-08-21 10:51:21 +0200222 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
223 remote_memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200224
225 self._connect_test_interface_pair(memif, remote_memif)
226
227 def _create_icmp(self, pg, memif, num):
228 pkts = []
229 for i in range(num):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200230 pkt = (
231 Ether(dst=pg.local_mac, src=pg.remote_mac)
232 / IP(src=pg.remote_ip4, dst=str(memif.ip_prefix.network_address))
233 / ICMP(id=memif.if_id, type="echo-request", seq=i)
234 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200235 pkts.append(pkt)
236 return pkts
237
238 def _verify_icmp(self, pg, memif, rx, seq):
239 ip = rx[IP]
Neale Rannsefd7bc22019-11-11 08:32:34 +0000240 self.assertEqual(ip.src, str(memif.ip_prefix.network_address))
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200241 self.assertEqual(ip.dst, pg.remote_ip4)
242 self.assertEqual(ip.proto, 1)
243 icmp = rx[ICMP]
244 self.assertEqual(icmp.type, 0) # echo-reply
245 self.assertEqual(icmp.id, memif.if_id)
246 self.assertEqual(icmp.seq, seq)
247
248 def test_memif_ping(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200249 """Memif ping"""
Neale Ranns097fa662018-05-01 05:17:55 -0700250
Jakub Grajciar546f9552019-08-21 10:51:21 +0200251 memif = VppMemif(
252 self,
253 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200254 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
255 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200256
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200257 remote_socket = VppSocketFilename(
258 self.remote_test, 1, "%s/memif.sock" % self.tempdir
259 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200260 remote_socket.add_vpp_config()
261
Jakub Grajciar546f9552019-08-21 10:51:21 +0200262 remote_memif = VppMemif(
263 self.remote_test,
264 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
265 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200266 socket_id=1,
267 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200268
269 memif.add_vpp_config()
270 memif.config_ip4()
271 memif.admin_up()
272
273 remote_memif.add_vpp_config()
274 remote_memif.config_ip4()
275 remote_memif.admin_up()
276
277 self.assertTrue(memif.wait_for_link_up(5))
278 self.assertTrue(remote_memif.wait_for_link_up(5))
279
280 # add routing to remote vpp
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200281 route = VppIpRoute(
282 self.remote_test,
283 self.pg0._local_ip4_subnet,
284 24,
285 [VppRoutePath(memif.ip_prefix.network_address, 0xFFFFFFFF)],
286 register=False,
287 )
Jakub Grajciar7db35de2019-06-25 10:22:11 +0200288
289 route.add_vpp_config()
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200290
291 # create ICMP echo-request from local pg to remote memif
292 packet_num = 10
293 pkts = self._create_icmp(self.pg0, remote_memif, packet_num)
294
295 self.pg0.add_stream(pkts)
296 self.pg_enable_capture(self.pg_interfaces)
297 self.pg_start()
298 capture = self.pg0.get_capture(packet_num, timeout=2)
299 seq = 0
300 for c in capture:
301 self._verify_icmp(self.pg0, remote_memif, c, seq)
302 seq += 1
303
Jakub Grajciar7db35de2019-06-25 10:22:11 +0200304 route.remove_vpp_config()
305
Daniel Béreš90c397c2021-11-03 08:55:04 +0000306 def test_memif_admin_up_down_up(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200307 """Memif admin up/down/up"""
Daniel Béreš90c397c2021-11-03 08:55:04 +0000308 memif = VppMemif(
309 self,
310 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
311 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
312 ring_size=1024,
313 buffer_size=2048,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200314 secret="abc",
315 )
Daniel Béreš90c397c2021-11-03 08:55:04 +0000316
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200317 remote_socket = VppSocketFilename(
318 self.remote_test, 1, "%s/memif.sock" % self.tempdir
319 )
Daniel Béreš90c397c2021-11-03 08:55:04 +0000320 remote_socket.add_vpp_config()
321
322 remote_memif = VppMemif(
323 self.remote_test,
324 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
325 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
326 socket_id=1,
327 ring_size=1024,
328 buffer_size=2048,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200329 secret="abc",
330 )
Daniel Béreš90c397c2021-11-03 08:55:04 +0000331
332 memif.add_vpp_config()
333 remote_memif.add_vpp_config()
334
335 memif.admin_up()
336 remote_memif.admin_up()
337 memif.admin_down()
338 remote_memif.admin_down()
339 memif.admin_up()
340 remote_memif.admin_up()
341
342 self._connect_test_one_interface(memif)
343 self._connect_test_one_interface(remote_memif)
344
345 memif.remove_vpp_config()
346 remote_memif.remove_vpp_config()
347 remote_socket.remove_vpp_config()
348
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200349
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200350if __name__ == "__main__":
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200351 unittest.main(testRunner=VppTestRunner)