1 // SPDX-License-Identifier: GPL-2.0
2 /* Multipath TCP
3 *
4 * Copyright (c) 2022, Intel Corporation.
5 */
6
7 #include "protocol.h"
8 #include "mib.h"
9 #include "mptcp_pm_gen.h"
10
11 #define mptcp_for_each_userspace_pm_addr(__msk, __entry) \
12 list_for_each_entry(__entry, \
13 &((__msk)->pm.userspace_pm_local_addr_list), list)
14
mptcp_userspace_pm_free_local_addr_list(struct mptcp_sock * msk)15 void mptcp_userspace_pm_free_local_addr_list(struct mptcp_sock *msk)
16 {
17 struct mptcp_pm_addr_entry *entry, *tmp;
18 struct sock *sk = (struct sock *)msk;
19 LIST_HEAD(free_list);
20
21 spin_lock_bh(&msk->pm.lock);
22 list_splice_init(&msk->pm.userspace_pm_local_addr_list, &free_list);
23 spin_unlock_bh(&msk->pm.lock);
24
25 list_for_each_entry_safe(entry, tmp, &free_list, list) {
26 sock_kfree_s(sk, entry, sizeof(*entry));
27 }
28 }
29
30 static struct mptcp_pm_addr_entry *
mptcp_userspace_pm_lookup_addr(struct mptcp_sock * msk,const struct mptcp_addr_info * addr)31 mptcp_userspace_pm_lookup_addr(struct mptcp_sock *msk,
32 const struct mptcp_addr_info *addr)
33 {
34 struct mptcp_pm_addr_entry *entry;
35
36 mptcp_for_each_userspace_pm_addr(msk, entry) {
37 if (mptcp_addresses_equal(&entry->addr, addr, false))
38 return entry;
39 }
40 return NULL;
41 }
42
mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock * msk,struct mptcp_pm_addr_entry * entry,bool needs_id)43 static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
44 struct mptcp_pm_addr_entry *entry,
45 bool needs_id)
46 {
47 DECLARE_BITMAP(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
48 struct sock *sk = (struct sock *)msk;
49 struct mptcp_pm_addr_entry *e;
50 bool addr_match = false;
51 bool id_match = false;
52 int ret = -EINVAL;
53
54 bitmap_zero(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
55
56 spin_lock_bh(&msk->pm.lock);
57 mptcp_for_each_userspace_pm_addr(msk, e) {
58 addr_match = mptcp_addresses_equal(&e->addr, &entry->addr, true);
59 if (addr_match && entry->addr.id == 0 && needs_id)
60 entry->addr.id = e->addr.id;
61 id_match = (e->addr.id == entry->addr.id);
62 if (addr_match || id_match)
63 break;
64 __set_bit(e->addr.id, id_bitmap);
65 }
66
67 if (!addr_match && !id_match) {
68 /* Memory for the entry is allocated from the
69 * sock option buffer.
70 */
71 e = sock_kmemdup(sk, entry, sizeof(*entry), GFP_ATOMIC);
72 if (!e) {
73 ret = -ENOMEM;
74 goto append_err;
75 }
76
77 if (!e->addr.id && needs_id)
78 e->addr.id = find_next_zero_bit(id_bitmap,
79 MPTCP_PM_MAX_ADDR_ID + 1,
80 1);
81 list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list);
82 msk->pm.local_addr_used++;
83 ret = e->addr.id;
84 } else if (addr_match && id_match) {
85 ret = entry->addr.id;
86 }
87
88 append_err:
89 spin_unlock_bh(&msk->pm.lock);
90 return ret;
91 }
92
93 /* If the subflow is closed from the other peer (not via a
94 * subflow destroy command then), we want to keep the entry
95 * not to assign the same ID to another address and to be
96 * able to send RM_ADDR after the removal of the subflow.
97 */
mptcp_userspace_pm_delete_local_addr(struct mptcp_sock * msk,struct mptcp_pm_addr_entry * addr)98 static int mptcp_userspace_pm_delete_local_addr(struct mptcp_sock *msk,
99 struct mptcp_pm_addr_entry *addr)
100 {
101 struct sock *sk = (struct sock *)msk;
102 struct mptcp_pm_addr_entry *entry;
103
104 entry = mptcp_userspace_pm_lookup_addr(msk, &addr->addr);
105 if (!entry)
106 return -EINVAL;
107
108 /* TODO: a refcount is needed because the entry can
109 * be used multiple times (e.g. fullmesh mode).
110 */
111 list_del_rcu(&entry->list);
112 sock_kfree_s(sk, entry, sizeof(*entry));
113 msk->pm.local_addr_used--;
114 return 0;
115 }
116
117 static struct mptcp_pm_addr_entry *
mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock * msk,unsigned int id)118 mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id)
119 {
120 struct mptcp_pm_addr_entry *entry;
121
122 mptcp_for_each_userspace_pm_addr(msk, entry) {
123 if (entry->addr.id == id)
124 return entry;
125 }
126 return NULL;
127 }
128
mptcp_userspace_pm_get_local_id(struct mptcp_sock * msk,struct mptcp_pm_addr_entry * skc)129 int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
130 struct mptcp_pm_addr_entry *skc)
131 {
132 __be16 msk_sport = ((struct inet_sock *)
133 inet_sk((struct sock *)msk))->inet_sport;
134 struct mptcp_pm_addr_entry *entry;
135
136 spin_lock_bh(&msk->pm.lock);
137 entry = mptcp_userspace_pm_lookup_addr(msk, &skc->addr);
138 spin_unlock_bh(&msk->pm.lock);
139 if (entry)
140 return entry->addr.id;
141
142 if (skc->addr.port == msk_sport)
143 skc->addr.port = 0;
144
145 return mptcp_userspace_pm_append_new_local_addr(msk, skc, true);
146 }
147
mptcp_userspace_pm_is_backup(struct mptcp_sock * msk,struct mptcp_addr_info * skc)148 bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
149 struct mptcp_addr_info *skc)
150 {
151 struct mptcp_pm_addr_entry *entry;
152 bool backup;
153
154 spin_lock_bh(&msk->pm.lock);
155 entry = mptcp_userspace_pm_lookup_addr(msk, skc);
156 backup = entry && !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
157 spin_unlock_bh(&msk->pm.lock);
158
159 return backup;
160 }
161
mptcp_userspace_pm_get_sock(const struct genl_info * info)162 static struct mptcp_sock *mptcp_userspace_pm_get_sock(const struct genl_info *info)
163 {
164 struct mptcp_sock *msk;
165 struct nlattr *token;
166
167 if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_TOKEN))
168 return NULL;
169
170 token = info->attrs[MPTCP_PM_ATTR_TOKEN];
171 msk = mptcp_token_get_sock(genl_info_net(info), nla_get_u32(token));
172 if (!msk) {
173 NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
174 return NULL;
175 }
176
177 if (!mptcp_pm_is_userspace(msk)) {
178 NL_SET_ERR_MSG_ATTR(info->extack, token,
179 "userspace PM not selected");
180 sock_put((struct sock *)msk);
181 return NULL;
182 }
183
184 return msk;
185 }
186
mptcp_pm_nl_announce_doit(struct sk_buff * skb,struct genl_info * info)187 int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
188 {
189 struct mptcp_pm_addr_entry addr_val;
190 struct mptcp_sock *msk;
191 struct nlattr *addr;
192 int err = -EINVAL;
193 struct sock *sk;
194
195 if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR))
196 return err;
197
198 msk = mptcp_userspace_pm_get_sock(info);
199 if (!msk)
200 return err;
201
202 sk = (struct sock *)msk;
203
204 addr = info->attrs[MPTCP_PM_ATTR_ADDR];
205 err = mptcp_pm_parse_entry(addr, info, true, &addr_val);
206 if (err < 0)
207 goto announce_err;
208
209 if (addr_val.addr.id == 0) {
210 NL_SET_ERR_MSG_ATTR(info->extack, addr, "invalid addr id");
211 err = -EINVAL;
212 goto announce_err;
213 }
214
215 if (!(addr_val.flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) {
216 NL_SET_ERR_MSG_ATTR(info->extack, addr, "invalid addr flags");
217 err = -EINVAL;
218 goto announce_err;
219 }
220
221 err = mptcp_userspace_pm_append_new_local_addr(msk, &addr_val, false);
222 if (err < 0) {
223 NL_SET_ERR_MSG_ATTR(info->extack, addr,
224 "did not match address and id");
225 goto announce_err;
226 }
227
228 lock_sock(sk);
229 spin_lock_bh(&msk->pm.lock);
230
231 if (mptcp_pm_alloc_anno_list(msk, &addr_val.addr)) {
232 msk->pm.add_addr_signaled++;
233 mptcp_pm_announce_addr(msk, &addr_val.addr, false);
234 mptcp_pm_addr_send_ack(msk);
235 }
236
237 spin_unlock_bh(&msk->pm.lock);
238 release_sock(sk);
239
240 err = 0;
241 announce_err:
242 sock_put(sk);
243 return err;
244 }
245
mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock * msk)246 static int mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock *msk)
247 {
248 struct mptcp_rm_list list = { .nr = 0 };
249 struct mptcp_subflow_context *subflow;
250 struct sock *sk = (struct sock *)msk;
251 bool has_id_0 = false;
252 int err = -EINVAL;
253
254 lock_sock(sk);
255 mptcp_for_each_subflow(msk, subflow) {
256 if (READ_ONCE(subflow->local_id) == 0) {
257 has_id_0 = true;
258 break;
259 }
260 }
261 if (!has_id_0)
262 goto remove_err;
263
264 list.ids[list.nr++] = 0;
265
266 spin_lock_bh(&msk->pm.lock);
267 mptcp_pm_remove_addr(msk, &list);
268 spin_unlock_bh(&msk->pm.lock);
269
270 err = 0;
271
272 remove_err:
273 release_sock(sk);
274 return err;
275 }
276
mptcp_pm_remove_addr_entry(struct mptcp_sock * msk,struct mptcp_pm_addr_entry * entry)277 void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
278 struct mptcp_pm_addr_entry *entry)
279 {
280 struct mptcp_rm_list alist = { .nr = 0 };
281 int anno_nr = 0;
282
283 /* only delete if either announced or matching a subflow */
284 if (mptcp_remove_anno_list_by_saddr(msk, &entry->addr))
285 anno_nr++;
286 else if (!mptcp_lookup_subflow_by_saddr(&msk->conn_list, &entry->addr))
287 return;
288
289 alist.ids[alist.nr++] = entry->addr.id;
290
291 spin_lock_bh(&msk->pm.lock);
292 msk->pm.add_addr_signaled -= anno_nr;
293 mptcp_pm_remove_addr(msk, &alist);
294 spin_unlock_bh(&msk->pm.lock);
295 }
296
mptcp_pm_nl_remove_doit(struct sk_buff * skb,struct genl_info * info)297 int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
298 {
299 struct mptcp_pm_addr_entry *match;
300 struct mptcp_sock *msk;
301 struct nlattr *id;
302 int err = -EINVAL;
303 struct sock *sk;
304 u8 id_val;
305
306 if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_LOC_ID))
307 return err;
308
309 id = info->attrs[MPTCP_PM_ATTR_LOC_ID];
310 id_val = nla_get_u8(id);
311
312 msk = mptcp_userspace_pm_get_sock(info);
313 if (!msk)
314 return err;
315
316 sk = (struct sock *)msk;
317
318 if (id_val == 0) {
319 err = mptcp_userspace_pm_remove_id_zero_address(msk);
320 goto out;
321 }
322
323 lock_sock(sk);
324
325 spin_lock_bh(&msk->pm.lock);
326 match = mptcp_userspace_pm_lookup_addr_by_id(msk, id_val);
327 if (!match) {
328 spin_unlock_bh(&msk->pm.lock);
329 release_sock(sk);
330 goto out;
331 }
332
333 list_del_rcu(&match->list);
334 spin_unlock_bh(&msk->pm.lock);
335
336 mptcp_pm_remove_addr_entry(msk, match);
337
338 release_sock(sk);
339
340 kfree_rcu_mightsleep(match);
341 /* Adjust sk_omem_alloc like sock_kfree_s() does, to match
342 * with allocation of this memory by sock_kmemdup()
343 */
344 atomic_sub(sizeof(*match), &sk->sk_omem_alloc);
345
346 err = 0;
347 out:
348 if (err)
349 NL_SET_ERR_MSG_ATTR_FMT(info->extack, id,
350 "address with id %u not found",
351 id_val);
352
353 sock_put(sk);
354 return err;
355 }
356
mptcp_pm_nl_subflow_create_doit(struct sk_buff * skb,struct genl_info * info)357 int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
358 {
359 struct mptcp_pm_addr_entry entry = { 0 };
360 struct mptcp_addr_info addr_r;
361 struct nlattr *raddr, *laddr;
362 struct mptcp_pm_local local;
363 struct mptcp_sock *msk;
364 int err = -EINVAL;
365 struct sock *sk;
366
367 if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR) ||
368 GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR_REMOTE))
369 return err;
370
371 msk = mptcp_userspace_pm_get_sock(info);
372 if (!msk)
373 return err;
374
375 sk = (struct sock *)msk;
376
377 laddr = info->attrs[MPTCP_PM_ATTR_ADDR];
378 err = mptcp_pm_parse_entry(laddr, info, true, &entry);
379 if (err < 0)
380 goto create_err;
381
382 if (entry.flags & MPTCP_PM_ADDR_FLAG_SIGNAL) {
383 NL_SET_ERR_MSG_ATTR(info->extack, laddr, "invalid addr flags");
384 err = -EINVAL;
385 goto create_err;
386 }
387 entry.flags |= MPTCP_PM_ADDR_FLAG_SUBFLOW;
388
389 raddr = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
390 err = mptcp_pm_parse_addr(raddr, info, &addr_r);
391 if (err < 0)
392 goto create_err;
393
394 if (!mptcp_pm_addr_families_match(sk, &entry.addr, &addr_r)) {
395 GENL_SET_ERR_MSG(info, "families mismatch");
396 err = -EINVAL;
397 goto create_err;
398 }
399
400 err = mptcp_userspace_pm_append_new_local_addr(msk, &entry, false);
401 if (err < 0) {
402 NL_SET_ERR_MSG_ATTR(info->extack, laddr,
403 "did not match address and id");
404 goto create_err;
405 }
406
407 local.addr = entry.addr;
408 local.flags = entry.flags;
409 local.ifindex = entry.ifindex;
410
411 spin_lock_bh(&msk->pm.lock);
412 msk->pm.extra_subflows++;
413 spin_unlock_bh(&msk->pm.lock);
414
415 lock_sock(sk);
416 err = __mptcp_subflow_connect(sk, &local, &addr_r);
417 release_sock(sk);
418
419 if (err) {
420 GENL_SET_ERR_MSG_FMT(info, "connect error: %d", err);
421
422 spin_lock_bh(&msk->pm.lock);
423 mptcp_userspace_pm_delete_local_addr(msk, &entry);
424 spin_unlock_bh(&msk->pm.lock);
425 }
426
427 create_err:
428 sock_put(sk);
429 return err;
430 }
431
mptcp_nl_find_ssk(struct mptcp_sock * msk,const struct mptcp_addr_info * local,const struct mptcp_addr_info * remote)432 static struct sock *mptcp_nl_find_ssk(struct mptcp_sock *msk,
433 const struct mptcp_addr_info *local,
434 const struct mptcp_addr_info *remote)
435 {
436 struct mptcp_subflow_context *subflow;
437
438 if (local->family != remote->family)
439 return NULL;
440
441 mptcp_for_each_subflow(msk, subflow) {
442 const struct inet_sock *issk;
443 struct sock *ssk;
444
445 ssk = mptcp_subflow_tcp_sock(subflow);
446
447 if (local->family != ssk->sk_family)
448 continue;
449
450 issk = inet_sk(ssk);
451
452 switch (ssk->sk_family) {
453 case AF_INET:
454 if (issk->inet_saddr != local->addr.s_addr ||
455 issk->inet_daddr != remote->addr.s_addr)
456 continue;
457 break;
458 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
459 case AF_INET6: {
460 if (!ipv6_addr_equal(&local->addr6, &issk->pinet6->saddr) ||
461 !ipv6_addr_equal(&remote->addr6, &ssk->sk_v6_daddr))
462 continue;
463 break;
464 }
465 #endif
466 default:
467 continue;
468 }
469
470 if (issk->inet_sport == local->port &&
471 issk->inet_dport == remote->port)
472 return ssk;
473 }
474
475 return NULL;
476 }
477
mptcp_pm_nl_subflow_destroy_doit(struct sk_buff * skb,struct genl_info * info)478 int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info)
479 {
480 struct mptcp_pm_addr_entry addr_l;
481 struct mptcp_addr_info addr_r;
482 struct nlattr *raddr, *laddr;
483 struct mptcp_sock *msk;
484 struct sock *sk, *ssk;
485 int err = -EINVAL;
486
487 if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR) ||
488 GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR_REMOTE))
489 return err;
490
491 msk = mptcp_userspace_pm_get_sock(info);
492 if (!msk)
493 return err;
494
495 sk = (struct sock *)msk;
496
497 laddr = info->attrs[MPTCP_PM_ATTR_ADDR];
498 err = mptcp_pm_parse_entry(laddr, info, true, &addr_l);
499 if (err < 0)
500 goto destroy_err;
501
502 raddr = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
503 err = mptcp_pm_parse_addr(raddr, info, &addr_r);
504 if (err < 0)
505 goto destroy_err;
506
507 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
508 if (addr_l.addr.family == AF_INET && ipv6_addr_v4mapped(&addr_r.addr6)) {
509 ipv6_addr_set_v4mapped(addr_l.addr.addr.s_addr, &addr_l.addr.addr6);
510 addr_l.addr.family = AF_INET6;
511 }
512 if (addr_r.family == AF_INET && ipv6_addr_v4mapped(&addr_l.addr.addr6)) {
513 ipv6_addr_set_v4mapped(addr_r.addr.s_addr, &addr_r.addr6);
514 addr_r.family = AF_INET6;
515 }
516 #endif
517 if (addr_l.addr.family != addr_r.family) {
518 GENL_SET_ERR_MSG(info, "address families do not match");
519 err = -EINVAL;
520 goto destroy_err;
521 }
522
523 if (!addr_l.addr.port) {
524 NL_SET_ERR_MSG_ATTR(info->extack, laddr, "missing local port");
525 err = -EINVAL;
526 goto destroy_err;
527 }
528
529 if (!addr_r.port) {
530 NL_SET_ERR_MSG_ATTR(info->extack, raddr, "missing remote port");
531 err = -EINVAL;
532 goto destroy_err;
533 }
534
535 lock_sock(sk);
536 ssk = mptcp_nl_find_ssk(msk, &addr_l.addr, &addr_r);
537 if (!ssk) {
538 GENL_SET_ERR_MSG(info, "subflow not found");
539 err = -ESRCH;
540 goto release_sock;
541 }
542
543 spin_lock_bh(&msk->pm.lock);
544 mptcp_userspace_pm_delete_local_addr(msk, &addr_l);
545 spin_unlock_bh(&msk->pm.lock);
546 mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN);
547 mptcp_close_ssk(sk, ssk, mptcp_subflow_ctx(ssk));
548 MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
549 release_sock:
550 release_sock(sk);
551
552 destroy_err:
553 sock_put(sk);
554 return err;
555 }
556
mptcp_userspace_pm_set_flags(struct mptcp_pm_addr_entry * local,struct genl_info * info)557 int mptcp_userspace_pm_set_flags(struct mptcp_pm_addr_entry *local,
558 struct genl_info *info)
559 {
560 struct mptcp_addr_info rem = { .family = AF_UNSPEC, };
561 struct mptcp_pm_addr_entry *entry;
562 struct nlattr *attr, *attr_rem;
563 struct mptcp_sock *msk;
564 int ret = -EINVAL;
565 struct sock *sk;
566 u8 bkup = 0;
567
568 if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR_REMOTE))
569 return ret;
570
571 msk = mptcp_userspace_pm_get_sock(info);
572 if (!msk)
573 return ret;
574
575 sk = (struct sock *)msk;
576
577 attr = info->attrs[MPTCP_PM_ATTR_ADDR];
578 if (local->addr.family == AF_UNSPEC) {
579 NL_SET_ERR_MSG_ATTR(info->extack, attr,
580 "invalid local address family");
581 ret = -EINVAL;
582 goto set_flags_err;
583 }
584
585 attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
586 ret = mptcp_pm_parse_addr(attr_rem, info, &rem);
587 if (ret < 0)
588 goto set_flags_err;
589
590 if (rem.family == AF_UNSPEC) {
591 NL_SET_ERR_MSG_ATTR(info->extack, attr_rem,
592 "invalid remote address family");
593 ret = -EINVAL;
594 goto set_flags_err;
595 }
596
597 if (local->flags & MPTCP_PM_ADDR_FLAG_BACKUP)
598 bkup = 1;
599
600 spin_lock_bh(&msk->pm.lock);
601 entry = mptcp_userspace_pm_lookup_addr(msk, &local->addr);
602 if (entry) {
603 if (bkup)
604 entry->flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
605 else
606 entry->flags &= ~MPTCP_PM_ADDR_FLAG_BACKUP;
607 }
608 spin_unlock_bh(&msk->pm.lock);
609
610 lock_sock(sk);
611 ret = mptcp_pm_mp_prio_send_ack(msk, &local->addr, &rem, bkup);
612 release_sock(sk);
613
614 /* mptcp_pm_mp_prio_send_ack() only fails in one case */
615 if (ret < 0)
616 GENL_SET_ERR_MSG(info, "subflow not found");
617
618 set_flags_err:
619 sock_put(sk);
620 return ret;
621 }
622
mptcp_userspace_pm_dump_addr(struct sk_buff * msg,struct netlink_callback * cb)623 int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
624 struct netlink_callback *cb)
625 {
626 struct id_bitmap {
627 DECLARE_BITMAP(map, MPTCP_PM_MAX_ADDR_ID + 1);
628 } *bitmap;
629 const struct genl_info *info = genl_info_dump(cb);
630 struct mptcp_pm_addr_entry *entry;
631 struct mptcp_sock *msk;
632 int ret = -EINVAL;
633 struct sock *sk;
634
635 BUILD_BUG_ON(sizeof(struct id_bitmap) > sizeof(cb->ctx));
636
637 bitmap = (struct id_bitmap *)cb->ctx;
638
639 msk = mptcp_userspace_pm_get_sock(info);
640 if (!msk)
641 return ret;
642
643 sk = (struct sock *)msk;
644
645 lock_sock(sk);
646 spin_lock_bh(&msk->pm.lock);
647 mptcp_for_each_userspace_pm_addr(msk, entry) {
648 if (test_bit(entry->addr.id, bitmap->map))
649 continue;
650
651 if (mptcp_pm_genl_fill_addr(msg, cb, entry) < 0)
652 break;
653
654 __set_bit(entry->addr.id, bitmap->map);
655 }
656 spin_unlock_bh(&msk->pm.lock);
657 release_sock(sk);
658 ret = msg->len;
659
660 sock_put(sk);
661 return ret;
662 }
663
mptcp_userspace_pm_get_addr(u8 id,struct mptcp_pm_addr_entry * addr,struct genl_info * info)664 int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
665 struct genl_info *info)
666 {
667 struct mptcp_pm_addr_entry *entry;
668 struct mptcp_sock *msk;
669 int ret = -EINVAL;
670 struct sock *sk;
671
672 msk = mptcp_userspace_pm_get_sock(info);
673 if (!msk)
674 return ret;
675
676 sk = (struct sock *)msk;
677
678 lock_sock(sk);
679 spin_lock_bh(&msk->pm.lock);
680 entry = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
681 if (entry) {
682 *addr = *entry;
683 ret = 0;
684 }
685 spin_unlock_bh(&msk->pm.lock);
686 release_sock(sk);
687
688 sock_put(sk);
689 return ret;
690 }
691
692 static struct mptcp_pm_ops mptcp_pm_userspace = {
693 .name = "userspace",
694 .owner = THIS_MODULE,
695 };
696
mptcp_pm_userspace_register(void)697 void __init mptcp_pm_userspace_register(void)
698 {
699 mptcp_pm_register(&mptcp_pm_userspace);
700 }
701