Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : /* Multipath TCP
3 : : *
4 : : * Copyright (c) 2020, Red Hat, Inc.
5 : : */
6 : :
7 : : #define pr_fmt(fmt) "MPTCP: " fmt
8 : :
9 : : #include "protocol.h"
10 : : #include "mptcp_pm_gen.h"
11 : :
12 : : #define MPTCP_PM_CMD_GRP_OFFSET 0
13 : : #define MPTCP_PM_EV_GRP_OFFSET 1
14 : :
15 : : static const struct genl_multicast_group mptcp_pm_mcgrps[] = {
16 : : [MPTCP_PM_CMD_GRP_OFFSET] = { .name = MPTCP_PM_CMD_GRP_NAME, },
17 : : [MPTCP_PM_EV_GRP_OFFSET] = { .name = MPTCP_PM_EV_GRP_NAME,
18 : : .flags = GENL_MCAST_CAP_NET_ADMIN,
19 : : },
20 : : };
21 : :
22 : 66 : static int mptcp_pm_family_to_addr(int family)
23 : : {
24 : : #if IS_ENABLED(CONFIG_MPTCP_IPV6)
25 : 1256 : if (family == AF_INET6)
26 : 106 : return MPTCP_PM_ADDR_ATTR_ADDR6;
27 : : #endif
28 : : return MPTCP_PM_ADDR_ATTR_ADDR4;
29 : : }
30 : :
31 : 1888 : static int mptcp_pm_parse_pm_addr_attr(struct nlattr *tb[],
32 : : const struct nlattr *attr,
33 : : struct genl_info *info,
34 : : struct mptcp_addr_info *addr,
35 : : bool require_family)
36 : : {
37 : 1888 : int err, addr_addr;
38 : :
39 [ - + ]: 1888 : if (!attr) {
40 [ # # ]: 0 : GENL_SET_ERR_MSG(info, "missing address info");
41 : 0 : return -EINVAL;
42 : : }
43 : :
44 : : /* no validation needed - was already done via nested policy */
45 : 1888 : err = nla_parse_nested_deprecated(tb, MPTCP_PM_ADDR_ATTR_MAX, attr,
46 : : mptcp_pm_address_nl_policy, info->extack);
47 [ + - ]: 1888 : if (err)
48 : : return err;
49 : :
50 [ + + ]: 1888 : if (tb[MPTCP_PM_ADDR_ATTR_ID])
51 : 1262 : addr->id = nla_get_u8(tb[MPTCP_PM_ADDR_ATTR_ID]);
52 : :
53 [ + + ]: 1888 : if (!tb[MPTCP_PM_ADDR_ATTR_FAMILY]) {
54 [ + - ]: 632 : if (!require_family)
55 : : return 0;
56 : :
57 [ # # ]: 0 : NL_SET_ERR_MSG_ATTR(info->extack, attr,
58 : : "missing family");
59 : 0 : return -EINVAL;
60 : : }
61 : :
62 [ - + ]: 1256 : addr->family = nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_FAMILY]);
63 : 1256 : if (addr->family != AF_INET
64 : : #if IS_ENABLED(CONFIG_MPTCP_IPV6)
65 [ - + ]: 1256 : && addr->family != AF_INET6
66 : : #endif
67 : : ) {
68 [ # # ]: 0 : NL_SET_ERR_MSG_ATTR(info->extack, attr,
69 : : "unknown address family");
70 : 0 : return -EINVAL;
71 : : }
72 [ + + ]: 1256 : addr_addr = mptcp_pm_family_to_addr(addr->family);
73 [ - + ]: 1256 : if (!tb[addr_addr]) {
74 [ # # ]: 0 : NL_SET_ERR_MSG_ATTR(info->extack, attr,
75 : : "missing address data");
76 : 0 : return -EINVAL;
77 : : }
78 : :
79 : : #if IS_ENABLED(CONFIG_MPTCP_IPV6)
80 [ + + ]: 1256 : if (addr->family == AF_INET6)
81 : 106 : addr->addr6 = nla_get_in6_addr(tb[addr_addr]);
82 : : else
83 : : #endif
84 : 1150 : addr->addr.s_addr = nla_get_in_addr(tb[addr_addr]);
85 : :
86 [ + + ]: 1256 : if (tb[MPTCP_PM_ADDR_ATTR_PORT])
87 : 96 : addr->port = htons(nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_PORT]));
88 : :
89 : : return 0;
90 : : }
91 : :
92 : 44 : int mptcp_pm_parse_addr(struct nlattr *attr, struct genl_info *info,
93 : : struct mptcp_addr_info *addr)
94 : : {
95 : 44 : struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1];
96 : :
97 : 44 : memset(addr, 0, sizeof(*addr));
98 : :
99 : 44 : return mptcp_pm_parse_pm_addr_attr(tb, attr, info, addr, true);
100 : : }
101 : :
102 : 1844 : int mptcp_pm_parse_entry(struct nlattr *attr, struct genl_info *info,
103 : : bool require_family,
104 : : struct mptcp_pm_addr_entry *entry)
105 : : {
106 : 1844 : struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1];
107 : 1844 : int err;
108 : :
109 : 1844 : memset(entry, 0, sizeof(*entry));
110 : :
111 : 1844 : err = mptcp_pm_parse_pm_addr_attr(tb, attr, info, &entry->addr, require_family);
112 [ + - ]: 1844 : if (err)
113 : : return err;
114 : :
115 [ + + ]: 1844 : if (tb[MPTCP_PM_ADDR_ATTR_IF_IDX]) {
116 : 62 : u32 val = nla_get_s32(tb[MPTCP_PM_ADDR_ATTR_IF_IDX]);
117 : :
118 : 62 : entry->ifindex = val;
119 : : }
120 : :
121 [ + + ]: 1844 : if (tb[MPTCP_PM_ADDR_ATTR_FLAGS])
122 : 700 : entry->flags = nla_get_u32(tb[MPTCP_PM_ADDR_ATTR_FLAGS]);
123 : :
124 [ + + ]: 1844 : if (tb[MPTCP_PM_ADDR_ATTR_PORT])
125 : 52 : entry->addr.port = htons(nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_PORT]));
126 : :
127 : : return 0;
128 : : }
129 : :
130 : 204 : static int mptcp_nl_fill_addr(struct sk_buff *skb,
131 : : struct mptcp_pm_addr_entry *entry)
132 : : {
133 : 204 : struct mptcp_addr_info *addr = &entry->addr;
134 : 204 : struct nlattr *attr;
135 : :
136 : 204 : attr = nla_nest_start(skb, MPTCP_PM_ATTR_ADDR);
137 [ - + ]: 204 : if (!attr)
138 : : return -EMSGSIZE;
139 : :
140 [ - + ]: 204 : if (nla_put_u16(skb, MPTCP_PM_ADDR_ATTR_FAMILY, addr->family))
141 : 0 : goto nla_put_failure;
142 [ - + ]: 204 : if (nla_put_u16(skb, MPTCP_PM_ADDR_ATTR_PORT, ntohs(addr->port)))
143 : 0 : goto nla_put_failure;
144 [ - + ]: 204 : if (nla_put_u8(skb, MPTCP_PM_ADDR_ATTR_ID, addr->id))
145 : 0 : goto nla_put_failure;
146 [ - + ]: 204 : if (nla_put_u32(skb, MPTCP_PM_ADDR_ATTR_FLAGS, entry->flags))
147 : 0 : goto nla_put_failure;
148 [ + + - + ]: 210 : if (entry->ifindex &&
149 [ # # ]: 0 : nla_put_s32(skb, MPTCP_PM_ADDR_ATTR_IF_IDX, entry->ifindex))
150 : 0 : goto nla_put_failure;
151 : :
152 [ + + - + ]: 390 : if (addr->family == AF_INET &&
153 [ # # ]: 186 : nla_put_in_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR4,
154 : : addr->addr.s_addr))
155 : 0 : goto nla_put_failure;
156 : : #if IS_ENABLED(CONFIG_MPTCP_IPV6)
157 [ + + - + ]: 222 : else if (addr->family == AF_INET6 &&
158 [ # # ]: 18 : nla_put_in6_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR6, &addr->addr6))
159 : 0 : goto nla_put_failure;
160 : : #endif
161 : 204 : nla_nest_end(skb, attr);
162 : 204 : return 0;
163 : :
164 : 0 : nla_put_failure:
165 : 0 : nla_nest_cancel(skb, attr);
166 : 0 : return -EMSGSIZE;
167 : : }
168 : :
169 : 28 : static int mptcp_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
170 : : struct genl_info *info)
171 : : {
172 [ + + ]: 28 : if (info->attrs[MPTCP_PM_ATTR_TOKEN])
173 : 6 : return mptcp_userspace_pm_get_addr(id, addr, info);
174 : 22 : return mptcp_pm_nl_get_addr(id, addr, info);
175 : : }
176 : :
177 : 28 : int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
178 : : {
179 : 28 : struct mptcp_pm_addr_entry addr;
180 : 28 : struct nlattr *attr;
181 : 28 : struct sk_buff *msg;
182 : 28 : void *reply;
183 : 28 : int ret;
184 : :
185 [ + - - - ]: 28 : if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ENDPOINT_ADDR))
186 : 0 : return -EINVAL;
187 : :
188 : 28 : attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
189 : 28 : ret = mptcp_pm_parse_entry(attr, info, false, &addr);
190 [ + - ]: 28 : if (ret < 0)
191 : : return ret;
192 : :
193 : 28 : msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
194 [ + - ]: 28 : if (!msg)
195 : : return -ENOMEM;
196 : :
197 : 28 : reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0,
198 : 28 : info->genlhdr->cmd);
199 [ - + ]: 28 : if (!reply) {
200 [ # # ]: 0 : GENL_SET_ERR_MSG(info, "not enough space in Netlink message");
201 : 0 : ret = -EMSGSIZE;
202 : 0 : goto fail;
203 : : }
204 : :
205 : 28 : ret = mptcp_pm_get_addr(addr.addr.id, &addr, info);
206 [ + + ]: 28 : if (ret) {
207 [ + - ]: 6 : NL_SET_ERR_MSG_ATTR(info->extack, attr, "address not found");
208 : 6 : goto fail;
209 : : }
210 : :
211 : 22 : ret = mptcp_nl_fill_addr(msg, &addr);
212 [ - + ]: 22 : if (ret)
213 : 0 : goto fail;
214 : :
215 : 22 : genlmsg_end(msg, reply);
216 : 22 : ret = genlmsg_reply(msg, info);
217 : 22 : return ret;
218 : :
219 : 6 : fail:
220 : 6 : nlmsg_free(msg);
221 : 6 : return ret;
222 : : }
223 : :
224 : 182 : int mptcp_pm_genl_fill_addr(struct sk_buff *msg,
225 : : struct netlink_callback *cb,
226 : : struct mptcp_pm_addr_entry *entry)
227 : : {
228 : 182 : void *hdr;
229 : :
230 : 182 : hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
231 : 182 : cb->nlh->nlmsg_seq, &mptcp_genl_family,
232 : : NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR);
233 [ - + ]: 182 : if (!hdr)
234 : : return -EINVAL;
235 : :
236 [ - + ]: 182 : if (mptcp_nl_fill_addr(msg, entry) < 0) {
237 : 0 : genlmsg_cancel(msg, hdr);
238 : 0 : return -EINVAL;
239 : : }
240 : :
241 : 182 : genlmsg_end(msg, hdr);
242 : 182 : return 0;
243 : : }
244 : :
245 : 236 : static int mptcp_pm_dump_addr(struct sk_buff *msg, struct netlink_callback *cb)
246 : : {
247 [ + + ]: 236 : const struct genl_info *info = genl_info_dump(cb);
248 : :
249 [ + + ]: 236 : if (info->attrs[MPTCP_PM_ATTR_TOKEN])
250 : 20 : return mptcp_userspace_pm_dump_addr(msg, cb);
251 : 216 : return mptcp_pm_nl_dump_addr(msg, cb);
252 : : }
253 : :
254 : 236 : int mptcp_pm_nl_get_addr_dumpit(struct sk_buff *msg,
255 : : struct netlink_callback *cb)
256 : : {
257 : 236 : return mptcp_pm_dump_addr(msg, cb);
258 : : }
259 : :
260 : 48 : static int mptcp_pm_set_flags(struct genl_info *info)
261 : : {
262 : 48 : struct mptcp_pm_addr_entry loc = { .addr = { .family = AF_UNSPEC }, };
263 : 48 : struct nlattr *attr_loc;
264 : 48 : int ret = -EINVAL;
265 : :
266 [ + - - - ]: 48 : if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR))
267 : 0 : return ret;
268 : :
269 : 48 : attr_loc = info->attrs[MPTCP_PM_ATTR_ADDR];
270 : 48 : ret = mptcp_pm_parse_entry(attr_loc, info, false, &loc);
271 [ + - ]: 48 : if (ret < 0)
272 : : return ret;
273 : :
274 [ + + ]: 48 : if (info->attrs[MPTCP_PM_ATTR_TOKEN])
275 : 2 : return mptcp_userspace_pm_set_flags(&loc, info);
276 : 46 : return mptcp_pm_nl_set_flags(&loc, info);
277 : : }
278 : :
279 : 48 : int mptcp_pm_nl_set_flags_doit(struct sk_buff *skb, struct genl_info *info)
280 : : {
281 : 48 : return mptcp_pm_set_flags(info);
282 : : }
283 : :
284 : 428 : static void mptcp_nl_mcast_send(struct net *net, struct sk_buff *nlskb, gfp_t gfp)
285 : : {
286 : 428 : genlmsg_multicast_netns(&mptcp_genl_family, net,
287 : : nlskb, 0, MPTCP_PM_EV_GRP_OFFSET, gfp);
288 : 428 : }
289 : :
290 : 78 : bool mptcp_userspace_pm_active(const struct mptcp_sock *msk)
291 : : {
292 : 78 : return genl_has_listeners(&mptcp_genl_family,
293 : : sock_net((const struct sock *)msk),
294 : : MPTCP_PM_EV_GRP_OFFSET);
295 : : }
296 : :
297 : 268 : static int mptcp_event_add_subflow(struct sk_buff *skb, const struct sock *ssk)
298 : : {
299 : 268 : const struct inet_sock *issk = inet_sk(ssk);
300 : 268 : const struct mptcp_subflow_context *sf;
301 : :
302 [ - + ]: 268 : if (nla_put_u16(skb, MPTCP_ATTR_FAMILY, ssk->sk_family))
303 : : return -EMSGSIZE;
304 : :
305 [ + + - ]: 268 : switch (ssk->sk_family) {
306 : 150 : case AF_INET:
307 [ - + ]: 150 : if (nla_put_in_addr(skb, MPTCP_ATTR_SADDR4, issk->inet_saddr))
308 : : return -EMSGSIZE;
309 [ - + ]: 150 : if (nla_put_in_addr(skb, MPTCP_ATTR_DADDR4, issk->inet_daddr))
310 : : return -EMSGSIZE;
311 : : break;
312 : : #if IS_ENABLED(CONFIG_MPTCP_IPV6)
313 : 118 : case AF_INET6: {
314 [ - + ]: 118 : if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &issk->pinet6->saddr))
315 : : return -EMSGSIZE;
316 [ - + ]: 118 : if (nla_put_in6_addr(skb, MPTCP_ATTR_DADDR6, &ssk->sk_v6_daddr))
317 : : return -EMSGSIZE;
318 : : break;
319 : : }
320 : : #endif
321 : : default:
322 : 0 : WARN_ON_ONCE(1);
323 : 0 : return -EMSGSIZE;
324 : : }
325 : :
326 [ - + ]: 268 : if (nla_put_be16(skb, MPTCP_ATTR_SPORT, issk->inet_sport))
327 : : return -EMSGSIZE;
328 [ - + ]: 268 : if (nla_put_be16(skb, MPTCP_ATTR_DPORT, issk->inet_dport))
329 : : return -EMSGSIZE;
330 : :
331 [ - + ]: 268 : sf = mptcp_subflow_ctx(ssk);
332 [ - + ]: 268 : if (WARN_ON_ONCE(!sf))
333 : 0 : return -EINVAL;
334 : :
335 [ - + ]: 268 : if (nla_put_u8(skb, MPTCP_ATTR_LOC_ID, subflow_get_local_id(sf)))
336 : : return -EMSGSIZE;
337 : :
338 [ - + ]: 268 : if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, sf->remote_id))
339 : : return -EMSGSIZE;
340 : :
341 : : return 0;
342 : : }
343 : :
344 : 188 : static int mptcp_event_put_token_and_ssk(struct sk_buff *skb,
345 : : const struct mptcp_sock *msk,
346 : : const struct sock *ssk)
347 : : {
348 : 188 : const struct sock *sk = (const struct sock *)msk;
349 : 188 : const struct mptcp_subflow_context *sf;
350 : 188 : u8 sk_err;
351 : :
352 [ - + ]: 188 : if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)))
353 : : return -EMSGSIZE;
354 : :
355 [ - + ]: 188 : if (mptcp_event_add_subflow(skb, ssk))
356 : : return -EMSGSIZE;
357 : :
358 [ - + ]: 188 : sf = mptcp_subflow_ctx(ssk);
359 [ - + ]: 188 : if (WARN_ON_ONCE(!sf))
360 : 0 : return -EINVAL;
361 : :
362 [ - + ]: 188 : if (nla_put_u8(skb, MPTCP_ATTR_BACKUP, sf->backup))
363 : : return -EMSGSIZE;
364 : :
365 [ + + - + ]: 204 : if (ssk->sk_bound_dev_if &&
366 [ # # ]: 0 : nla_put_s32(skb, MPTCP_ATTR_IF_IDX, ssk->sk_bound_dev_if))
367 : : return -EMSGSIZE;
368 : :
369 : 188 : sk_err = READ_ONCE(ssk->sk_err);
370 [ - + - - : 188 : if (sk_err && sk->sk_state == TCP_ESTABLISHED &&
- - ]
371 [ # # ]: 0 : nla_put_u8(skb, MPTCP_ATTR_ERROR, sk_err))
372 : : return -EMSGSIZE;
373 : :
374 : : return 0;
375 : : }
376 : :
377 : 0 : static int mptcp_event_sub_established(struct sk_buff *skb,
378 : : const struct mptcp_sock *msk,
379 : : const struct sock *ssk)
380 : : {
381 : 106 : return mptcp_event_put_token_and_ssk(skb, msk, ssk);
382 : : }
383 : :
384 : 82 : static int mptcp_event_sub_closed(struct sk_buff *skb,
385 : : const struct mptcp_sock *msk,
386 : : const struct sock *ssk)
387 : : {
388 : 82 : const struct mptcp_subflow_context *sf;
389 : :
390 [ - + ]: 82 : if (mptcp_event_put_token_and_ssk(skb, msk, ssk))
391 : : return -EMSGSIZE;
392 : :
393 [ + - ]: 82 : sf = mptcp_subflow_ctx(ssk);
394 [ + - ]: 82 : if (!sf->reset_seen)
395 : : return 0;
396 : :
397 [ # # ]: 0 : if (nla_put_u32(skb, MPTCP_ATTR_RESET_REASON, sf->reset_reason))
398 : : return -EMSGSIZE;
399 : :
400 [ # # ]: 0 : if (nla_put_u32(skb, MPTCP_ATTR_RESET_FLAGS, sf->reset_transient))
401 : : return -EMSGSIZE;
402 : :
403 : : return 0;
404 : : }
405 : :
406 : 80 : static int mptcp_event_created(struct sk_buff *skb,
407 : : const struct mptcp_sock *msk,
408 : : const struct sock *ssk)
409 : : {
410 : 80 : int err = nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token));
411 : :
412 [ + - ]: 80 : if (err)
413 : : return err;
414 : :
415 [ + + + - ]: 120 : if (nla_put_u8(skb, MPTCP_ATTR_SERVER_SIDE, READ_ONCE(msk->pm.server_side)))
416 : : return -EMSGSIZE;
417 : :
418 : 80 : return mptcp_event_add_subflow(skb, ssk);
419 : : }
420 : :
421 : 114 : void mptcp_event_addr_removed(const struct mptcp_sock *msk, uint8_t id)
422 : : {
423 : 114 : struct net *net = sock_net((const struct sock *)msk);
424 : 114 : struct nlmsghdr *nlh;
425 : 114 : struct sk_buff *skb;
426 : :
427 [ + + ]: 114 : if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
428 : : return;
429 : :
430 : 48 : skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
431 [ + - ]: 48 : if (!skb)
432 : : return;
433 : :
434 : 48 : nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, MPTCP_EVENT_REMOVED);
435 [ - + ]: 48 : if (!nlh)
436 : 0 : goto nla_put_failure;
437 : :
438 [ - + ]: 48 : if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)))
439 : 0 : goto nla_put_failure;
440 : :
441 [ - + ]: 48 : if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, id))
442 : 0 : goto nla_put_failure;
443 : :
444 : 48 : genlmsg_end(skb, nlh);
445 : 48 : mptcp_nl_mcast_send(net, skb, GFP_ATOMIC);
446 : 48 : return;
447 : :
448 : 0 : nla_put_failure:
449 : 0 : nlmsg_free(skb);
450 : : }
451 : :
452 : 366 : void mptcp_event_addr_announced(const struct sock *ssk,
453 : : const struct mptcp_addr_info *info)
454 : : {
455 [ - + ]: 366 : struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
456 [ - + ]: 366 : struct mptcp_sock *msk = mptcp_sk(subflow->conn);
457 : 366 : struct net *net = sock_net(ssk);
458 : 366 : struct nlmsghdr *nlh;
459 : 366 : struct sk_buff *skb;
460 : :
461 [ + + ]: 366 : if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
462 : : return;
463 : :
464 : 48 : skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
465 [ + - ]: 48 : if (!skb)
466 : : return;
467 : :
468 : 48 : nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0,
469 : : MPTCP_EVENT_ANNOUNCED);
470 [ - + ]: 48 : if (!nlh)
471 : 0 : goto nla_put_failure;
472 : :
473 [ - + ]: 48 : if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)))
474 : 0 : goto nla_put_failure;
475 : :
476 [ - + ]: 48 : if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, info->id))
477 : 0 : goto nla_put_failure;
478 : :
479 [ - + ]: 48 : if (nla_put_be16(skb, MPTCP_ATTR_DPORT,
480 [ + + ]: 48 : info->port == 0 ?
481 : 38 : inet_sk(ssk)->inet_dport :
482 : : info->port))
483 : 0 : goto nla_put_failure;
484 : :
485 [ + + - ]: 48 : switch (info->family) {
486 : 40 : case AF_INET:
487 [ - + ]: 40 : if (nla_put_in_addr(skb, MPTCP_ATTR_DADDR4, info->addr.s_addr))
488 : 0 : goto nla_put_failure;
489 : : break;
490 : : #if IS_ENABLED(CONFIG_MPTCP_IPV6)
491 : 8 : case AF_INET6:
492 [ - + ]: 8 : if (nla_put_in6_addr(skb, MPTCP_ATTR_DADDR6, &info->addr6))
493 : 0 : goto nla_put_failure;
494 : : break;
495 : : #endif
496 : : default:
497 : 0 : WARN_ON_ONCE(1);
498 : 0 : goto nla_put_failure;
499 : : }
500 : :
501 : 48 : genlmsg_end(skb, nlh);
502 : 48 : mptcp_nl_mcast_send(net, skb, GFP_ATOMIC);
503 : 48 : return;
504 : :
505 : 0 : nla_put_failure:
506 : 0 : nlmsg_free(skb);
507 : : }
508 : :
509 : 2522 : void mptcp_event_pm_listener(const struct sock *ssk,
510 : : enum mptcp_event_type event)
511 : : {
512 : 2522 : const struct inet_sock *issk = inet_sk(ssk);
513 : 2522 : struct net *net = sock_net(ssk);
514 : 2522 : struct nlmsghdr *nlh;
515 : 2522 : struct sk_buff *skb;
516 : :
517 [ + + ]: 2522 : if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
518 : : return;
519 : :
520 : 52 : skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
521 [ + - ]: 52 : if (!skb)
522 : : return;
523 : :
524 : 52 : nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, event);
525 [ - + ]: 52 : if (!nlh)
526 : 0 : goto nla_put_failure;
527 : :
528 [ - + ]: 52 : if (nla_put_u16(skb, MPTCP_ATTR_FAMILY, ssk->sk_family))
529 : 0 : goto nla_put_failure;
530 : :
531 [ - + ]: 52 : if (nla_put_be16(skb, MPTCP_ATTR_SPORT, issk->inet_sport))
532 : 0 : goto nla_put_failure;
533 : :
534 [ + + - ]: 52 : switch (ssk->sk_family) {
535 : 26 : case AF_INET:
536 [ - + ]: 26 : if (nla_put_in_addr(skb, MPTCP_ATTR_SADDR4, issk->inet_saddr))
537 : 0 : goto nla_put_failure;
538 : : break;
539 : : #if IS_ENABLED(CONFIG_MPTCP_IPV6)
540 : 26 : case AF_INET6: {
541 [ - + ]: 26 : if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &issk->pinet6->saddr))
542 : 0 : goto nla_put_failure;
543 : : break;
544 : : }
545 : : #endif
546 : : default:
547 : 0 : WARN_ON_ONCE(1);
548 : 0 : goto nla_put_failure;
549 : : }
550 : :
551 : 52 : genlmsg_end(skb, nlh);
552 : 52 : mptcp_nl_mcast_send(net, skb, GFP_KERNEL);
553 : 52 : return;
554 : :
555 : 0 : nla_put_failure:
556 : 0 : nlmsg_free(skb);
557 : : }
558 : :
559 : 8190 : void mptcp_event(enum mptcp_event_type type, const struct mptcp_sock *msk,
560 : : const struct sock *ssk, gfp_t gfp)
561 : : {
562 : 8190 : struct net *net = sock_net((const struct sock *)msk);
563 : 8190 : struct nlmsghdr *nlh;
564 : 8190 : struct sk_buff *skb;
565 : :
566 [ + + ]: 8190 : if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
567 : : return;
568 : :
569 : 280 : skb = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
570 [ + - ]: 280 : if (!skb)
571 : : return;
572 : :
573 : 280 : nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, type);
574 [ - + ]: 280 : if (!nlh)
575 : 0 : goto nla_put_failure;
576 : :
577 [ - + + - : 280 : switch (type) {
+ + - ]
578 : : case MPTCP_EVENT_UNSPEC:
579 : 0 : WARN_ON_ONCE(1);
580 : 0 : break;
581 : 80 : case MPTCP_EVENT_CREATED:
582 : : case MPTCP_EVENT_ESTABLISHED:
583 [ - + ]: 80 : if (mptcp_event_created(skb, msk, ssk) < 0)
584 : 0 : goto nla_put_failure;
585 : : break;
586 : : case MPTCP_EVENT_CLOSED:
587 [ - + ]: 12 : if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)) < 0)
588 : 0 : goto nla_put_failure;
589 : : break;
590 : : case MPTCP_EVENT_ANNOUNCED:
591 : : case MPTCP_EVENT_REMOVED:
592 : : /* call mptcp_event_addr_announced()/removed instead */
593 : 0 : WARN_ON_ONCE(1);
594 : 0 : break;
595 : : case MPTCP_EVENT_SUB_ESTABLISHED:
596 : : case MPTCP_EVENT_SUB_PRIORITY:
597 [ - + ]: 106 : if (mptcp_event_sub_established(skb, msk, ssk) < 0)
598 : 0 : goto nla_put_failure;
599 : : break;
600 : 82 : case MPTCP_EVENT_SUB_CLOSED:
601 [ - + ]: 82 : if (mptcp_event_sub_closed(skb, msk, ssk) < 0)
602 : 0 : goto nla_put_failure;
603 : : break;
604 : : case MPTCP_EVENT_LISTENER_CREATED:
605 : : case MPTCP_EVENT_LISTENER_CLOSED:
606 : : break;
607 : : }
608 : :
609 : 280 : genlmsg_end(skb, nlh);
610 : 280 : mptcp_nl_mcast_send(net, skb, gfp);
611 : 280 : return;
612 : :
613 : 0 : nla_put_failure:
614 : 0 : nlmsg_free(skb);
615 : : }
616 : :
617 : : struct genl_family mptcp_genl_family __ro_after_init = {
618 : : .name = MPTCP_PM_NAME,
619 : : .version = MPTCP_PM_VER,
620 : : .netnsok = true,
621 : : .module = THIS_MODULE,
622 : : .ops = mptcp_pm_nl_ops,
623 : : .n_ops = ARRAY_SIZE(mptcp_pm_nl_ops),
624 : : .resv_start_op = MPTCP_PM_CMD_SUBFLOW_DESTROY + 1,
625 : : .mcgrps = mptcp_pm_mcgrps,
626 : : .n_mcgrps = ARRAY_SIZE(mptcp_pm_mcgrps),
627 : : };
628 : :
629 : 4 : void __init mptcp_pm_nl_init(void)
630 : : {
631 [ - + ]: 4 : if (genl_register_family(&mptcp_genl_family))
632 : 0 : panic("Failed to register MPTCP PM netlink family\n");
633 : 4 : }
|