History

mptcp: move option parsing into mptcp_incoming_options()

The mptcp_options_received structure carries several per packet flags (mp_capable, mp_join, etc.). Such fields must be cleared on each packet, even on dropped ones or packet not carrying any MPTCP options, but the current mptcp code clears them only on TCP option reset. On several races/corner cases we end-up with stray bits in incoming options, leading to WARN_ON splats. e.g.: [ 171.164906] Bad mapping: ssn=32714 map_seq=1 map_data_len=32713 [ 171.165006] WARNING: CPU: 1 PID: 5026 at net/mptcp/subflow.c:533 warn_bad_map (linux-mptcp/net/mptcp/subflow.c:533 linux-mptcp/net/mptcp/subflow.c:531) [ 171.167632] Modules linked in: ip6_vti ip_vti ip_gre ipip sit tunnel4 ip_tunnel geneve ip6_udp_tunnel udp_tunnel macsec macvtap tap ipvlan macvlan 8021q garp mrp xfrm_interface veth netdevsim nlmon dummy team bonding vcan bridge stp llc ip6_gre gre ip6_tunnel tunnel6 tun binfmt_misc intel_rapl_msr intel_rapl_common rfkill kvm_intel kvm irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel joydev virtio_balloon pcspkr i2c_piix4 sunrpc ip_tables xfs libcrc32c crc32c_intel serio_raw virtio_console ata_generic virtio_blk virtio_net net_failover failover ata_piix libata [ 171.199464] CPU: 1 PID: 5026 Comm: repro Not tainted 5.7.0-rc1.mptcp_f227fdf5d388+ #95 [ 171.200886] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-2.fc30 04/01/2014 [ 171.202546] RIP: 0010:warn_bad_map (linux-mptcp/net/mptcp/subflow.c:533 linux-mptcp/net/mptcp/subflow.c:531) [ 171.206537] Code: c1 ea 03 0f b6 14 02 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 04 84 d2 75 1d 8b 55 3c 44 89 e6 48 c7 c7 20 51 13 95 e8 37 8b 22 fe <0f> 0b 48 83 c4 08 5b 5d 41 5c c3 89 4c 24 04 e8 db d6 94 fe 8b 4c [ 171.220473] RSP: 0018:ffffc90000150560 EFLAGS: 00010282 [ 171.221639] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 [ 171.223108] RDX: 0000000000000000 RSI: 0000000000000008 RDI: fffff5200002a09e [ 171.224388] RBP: ffff8880aa6e3c00 R08: 0000000000000001 R09: fffffbfff2ec9955 [ 171.225706] R10: ffffffff9764caa7 R11: fffffbfff2ec9954 R12: 0000000000007fca [ 171.227211] R13: ffff8881066f4a7f R14: ffff8880aa6e3c00 R15: 0000000000000020 [ 171.228460] FS: 00007f8623719740(0000) GS:ffff88810be00000(0000) knlGS:0000000000000000 [ 171.230065] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 171.231303] CR2: 00007ffdab190a50 CR3: 00000001038ea006 CR4: 0000000000160ee0 [ 171.232586] Call Trace: [ 171.233109] <IRQ> [ 171.233531] get_mapping_status (linux-mptcp/net/mptcp/subflow.c:691) [ 171.234371] mptcp_subflow_data_available (linux-mptcp/net/mptcp/subflow.c:736 linux-mptcp/net/mptcp/subflow.c:832) [ 171.238181] subflow_state_change (linux-mptcp/net/mptcp/subflow.c:1085 (discriminator 1)) [ 171.239066] tcp_fin (linux-mptcp/net/ipv4/tcp_input.c:4217) [ 171.240123] tcp_data_queue (linux-mptcp/./include/linux/compiler.h:199 linux-mptcp/net/ipv4/tcp_input.c:4822) [ 171.245083] tcp_rcv_established (linux-mptcp/./include/linux/skbuff.h:1785 linux-mptcp/./include/net/tcp.h:1774 linux-mptcp/./include/net/tcp.h:1847 linux-mptcp/net/ipv4/tcp_input.c:5238 linux-mptcp/net/ipv4/tcp_input.c:5730) [ 171.254089] tcp_v4_rcv (linux-mptcp/./include/linux/spinlock.h:393 linux-mptcp/net/ipv4/tcp_ipv4.c:2009) [ 171.258969] ip_protocol_deliver_rcu (linux-mptcp/net/ipv4/ip_input.c:204 (discriminator 1)) [ 171.260214] ip_local_deliver_finish (linux-mptcp/./include/linux/rcupdate.h:651 linux-mptcp/net/ipv4/ip_input.c:232) [ 171.261389] ip_local_deliver (linux-mptcp/./include/linux/netfilter.h:307 linux-mptcp/./include/linux/netfilter.h:301 linux-mptcp/net/ipv4/ip_input.c:252) [ 171.265884] ip_rcv (linux-mptcp/./include/linux/netfilter.h:307 linux-mptcp/./include/linux/netfilter.h:301 linux-mptcp/net/ipv4/ip_input.c:539) [ 171.273666] process_backlog (linux-mptcp/./include/linux/rcupdate.h:651 linux-mptcp/net/core/dev.c:6135) [ 171.275328] net_rx_action (linux-mptcp/net/core/dev.c:6572 linux-mptcp/net/core/dev.c:6640) [ 171.280472] __do_softirq (linux-mptcp/./arch/x86/include/asm/jump_label.h:25 linux-mptcp/./include/linux/jump_label.h:200 linux-mptcp/./include/trace/events/irq.h:142 linux-mptcp/kernel/softirq.c:293) [ 171.281379] do_softirq_own_stack (linux-mptcp/arch/x86/entry/entry_64.S:1083) [ 171.282358] </IRQ> We could address the issue clearing explicitly the relevant fields in several places - tcp_parse_option, tcp_fast_parse_options, possibly others. Instead we move the MPTCP option parsing into the already existing mptcp ingress hook, so that we need to clear the fields in a single place. This allows us dropping an MPTCP hook from the TCP code and removing the quite large mptcp_options_received from the tcp_sock struct. On the flip side, the MPTCP sockets will traverse the option space twice (in tcp_parse_option() and in mptcp_incoming_options(). That looks acceptable: we already do that for syn and 3rd ack packets, plain TCP socket will benefit from it, and even MPTCP sockets will experience better code locality, reducing the jumps between TCP and MPTCP code. v1 -> v2: - rebased on current '-net' tree

Paolo Abeni committed 6 years ago

Commit cfde1411 parent 263e1207 files · +115 −122Browse files

Unified · Split

7 files
  1. include/linux/tcp.h +0 −51
  2. include/net/mptcp.h +0 −2
  3. net/ipv4/tcp_input.c +0 −4
  4. net/mptcp/options.c +37 −29
  5. net/mptcp/protocol.c +3 −3
  6. net/mptcp/protocol.h +41 −2
  7. net/mptcp/subflow.c +34 −31
include/linux/tcp.h+0−51
@@ -78,47 +78,6 @@ struct tcp_sack_block { · 77 unmodified lines
78#define TCP_SACK_SEEN (1 << 0) /*1 = peer is SACK capable, */78#define TCP_SACK_SEEN (1 << 0) /*1 = peer is SACK capable, */
79#define TCP_DSACK_SEEN (1 << 2) /*1 = DSACK was received from peer*/79#define TCP_DSACK_SEEN (1 << 2) /*1 = DSACK was received from peer*/
80 80
81#if IS_ENABLED(CONFIG_MPTCP)
82struct 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 u16 mp_capable : 1,
90 mp_join : 1,
91 dss : 1,
92 add_addr : 1,
93 rm_addr : 1,
94 family : 4,
95 echo : 1,
96 backup : 1;
97 u32 token;
98 u32 nonce;
99 u64 thmac;
100 u8 hmac[20];
101 u8 join_id;
102 u8 use_map:1,
103 dsn64:1,
104 data_fin:1,
105 use_ack:1,
106 ack64:1,
107 mpc_map:1,
108 __unused:2;
109 u8 addr_id;
110 u8 rm_id;
111 union {
112 struct in_addr addr;
113#if IS_ENABLED(CONFIG_MPTCP_IPV6)
114 struct in6_addr addr6;
115#endif
116 };
117 u64 ahmac;
118 u16 port;
119};
120#endif
121
122struct tcp_options_received {81struct tcp_options_received {
123/* PAWS/RTTM data */82/* PAWS/RTTM data */
124 int ts_recent_stamp;/* Time we stored ts_recent (for aging) */83 int ts_recent_stamp;/* Time we stored ts_recent (for aging) */
@@ -136,9 +95,6 @@ struct tcp_options_received { · 11 unmodified lines
136 u8 num_sacks; /* Number of SACK blocks */95 u8 num_sacks; /* Number of SACK blocks */
137 u16 user_mss; /* mss requested by user in ioctl */96 u16 user_mss; /* mss requested by user in ioctl */
138 u16 mss_clamp; /* Maximal mss, negotiated at connection setup */97 u16 mss_clamp; /* Maximal mss, negotiated at connection setup */
139#if IS_ENABLED(CONFIG_MPTCP)
140 struct mptcp_options_received mptcp;
141#endif
142};98};
143 99
144static inline void tcp_clear_options(struct tcp_options_received *rx_opt)100static inline void tcp_clear_options(struct tcp_options_received *rx_opt)
@@ -148,13 +104,6 @@ static inline void tcp_clear_options(struct tcp_options_received *rx_opt) · 3 unmodified lines
148#if IS_ENABLED(CONFIG_SMC)104#if IS_ENABLED(CONFIG_SMC)
149 rx_opt->smc_ok = 0;105 rx_opt->smc_ok = 0;
150#endif106#endif
151#if IS_ENABLED(CONFIG_MPTCP)
152 rx_opt->mptcp.mp_capable = 0;
153 rx_opt->mptcp.mp_join = 0;
154 rx_opt->mptcp.add_addr = 0;
155 rx_opt->mptcp.rm_addr = 0;
156 rx_opt->mptcp.dss = 0;
157#endif
158}107}
159 108
160/* This is the max number of SACKS that we'll generate and process. It's safe109/* This is the max number of SACKS that we'll generate and process. It's safe
include/net/mptcp.h+0−2
@@ -68,8 +68,6 @@ static inline bool rsk_is_mptcp(const struct request_sock *req) · 67 unmodified lines
68 return tcp_rsk(req)->is_mptcp;68 return tcp_rsk(req)->is_mptcp;
69}69}
70 70
71void mptcp_parse_option(const struct sk_buff *skb, const unsigned char *ptr,
72 int opsize, struct tcp_options_received *opt_rx);
73bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,71bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
74 unsigned int *size, struct mptcp_out_options *opts);72 unsigned int *size, struct mptcp_out_options *opts);
75bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,73bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,
net/ipv4/tcp_input.c+0−4
@@ -3926,10 +3926,6 @@ void tcp_parse_options(const struct net *net, · 3925 unmodified lines
3926 */3926 */
3927 break;3927 break;
3928#endif3928#endif
3929 case TCPOPT_MPTCP:
3930 mptcp_parse_option(skb, ptr, opsize, opt_rx);
3931 break;
3932
3933 case TCPOPT_FASTOPEN:3929 case TCPOPT_FASTOPEN:
3934 tcp_parse_fastopen_option(3930 tcp_parse_fastopen_option(
3935 opsize - TCPOLEN_FASTOPEN_BASE,3931 opsize - TCPOLEN_FASTOPEN_BASE,
net/mptcp/options.c+37−29
@@ -16,10 +16,10 @@ static bool mptcp_cap_flag_sha256(u8 flags) · 15 unmodified lines
16 return (flags & MPTCP_CAP_FLAG_MASK) == MPTCP_CAP_HMAC_SHA256;16 return (flags & MPTCP_CAP_FLAG_MASK) == MPTCP_CAP_HMAC_SHA256;
17}17}
18 18
19void mptcp_parse_option(const struct sk_buff *skb, const unsigned char *ptr,19static void mptcp_parse_option(const struct sk_buff *skb,
20 int opsize, struct tcp_options_received *opt_rx)20 const unsigned char *ptr, int opsize,
21 struct mptcp_options_received *mp_opt)
21{22{
22 struct mptcp_options_received *mp_opt = &opt_rx->mptcp;
23 u8 subtype = *ptr >> 4;23 u8 subtype = *ptr >> 4;
24 int expected_opsize;24 int expected_opsize;
25 u8 version;25 u8 version;
@@ -283,12 +283,20 @@ void mptcp_parse_option(const struct sk_buff *skb, const unsigned char *ptr, · 257 unmodified lines
283}283}
284 284
285void mptcp_get_options(const struct sk_buff *skb,285void mptcp_get_options(const struct sk_buff *skb,
286 struct tcp_options_received *opt_rx)286 struct mptcp_options_received *mp_opt)
287{287{
288 const unsigned char *ptr;
289 const struct tcphdr *th = tcp_hdr(skb);288 const struct tcphdr *th = tcp_hdr(skb);
290 int length = (th->doff * 4) - sizeof(struct tcphdr);289 const unsigned char *ptr;
290 int length;
291 291
292 /* initialize option status */
293 mp_opt->mp_capable = 0;
294 mp_opt->mp_join = 0;
295 mp_opt->add_addr = 0;
296 mp_opt->rm_addr = 0;
297 mp_opt->dss = 0;
298
299 length = (th->doff * 4) - sizeof(struct tcphdr);
292 ptr = (const unsigned char *)(th + 1);300 ptr = (const unsigned char *)(th + 1);
293 301
294 while (length > 0) {302 while (length > 0) {
@@ -308,7 +316,7 @@ void mptcp_get_options(const struct sk_buff *skb, · 13 unmodified lines
308 if (opsize > length)316 if (opsize > length)
309 return; /* don't parse partial options */317 return; /* don't parse partial options */
310 if (opcode == TCPOPT_MPTCP)318 if (opcode == TCPOPT_MPTCP)
311 mptcp_parse_option(skb, ptr, opsize, opt_rx);319 mptcp_parse_option(skb, ptr, opsize, mp_opt);
312 ptr += opsize - 2;320 ptr += opsize - 2;
313 length -= opsize;321 length -= opsize;
314 }322 }
@@ -797,41 +805,41 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb, · 482 unmodified lines
797{805{
798 struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);806 struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
799 struct mptcp_sock *msk = mptcp_sk(subflow->conn);807 struct mptcp_sock *msk = mptcp_sk(subflow->conn);
800 struct mptcp_options_received *mp_opt;808 struct mptcp_options_received mp_opt;
801 struct mptcp_ext *mpext;809 struct mptcp_ext *mpext;
802 810
803 mp_opt = &opt_rx->mptcp;811 mptcp_get_options(skb, &mp_opt);
804 if (!check_fully_established(msk, sk, subflow, skb, mp_opt))812 if (!check_fully_established(msk, sk, subflow, skb, &mp_opt))
805 return;813 return;
806 814
807 if (mp_opt->add_addr && add_addr_hmac_valid(msk, mp_opt)) {815 if (mp_opt.add_addr && add_addr_hmac_valid(msk, &mp_opt)) {
808 struct mptcp_addr_info addr;816 struct mptcp_addr_info addr;
809 817
810 addr.port = htons(mp_opt->port);818 addr.port = htons(mp_opt.port);
811 addr.id = mp_opt->addr_id;819 addr.id = mp_opt.addr_id;
812 if (mp_opt->family == MPTCP_ADDR_IPVERSION_4) {820 if (mp_opt.family == MPTCP_ADDR_IPVERSION_4) {
813 addr.family = AF_INET;821 addr.family = AF_INET;
814 addr.addr = mp_opt->addr;822 addr.addr = mp_opt.addr;
815 }823 }
816#if IS_ENABLED(CONFIG_MPTCP_IPV6)824#if IS_ENABLED(CONFIG_MPTCP_IPV6)
817 else if (mp_opt->family == MPTCP_ADDR_IPVERSION_6) {825 else if (mp_opt.family == MPTCP_ADDR_IPVERSION_6) {
818 addr.family = AF_INET6;826 addr.family = AF_INET6;
819 addr.addr6 = mp_opt->addr6;827 addr.addr6 = mp_opt.addr6;
820 }828 }
821#endif829#endif
822 if (!mp_opt->echo)830 if (!mp_opt.echo)
823 mptcp_pm_add_addr_received(msk, &addr);831 mptcp_pm_add_addr_received(msk, &addr);
824 mp_opt->add_addr = 0;832 mp_opt.add_addr = 0;
825 }833 }
826 834
827 if (!mp_opt->dss)835 if (!mp_opt.dss)
828 return;836 return;
829 837
830 /* we can't wait for recvmsg() to update the ack_seq, otherwise838 /* we can't wait for recvmsg() to update the ack_seq, otherwise
831 * monodirectional flows will stuck839 * monodirectional flows will stuck
832 */840 */
833 if (mp_opt->use_ack)841 if (mp_opt.use_ack)
834 update_una(msk, mp_opt);842 update_una(msk, &mp_opt);
835 843
836 mpext = skb_ext_add(skb, SKB_EXT_MPTCP);844 mpext = skb_ext_add(skb, SKB_EXT_MPTCP);
837 if (!mpext)845 if (!mpext)
@@ -839,8 +847,8 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb, · 1 unmodified line
839 847
840 memset(mpext, 0, sizeof(*mpext));848 memset(mpext, 0, sizeof(*mpext));
841 849
842 if (mp_opt->use_map) {850 if (mp_opt.use_map) {
843 if (mp_opt->mpc_map) {851 if (mp_opt.mpc_map) {
844 /* this is an MP_CAPABLE carrying MPTCP data852 /* this is an MP_CAPABLE carrying MPTCP data
845 * we know this map the first chunk of data853 * we know this map the first chunk of data
846 */854 */
@@ -851,12 +859,12 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb, · 4 unmodified lines
851 mpext->dsn64 = 1;859 mpext->dsn64 = 1;
852 mpext->mpc_map = 1;860 mpext->mpc_map = 1;
853 } else {861 } else {
854 mpext->data_seq = mp_opt->data_seq;862 mpext->data_seq = mp_opt.data_seq;
855 mpext->subflow_seq = mp_opt->subflow_seq;863 mpext->subflow_seq = mp_opt.subflow_seq;
856 mpext->dsn64 = mp_opt->dsn64;864 mpext->dsn64 = mp_opt.dsn64;
857 mpext->data_fin = mp_opt->data_fin;865 mpext->data_fin = mp_opt.data_fin;
858 }866 }
859 mpext->data_len = mp_opt->data_len;867 mpext->data_len = mp_opt.data_len;
860 mpext->use_map = 1;868 mpext->use_map = 1;
861 }869 }
862}870}
net/mptcp/protocol.c+3−3
@@ -1334,7 +1334,7 @@ static struct ipv6_pinfo *mptcp_inet6_sk(const struct sock *sk) · 1333 unmodified lines
1334#endif1334#endif
1335 1335
1336struct sock *mptcp_sk_clone(const struct sock *sk,1336struct sock *mptcp_sk_clone(const struct sock *sk,
1337 const struct tcp_options_received *opt_rx,1337 const struct mptcp_options_received *mp_opt,
1338 struct request_sock *req)1338 struct request_sock *req)
1339{1339{
1340 struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);1340 struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
@@ -1373,9 +1373,9 @@ struct sock *mptcp_sk_clone(const struct sock *sk, · 32 unmodified lines
1373 1373
1374 msk->write_seq = subflow_req->idsn + 1;1374 msk->write_seq = subflow_req->idsn + 1;
1375 atomic64_set(&msk->snd_una, msk->write_seq);1375 atomic64_set(&msk->snd_una, msk->write_seq);
1376 if (opt_rx->mptcp.mp_capable) {1376 if (mp_opt->mp_capable) {
1377 msk->can_ack = true;1377 msk->can_ack = true;
1378 msk->remote_key = opt_rx->mptcp.sndr_key;1378 msk->remote_key = mp_opt->sndr_key;
1379 mptcp_crypto_key_sha(msk->remote_key, NULL, &ack_seq);1379 mptcp_crypto_key_sha(msk->remote_key, NULL, &ack_seq);
1380 ack_seq++;1380 ack_seq++;
1381 msk->ack_seq = ack_seq;1381 msk->ack_seq = ack_seq;
net/mptcp/protocol.h+41−2
@@ -91,6 +91,45 @@ · 90 unmodified lines
91#define MPTCP_WORK_RTX 291#define MPTCP_WORK_RTX 2
92#define MPTCP_WORK_EOF 392#define MPTCP_WORK_EOF 3
93 93
94struct mptcp_options_received {
95 u64 sndr_key;
96 u64 rcvr_key;
97 u64 data_ack;
98 u64 data_seq;
99 u32 subflow_seq;
100 u16 data_len;
101 u16 mp_capable : 1,
102 mp_join : 1,
103 dss : 1,
104 add_addr : 1,
105 rm_addr : 1,
106 family : 4,
107 echo : 1,
108 backup : 1;
109 u32 token;
110 u32 nonce;
111 u64 thmac;
112 u8 hmac[20];
113 u8 join_id;
114 u8 use_map:1,
115 dsn64:1,
116 data_fin:1,
117 use_ack:1,
118 ack64:1,
119 mpc_map:1,
120 __unused:2;
121 u8 addr_id;
122 u8 rm_id;
123 union {
124 struct in_addr addr;
125#if IS_ENABLED(CONFIG_MPTCP_IPV6)
126 struct in6_addr addr6;
127#endif
128 };
129 u64 ahmac;
130 u16 port;
131};
132
94static inline __be32 mptcp_option(u8 subopt, u8 len, u8 nib, u8 field)133static inline __be32 mptcp_option(u8 subopt, u8 len, u8 nib, u8 field)
95{134{
96 return htonl((TCPOPT_MPTCP << 24) | (len << 16) | (subopt << 12) |135 return htonl((TCPOPT_MPTCP << 24) | (len << 16) | (subopt << 12) |
@@ -331,10 +370,10 @@ int mptcp_proto_v6_init(void); · 234 unmodified lines
331#endif370#endif
332 371
333struct sock *mptcp_sk_clone(const struct sock *sk,372struct sock *mptcp_sk_clone(const struct sock *sk,
334 const struct tcp_options_received *opt_rx,373 const struct mptcp_options_received *mp_opt,
335 struct request_sock *req);374 struct request_sock *req);
336void mptcp_get_options(const struct sk_buff *skb,375void mptcp_get_options(const struct sk_buff *skb,
337 struct tcp_options_received *opt_rx);376 struct mptcp_options_received *mp_opt);
338 377
339void mptcp_finish_connect(struct sock *sk);378void mptcp_finish_connect(struct sock *sk);
340void mptcp_data_ready(struct sock *sk, struct sock *ssk);379void mptcp_data_ready(struct sock *sk, struct sock *ssk);
net/mptcp/subflow.c+34−31
@@ -124,12 +124,11 @@ static void subflow_init_req(struct request_sock *req, · 123 unmodified lines
124{124{
125 struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk_listener);125 struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk_listener);
126 struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);126 struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
127 struct tcp_options_received rx_opt;127 struct mptcp_options_received mp_opt;
128 128
129 pr_debug("subflow_req=%p, listener=%p", subflow_req, listener);129 pr_debug("subflow_req=%p, listener=%p", subflow_req, listener);
130 130
131 memset(&rx_opt.mptcp, 0, sizeof(rx_opt.mptcp));131 mptcp_get_options(skb, &mp_opt);
132 mptcp_get_options(skb, &rx_opt);
133 132
134 subflow_req->mp_capable = 0;133 subflow_req->mp_capable = 0;
135 subflow_req->mp_join = 0;134 subflow_req->mp_join = 0;
@@ -142,16 +141,16 @@ static void subflow_init_req(struct request_sock *req, · 6 unmodified lines
142 return;141 return;
143#endif142#endif
144 143
145 if (rx_opt.mptcp.mp_capable) {144 if (mp_opt.mp_capable) {
146 SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEPASSIVE);145 SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEPASSIVE);
147 146
148 if (rx_opt.mptcp.mp_join)147 if (mp_opt.mp_join)
149 return;148 return;
150 } else if (rx_opt.mptcp.mp_join) {149 } else if (mp_opt.mp_join) {
151 SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINSYNRX);150 SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINSYNRX);
152 }151 }
153 152
154 if (rx_opt.mptcp.mp_capable && listener->request_mptcp) {153 if (mp_opt.mp_capable && listener->request_mptcp) {
155 int err;154 int err;
156 155
157 err = mptcp_token_new_request(req);156 err = mptcp_token_new_request(req);
@@ -159,13 +158,13 @@ static void subflow_init_req(struct request_sock *req, · 1 unmodified line
159 subflow_req->mp_capable = 1;158 subflow_req->mp_capable = 1;
160 159
161 subflow_req->ssn_offset = TCP_SKB_CB(skb)->seq;160 subflow_req->ssn_offset = TCP_SKB_CB(skb)->seq;
162 } else if (rx_opt.mptcp.mp_join && listener->request_mptcp) {161 } else if (mp_opt.mp_join && listener->request_mptcp) {
163 subflow_req->ssn_offset = TCP_SKB_CB(skb)->seq;162 subflow_req->ssn_offset = TCP_SKB_CB(skb)->seq;
164 subflow_req->mp_join = 1;163 subflow_req->mp_join = 1;
165 subflow_req->backup = rx_opt.mptcp.backup;164 subflow_req->backup = mp_opt.backup;
166 subflow_req->remote_id = rx_opt.mptcp.join_id;165 subflow_req->remote_id = mp_opt.join_id;
167 subflow_req->token = rx_opt.mptcp.token;166 subflow_req->token = mp_opt.token;
168 subflow_req->remote_nonce = rx_opt.mptcp.nonce;167 subflow_req->remote_nonce = mp_opt.nonce;
169 pr_debug("token=%u, remote_nonce=%u", subflow_req->token,168 pr_debug("token=%u, remote_nonce=%u", subflow_req->token,
170 subflow_req->remote_nonce);169 subflow_req->remote_nonce);
171 if (!subflow_token_join_request(req, skb)) {170 if (!subflow_token_join_request(req, skb)) {
@@ -221,6 +220,7 @@ static bool subflow_thmac_valid(struct mptcp_subflow_context *subflow) · 49 unmodified lines
221static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)220static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
222{221{
223 struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);222 struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
223 struct mptcp_options_received mp_opt;
224 struct sock *parent = subflow->conn;224 struct sock *parent = subflow->conn;
225 struct tcp_sock *tp = tcp_sk(sk);225 struct tcp_sock *tp = tcp_sk(sk);
226 226
@@ -237,16 +237,17 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) · 10 unmodified lines
237 237
238 subflow->conn_finished = 1;238 subflow->conn_finished = 1;
239 239
240 if (subflow->request_mptcp && tp->rx_opt.mptcp.mp_capable) {240 mptcp_get_options(skb, &mp_opt);
241 if (subflow->request_mptcp && mp_opt.mp_capable) {
241 subflow->mp_capable = 1;242 subflow->mp_capable = 1;
242 subflow->can_ack = 1;243 subflow->can_ack = 1;
243 subflow->remote_key = tp->rx_opt.mptcp.sndr_key;244 subflow->remote_key = mp_opt.sndr_key;
244 pr_debug("subflow=%p, remote_key=%llu", subflow,245 pr_debug("subflow=%p, remote_key=%llu", subflow,
245 subflow->remote_key);246 subflow->remote_key);
246 } else if (subflow->request_join && tp->rx_opt.mptcp.mp_join) {247 } else if (subflow->request_join && mp_opt.mp_join) {
247 subflow->mp_join = 1;248 subflow->mp_join = 1;
248 subflow->thmac = tp->rx_opt.mptcp.thmac;249 subflow->thmac = mp_opt.thmac;
249 subflow->remote_nonce = tp->rx_opt.mptcp.nonce;250 subflow->remote_nonce = mp_opt.nonce;
250 pr_debug("subflow=%p, thmac=%llu, remote_nonce=%u", subflow,251 pr_debug("subflow=%p, thmac=%llu, remote_nonce=%u", subflow,
251 subflow->thmac, subflow->remote_nonce);252 subflow->thmac, subflow->remote_nonce);
252 } else if (subflow->request_mptcp) {253 } else if (subflow->request_mptcp) {
@@ -343,7 +344,7 @@ drop: · 90 unmodified lines
343 344
344/* validate hmac received in third ACK */345/* validate hmac received in third ACK */
345static bool subflow_hmac_valid(const struct request_sock *req,346static bool subflow_hmac_valid(const struct request_sock *req,
346 const struct tcp_options_received *rx_opt)347 const struct mptcp_options_received *mp_opt)
347{348{
348 const struct mptcp_subflow_request_sock *subflow_req;349 const struct mptcp_subflow_request_sock *subflow_req;
349 u8 hmac[MPTCPOPT_HMAC_LEN];350 u8 hmac[MPTCPOPT_HMAC_LEN];
@@ -360,7 +361,7 @@ static bool subflow_hmac_valid(const struct request_sock *req, · 10 unmodified lines
360 subflow_req->local_nonce, hmac);361 subflow_req->local_nonce, hmac);
361 362
362 ret = true;363 ret = true;
363 if (crypto_memneq(hmac, rx_opt->mptcp.hmac, sizeof(hmac)))364 if (crypto_memneq(hmac, mp_opt->hmac, sizeof(hmac)))
364 ret = false;365 ret = false;
365 366
366 sock_put((struct sock *)msk);367 sock_put((struct sock *)msk);
@@ -416,7 +417,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, · 49 unmodified lines
416{417{
417 struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk);418 struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk);
418 struct mptcp_subflow_request_sock *subflow_req;419 struct mptcp_subflow_request_sock *subflow_req;
419 struct tcp_options_received opt_rx;420 struct mptcp_options_received mp_opt;
420 bool fallback_is_fatal = false;421 bool fallback_is_fatal = false;
421 struct sock *new_msk = NULL;422 struct sock *new_msk = NULL;
422 bool fallback = false;423 bool fallback = false;
@@ -424,7 +425,10 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, · 1 unmodified line
424 425
425 pr_debug("listener=%p, req=%p, conn=%p", listener, req, listener->conn);426 pr_debug("listener=%p, req=%p, conn=%p", listener, req, listener->conn);
426 427
427 opt_rx.mptcp.mp_capable = 0;428 /* we need later a valid 'mp_capable' value even when options are not
429 * parsed
430 */
431 mp_opt.mp_capable = 0;
428 if (tcp_rsk(req)->is_mptcp == 0)432 if (tcp_rsk(req)->is_mptcp == 0)
429 goto create_child;433 goto create_child;
430 434
@@ -439,22 +443,21 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, · 8 unmodified lines
439 goto create_msk;443 goto create_msk;
440 }444 }
441 445
442 mptcp_get_options(skb, &opt_rx);446 mptcp_get_options(skb, &mp_opt);
443 if (!opt_rx.mptcp.mp_capable) {447 if (!mp_opt.mp_capable) {
444 fallback = true;448 fallback = true;
445 goto create_child;449 goto create_child;
446 }450 }
447 451
448create_msk:452create_msk:
449 new_msk = mptcp_sk_clone(listener->conn, &opt_rx, req);453 new_msk = mptcp_sk_clone(listener->conn, &mp_opt, req);
450 if (!new_msk)454 if (!new_msk)
451 fallback = true;455 fallback = true;
452 } else if (subflow_req->mp_join) {456 } else if (subflow_req->mp_join) {
453 fallback_is_fatal = true;457 fallback_is_fatal = true;
454 opt_rx.mptcp.mp_join = 0;458 mptcp_get_options(skb, &mp_opt);
455 mptcp_get_options(skb, &opt_rx);459 if (!mp_opt.mp_join ||
456 if (!opt_rx.mptcp.mp_join ||460 !subflow_hmac_valid(req, &mp_opt)) {
457 !subflow_hmac_valid(req, &opt_rx)) {
458 SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);461 SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);
459 return NULL;462 return NULL;
460 }463 }
@@ -494,9 +497,9 @@ create_child: · 33 unmodified lines
494 /* with OoO packets we can reach here without ingress497 /* with OoO packets we can reach here without ingress
495 * mpc option498 * mpc option
496 */499 */
497 ctx->remote_key = opt_rx.mptcp.sndr_key;500 ctx->remote_key = mp_opt.sndr_key;
498 ctx->fully_established = opt_rx.mptcp.mp_capable;501 ctx->fully_established = mp_opt.mp_capable;
499 ctx->can_ack = opt_rx.mptcp.mp_capable;502 ctx->can_ack = mp_opt.mp_capable;
500 } else if (ctx->mp_join) {503 } else if (ctx->mp_join) {
501 struct mptcp_sock *owner;504 struct mptcp_sock *owner;
502 505