xref: /linux/net/mctp/test/sock-test.c (revision f7c595c9d9f4cce9ec335f0d3c5d875bb547f9d5)
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 struct kunit_case mctp_test_cases[] = {
219 	KUNIT_CASE(mctp_test_sock_sendmsg_extaddr),
220 	KUNIT_CASE(mctp_test_sock_recvmsg_extaddr),
221 	{}
222 };
223 
224 static struct kunit_suite mctp_test_suite = {
225 	.name = "mctp-sock",
226 	.test_cases = mctp_test_cases,
227 };
228 
229 kunit_test_suite(mctp_test_suite);
230