xref: /linux/net/mptcp/pm_userspace.c (revision ddd664bbff63e09e7a7f9acae9c43605d4cf185f)
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