Commit 5a40cce2 authored by David S. Miller's avatar David S. Miller

Merge branch 'mptcp-Add-port-parameter-to-ADD_ADDR-option'

Mat Martineau says:

====================
mptcp: Add port parameter to ADD_ADDR option

The ADD_ADDR MPTCP option is used to announce available IP addresses
that a peer may connect to when adding more TCP subflows to an existing
MPTCP connection. There is an optional port number field in that
ADD_ADDR header, and this patch set adds capability for that port number
to be sent and received.

Patches 1, 2, and 4 refactor existing ADD_ADDR code to simplify implementation
of port number support.

Patches 3 and 5 are the main functional changes, for sending and
receiving the port number in the MPTCP ADD_ADDR option.

Patch 6 sends the ADD_ADDR option with port number on a bare TCP ACK,
since the extra length of the option may run in to cases where
sufficient TCP option space is not available on a data packet.

Patch 7 plumbs in port number support for the in-kernel MPTCP path
manager.

Patches 8-11 add some optional debug output and a little more cleanup
refactoring.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents dc528d5b 432d9e74
...@@ -46,6 +46,7 @@ struct mptcp_out_options { ...@@ -46,6 +46,7 @@ struct mptcp_out_options {
#endif #endif
}; };
u8 addr_id; u8 addr_id;
u16 port;
u64 ahmac; u64 ahmac;
u8 rm_id; u8 rm_id;
u8 join_id; u8 join_id;
......
...@@ -242,9 +242,6 @@ static void mptcp_parse_option(const struct sk_buff *skb, ...@@ -242,9 +242,6 @@ static void mptcp_parse_option(const struct sk_buff *skb,
mp_opt->add_addr = 1; mp_opt->add_addr = 1;
mp_opt->addr_id = *ptr++; mp_opt->addr_id = *ptr++;
pr_debug("ADD_ADDR%s: id=%d, echo=%d",
(mp_opt->family == MPTCP_ADDR_IPVERSION_6) ? "6" : "",
mp_opt->addr_id, mp_opt->echo);
if (mp_opt->family == MPTCP_ADDR_IPVERSION_4) { if (mp_opt->family == MPTCP_ADDR_IPVERSION_4) {
memcpy((u8 *)&mp_opt->addr.s_addr, (u8 *)ptr, 4); memcpy((u8 *)&mp_opt->addr.s_addr, (u8 *)ptr, 4);
ptr += 4; ptr += 4;
...@@ -269,6 +266,9 @@ static void mptcp_parse_option(const struct sk_buff *skb, ...@@ -269,6 +266,9 @@ static void mptcp_parse_option(const struct sk_buff *skb,
mp_opt->ahmac = get_unaligned_be64(ptr); mp_opt->ahmac = get_unaligned_be64(ptr);
ptr += 8; ptr += 8;
} }
pr_debug("ADD_ADDR%s: id=%d, ahmac=%llu, echo=%d, port=%d",
(mp_opt->family == MPTCP_ADDR_IPVERSION_6) ? "6" : "",
mp_opt->addr_id, mp_opt->ahmac, mp_opt->echo, mp_opt->port);
break; break;
case MPTCPOPT_RM_ADDR: case MPTCPOPT_RM_ADDR:
...@@ -587,9 +587,11 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff * ...@@ -587,9 +587,11 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
unsigned int opt_size = *size; unsigned int opt_size = *size;
struct mptcp_addr_info saddr; struct mptcp_addr_info saddr;
bool echo; bool echo;
bool port;
int len; int len;
if (mptcp_pm_should_add_signal_ipv6(msk) && if ((mptcp_pm_should_add_signal_ipv6(msk) ||
mptcp_pm_should_add_signal_port(msk)) &&
skb && skb_is_tcp_pure_ack(skb)) { skb && skb_is_tcp_pure_ack(skb)) {
pr_debug("drop other suboptions"); pr_debug("drop other suboptions");
opts->suboptions = 0; opts->suboptions = 0;
...@@ -598,10 +600,10 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff * ...@@ -598,10 +600,10 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
} }
if (!mptcp_pm_should_add_signal(msk) || if (!mptcp_pm_should_add_signal(msk) ||
!(mptcp_pm_add_addr_signal(msk, remaining, &saddr, &echo))) !(mptcp_pm_add_addr_signal(msk, remaining, &saddr, &echo, &port)))
return false; return false;
len = mptcp_add_addr_len(saddr.family, echo); len = mptcp_add_addr_len(saddr.family, echo, port);
if (remaining < len) if (remaining < len)
return false; return false;
...@@ -609,6 +611,8 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff * ...@@ -609,6 +611,8 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
if (drop_other_suboptions) if (drop_other_suboptions)
*size -= opt_size; *size -= opt_size;
opts->addr_id = saddr.id; opts->addr_id = saddr.id;
if (port)
opts->port = ntohs(saddr.port);
if (saddr.family == AF_INET) { if (saddr.family == AF_INET) {
opts->suboptions |= OPTION_MPTCP_ADD_ADDR; opts->suboptions |= OPTION_MPTCP_ADD_ADDR;
opts->addr = saddr.addr; opts->addr = saddr.addr;
...@@ -631,7 +635,8 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff * ...@@ -631,7 +635,8 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
} }
} }
#endif #endif
pr_debug("addr_id=%d, ahmac=%llu, echo=%d", opts->addr_id, opts->ahmac, echo); pr_debug("addr_id=%d, ahmac=%llu, echo=%d, port=%d",
opts->addr_id, opts->ahmac, echo, opts->port);
return true; return true;
} }
...@@ -1070,44 +1075,66 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp, ...@@ -1070,44 +1075,66 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
} }
mp_capable_done: mp_capable_done:
if (OPTION_MPTCP_ADD_ADDR & opts->suboptions) { if ((OPTION_MPTCP_ADD_ADDR
if (opts->ahmac) #if IS_ENABLED(CONFIG_MPTCP_IPV6)
*ptr++ = mptcp_option(MPTCPOPT_ADD_ADDR, | OPTION_MPTCP_ADD_ADDR6
TCPOLEN_MPTCP_ADD_ADDR, 0, #endif
opts->addr_id); ) & opts->suboptions) {
else u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
*ptr++ = mptcp_option(MPTCPOPT_ADD_ADDR, u8 echo = MPTCP_ADDR_ECHO;
TCPOLEN_MPTCP_ADD_ADDR_BASE,
MPTCP_ADDR_ECHO, #if IS_ENABLED(CONFIG_MPTCP_IPV6)
opts->addr_id); if (OPTION_MPTCP_ADD_ADDR6 & opts->suboptions)
memcpy((u8 *)ptr, (u8 *)&opts->addr.s_addr, 4); len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
ptr += 1; #endif
if (opts->port)
len += TCPOLEN_MPTCP_PORT_LEN;
if (opts->ahmac) { if (opts->ahmac) {
put_unaligned_be64(opts->ahmac, ptr); len += sizeof(opts->ahmac);
ptr += 2; echo = 0;
} }
}
*ptr++ = mptcp_option(MPTCPOPT_ADD_ADDR,
len, echo, opts->addr_id);
if (OPTION_MPTCP_ADD_ADDR & opts->suboptions) {
memcpy((u8 *)ptr, (u8 *)&opts->addr.s_addr, 4);
ptr += 1;
}
#if IS_ENABLED(CONFIG_MPTCP_IPV6) #if IS_ENABLED(CONFIG_MPTCP_IPV6)
if (OPTION_MPTCP_ADD_ADDR6 & opts->suboptions) { else if (OPTION_MPTCP_ADD_ADDR6 & opts->suboptions) {
if (opts->ahmac) memcpy((u8 *)ptr, opts->addr6.s6_addr, 16);
*ptr++ = mptcp_option(MPTCPOPT_ADD_ADDR, ptr += 4;
TCPOLEN_MPTCP_ADD_ADDR6, 0,
opts->addr_id);
else
*ptr++ = mptcp_option(MPTCPOPT_ADD_ADDR,
TCPOLEN_MPTCP_ADD_ADDR6_BASE,
MPTCP_ADDR_ECHO,
opts->addr_id);
memcpy((u8 *)ptr, opts->addr6.s6_addr, 16);
ptr += 4;
if (opts->ahmac) {
put_unaligned_be64(opts->ahmac, ptr);
ptr += 2;
} }
}
#endif #endif
if (!opts->port) {
if (opts->ahmac) {
put_unaligned_be64(opts->ahmac, ptr);
ptr += 2;
}
} else {
if (opts->ahmac) {
u8 *bptr = (u8 *)ptr;
put_unaligned_be16(opts->port, bptr);
bptr += 2;
put_unaligned_be64(opts->ahmac, bptr);
bptr += 8;
put_unaligned_be16(TCPOPT_NOP << 8 |
TCPOPT_NOP, bptr);
ptr += 3;
} else {
put_unaligned_be32(opts->port << 16 |
TCPOPT_NOP << 8 |
TCPOPT_NOP, ptr);
ptr += 1;
}
}
}
if (OPTION_MPTCP_RM_ADDR & opts->suboptions) { if (OPTION_MPTCP_RM_ADDR & opts->suboptions) {
*ptr++ = mptcp_option(MPTCPOPT_RM_ADDR, *ptr++ = mptcp_option(MPTCPOPT_RM_ADDR,
TCPOLEN_MPTCP_RM_ADDR_BASE, TCPOLEN_MPTCP_RM_ADDR_BASE,
......
...@@ -14,28 +14,43 @@ ...@@ -14,28 +14,43 @@
int mptcp_pm_announce_addr(struct mptcp_sock *msk, int mptcp_pm_announce_addr(struct mptcp_sock *msk,
const struct mptcp_addr_info *addr, const struct mptcp_addr_info *addr,
bool echo) bool echo, bool port)
{ {
u8 add_addr = READ_ONCE(msk->pm.add_addr_signal); u8 add_addr = READ_ONCE(msk->pm.addr_signal);
pr_debug("msk=%p, local_id=%d", msk, addr->id); pr_debug("msk=%p, local_id=%d", msk, addr->id);
if (add_addr) {
pr_warn("addr_signal error, add_addr=%d", add_addr);
return -EINVAL;
}
msk->pm.local = *addr; msk->pm.local = *addr;
add_addr |= BIT(MPTCP_ADD_ADDR_SIGNAL); add_addr |= BIT(MPTCP_ADD_ADDR_SIGNAL);
if (echo) if (echo)
add_addr |= BIT(MPTCP_ADD_ADDR_ECHO); add_addr |= BIT(MPTCP_ADD_ADDR_ECHO);
if (addr->family == AF_INET6) if (addr->family == AF_INET6)
add_addr |= BIT(MPTCP_ADD_ADDR_IPV6); add_addr |= BIT(MPTCP_ADD_ADDR_IPV6);
WRITE_ONCE(msk->pm.add_addr_signal, add_addr); if (port)
add_addr |= BIT(MPTCP_ADD_ADDR_PORT);
WRITE_ONCE(msk->pm.addr_signal, add_addr);
return 0; return 0;
} }
int mptcp_pm_remove_addr(struct mptcp_sock *msk, u8 local_id) int mptcp_pm_remove_addr(struct mptcp_sock *msk, u8 local_id)
{ {
u8 rm_addr = READ_ONCE(msk->pm.addr_signal);
pr_debug("msk=%p, local_id=%d", msk, local_id); pr_debug("msk=%p, local_id=%d", msk, local_id);
if (rm_addr) {
pr_warn("addr_signal error, rm_addr=%d", rm_addr);
return -EINVAL;
}
msk->pm.rm_id = local_id; msk->pm.rm_id = local_id;
WRITE_ONCE(msk->pm.rm_addr_signal, true); rm_addr |= BIT(MPTCP_RM_ADDR_SIGNAL);
WRITE_ONCE(msk->pm.addr_signal, rm_addr);
return 0; return 0;
} }
...@@ -156,7 +171,7 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk, ...@@ -156,7 +171,7 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk,
spin_lock_bh(&pm->lock); spin_lock_bh(&pm->lock);
if (!READ_ONCE(pm->accept_addr)) { if (!READ_ONCE(pm->accept_addr)) {
mptcp_pm_announce_addr(msk, addr, true); mptcp_pm_announce_addr(msk, addr, true, addr->port);
mptcp_pm_add_addr_send_ack(msk); mptcp_pm_add_addr_send_ack(msk);
} else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) { } else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) {
pm->remote = *addr; pm->remote = *addr;
...@@ -167,7 +182,8 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk, ...@@ -167,7 +182,8 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk,
void mptcp_pm_add_addr_send_ack(struct mptcp_sock *msk) void mptcp_pm_add_addr_send_ack(struct mptcp_sock *msk)
{ {
if (!mptcp_pm_should_add_signal_ipv6(msk)) if (!mptcp_pm_should_add_signal_ipv6(msk) &&
!mptcp_pm_should_add_signal_port(msk))
return; return;
mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_SEND_ACK); mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_SEND_ACK);
...@@ -188,7 +204,7 @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id) ...@@ -188,7 +204,7 @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id)
/* path manager helpers */ /* path manager helpers */
bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining, bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
struct mptcp_addr_info *saddr, bool *echo) struct mptcp_addr_info *saddr, bool *echo, bool *port)
{ {
int ret = false; int ret = false;
...@@ -199,12 +215,13 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining, ...@@ -199,12 +215,13 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
goto out_unlock; goto out_unlock;
*echo = mptcp_pm_should_add_signal_echo(msk); *echo = mptcp_pm_should_add_signal_echo(msk);
*port = mptcp_pm_should_add_signal_port(msk);
if (remaining < mptcp_add_addr_len(msk->pm.local.family, *echo)) if (remaining < mptcp_add_addr_len(msk->pm.local.family, *echo, *port))
goto out_unlock; goto out_unlock;
*saddr = msk->pm.local; *saddr = msk->pm.local;
WRITE_ONCE(msk->pm.add_addr_signal, 0); WRITE_ONCE(msk->pm.addr_signal, 0);
ret = true; ret = true;
out_unlock: out_unlock:
...@@ -227,7 +244,7 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining, ...@@ -227,7 +244,7 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
goto out_unlock; goto out_unlock;
*rm_id = msk->pm.rm_id; *rm_id = msk->pm.rm_id;
WRITE_ONCE(msk->pm.rm_addr_signal, false); WRITE_ONCE(msk->pm.addr_signal, 0);
ret = true; ret = true;
out_unlock: out_unlock:
...@@ -248,8 +265,7 @@ void mptcp_pm_data_init(struct mptcp_sock *msk) ...@@ -248,8 +265,7 @@ void mptcp_pm_data_init(struct mptcp_sock *msk)
msk->pm.subflows = 0; msk->pm.subflows = 0;
msk->pm.rm_id = 0; msk->pm.rm_id = 0;
WRITE_ONCE(msk->pm.work_pending, false); WRITE_ONCE(msk->pm.work_pending, false);
WRITE_ONCE(msk->pm.add_addr_signal, 0); WRITE_ONCE(msk->pm.addr_signal, 0);
WRITE_ONCE(msk->pm.rm_addr_signal, false);
WRITE_ONCE(msk->pm.accept_addr, false); WRITE_ONCE(msk->pm.accept_addr, false);
WRITE_ONCE(msk->pm.accept_subflow, false); WRITE_ONCE(msk->pm.accept_subflow, false);
msk->pm.status = 0; msk->pm.status = 0;
......
...@@ -227,7 +227,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer) ...@@ -227,7 +227,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
if (!mptcp_pm_should_add_signal(msk)) { if (!mptcp_pm_should_add_signal(msk)) {
pr_debug("retransmit ADD_ADDR id=%d", entry->addr.id); pr_debug("retransmit ADD_ADDR id=%d", entry->addr.id);
mptcp_pm_announce_addr(msk, &entry->addr, false); mptcp_pm_announce_addr(msk, &entry->addr, false, entry->addr.port);
mptcp_pm_add_addr_send_ack(msk); mptcp_pm_add_addr_send_ack(msk);
entry->retrans_times++; entry->retrans_times++;
} }
...@@ -313,7 +313,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) ...@@ -313,7 +313,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
struct mptcp_pm_addr_entry *local; struct mptcp_pm_addr_entry *local;
struct pm_nl_pernet *pernet; struct pm_nl_pernet *pernet;
pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id); pernet = net_generic(sock_net(sk), pm_nl_pernet_id);
pr_debug("local %d:%d signal %d:%d subflows %d:%d\n", pr_debug("local %d:%d signal %d:%d subflows %d:%d\n",
msk->pm.local_addr_used, msk->pm.local_addr_max, msk->pm.local_addr_used, msk->pm.local_addr_max,
...@@ -328,7 +328,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) ...@@ -328,7 +328,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
if (local) { if (local) {
if (mptcp_pm_alloc_anno_list(msk, local)) { if (mptcp_pm_alloc_anno_list(msk, local)) {
msk->pm.add_addr_signaled++; msk->pm.add_addr_signaled++;
mptcp_pm_announce_addr(msk, &local->addr, false); mptcp_pm_announce_addr(msk, &local->addr, false, local->addr.port);
mptcp_pm_nl_add_addr_send_ack(msk); mptcp_pm_nl_add_addr_send_ack(msk);
} }
} else { } else {
...@@ -376,6 +376,7 @@ void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk) ...@@ -376,6 +376,7 @@ void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
struct sock *sk = (struct sock *)msk; struct sock *sk = (struct sock *)msk;
struct mptcp_addr_info remote; struct mptcp_addr_info remote;
struct mptcp_addr_info local; struct mptcp_addr_info local;
bool use_port = false;
pr_debug("accepted %d:%d remote family %d", pr_debug("accepted %d:%d remote family %d",
msk->pm.add_addr_accepted, msk->pm.add_addr_accept_max, msk->pm.add_addr_accepted, msk->pm.add_addr_accept_max,
...@@ -392,14 +393,16 @@ void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk) ...@@ -392,14 +393,16 @@ void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
remote = msk->pm.remote; remote = msk->pm.remote;
if (!remote.port) if (!remote.port)
remote.port = sk->sk_dport; remote.port = sk->sk_dport;
else
use_port = true;
memset(&local, 0, sizeof(local)); memset(&local, 0, sizeof(local));
local.family = remote.family; local.family = remote.family;
spin_unlock_bh(&msk->pm.lock); spin_unlock_bh(&msk->pm.lock);
__mptcp_subflow_connect((struct sock *)msk, &local, &remote); __mptcp_subflow_connect(sk, &local, &remote);
spin_lock_bh(&msk->pm.lock); spin_lock_bh(&msk->pm.lock);
mptcp_pm_announce_addr(msk, &remote, true); mptcp_pm_announce_addr(msk, &remote, true, use_port);
mptcp_pm_nl_add_addr_send_ack(msk); mptcp_pm_nl_add_addr_send_ack(msk);
} }
...@@ -407,7 +410,8 @@ void mptcp_pm_nl_add_addr_send_ack(struct mptcp_sock *msk) ...@@ -407,7 +410,8 @@ void mptcp_pm_nl_add_addr_send_ack(struct mptcp_sock *msk)
{ {
struct mptcp_subflow_context *subflow; struct mptcp_subflow_context *subflow;
if (!mptcp_pm_should_add_signal_ipv6(msk)) if (!mptcp_pm_should_add_signal_ipv6(msk) &&
!mptcp_pm_should_add_signal_port(msk))
return; return;
__mptcp_flush_join_list(msk); __mptcp_flush_join_list(msk);
...@@ -417,15 +421,22 @@ void mptcp_pm_nl_add_addr_send_ack(struct mptcp_sock *msk) ...@@ -417,15 +421,22 @@ void mptcp_pm_nl_add_addr_send_ack(struct mptcp_sock *msk)
u8 add_addr; u8 add_addr;
spin_unlock_bh(&msk->pm.lock); spin_unlock_bh(&msk->pm.lock);
pr_debug("send ack for add_addr6"); if (mptcp_pm_should_add_signal_ipv6(msk))
pr_debug("send ack for add_addr6");
if (mptcp_pm_should_add_signal_port(msk))
pr_debug("send ack for add_addr_port");
lock_sock(ssk); lock_sock(ssk);
tcp_send_ack(ssk); tcp_send_ack(ssk);
release_sock(ssk); release_sock(ssk);
spin_lock_bh(&msk->pm.lock); spin_lock_bh(&msk->pm.lock);
add_addr = READ_ONCE(msk->pm.add_addr_signal); add_addr = READ_ONCE(msk->pm.addr_signal);
add_addr &= ~BIT(MPTCP_ADD_ADDR_IPV6); if (mptcp_pm_should_add_signal_ipv6(msk))
WRITE_ONCE(msk->pm.add_addr_signal, add_addr); add_addr &= ~BIT(MPTCP_ADD_ADDR_IPV6);
if (mptcp_pm_should_add_signal_port(msk))
add_addr &= ~BIT(MPTCP_ADD_ADDR_PORT);
WRITE_ONCE(msk->pm.addr_signal, add_addr);
} }
} }
......
...@@ -49,14 +49,14 @@ ...@@ -49,14 +49,14 @@
#define TCPOLEN_MPTCP_DSS_MAP64 14 #define TCPOLEN_MPTCP_DSS_MAP64 14
#define TCPOLEN_MPTCP_DSS_CHECKSUM 2 #define TCPOLEN_MPTCP_DSS_CHECKSUM 2
#define TCPOLEN_MPTCP_ADD_ADDR 16 #define TCPOLEN_MPTCP_ADD_ADDR 16
#define TCPOLEN_MPTCP_ADD_ADDR_PORT 18 #define TCPOLEN_MPTCP_ADD_ADDR_PORT 20
#define TCPOLEN_MPTCP_ADD_ADDR_BASE 8 #define TCPOLEN_MPTCP_ADD_ADDR_BASE 8
#define TCPOLEN_MPTCP_ADD_ADDR_BASE_PORT 10 #define TCPOLEN_MPTCP_ADD_ADDR_BASE_PORT 12
#define TCPOLEN_MPTCP_ADD_ADDR6 28 #define TCPOLEN_MPTCP_ADD_ADDR6 28
#define TCPOLEN_MPTCP_ADD_ADDR6_PORT 30 #define TCPOLEN_MPTCP_ADD_ADDR6_PORT 32
#define TCPOLEN_MPTCP_ADD_ADDR6_BASE 20 #define TCPOLEN_MPTCP_ADD_ADDR6_BASE 20
#define TCPOLEN_MPTCP_ADD_ADDR6_BASE_PORT 22 #define TCPOLEN_MPTCP_ADD_ADDR6_BASE_PORT 24
#define TCPOLEN_MPTCP_PORT_LEN 2 #define TCPOLEN_MPTCP_PORT_LEN 4
#define TCPOLEN_MPTCP_RM_ADDR_BASE 4 #define TCPOLEN_MPTCP_RM_ADDR_BASE 4
/* MPTCP MP_JOIN flags */ /* MPTCP MP_JOIN flags */
...@@ -168,10 +168,12 @@ enum mptcp_pm_status { ...@@ -168,10 +168,12 @@ enum mptcp_pm_status {
MPTCP_PM_SUBFLOW_ESTABLISHED, MPTCP_PM_SUBFLOW_ESTABLISHED,
}; };
enum mptcp_add_addr_status { enum mptcp_addr_signal_status {
MPTCP_ADD_ADDR_SIGNAL, MPTCP_ADD_ADDR_SIGNAL,
MPTCP_ADD_ADDR_ECHO, MPTCP_ADD_ADDR_ECHO,
MPTCP_ADD_ADDR_IPV6, MPTCP_ADD_ADDR_IPV6,
MPTCP_ADD_ADDR_PORT,
MPTCP_RM_ADDR_SIGNAL,
}; };
struct mptcp_pm_data { struct mptcp_pm_data {
...@@ -181,8 +183,7 @@ struct mptcp_pm_data { ...@@ -181,8 +183,7 @@ struct mptcp_pm_data {
spinlock_t lock; /*protects the whole PM data */ spinlock_t lock; /*protects the whole PM data */
u8 add_addr_signal; u8 addr_signal;
bool rm_addr_signal;
bool server_side; bool server_side;
bool work_pending; bool work_pending;
bool accept_addr; bool accept_addr;
...@@ -551,40 +552,51 @@ mptcp_pm_del_add_timer(struct mptcp_sock *msk, ...@@ -551,40 +552,51 @@ mptcp_pm_del_add_timer(struct mptcp_sock *msk,
int mptcp_pm_announce_addr(struct mptcp_sock *msk, int mptcp_pm_announce_addr(struct mptcp_sock *msk,
const struct mptcp_addr_info *addr, const struct mptcp_addr_info *addr,
bool echo); bool echo, bool port);
int mptcp_pm_remove_addr(struct mptcp_sock *msk, u8 local_id); int mptcp_pm_remove_addr(struct mptcp_sock *msk, u8 local_id);
int mptcp_pm_remove_subflow(struct mptcp_sock *msk, u8 local_id); int mptcp_pm_remove_subflow(struct mptcp_sock *msk, u8 local_id);
static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk) static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk)
{ {
return READ_ONCE(msk->pm.add_addr_signal) & BIT(MPTCP_ADD_ADDR_SIGNAL); return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_ADD_ADDR_SIGNAL);
} }
static inline bool mptcp_pm_should_add_signal_echo(struct mptcp_sock *msk) static inline bool mptcp_pm_should_add_signal_echo(struct mptcp_sock *msk)
{ {
return READ_ONCE(msk->pm.add_addr_signal) & BIT(MPTCP_ADD_ADDR_ECHO); return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_ADD_ADDR_ECHO);
} }
static inline bool mptcp_pm_should_add_signal_ipv6(struct mptcp_sock *msk) static inline bool mptcp_pm_should_add_signal_ipv6(struct mptcp_sock *msk)
{ {
return READ_ONCE(msk->pm.add_addr_signal) & BIT(MPTCP_ADD_ADDR_IPV6); return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_ADD_ADDR_IPV6);
}
static inline bool mptcp_pm_should_add_signal_port(struct mptcp_sock *msk)
{
return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_ADD_ADDR_PORT);
} }
static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk) static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
{ {
return READ_ONCE(msk->pm.rm_addr_signal); return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_RM_ADDR_SIGNAL);
} }
static inline unsigned int mptcp_add_addr_len(int family, bool echo) static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
{ {
if (family == AF_INET) u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
return echo ? TCPOLEN_MPTCP_ADD_ADDR_BASE
: TCPOLEN_MPTCP_ADD_ADDR; if (family == AF_INET6)
return echo ? TCPOLEN_MPTCP_ADD_ADDR6_BASE : TCPOLEN_MPTCP_ADD_ADDR6; len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
if (!echo)
len += MPTCPOPT_THMAC_LEN;
if (port)
len += TCPOLEN_MPTCP_PORT_LEN;
return len;
} }
bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining, bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
struct mptcp_addr_info *saddr, bool *echo); struct mptcp_addr_info *saddr, bool *echo, bool *port);
bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining, bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
u8 *rm_id); u8 *rm_id);
int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc); int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment