@@ -197,6 +197,11 @@ static inline __be32 mptcp_reset_option(const struct sk_buff *skb)
return htonl(0u);
}
+
+static inline struct sock *mptcp_handle_join4(struct sk_buff *skb)
+{
+ return NULL;
+}
#else
static inline void mptcp_init(void)
@@ -274,14 +279,21 @@ static inline int mptcp_subflow_init_cookie_req(struct request_sock *req,
}
static inline __be32 mptcp_reset_option(const struct sk_buff *skb) { return htonl(0u); }
+static inline struct sock *mptcp_handle_join4(struct sk_buff *skb) { return NULL; }
#endif /* CONFIG_MPTCP */
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
int mptcpv6_init(void);
void mptcpv6_handle_mapped(struct sock *sk, bool mapped);
+
+static inline struct sock *mptcp_handle_join6(struct sk_buff *skb)
+{
+ return NULL;
+}
#elif IS_ENABLED(CONFIG_IPV6)
static inline int mptcpv6_init(void) { return 0; }
static inline void mptcpv6_handle_mapped(struct sock *sk, bool mapped) { }
+static inline struct sock *mptcp_handle_join6(struct sk_buff *skb) { return NULL; }
#endif
#endif /* __NET_MPTCP_H */
@@ -2155,6 +2155,10 @@ int tcp_v4_rcv(struct sk_buff *skb)
if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
goto discard_it;
+ sk = mptcp_handle_join4(skb);
+ if (sk)
+ goto process;
+
tcp_v4_fill_cb(skb, iph, th);
if (tcp_checksum_complete(skb)) {
@@ -2201,6 +2205,9 @@ int tcp_v4_rcv(struct sk_buff *skb)
iph->daddr, th->dest,
inet_iif(skb),
sdif);
+ if (!sk2)
+ sk2 = mptcp_handle_join4(skb);
+
if (sk2) {
inet_twsk_deschedule_put(inet_twsk(sk));
sk = sk2;
@@ -1800,6 +1800,10 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
goto discard_it;
+ sk = mptcp_handle_join6(skb);
+ if (sk)
+ goto process;
+
tcp_v6_fill_cb(skb, hdr, th);
if (tcp_checksum_complete(skb)) {
@@ -1849,6 +1853,9 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
ntohs(th->dest),
tcp_v6_iif_l3_slave(skb),
sdif);
+ if (!sk2)
+ sk2 = mptcp_handle_join6(skb);
+
if (sk2) {
struct inet_timewait_sock *tw = inet_twsk(sk);
inet_twsk_deschedule_put(tw);
Split from the next patch to make core tcp changes more obvious: add a dummy function that gets called after tcp socket demux came up empty. This will be used by mptcp to check if a tcp syn contains an mptcp join option with a valid token (connection id). If so, a hidden pernet mptcp listener socket is returned and packet resumes normally. Signed-off-by: Florian Westphal <fw@strlen.de> --- include/net/mptcp.h | 12 ++++++++++++ net/ipv4/tcp_ipv4.c | 7 +++++++ net/ipv6/tcp_ipv6.c | 7 +++++++ 3 files changed, 26 insertions(+)