xref: /linux/net/mctp/test/sock-test.c (revision 4ec4b7fc04a7217a6a581ac132bd0fb6abc2f4d5)
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 struct mctp_bind_pair_test {
249 	const struct mctp_test_bind_setup *bind1;
250 	const struct mctp_test_bind_setup *bind2;
251 	int error;
252 };
253 
254 /* Pairs of binds and whether they will conflict */
255 static const struct mctp_bind_pair_test mctp_bind_pair_tests[] = {
256 	/* Both ADDR_ANY, conflict */
257 	{ &bind_addrany_netdefault_type1, &bind_addrany_netdefault_type1,
258 	  EADDRINUSE },
259 	/* Same specific EID, conflict */
260 	{ &bind_addr8_netdefault_type1, &bind_addr8_netdefault_type1,
261 	  EADDRINUSE },
262 	/* ADDR_ANY vs specific EID, OK */
263 	{ &bind_addrany_netdefault_type1, &bind_addr8_netdefault_type1, 0 },
264 	/* ADDR_ANY different types, OK */
265 	{ &bind_addrany_net2_type2, &bind_addrany_net2_type1, 0 },
266 	/* ADDR_ANY different nets, OK */
267 	{ &bind_addrany_net2_type1, &bind_addrany_netdefault_type1, 0 },
268 
269 	/* specific EID, NET_ANY (resolves to default)
270 	 *  vs specific EID, explicit default net 1, conflict
271 	 */
272 	{ &bind_addr8_netdefault_type1, &bind_addr8_net1_type1, EADDRINUSE },
273 
274 	/* specific EID, net 1 vs specific EID, net 2, ok */
275 	{ &bind_addr8_net1_type1, &bind_addr8_net2_type1, 0 },
276 
277 	/* ANY_ADDR, NET_ANY (doesn't resolve to default)
278 	 *  vs ADDR_ANY, explicit default net 1, OK
279 	 */
280 	{ &bind_addrany_netdefault_type1, &bind_addrany_net1_type1, 0 },
281 };
282 
283 static void mctp_bind_pair_desc(const struct mctp_bind_pair_test *t, char *desc)
284 {
285 	snprintf(desc, KUNIT_PARAM_DESC_SIZE,
286 		 "{bind(addr %d, type %d, net %d)} {bind(addr %d, type %d, net %d)} -> error %d",
287 		 t->bind1->bind_addr, t->bind1->bind_type, t->bind1->bind_net,
288 		 t->bind2->bind_addr, t->bind2->bind_type, t->bind2->bind_net,
289 		 t->error);
290 }
291 
292 KUNIT_ARRAY_PARAM(mctp_bind_pair, mctp_bind_pair_tests, mctp_bind_pair_desc);
293 
294 static int
295 mctp_test_bind_conflicts_inner(struct kunit *test,
296 			       const struct mctp_test_bind_setup *bind1,
297 			       const struct mctp_test_bind_setup *bind2)
298 {
299 	struct socket *sock1 = NULL, *sock2 = NULL, *sock3 = NULL;
300 	int bind_errno;
301 
302 	/* Bind to first address, always succeeds */
303 	mctp_test_bind_run(test, bind1, &bind_errno, &sock1);
304 	KUNIT_EXPECT_EQ(test, bind_errno, 0);
305 
306 	/* A second identical bind always fails */
307 	mctp_test_bind_run(test, bind1, &bind_errno, &sock2);
308 	KUNIT_EXPECT_EQ(test, -bind_errno, EADDRINUSE);
309 
310 	/* A different bind, result is returned */
311 	mctp_test_bind_run(test, bind2, &bind_errno, &sock3);
312 
313 	if (sock1)
314 		sock_release(sock1);
315 	if (sock2)
316 		sock_release(sock2);
317 	if (sock3)
318 		sock_release(sock3);
319 
320 	return bind_errno;
321 }
322 
323 static void mctp_test_bind_conflicts(struct kunit *test)
324 {
325 	const struct mctp_bind_pair_test *pair;
326 	int bind_errno;
327 
328 	pair = test->param_value;
329 
330 	bind_errno =
331 		mctp_test_bind_conflicts_inner(test, pair->bind1, pair->bind2);
332 	KUNIT_EXPECT_EQ(test, -bind_errno, pair->error);
333 
334 	/* swapping the calls, the second bind should still fail */
335 	bind_errno =
336 		mctp_test_bind_conflicts_inner(test, pair->bind2, pair->bind1);
337 	KUNIT_EXPECT_EQ(test, -bind_errno, pair->error);
338 }
339 
340 static void mctp_test_assumptions(struct kunit *test)
341 {
342 	/* check assumption of default net from bind_addr8_net1_type1 */
343 	KUNIT_ASSERT_EQ(test, mctp_default_net(&init_net), 1);
344 }
345 
346 static struct kunit_case mctp_test_cases[] = {
347 	KUNIT_CASE(mctp_test_assumptions),
348 	KUNIT_CASE(mctp_test_sock_sendmsg_extaddr),
349 	KUNIT_CASE(mctp_test_sock_recvmsg_extaddr),
350 	KUNIT_CASE_PARAM(mctp_test_bind_conflicts, mctp_bind_pair_gen_params),
351 	{}
352 };
353 
354 static struct kunit_suite mctp_test_suite = {
355 	.name = "mctp-sock",
356 	.test_cases = mctp_test_cases,
357 };
358 
359 kunit_test_suite(mctp_test_suite);
360