xref: /linux/net/mctp/test/sock-test.c (revision af2d6148d2a159e1a0862bce5a2c88c1618a2b27)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <kunit/static_stub.h>
4 #include <kunit/test.h>
5 
6 #include <linux/socket.h>
7 #include <linux/spinlock.h>
8 
9 #include "utils.h"
10 
11 static const u8 dev_default_lladdr[] = { 0x01, 0x02 };
12 
13 /* helper for simple sock setup: single device, with dev_default_lladdr as its
14  * hardware address, assigned with a local EID 8, and a route to EID 9
15  */
16 static void __mctp_sock_test_init(struct kunit *test,
17 				  struct mctp_test_dev **devp,
18 				  struct mctp_test_route **rtp,
19 				  struct socket **sockp)
20 {
21 	struct mctp_test_route *rt;
22 	struct mctp_test_dev *dev;
23 	struct socket *sock;
24 	unsigned long flags;
25 	u8 *addrs;
26 	int rc;
27 
28 	dev = mctp_test_create_dev_lladdr(sizeof(dev_default_lladdr),
29 					  dev_default_lladdr);
30 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
31 
32 	addrs = kmalloc(1, GFP_KERNEL);
33 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, addrs);
34 	addrs[0] = 8;
35 
36 	spin_lock_irqsave(&dev->mdev->addrs_lock, flags);
37 	dev->mdev->num_addrs = 1;
38 	swap(addrs, dev->mdev->addrs);
39 	spin_unlock_irqrestore(&dev->mdev->addrs_lock, flags);
40 
41 	kfree(addrs);
42 
43 	rt = mctp_test_create_route_direct(dev_net(dev->ndev), dev->mdev, 9, 0);
44 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt);
45 
46 	rc = sock_create_kern(&init_net, AF_MCTP, SOCK_DGRAM, 0, &sock);
47 	KUNIT_ASSERT_EQ(test, rc, 0);
48 
49 	*devp = dev;
50 	*rtp = rt;
51 	*sockp = sock;
52 }
53 
54 static void __mctp_sock_test_fini(struct kunit *test,
55 				  struct mctp_test_dev *dev,
56 				  struct mctp_test_route *rt,
57 				  struct socket *sock)
58 {
59 	sock_release(sock);
60 	mctp_test_route_destroy(test, rt);
61 	mctp_test_destroy_dev(dev);
62 }
63 
64 struct mctp_test_sock_local_output_config {
65 	struct mctp_test_dev *dev;
66 	size_t halen;
67 	u8 haddr[MAX_ADDR_LEN];
68 	bool invoked;
69 	int rc;
70 };
71 
72 static int mctp_test_sock_local_output(struct sock *sk,
73 				       struct mctp_dst *dst,
74 				       struct sk_buff *skb,
75 				       mctp_eid_t daddr, u8 req_tag)
76 {
77 	struct kunit *test = kunit_get_current_test();
78 	struct mctp_test_sock_local_output_config *cfg = test->priv;
79 
80 	KUNIT_EXPECT_PTR_EQ(test, dst->dev, cfg->dev->mdev);
81 	KUNIT_EXPECT_EQ(test, dst->halen, cfg->halen);
82 	KUNIT_EXPECT_MEMEQ(test, dst->haddr, cfg->haddr, dst->halen);
83 
84 	cfg->invoked = true;
85 
86 	kfree_skb(skb);
87 
88 	return cfg->rc;
89 }
90 
91 static void mctp_test_sock_sendmsg_extaddr(struct kunit *test)
92 {
93 	struct sockaddr_mctp_ext addr = {
94 		.smctp_base = {
95 			.smctp_family = AF_MCTP,
96 			.smctp_tag = MCTP_TAG_OWNER,
97 			.smctp_network = MCTP_NET_ANY,
98 		},
99 	};
100 	struct mctp_test_sock_local_output_config cfg = { 0 };
101 	u8 haddr[] = { 0xaa, 0x01 };
102 	u8 buf[4] = { 0, 1, 2, 3 };
103 	struct mctp_test_route *rt;
104 	struct msghdr msg = { 0 };
105 	struct mctp_test_dev *dev;
106 	struct mctp_sock *msk;
107 	struct socket *sock;
108 	ssize_t send_len;
109 	struct kvec vec = {
110 		.iov_base = buf,
111 		.iov_len = sizeof(buf),
112 	};
113 
114 	__mctp_sock_test_init(test, &dev, &rt, &sock);
115 
116 	/* Expect to see the dst configured up with the addressing data we
117 	 * provide in the struct sockaddr_mctp_ext
118 	 */
119 	cfg.dev = dev;
120 	cfg.halen = sizeof(haddr);
121 	memcpy(cfg.haddr, haddr, sizeof(haddr));
122 
123 	test->priv = &cfg;
124 
125 	kunit_activate_static_stub(test, mctp_local_output,
126 				   mctp_test_sock_local_output);
127 
128 	/* enable and configure direct addressing */
129 	msk = container_of(sock->sk, struct mctp_sock, sk);
130 	msk->addr_ext = true;
131 
132 	addr.smctp_ifindex = dev->ndev->ifindex;
133 	addr.smctp_halen = sizeof(haddr);
134 	memcpy(addr.smctp_haddr, haddr, sizeof(haddr));
135 
136 	msg.msg_name = &addr;
137 	msg.msg_namelen = sizeof(addr);
138 
139 	iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, &vec, 1, sizeof(buf));
140 	send_len = mctp_sendmsg(sock, &msg, sizeof(buf));
141 	KUNIT_EXPECT_EQ(test, send_len, sizeof(buf));
142 	KUNIT_EXPECT_TRUE(test, cfg.invoked);
143 
144 	__mctp_sock_test_fini(test, dev, rt, sock);
145 }
146 
147 static void mctp_test_sock_recvmsg_extaddr(struct kunit *test)
148 {
149 	struct sockaddr_mctp_ext recv_addr = { 0 };
150 	u8 rcv_buf[1], rcv_data[] = { 0, 1 };
151 	u8 haddr[] = { 0xaa, 0x02 };
152 	struct mctp_test_route *rt;
153 	struct mctp_test_dev *dev;
154 	struct mctp_skb_cb *cb;
155 	struct mctp_sock *msk;
156 	struct sk_buff *skb;
157 	struct mctp_hdr hdr;
158 	struct socket *sock;
159 	struct msghdr msg;
160 	ssize_t recv_len;
161 	int rc;
162 	struct kvec vec = {
163 		.iov_base = rcv_buf,
164 		.iov_len = sizeof(rcv_buf),
165 	};
166 
167 	__mctp_sock_test_init(test, &dev, &rt, &sock);
168 
169 	/* enable extended addressing on recv */
170 	msk = container_of(sock->sk, struct mctp_sock, sk);
171 	msk->addr_ext = true;
172 
173 	/* base incoming header, using a nul-EID dest */
174 	hdr.ver = 1;
175 	hdr.dest = 0;
176 	hdr.src = 9;
177 	hdr.flags_seq_tag = MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM |
178 			    MCTP_HDR_FLAG_TO;
179 
180 	skb = mctp_test_create_skb_data(&hdr, &rcv_data);
181 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, skb);
182 
183 	mctp_test_skb_set_dev(skb, dev);
184 
185 	/* set incoming extended address data */
186 	cb = mctp_cb(skb);
187 	cb->halen = sizeof(haddr);
188 	cb->ifindex = dev->ndev->ifindex;
189 	memcpy(cb->haddr, haddr, sizeof(haddr));
190 
191 	/* Deliver to socket. The route input path pulls the network header,
192 	 * leaving skb data at type byte onwards. recvmsg will consume the
193 	 * type for addr.smctp_type
194 	 */
195 	skb_pull(skb, sizeof(hdr));
196 	rc = sock_queue_rcv_skb(sock->sk, skb);
197 	KUNIT_ASSERT_EQ(test, rc, 0);
198 
199 	msg.msg_name = &recv_addr;
200 	msg.msg_namelen = sizeof(recv_addr);
201 	iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1, sizeof(rcv_buf));
202 
203 	recv_len = mctp_recvmsg(sock, &msg, sizeof(rcv_buf),
204 				MSG_DONTWAIT | MSG_TRUNC);
205 
206 	KUNIT_EXPECT_EQ(test, recv_len, sizeof(rcv_buf));
207 
208 	/* expect our extended address to be populated from hdr and cb */
209 	KUNIT_EXPECT_EQ(test, msg.msg_namelen, sizeof(recv_addr));
210 	KUNIT_EXPECT_EQ(test, recv_addr.smctp_base.smctp_family, AF_MCTP);
211 	KUNIT_EXPECT_EQ(test, recv_addr.smctp_ifindex, dev->ndev->ifindex);
212 	KUNIT_EXPECT_EQ(test, recv_addr.smctp_halen, sizeof(haddr));
213 	KUNIT_EXPECT_MEMEQ(test, recv_addr.smctp_haddr, haddr, sizeof(haddr));
214 
215 	__mctp_sock_test_fini(test, dev, rt, sock);
216 }
217 
218 static const struct mctp_test_bind_setup bind_addrany_netdefault_type1 = {
219 	.bind_addr = MCTP_ADDR_ANY, .bind_net = MCTP_NET_ANY, .bind_type = 1,
220 };
221 
222 static const struct mctp_test_bind_setup bind_addrany_net2_type1 = {
223 	.bind_addr = MCTP_ADDR_ANY, .bind_net = 2, .bind_type = 1,
224 };
225 
226 /* 1 is default net */
227 static const struct mctp_test_bind_setup bind_addr8_net1_type1 = {
228 	.bind_addr = 8, .bind_net = 1, .bind_type = 1,
229 };
230 
231 static const struct mctp_test_bind_setup bind_addrany_net1_type1 = {
232 	.bind_addr = MCTP_ADDR_ANY, .bind_net = 1, .bind_type = 1,
233 };
234 
235 /* 2 is an arbitrary net */
236 static const struct mctp_test_bind_setup bind_addr8_net2_type1 = {
237 	.bind_addr = 8, .bind_net = 2, .bind_type = 1,
238 };
239 
240 static const struct mctp_test_bind_setup bind_addr8_netdefault_type1 = {
241 	.bind_addr = 8, .bind_net = MCTP_NET_ANY, .bind_type = 1,
242 };
243 
244 static const struct mctp_test_bind_setup bind_addrany_net2_type2 = {
245 	.bind_addr = MCTP_ADDR_ANY, .bind_net = 2, .bind_type = 2,
246 };
247 
248 static const struct mctp_test_bind_setup bind_addrany_net2_type1_peer9 = {
249 	.bind_addr = MCTP_ADDR_ANY, .bind_net = 2, .bind_type = 1,
250 	.have_peer = true, .peer_addr = 9, .peer_net = 2,
251 };
252 
253 struct mctp_bind_pair_test {
254 	const struct mctp_test_bind_setup *bind1;
255 	const struct mctp_test_bind_setup *bind2;
256 	int error;
257 };
258 
259 /* Pairs of binds and whether they will conflict */
260 static const struct mctp_bind_pair_test mctp_bind_pair_tests[] = {
261 	/* Both ADDR_ANY, conflict */
262 	{ &bind_addrany_netdefault_type1, &bind_addrany_netdefault_type1,
263 	  EADDRINUSE },
264 	/* Same specific EID, conflict */
265 	{ &bind_addr8_netdefault_type1, &bind_addr8_netdefault_type1,
266 	  EADDRINUSE },
267 	/* ADDR_ANY vs specific EID, OK */
268 	{ &bind_addrany_netdefault_type1, &bind_addr8_netdefault_type1, 0 },
269 	/* ADDR_ANY different types, OK */
270 	{ &bind_addrany_net2_type2, &bind_addrany_net2_type1, 0 },
271 	/* ADDR_ANY different nets, OK */
272 	{ &bind_addrany_net2_type1, &bind_addrany_netdefault_type1, 0 },
273 
274 	/* specific EID, NET_ANY (resolves to default)
275 	 *  vs specific EID, explicit default net 1, conflict
276 	 */
277 	{ &bind_addr8_netdefault_type1, &bind_addr8_net1_type1, EADDRINUSE },
278 
279 	/* specific EID, net 1 vs specific EID, net 2, ok */
280 	{ &bind_addr8_net1_type1, &bind_addr8_net2_type1, 0 },
281 
282 	/* ANY_ADDR, NET_ANY (doesn't resolve to default)
283 	 *  vs ADDR_ANY, explicit default net 1, OK
284 	 */
285 	{ &bind_addrany_netdefault_type1, &bind_addrany_net1_type1, 0 },
286 
287 	/* specific remote peer doesn't conflict with any-peer bind */
288 	{ &bind_addrany_net2_type1_peer9, &bind_addrany_net2_type1, 0 },
289 
290 	/* bind() NET_ANY is allowed with a connect() net */
291 	{ &bind_addrany_net2_type1_peer9, &bind_addrany_netdefault_type1, 0 },
292 };
293 
294 static void mctp_bind_pair_desc(const struct mctp_bind_pair_test *t, char *desc)
295 {
296 	char peer1[25] = {0}, peer2[25] = {0};
297 
298 	if (t->bind1->have_peer)
299 		snprintf(peer1, sizeof(peer1), ", peer %d net %d",
300 			 t->bind1->peer_addr, t->bind1->peer_net);
301 	if (t->bind2->have_peer)
302 		snprintf(peer2, sizeof(peer2), ", peer %d net %d",
303 			 t->bind2->peer_addr, t->bind2->peer_net);
304 
305 	snprintf(desc, KUNIT_PARAM_DESC_SIZE,
306 		 "{bind(addr %d, type %d, net %d%s)} {bind(addr %d, type %d, net %d%s)} -> error %d",
307 		 t->bind1->bind_addr, t->bind1->bind_type,
308 		 t->bind1->bind_net, peer1,
309 		 t->bind2->bind_addr, t->bind2->bind_type,
310 		 t->bind2->bind_net, peer2, t->error);
311 }
312 
313 KUNIT_ARRAY_PARAM(mctp_bind_pair, mctp_bind_pair_tests, mctp_bind_pair_desc);
314 
315 static void mctp_test_bind_invalid(struct kunit *test)
316 {
317 	struct socket *sock;
318 	int rc;
319 
320 	/* bind() fails if the bind() vs connect() networks mismatch. */
321 	const struct mctp_test_bind_setup bind_connect_net_mismatch = {
322 		.bind_addr = MCTP_ADDR_ANY, .bind_net = 1, .bind_type = 1,
323 		.have_peer = true, .peer_addr = 9, .peer_net = 2,
324 	};
325 	mctp_test_bind_run(test, &bind_connect_net_mismatch, &rc, &sock);
326 	KUNIT_EXPECT_EQ(test, -rc, EINVAL);
327 	sock_release(sock);
328 }
329 
330 static int
331 mctp_test_bind_conflicts_inner(struct kunit *test,
332 			       const struct mctp_test_bind_setup *bind1,
333 			       const struct mctp_test_bind_setup *bind2)
334 {
335 	struct socket *sock1 = NULL, *sock2 = NULL, *sock3 = NULL;
336 	int bind_errno;
337 
338 	/* Bind to first address, always succeeds */
339 	mctp_test_bind_run(test, bind1, &bind_errno, &sock1);
340 	KUNIT_EXPECT_EQ(test, bind_errno, 0);
341 
342 	/* A second identical bind always fails */
343 	mctp_test_bind_run(test, bind1, &bind_errno, &sock2);
344 	KUNIT_EXPECT_EQ(test, -bind_errno, EADDRINUSE);
345 
346 	/* A different bind, result is returned */
347 	mctp_test_bind_run(test, bind2, &bind_errno, &sock3);
348 
349 	if (sock1)
350 		sock_release(sock1);
351 	if (sock2)
352 		sock_release(sock2);
353 	if (sock3)
354 		sock_release(sock3);
355 
356 	return bind_errno;
357 }
358 
359 static void mctp_test_bind_conflicts(struct kunit *test)
360 {
361 	const struct mctp_bind_pair_test *pair;
362 	int bind_errno;
363 
364 	pair = test->param_value;
365 
366 	bind_errno =
367 		mctp_test_bind_conflicts_inner(test, pair->bind1, pair->bind2);
368 	KUNIT_EXPECT_EQ(test, -bind_errno, pair->error);
369 
370 	/* swapping the calls, the second bind should still fail */
371 	bind_errno =
372 		mctp_test_bind_conflicts_inner(test, pair->bind2, pair->bind1);
373 	KUNIT_EXPECT_EQ(test, -bind_errno, pair->error);
374 }
375 
376 static void mctp_test_assumptions(struct kunit *test)
377 {
378 	/* check assumption of default net from bind_addr8_net1_type1 */
379 	KUNIT_ASSERT_EQ(test, mctp_default_net(&init_net), 1);
380 }
381 
382 static struct kunit_case mctp_test_cases[] = {
383 	KUNIT_CASE(mctp_test_assumptions),
384 	KUNIT_CASE(mctp_test_sock_sendmsg_extaddr),
385 	KUNIT_CASE(mctp_test_sock_recvmsg_extaddr),
386 	KUNIT_CASE_PARAM(mctp_test_bind_conflicts, mctp_bind_pair_gen_params),
387 	KUNIT_CASE(mctp_test_bind_invalid),
388 	{}
389 };
390 
391 static struct kunit_suite mctp_test_suite = {
392 	.name = "mctp-sock",
393 	.test_cases = mctp_test_cases,
394 };
395 
396 kunit_test_suite(mctp_test_suite);
397