blob: fc7cf9b2e7e28a45004ffa0ddd5b87f70d300f4d [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
7from framework import VppTestCase, VppTestRunner, running_extended_tests
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
Jakub Grajciar546f9552019-08-21 10:51:21 +020010from vpp_memif import remove_all_memif_vpp_config, \
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -080011 VppSocketFilename, VppMemif
Neale Ranns097fa662018-05-01 05:17:55 -070012from vpp_ip_route import VppIpRoute, VppRoutePath
Jakub Grajciar546f9552019-08-21 10:51:21 +020013from vpp_papi import VppEnum
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020014
15
Andrew Yourtchenko06f32812021-01-14 10:19:08 +000016@tag_run_solo
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020017class TestMemif(VppTestCase):
18 """ Memif Test Case """
Klement Sekera558ceab2021-04-08 19:37:41 +020019 remote_class = RemoteVppTestCase
20
21 @classmethod
22 def get_cpus_required(cls):
23 return (super().get_cpus_required() +
24 cls.remote_class.get_cpus_required())
25
26 @classmethod
27 def assign_cpus(cls, cpus):
28 remote_cpus = cpus[:cls.remote_class.get_cpus_required()]
29 my_cpus = cpus[cls.remote_class.get_cpus_required():]
30 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()
40 cls.remote_test.setUpClass(cls.tempdir)
41 cls.create_pg_interfaces(range(1))
42 for pg in cls.pg_interfaces:
43 pg.config_ip4()
44 pg.admin_up()
45 pg.resolve_arp()
46
47 @classmethod
48 def tearDownClass(cls):
49 cls.remote_test.tearDownClass()
50 cls.remote_test.quit_remote()
51 for pg in cls.pg_interfaces:
52 pg.unconfig_ip4()
53 pg.set_table_ip4(0)
54 pg.admin_down()
55 super(TestMemif, cls).tearDownClass()
56
57 def tearDown(self):
58 remove_all_memif_vpp_config(self)
59 remove_all_memif_vpp_config(self.remote_test)
60 super(TestMemif, self).tearDown()
61
62 def _check_socket_filename(self, dump, socket_id, filename):
63 for d in dump:
64 if (d.socket_id == socket_id) and (
Ole Troane5b83aa2019-10-18 03:39:26 +020065 d.socket_filename == filename):
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020066 return True
67 return False
68
69 def test_memif_socket_filename_add_del(self):
Neale Ranns097fa662018-05-01 05:17:55 -070070 """ Memif socket filename add/del """
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020071
72 # dump default socket filename
73 dump = self.vapi.memif_socket_filename_dump()
74 self.assertTrue(
75 self._check_socket_filename(
Ole Troane5b83aa2019-10-18 03:39:26 +020076 dump, 0, "%s/memif.sock" % self.tempdir))
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020077
78 memif_sockets = []
79 # existing path
80 memif_sockets.append(
81 VppSocketFilename(
Ole Troane5b83aa2019-10-18 03:39:26 +020082 self, 1, "%s/memif1.sock" % self.tempdir))
Jakub Grajciar99743912018-10-09 12:28:21 +020083 # default path (test tempdir)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020084 memif_sockets.append(
85 VppSocketFilename(
86 self,
87 2,
Ole Troane5b83aa2019-10-18 03:39:26 +020088 "memif2.sock",
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020089 add_default_folder=True))
90 # create new folder in default folder
91 memif_sockets.append(
92 VppSocketFilename(
93 self,
94 3,
Ole Troane5b83aa2019-10-18 03:39:26 +020095 "sock/memif3.sock",
Jakub Grajciarb1be2a02018-09-19 13:36:16 +020096 add_default_folder=True))
97
98 for sock in memif_sockets:
99 sock.add_vpp_config()
100 dump = sock.query_vpp_config()
101 self.assertTrue(
102 self._check_socket_filename(
103 dump,
104 sock.socket_id,
105 sock.socket_filename))
106
107 for sock in memif_sockets:
108 sock.remove_vpp_config()
109
110 dump = self.vapi.memif_socket_filename_dump()
111 self.assertTrue(
112 self._check_socket_filename(
Ole Troane5b83aa2019-10-18 03:39:26 +0200113 dump, 0, "%s/memif.sock" % self.tempdir))
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)
124 if (memif.socket_id is not None):
125 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):
158 """ Memif create/delete interface """
159
Jakub Grajciar546f9552019-08-21 10:51:21 +0200160 memif = VppMemif(
161 self,
162 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
163 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200164 self._create_delete_test_one_interface(memif)
Jakub Grajciar546f9552019-08-21 10:51:21 +0200165 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200166 self._create_delete_test_one_interface(memif)
167
168 def test_memif_create_custom_socket(self):
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800169 """ Memif create with non-default socket filename """
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200170
171 memif_sockets = []
172 # existing path
173 memif_sockets.append(
174 VppSocketFilename(
Ole Troane5b83aa2019-10-18 03:39:26 +0200175 self, 1, "%s/memif1.sock" % self.tempdir))
Jakub Grajciar99743912018-10-09 12:28:21 +0200176 # default path (test tempdir)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200177 memif_sockets.append(
178 VppSocketFilename(
179 self,
180 2,
Ole Troane5b83aa2019-10-18 03:39:26 +0200181 "memif2.sock",
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200182 add_default_folder=True))
183 # create new folder in default folder
184 memif_sockets.append(
185 VppSocketFilename(
186 self,
187 3,
Ole Troane5b83aa2019-10-18 03:39:26 +0200188 "sock/memif3.sock",
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200189 add_default_folder=True))
190
Jakub Grajciar546f9552019-08-21 10:51:21 +0200191 memif = VppMemif(
192 self,
193 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
194 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200195
196 for sock in memif_sockets:
197 sock.add_vpp_config()
198 memif.socket_id = sock.socket_id
Jakub Grajciar546f9552019-08-21 10:51:21 +0200199 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200200 self._create_delete_test_one_interface(memif)
Jakub Grajciar546f9552019-08-21 10:51:21 +0200201 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200202 self._create_delete_test_one_interface(memif)
203
204 def test_memif_connect(self):
205 """ Memif connect """
Jakub Grajciar546f9552019-08-21 10:51:21 +0200206 memif = VppMemif(
207 self,
208 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
209 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
210 ring_size=1024,
211 buffer_size=2048,
212 secret="abc")
Jakub Grajciar99743912018-10-09 12:28:21 +0200213
214 remote_socket = VppSocketFilename(self.remote_test, 1,
Ole Troane5b83aa2019-10-18 03:39:26 +0200215 "%s/memif.sock" % self.tempdir)
Jakub Grajciar99743912018-10-09 12:28:21 +0200216 remote_socket.add_vpp_config()
217
Jakub Grajciar546f9552019-08-21 10:51:21 +0200218 remote_memif = VppMemif(
219 self.remote_test,
220 VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
221 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
222 socket_id=1,
223 ring_size=1024,
224 buffer_size=2048,
225 secret="abc")
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200226
227 self._connect_test_interface_pair(memif, remote_memif)
228
Jakub Grajciar546f9552019-08-21 10:51:21 +0200229 memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
230 remote_memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200231
232 self._connect_test_interface_pair(memif, remote_memif)
233
234 def _create_icmp(self, pg, memif, num):
235 pkts = []
236 for i in range(num):
237 pkt = (Ether(dst=pg.local_mac, src=pg.remote_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +0000238 IP(src=pg.remote_ip4,
239 dst=str(memif.ip_prefix.network_address)) /
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200240 ICMP(id=memif.if_id, type='echo-request', seq=i))
241 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):
255 """ 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,
260 VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET)
Jakub Grajciar99743912018-10-09 12:28:21 +0200261
262 remote_socket = VppSocketFilename(self.remote_test, 1,
Ole Troane5b83aa2019-10-18 03:39:26 +0200263 "%s/memif.sock" % self.tempdir)
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,
270 socket_id=1)
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200271
272 memif.add_vpp_config()
273 memif.config_ip4()
274 memif.admin_up()
275
276 remote_memif.add_vpp_config()
277 remote_memif.config_ip4()
278 remote_memif.admin_up()
279
280 self.assertTrue(memif.wait_for_link_up(5))
281 self.assertTrue(remote_memif.wait_for_link_up(5))
282
283 # add routing to remote vpp
Jakub Grajciar7db35de2019-06-25 10:22:11 +0200284 route = VppIpRoute(self.remote_test, self.pg0._local_ip4_subnet, 24,
Neale Rannsefd7bc22019-11-11 08:32:34 +0000285 [VppRoutePath(memif.ip_prefix.network_address,
286 0xffffffff)],
Paul Vinciguerrac118a222019-06-26 06:52:32 -0400287 register=False)
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
Jakub Grajciarb1be2a02018-09-19 13:36:16 +0200306
307if __name__ == '__main__':
308 unittest.main(testRunner=VppTestRunner)