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