blob: 9b15cd0005be7a7a0ff4989b2da2145fc4db079a [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
Andrew Yourtchenko06f32812021-01-14 10:19:08 +00008from framework import tag_run_solo
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
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020016class TestMemif(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020017 """Memif Test Case"""
18
Klement Sekera558ceab2021-04-08 19:37:41 +020019 remote_class = RemoteVppTestCase
20
21 @classmethod
22 def get_cpus_required(cls):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020023 return super().get_cpus_required() + cls.remote_class.get_cpus_required()
Klement Sekera558ceab2021-04-08 19:37:41 +020024
25 @classmethod
26 def assign_cpus(cls, cpus):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020027 remote_cpus = cpus[: cls.remote_class.get_cpus_required()]
28 my_cpus = cpus[cls.remote_class.get_cpus_required() :]
Klement Sekera558ceab2021-04-08 19:37:41 +020029 cls.remote_class.assign_cpus(remote_cpus)
30 super().assign_cpus(my_cpus)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020031
32 @classmethod
33 def setUpClass(cls):
34 # fork new process before client connects to VPP
Klement Sekera558ceab2021-04-08 19:37:41 +020035 cls.remote_test = RemoteClass(cls.remote_class)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020036 cls.remote_test.start_remote()
37 cls.remote_test.set_request_timeout(10)
38 super(TestMemif, cls).setUpClass()
39 cls.remote_test.setUpClass(cls.tempdir)
40 cls.create_pg_interfaces(range(1))
41 for pg in cls.pg_interfaces:
42 pg.config_ip4()
43 pg.admin_up()
44 pg.resolve_arp()
45
46 @classmethod
47 def tearDownClass(cls):
48 cls.remote_test.tearDownClass()
49 cls.remote_test.quit_remote()
50 for pg in cls.pg_interfaces:
51 pg.unconfig_ip4()
52 pg.set_table_ip4(0)
53 pg.admin_down()
54 super(TestMemif, cls).tearDownClass()
55
56 def tearDown(self):
57 remove_all_memif_vpp_config(self)
58 remove_all_memif_vpp_config(self.remote_test)
59 super(TestMemif, self).tearDown()
60
61 def _check_socket_filename(self, dump, socket_id, filename):
62 for d in dump:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020063 if (d.socket_id == socket_id) and (d.socket_filename == filename):
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020064 return True
65 return False
66
67 def test_memif_socket_filename_add_del(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020068 """Memif socket filename add/del"""
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020069
70 # dump default socket filename
71 dump = self.vapi.memif_socket_filename_dump()
72 self.assertTrue(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020073 self._check_socket_filename(dump, 0, "%s/memif.sock" % self.tempdir)
74 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020075
76 memif_sockets = []
77 # existing path
78 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020079 VppSocketFilename(self, 1, "%s/memif1.sock" % self.tempdir)
80 )
Jakub Grajciar99743912018-10-09 12:28:21 +020081 # default path (test tempdir)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020082 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020083 VppSocketFilename(self, 2, "memif2.sock", add_default_folder=True)
84 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020085 # create new folder in default folder
86 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020087 VppSocketFilename(self, 3, "sock/memif3.sock", add_default_folder=True)
88 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020089
90 for sock in memif_sockets:
91 sock.add_vpp_config()
92 dump = sock.query_vpp_config()
93 self.assertTrue(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020094 self._check_socket_filename(dump, sock.socket_id, sock.socket_filename)
95 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020096
97 for sock in memif_sockets:
98 sock.remove_vpp_config()
99
100 dump = self.vapi.memif_socket_filename_dump()
101 self.assertTrue(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200102 self._check_socket_filename(dump, 0, "%s/memif.sock" % self.tempdir)
103 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200104
105 def _create_delete_test_one_interface(self, memif):
106 memif.add_vpp_config()
107
108 dump = memif.query_vpp_config()
109
110 self.assertTrue(dump)
111 self.assertEqual(dump.sw_if_index, memif.sw_if_index)
112 self.assertEqual(dump.role, memif.role)
113 self.assertEqual(dump.mode, memif.mode)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200114 if memif.socket_id is not None:
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200115 self.assertEqual(dump.socket_id, memif.socket_id)
116
117 memif.remove_vpp_config()
118
119 dump = memif.query_vpp_config()
120
121 self.assertFalse(dump)
122
123 def _connect_test_one_interface(self, memif):
124 self.assertTrue(memif.wait_for_link_up(5))
125 dump = memif.query_vpp_config()
126
Jakub Grajciar546f9552019-08-21 10:51:21 +0200127 if memif.role == VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE:
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200128 self.assertEqual(dump.ring_size, memif.ring_size)
129 self.assertEqual(dump.buffer_size, memif.buffer_size)
130 else:
131 self.assertEqual(dump.ring_size, 1)
132 self.assertEqual(dump.buffer_size, 0)
133
134 def _connect_test_interface_pair(self, memif0, memif1):
135 memif0.add_vpp_config()
136 memif1.add_vpp_config()
137
138 memif0.admin_up()
139 memif1.admin_up()
140
141 self._connect_test_one_interface(memif0)
142 self._connect_test_one_interface(memif1)
143
144 memif0.remove_vpp_config()
145 memif1.remove_vpp_config()
146
147 def test_memif_create_delete(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200148 """Memif create/delete interface"""
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200149
Jakub Grajciar546f9552019-08-21 10:51:21 +0200150 memif = VppMemif(
151 self,
152 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200153 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
154 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200155 self._create_delete_test_one_interface(memif)
Jakub Grajciar546f9552019-08-21 10:51:21 +0200156 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200157 self._create_delete_test_one_interface(memif)
158
159 def test_memif_create_custom_socket(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200160 """Memif create with non-default socket filename"""
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200161
162 memif_sockets = []
163 # existing path
164 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200165 VppSocketFilename(self, 1, "%s/memif1.sock" % self.tempdir)
166 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200167 # default path (test tempdir)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200168 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200169 VppSocketFilename(self, 2, "memif2.sock", add_default_folder=True)
170 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200171 # create new folder in default folder
172 memif_sockets.append(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200173 VppSocketFilename(self, 3, "sock/memif3.sock", add_default_folder=True)
174 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200175
Jakub Grajciar546f9552019-08-21 10:51:21 +0200176 memif = VppMemif(
177 self,
178 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200179 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
180 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200181
182 for sock in memif_sockets:
183 sock.add_vpp_config()
184 memif.socket_id = sock.socket_id
Jakub Grajciar546f9552019-08-21 10:51:21 +0200185 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200186 self._create_delete_test_one_interface(memif)
Jakub Grajciar546f9552019-08-21 10:51:21 +0200187 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200188 self._create_delete_test_one_interface(memif)
189
190 def test_memif_connect(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200191 """Memif connect"""
Jakub Grajciar546f9552019-08-21 10:51:21 +0200192 memif = VppMemif(
193 self,
194 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
195 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
196 ring_size=1024,
197 buffer_size=2048,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200198 secret="abc",
199 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200200
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200201 remote_socket = VppSocketFilename(
202 self.remote_test, 1, "%s/memif.sock" % self.tempdir
203 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200204 remote_socket.add_vpp_config()
205
Jakub Grajciar546f9552019-08-21 10:51:21 +0200206 remote_memif = VppMemif(
207 self.remote_test,
208 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
209 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
210 socket_id=1,
211 ring_size=1024,
212 buffer_size=2048,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200213 secret="abc",
214 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200215
216 self._connect_test_interface_pair(memif, remote_memif)
217
Jakub Grajciar546f9552019-08-21 10:51:21 +0200218 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
219 remote_memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200220
221 self._connect_test_interface_pair(memif, remote_memif)
222
223 def _create_icmp(self, pg, memif, num):
224 pkts = []
225 for i in range(num):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200226 pkt = (
227 Ether(dst=pg.local_mac, src=pg.remote_mac)
228 / IP(src=pg.remote_ip4, dst=str(memif.ip_prefix.network_address))
229 / ICMP(id=memif.if_id, type="echo-request", seq=i)
230 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200231 pkts.append(pkt)
232 return pkts
233
234 def _verify_icmp(self, pg, memif, rx, seq):
235 ip = rx[IP]
Neale Rannsefd7bc22019-11-11 08:32:34 +0000236 self.assertEqual(ip.src, str(memif.ip_prefix.network_address))
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200237 self.assertEqual(ip.dst, pg.remote_ip4)
238 self.assertEqual(ip.proto, 1)
239 icmp = rx[ICMP]
240 self.assertEqual(icmp.type, 0) # echo-reply
241 self.assertEqual(icmp.id, memif.if_id)
242 self.assertEqual(icmp.seq, seq)
243
244 def test_memif_ping(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200245 """Memif ping"""
Neale Ranns097fa662018-05-01 05:17:55 -0700246
Jakub Grajciar546f9552019-08-21 10:51:21 +0200247 memif = VppMemif(
248 self,
249 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200250 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
251 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200252
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200253 remote_socket = VppSocketFilename(
254 self.remote_test, 1, "%s/memif.sock" % self.tempdir
255 )
Jakub Grajciar99743912018-10-09 12:28:21 +0200256 remote_socket.add_vpp_config()
257
Jakub Grajciar546f9552019-08-21 10:51:21 +0200258 remote_memif = VppMemif(
259 self.remote_test,
260 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
261 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200262 socket_id=1,
263 )
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200264
265 memif.add_vpp_config()
266 memif.config_ip4()
267 memif.admin_up()
268
269 remote_memif.add_vpp_config()
270 remote_memif.config_ip4()
271 remote_memif.admin_up()
272
273 self.assertTrue(memif.wait_for_link_up(5))
274 self.assertTrue(remote_memif.wait_for_link_up(5))
275
276 # add routing to remote vpp
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200277 route = VppIpRoute(
278 self.remote_test,
279 self.pg0._local_ip4_subnet,
280 24,
281 [VppRoutePath(memif.ip_prefix.network_address, 0xFFFFFFFF)],
282 register=False,
283 )
Jakub Grajciar7db35de2019-06-25 10:22:11 +0200284
285 route.add_vpp_config()
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200286
287 # create ICMP echo-request from local pg to remote memif
288 packet_num = 10
289 pkts = self._create_icmp(self.pg0, remote_memif, packet_num)
290
291 self.pg0.add_stream(pkts)
292 self.pg_enable_capture(self.pg_interfaces)
293 self.pg_start()
294 capture = self.pg0.get_capture(packet_num, timeout=2)
295 seq = 0
296 for c in capture:
297 self._verify_icmp(self.pg0, remote_memif, c, seq)
298 seq += 1
299
Jakub Grajciar7db35de2019-06-25 10:22:11 +0200300 route.remove_vpp_config()
301
Daniel Béreš90c397c2021-11-03 08:55:04 +0000302 def test_memif_admin_up_down_up(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200303 """Memif admin up/down/up"""
Daniel Béreš90c397c2021-11-03 08:55:04 +0000304 memif = VppMemif(
305 self,
306 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
307 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
308 ring_size=1024,
309 buffer_size=2048,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200310 secret="abc",
311 )
Daniel Béreš90c397c2021-11-03 08:55:04 +0000312
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200313 remote_socket = VppSocketFilename(
314 self.remote_test, 1, "%s/memif.sock" % self.tempdir
315 )
Daniel Béreš90c397c2021-11-03 08:55:04 +0000316 remote_socket.add_vpp_config()
317
318 remote_memif = VppMemif(
319 self.remote_test,
320 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
321 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
322 socket_id=1,
323 ring_size=1024,
324 buffer_size=2048,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200325 secret="abc",
326 )
Daniel Béreš90c397c2021-11-03 08:55:04 +0000327
328 memif.add_vpp_config()
329 remote_memif.add_vpp_config()
330
331 memif.admin_up()
332 remote_memif.admin_up()
333 memif.admin_down()
334 remote_memif.admin_down()
335 memif.admin_up()
336 remote_memif.admin_up()
337
338 self._connect_test_one_interface(memif)
339 self._connect_test_one_interface(remote_memif)
340
341 memif.remove_vpp_config()
342 remote_memif.remove_vpp_config()
343 remote_socket.remove_vpp_config()
344
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200345
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200346if __name__ == "__main__":
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200347 unittest.main(testRunner=VppTestRunner)