diff options
author | Geliang Tang <geliangtang@gmail.com> | 2020-09-24 08:29:50 +0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-09-24 19:58:33 -0700 |
commit | 6a6c05a8b016bb5c63750f91cdb6d669b5a4b14f (patch) | |
tree | 53f5ef6d433502b618caed3755fae16c50294d9c | |
parent | d0876b2284cf8b34dd214b2d0aa21071c345da59 (diff) |
mptcp: send out ADD_ADDR with echo flag
When the ADD_ADDR suboption has been received, we need to send out the same
ADD_ADDR suboption with echo-flag=1, and no HMAC.
Suggested-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/mptcp/options.c | 27 | ||||
-rw-r--r-- | net/mptcp/pm.c | 18 | ||||
-rw-r--r-- | net/mptcp/pm_netlink.c | 4 | ||||
-rw-r--r-- | net/mptcp/protocol.h | 6 |
4 files changed, 32 insertions, 23 deletions
diff --git a/net/mptcp/options.c b/net/mptcp/options.c index a52a05effac9..a41996e6c6d7 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -242,7 +242,7 @@ static void mptcp_parse_option(const struct sk_buff *skb, mp_opt->add_addr = 1; mp_opt->port = 0; mp_opt->addr_id = *ptr++; - pr_debug("ADD_ADDR: id=%d", mp_opt->addr_id); + pr_debug("ADD_ADDR: id=%d, echo=%d", mp_opt->addr_id, mp_opt->echo); if (mp_opt->family == MPTCP_ADDR_IPVERSION_4) { memcpy((u8 *)&mp_opt->addr.s_addr, (u8 *)ptr, 4); ptr += 4; @@ -579,10 +579,11 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); struct mptcp_sock *msk = mptcp_sk(subflow->conn); struct mptcp_addr_info saddr; + bool echo; int len; if (!mptcp_pm_should_add_signal(msk) || - !(mptcp_pm_add_addr_signal(msk, remaining, &saddr))) + !(mptcp_pm_add_addr_signal(msk, remaining, &saddr, &echo))) return false; len = mptcp_add_addr_len(saddr.family); @@ -594,22 +595,26 @@ static bool mptcp_established_options_add_addr(struct sock *sk, if (saddr.family == AF_INET) { opts->suboptions |= OPTION_MPTCP_ADD_ADDR; opts->addr = saddr.addr; - opts->ahmac = add_addr_generate_hmac(msk->local_key, - msk->remote_key, - opts->addr_id, - &opts->addr); + if (!echo) { + opts->ahmac = add_addr_generate_hmac(msk->local_key, + msk->remote_key, + opts->addr_id, + &opts->addr); + } } #if IS_ENABLED(CONFIG_MPTCP_IPV6) else if (saddr.family == AF_INET6) { opts->suboptions |= OPTION_MPTCP_ADD_ADDR6; opts->addr6 = saddr.addr6; - opts->ahmac = add_addr6_generate_hmac(msk->local_key, - msk->remote_key, - opts->addr_id, - &opts->addr6); + if (!echo) { + opts->ahmac = add_addr6_generate_hmac(msk->local_key, + msk->remote_key, + opts->addr_id, + &opts->addr6); + } } #endif - pr_debug("addr_id=%d, ahmac=%llu", opts->addr_id, opts->ahmac); + pr_debug("addr_id=%d, ahmac=%llu, echo=%d", opts->addr_id, opts->ahmac, echo); return true; } diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 558462d87eb3..39a76620d0a5 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -13,11 +13,13 @@ /* path manager command handlers */ int mptcp_pm_announce_addr(struct mptcp_sock *msk, - const struct mptcp_addr_info *addr) + const struct mptcp_addr_info *addr, + bool echo) { pr_debug("msk=%p, local_id=%d", msk, addr->id); msk->pm.local = *addr; + WRITE_ONCE(msk->pm.add_addr_echo, echo); WRITE_ONCE(msk->pm.add_addr_signal, true); return 0; } @@ -135,15 +137,11 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk, pr_debug("msk=%p remote_id=%d accept=%d", msk, addr->id, READ_ONCE(pm->accept_addr)); - /* avoid acquiring the lock if there is no room for fouther addresses */ - if (!READ_ONCE(pm->accept_addr)) - return; - spin_lock_bh(&pm->lock); - /* be sure there is something to signal re-checking under PM lock */ - if (READ_ONCE(pm->accept_addr) && - mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) + if (!READ_ONCE(pm->accept_addr)) + mptcp_pm_announce_addr(msk, addr, true); + else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) pm->remote = *addr; spin_unlock_bh(&pm->lock); @@ -164,7 +162,7 @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id) /* path manager helpers */ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining, - struct mptcp_addr_info *saddr) + struct mptcp_addr_info *saddr, bool *echo) { int ret = false; @@ -178,6 +176,7 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining, goto out_unlock; *saddr = msk->pm.local; + *echo = READ_ONCE(msk->pm.add_addr_echo); WRITE_ONCE(msk->pm.add_addr_signal, false); ret = true; @@ -226,6 +225,7 @@ void mptcp_pm_data_init(struct mptcp_sock *msk) WRITE_ONCE(msk->pm.rm_addr_signal, false); WRITE_ONCE(msk->pm.accept_addr, false); WRITE_ONCE(msk->pm.accept_subflow, false); + WRITE_ONCE(msk->pm.add_addr_echo, false); msk->pm.status = 0; spin_lock_init(&msk->pm.lock); diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index 4124bc581308..f6f96bc2046b 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -198,7 +198,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) if (local) { msk->pm.add_addr_signaled++; - mptcp_pm_announce_addr(msk, &local->addr); + mptcp_pm_announce_addr(msk, &local->addr, false); } else { /* pick failed, avoid fourther attempts later */ msk->pm.local_addr_used = msk->pm.add_addr_signal_max; @@ -266,6 +266,8 @@ void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk) spin_unlock_bh(&msk->pm.lock); __mptcp_subflow_connect((struct sock *)msk, &local, &remote); spin_lock_bh(&msk->pm.lock); + + mptcp_pm_announce_addr(msk, &remote, true); } void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk) diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 837e01057544..ba253a6947b0 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -169,6 +169,7 @@ struct mptcp_pm_data { bool work_pending; bool accept_addr; bool accept_subflow; + bool add_addr_echo; u8 add_addr_signaled; u8 add_addr_accepted; u8 local_addr_used; @@ -442,7 +443,8 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk, void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id); int mptcp_pm_announce_addr(struct mptcp_sock *msk, - const struct mptcp_addr_info *addr); + const struct mptcp_addr_info *addr, + bool echo); int mptcp_pm_remove_addr(struct mptcp_sock *msk, u8 local_id); int mptcp_pm_remove_subflow(struct mptcp_sock *msk, u8 remote_id); @@ -464,7 +466,7 @@ static inline unsigned int mptcp_add_addr_len(int family) } bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining, - struct mptcp_addr_info *saddr); + struct mptcp_addr_info *saddr, bool *echo); bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining, u8 *rm_id); int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc); |