blob: f0afff6ba015fc65312084b7d00f7fabf94a3671 [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"
Geliang Tang7a7e52e2020-09-24 08:29:56 +080018#include "mib.h"
Paolo Abeni01cacb02020-03-27 14:48:51 -070019
20/* forward declaration */
21static struct genl_family mptcp_genl_family;
22
23static int pm_nl_pernet_id;
24
25struct mptcp_pm_addr_entry {
26 struct list_head list;
Paolo Abeni01cacb02020-03-27 14:48:51 -070027 struct mptcp_addr_info addr;
28 struct rcu_head rcu;
29};
30
Geliang Tang0abd40f2020-09-24 08:30:00 +080031struct mptcp_pm_add_entry {
32 struct list_head list;
33 struct mptcp_addr_info addr;
Geliang Tang00cfd772020-09-24 08:30:02 +080034 struct timer_list add_timer;
35 struct mptcp_sock *sock;
36 u8 retrans_times;
Geliang Tang0abd40f2020-09-24 08:30:00 +080037};
38
Geliang Tangefd5a4c2021-01-08 16:47:55 -080039#define MAX_ADDR_ID 255
40#define BITMAP_SZ DIV_ROUND_UP(MAX_ADDR_ID + 1, BITS_PER_LONG)
41
Paolo Abeni01cacb02020-03-27 14:48:51 -070042struct pm_nl_pernet {
43 /* protects pernet updates */
44 spinlock_t lock;
45 struct list_head local_addr_list;
46 unsigned int addrs;
47 unsigned int add_addr_signal_max;
48 unsigned int add_addr_accept_max;
49 unsigned int local_addr_max;
50 unsigned int subflows_max;
51 unsigned int next_id;
Geliang Tangefd5a4c2021-01-08 16:47:55 -080052 unsigned long id_bitmap[BITMAP_SZ];
Paolo Abeni01cacb02020-03-27 14:48:51 -070053};
54
55#define MPTCP_PM_ADDR_MAX 8
Geliang Tang00cfd772020-09-24 08:30:02 +080056#define ADD_ADDR_RETRANS_MAX 3
Paolo Abeni01cacb02020-03-27 14:48:51 -070057
58static bool addresses_equal(const struct mptcp_addr_info *a,
59 struct mptcp_addr_info *b, bool use_port)
60{
61 bool addr_equals = false;
62
Matthieu Baerts7b9b0f72021-01-25 10:59:01 -080063 if (a->family == b->family) {
64 if (a->family == AF_INET)
65 addr_equals = a->addr.s_addr == b->addr.s_addr;
Paolo Abeni01cacb02020-03-27 14:48:51 -070066#if IS_ENABLED(CONFIG_MPTCP_IPV6)
Matthieu Baerts7b9b0f72021-01-25 10:59:01 -080067 else
68 addr_equals = !ipv6_addr_cmp(&a->addr6, &b->addr6);
69 } else if (a->family == AF_INET) {
70 if (ipv6_addr_v4mapped(&b->addr6))
71 addr_equals = a->addr.s_addr == b->addr6.s6_addr32[3];
72 } else if (b->family == AF_INET) {
73 if (ipv6_addr_v4mapped(&a->addr6))
74 addr_equals = a->addr6.s6_addr32[3] == b->addr.s_addr;
Paolo Abeni01cacb02020-03-27 14:48:51 -070075#endif
Matthieu Baerts7b9b0f72021-01-25 10:59:01 -080076 }
Paolo Abeni01cacb02020-03-27 14:48:51 -070077
78 if (!addr_equals)
79 return false;
80 if (!use_port)
81 return true;
82
83 return a->port == b->port;
84}
85
Geliang Tang57025812020-09-08 10:49:38 +080086static bool address_zero(const struct mptcp_addr_info *addr)
87{
88 struct mptcp_addr_info zero;
89
90 memset(&zero, 0, sizeof(zero));
91 zero.family = addr->family;
92
93 return addresses_equal(addr, &zero, false);
94}
95
Paolo Abeni01cacb02020-03-27 14:48:51 -070096static void local_address(const struct sock_common *skc,
97 struct mptcp_addr_info *addr)
98{
99 addr->port = 0;
100 addr->family = skc->skc_family;
101 if (addr->family == AF_INET)
102 addr->addr.s_addr = skc->skc_rcv_saddr;
103#if IS_ENABLED(CONFIG_MPTCP_IPV6)
104 else if (addr->family == AF_INET6)
105 addr->addr6 = skc->skc_v6_rcv_saddr;
106#endif
107}
108
109static void remote_address(const struct sock_common *skc,
110 struct mptcp_addr_info *addr)
111{
112 addr->family = skc->skc_family;
113 addr->port = skc->skc_dport;
114 if (addr->family == AF_INET)
115 addr->addr.s_addr = skc->skc_daddr;
116#if IS_ENABLED(CONFIG_MPTCP_IPV6)
117 else if (addr->family == AF_INET6)
118 addr->addr6 = skc->skc_v6_daddr;
119#endif
120}
121
122static bool lookup_subflow_by_saddr(const struct list_head *list,
123 struct mptcp_addr_info *saddr)
124{
125 struct mptcp_subflow_context *subflow;
126 struct mptcp_addr_info cur;
127 struct sock_common *skc;
128
129 list_for_each_entry(subflow, list, node) {
130 skc = (struct sock_common *)mptcp_subflow_tcp_sock(subflow);
131
132 local_address(skc, &cur);
133 if (addresses_equal(&cur, saddr, false))
134 return true;
135 }
136
137 return false;
138}
139
140static struct mptcp_pm_addr_entry *
141select_local_address(const struct pm_nl_pernet *pernet,
142 struct mptcp_sock *msk)
143{
144 struct mptcp_pm_addr_entry *entry, *ret = NULL;
Matthieu Baerts7b9b0f72021-01-25 10:59:01 -0800145 struct sock *sk = (struct sock *)msk;
Paolo Abeni01cacb02020-03-27 14:48:51 -0700146
147 rcu_read_lock();
Paolo Abeni1bc73272020-12-10 14:25:05 -0800148 __mptcp_flush_join_list(msk);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700149 list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
Paolo Abenief0da3b2020-09-14 10:01:15 +0200150 if (!(entry->addr.flags & MPTCP_PM_ADDR_FLAG_SUBFLOW))
Paolo Abeni01cacb02020-03-27 14:48:51 -0700151 continue;
152
Matthieu Baerts7b9b0f72021-01-25 10:59:01 -0800153 if (entry->addr.family != sk->sk_family) {
154#if IS_ENABLED(CONFIG_MPTCP_IPV6)
155 if ((entry->addr.family == AF_INET &&
156 !ipv6_addr_v4mapped(&sk->sk_v6_daddr)) ||
157 (sk->sk_family == AF_INET &&
158 !ipv6_addr_v4mapped(&entry->addr.addr6)))
159#endif
160 continue;
161 }
162
Paolo Abeni01cacb02020-03-27 14:48:51 -0700163 /* avoid any address already in use by subflows and
164 * pending join
165 */
Matthieu Baerts7b9b0f72021-01-25 10:59:01 -0800166 if (!lookup_subflow_by_saddr(&msk->conn_list, &entry->addr)) {
Paolo Abeni01cacb02020-03-27 14:48:51 -0700167 ret = entry;
168 break;
169 }
170 }
Paolo Abeni01cacb02020-03-27 14:48:51 -0700171 rcu_read_unlock();
172 return ret;
173}
174
175static struct mptcp_pm_addr_entry *
176select_signal_address(struct pm_nl_pernet *pernet, unsigned int pos)
177{
178 struct mptcp_pm_addr_entry *entry, *ret = NULL;
179 int i = 0;
180
181 rcu_read_lock();
182 /* do not keep any additional per socket state, just signal
183 * the address list in order.
184 * Note: removal from the local address list during the msk life-cycle
185 * can lead to additional addresses not being announced.
186 */
187 list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
Paolo Abenief0da3b2020-09-14 10:01:15 +0200188 if (!(entry->addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
Paolo Abeni01cacb02020-03-27 14:48:51 -0700189 continue;
190 if (i++ == pos) {
191 ret = entry;
192 break;
193 }
194 }
195 rcu_read_unlock();
196 return ret;
197}
198
199static void check_work_pending(struct mptcp_sock *msk)
200{
201 if (msk->pm.add_addr_signaled == msk->pm.add_addr_signal_max &&
202 (msk->pm.local_addr_used == msk->pm.local_addr_max ||
203 msk->pm.subflows == msk->pm.subflows_max))
204 WRITE_ONCE(msk->pm.work_pending, false);
205}
206
Geliang Tang00cfd772020-09-24 08:30:02 +0800207static struct mptcp_pm_add_entry *
208lookup_anno_list_by_saddr(struct mptcp_sock *msk,
209 struct mptcp_addr_info *addr)
Geliang Tangb6c08382020-09-24 08:29:54 +0800210{
Geliang Tang0abd40f2020-09-24 08:30:00 +0800211 struct mptcp_pm_add_entry *entry;
Geliang Tangb6c08382020-09-24 08:29:54 +0800212
213 list_for_each_entry(entry, &msk->pm.anno_list, list) {
214 if (addresses_equal(&entry->addr, addr, false))
Geliang Tang00cfd772020-09-24 08:30:02 +0800215 return entry;
Geliang Tangb6c08382020-09-24 08:29:54 +0800216 }
217
Geliang Tang00cfd772020-09-24 08:30:02 +0800218 return NULL;
219}
220
221static void mptcp_pm_add_timer(struct timer_list *timer)
222{
223 struct mptcp_pm_add_entry *entry = from_timer(entry, timer, add_timer);
224 struct mptcp_sock *msk = entry->sock;
225 struct sock *sk = (struct sock *)msk;
226
227 pr_debug("msk=%p", msk);
228
229 if (!msk)
230 return;
231
232 if (inet_sk_state_load(sk) == TCP_CLOSE)
233 return;
234
235 if (!entry->addr.id)
236 return;
237
238 if (mptcp_pm_should_add_signal(msk)) {
239 sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
240 goto out;
241 }
242
243 spin_lock_bh(&msk->pm.lock);
244
245 if (!mptcp_pm_should_add_signal(msk)) {
246 pr_debug("retransmit ADD_ADDR id=%d", entry->addr.id);
Geliang Tang0f5c9e32020-12-09 15:51:24 -0800247 mptcp_pm_announce_addr(msk, &entry->addr, false, entry->addr.port);
Geliang Tang84dfe362020-11-19 11:46:00 -0800248 mptcp_pm_add_addr_send_ack(msk);
Geliang Tang00cfd772020-09-24 08:30:02 +0800249 entry->retrans_times++;
250 }
251
252 if (entry->retrans_times < ADD_ADDR_RETRANS_MAX)
Geliang Tang93f323b2020-11-03 11:05:07 -0800253 sk_reset_timer(sk, timer,
Geliang Tang724d06b2020-11-10 11:01:43 +0800254 jiffies + mptcp_get_add_addr_timeout(sock_net(sk)));
Geliang Tang00cfd772020-09-24 08:30:02 +0800255
256 spin_unlock_bh(&msk->pm.lock);
257
258out:
259 __sock_put(sk);
260}
261
262struct mptcp_pm_add_entry *
263mptcp_pm_del_add_timer(struct mptcp_sock *msk,
264 struct mptcp_addr_info *addr)
265{
266 struct mptcp_pm_add_entry *entry;
267 struct sock *sk = (struct sock *)msk;
268
269 spin_lock_bh(&msk->pm.lock);
270 entry = lookup_anno_list_by_saddr(msk, addr);
271 if (entry)
272 entry->retrans_times = ADD_ADDR_RETRANS_MAX;
273 spin_unlock_bh(&msk->pm.lock);
274
275 if (entry)
276 sk_stop_timer_sync(sk, &entry->add_timer);
277
278 return entry;
Geliang Tangb6c08382020-09-24 08:29:54 +0800279}
280
281static bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
282 struct mptcp_pm_addr_entry *entry)
283{
Geliang Tang0abd40f2020-09-24 08:30:00 +0800284 struct mptcp_pm_add_entry *add_entry = NULL;
Geliang Tang00cfd772020-09-24 08:30:02 +0800285 struct sock *sk = (struct sock *)msk;
Geliang Tang93f323b2020-11-03 11:05:07 -0800286 struct net *net = sock_net(sk);
Geliang Tangb6c08382020-09-24 08:29:54 +0800287
288 if (lookup_anno_list_by_saddr(msk, &entry->addr))
289 return false;
290
Geliang Tang0abd40f2020-09-24 08:30:00 +0800291 add_entry = kmalloc(sizeof(*add_entry), GFP_ATOMIC);
292 if (!add_entry)
Geliang Tangb6c08382020-09-24 08:29:54 +0800293 return false;
294
Geliang Tang0abd40f2020-09-24 08:30:00 +0800295 list_add(&add_entry->list, &msk->pm.anno_list);
Geliang Tangb6c08382020-09-24 08:29:54 +0800296
Geliang Tang00cfd772020-09-24 08:30:02 +0800297 add_entry->addr = entry->addr;
298 add_entry->sock = msk;
299 add_entry->retrans_times = 0;
300
301 timer_setup(&add_entry->add_timer, mptcp_pm_add_timer, 0);
Geliang Tang93f323b2020-11-03 11:05:07 -0800302 sk_reset_timer(sk, &add_entry->add_timer,
303 jiffies + mptcp_get_add_addr_timeout(net));
Geliang Tang00cfd772020-09-24 08:30:02 +0800304
Geliang Tangb6c08382020-09-24 08:29:54 +0800305 return true;
306}
307
308void mptcp_pm_free_anno_list(struct mptcp_sock *msk)
309{
Geliang Tang0abd40f2020-09-24 08:30:00 +0800310 struct mptcp_pm_add_entry *entry, *tmp;
Geliang Tang00cfd772020-09-24 08:30:02 +0800311 struct sock *sk = (struct sock *)msk;
312 LIST_HEAD(free_list);
Geliang Tangb6c08382020-09-24 08:29:54 +0800313
314 pr_debug("msk=%p", msk);
315
316 spin_lock_bh(&msk->pm.lock);
Geliang Tang00cfd772020-09-24 08:30:02 +0800317 list_splice_init(&msk->pm.anno_list, &free_list);
318 spin_unlock_bh(&msk->pm.lock);
319
320 list_for_each_entry_safe(entry, tmp, &free_list, list) {
321 sk_stop_timer_sync(sk, &entry->add_timer);
Geliang Tangb6c08382020-09-24 08:29:54 +0800322 kfree(entry);
323 }
Geliang Tangb6c08382020-09-24 08:29:54 +0800324}
325
Paolo Abeni01cacb02020-03-27 14:48:51 -0700326static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
327{
Geliang Tang2ff0e562020-09-08 10:49:39 +0800328 struct mptcp_addr_info remote = { 0 };
Paolo Abeni01cacb02020-03-27 14:48:51 -0700329 struct sock *sk = (struct sock *)msk;
330 struct mptcp_pm_addr_entry *local;
Paolo Abeni01cacb02020-03-27 14:48:51 -0700331 struct pm_nl_pernet *pernet;
332
Geliang Tang432d9e72020-12-09 15:51:28 -0800333 pernet = net_generic(sock_net(sk), pm_nl_pernet_id);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700334
335 pr_debug("local %d:%d signal %d:%d subflows %d:%d\n",
336 msk->pm.local_addr_used, msk->pm.local_addr_max,
337 msk->pm.add_addr_signaled, msk->pm.add_addr_signal_max,
338 msk->pm.subflows, msk->pm.subflows_max);
339
340 /* check first for announce */
341 if (msk->pm.add_addr_signaled < msk->pm.add_addr_signal_max) {
342 local = select_signal_address(pernet,
343 msk->pm.add_addr_signaled);
344
345 if (local) {
Geliang Tangb6c08382020-09-24 08:29:54 +0800346 if (mptcp_pm_alloc_anno_list(msk, local)) {
347 msk->pm.add_addr_signaled++;
Geliang Tang0f5c9e32020-12-09 15:51:24 -0800348 mptcp_pm_announce_addr(msk, &local->addr, false, local->addr.port);
Geliang Tang84dfe362020-11-19 11:46:00 -0800349 mptcp_pm_nl_add_addr_send_ack(msk);
Geliang Tangb6c08382020-09-24 08:29:54 +0800350 }
Paolo Abeni01cacb02020-03-27 14:48:51 -0700351 } else {
352 /* pick failed, avoid fourther attempts later */
353 msk->pm.local_addr_used = msk->pm.add_addr_signal_max;
354 }
355
356 check_work_pending(msk);
357 }
358
359 /* check if should create a new subflow */
360 if (msk->pm.local_addr_used < msk->pm.local_addr_max &&
361 msk->pm.subflows < msk->pm.subflows_max) {
362 remote_address((struct sock_common *)sk, &remote);
363
364 local = select_local_address(pernet, msk);
365 if (local) {
366 msk->pm.local_addr_used++;
367 msk->pm.subflows++;
368 check_work_pending(msk);
369 spin_unlock_bh(&msk->pm.lock);
Paolo Abenief0da3b2020-09-14 10:01:15 +0200370 __mptcp_subflow_connect(sk, &local->addr, &remote);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700371 spin_lock_bh(&msk->pm.lock);
372 return;
373 }
374
375 /* lookup failed, avoid fourther attempts later */
376 msk->pm.local_addr_used = msk->pm.local_addr_max;
377 check_work_pending(msk);
378 }
379}
380
381void mptcp_pm_nl_fully_established(struct mptcp_sock *msk)
382{
383 mptcp_pm_create_subflow_or_signal_addr(msk);
384}
385
386void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk)
387{
388 mptcp_pm_create_subflow_or_signal_addr(msk);
389}
390
391void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
392{
393 struct sock *sk = (struct sock *)msk;
394 struct mptcp_addr_info remote;
395 struct mptcp_addr_info local;
Geliang Tang0f5c9e32020-12-09 15:51:24 -0800396 bool use_port = false;
Paolo Abeni01cacb02020-03-27 14:48:51 -0700397
398 pr_debug("accepted %d:%d remote family %d",
399 msk->pm.add_addr_accepted, msk->pm.add_addr_accept_max,
400 msk->pm.remote.family);
401 msk->pm.add_addr_accepted++;
402 msk->pm.subflows++;
403 if (msk->pm.add_addr_accepted >= msk->pm.add_addr_accept_max ||
404 msk->pm.subflows >= msk->pm.subflows_max)
405 WRITE_ONCE(msk->pm.accept_addr, false);
406
407 /* connect to the specified remote address, using whatever
408 * local address the routing configuration will pick.
409 */
410 remote = msk->pm.remote;
411 if (!remote.port)
412 remote.port = sk->sk_dport;
Geliang Tang0f5c9e32020-12-09 15:51:24 -0800413 else
414 use_port = true;
Paolo Abeni01cacb02020-03-27 14:48:51 -0700415 memset(&local, 0, sizeof(local));
416 local.family = remote.family;
417
418 spin_unlock_bh(&msk->pm.lock);
Geliang Tang432d9e72020-12-09 15:51:28 -0800419 __mptcp_subflow_connect(sk, &local, &remote);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700420 spin_lock_bh(&msk->pm.lock);
Geliang Tang6a6c05a2020-09-24 08:29:50 +0800421
Geliang Tang0f5c9e32020-12-09 15:51:24 -0800422 mptcp_pm_announce_addr(msk, &remote, true, use_port);
Geliang Tang84dfe362020-11-19 11:46:00 -0800423 mptcp_pm_nl_add_addr_send_ack(msk);
424}
425
426void mptcp_pm_nl_add_addr_send_ack(struct mptcp_sock *msk)
427{
428 struct mptcp_subflow_context *subflow;
429
Geliang Tangfbe0f872020-12-09 15:51:23 -0800430 if (!mptcp_pm_should_add_signal_ipv6(msk) &&
431 !mptcp_pm_should_add_signal_port(msk))
Geliang Tang84dfe362020-11-19 11:46:00 -0800432 return;
433
434 __mptcp_flush_join_list(msk);
435 subflow = list_first_entry_or_null(&msk->conn_list, typeof(*subflow), node);
436 if (subflow) {
437 struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
438 u8 add_addr;
439
440 spin_unlock_bh(&msk->pm.lock);
Geliang Tangfbe0f872020-12-09 15:51:23 -0800441 if (mptcp_pm_should_add_signal_ipv6(msk))
442 pr_debug("send ack for add_addr6");
443 if (mptcp_pm_should_add_signal_port(msk))
444 pr_debug("send ack for add_addr_port");
445
Geliang Tang84dfe362020-11-19 11:46:00 -0800446 lock_sock(ssk);
447 tcp_send_ack(ssk);
448 release_sock(ssk);
449 spin_lock_bh(&msk->pm.lock);
450
Geliang Tang13ad9f02020-12-09 15:51:27 -0800451 add_addr = READ_ONCE(msk->pm.addr_signal);
Geliang Tangfbe0f872020-12-09 15:51:23 -0800452 if (mptcp_pm_should_add_signal_ipv6(msk))
453 add_addr &= ~BIT(MPTCP_ADD_ADDR_IPV6);
454 if (mptcp_pm_should_add_signal_port(msk))
455 add_addr &= ~BIT(MPTCP_ADD_ADDR_PORT);
Geliang Tang13ad9f02020-12-09 15:51:27 -0800456 WRITE_ONCE(msk->pm.addr_signal, add_addr);
Geliang Tang84dfe362020-11-19 11:46:00 -0800457 }
Paolo Abeni01cacb02020-03-27 14:48:51 -0700458}
459
Geliang Tang06706542021-01-08 16:47:57 -0800460int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
461 struct mptcp_addr_info *addr,
462 u8 bkup)
463{
464 struct mptcp_subflow_context *subflow;
465
466 pr_debug("bkup=%d", bkup);
467
468 mptcp_for_each_subflow(msk, subflow) {
469 struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
Geliang Tang0be2ac22021-01-08 16:48:01 -0800470 struct sock *sk = (struct sock *)msk;
Geliang Tang06706542021-01-08 16:47:57 -0800471 struct mptcp_addr_info local;
472
473 local_address((struct sock_common *)ssk, &local);
474 if (!addresses_equal(&local, addr, addr->port))
475 continue;
476
477 subflow->backup = bkup;
478 subflow->send_mp_prio = 1;
479 subflow->request_bkup = bkup;
Geliang Tang0be2ac22021-01-08 16:48:01 -0800480 __MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPPRIOTX);
Geliang Tang06706542021-01-08 16:47:57 -0800481
482 spin_unlock_bh(&msk->pm.lock);
483 pr_debug("send ack for mp_prio");
484 lock_sock(ssk);
485 tcp_send_ack(ssk);
486 release_sock(ssk);
487 spin_lock_bh(&msk->pm.lock);
488
489 return 0;
490 }
491
492 return -EINVAL;
493}
494
Geliang Tangd0876b22020-09-24 08:29:49 +0800495void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk)
496{
497 struct mptcp_subflow_context *subflow, *tmp;
498 struct sock *sk = (struct sock *)msk;
499
500 pr_debug("address rm_id %d", msk->pm.rm_id);
501
502 if (!msk->pm.rm_id)
503 return;
504
505 if (list_empty(&msk->conn_list))
506 return;
507
508 list_for_each_entry_safe(subflow, tmp, &msk->conn_list, node) {
509 struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
510 int how = RCV_SHUTDOWN | SEND_SHUTDOWN;
Geliang Tangd0876b22020-09-24 08:29:49 +0800511
512 if (msk->pm.rm_id != subflow->remote_id)
513 continue;
514
515 spin_unlock_bh(&msk->pm.lock);
516 mptcp_subflow_shutdown(sk, ssk, how);
Paolo Abenie16163b2020-11-16 10:48:09 +0100517 __mptcp_close_ssk(sk, ssk, subflow);
Geliang Tangd0876b22020-09-24 08:29:49 +0800518 spin_lock_bh(&msk->pm.lock);
519
520 msk->pm.add_addr_accepted--;
521 msk->pm.subflows--;
522 WRITE_ONCE(msk->pm.accept_addr, true);
523
Geliang Tang7a7e52e2020-09-24 08:29:56 +0800524 __MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMADDR);
525
Geliang Tangd0876b22020-09-24 08:29:49 +0800526 break;
527 }
528}
529
Geliang Tang0ee42612020-09-24 08:29:55 +0800530void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk, u8 rm_id)
531{
532 struct mptcp_subflow_context *subflow, *tmp;
533 struct sock *sk = (struct sock *)msk;
534
535 pr_debug("subflow rm_id %d", rm_id);
536
537 if (!rm_id)
538 return;
539
540 if (list_empty(&msk->conn_list))
541 return;
542
543 list_for_each_entry_safe(subflow, tmp, &msk->conn_list, node) {
544 struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
545 int how = RCV_SHUTDOWN | SEND_SHUTDOWN;
Geliang Tang0ee42612020-09-24 08:29:55 +0800546
547 if (rm_id != subflow->local_id)
548 continue;
549
550 spin_unlock_bh(&msk->pm.lock);
551 mptcp_subflow_shutdown(sk, ssk, how);
Paolo Abenie16163b2020-11-16 10:48:09 +0100552 __mptcp_close_ssk(sk, ssk, subflow);
Geliang Tang0ee42612020-09-24 08:29:55 +0800553 spin_lock_bh(&msk->pm.lock);
554
555 msk->pm.local_addr_used--;
556 msk->pm.subflows--;
557
Geliang Tang7a7e52e2020-09-24 08:29:56 +0800558 __MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
559
Geliang Tang0ee42612020-09-24 08:29:55 +0800560 break;
561 }
562}
563
Paolo Abeni01cacb02020-03-27 14:48:51 -0700564static bool address_use_port(struct mptcp_pm_addr_entry *entry)
565{
Paolo Abenief0da3b2020-09-14 10:01:15 +0200566 return (entry->addr.flags &
Paolo Abeni01cacb02020-03-27 14:48:51 -0700567 (MPTCP_PM_ADDR_FLAG_SIGNAL | MPTCP_PM_ADDR_FLAG_SUBFLOW)) ==
568 MPTCP_PM_ADDR_FLAG_SIGNAL;
569}
570
571static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
572 struct mptcp_pm_addr_entry *entry)
573{
574 struct mptcp_pm_addr_entry *cur;
575 int ret = -EINVAL;
576
577 spin_lock_bh(&pernet->lock);
578 /* to keep the code simple, don't do IDR-like allocation for address ID,
579 * just bail when we exceed limits
580 */
Geliang Tangefd5a4c2021-01-08 16:47:55 -0800581 if (pernet->next_id == MAX_ADDR_ID)
582 pernet->next_id = 1;
Paolo Abeni01cacb02020-03-27 14:48:51 -0700583 if (pernet->addrs >= MPTCP_PM_ADDR_MAX)
584 goto out;
Geliang Tangefd5a4c2021-01-08 16:47:55 -0800585 if (test_bit(entry->addr.id, pernet->id_bitmap))
586 goto out;
Paolo Abeni01cacb02020-03-27 14:48:51 -0700587
588 /* do not insert duplicate address, differentiate on port only
589 * singled addresses
590 */
591 list_for_each_entry(cur, &pernet->local_addr_list, list) {
592 if (addresses_equal(&cur->addr, &entry->addr,
593 address_use_port(entry) &&
594 address_use_port(cur)))
595 goto out;
596 }
597
Geliang Tangefd5a4c2021-01-08 16:47:55 -0800598 if (!entry->addr.id) {
599find_next:
600 entry->addr.id = find_next_zero_bit(pernet->id_bitmap,
601 MAX_ADDR_ID + 1,
602 pernet->next_id);
603 if ((!entry->addr.id || entry->addr.id > MAX_ADDR_ID) &&
604 pernet->next_id != 1) {
605 pernet->next_id = 1;
606 goto find_next;
607 }
608 }
609
610 if (!entry->addr.id || entry->addr.id > MAX_ADDR_ID)
611 goto out;
612
613 __set_bit(entry->addr.id, pernet->id_bitmap);
614 if (entry->addr.id > pernet->next_id)
615 pernet->next_id = entry->addr.id;
616
Paolo Abenief0da3b2020-09-14 10:01:15 +0200617 if (entry->addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL)
Paolo Abeni01cacb02020-03-27 14:48:51 -0700618 pernet->add_addr_signal_max++;
Paolo Abenief0da3b2020-09-14 10:01:15 +0200619 if (entry->addr.flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
Paolo Abeni01cacb02020-03-27 14:48:51 -0700620 pernet->local_addr_max++;
621
Paolo Abeni01cacb02020-03-27 14:48:51 -0700622 pernet->addrs++;
623 list_add_tail_rcu(&entry->list, &pernet->local_addr_list);
624 ret = entry->addr.id;
625
626out:
627 spin_unlock_bh(&pernet->lock);
628 return ret;
629}
630
631int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
632{
633 struct mptcp_pm_addr_entry *entry;
634 struct mptcp_addr_info skc_local;
635 struct mptcp_addr_info msk_local;
636 struct pm_nl_pernet *pernet;
637 int ret = -1;
638
639 if (WARN_ON_ONCE(!msk))
640 return -1;
641
642 /* The 0 ID mapping is defined by the first subflow, copied into the msk
643 * addr
644 */
645 local_address((struct sock_common *)msk, &msk_local);
Geliang Tang57025812020-09-08 10:49:38 +0800646 local_address((struct sock_common *)skc, &skc_local);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700647 if (addresses_equal(&msk_local, &skc_local, false))
648 return 0;
649
Geliang Tang57025812020-09-08 10:49:38 +0800650 if (address_zero(&skc_local))
651 return 0;
652
Paolo Abeni01cacb02020-03-27 14:48:51 -0700653 pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);
654
655 rcu_read_lock();
656 list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
657 if (addresses_equal(&entry->addr, &skc_local, false)) {
658 ret = entry->addr.id;
659 break;
660 }
661 }
662 rcu_read_unlock();
663 if (ret >= 0)
664 return ret;
665
666 /* address not found, add to local list */
Geliang Tangf612eb72020-09-09 11:01:24 +0800667 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700668 if (!entry)
669 return -ENOMEM;
670
Paolo Abeni01cacb02020-03-27 14:48:51 -0700671 entry->addr = skc_local;
Paolo Abenief0da3b2020-09-14 10:01:15 +0200672 entry->addr.ifindex = 0;
673 entry->addr.flags = 0;
Geliang Tangefd5a4c2021-01-08 16:47:55 -0800674 entry->addr.id = 0;
Paolo Abeni01cacb02020-03-27 14:48:51 -0700675 ret = mptcp_pm_nl_append_new_local_addr(pernet, entry);
676 if (ret < 0)
677 kfree(entry);
678
679 return ret;
680}
681
682void mptcp_pm_nl_data_init(struct mptcp_sock *msk)
683{
684 struct mptcp_pm_data *pm = &msk->pm;
685 struct pm_nl_pernet *pernet;
686 bool subflows;
687
688 pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);
689
690 pm->add_addr_signal_max = READ_ONCE(pernet->add_addr_signal_max);
691 pm->add_addr_accept_max = READ_ONCE(pernet->add_addr_accept_max);
692 pm->local_addr_max = READ_ONCE(pernet->local_addr_max);
693 pm->subflows_max = READ_ONCE(pernet->subflows_max);
694 subflows = !!pm->subflows_max;
695 WRITE_ONCE(pm->work_pending, (!!pm->local_addr_max && subflows) ||
696 !!pm->add_addr_signal_max);
697 WRITE_ONCE(pm->accept_addr, !!pm->add_addr_accept_max && subflows);
698 WRITE_ONCE(pm->accept_subflow, subflows);
699}
700
701#define MPTCP_PM_CMD_GRP_OFFSET 0
702
703static const struct genl_multicast_group mptcp_pm_mcgrps[] = {
704 [MPTCP_PM_CMD_GRP_OFFSET] = { .name = MPTCP_PM_CMD_GRP_NAME, },
705};
706
707static const struct nla_policy
708mptcp_pm_addr_policy[MPTCP_PM_ADDR_ATTR_MAX + 1] = {
709 [MPTCP_PM_ADDR_ATTR_FAMILY] = { .type = NLA_U16, },
710 [MPTCP_PM_ADDR_ATTR_ID] = { .type = NLA_U8, },
711 [MPTCP_PM_ADDR_ATTR_ADDR4] = { .type = NLA_U32, },
Johannes Berg81408602020-08-18 10:17:31 +0200712 [MPTCP_PM_ADDR_ATTR_ADDR6] =
713 NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
Paolo Abeni01cacb02020-03-27 14:48:51 -0700714 [MPTCP_PM_ADDR_ATTR_PORT] = { .type = NLA_U16 },
715 [MPTCP_PM_ADDR_ATTR_FLAGS] = { .type = NLA_U32 },
716 [MPTCP_PM_ADDR_ATTR_IF_IDX] = { .type = NLA_S32 },
717};
718
719static const struct nla_policy mptcp_pm_policy[MPTCP_PM_ATTR_MAX + 1] = {
720 [MPTCP_PM_ATTR_ADDR] =
721 NLA_POLICY_NESTED(mptcp_pm_addr_policy),
722 [MPTCP_PM_ATTR_RCV_ADD_ADDRS] = { .type = NLA_U32, },
723 [MPTCP_PM_ATTR_SUBFLOWS] = { .type = NLA_U32, },
724};
725
726static int mptcp_pm_family_to_addr(int family)
727{
728#if IS_ENABLED(CONFIG_MPTCP_IPV6)
729 if (family == AF_INET6)
730 return MPTCP_PM_ADDR_ATTR_ADDR6;
731#endif
732 return MPTCP_PM_ADDR_ATTR_ADDR4;
733}
734
735static int mptcp_pm_parse_addr(struct nlattr *attr, struct genl_info *info,
736 bool require_family,
737 struct mptcp_pm_addr_entry *entry)
738{
739 struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1];
740 int err, addr_addr;
741
742 if (!attr) {
743 GENL_SET_ERR_MSG(info, "missing address info");
744 return -EINVAL;
745 }
746
747 /* no validation needed - was already done via nested policy */
748 err = nla_parse_nested_deprecated(tb, MPTCP_PM_ADDR_ATTR_MAX, attr,
749 mptcp_pm_addr_policy, info->extack);
750 if (err)
751 return err;
752
753 memset(entry, 0, sizeof(*entry));
754 if (!tb[MPTCP_PM_ADDR_ATTR_FAMILY]) {
755 if (!require_family)
756 goto skip_family;
757
758 NL_SET_ERR_MSG_ATTR(info->extack, attr,
759 "missing family");
760 return -EINVAL;
761 }
762
763 entry->addr.family = nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_FAMILY]);
764 if (entry->addr.family != AF_INET
765#if IS_ENABLED(CONFIG_MPTCP_IPV6)
766 && entry->addr.family != AF_INET6
767#endif
768 ) {
769 NL_SET_ERR_MSG_ATTR(info->extack, attr,
770 "unknown address family");
771 return -EINVAL;
772 }
773 addr_addr = mptcp_pm_family_to_addr(entry->addr.family);
774 if (!tb[addr_addr]) {
775 NL_SET_ERR_MSG_ATTR(info->extack, attr,
776 "missing address data");
777 return -EINVAL;
778 }
779
780#if IS_ENABLED(CONFIG_MPTCP_IPV6)
781 if (entry->addr.family == AF_INET6)
782 entry->addr.addr6 = nla_get_in6_addr(tb[addr_addr]);
783 else
784#endif
785 entry->addr.addr.s_addr = nla_get_in_addr(tb[addr_addr]);
786
787skip_family:
Paolo Abenief0da3b2020-09-14 10:01:15 +0200788 if (tb[MPTCP_PM_ADDR_ATTR_IF_IDX]) {
789 u32 val = nla_get_s32(tb[MPTCP_PM_ADDR_ATTR_IF_IDX]);
790
791 entry->addr.ifindex = val;
792 }
Paolo Abeni01cacb02020-03-27 14:48:51 -0700793
794 if (tb[MPTCP_PM_ADDR_ATTR_ID])
795 entry->addr.id = nla_get_u8(tb[MPTCP_PM_ADDR_ATTR_ID]);
796
797 if (tb[MPTCP_PM_ADDR_ATTR_FLAGS])
Paolo Abenief0da3b2020-09-14 10:01:15 +0200798 entry->addr.flags = nla_get_u32(tb[MPTCP_PM_ADDR_ATTR_FLAGS]);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700799
800 return 0;
801}
802
803static struct pm_nl_pernet *genl_info_pm_nl(struct genl_info *info)
804{
805 return net_generic(genl_info_net(info), pm_nl_pernet_id);
806}
807
808static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info)
809{
810 struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
811 struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
812 struct mptcp_pm_addr_entry addr, *entry;
813 int ret;
814
815 ret = mptcp_pm_parse_addr(attr, info, true, &addr);
816 if (ret < 0)
817 return ret;
818
819 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
820 if (!entry) {
821 GENL_SET_ERR_MSG(info, "can't allocate addr");
822 return -ENOMEM;
823 }
824
825 *entry = addr;
826 ret = mptcp_pm_nl_append_new_local_addr(pernet, entry);
827 if (ret < 0) {
828 GENL_SET_ERR_MSG(info, "too many addresses or duplicate one");
829 kfree(entry);
830 return ret;
831 }
832
833 return 0;
834}
835
836static struct mptcp_pm_addr_entry *
837__lookup_addr_by_id(struct pm_nl_pernet *pernet, unsigned int id)
838{
839 struct mptcp_pm_addr_entry *entry;
840
841 list_for_each_entry(entry, &pernet->local_addr_list, list) {
842 if (entry->addr.id == id)
843 return entry;
844 }
845 return NULL;
846}
847
Geliang Tangb6c08382020-09-24 08:29:54 +0800848static bool remove_anno_list_by_saddr(struct mptcp_sock *msk,
849 struct mptcp_addr_info *addr)
850{
Geliang Tang00cfd772020-09-24 08:30:02 +0800851 struct mptcp_pm_add_entry *entry;
Geliang Tangb6c08382020-09-24 08:29:54 +0800852
Geliang Tang00cfd772020-09-24 08:30:02 +0800853 entry = mptcp_pm_del_add_timer(msk, addr);
854 if (entry) {
855 list_del(&entry->list);
856 kfree(entry);
857 return true;
Geliang Tangb6c08382020-09-24 08:29:54 +0800858 }
859
860 return false;
861}
862
863static bool mptcp_pm_remove_anno_addr(struct mptcp_sock *msk,
864 struct mptcp_addr_info *addr,
865 bool force)
866{
867 bool ret;
868
Geliang Tangb6c08382020-09-24 08:29:54 +0800869 ret = remove_anno_list_by_saddr(msk, addr);
Geliang Tang00cfd772020-09-24 08:30:02 +0800870 if (ret || force) {
871 spin_lock_bh(&msk->pm.lock);
Geliang Tangb6c08382020-09-24 08:29:54 +0800872 mptcp_pm_remove_addr(msk, addr->id);
Geliang Tang00cfd772020-09-24 08:30:02 +0800873 spin_unlock_bh(&msk->pm.lock);
874 }
Geliang Tangb6c08382020-09-24 08:29:54 +0800875 return ret;
876}
877
878static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
879 struct mptcp_addr_info *addr)
880{
881 struct mptcp_sock *msk;
882 long s_slot = 0, s_num = 0;
883
884 pr_debug("remove_id=%d", addr->id);
885
886 while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
887 struct sock *sk = (struct sock *)msk;
888 bool remove_subflow;
889
890 if (list_empty(&msk->conn_list)) {
891 mptcp_pm_remove_anno_addr(msk, addr, false);
892 goto next;
893 }
894
895 lock_sock(sk);
896 remove_subflow = lookup_subflow_by_saddr(&msk->conn_list, addr);
897 mptcp_pm_remove_anno_addr(msk, addr, remove_subflow);
898 if (remove_subflow)
899 mptcp_pm_remove_subflow(msk, addr->id);
900 release_sock(sk);
901
902next:
903 sock_put(sk);
904 cond_resched();
905 }
906
907 return 0;
908}
909
Paolo Abeni01cacb02020-03-27 14:48:51 -0700910static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
911{
912 struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
913 struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
914 struct mptcp_pm_addr_entry addr, *entry;
915 int ret;
916
917 ret = mptcp_pm_parse_addr(attr, info, false, &addr);
918 if (ret < 0)
919 return ret;
920
921 spin_lock_bh(&pernet->lock);
922 entry = __lookup_addr_by_id(pernet, addr.addr.id);
923 if (!entry) {
924 GENL_SET_ERR_MSG(info, "address not found");
Geliang Tangb6c08382020-09-24 08:29:54 +0800925 spin_unlock_bh(&pernet->lock);
926 return -EINVAL;
Paolo Abeni01cacb02020-03-27 14:48:51 -0700927 }
Paolo Abenief0da3b2020-09-14 10:01:15 +0200928 if (entry->addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL)
Paolo Abeni01cacb02020-03-27 14:48:51 -0700929 pernet->add_addr_signal_max--;
Paolo Abenief0da3b2020-09-14 10:01:15 +0200930 if (entry->addr.flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
Paolo Abeni01cacb02020-03-27 14:48:51 -0700931 pernet->local_addr_max--;
932
933 pernet->addrs--;
934 list_del_rcu(&entry->list);
Geliang Tangefd5a4c2021-01-08 16:47:55 -0800935 __clear_bit(entry->addr.id, pernet->id_bitmap);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700936 spin_unlock_bh(&pernet->lock);
Geliang Tangb6c08382020-09-24 08:29:54 +0800937
938 mptcp_nl_remove_subflow_and_signal_addr(sock_net(skb->sk), &entry->addr);
939 kfree_rcu(entry, rcu);
940
Paolo Abeni01cacb02020-03-27 14:48:51 -0700941 return ret;
942}
943
Geliang Tang141694d2020-12-10 14:24:59 -0800944static void __flush_addrs(struct net *net, struct list_head *list)
Paolo Abeni01cacb02020-03-27 14:48:51 -0700945{
Geliang Tang141694d2020-12-10 14:24:59 -0800946 while (!list_empty(list)) {
Paolo Abeni01cacb02020-03-27 14:48:51 -0700947 struct mptcp_pm_addr_entry *cur;
948
Geliang Tang141694d2020-12-10 14:24:59 -0800949 cur = list_entry(list->next,
Paolo Abeni01cacb02020-03-27 14:48:51 -0700950 struct mptcp_pm_addr_entry, list);
Geliang Tang141694d2020-12-10 14:24:59 -0800951 mptcp_nl_remove_subflow_and_signal_addr(net, &cur->addr);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700952 list_del_rcu(&cur->list);
953 kfree_rcu(cur, rcu);
954 }
955}
956
957static void __reset_counters(struct pm_nl_pernet *pernet)
958{
959 pernet->add_addr_signal_max = 0;
960 pernet->add_addr_accept_max = 0;
961 pernet->local_addr_max = 0;
962 pernet->addrs = 0;
963}
964
965static int mptcp_nl_cmd_flush_addrs(struct sk_buff *skb, struct genl_info *info)
966{
967 struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
Geliang Tang141694d2020-12-10 14:24:59 -0800968 LIST_HEAD(free_list);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700969
970 spin_lock_bh(&pernet->lock);
Geliang Tang141694d2020-12-10 14:24:59 -0800971 list_splice_init(&pernet->local_addr_list, &free_list);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700972 __reset_counters(pernet);
Geliang Tangefd5a4c2021-01-08 16:47:55 -0800973 pernet->next_id = 1;
974 bitmap_zero(pernet->id_bitmap, MAX_ADDR_ID + 1);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700975 spin_unlock_bh(&pernet->lock);
Geliang Tang141694d2020-12-10 14:24:59 -0800976 __flush_addrs(sock_net(skb->sk), &free_list);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700977 return 0;
978}
979
980static int mptcp_nl_fill_addr(struct sk_buff *skb,
981 struct mptcp_pm_addr_entry *entry)
982{
983 struct mptcp_addr_info *addr = &entry->addr;
984 struct nlattr *attr;
985
986 attr = nla_nest_start(skb, MPTCP_PM_ATTR_ADDR);
987 if (!attr)
988 return -EMSGSIZE;
989
990 if (nla_put_u16(skb, MPTCP_PM_ADDR_ATTR_FAMILY, addr->family))
991 goto nla_put_failure;
992 if (nla_put_u8(skb, MPTCP_PM_ADDR_ATTR_ID, addr->id))
993 goto nla_put_failure;
Paolo Abenief0da3b2020-09-14 10:01:15 +0200994 if (nla_put_u32(skb, MPTCP_PM_ADDR_ATTR_FLAGS, entry->addr.flags))
Paolo Abeni01cacb02020-03-27 14:48:51 -0700995 goto nla_put_failure;
Paolo Abenief0da3b2020-09-14 10:01:15 +0200996 if (entry->addr.ifindex &&
997 nla_put_s32(skb, MPTCP_PM_ADDR_ATTR_IF_IDX, entry->addr.ifindex))
Paolo Abeni01cacb02020-03-27 14:48:51 -0700998 goto nla_put_failure;
999
Bo YUb4e0f9a2020-04-23 10:10:03 +08001000 if (addr->family == AF_INET &&
1001 nla_put_in_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR4,
1002 addr->addr.s_addr))
1003 goto nla_put_failure;
Paolo Abeni01cacb02020-03-27 14:48:51 -07001004#if IS_ENABLED(CONFIG_MPTCP_IPV6)
Bo YUb4e0f9a2020-04-23 10:10:03 +08001005 else if (addr->family == AF_INET6 &&
1006 nla_put_in6_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR6, &addr->addr6))
1007 goto nla_put_failure;
Paolo Abeni01cacb02020-03-27 14:48:51 -07001008#endif
1009 nla_nest_end(skb, attr);
1010 return 0;
1011
1012nla_put_failure:
1013 nla_nest_cancel(skb, attr);
1014 return -EMSGSIZE;
1015}
1016
1017static int mptcp_nl_cmd_get_addr(struct sk_buff *skb, struct genl_info *info)
1018{
1019 struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
1020 struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
1021 struct mptcp_pm_addr_entry addr, *entry;
1022 struct sk_buff *msg;
1023 void *reply;
1024 int ret;
1025
1026 ret = mptcp_pm_parse_addr(attr, info, false, &addr);
1027 if (ret < 0)
1028 return ret;
1029
1030 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1031 if (!msg)
1032 return -ENOMEM;
1033
1034 reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0,
1035 info->genlhdr->cmd);
1036 if (!reply) {
1037 GENL_SET_ERR_MSG(info, "not enough space in Netlink message");
1038 ret = -EMSGSIZE;
1039 goto fail;
1040 }
1041
1042 spin_lock_bh(&pernet->lock);
1043 entry = __lookup_addr_by_id(pernet, addr.addr.id);
1044 if (!entry) {
1045 GENL_SET_ERR_MSG(info, "address not found");
1046 ret = -EINVAL;
1047 goto unlock_fail;
1048 }
1049
1050 ret = mptcp_nl_fill_addr(msg, entry);
1051 if (ret)
1052 goto unlock_fail;
1053
1054 genlmsg_end(msg, reply);
1055 ret = genlmsg_reply(msg, info);
1056 spin_unlock_bh(&pernet->lock);
1057 return ret;
1058
1059unlock_fail:
1060 spin_unlock_bh(&pernet->lock);
1061
1062fail:
1063 nlmsg_free(msg);
1064 return ret;
1065}
1066
1067static int mptcp_nl_cmd_dump_addrs(struct sk_buff *msg,
1068 struct netlink_callback *cb)
1069{
1070 struct net *net = sock_net(msg->sk);
1071 struct mptcp_pm_addr_entry *entry;
1072 struct pm_nl_pernet *pernet;
1073 int id = cb->args[0];
1074 void *hdr;
Geliang Tangefd5a4c2021-01-08 16:47:55 -08001075 int i;
Paolo Abeni01cacb02020-03-27 14:48:51 -07001076
1077 pernet = net_generic(net, pm_nl_pernet_id);
1078
1079 spin_lock_bh(&pernet->lock);
Geliang Tangefd5a4c2021-01-08 16:47:55 -08001080 for (i = id; i < MAX_ADDR_ID + 1; i++) {
1081 if (test_bit(i, pernet->id_bitmap)) {
1082 entry = __lookup_addr_by_id(pernet, i);
1083 if (!entry)
1084 break;
Paolo Abeni01cacb02020-03-27 14:48:51 -07001085
Geliang Tangefd5a4c2021-01-08 16:47:55 -08001086 if (entry->addr.id <= id)
1087 continue;
Paolo Abeni01cacb02020-03-27 14:48:51 -07001088
Geliang Tangefd5a4c2021-01-08 16:47:55 -08001089 hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
1090 cb->nlh->nlmsg_seq, &mptcp_genl_family,
1091 NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR);
1092 if (!hdr)
1093 break;
1094
1095 if (mptcp_nl_fill_addr(msg, entry) < 0) {
1096 genlmsg_cancel(msg, hdr);
1097 break;
1098 }
1099
1100 id = entry->addr.id;
1101 genlmsg_end(msg, hdr);
Paolo Abeni01cacb02020-03-27 14:48:51 -07001102 }
Paolo Abeni01cacb02020-03-27 14:48:51 -07001103 }
1104 spin_unlock_bh(&pernet->lock);
1105
1106 cb->args[0] = id;
1107 return msg->len;
1108}
1109
1110static int parse_limit(struct genl_info *info, int id, unsigned int *limit)
1111{
1112 struct nlattr *attr = info->attrs[id];
1113
1114 if (!attr)
1115 return 0;
1116
1117 *limit = nla_get_u32(attr);
1118 if (*limit > MPTCP_PM_ADDR_MAX) {
1119 GENL_SET_ERR_MSG(info, "limit greater than maximum");
1120 return -EINVAL;
1121 }
1122 return 0;
1123}
1124
1125static int
1126mptcp_nl_cmd_set_limits(struct sk_buff *skb, struct genl_info *info)
1127{
1128 struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
1129 unsigned int rcv_addrs, subflows;
1130 int ret;
1131
1132 spin_lock_bh(&pernet->lock);
1133 rcv_addrs = pernet->add_addr_accept_max;
1134 ret = parse_limit(info, MPTCP_PM_ATTR_RCV_ADD_ADDRS, &rcv_addrs);
1135 if (ret)
1136 goto unlock;
1137
1138 subflows = pernet->subflows_max;
1139 ret = parse_limit(info, MPTCP_PM_ATTR_SUBFLOWS, &subflows);
1140 if (ret)
1141 goto unlock;
1142
1143 WRITE_ONCE(pernet->add_addr_accept_max, rcv_addrs);
1144 WRITE_ONCE(pernet->subflows_max, subflows);
1145
1146unlock:
1147 spin_unlock_bh(&pernet->lock);
1148 return ret;
1149}
1150
1151static int
1152mptcp_nl_cmd_get_limits(struct sk_buff *skb, struct genl_info *info)
1153{
1154 struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
1155 struct sk_buff *msg;
1156 void *reply;
1157
1158 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1159 if (!msg)
1160 return -ENOMEM;
1161
1162 reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0,
1163 MPTCP_PM_CMD_GET_LIMITS);
1164 if (!reply)
1165 goto fail;
1166
1167 if (nla_put_u32(msg, MPTCP_PM_ATTR_RCV_ADD_ADDRS,
1168 READ_ONCE(pernet->add_addr_accept_max)))
1169 goto fail;
1170
1171 if (nla_put_u32(msg, MPTCP_PM_ATTR_SUBFLOWS,
1172 READ_ONCE(pernet->subflows_max)))
1173 goto fail;
1174
1175 genlmsg_end(msg, reply);
1176 return genlmsg_reply(msg, info);
1177
1178fail:
1179 GENL_SET_ERR_MSG(info, "not enough space in Netlink message");
1180 nlmsg_free(msg);
1181 return -EMSGSIZE;
1182}
1183
Geliang Tang0f9f6962021-01-08 16:47:59 -08001184static int mptcp_nl_addr_backup(struct net *net,
1185 struct mptcp_addr_info *addr,
1186 u8 bkup)
1187{
1188 long s_slot = 0, s_num = 0;
1189 struct mptcp_sock *msk;
1190 int ret = -EINVAL;
1191
1192 while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
1193 struct sock *sk = (struct sock *)msk;
1194
1195 if (list_empty(&msk->conn_list))
1196 goto next;
1197
1198 lock_sock(sk);
1199 spin_lock_bh(&msk->pm.lock);
1200 ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, bkup);
1201 spin_unlock_bh(&msk->pm.lock);
1202 release_sock(sk);
1203
1204next:
1205 sock_put(sk);
1206 cond_resched();
1207 }
1208
1209 return ret;
1210}
1211
1212static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)
1213{
1214 struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
1215 struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
1216 struct mptcp_pm_addr_entry addr, *entry;
1217 struct net *net = sock_net(skb->sk);
1218 u8 bkup = 0;
1219 int ret;
1220
1221 ret = mptcp_pm_parse_addr(attr, info, true, &addr);
1222 if (ret < 0)
1223 return ret;
1224
1225 if (addr.addr.flags & MPTCP_PM_ADDR_FLAG_BACKUP)
1226 bkup = 1;
1227
1228 list_for_each_entry(entry, &pernet->local_addr_list, list) {
1229 if (addresses_equal(&entry->addr, &addr.addr, true)) {
1230 ret = mptcp_nl_addr_backup(net, &entry->addr, bkup);
1231 if (ret)
1232 return ret;
1233
1234 if (bkup)
1235 entry->addr.flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
1236 else
1237 entry->addr.flags &= ~MPTCP_PM_ADDR_FLAG_BACKUP;
1238 }
1239 }
1240
1241 return 0;
1242}
1243
Rikard Falkeborn674d3ab2020-10-05 01:44:16 +02001244static const struct genl_small_ops mptcp_pm_ops[] = {
Paolo Abeni01cacb02020-03-27 14:48:51 -07001245 {
1246 .cmd = MPTCP_PM_CMD_ADD_ADDR,
1247 .doit = mptcp_nl_cmd_add_addr,
1248 .flags = GENL_ADMIN_PERM,
1249 },
1250 {
1251 .cmd = MPTCP_PM_CMD_DEL_ADDR,
1252 .doit = mptcp_nl_cmd_del_addr,
1253 .flags = GENL_ADMIN_PERM,
1254 },
1255 {
1256 .cmd = MPTCP_PM_CMD_FLUSH_ADDRS,
1257 .doit = mptcp_nl_cmd_flush_addrs,
1258 .flags = GENL_ADMIN_PERM,
1259 },
1260 {
1261 .cmd = MPTCP_PM_CMD_GET_ADDR,
1262 .doit = mptcp_nl_cmd_get_addr,
1263 .dumpit = mptcp_nl_cmd_dump_addrs,
1264 },
1265 {
1266 .cmd = MPTCP_PM_CMD_SET_LIMITS,
1267 .doit = mptcp_nl_cmd_set_limits,
1268 .flags = GENL_ADMIN_PERM,
1269 },
1270 {
1271 .cmd = MPTCP_PM_CMD_GET_LIMITS,
1272 .doit = mptcp_nl_cmd_get_limits,
1273 },
Geliang Tang0f9f6962021-01-08 16:47:59 -08001274 {
1275 .cmd = MPTCP_PM_CMD_SET_FLAGS,
1276 .doit = mptcp_nl_cmd_set_flags,
1277 .flags = GENL_ADMIN_PERM,
1278 },
Paolo Abeni01cacb02020-03-27 14:48:51 -07001279};
1280
1281static struct genl_family mptcp_genl_family __ro_after_init = {
1282 .name = MPTCP_PM_NAME,
1283 .version = MPTCP_PM_VER,
1284 .maxattr = MPTCP_PM_ATTR_MAX,
1285 .policy = mptcp_pm_policy,
1286 .netnsok = true,
1287 .module = THIS_MODULE,
Jakub Kicinski66a9b922020-10-02 14:49:54 -07001288 .small_ops = mptcp_pm_ops,
1289 .n_small_ops = ARRAY_SIZE(mptcp_pm_ops),
Paolo Abeni01cacb02020-03-27 14:48:51 -07001290 .mcgrps = mptcp_pm_mcgrps,
1291 .n_mcgrps = ARRAY_SIZE(mptcp_pm_mcgrps),
1292};
1293
1294static int __net_init pm_nl_init_net(struct net *net)
1295{
1296 struct pm_nl_pernet *pernet = net_generic(net, pm_nl_pernet_id);
1297
1298 INIT_LIST_HEAD_RCU(&pernet->local_addr_list);
1299 __reset_counters(pernet);
1300 pernet->next_id = 1;
Geliang Tangefd5a4c2021-01-08 16:47:55 -08001301 bitmap_zero(pernet->id_bitmap, MAX_ADDR_ID + 1);
Paolo Abeni01cacb02020-03-27 14:48:51 -07001302 spin_lock_init(&pernet->lock);
1303 return 0;
1304}
1305
1306static void __net_exit pm_nl_exit_net(struct list_head *net_list)
1307{
1308 struct net *net;
1309
1310 list_for_each_entry(net, net_list, exit_list) {
Geliang Tang141694d2020-12-10 14:24:59 -08001311 struct pm_nl_pernet *pernet = net_generic(net, pm_nl_pernet_id);
1312
Paolo Abeni01cacb02020-03-27 14:48:51 -07001313 /* net is removed from namespace list, can't race with
1314 * other modifiers
1315 */
Geliang Tang141694d2020-12-10 14:24:59 -08001316 __flush_addrs(net, &pernet->local_addr_list);
Paolo Abeni01cacb02020-03-27 14:48:51 -07001317 }
1318}
1319
1320static struct pernet_operations mptcp_pm_pernet_ops = {
1321 .init = pm_nl_init_net,
1322 .exit_batch = pm_nl_exit_net,
1323 .id = &pm_nl_pernet_id,
1324 .size = sizeof(struct pm_nl_pernet),
1325};
1326
Paolo Abenid39dcec2020-06-26 19:29:59 +02001327void __init mptcp_pm_nl_init(void)
Paolo Abeni01cacb02020-03-27 14:48:51 -07001328{
1329 if (register_pernet_subsys(&mptcp_pm_pernet_ops) < 0)
1330 panic("Failed to register MPTCP PM pernet subsystem.\n");
1331
1332 if (genl_register_family(&mptcp_genl_family))
1333 panic("Failed to register MPTCP PM netlink family\n");
1334}