linux/net/mptcp/pm.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Multipath TCP
   3 *
   4 * Copyright (c) 2019, Intel Corporation.
   5 */
   6#define pr_fmt(fmt) "MPTCP: " fmt
   7
   8#include <linux/kernel.h>
   9#include <net/tcp.h>
  10#include <net/mptcp.h>
  11#include "protocol.h"
  12
  13/* path manager command handlers */
  14
  15int mptcp_pm_announce_addr(struct mptcp_sock *msk,
  16                           const struct mptcp_addr_info *addr,
  17                           bool echo)
  18{
  19        u8 add_addr = READ_ONCE(msk->pm.addr_signal);
  20
  21        pr_debug("msk=%p, local_id=%d", msk, addr->id);
  22
  23        lockdep_assert_held(&msk->pm.lock);
  24
  25        if (add_addr) {
  26                pr_warn("addr_signal error, add_addr=%d", add_addr);
  27                return -EINVAL;
  28        }
  29
  30        msk->pm.local = *addr;
  31        add_addr |= BIT(MPTCP_ADD_ADDR_SIGNAL);
  32        if (echo)
  33                add_addr |= BIT(MPTCP_ADD_ADDR_ECHO);
  34        if (addr->family == AF_INET6)
  35                add_addr |= BIT(MPTCP_ADD_ADDR_IPV6);
  36        if (addr->port)
  37                add_addr |= BIT(MPTCP_ADD_ADDR_PORT);
  38        WRITE_ONCE(msk->pm.addr_signal, add_addr);
  39        return 0;
  40}
  41
  42int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list)
  43{
  44        u8 rm_addr = READ_ONCE(msk->pm.addr_signal);
  45
  46        pr_debug("msk=%p, rm_list_nr=%d", msk, rm_list->nr);
  47
  48        if (rm_addr) {
  49                pr_warn("addr_signal error, rm_addr=%d", rm_addr);
  50                return -EINVAL;
  51        }
  52
  53        msk->pm.rm_list_tx = *rm_list;
  54        rm_addr |= BIT(MPTCP_RM_ADDR_SIGNAL);
  55        WRITE_ONCE(msk->pm.addr_signal, rm_addr);
  56        mptcp_pm_nl_addr_send_ack(msk);
  57        return 0;
  58}
  59
  60int mptcp_pm_remove_subflow(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list)
  61{
  62        pr_debug("msk=%p, rm_list_nr=%d", msk, rm_list->nr);
  63
  64        spin_lock_bh(&msk->pm.lock);
  65        mptcp_pm_nl_rm_subflow_received(msk, rm_list);
  66        spin_unlock_bh(&msk->pm.lock);
  67        return 0;
  68}
  69
  70/* path manager event handlers */
  71
  72void mptcp_pm_new_connection(struct mptcp_sock *msk, const struct sock *ssk, int server_side)
  73{
  74        struct mptcp_pm_data *pm = &msk->pm;
  75
  76        pr_debug("msk=%p, token=%u side=%d", msk, msk->token, server_side);
  77
  78        WRITE_ONCE(pm->server_side, server_side);
  79        mptcp_event(MPTCP_EVENT_CREATED, msk, ssk, GFP_ATOMIC);
  80}
  81
  82bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk)
  83{
  84        struct mptcp_pm_data *pm = &msk->pm;
  85        unsigned int subflows_max;
  86        int ret = 0;
  87
  88        subflows_max = mptcp_pm_get_subflows_max(msk);
  89
  90        pr_debug("msk=%p subflows=%d max=%d allow=%d", msk, pm->subflows,
  91                 subflows_max, READ_ONCE(pm->accept_subflow));
  92
  93        /* try to avoid acquiring the lock below */
  94        if (!READ_ONCE(pm->accept_subflow))
  95                return false;
  96
  97        spin_lock_bh(&pm->lock);
  98        if (READ_ONCE(pm->accept_subflow)) {
  99                ret = pm->subflows < subflows_max;
 100                if (ret && ++pm->subflows == subflows_max)
 101                        WRITE_ONCE(pm->accept_subflow, false);
 102        }
 103        spin_unlock_bh(&pm->lock);
 104
 105        return ret;
 106}
 107
 108/* return true if the new status bit is currently cleared, that is, this event
 109 * can be server, eventually by an already scheduled work
 110 */
 111static bool mptcp_pm_schedule_work(struct mptcp_sock *msk,
 112                                   enum mptcp_pm_status new_status)
 113{
 114        pr_debug("msk=%p status=%x new=%lx", msk, msk->pm.status,
 115                 BIT(new_status));
 116        if (msk->pm.status & BIT(new_status))
 117                return false;
 118
 119        msk->pm.status |= BIT(new_status);
 120        mptcp_schedule_work((struct sock *)msk);
 121        return true;
 122}
 123
 124void mptcp_pm_fully_established(struct mptcp_sock *msk, const struct sock *ssk, gfp_t gfp)
 125{
 126        struct mptcp_pm_data *pm = &msk->pm;
 127        bool announce = false;
 128
 129        pr_debug("msk=%p", msk);
 130
 131        spin_lock_bh(&pm->lock);
 132
 133        /* mptcp_pm_fully_established() can be invoked by multiple
 134         * racing paths - accept() and check_fully_established()
 135         * be sure to serve this event only once.
 136         */
 137        if (READ_ONCE(pm->work_pending) &&
 138            !(msk->pm.status & BIT(MPTCP_PM_ALREADY_ESTABLISHED)))
 139                mptcp_pm_schedule_work(msk, MPTCP_PM_ESTABLISHED);
 140
 141        if ((msk->pm.status & BIT(MPTCP_PM_ALREADY_ESTABLISHED)) == 0)
 142                announce = true;
 143
 144        msk->pm.status |= BIT(MPTCP_PM_ALREADY_ESTABLISHED);
 145        spin_unlock_bh(&pm->lock);
 146
 147        if (announce)
 148                mptcp_event(MPTCP_EVENT_ESTABLISHED, msk, ssk, gfp);
 149}
 150
 151void mptcp_pm_connection_closed(struct mptcp_sock *msk)
 152{
 153        pr_debug("msk=%p", msk);
 154}
 155
 156void mptcp_pm_subflow_established(struct mptcp_sock *msk)
 157{
 158        struct mptcp_pm_data *pm = &msk->pm;
 159
 160        pr_debug("msk=%p", msk);
 161
 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);
 171}
 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{
 181        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
 186        mptcp_event_addr_announced(msk, addr);
 187
 188        spin_lock_bh(&pm->lock);
 189
 190        if (!READ_ONCE(pm->accept_addr)) {
 191                mptcp_pm_announce_addr(msk, addr, true);
 192                mptcp_pm_add_addr_send_ack(msk);
 193        } else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) {
 194                pm->remote = *addr;
 195        }
 196
 197        spin_unlock_bh(&pm->lock);
 198}
 199
 200void mptcp_pm_add_addr_echoed(struct mptcp_sock *msk,
 201                              struct mptcp_addr_info *addr)
 202{
 203        struct mptcp_pm_data *pm = &msk->pm;
 204
 205        pr_debug("msk=%p", msk);
 206
 207        spin_lock_bh(&pm->lock);
 208
 209        if (mptcp_lookup_anno_list_by_saddr(msk, addr) && READ_ONCE(pm->work_pending))
 210                mptcp_pm_schedule_work(msk, MPTCP_PM_SUBFLOW_ESTABLISHED);
 211
 212        spin_unlock_bh(&pm->lock);
 213}
 214
 215void mptcp_pm_add_addr_send_ack(struct mptcp_sock *msk)
 216{
 217        if (!mptcp_pm_should_add_signal(msk))
 218                return;
 219
 220        mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_SEND_ACK);
 221}
 222
 223void mptcp_pm_rm_addr_received(struct mptcp_sock *msk,
 224                               const struct mptcp_rm_list *rm_list)
 225{
 226        struct mptcp_pm_data *pm = &msk->pm;
 227        u8 i;
 228
 229        pr_debug("msk=%p remote_ids_nr=%d", msk, rm_list->nr);
 230
 231        for (i = 0; i < rm_list->nr; i++)
 232                mptcp_event_addr_removed(msk, rm_list->ids[i]);
 233
 234        spin_lock_bh(&pm->lock);
 235        mptcp_pm_schedule_work(msk, MPTCP_PM_RM_ADDR_RECEIVED);
 236        pm->rm_list_rx = *rm_list;
 237        spin_unlock_bh(&pm->lock);
 238}
 239
 240void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
 241{
 242        struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
 243
 244        pr_debug("subflow->backup=%d, bkup=%d\n", subflow->backup, bkup);
 245        subflow->backup = bkup;
 246
 247        mptcp_event(MPTCP_EVENT_SUB_PRIORITY, mptcp_sk(subflow->conn), sk, GFP_ATOMIC);
 248}
 249
 250/* path manager helpers */
 251
 252bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
 253                              struct mptcp_addr_info *saddr, bool *echo, bool *port)
 254{
 255        int ret = false;
 256
 257        spin_lock_bh(&msk->pm.lock);
 258
 259        /* double check after the lock is acquired */
 260        if (!mptcp_pm_should_add_signal(msk))
 261                goto out_unlock;
 262
 263        *echo = mptcp_pm_should_add_signal_echo(msk);
 264        *port = mptcp_pm_should_add_signal_port(msk);
 265
 266        if (remaining < mptcp_add_addr_len(msk->pm.local.family, *echo, *port))
 267                goto out_unlock;
 268
 269        *saddr = msk->pm.local;
 270        WRITE_ONCE(msk->pm.addr_signal, 0);
 271        ret = true;
 272
 273out_unlock:
 274        spin_unlock_bh(&msk->pm.lock);
 275        return ret;
 276}
 277
 278bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
 279                             struct mptcp_rm_list *rm_list)
 280{
 281        int ret = false, len;
 282
 283        spin_lock_bh(&msk->pm.lock);
 284
 285        /* double check after the lock is acquired */
 286        if (!mptcp_pm_should_rm_signal(msk))
 287                goto out_unlock;
 288
 289        len = mptcp_rm_addr_len(&msk->pm.rm_list_tx);
 290        if (len < 0) {
 291                WRITE_ONCE(msk->pm.addr_signal, 0);
 292                goto out_unlock;
 293        }
 294        if (remaining < len)
 295                goto out_unlock;
 296
 297        *rm_list = msk->pm.rm_list_tx;
 298        WRITE_ONCE(msk->pm.addr_signal, 0);
 299        ret = true;
 300
 301out_unlock:
 302        spin_unlock_bh(&msk->pm.lock);
 303        return ret;
 304}
 305
 306int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
 307{
 308        return mptcp_pm_nl_get_local_id(msk, skc);
 309}
 310
 311void mptcp_pm_data_init(struct mptcp_sock *msk)
 312{
 313        msk->pm.add_addr_signaled = 0;
 314        msk->pm.add_addr_accepted = 0;
 315        msk->pm.local_addr_used = 0;
 316        msk->pm.subflows = 0;
 317        msk->pm.rm_list_tx.nr = 0;
 318        msk->pm.rm_list_rx.nr = 0;
 319        WRITE_ONCE(msk->pm.work_pending, false);
 320        WRITE_ONCE(msk->pm.addr_signal, 0);
 321        WRITE_ONCE(msk->pm.accept_addr, false);
 322        WRITE_ONCE(msk->pm.accept_subflow, false);
 323        WRITE_ONCE(msk->pm.remote_deny_join_id0, false);
 324        msk->pm.status = 0;
 325
 326        spin_lock_init(&msk->pm.lock);
 327        INIT_LIST_HEAD(&msk->pm.anno_list);
 328
 329        mptcp_pm_nl_data_init(msk);
 330}
 331
 332void __init mptcp_pm_init(void)
 333{
 334        mptcp_pm_nl_init();
 335}
 336