History

mptcp: add mptcp reset option support

The MPTCP reset option allows to carry a mptcp-specific error code that provides more information on the nature of a connection reset. Reset option data received gets stored in the subflow context so it can be sent to userspace via the 'subflow closed' netlink event. When a subflow is closed, the desired error code that should be sent to the peer is also placed in the subflow context structure. If a reset is sent before subflow establishment could complete, e.g. on HMAC failure during an MP_JOIN operation, the mptcp skb extension is used to store the reset information.

Florian Westphal committed 5 years ago

Commit dc87efd1 parent 781bf139 files · +180 −19Browse files

Unified · Split

9 files
  1. include/net/mptcp.h +16 −2
  2. include/uapi/linux/mptcp.h +11 −0
  3. net/ipv4/tcp_ipv4.c +18 −3
  4. net/ipv6/tcp_ipv6.c +13 −1
  5. net/mptcp/options.c +62 −5
  6. net/mptcp/pm_netlink.c +12 −0
  7. net/mptcp/protocol.c +9 −3
  8. net/mptcp/protocol.h +13 −1
  9. net/mptcp/subflow.c +26 −4
include/net/mptcp.h+16−2
@@ -30,8 +30,8 @@ struct mptcp_ext { · 29 unmodified lines
30 ack64:1,30 ack64:1,
31 mpc_map:1,31 mpc_map:1,
32 frozen:1,32 frozen:1,
33 __unused:1;33 reset_transient:1;
34 /* one byte hole */34 u8 reset_reason:4;
35};35};
36 36
37#define MPTCP_RM_IDS_MAX 837#define MPTCP_RM_IDS_MAX 8
@@ -58,6 +58,8 @@ struct mptcp_out_options { · 20 unmodified lines
58 struct mptcp_rm_list rm_list;58 struct mptcp_rm_list rm_list;
59 u8 join_id;59 u8 join_id;
60 u8 backup;60 u8 backup;
61 u8 reset_reason:4;
62 u8 reset_transient:1;
61 u32 nonce;63 u32 nonce;
62 u64 thmac;64 u64 thmac;
63 u32 token;65 u32 token;
@@ -156,6 +158,16 @@ void mptcp_seq_show(struct seq_file *seq); · 92 unmodified lines
156int mptcp_subflow_init_cookie_req(struct request_sock *req,158int mptcp_subflow_init_cookie_req(struct request_sock *req,
157 const struct sock *sk_listener,159 const struct sock *sk_listener,
158 struct sk_buff *skb);160 struct sk_buff *skb);
161
162__be32 mptcp_get_reset_option(const struct sk_buff *skb);
163
164static inline __be32 mptcp_reset_option(const struct sk_buff *skb)
165{
166 if (skb_ext_exist(skb, SKB_EXT_MPTCP))
167 return mptcp_get_reset_option(skb);
168
169 return htonl(0u);
170}
159#else171#else
160 172
161static inline void mptcp_init(void)173static inline void mptcp_init(void)
@@ -236,6 +248,8 @@ static inline int mptcp_subflow_init_cookie_req(struct request_sock *req, · 74 unmodified lines
236{248{
237 return 0; /* TCP fallback */249 return 0; /* TCP fallback */
238}250}
251
252static inline __be32 mptcp_reset_option(const struct sk_buff *skb) { return htonl(0u); }
239#endif /* CONFIG_MPTCP */253#endif /* CONFIG_MPTCP */
240 254
241#if IS_ENABLED(CONFIG_MPTCP_IPV6)255#if IS_ENABLED(CONFIG_MPTCP_IPV6)
include/uapi/linux/mptcp.h+11−0
@@ -174,10 +174,21 @@ enum mptcp_event_attr { · 173 unmodified lines
174 MPTCP_ATTR_FLAGS, /* u16 */174 MPTCP_ATTR_FLAGS, /* u16 */
175 MPTCP_ATTR_TIMEOUT, /* u32 */175 MPTCP_ATTR_TIMEOUT, /* u32 */
176 MPTCP_ATTR_IF_IDX, /* s32 */176 MPTCP_ATTR_IF_IDX, /* s32 */
177 MPTCP_ATTR_RESET_REASON,/* u32 */
178 MPTCP_ATTR_RESET_FLAGS, /* u32 */
177 179
178 __MPTCP_ATTR_AFTER_LAST180 __MPTCP_ATTR_AFTER_LAST
179};181};
180 182
181#define MPTCP_ATTR_MAX (__MPTCP_ATTR_AFTER_LAST - 1)183#define MPTCP_ATTR_MAX (__MPTCP_ATTR_AFTER_LAST - 1)
182 184
185/* MPTCP Reset reason codes, rfc8684 */
186#define MPTCP_RST_EUNSPEC 0
187#define MPTCP_RST_EMPTCP 1
188#define MPTCP_RST_ERESOURCE 2
189#define MPTCP_RST_EPROHIBIT 3
190#define MPTCP_RST_EWQ2BIG 4
191#define MPTCP_RST_EBADPERF 5
192#define MPTCP_RST_EMIDDLEBOX 6
193
183#endif /* _UAPI_MPTCP_H */194#endif /* _UAPI_MPTCP_H */
net/ipv4/tcp_ipv4.c+18−3
@@ -655,14 +655,18 @@ EXPORT_SYMBOL(tcp_v4_send_check); · 654 unmodified lines
655 * Exception: precedence violation. We do not implement it in any case.655 * Exception: precedence violation. We do not implement it in any case.
656 */656 */
657 657
658#ifdef CONFIG_TCP_MD5SIG
659#define OPTION_BYTES TCPOLEN_MD5SIG_ALIGNED
660#else
661#define OPTION_BYTES sizeof(__be32)
662#endif
663
658static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb)664static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb)
659{665{
660 const struct tcphdr *th = tcp_hdr(skb);666 const struct tcphdr *th = tcp_hdr(skb);
661 struct {667 struct {
662 struct tcphdr th;668 struct tcphdr th;
663#ifdef CONFIG_TCP_MD5SIG669 __be32 opt[OPTION_BYTES / sizeof(__be32)];
664 __be32 opt[(TCPOLEN_MD5SIG_ALIGNED >> 2)];
665#endif
666 } rep;670 } rep;
667 struct ip_reply_arg arg;671 struct ip_reply_arg arg;
668#ifdef CONFIG_TCP_MD5SIG672#ifdef CONFIG_TCP_MD5SIG
@@ -770,6 +774,17 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) · 101 unmodified lines
770 ip_hdr(skb)->daddr, &rep.th);774 ip_hdr(skb)->daddr, &rep.th);
771 }775 }
772#endif776#endif
777 /* Can't co-exist with TCPMD5, hence check rep.opt[0] */
778 if (rep.opt[0] == 0) {
779 __be32 mrst = mptcp_reset_option(skb);
780
781 if (mrst) {
782 rep.opt[0] = mrst;
783 arg.iov[0].iov_len += sizeof(mrst);
784 rep.th.doff = arg.iov[0].iov_len / 4;
785 }
786 }
787
773 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,788 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
774 ip_hdr(skb)->saddr, /* XXX */789 ip_hdr(skb)->saddr, /* XXX */
775 arg.iov[0].iov_len, IPPROTO_TCP, 0);790 arg.iov[0].iov_len, IPPROTO_TCP, 0);
net/ipv6/tcp_ipv6.c+13−1
@@ -879,8 +879,8 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 · 878 unmodified lines
879 struct net *net = sk ? sock_net(sk) : dev_net(skb_dst(skb)->dev);879 struct net *net = sk ? sock_net(sk) : dev_net(skb_dst(skb)->dev);
880 struct sock *ctl_sk = net->ipv6.tcp_sk;880 struct sock *ctl_sk = net->ipv6.tcp_sk;
881 unsigned int tot_len = sizeof(struct tcphdr);881 unsigned int tot_len = sizeof(struct tcphdr);
882 __be32 mrst = 0, *topt;
882 struct dst_entry *dst;883 struct dst_entry *dst;
883 __be32 *topt;
884 __u32 mark = 0;884 __u32 mark = 0;
885 885
886 if (tsecr)886 if (tsecr)
@@ -890,6 +890,15 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 · 3 unmodified lines
890 tot_len += TCPOLEN_MD5SIG_ALIGNED;890 tot_len += TCPOLEN_MD5SIG_ALIGNED;
891#endif891#endif
892 892
893#ifdef CONFIG_MPTCP
894 if (rst && !key) {
895 mrst = mptcp_reset_option(skb);
896
897 if (mrst)
898 tot_len += sizeof(__be32);
899 }
900#endif
901
893 buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len,902 buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len,
894 GFP_ATOMIC);903 GFP_ATOMIC);
895 if (!buff)904 if (!buff)
@@ -920,6 +929,9 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 · 24 unmodified lines
920 *topt++ = htonl(tsecr);929 *topt++ = htonl(tsecr);
921 }930 }
922 931
932 if (mrst)
933 *topt++ = mrst;
934
923#ifdef CONFIG_TCP_MD5SIG935#ifdef CONFIG_TCP_MD5SIG
924 if (key) {936 if (key) {
925 *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |937 *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
net/mptcp/options.c+62−5
@@ -305,6 +305,18 @@ static void mptcp_parse_option(const struct sk_buff *skb, · 304 unmodified lines
305 mp_opt->fastclose = 1;305 mp_opt->fastclose = 1;
306 break;306 break;
307 307
308 case MPTCPOPT_RST:
309 if (opsize != TCPOLEN_MPTCP_RST)
310 break;
311
312 if (!(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST))
313 break;
314 mp_opt->reset = 1;
315 flags = *ptr++;
316 mp_opt->reset_transient = flags & MPTCP_RST_TRANSIENT;
317 mp_opt->reset_reason = *ptr;
318 break;
319
308 default:320 default:
309 break;321 break;
310 }322 }
@@ -327,6 +339,7 @@ void mptcp_get_options(const struct sk_buff *skb, · 16 unmodified lines
327 mp_opt->rm_addr = 0;339 mp_opt->rm_addr = 0;
328 mp_opt->dss = 0;340 mp_opt->dss = 0;
329 mp_opt->mp_prio = 0;341 mp_opt->mp_prio = 0;
342 mp_opt->reset = 0;
330 343
331 length = (th->doff * 4) - sizeof(struct tcphdr);344 length = (th->doff * 4) - sizeof(struct tcphdr);
332 ptr = (const unsigned char *)(th + 1);345 ptr = (const unsigned char *)(th + 1);
@@ -726,6 +739,22 @@ static bool mptcp_established_options_mp_prio(struct sock *sk, · 393 unmodified lines
726 return true;739 return true;
727}740}
728 741
742static noinline void mptcp_established_options_rst(struct sock *sk, struct sk_buff *skb,
743 unsigned int *size,
744 unsigned int remaining,
745 struct mptcp_out_options *opts)
746{
747 const struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
748
749 if (remaining < TCPOLEN_MPTCP_RST)
750 return;
751
752 *size = TCPOLEN_MPTCP_RST;
753 opts->suboptions |= OPTION_MPTCP_RST;
754 opts->reset_transient = subflow->reset_transient;
755 opts->reset_reason = subflow->reset_reason;
756}
757
729bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,758bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
730 unsigned int *size, unsigned int remaining,759 unsigned int *size, unsigned int remaining,
731 struct mptcp_out_options *opts)760 struct mptcp_out_options *opts)
@@ -741,11 +770,10 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, · 9 unmodified lines
741 if (unlikely(__mptcp_check_fallback(msk)))770 if (unlikely(__mptcp_check_fallback(msk)))
742 return false;771 return false;
743 772
744 /* prevent adding of any MPTCP related options on reset packet773 if (unlikely(skb && TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST)) {
745 * until we support MP_TCPRST/MP_FASTCLOSE774 mptcp_established_options_rst(sk, skb, size, remaining, opts);
746 */775 return true;
747 if (unlikely(skb && TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST))776 }
748 return false;
749 777
750 snd_data_fin = mptcp_data_fin_enabled(msk);778 snd_data_fin = mptcp_data_fin_enabled(msk);
751 if (mptcp_established_options_mp(sk, skb, snd_data_fin, &opt_size, remaining, opts))779 if (mptcp_established_options_mp(sk, skb, snd_data_fin, &opt_size, remaining, opts))
@@ -1062,6 +1090,12 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) · 310 unmodified lines
1062 mp_opt.mp_prio = 0;1090 mp_opt.mp_prio = 0;
1063 }1091 }
1064 1092
1093 if (mp_opt.reset) {
1094 subflow->reset_seen = 1;
1095 subflow->reset_reason = mp_opt.reset_reason;
1096 subflow->reset_transient = mp_opt.reset_transient;
1097 }
1098
1065 if (!mp_opt.dss)1099 if (!mp_opt.dss)
1066 return;1100 return;
1067 1101
@@ -1289,6 +1323,12 @@ mp_capable_done: · 221 unmodified lines
1289 ptr += 5;1323 ptr += 5;
1290 }1324 }
1291 1325
1326 if (OPTION_MPTCP_RST & opts->suboptions)
1327 *ptr++ = mptcp_option(MPTCPOPT_RST,
1328 TCPOLEN_MPTCP_RST,
1329 opts->reset_transient,
1330 opts->reset_reason);
1331
1292 if (opts->ext_copy.use_ack || opts->ext_copy.use_map) {1332 if (opts->ext_copy.use_ack || opts->ext_copy.use_map) {
1293 struct mptcp_ext *mpext = &opts->ext_copy;1333 struct mptcp_ext *mpext = &opts->ext_copy;
1294 u8 len = TCPOLEN_MPTCP_DSS_BASE;1334 u8 len = TCPOLEN_MPTCP_DSS_BASE;
@@ -1340,3 +1380,20 @@ mp_capable_done: · 45 unmodified lines
1340 if (tp)1380 if (tp)
1341 mptcp_set_rwin(tp);1381 mptcp_set_rwin(tp);
1342}1382}
1383
1384__be32 mptcp_get_reset_option(const struct sk_buff *skb)
1385{
1386 const struct mptcp_ext *ext = mptcp_get_ext(skb);
1387 u8 flags, reason;
1388
1389 if (ext) {
1390 flags = ext->reset_transient;
1391 reason = ext->reset_reason;
1392
1393 return mptcp_option(MPTCPOPT_RST, TCPOLEN_MPTCP_RST,
1394 flags, reason);
1395 }
1396
1397 return htonl(0u);
1398}
1399EXPORT_SYMBOL_GPL(mptcp_get_reset_option);
net/mptcp/pm_netlink.c+12−0
@@ -1687,9 +1687,21 @@ static int mptcp_event_sub_closed(struct sk_buff *skb, · 1686 unmodified lines
1687 const struct mptcp_sock *msk,1687 const struct mptcp_sock *msk,
1688 const struct sock *ssk)1688 const struct sock *ssk)
1689{1689{
1690 const struct mptcp_subflow_context *sf;
1691
1690 if (mptcp_event_put_token_and_ssk(skb, msk, ssk))1692 if (mptcp_event_put_token_and_ssk(skb, msk, ssk))
1691 return -EMSGSIZE;1693 return -EMSGSIZE;
1692 1694
1695 sf = mptcp_subflow_ctx(ssk);
1696 if (!sf->reset_seen)
1697 return 0;
1698
1699 if (nla_put_u32(skb, MPTCP_ATTR_RESET_REASON, sf->reset_reason))
1700 return -EMSGSIZE;
1701
1702 if (nla_put_u32(skb, MPTCP_ATTR_RESET_FLAGS, sf->reset_transient))
1703 return -EMSGSIZE;
1704
1693 return 0;1705 return 0;
1694}1706}
1695 1707
net/mptcp/protocol.c+9−3
@@ -3090,14 +3090,18 @@ bool mptcp_finish_join(struct sock *ssk) · 3089 unmodified lines
3090 pr_debug("msk=%p, subflow=%p", msk, subflow);3090 pr_debug("msk=%p, subflow=%p", msk, subflow);
3091 3091
3092 /* mptcp socket already closing? */3092 /* mptcp socket already closing? */
3093 if (!mptcp_is_fully_established(parent))3093 if (!mptcp_is_fully_established(parent)) {
3094 subflow->reset_reason = MPTCP_RST_EMPTCP;
3094 return false;3095 return false;
3096 }
3095 3097
3096 if (!msk->pm.server_side)3098 if (!msk->pm.server_side)
3097 goto out;3099 goto out;
3098 3100
3099 if (!mptcp_pm_allow_new_subflow(msk))3101 if (!mptcp_pm_allow_new_subflow(msk)) {
3102 subflow->reset_reason = MPTCP_RST_EPROHIBIT;
3100 return false;3103 return false;
3104 }
3101 3105
3102 /* active connections are already on conn_list, and we can't acquire3106 /* active connections are already on conn_list, and we can't acquire
3103 * msk lock here.3107 * msk lock here.
@@ -3111,8 +3115,10 @@ bool mptcp_finish_join(struct sock *ssk) · 7 unmodified lines
3111 sock_hold(ssk);3115 sock_hold(ssk);
3112 }3116 }
3113 spin_unlock_bh(&msk->join_list_lock);3117 spin_unlock_bh(&msk->join_list_lock);
3114 if (!ret)3118 if (!ret) {
3119 subflow->reset_reason = MPTCP_RST_EPROHIBIT;
3115 return false;3120 return false;
3121 }
3116 3122
3117 /* attach to msk socket only after we are sure he will deal with us3123 /* attach to msk socket only after we are sure he will deal with us
3118 * at close time3124 * at close time
net/mptcp/protocol.h+13−1
@@ -26,6 +26,7 @@ · 25 unmodified lines
26#define OPTION_MPTCP_RM_ADDR BIT(8)26#define OPTION_MPTCP_RM_ADDR BIT(8)
27#define OPTION_MPTCP_FASTCLOSE BIT(9)27#define OPTION_MPTCP_FASTCLOSE BIT(9)
28#define OPTION_MPTCP_PRIO BIT(10)28#define OPTION_MPTCP_PRIO BIT(10)
29#define OPTION_MPTCP_RST BIT(11)
29 30
30/* MPTCP option subtypes */31/* MPTCP option subtypes */
31#define MPTCPOPT_MP_CAPABLE 032#define MPTCPOPT_MP_CAPABLE 0
@@ -36,6 +37,7 @@ · 4 unmodified lines
36#define MPTCPOPT_MP_PRIO 537#define MPTCPOPT_MP_PRIO 5
37#define MPTCPOPT_MP_FAIL 638#define MPTCPOPT_MP_FAIL 6
38#define MPTCPOPT_MP_FASTCLOSE 739#define MPTCPOPT_MP_FASTCLOSE 7
40#define MPTCPOPT_RST 8
39 41
40/* MPTCP suboption lengths */42/* MPTCP suboption lengths */
41#define TCPOLEN_MPTCP_MPC_SYN 443#define TCPOLEN_MPTCP_MPC_SYN 4
@@ -65,6 +67,7 @@ · 23 unmodified lines
65#define TCPOLEN_MPTCP_PRIO 367#define TCPOLEN_MPTCP_PRIO 3
66#define TCPOLEN_MPTCP_PRIO_ALIGN 468#define TCPOLEN_MPTCP_PRIO_ALIGN 4
67#define TCPOLEN_MPTCP_FASTCLOSE 1269#define TCPOLEN_MPTCP_FASTCLOSE 12
70#define TCPOLEN_MPTCP_RST 4
68 71
69/* MPTCP MP_JOIN flags */72/* MPTCP MP_JOIN flags */
70#define MPTCPOPT_BACKUP BIT(0)73#define MPTCPOPT_BACKUP BIT(0)
@@ -94,6 +97,9 @@ · 23 unmodified lines
94/* MPTCP MP_PRIO flags */97/* MPTCP MP_PRIO flags */
95#define MPTCP_PRIO_BKUP BIT(0)98#define MPTCP_PRIO_BKUP BIT(0)
96 99
100/* MPTCP TCPRST flags */
101#define MPTCP_RST_TRANSIENT BIT(0)
102
97/* MPTCP socket flags */103/* MPTCP socket flags */
98#define MPTCP_DATA_READY 0104#define MPTCP_DATA_READY 0
99#define MPTCP_NOSPACE 1105#define MPTCP_NOSPACE 1
@@ -123,6 +129,7 @@ struct mptcp_options_received { · 23 unmodified lines
123 u16 mp_capable : 1,129 u16 mp_capable : 1,
124 mp_join : 1,130 mp_join : 1,
125 fastclose : 1,131 fastclose : 1,
132 reset : 1,
126 dss : 1,133 dss : 1,
127 add_addr : 1,134 add_addr : 1,
128 rm_addr : 1,135 rm_addr : 1,
@@ -152,6 +159,8 @@ struct mptcp_options_received { · 23 unmodified lines
152 };159 };
153 u64 ahmac;160 u64 ahmac;
154 u16 port;161 u16 port;
162 u8 reset_reason:4;
163 u8 reset_transient:1;
155};164};
156 165
157static inline __be32 mptcp_option(u8 subopt, u8 len, u8 nib, u8 field)166static inline __be32 mptcp_option(u8 subopt, u8 len, u8 nib, u8 field)
@@ -422,6 +431,9 @@ struct mptcp_subflow_context { · 264 unmodified lines
422 u8 hmac[MPTCPOPT_HMAC_LEN];431 u8 hmac[MPTCPOPT_HMAC_LEN];
423 u8 local_id;432 u8 local_id;
424 u8 remote_id;433 u8 remote_id;
434 u8 reset_seen:1;
435 u8 reset_transient:1;
436 u8 reset_reason:4;
425 437
426 long delegated_status;438 long delegated_status;
427 struct list_head delegated_node; /* link into delegated_action, protected by local BH */439 struct list_head delegated_node; /* link into delegated_action, protected by local BH */
@@ -742,7 +754,7 @@ unsigned int mptcp_pm_get_add_addr_accept_max(struct mptcp_sock *msk); · 314 unmodified lines
742unsigned int mptcp_pm_get_subflows_max(struct mptcp_sock *msk);754unsigned int mptcp_pm_get_subflows_max(struct mptcp_sock *msk);
743unsigned int mptcp_pm_get_local_addr_max(struct mptcp_sock *msk);755unsigned int mptcp_pm_get_local_addr_max(struct mptcp_sock *msk);
744 756
745static inline struct mptcp_ext *mptcp_get_ext(struct sk_buff *skb)757static inline struct mptcp_ext *mptcp_get_ext(const struct sk_buff *skb)
746{758{
747 return (struct mptcp_ext *)skb_ext_find(skb, SKB_EXT_MPTCP);759 return (struct mptcp_ext *)skb_ext_find(skb, SKB_EXT_MPTCP);
748}760}
net/mptcp/subflow.c+26−4
@@ -115,6 +115,16 @@ static bool subflow_use_different_sport(struct mptcp_sock *msk, const struct soc · 114 unmodified lines
115 return inet_sk(sk)->inet_sport != inet_sk((struct sock *)msk)->inet_sport;115 return inet_sk(sk)->inet_sport != inet_sk((struct sock *)msk)->inet_sport;
116}116}
117 117
118static void subflow_add_reset_reason(struct sk_buff *skb, u8 reason)
119{
120 struct mptcp_ext *mpext = skb_ext_add(skb, SKB_EXT_MPTCP);
121
122 if (mpext) {
123 memset(mpext, 0, sizeof(*mpext));
124 mpext->reset_reason = reason;
125 }
126}
127
118/* Init mptcp request socket.128/* Init mptcp request socket.
119 *129 *
120 * Returns an error code if a JOIN has failed and a TCP reset130 * Returns an error code if a JOIN has failed and a TCP reset
@@ -190,8 +200,10 @@ again: · 69 unmodified lines
190 subflow_req->msk = subflow_token_join_request(req);200 subflow_req->msk = subflow_token_join_request(req);
191 201
192 /* Can't fall back to TCP in this case. */202 /* Can't fall back to TCP in this case. */
193 if (!subflow_req->msk)203 if (!subflow_req->msk) {
204 subflow_add_reset_reason(skb, MPTCP_RST_EMPTCP);
194 return -EPERM;205 return -EPERM;
206 }
195 207
196 if (subflow_use_different_sport(subflow_req->msk, sk_listener)) {208 if (subflow_use_different_sport(subflow_req->msk, sk_listener)) {
197 pr_debug("syn inet_sport=%d %d",209 pr_debug("syn inet_sport=%d %d",
@@ -400,8 +412,10 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) · 202 unmodified lines
400 } else if (subflow->request_join) {412 } else if (subflow->request_join) {
401 u8 hmac[SHA256_DIGEST_SIZE];413 u8 hmac[SHA256_DIGEST_SIZE];
402 414
403 if (!mp_opt.mp_join)415 if (!mp_opt.mp_join) {
416 subflow->reset_reason = MPTCP_RST_EMPTCP;
404 goto do_reset;417 goto do_reset;
418 }
405 419
406 subflow->thmac = mp_opt.thmac;420 subflow->thmac = mp_opt.thmac;
407 subflow->remote_nonce = mp_opt.nonce;421 subflow->remote_nonce = mp_opt.nonce;
@@ -410,6 +424,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) · 2 unmodified lines
410 424
411 if (!subflow_thmac_valid(subflow)) {425 if (!subflow_thmac_valid(subflow)) {
412 MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINACKMAC);426 MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINACKMAC);
427 subflow->reset_reason = MPTCP_RST_EMPTCP;
413 goto do_reset;428 goto do_reset;
414 }429 }
415 430
@@ -438,6 +453,7 @@ fallback: · 22 unmodified lines
438 return;453 return;
439 454
440do_reset:455do_reset:
456 subflow->reset_transient = 0;
441 mptcp_subflow_reset(sk);457 mptcp_subflow_reset(sk);
442}458}
443 459
@@ -654,8 +670,10 @@ create_child: · 210 unmodified lines
654 * to reset the context to non MPTCP status.670 * to reset the context to non MPTCP status.
655 */671 */
656 if (!ctx || fallback) {672 if (!ctx || fallback) {
657 if (fallback_is_fatal)673 if (fallback_is_fatal) {
674 subflow_add_reset_reason(skb, MPTCP_RST_EMPTCP);
658 goto dispose_child;675 goto dispose_child;
676 }
659 677
660 subflow_drop_ctx(child);678 subflow_drop_ctx(child);
661 goto out;679 goto out;
@@ -690,8 +708,10 @@ create_child: · 28 unmodified lines
690 struct mptcp_sock *owner;708 struct mptcp_sock *owner;
691 709
692 owner = subflow_req->msk;710 owner = subflow_req->msk;
693 if (!owner)711 if (!owner) {
712 subflow_add_reset_reason(skb, MPTCP_RST_EPROHIBIT);
694 goto dispose_child;713 goto dispose_child;
714 }
695 715
696 /* move the msk reference ownership to the subflow */716 /* move the msk reference ownership to the subflow */
697 subflow_req->msk = NULL;717 subflow_req->msk = NULL;
@@ -1056,6 +1076,8 @@ fatal: · 358 unmodified lines
1056 smp_wmb();1076 smp_wmb();
1057 ssk->sk_error_report(ssk);1077 ssk->sk_error_report(ssk);
1058 tcp_set_state(ssk, TCP_CLOSE);1078 tcp_set_state(ssk, TCP_CLOSE);
1079 subflow->reset_transient = 0;
1080 subflow->reset_reason = MPTCP_RST_EMPTCP;
1059 tcp_send_active_reset(ssk, GFP_ATOMIC);1081 tcp_send_active_reset(ssk, GFP_ATOMIC);
1060 subflow->data_avail = 0;1082 subflow->data_avail = 0;
1061 return false;1083 return false;