Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tcp: syncookies: create mptcp request socket for ACK cookies with MPTCP option

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>

authored by

Florian Westphal and committed by
David S. Miller
6fc8c827 c83a47e5

+37 -11
+2
include/net/tcp.h
··· 469 469 int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th, 470 470 u32 cookie); 471 471 struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb); 472 + struct request_sock *cookie_tcp_reqsk_alloc(const struct request_sock_ops *ops, 473 + struct sock *sk, struct sk_buff *skb); 472 474 #ifdef CONFIG_SYN_COOKIES 473 475 474 476 /* Syncookies use a monotonic timer which increments every 60 seconds.
+34 -4
net/ipv4/syncookies.c
··· 276 276 } 277 277 EXPORT_SYMBOL(cookie_ecn_ok); 278 278 279 + struct request_sock *cookie_tcp_reqsk_alloc(const struct request_sock_ops *ops, 280 + struct sock *sk, 281 + struct sk_buff *skb) 282 + { 283 + struct tcp_request_sock *treq; 284 + struct request_sock *req; 285 + 286 + #ifdef CONFIG_MPTCP 287 + if (sk_is_mptcp(sk)) 288 + ops = &mptcp_subflow_request_sock_ops; 289 + #endif 290 + 291 + req = inet_reqsk_alloc(ops, sk, false); 292 + if (!req) 293 + return NULL; 294 + 295 + #if IS_ENABLED(CONFIG_MPTCP) 296 + treq = tcp_rsk(req); 297 + treq->is_mptcp = sk_is_mptcp(sk); 298 + if (treq->is_mptcp) { 299 + int err = mptcp_subflow_init_cookie_req(req, sk, skb); 300 + 301 + if (err) { 302 + reqsk_free(req); 303 + return NULL; 304 + } 305 + } 306 + #endif 307 + 308 + return req; 309 + } 310 + EXPORT_SYMBOL_GPL(cookie_tcp_reqsk_alloc); 311 + 279 312 /* On input, sk is a listener. 280 313 * Output is listener if incoming packet would not create a child 281 314 * NULL if memory could not be allocated. ··· 359 326 goto out; 360 327 361 328 ret = NULL; 362 - req = inet_reqsk_alloc(&tcp_request_sock_ops, sk, false); /* for safety */ 329 + req = cookie_tcp_reqsk_alloc(&tcp_request_sock_ops, sk, skb); 363 330 if (!req) 364 331 goto out; 365 332 ··· 382 349 req->ts_recent = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0; 383 350 treq->snt_synack = 0; 384 351 treq->tfo_listener = false; 385 - 386 - if (IS_ENABLED(CONFIG_MPTCP)) 387 - treq->is_mptcp = 0; 388 352 389 353 if (IS_ENABLED(CONFIG_SMC)) 390 354 ireq->smc_ok = 0;
-3
net/ipv4/tcp_input.c
··· 6701 6701 6702 6702 af_ops->init_req(req, sk, skb); 6703 6703 6704 - if (IS_ENABLED(CONFIG_MPTCP) && want_cookie) 6705 - tcp_rsk(req)->is_mptcp = 0; 6706 - 6707 6704 if (security_inet_conn_request(sk, skb, req)) 6708 6705 goto drop_and_free; 6709 6706
+1 -4
net/ipv6/syncookies.c
··· 170 170 goto out; 171 171 172 172 ret = NULL; 173 - req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk, false); 173 + req = cookie_tcp_reqsk_alloc(&tcp6_request_sock_ops, sk, skb); 174 174 if (!req) 175 175 goto out; 176 176 177 177 ireq = inet_rsk(req); 178 178 treq = tcp_rsk(req); 179 179 treq->tfo_listener = false; 180 - 181 - if (IS_ENABLED(CONFIG_MPTCP)) 182 - treq->is_mptcp = 0; 183 180 184 181 if (security_inet_conn_request(sk, skb, req)) 185 182 goto out_free;