Commit c189b548 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mptcp-multiple-subflows-path-management'



Mat Martineau says:

====================
Multipath TCP part 3: Multiple subflows and path management

v2 -> v3: Remove 'inline' in .c files, fix uapi bit macros, and rebase.

v1 -> v2: Rebase on current net-next, fix for netlink limit setting,
and update .gitignore for selftest.

This patch set allows more than one TCP subflow to be established and
used for a multipath TCP connection. Subflows are added to an existing
connection using the MP_JOIN option during the 3-way handshake. With
multiple TCP subflows available, sent data is now stored in the MPTCP
socket so it may be retransmitted on any TCP subflow if there is no
DATA_ACK before a timeout. If an MPTCP-level timeout occurs, data is
retransmitted using an available subflow. Storing this sent data
requires the addition of memory accounting at the MPTCP level, which was
previously delegated to the single subflow. Incoming DATA_ACKs now free
data from the MPTCP-level retransmit buffer.

IP addresses available for new subflow connections can now be advertised
and received with the ADD_ADDR option, and the corresponding REMOVE_ADDR
option likewise advertises that an address is no longer available.

The MPTCP path manager netlink interface has commands to set in-kernel
limits for the number of concurrent subflows and control the
advertisement of IP addresses between peers.

To track and debug MPTCP connections there are new MPTCP MIB counters,
and subflow context can be requested using inet_diag. The MPTCP
self-tests now validate multiple-subflow operation and the netlink path
manager interface.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 41b14502 b08fbf24
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -11727,6 +11727,7 @@ W: https://github.com/multipath-tcp/mptcp_net-next/wiki
B:	https://github.com/multipath-tcp/mptcp_net-next/issues
S:	Maintained
F:	include/net/mptcp.h
F:	include/uapi/linux/mptcp.h
F:	net/mptcp/
F:	tools/testing/selftests/net/mptcp/
+24 −2
Original line number Diff line number Diff line
@@ -86,9 +86,19 @@ struct mptcp_options_received {
	u64	data_seq;
	u32	subflow_seq;
	u16	data_len;
	u8	mp_capable : 1,
	u16	mp_capable : 1,
		mp_join : 1,
		dss : 1;
		dss : 1,
		add_addr : 1,
		rm_addr : 1,
		family : 4,
		echo : 1,
		backup : 1;
	u32	token;
	u32	nonce;
	u64	thmac;
	u8	hmac[20];
	u8	join_id;
	u8	use_map:1,
		dsn64:1,
		data_fin:1,
@@ -96,6 +106,16 @@ struct mptcp_options_received {
		ack64:1,
		mpc_map:1,
		__unused:2;
	u8	addr_id;
	u8	rm_id;
	union {
		struct in_addr	addr;
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
		struct in6_addr	addr6;
#endif
	};
	u64	ahmac;
	u16	port;
};
#endif

@@ -131,6 +151,8 @@ static inline void tcp_clear_options(struct tcp_options_received *rx_opt)
#if IS_ENABLED(CONFIG_MPTCP)
	rx_opt->mptcp.mp_capable = 0;
	rx_opt->mptcp.mp_join = 0;
	rx_opt->mptcp.add_addr = 0;
	rx_opt->mptcp.rm_addr = 0;
	rx_opt->mptcp.dss = 0;
#endif
}
+26 −0
Original line number Diff line number Diff line
@@ -12,6 +12,8 @@
#include <linux/tcp.h>
#include <linux/types.h>

struct seq_file;

/* MPTCP sk_buff extension data */
struct mptcp_ext {
	u64		data_ack;
@@ -33,6 +35,21 @@ struct mptcp_out_options {
	u16 suboptions;
	u64 sndr_key;
	u64 rcvr_key;
	union {
		struct in_addr addr;
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
		struct in6_addr addr6;
#endif
	};
	u8 addr_id;
	u64 ahmac;
	u8 rm_id;
	u8 join_id;
	u8 backup;
	u32 nonce;
	u64 thmac;
	u32 token;
	u8 hmac[20];
	struct mptcp_ext ext_copy;
#endif
};
@@ -106,6 +123,9 @@ static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
				 skb_ext_find(from, SKB_EXT_MPTCP));
}

bool mptcp_sk_is_subflow(const struct sock *sk);

void mptcp_seq_show(struct seq_file *seq);
#else

static inline void mptcp_init(void)
@@ -172,6 +192,12 @@ static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
	return true;
}

static inline bool mptcp_sk_is_subflow(const struct sock *sk)
{
	return false;
}

static inline void mptcp_seq_show(struct seq_file *seq) { }
#endif /* CONFIG_MPTCP */

#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+3 −0
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@ struct netns_mib {
#if IS_ENABLED(CONFIG_TLS)
	DEFINE_SNMP_STAT(struct linux_tls_mib, tls_statistics);
#endif
#ifdef CONFIG_MPTCP
	DEFINE_SNMP_STAT(struct mptcp_mib, mptcp_statistics);
#endif
};

#endif
+1 −0
Original line number Diff line number Diff line
@@ -166,6 +166,7 @@ enum {
	INET_ULP_INFO_UNSPEC,
	INET_ULP_INFO_NAME,
	INET_ULP_INFO_TLS,
	INET_ULP_INFO_MPTCP,
	__INET_ULP_INFO_MAX,
};
#define INET_ULP_INFO_MAX (__INET_ULP_INFO_MAX - 1)
Loading