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 */
__mctp_sock_test_init(struct kunit * test,struct mctp_test_dev ** devp,struct mctp_test_route ** rtp,struct socket ** sockp)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
__mctp_sock_test_fini(struct kunit * test,struct mctp_test_dev * dev,struct mctp_test_route * rt,struct socket * sock)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
mctp_test_sock_local_output(struct sock * sk,struct mctp_dst * dst,struct sk_buff * skb,mctp_eid_t daddr,u8 req_tag)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
mctp_test_sock_sendmsg_extaddr(struct kunit * test)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
mctp_test_sock_recvmsg_extaddr(struct kunit * test)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
mctp_bind_pair_desc(const struct mctp_bind_pair_test * t,char * desc)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
mctp_test_bind_invalid(struct kunit * test)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
mctp_test_bind_conflicts_inner(struct kunit * test,const struct mctp_test_bind_setup * bind1,const struct mctp_test_bind_setup * bind2)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
mctp_test_bind_conflicts(struct kunit * test)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
mctp_test_assumptions(struct kunit * test)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