blob: f6f96bc2046bda8b913679dd807ef372f44e99e0 [file] [log] [blame]
Paolo Abeni01cacb02020-03-27 14:48:51 -07001// SPDX-License-Identifier: GPL-2.0
2/* Multipath TCP
3 *
4 * Copyright (c) 2020, Red Hat, Inc.
5 */
6
Geliang Tangc85adce2020-04-03 17:14:08 +08007#define pr_fmt(fmt) "MPTCP: " fmt
8
Paolo Abeni01cacb02020-03-27 14:48:51 -07009#include <linux/inet.h>
10#include <linux/kernel.h>
11#include <net/tcp.h>
12#include <net/netns/generic.h>
13#include <net/mptcp.h>
14#include <net/genetlink.h>
15#include <uapi/linux/mptcp.h>
16
17#include "protocol.h"
18
19/* forward declaration */
20static struct genl_family mptcp_genl_family;
21
22static int pm_nl_pernet_id;
23
24struct mptcp_pm_addr_entry {
25 struct list_head list;
Paolo Abeni01cacb02020-03-27 14:48:51 -070026 struct mptcp_addr_info addr;
27 struct rcu_head rcu;
28};
29
30struct pm_nl_pernet {
31 /* protects pernet updates */
32 spinlock_t lock;
33 struct list_head local_addr_list;
34 unsigned int addrs;
35 unsigned int add_addr_signal_max;
36 unsigned int add_addr_accept_max;
37 unsigned int local_addr_max;
38 unsigned int subflows_max;
39 unsigned int next_id;
40};
41
42#define MPTCP_PM_ADDR_MAX 8
43
44static bool addresses_equal(const struct mptcp_addr_info *a,
45 struct mptcp_addr_info *b, bool use_port)
46{
47 bool addr_equals = false;
48
49 if (a->family != b->family)
50 return false;
51
52 if (a->family == AF_INET)
53 addr_equals = a->addr.s_addr == b->addr.s_addr;
54#if IS_ENABLED(CONFIG_MPTCP_IPV6)
55 else
56 addr_equals = !ipv6_addr_cmp(&a->addr6, &b->addr6);
57#endif
58
59 if (!addr_equals)
60 return false;
61 if (!use_port)
62 return true;
63
64 return a->port == b->port;
65}
66
Geliang Tang57025812020-09-08 10:49:38 +080067static bool address_zero(const struct mptcp_addr_info *addr)
68{
69 struct mptcp_addr_info zero;
70
71 memset(&zero, 0, sizeof(zero));
72 zero.family = addr->family;
73
74 return addresses_equal(addr, &zero, false);
75}
76
Paolo Abeni01cacb02020-03-27 14:48:51 -070077static void local_address(const struct sock_common *skc,
78 struct mptcp_addr_info *addr)
79{
80 addr->port = 0;
81 addr->family = skc->skc_family;
82 if (addr->family == AF_INET)
83 addr->addr.s_addr = skc->skc_rcv_saddr;
84#if IS_ENABLED(CONFIG_MPTCP_IPV6)
85 else if (addr->family == AF_INET6)
86 addr->addr6 = skc->skc_v6_rcv_saddr;
87#endif
88}
89
90static void remote_address(const struct sock_common *skc,
91 struct mptcp_addr_info *addr)
92{
93 addr->family = skc->skc_family;
94 addr->port = skc->skc_dport;
95 if (addr->family == AF_INET)
96 addr->addr.s_addr = skc->skc_daddr;
97#if IS_ENABLED(CONFIG_MPTCP_IPV6)
98 else if (addr->family == AF_INET6)
99 addr->addr6 = skc->skc_v6_daddr;
100#endif
101}
102
103static bool lookup_subflow_by_saddr(const struct list_head *list,
104 struct mptcp_addr_info *saddr)
105{
106 struct mptcp_subflow_context *subflow;
107 struct mptcp_addr_info cur;
108 struct sock_common *skc;
109
110 list_for_each_entry(subflow, list, node) {
111 skc = (struct sock_common *)mptcp_subflow_tcp_sock(subflow);
112
113 local_address(skc, &cur);
114 if (addresses_equal(&cur, saddr, false))
115 return true;
116 }
117
118 return false;
119}
120
121static struct mptcp_pm_addr_entry *
122select_local_address(const struct pm_nl_pernet *pernet,
123 struct mptcp_sock *msk)
124{
125 struct mptcp_pm_addr_entry *entry, *ret = NULL;
126
127 rcu_read_lock();
128 spin_lock_bh(&msk->join_list_lock);
129 list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
Paolo Abenief0da3b2020-09-14 10:01:15 +0200130 if (!(entry->addr.flags & MPTCP_PM_ADDR_FLAG_SUBFLOW))
Paolo Abeni01cacb02020-03-27 14:48:51 -0700131 continue;
132
133 /* avoid any address already in use by subflows and
134 * pending join
135 */
136 if (entry->addr.family == ((struct sock *)msk)->sk_family &&
137 !lookup_subflow_by_saddr(&msk->conn_list, &entry->addr) &&
138 !lookup_subflow_by_saddr(&msk->join_list, &entry->addr)) {
139 ret = entry;
140 break;
141 }
142 }
143 spin_unlock_bh(&msk->join_list_lock);
144 rcu_read_unlock();
145 return ret;
146}
147
148static struct mptcp_pm_addr_entry *
149select_signal_address(struct pm_nl_pernet *pernet, unsigned int pos)
150{
151 struct mptcp_pm_addr_entry *entry, *ret = NULL;
152 int i = 0;
153
154 rcu_read_lock();
155 /* do not keep any additional per socket state, just signal
156 * the address list in order.
157 * Note: removal from the local address list during the msk life-cycle
158 * can lead to additional addresses not being announced.
159 */
160 list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
Paolo Abenief0da3b2020-09-14 10:01:15 +0200161 if (!(entry->addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
Paolo Abeni01cacb02020-03-27 14:48:51 -0700162 continue;
163 if (i++ == pos) {
164 ret = entry;
165 break;
166 }
167 }
168 rcu_read_unlock();
169 return ret;
170}
171
172static void check_work_pending(struct mptcp_sock *msk)
173{
174 if (msk->pm.add_addr_signaled == msk->pm.add_addr_signal_max &&
175 (msk->pm.local_addr_used == msk->pm.local_addr_max ||
176 msk->pm.subflows == msk->pm.subflows_max))
177 WRITE_ONCE(msk->pm.work_pending, false);
178}
179
180static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
181{
Geliang Tang2ff0e562020-09-08 10:49:39 +0800182 struct mptcp_addr_info remote = { 0 };
Paolo Abeni01cacb02020-03-27 14:48:51 -0700183 struct sock *sk = (struct sock *)msk;
184 struct mptcp_pm_addr_entry *local;
Paolo Abeni01cacb02020-03-27 14:48:51 -0700185 struct pm_nl_pernet *pernet;
186
187 pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);
188
189 pr_debug("local %d:%d signal %d:%d subflows %d:%d\n",
190 msk->pm.local_addr_used, msk->pm.local_addr_max,
191 msk->pm.add_addr_signaled, msk->pm.add_addr_signal_max,
192 msk->pm.subflows, msk->pm.subflows_max);
193
194 /* check first for announce */
195 if (msk->pm.add_addr_signaled < msk->pm.add_addr_signal_max) {
196 local = select_signal_address(pernet,
197 msk->pm.add_addr_signaled);
198
199 if (local) {
200 msk->pm.add_addr_signaled++;
Geliang Tang6a6c05a2020-09-24 08:29:50 +0800201 mptcp_pm_announce_addr(msk, &local->addr, false);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700202 } else {
203 /* pick failed, avoid fourther attempts later */
204 msk->pm.local_addr_used = msk->pm.add_addr_signal_max;
205 }
206
207 check_work_pending(msk);
208 }
209
210 /* check if should create a new subflow */
211 if (msk->pm.local_addr_used < msk->pm.local_addr_max &&
212 msk->pm.subflows < msk->pm.subflows_max) {
213 remote_address((struct sock_common *)sk, &remote);
214
215 local = select_local_address(pernet, msk);
216 if (local) {
217 msk->pm.local_addr_used++;
218 msk->pm.subflows++;
219 check_work_pending(msk);
220 spin_unlock_bh(&msk->pm.lock);
Paolo Abenief0da3b2020-09-14 10:01:15 +0200221 __mptcp_subflow_connect(sk, &local->addr, &remote);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700222 spin_lock_bh(&msk->pm.lock);
223 return;
224 }
225
226 /* lookup failed, avoid fourther attempts later */
227 msk->pm.local_addr_used = msk->pm.local_addr_max;
228 check_work_pending(msk);
229 }
230}
231
232void mptcp_pm_nl_fully_established(struct mptcp_sock *msk)
233{
234 mptcp_pm_create_subflow_or_signal_addr(msk);
235}
236
237void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk)
238{
239 mptcp_pm_create_subflow_or_signal_addr(msk);
240}
241
242void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
243{
244 struct sock *sk = (struct sock *)msk;
245 struct mptcp_addr_info remote;
246 struct mptcp_addr_info local;
247
248 pr_debug("accepted %d:%d remote family %d",
249 msk->pm.add_addr_accepted, msk->pm.add_addr_accept_max,
250 msk->pm.remote.family);
251 msk->pm.add_addr_accepted++;
252 msk->pm.subflows++;
253 if (msk->pm.add_addr_accepted >= msk->pm.add_addr_accept_max ||
254 msk->pm.subflows >= msk->pm.subflows_max)
255 WRITE_ONCE(msk->pm.accept_addr, false);
256
257 /* connect to the specified remote address, using whatever
258 * local address the routing configuration will pick.
259 */
260 remote = msk->pm.remote;
261 if (!remote.port)
262 remote.port = sk->sk_dport;
263 memset(&local, 0, sizeof(local));
264 local.family = remote.family;
265
266 spin_unlock_bh(&msk->pm.lock);
Paolo Abenief0da3b2020-09-14 10:01:15 +0200267 __mptcp_subflow_connect((struct sock *)msk, &local, &remote);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700268 spin_lock_bh(&msk->pm.lock);
Geliang Tang6a6c05a2020-09-24 08:29:50 +0800269
270 mptcp_pm_announce_addr(msk, &remote, true);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700271}
272
Geliang Tangd0876b22020-09-24 08:29:49 +0800273void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk)
274{
275 struct mptcp_subflow_context *subflow, *tmp;
276 struct sock *sk = (struct sock *)msk;
277
278 pr_debug("address rm_id %d", msk->pm.rm_id);
279
280 if (!msk->pm.rm_id)
281 return;
282
283 if (list_empty(&msk->conn_list))
284 return;
285
286 list_for_each_entry_safe(subflow, tmp, &msk->conn_list, node) {
287 struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
288 int how = RCV_SHUTDOWN | SEND_SHUTDOWN;
289 long timeout = 0;
290
291 if (msk->pm.rm_id != subflow->remote_id)
292 continue;
293
294 spin_unlock_bh(&msk->pm.lock);
295 mptcp_subflow_shutdown(sk, ssk, how);
296 __mptcp_close_ssk(sk, ssk, subflow, timeout);
297 spin_lock_bh(&msk->pm.lock);
298
299 msk->pm.add_addr_accepted--;
300 msk->pm.subflows--;
301 WRITE_ONCE(msk->pm.accept_addr, true);
302
303 break;
304 }
305}
306
Paolo Abeni01cacb02020-03-27 14:48:51 -0700307static bool address_use_port(struct mptcp_pm_addr_entry *entry)
308{
Paolo Abenief0da3b2020-09-14 10:01:15 +0200309 return (entry->addr.flags &
Paolo Abeni01cacb02020-03-27 14:48:51 -0700310 (MPTCP_PM_ADDR_FLAG_SIGNAL | MPTCP_PM_ADDR_FLAG_SUBFLOW)) ==
311 MPTCP_PM_ADDR_FLAG_SIGNAL;
312}
313
314static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
315 struct mptcp_pm_addr_entry *entry)
316{
317 struct mptcp_pm_addr_entry *cur;
318 int ret = -EINVAL;
319
320 spin_lock_bh(&pernet->lock);
321 /* to keep the code simple, don't do IDR-like allocation for address ID,
322 * just bail when we exceed limits
323 */
324 if (pernet->next_id > 255)
325 goto out;
326 if (pernet->addrs >= MPTCP_PM_ADDR_MAX)
327 goto out;
328
329 /* do not insert duplicate address, differentiate on port only
330 * singled addresses
331 */
332 list_for_each_entry(cur, &pernet->local_addr_list, list) {
333 if (addresses_equal(&cur->addr, &entry->addr,
334 address_use_port(entry) &&
335 address_use_port(cur)))
336 goto out;
337 }
338
Paolo Abenief0da3b2020-09-14 10:01:15 +0200339 if (entry->addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL)
Paolo Abeni01cacb02020-03-27 14:48:51 -0700340 pernet->add_addr_signal_max++;
Paolo Abenief0da3b2020-09-14 10:01:15 +0200341 if (entry->addr.flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
Paolo Abeni01cacb02020-03-27 14:48:51 -0700342 pernet->local_addr_max++;
343
344 entry->addr.id = pernet->next_id++;
345 pernet->addrs++;
346 list_add_tail_rcu(&entry->list, &pernet->local_addr_list);
347 ret = entry->addr.id;
348
349out:
350 spin_unlock_bh(&pernet->lock);
351 return ret;
352}
353
354int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
355{
356 struct mptcp_pm_addr_entry *entry;
357 struct mptcp_addr_info skc_local;
358 struct mptcp_addr_info msk_local;
359 struct pm_nl_pernet *pernet;
360 int ret = -1;
361
362 if (WARN_ON_ONCE(!msk))
363 return -1;
364
365 /* The 0 ID mapping is defined by the first subflow, copied into the msk
366 * addr
367 */
368 local_address((struct sock_common *)msk, &msk_local);
Geliang Tang57025812020-09-08 10:49:38 +0800369 local_address((struct sock_common *)skc, &skc_local);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700370 if (addresses_equal(&msk_local, &skc_local, false))
371 return 0;
372
Geliang Tang57025812020-09-08 10:49:38 +0800373 if (address_zero(&skc_local))
374 return 0;
375
Paolo Abeni01cacb02020-03-27 14:48:51 -0700376 pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);
377
378 rcu_read_lock();
379 list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
380 if (addresses_equal(&entry->addr, &skc_local, false)) {
381 ret = entry->addr.id;
382 break;
383 }
384 }
385 rcu_read_unlock();
386 if (ret >= 0)
387 return ret;
388
389 /* address not found, add to local list */
Geliang Tangf612eb72020-09-09 11:01:24 +0800390 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700391 if (!entry)
392 return -ENOMEM;
393
Paolo Abeni01cacb02020-03-27 14:48:51 -0700394 entry->addr = skc_local;
Paolo Abenief0da3b2020-09-14 10:01:15 +0200395 entry->addr.ifindex = 0;
396 entry->addr.flags = 0;
Paolo Abeni01cacb02020-03-27 14:48:51 -0700397 ret = mptcp_pm_nl_append_new_local_addr(pernet, entry);
398 if (ret < 0)
399 kfree(entry);
400
401 return ret;
402}
403
404void mptcp_pm_nl_data_init(struct mptcp_sock *msk)
405{
406 struct mptcp_pm_data *pm = &msk->pm;
407 struct pm_nl_pernet *pernet;
408 bool subflows;
409
410 pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);
411
412 pm->add_addr_signal_max = READ_ONCE(pernet->add_addr_signal_max);
413 pm->add_addr_accept_max = READ_ONCE(pernet->add_addr_accept_max);
414 pm->local_addr_max = READ_ONCE(pernet->local_addr_max);
415 pm->subflows_max = READ_ONCE(pernet->subflows_max);
416 subflows = !!pm->subflows_max;
417 WRITE_ONCE(pm->work_pending, (!!pm->local_addr_max && subflows) ||
418 !!pm->add_addr_signal_max);
419 WRITE_ONCE(pm->accept_addr, !!pm->add_addr_accept_max && subflows);
420 WRITE_ONCE(pm->accept_subflow, subflows);
421}
422
423#define MPTCP_PM_CMD_GRP_OFFSET 0
424
425static const struct genl_multicast_group mptcp_pm_mcgrps[] = {
426 [MPTCP_PM_CMD_GRP_OFFSET] = { .name = MPTCP_PM_CMD_GRP_NAME, },
427};
428
429static const struct nla_policy
430mptcp_pm_addr_policy[MPTCP_PM_ADDR_ATTR_MAX + 1] = {
431 [MPTCP_PM_ADDR_ATTR_FAMILY] = { .type = NLA_U16, },
432 [MPTCP_PM_ADDR_ATTR_ID] = { .type = NLA_U8, },
433 [MPTCP_PM_ADDR_ATTR_ADDR4] = { .type = NLA_U32, },
Johannes Berg81408602020-08-18 10:17:31 +0200434 [MPTCP_PM_ADDR_ATTR_ADDR6] =
435 NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
Paolo Abeni01cacb02020-03-27 14:48:51 -0700436 [MPTCP_PM_ADDR_ATTR_PORT] = { .type = NLA_U16 },
437 [MPTCP_PM_ADDR_ATTR_FLAGS] = { .type = NLA_U32 },
438 [MPTCP_PM_ADDR_ATTR_IF_IDX] = { .type = NLA_S32 },
439};
440
441static const struct nla_policy mptcp_pm_policy[MPTCP_PM_ATTR_MAX + 1] = {
442 [MPTCP_PM_ATTR_ADDR] =
443 NLA_POLICY_NESTED(mptcp_pm_addr_policy),
444 [MPTCP_PM_ATTR_RCV_ADD_ADDRS] = { .type = NLA_U32, },
445 [MPTCP_PM_ATTR_SUBFLOWS] = { .type = NLA_U32, },
446};
447
448static int mptcp_pm_family_to_addr(int family)
449{
450#if IS_ENABLED(CONFIG_MPTCP_IPV6)
451 if (family == AF_INET6)
452 return MPTCP_PM_ADDR_ATTR_ADDR6;
453#endif
454 return MPTCP_PM_ADDR_ATTR_ADDR4;
455}
456
457static int mptcp_pm_parse_addr(struct nlattr *attr, struct genl_info *info,
458 bool require_family,
459 struct mptcp_pm_addr_entry *entry)
460{
461 struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1];
462 int err, addr_addr;
463
464 if (!attr) {
465 GENL_SET_ERR_MSG(info, "missing address info");
466 return -EINVAL;
467 }
468
469 /* no validation needed - was already done via nested policy */
470 err = nla_parse_nested_deprecated(tb, MPTCP_PM_ADDR_ATTR_MAX, attr,
471 mptcp_pm_addr_policy, info->extack);
472 if (err)
473 return err;
474
475 memset(entry, 0, sizeof(*entry));
476 if (!tb[MPTCP_PM_ADDR_ATTR_FAMILY]) {
477 if (!require_family)
478 goto skip_family;
479
480 NL_SET_ERR_MSG_ATTR(info->extack, attr,
481 "missing family");
482 return -EINVAL;
483 }
484
485 entry->addr.family = nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_FAMILY]);
486 if (entry->addr.family != AF_INET
487#if IS_ENABLED(CONFIG_MPTCP_IPV6)
488 && entry->addr.family != AF_INET6
489#endif
490 ) {
491 NL_SET_ERR_MSG_ATTR(info->extack, attr,
492 "unknown address family");
493 return -EINVAL;
494 }
495 addr_addr = mptcp_pm_family_to_addr(entry->addr.family);
496 if (!tb[addr_addr]) {
497 NL_SET_ERR_MSG_ATTR(info->extack, attr,
498 "missing address data");
499 return -EINVAL;
500 }
501
502#if IS_ENABLED(CONFIG_MPTCP_IPV6)
503 if (entry->addr.family == AF_INET6)
504 entry->addr.addr6 = nla_get_in6_addr(tb[addr_addr]);
505 else
506#endif
507 entry->addr.addr.s_addr = nla_get_in_addr(tb[addr_addr]);
508
509skip_family:
Paolo Abenief0da3b2020-09-14 10:01:15 +0200510 if (tb[MPTCP_PM_ADDR_ATTR_IF_IDX]) {
511 u32 val = nla_get_s32(tb[MPTCP_PM_ADDR_ATTR_IF_IDX]);
512
513 entry->addr.ifindex = val;
514 }
Paolo Abeni01cacb02020-03-27 14:48:51 -0700515
516 if (tb[MPTCP_PM_ADDR_ATTR_ID])
517 entry->addr.id = nla_get_u8(tb[MPTCP_PM_ADDR_ATTR_ID]);
518
519 if (tb[MPTCP_PM_ADDR_ATTR_FLAGS])
Paolo Abenief0da3b2020-09-14 10:01:15 +0200520 entry->addr.flags = nla_get_u32(tb[MPTCP_PM_ADDR_ATTR_FLAGS]);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700521
522 return 0;
523}
524
525static struct pm_nl_pernet *genl_info_pm_nl(struct genl_info *info)
526{
527 return net_generic(genl_info_net(info), pm_nl_pernet_id);
528}
529
530static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info)
531{
532 struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
533 struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
534 struct mptcp_pm_addr_entry addr, *entry;
535 int ret;
536
537 ret = mptcp_pm_parse_addr(attr, info, true, &addr);
538 if (ret < 0)
539 return ret;
540
541 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
542 if (!entry) {
543 GENL_SET_ERR_MSG(info, "can't allocate addr");
544 return -ENOMEM;
545 }
546
547 *entry = addr;
548 ret = mptcp_pm_nl_append_new_local_addr(pernet, entry);
549 if (ret < 0) {
550 GENL_SET_ERR_MSG(info, "too many addresses or duplicate one");
551 kfree(entry);
552 return ret;
553 }
554
555 return 0;
556}
557
558static struct mptcp_pm_addr_entry *
559__lookup_addr_by_id(struct pm_nl_pernet *pernet, unsigned int id)
560{
561 struct mptcp_pm_addr_entry *entry;
562
563 list_for_each_entry(entry, &pernet->local_addr_list, list) {
564 if (entry->addr.id == id)
565 return entry;
566 }
567 return NULL;
568}
569
570static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
571{
572 struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
573 struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
574 struct mptcp_pm_addr_entry addr, *entry;
575 int ret;
576
577 ret = mptcp_pm_parse_addr(attr, info, false, &addr);
578 if (ret < 0)
579 return ret;
580
581 spin_lock_bh(&pernet->lock);
582 entry = __lookup_addr_by_id(pernet, addr.addr.id);
583 if (!entry) {
584 GENL_SET_ERR_MSG(info, "address not found");
585 ret = -EINVAL;
586 goto out;
587 }
Paolo Abenief0da3b2020-09-14 10:01:15 +0200588 if (entry->addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL)
Paolo Abeni01cacb02020-03-27 14:48:51 -0700589 pernet->add_addr_signal_max--;
Paolo Abenief0da3b2020-09-14 10:01:15 +0200590 if (entry->addr.flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
Paolo Abeni01cacb02020-03-27 14:48:51 -0700591 pernet->local_addr_max--;
592
593 pernet->addrs--;
594 list_del_rcu(&entry->list);
595 kfree_rcu(entry, rcu);
596out:
597 spin_unlock_bh(&pernet->lock);
598 return ret;
599}
600
601static void __flush_addrs(struct pm_nl_pernet *pernet)
602{
603 while (!list_empty(&pernet->local_addr_list)) {
604 struct mptcp_pm_addr_entry *cur;
605
606 cur = list_entry(pernet->local_addr_list.next,
607 struct mptcp_pm_addr_entry, list);
608 list_del_rcu(&cur->list);
609 kfree_rcu(cur, rcu);
610 }
611}
612
613static void __reset_counters(struct pm_nl_pernet *pernet)
614{
615 pernet->add_addr_signal_max = 0;
616 pernet->add_addr_accept_max = 0;
617 pernet->local_addr_max = 0;
618 pernet->addrs = 0;
619}
620
621static int mptcp_nl_cmd_flush_addrs(struct sk_buff *skb, struct genl_info *info)
622{
623 struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
624
625 spin_lock_bh(&pernet->lock);
626 __flush_addrs(pernet);
627 __reset_counters(pernet);
628 spin_unlock_bh(&pernet->lock);
629 return 0;
630}
631
632static int mptcp_nl_fill_addr(struct sk_buff *skb,
633 struct mptcp_pm_addr_entry *entry)
634{
635 struct mptcp_addr_info *addr = &entry->addr;
636 struct nlattr *attr;
637
638 attr = nla_nest_start(skb, MPTCP_PM_ATTR_ADDR);
639 if (!attr)
640 return -EMSGSIZE;
641
642 if (nla_put_u16(skb, MPTCP_PM_ADDR_ATTR_FAMILY, addr->family))
643 goto nla_put_failure;
644 if (nla_put_u8(skb, MPTCP_PM_ADDR_ATTR_ID, addr->id))
645 goto nla_put_failure;
Paolo Abenief0da3b2020-09-14 10:01:15 +0200646 if (nla_put_u32(skb, MPTCP_PM_ADDR_ATTR_FLAGS, entry->addr.flags))
Paolo Abeni01cacb02020-03-27 14:48:51 -0700647 goto nla_put_failure;
Paolo Abenief0da3b2020-09-14 10:01:15 +0200648 if (entry->addr.ifindex &&
649 nla_put_s32(skb, MPTCP_PM_ADDR_ATTR_IF_IDX, entry->addr.ifindex))
Paolo Abeni01cacb02020-03-27 14:48:51 -0700650 goto nla_put_failure;
651
Bo YUb4e0f9a2020-04-23 10:10:03 +0800652 if (addr->family == AF_INET &&
653 nla_put_in_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR4,
654 addr->addr.s_addr))
655 goto nla_put_failure;
Paolo Abeni01cacb02020-03-27 14:48:51 -0700656#if IS_ENABLED(CONFIG_MPTCP_IPV6)
Bo YUb4e0f9a2020-04-23 10:10:03 +0800657 else if (addr->family == AF_INET6 &&
658 nla_put_in6_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR6, &addr->addr6))
659 goto nla_put_failure;
Paolo Abeni01cacb02020-03-27 14:48:51 -0700660#endif
661 nla_nest_end(skb, attr);
662 return 0;
663
664nla_put_failure:
665 nla_nest_cancel(skb, attr);
666 return -EMSGSIZE;
667}
668
669static int mptcp_nl_cmd_get_addr(struct sk_buff *skb, struct genl_info *info)
670{
671 struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
672 struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
673 struct mptcp_pm_addr_entry addr, *entry;
674 struct sk_buff *msg;
675 void *reply;
676 int ret;
677
678 ret = mptcp_pm_parse_addr(attr, info, false, &addr);
679 if (ret < 0)
680 return ret;
681
682 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
683 if (!msg)
684 return -ENOMEM;
685
686 reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0,
687 info->genlhdr->cmd);
688 if (!reply) {
689 GENL_SET_ERR_MSG(info, "not enough space in Netlink message");
690 ret = -EMSGSIZE;
691 goto fail;
692 }
693
694 spin_lock_bh(&pernet->lock);
695 entry = __lookup_addr_by_id(pernet, addr.addr.id);
696 if (!entry) {
697 GENL_SET_ERR_MSG(info, "address not found");
698 ret = -EINVAL;
699 goto unlock_fail;
700 }
701
702 ret = mptcp_nl_fill_addr(msg, entry);
703 if (ret)
704 goto unlock_fail;
705
706 genlmsg_end(msg, reply);
707 ret = genlmsg_reply(msg, info);
708 spin_unlock_bh(&pernet->lock);
709 return ret;
710
711unlock_fail:
712 spin_unlock_bh(&pernet->lock);
713
714fail:
715 nlmsg_free(msg);
716 return ret;
717}
718
719static int mptcp_nl_cmd_dump_addrs(struct sk_buff *msg,
720 struct netlink_callback *cb)
721{
722 struct net *net = sock_net(msg->sk);
723 struct mptcp_pm_addr_entry *entry;
724 struct pm_nl_pernet *pernet;
725 int id = cb->args[0];
726 void *hdr;
727
728 pernet = net_generic(net, pm_nl_pernet_id);
729
730 spin_lock_bh(&pernet->lock);
731 list_for_each_entry(entry, &pernet->local_addr_list, list) {
732 if (entry->addr.id <= id)
733 continue;
734
735 hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
736 cb->nlh->nlmsg_seq, &mptcp_genl_family,
737 NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR);
738 if (!hdr)
739 break;
740
741 if (mptcp_nl_fill_addr(msg, entry) < 0) {
742 genlmsg_cancel(msg, hdr);
743 break;
744 }
745
746 id = entry->addr.id;
747 genlmsg_end(msg, hdr);
748 }
749 spin_unlock_bh(&pernet->lock);
750
751 cb->args[0] = id;
752 return msg->len;
753}
754
755static int parse_limit(struct genl_info *info, int id, unsigned int *limit)
756{
757 struct nlattr *attr = info->attrs[id];
758
759 if (!attr)
760 return 0;
761
762 *limit = nla_get_u32(attr);
763 if (*limit > MPTCP_PM_ADDR_MAX) {
764 GENL_SET_ERR_MSG(info, "limit greater than maximum");
765 return -EINVAL;
766 }
767 return 0;
768}
769
770static int
771mptcp_nl_cmd_set_limits(struct sk_buff *skb, struct genl_info *info)
772{
773 struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
774 unsigned int rcv_addrs, subflows;
775 int ret;
776
777 spin_lock_bh(&pernet->lock);
778 rcv_addrs = pernet->add_addr_accept_max;
779 ret = parse_limit(info, MPTCP_PM_ATTR_RCV_ADD_ADDRS, &rcv_addrs);
780 if (ret)
781 goto unlock;
782
783 subflows = pernet->subflows_max;
784 ret = parse_limit(info, MPTCP_PM_ATTR_SUBFLOWS, &subflows);
785 if (ret)
786 goto unlock;
787
788 WRITE_ONCE(pernet->add_addr_accept_max, rcv_addrs);
789 WRITE_ONCE(pernet->subflows_max, subflows);
790
791unlock:
792 spin_unlock_bh(&pernet->lock);
793 return ret;
794}
795
796static int
797mptcp_nl_cmd_get_limits(struct sk_buff *skb, struct genl_info *info)
798{
799 struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
800 struct sk_buff *msg;
801 void *reply;
802
803 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
804 if (!msg)
805 return -ENOMEM;
806
807 reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0,
808 MPTCP_PM_CMD_GET_LIMITS);
809 if (!reply)
810 goto fail;
811
812 if (nla_put_u32(msg, MPTCP_PM_ATTR_RCV_ADD_ADDRS,
813 READ_ONCE(pernet->add_addr_accept_max)))
814 goto fail;
815
816 if (nla_put_u32(msg, MPTCP_PM_ATTR_SUBFLOWS,
817 READ_ONCE(pernet->subflows_max)))
818 goto fail;
819
820 genlmsg_end(msg, reply);
821 return genlmsg_reply(msg, info);
822
823fail:
824 GENL_SET_ERR_MSG(info, "not enough space in Netlink message");
825 nlmsg_free(msg);
826 return -EMSGSIZE;
827}
828
829static struct genl_ops mptcp_pm_ops[] = {
830 {
831 .cmd = MPTCP_PM_CMD_ADD_ADDR,
832 .doit = mptcp_nl_cmd_add_addr,
833 .flags = GENL_ADMIN_PERM,
834 },
835 {
836 .cmd = MPTCP_PM_CMD_DEL_ADDR,
837 .doit = mptcp_nl_cmd_del_addr,
838 .flags = GENL_ADMIN_PERM,
839 },
840 {
841 .cmd = MPTCP_PM_CMD_FLUSH_ADDRS,
842 .doit = mptcp_nl_cmd_flush_addrs,
843 .flags = GENL_ADMIN_PERM,
844 },
845 {
846 .cmd = MPTCP_PM_CMD_GET_ADDR,
847 .doit = mptcp_nl_cmd_get_addr,
848 .dumpit = mptcp_nl_cmd_dump_addrs,
849 },
850 {
851 .cmd = MPTCP_PM_CMD_SET_LIMITS,
852 .doit = mptcp_nl_cmd_set_limits,
853 .flags = GENL_ADMIN_PERM,
854 },
855 {
856 .cmd = MPTCP_PM_CMD_GET_LIMITS,
857 .doit = mptcp_nl_cmd_get_limits,
858 },
859};
860
861static struct genl_family mptcp_genl_family __ro_after_init = {
862 .name = MPTCP_PM_NAME,
863 .version = MPTCP_PM_VER,
864 .maxattr = MPTCP_PM_ATTR_MAX,
865 .policy = mptcp_pm_policy,
866 .netnsok = true,
867 .module = THIS_MODULE,
868 .ops = mptcp_pm_ops,
869 .n_ops = ARRAY_SIZE(mptcp_pm_ops),
870 .mcgrps = mptcp_pm_mcgrps,
871 .n_mcgrps = ARRAY_SIZE(mptcp_pm_mcgrps),
872};
873
874static int __net_init pm_nl_init_net(struct net *net)
875{
876 struct pm_nl_pernet *pernet = net_generic(net, pm_nl_pernet_id);
877
878 INIT_LIST_HEAD_RCU(&pernet->local_addr_list);
879 __reset_counters(pernet);
880 pernet->next_id = 1;
881 spin_lock_init(&pernet->lock);
882 return 0;
883}
884
885static void __net_exit pm_nl_exit_net(struct list_head *net_list)
886{
887 struct net *net;
888
889 list_for_each_entry(net, net_list, exit_list) {
890 /* net is removed from namespace list, can't race with
891 * other modifiers
892 */
893 __flush_addrs(net_generic(net, pm_nl_pernet_id));
894 }
895}
896
897static struct pernet_operations mptcp_pm_pernet_ops = {
898 .init = pm_nl_init_net,
899 .exit_batch = pm_nl_exit_net,
900 .id = &pm_nl_pernet_id,
901 .size = sizeof(struct pm_nl_pernet),
902};
903
Paolo Abenid39dcec2020-06-26 19:29:59 +0200904void __init mptcp_pm_nl_init(void)
Paolo Abeni01cacb02020-03-27 14:48:51 -0700905{
906 if (register_pernet_subsys(&mptcp_pm_pernet_ops) < 0)
907 panic("Failed to register MPTCP PM pernet subsystem.\n");
908
909 if (genl_register_family(&mptcp_genl_family))
910 panic("Failed to register MPTCP PM netlink family\n");
911}