blob: 51e60582b408cec0f8bf5feda184c1283306df36 [file] [log] [blame]
Peter Krystad1b1c7a02020-03-27 14:48:38 -07001// SPDX-License-Identifier: GPL-2.0
2/* Multipath TCP
3 *
4 * Copyright (c) 2019, Intel Corporation.
5 */
Geliang Tangc85adce2020-04-03 17:14:08 +08006#define pr_fmt(fmt) "MPTCP: " fmt
7
Peter Krystad1b1c7a02020-03-27 14:48:38 -07008#include <linux/kernel.h>
9#include <net/tcp.h>
10#include <net/mptcp.h>
11#include "protocol.h"
12
Peter Krystad1b1c7a02020-03-27 14:48:38 -070013/* path manager command handlers */
14
15int mptcp_pm_announce_addr(struct mptcp_sock *msk,
Geliang Tang6a6c05a2020-09-24 08:29:50 +080016 const struct mptcp_addr_info *addr,
Geliang Tangf7efc772021-03-26 11:26:31 -070017 bool echo)
Peter Krystad1b1c7a02020-03-27 14:48:38 -070018{
Geliang Tang13ad9f02020-12-09 15:51:27 -080019 u8 add_addr = READ_ONCE(msk->pm.addr_signal);
Geliang Tangd91d3222020-11-19 11:45:59 -080020
Peter Krystad926bdea2020-03-27 14:48:41 -070021 pr_debug("msk=%p, local_id=%d", msk, addr->id);
22
Florian Westphal3abc05d2021-02-04 15:23:30 -080023 lockdep_assert_held(&msk->pm.lock);
24
Geliang Tang42842a42020-12-09 15:51:26 -080025 if (add_addr) {
26 pr_warn("addr_signal error, add_addr=%d", add_addr);
27 return -EINVAL;
28 }
29
Peter Krystad926bdea2020-03-27 14:48:41 -070030 msk->pm.local = *addr;
Geliang Tangd91d3222020-11-19 11:45:59 -080031 add_addr |= BIT(MPTCP_ADD_ADDR_SIGNAL);
32 if (echo)
33 add_addr |= BIT(MPTCP_ADD_ADDR_ECHO);
Geliang Tang84dfe362020-11-19 11:46:00 -080034 if (addr->family == AF_INET6)
35 add_addr |= BIT(MPTCP_ADD_ADDR_IPV6);
Geliang Tangf7efc772021-03-26 11:26:31 -070036 if (addr->port)
Geliang Tang0f5c9e32020-12-09 15:51:24 -080037 add_addr |= BIT(MPTCP_ADD_ADDR_PORT);
Geliang Tang13ad9f02020-12-09 15:51:27 -080038 WRITE_ONCE(msk->pm.addr_signal, add_addr);
Peter Krystad926bdea2020-03-27 14:48:41 -070039 return 0;
Peter Krystad1b1c7a02020-03-27 14:48:38 -070040}
41
Geliang Tangcbde2782021-03-12 17:16:12 -080042int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list)
Peter Krystad1b1c7a02020-03-27 14:48:38 -070043{
Geliang Tang13ad9f02020-12-09 15:51:27 -080044 u8 rm_addr = READ_ONCE(msk->pm.addr_signal);
Geliang Tang42842a42020-12-09 15:51:26 -080045
Geliang Tangcbde2782021-03-12 17:16:12 -080046 pr_debug("msk=%p, rm_list_nr=%d", msk, rm_list->nr);
Geliang Tangb6c08382020-09-24 08:29:54 +080047
Geliang Tang42842a42020-12-09 15:51:26 -080048 if (rm_addr) {
49 pr_warn("addr_signal error, rm_addr=%d", rm_addr);
50 return -EINVAL;
51 }
52
Geliang Tangcbde2782021-03-12 17:16:12 -080053 msk->pm.rm_list_tx = *rm_list;
Geliang Tang42842a42020-12-09 15:51:26 -080054 rm_addr |= BIT(MPTCP_RM_ADDR_SIGNAL);
Geliang Tang13ad9f02020-12-09 15:51:27 -080055 WRITE_ONCE(msk->pm.addr_signal, rm_addr);
Geliang Tangb6c08382020-09-24 08:29:54 +080056 return 0;
Peter Krystad1b1c7a02020-03-27 14:48:38 -070057}
58
Geliang Tangddd14bb2021-03-12 17:16:16 -080059int mptcp_pm_remove_subflow(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list)
Peter Krystad1b1c7a02020-03-27 14:48:38 -070060{
Geliang Tangddd14bb2021-03-12 17:16:16 -080061 pr_debug("msk=%p, rm_list_nr=%d", msk, rm_list->nr);
Geliang Tang0ee42612020-09-24 08:29:55 +080062
63 spin_lock_bh(&msk->pm.lock);
Geliang Tangddd14bb2021-03-12 17:16:16 -080064 mptcp_pm_nl_rm_subflow_received(msk, rm_list);
Geliang Tang0ee42612020-09-24 08:29:55 +080065 spin_unlock_bh(&msk->pm.lock);
66 return 0;
Peter Krystad1b1c7a02020-03-27 14:48:38 -070067}
68
69/* path manager event handlers */
70
Florian Westphal6c714f12021-02-12 15:59:58 -080071void mptcp_pm_new_connection(struct mptcp_sock *msk, const struct sock *ssk, int server_side)
Peter Krystad1b1c7a02020-03-27 14:48:38 -070072{
73 struct mptcp_pm_data *pm = &msk->pm;
74
75 pr_debug("msk=%p, token=%u side=%d", msk, msk->token, server_side);
76
77 WRITE_ONCE(pm->server_side, server_side);
Florian Westphalb911c972021-02-12 16:00:01 -080078 mptcp_event(MPTCP_EVENT_CREATED, msk, ssk, GFP_ATOMIC);
Peter Krystad1b1c7a02020-03-27 14:48:38 -070079}
80
81bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk)
82{
Peter Krystad926bdea2020-03-27 14:48:41 -070083 struct mptcp_pm_data *pm = &msk->pm;
Geliang Tanga914e582021-02-01 15:09:07 -080084 unsigned int subflows_max;
Geliang Tangf58f0652020-09-24 08:29:53 +080085 int ret = 0;
Peter Krystad926bdea2020-03-27 14:48:41 -070086
Geliang Tanga914e582021-02-01 15:09:07 -080087 subflows_max = mptcp_pm_get_subflows_max(msk);
88
Peter Krystad926bdea2020-03-27 14:48:41 -070089 pr_debug("msk=%p subflows=%d max=%d allow=%d", msk, pm->subflows,
Geliang Tanga914e582021-02-01 15:09:07 -080090 subflows_max, READ_ONCE(pm->accept_subflow));
Peter Krystad926bdea2020-03-27 14:48:41 -070091
92 /* try to avoid acquiring the lock below */
93 if (!READ_ONCE(pm->accept_subflow))
94 return false;
95
96 spin_lock_bh(&pm->lock);
Geliang Tangf58f0652020-09-24 08:29:53 +080097 if (READ_ONCE(pm->accept_subflow)) {
Geliang Tanga914e582021-02-01 15:09:07 -080098 ret = pm->subflows < subflows_max;
99 if (ret && ++pm->subflows == subflows_max)
Geliang Tangf58f0652020-09-24 08:29:53 +0800100 WRITE_ONCE(pm->accept_subflow, false);
101 }
Peter Krystad926bdea2020-03-27 14:48:41 -0700102 spin_unlock_bh(&pm->lock);
103
104 return ret;
105}
106
107/* return true if the new status bit is currently cleared, that is, this event
108 * can be server, eventually by an already scheduled work
109 */
110static bool mptcp_pm_schedule_work(struct mptcp_sock *msk,
111 enum mptcp_pm_status new_status)
112{
113 pr_debug("msk=%p status=%x new=%lx", msk, msk->pm.status,
114 BIT(new_status));
115 if (msk->pm.status & BIT(new_status))
116 return false;
117
118 msk->pm.status |= BIT(new_status);
Paolo Abeniba8f48f2020-11-16 10:48:05 +0100119 mptcp_schedule_work((struct sock *)msk);
Peter Krystad926bdea2020-03-27 14:48:41 -0700120 return true;
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700121}
122
Florian Westphal6c714f12021-02-12 15:59:58 -0800123void mptcp_pm_fully_established(struct mptcp_sock *msk, const struct sock *ssk, gfp_t gfp)
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700124{
Peter Krystad926bdea2020-03-27 14:48:41 -0700125 struct mptcp_pm_data *pm = &msk->pm;
Florian Westphalb911c972021-02-12 16:00:01 -0800126 bool announce = false;
Peter Krystad926bdea2020-03-27 14:48:41 -0700127
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700128 pr_debug("msk=%p", msk);
Peter Krystad926bdea2020-03-27 14:48:41 -0700129
Peter Krystad926bdea2020-03-27 14:48:41 -0700130 spin_lock_bh(&pm->lock);
131
Paolo Abeni5b950ff2020-12-09 12:03:29 +0100132 /* mptcp_pm_fully_established() can be invoked by multiple
133 * racing paths - accept() and check_fully_established()
134 * be sure to serve this event only once.
135 */
136 if (READ_ONCE(pm->work_pending) &&
137 !(msk->pm.status & BIT(MPTCP_PM_ALREADY_ESTABLISHED)))
Peter Krystad926bdea2020-03-27 14:48:41 -0700138 mptcp_pm_schedule_work(msk, MPTCP_PM_ESTABLISHED);
139
Florian Westphalb911c972021-02-12 16:00:01 -0800140 if ((msk->pm.status & BIT(MPTCP_PM_ALREADY_ESTABLISHED)) == 0)
141 announce = true;
142
143 msk->pm.status |= BIT(MPTCP_PM_ALREADY_ESTABLISHED);
Peter Krystad926bdea2020-03-27 14:48:41 -0700144 spin_unlock_bh(&pm->lock);
Florian Westphalb911c972021-02-12 16:00:01 -0800145
146 if (announce)
147 mptcp_event(MPTCP_EVENT_ESTABLISHED, msk, ssk, gfp);
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700148}
149
150void mptcp_pm_connection_closed(struct mptcp_sock *msk)
151{
152 pr_debug("msk=%p", msk);
153}
154
155void mptcp_pm_subflow_established(struct mptcp_sock *msk,
156 struct mptcp_subflow_context *subflow)
157{
Peter Krystad926bdea2020-03-27 14:48:41 -0700158 struct mptcp_pm_data *pm = &msk->pm;
159
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700160 pr_debug("msk=%p", msk);
Peter Krystad926bdea2020-03-27 14:48:41 -0700161
162 if (!READ_ONCE(pm->work_pending))
163 return;
164
165 spin_lock_bh(&pm->lock);
166
167 if (READ_ONCE(pm->work_pending))
168 mptcp_pm_schedule_work(msk, MPTCP_PM_SUBFLOW_ESTABLISHED);
169
170 spin_unlock_bh(&pm->lock);
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700171}
172
173void mptcp_pm_subflow_closed(struct mptcp_sock *msk, u8 id)
174{
175 pr_debug("msk=%p", msk);
176}
177
178void mptcp_pm_add_addr_received(struct mptcp_sock *msk,
179 const struct mptcp_addr_info *addr)
180{
Peter Krystad926bdea2020-03-27 14:48:41 -0700181 struct mptcp_pm_data *pm = &msk->pm;
182
183 pr_debug("msk=%p remote_id=%d accept=%d", msk, addr->id,
184 READ_ONCE(pm->accept_addr));
185
Florian Westphalb911c972021-02-12 16:00:01 -0800186 mptcp_event_addr_announced(msk, addr);
187
Peter Krystad926bdea2020-03-27 14:48:41 -0700188 spin_lock_bh(&pm->lock);
189
Geliang Tang84dfe362020-11-19 11:46:00 -0800190 if (!READ_ONCE(pm->accept_addr)) {
Geliang Tangf7efc772021-03-26 11:26:31 -0700191 mptcp_pm_announce_addr(msk, addr, true);
Geliang Tang84dfe362020-11-19 11:46:00 -0800192 mptcp_pm_add_addr_send_ack(msk);
193 } else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) {
Peter Krystad926bdea2020-03-27 14:48:41 -0700194 pm->remote = *addr;
Geliang Tang84dfe362020-11-19 11:46:00 -0800195 }
Peter Krystad926bdea2020-03-27 14:48:41 -0700196
197 spin_unlock_bh(&pm->lock);
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700198}
199
Geliang Tang84dfe362020-11-19 11:46:00 -0800200void mptcp_pm_add_addr_send_ack(struct mptcp_sock *msk)
201{
Geliang Tangb5a7acd2021-02-01 15:09:09 -0800202 if (!mptcp_pm_should_add_signal(msk))
Geliang Tang84dfe362020-11-19 11:46:00 -0800203 return;
204
205 mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_SEND_ACK);
206}
207
Geliang Tang5c4a8242021-03-12 17:16:13 -0800208void mptcp_pm_rm_addr_received(struct mptcp_sock *msk,
209 const struct mptcp_rm_list *rm_list)
Geliang Tangd0876b22020-09-24 08:29:49 +0800210{
211 struct mptcp_pm_data *pm = &msk->pm;
Geliang Tang5c4a8242021-03-12 17:16:13 -0800212 u8 i;
Geliang Tangd0876b22020-09-24 08:29:49 +0800213
Geliang Tang5c4a8242021-03-12 17:16:13 -0800214 pr_debug("msk=%p remote_ids_nr=%d", msk, rm_list->nr);
Geliang Tangd0876b22020-09-24 08:29:49 +0800215
Geliang Tang5c4a8242021-03-12 17:16:13 -0800216 for (i = 0; i < rm_list->nr; i++)
217 mptcp_event_addr_removed(msk, rm_list->ids[i]);
Florian Westphalb911c972021-02-12 16:00:01 -0800218
Geliang Tangd0876b22020-09-24 08:29:49 +0800219 spin_lock_bh(&pm->lock);
220 mptcp_pm_schedule_work(msk, MPTCP_PM_RM_ADDR_RECEIVED);
Geliang Tangb5c55f32021-03-12 17:16:14 -0800221 pm->rm_list_rx = *rm_list;
Geliang Tangd0876b22020-09-24 08:29:49 +0800222 spin_unlock_bh(&pm->lock);
223}
224
Geliang Tang40453a52021-01-08 16:47:58 -0800225void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
226{
227 struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
228
229 pr_debug("subflow->backup=%d, bkup=%d\n", subflow->backup, bkup);
230 subflow->backup = bkup;
Florian Westphalb911c972021-02-12 16:00:01 -0800231
232 mptcp_event(MPTCP_EVENT_SUB_PRIORITY, mptcp_sk(subflow->conn), sk, GFP_ATOMIC);
Geliang Tang40453a52021-01-08 16:47:58 -0800233}
234
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700235/* path manager helpers */
236
Geliang Tangf643b802020-09-24 08:29:47 +0800237bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
Geliang Tang4a2777a82020-12-09 15:51:22 -0800238 struct mptcp_addr_info *saddr, bool *echo, bool *port)
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700239{
Peter Krystad926bdea2020-03-27 14:48:41 -0700240 int ret = false;
241
242 spin_lock_bh(&msk->pm.lock);
243
244 /* double check after the lock is acquired */
Geliang Tangf643b802020-09-24 08:29:47 +0800245 if (!mptcp_pm_should_add_signal(msk))
Peter Krystad926bdea2020-03-27 14:48:41 -0700246 goto out_unlock;
247
Geliang Tangd91d3222020-11-19 11:45:59 -0800248 *echo = mptcp_pm_should_add_signal_echo(msk);
Geliang Tang4a2777a82020-12-09 15:51:22 -0800249 *port = mptcp_pm_should_add_signal_port(msk);
Matthieu Baerts456afe02020-10-03 17:36:56 +0200250
Geliang Tang4a2777a82020-12-09 15:51:22 -0800251 if (remaining < mptcp_add_addr_len(msk->pm.local.family, *echo, *port))
Peter Krystad926bdea2020-03-27 14:48:41 -0700252 goto out_unlock;
253
254 *saddr = msk->pm.local;
Geliang Tang13ad9f02020-12-09 15:51:27 -0800255 WRITE_ONCE(msk->pm.addr_signal, 0);
Peter Krystad926bdea2020-03-27 14:48:41 -0700256 ret = true;
257
258out_unlock:
259 spin_unlock_bh(&msk->pm.lock);
260 return ret;
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700261}
262
Geliang Tang5cb104a2020-09-24 08:29:48 +0800263bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
Geliang Tang6445e172021-03-12 17:16:11 -0800264 struct mptcp_rm_list *rm_list)
Geliang Tang5cb104a2020-09-24 08:29:48 +0800265{
Geliang Tangcbde2782021-03-12 17:16:12 -0800266 int ret = false, len;
Geliang Tang5cb104a2020-09-24 08:29:48 +0800267
268 spin_lock_bh(&msk->pm.lock);
269
270 /* double check after the lock is acquired */
271 if (!mptcp_pm_should_rm_signal(msk))
272 goto out_unlock;
273
Geliang Tangcbde2782021-03-12 17:16:12 -0800274 len = mptcp_rm_addr_len(&msk->pm.rm_list_tx);
275 if (len < 0) {
276 WRITE_ONCE(msk->pm.addr_signal, 0);
277 goto out_unlock;
278 }
279 if (remaining < len)
Geliang Tang5cb104a2020-09-24 08:29:48 +0800280 goto out_unlock;
281
Geliang Tangcbde2782021-03-12 17:16:12 -0800282 *rm_list = msk->pm.rm_list_tx;
Geliang Tang13ad9f02020-12-09 15:51:27 -0800283 WRITE_ONCE(msk->pm.addr_signal, 0);
Geliang Tang5cb104a2020-09-24 08:29:48 +0800284 ret = true;
285
286out_unlock:
287 spin_unlock_bh(&msk->pm.lock);
288 return ret;
289}
290
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700291int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
292{
Paolo Abeni01cacb02020-03-27 14:48:51 -0700293 return mptcp_pm_nl_get_local_id(msk, skc);
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700294}
295
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700296void mptcp_pm_data_init(struct mptcp_sock *msk)
297{
298 msk->pm.add_addr_signaled = 0;
299 msk->pm.add_addr_accepted = 0;
300 msk->pm.local_addr_used = 0;
301 msk->pm.subflows = 0;
Geliang Tangcbde2782021-03-12 17:16:12 -0800302 msk->pm.rm_list_tx.nr = 0;
Geliang Tangb5c55f32021-03-12 17:16:14 -0800303 msk->pm.rm_list_rx.nr = 0;
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700304 WRITE_ONCE(msk->pm.work_pending, false);
Geliang Tang13ad9f02020-12-09 15:51:27 -0800305 WRITE_ONCE(msk->pm.addr_signal, 0);
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700306 WRITE_ONCE(msk->pm.accept_addr, false);
307 WRITE_ONCE(msk->pm.accept_subflow, false);
308 msk->pm.status = 0;
309
310 spin_lock_init(&msk->pm.lock);
Geliang Tangb6c08382020-09-24 08:29:54 +0800311 INIT_LIST_HEAD(&msk->pm.anno_list);
Paolo Abeni01cacb02020-03-27 14:48:51 -0700312
313 mptcp_pm_nl_data_init(msk);
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700314}
315
Paolo Abenid39dcec2020-06-26 19:29:59 +0200316void __init mptcp_pm_init(void)
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700317{
Paolo Abeni01cacb02020-03-27 14:48:51 -0700318 mptcp_pm_nl_init();
Peter Krystad1b1c7a02020-03-27 14:48:38 -0700319}