Skip to content

Commit 08a45c5

Browse files
committed
Merge branch 'mptcp-part-two'
Christoph Paasch says: ==================== Multipath TCP part 2: Single subflow & RFC8684 support v2 -> v3: Added RFC8684-style handshake (see below fore more details) and some minor fixes v1 -> v2: Rebased on latest "Multipath TCP: Prerequisites" v3 series This set adds MPTCP connection establishment, writing & reading MPTCP options on data packets, a sysctl to allow MPTCP per-namespace, and self tests. This is sufficient to establish and maintain a connection with a MPTCP peer, but will not yet allow or initiate establishment of additional MPTCP subflows. We also add the necessary code for the RFC8684-style handshake. RFC8684 obsoletes the experimental RFC6824 and makes MPTCP move-on to version 1. Originally our plan was to submit single-subflow and RFC8684 support in two patchsets, but to simplify the merging-process and ensure that a coherent MPTCP-version lands in Linux we decided to merge the two sets into a single one. The MPTCP patchset exclusively supports RFC 8684. Although all MPTCP deployments are currently based on RFC 6824, future deployments will be migrating to MPTCP version 1. 3GPP's 5G standardization also solely supports RFC 8684. In addition, we believe that this initial submission of MPTCP will be cleaner by solely supporting RFC 8684. If later on support for the old MPTCP-version is required it can always be added in the future. The major difference between RFC 8684 and RFC 6824 is that it has a better support for servers using TCP SYN-cookies by reliably retransmitting the MP_CAPABLE option. Before ending this cover letter with some refs, it is worth mentioning that we promise David Miller that merging this series will be rewarded by Twitter dopamine hits :-D Clone/fetch: https://github.com/multipath-tcp/mptcp_net-next.git (tag: netdev-v3-part2) Browse: https://github.com/multipath-tcp/mptcp_net-next/tree/netdev-v3-part2 Thank you for your review. You can find us at [email protected] and https://is.gd/mptcp_upstream ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 23f4eac + 8ab183d commit 08a45c5

File tree

25 files changed

+5118
-2
lines changed

25 files changed

+5118
-2
lines changed

MAINTAINERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11583,6 +11583,8 @@ W: https://github.com/multipath-tcp/mptcp_net-next/wiki
1158311583
B: https://github.com/multipath-tcp/mptcp_net-next/issues
1158411584
S: Maintained
1158511585
F: include/net/mptcp.h
11586+
F: net/mptcp/
11587+
F: tools/testing/selftests/net/mptcp/
1158611588

1158711589
NETWORKING [TCP]
1158811590
M: Eric Dumazet <[email protected]>

include/linux/tcp.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,27 @@ struct tcp_sack_block {
7878
#define TCP_SACK_SEEN (1 << 0) /*1 = peer is SACK capable, */
7979
#define TCP_DSACK_SEEN (1 << 2) /*1 = DSACK was received from peer*/
8080

81+
#if IS_ENABLED(CONFIG_MPTCP)
82+
struct mptcp_options_received {
83+
u64 sndr_key;
84+
u64 rcvr_key;
85+
u64 data_ack;
86+
u64 data_seq;
87+
u32 subflow_seq;
88+
u16 data_len;
89+
u8 mp_capable : 1,
90+
mp_join : 1,
91+
dss : 1;
92+
u8 use_map:1,
93+
dsn64:1,
94+
data_fin:1,
95+
use_ack:1,
96+
ack64:1,
97+
mpc_map:1,
98+
__unused:2;
99+
};
100+
#endif
101+
81102
struct tcp_options_received {
82103
/* PAWS/RTTM data */
83104
int ts_recent_stamp;/* Time we stored ts_recent (for aging) */
@@ -95,6 +116,9 @@ struct tcp_options_received {
95116
u8 num_sacks; /* Number of SACK blocks */
96117
u16 user_mss; /* mss requested by user in ioctl */
97118
u16 mss_clamp; /* Maximal mss, negotiated at connection setup */
119+
#if IS_ENABLED(CONFIG_MPTCP)
120+
struct mptcp_options_received mptcp;
121+
#endif
98122
};
99123

100124
static inline void tcp_clear_options(struct tcp_options_received *rx_opt)
@@ -104,6 +128,11 @@ static inline void tcp_clear_options(struct tcp_options_received *rx_opt)
104128
#if IS_ENABLED(CONFIG_SMC)
105129
rx_opt->smc_ok = 0;
106130
#endif
131+
#if IS_ENABLED(CONFIG_MPTCP)
132+
rx_opt->mptcp.mp_capable = 0;
133+
rx_opt->mptcp.mp_join = 0;
134+
rx_opt->mptcp.dss = 0;
135+
#endif
107136
}
108137

109138
/* This is the max number of SACKS that we'll generate and process. It's safe
@@ -119,6 +148,9 @@ struct tcp_request_sock {
119148
const struct tcp_request_sock_ops *af_specific;
120149
u64 snt_synack; /* first SYNACK sent time */
121150
bool tfo_listener;
151+
#if IS_ENABLED(CONFIG_MPTCP)
152+
bool is_mptcp;
153+
#endif
122154
u32 txhash;
123155
u32 rcv_isn;
124156
u32 snt_isn;
@@ -379,6 +411,9 @@ struct tcp_sock {
379411
u32 mtu_info; /* We received an ICMP_FRAG_NEEDED / ICMPV6_PKT_TOOBIG
380412
* while socket was owned by user.
381413
*/
414+
#if IS_ENABLED(CONFIG_MPTCP)
415+
bool is_mptcp;
416+
#endif
382417

383418
#ifdef CONFIG_TCP_MD5SIG
384419
/* TCP AF-Specific parts; only used by MD5 Signature support so far */

include/net/mptcp.h

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#define __NET_MPTCP_H
1010

1111
#include <linux/skbuff.h>
12+
#include <linux/tcp.h>
1213
#include <linux/types.h>
1314

1415
/* MPTCP sk_buff extension data */
@@ -22,12 +23,49 @@ struct mptcp_ext {
2223
data_fin:1,
2324
use_ack:1,
2425
ack64:1,
25-
__unused:3;
26+
mpc_map:1,
27+
__unused:2;
2628
/* one byte hole */
2729
};
2830

31+
struct mptcp_out_options {
32+
#if IS_ENABLED(CONFIG_MPTCP)
33+
u16 suboptions;
34+
u64 sndr_key;
35+
u64 rcvr_key;
36+
struct mptcp_ext ext_copy;
37+
#endif
38+
};
39+
2940
#ifdef CONFIG_MPTCP
3041

42+
void mptcp_init(void);
43+
44+
static inline bool sk_is_mptcp(const struct sock *sk)
45+
{
46+
return tcp_sk(sk)->is_mptcp;
47+
}
48+
49+
static inline bool rsk_is_mptcp(const struct request_sock *req)
50+
{
51+
return tcp_rsk(req)->is_mptcp;
52+
}
53+
54+
void mptcp_parse_option(const struct sk_buff *skb, const unsigned char *ptr,
55+
int opsize, struct tcp_options_received *opt_rx);
56+
bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
57+
unsigned int *size, struct mptcp_out_options *opts);
58+
void mptcp_rcv_synsent(struct sock *sk);
59+
bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,
60+
struct mptcp_out_options *opts);
61+
bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
62+
unsigned int *size, unsigned int remaining,
63+
struct mptcp_out_options *opts);
64+
void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb,
65+
struct tcp_options_received *opt_rx);
66+
67+
void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts);
68+
3169
/* move the skb extension owership, with the assumption that 'to' is
3270
* newly allocated
3371
*/
@@ -70,6 +108,59 @@ static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
70108

71109
#else
72110

111+
static inline void mptcp_init(void)
112+
{
113+
}
114+
115+
static inline bool sk_is_mptcp(const struct sock *sk)
116+
{
117+
return false;
118+
}
119+
120+
static inline bool rsk_is_mptcp(const struct request_sock *req)
121+
{
122+
return false;
123+
}
124+
125+
static inline void mptcp_parse_option(const struct sk_buff *skb,
126+
const unsigned char *ptr, int opsize,
127+
struct tcp_options_received *opt_rx)
128+
{
129+
}
130+
131+
static inline bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
132+
unsigned int *size,
133+
struct mptcp_out_options *opts)
134+
{
135+
return false;
136+
}
137+
138+
static inline void mptcp_rcv_synsent(struct sock *sk)
139+
{
140+
}
141+
142+
static inline bool mptcp_synack_options(const struct request_sock *req,
143+
unsigned int *size,
144+
struct mptcp_out_options *opts)
145+
{
146+
return false;
147+
}
148+
149+
static inline bool mptcp_established_options(struct sock *sk,
150+
struct sk_buff *skb,
151+
unsigned int *size,
152+
unsigned int remaining,
153+
struct mptcp_out_options *opts)
154+
{
155+
return false;
156+
}
157+
158+
static inline void mptcp_incoming_options(struct sock *sk,
159+
struct sk_buff *skb,
160+
struct tcp_options_received *opt_rx)
161+
{
162+
}
163+
73164
static inline void mptcp_skb_ext_move(struct sk_buff *to,
74165
const struct sk_buff *from)
75166
{
@@ -82,4 +173,16 @@ static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
82173
}
83174

84175
#endif /* CONFIG_MPTCP */
176+
177+
void mptcp_handle_ipv6_mapped(struct sock *sk, bool mapped);
178+
179+
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
180+
int mptcpv6_init(void);
181+
#elif IS_ENABLED(CONFIG_IPV6)
182+
static inline int mptcpv6_init(void)
183+
{
184+
return 0;
185+
}
186+
#endif
187+
85188
#endif /* __NET_MPTCP_H */

net/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ if INET
9191
source "net/ipv4/Kconfig"
9292
source "net/ipv6/Kconfig"
9393
source "net/netlabel/Kconfig"
94+
source "net/mptcp/Kconfig"
9495

9596
endif # if INET
9697

net/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,4 @@ endif
8787
obj-$(CONFIG_QRTR) += qrtr/
8888
obj-$(CONFIG_NET_NCSI) += ncsi/
8989
obj-$(CONFIG_XDP_SOCKETS) += xdp/
90+
obj-$(CONFIG_MPTCP) += mptcp/

net/ipv4/tcp.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@
271271
#include <net/icmp.h>
272272
#include <net/inet_common.h>
273273
#include <net/tcp.h>
274+
#include <net/mptcp.h>
274275
#include <net/xfrm.h>
275276
#include <net/ip.h>
276277
#include <net/sock.h>
@@ -4021,4 +4022,5 @@ void __init tcp_init(void)
40214022
tcp_metrics_init();
40224023
BUG_ON(tcp_register_congestion_control(&tcp_reno) != 0);
40234024
tcp_tasklet_init();
4025+
mptcp_init();
40244026
}

net/ipv4/tcp_input.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
#include <trace/events/tcp.h>
8080
#include <linux/jump_label_ratelimit.h>
8181
#include <net/busy_poll.h>
82+
#include <net/mptcp.h>
8283

8384
int sysctl_tcp_max_orphans __read_mostly = NR_FILE;
8485

@@ -3924,6 +3925,10 @@ void tcp_parse_options(const struct net *net,
39243925
*/
39253926
break;
39263927
#endif
3928+
case TCPOPT_MPTCP:
3929+
mptcp_parse_option(skb, ptr, opsize, opt_rx);
3930+
break;
3931+
39273932
case TCPOPT_FASTOPEN:
39283933
tcp_parse_fastopen_option(
39293934
opsize - TCPOLEN_FASTOPEN_BASE,
@@ -4765,6 +4770,9 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
47654770
bool fragstolen;
47664771
int eaten;
47674772

4773+
if (sk_is_mptcp(sk))
4774+
mptcp_incoming_options(sk, skb, &tp->rx_opt);
4775+
47684776
if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) {
47694777
__kfree_skb(skb);
47704778
return;
@@ -5973,6 +5981,9 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
59735981
tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
59745982
tcp_initialize_rcv_mss(sk);
59755983

5984+
if (sk_is_mptcp(sk))
5985+
mptcp_rcv_synsent(sk);
5986+
59765987
/* Remember, tcp_poll() does not lock socket!
59775988
* Change state from SYN-SENT only after copied_seq
59785989
* is initialized. */
@@ -6338,8 +6349,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
63386349
case TCP_CLOSE_WAIT:
63396350
case TCP_CLOSING:
63406351
case TCP_LAST_ACK:
6341-
if (!before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt))
6352+
if (!before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) {
6353+
if (sk_is_mptcp(sk))
6354+
mptcp_incoming_options(sk, skb, &tp->rx_opt);
63426355
break;
6356+
}
63436357
/* fall through */
63446358
case TCP_FIN_WAIT1:
63456359
case TCP_FIN_WAIT2:
@@ -6595,6 +6609,9 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
65956609

65966610
tcp_rsk(req)->af_specific = af_ops;
65976611
tcp_rsk(req)->ts_off = 0;
6612+
#if IS_ENABLED(CONFIG_MPTCP)
6613+
tcp_rsk(req)->is_mptcp = 0;
6614+
#endif
65986615

65996616
tcp_clear_options(&tmp_opt);
66006617
tmp_opt.mss_clamp = af_ops->mss_clamp;

0 commit comments

Comments
 (0)