tcp: syncookies: create mptcp request socket for ACK cookies with MPTCP option
authorFlorian Westphal <fw@strlen.de>
Thu, 30 Jul 2020 19:25:55 +0000 (21:25 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 31 Jul 2020 23:55:32 +0000 (16:55 -0700)
If SYN packet contains MP_CAPABLE option, keep it enabled.
Syncokie validation and cookie-based socket creation is changed to
instantiate an mptcp request sockets if the ACK contains an MPTCP
connection request.

Rather than extend both cookie_v4/6_check, add a common helper to create
the (mp)tcp request socket.

Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/tcp.h
net/ipv4/syncookies.c
net/ipv4/tcp_input.c
net/ipv6/syncookies.c

index e0c35d56091f223b0a096f16ca5b52d9e2993b3d..dbf5c791a6eb43181e54b972e9847f29542bceb9 100644 (file)
@@ -469,6 +469,8 @@ struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb,
 int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th,
                      u32 cookie);
 struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb);
+struct request_sock *cookie_tcp_reqsk_alloc(const struct request_sock_ops *ops,
+                                           struct sock *sk, struct sk_buff *skb);
 #ifdef CONFIG_SYN_COOKIES
 
 /* Syncookies use a monotonic timer which increments every 60 seconds.
index 9a4f6b16c9bcec70b0d8b8d06a12f9faa79c84fb..54838ee2e8d4cfff4ae6747c761482f88c7ebb00 100644 (file)
@@ -276,6 +276,39 @@ bool cookie_ecn_ok(const struct tcp_options_received *tcp_opt,
 }
 EXPORT_SYMBOL(cookie_ecn_ok);
 
+struct request_sock *cookie_tcp_reqsk_alloc(const struct request_sock_ops *ops,
+                                           struct sock *sk,
+                                           struct sk_buff *skb)
+{
+       struct tcp_request_sock *treq;
+       struct request_sock *req;
+
+#ifdef CONFIG_MPTCP
+       if (sk_is_mptcp(sk))
+               ops = &mptcp_subflow_request_sock_ops;
+#endif
+
+       req = inet_reqsk_alloc(ops, sk, false);
+       if (!req)
+               return NULL;
+
+#if IS_ENABLED(CONFIG_MPTCP)
+       treq = tcp_rsk(req);
+       treq->is_mptcp = sk_is_mptcp(sk);
+       if (treq->is_mptcp) {
+               int err = mptcp_subflow_init_cookie_req(req, sk, skb);
+
+               if (err) {
+                       reqsk_free(req);
+                       return NULL;
+               }
+       }
+#endif
+
+       return req;
+}
+EXPORT_SYMBOL_GPL(cookie_tcp_reqsk_alloc);
+
 /* On input, sk is a listener.
  * Output is listener if incoming packet would not create a child
  *           NULL if memory could not be allocated.
@@ -326,7 +359,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
                goto out;
 
        ret = NULL;
-       req = inet_reqsk_alloc(&tcp_request_sock_ops, sk, false); /* for safety */
+       req = cookie_tcp_reqsk_alloc(&tcp_request_sock_ops, sk, skb);
        if (!req)
                goto out;
 
@@ -350,9 +383,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
        treq->snt_synack        = 0;
        treq->tfo_listener      = false;
 
-       if (IS_ENABLED(CONFIG_MPTCP))
-               treq->is_mptcp = 0;
-
        if (IS_ENABLED(CONFIG_SMC))
                ireq->smc_ok = 0;
 
index 11a6f128e51cd4d18f55dc989b1c675b491e9e7f..739da25b0c23a64932141122e66b5a922e1186d6 100644 (file)
@@ -6701,9 +6701,6 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
 
        af_ops->init_req(req, sk, skb);
 
-       if (IS_ENABLED(CONFIG_MPTCP) && want_cookie)
-               tcp_rsk(req)->is_mptcp = 0;
-
        if (security_inet_conn_request(sk, skb, req))
                goto drop_and_free;
 
index 13235a012388b7c0103c23fcb33fff96616d3579..e796a64be308ccf6d1fc2d6c726d3f1763aafb8b 100644 (file)
@@ -170,7 +170,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
                goto out;
 
        ret = NULL;
-       req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk, false);
+       req = cookie_tcp_reqsk_alloc(&tcp6_request_sock_ops, sk, skb);
        if (!req)
                goto out;
 
@@ -178,9 +178,6 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
        treq = tcp_rsk(req);
        treq->tfo_listener = false;
 
-       if (IS_ENABLED(CONFIG_MPTCP))
-               treq->is_mptcp = 0;
-
        if (security_inet_conn_request(sk, skb, req))
                goto out_free;