@@ -472,7 +472,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
472
472
static int tcp_v6_send_synack (struct sock * sk , struct dst_entry * dst ,
473
473
struct flowi6 * fl6 ,
474
474
struct request_sock * req ,
475
- u16 queue_mapping )
475
+ u16 queue_mapping ,
476
+ struct tcp_fastopen_cookie * foc )
476
477
{
477
478
struct inet_request_sock * ireq = inet_rsk (req );
478
479
struct ipv6_pinfo * np = inet6_sk (sk );
@@ -483,7 +484,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst,
483
484
if (!dst && (dst = inet6_csk_route_req (sk , fl6 , req )) == NULL )
484
485
goto done ;
485
486
486
- skb = tcp_make_synack (sk , dst , req , NULL );
487
+ skb = tcp_make_synack (sk , dst , req , foc );
487
488
488
489
if (skb ) {
489
490
__tcp_v6_send_check (skb , & ireq -> ir_v6_loc_addr ,
@@ -507,7 +508,7 @@ static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req)
507
508
struct flowi6 fl6 ;
508
509
int res ;
509
510
510
- res = tcp_v6_send_synack (sk , NULL , & fl6 , req , 0 );
511
+ res = tcp_v6_send_synack (sk , NULL , & fl6 , req , 0 , NULL );
511
512
if (!res ) {
512
513
TCP_INC_STATS_BH (sock_net (sk ), TCP_MIB_RETRANSSEGS );
513
514
NET_INC_STATS_BH (sock_net (sk ), LINUX_MIB_TCPSYNRETRANS );
@@ -926,7 +927,12 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
926
927
static void tcp_v6_reqsk_send_ack (struct sock * sk , struct sk_buff * skb ,
927
928
struct request_sock * req )
928
929
{
929
- tcp_v6_send_ack (skb , tcp_rsk (req )-> snt_isn + 1 , tcp_rsk (req )-> rcv_isn + 1 ,
930
+ /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV
931
+ * sk->sk_state == TCP_SYN_RECV -> for Fast Open.
932
+ */
933
+ tcp_v6_send_ack (skb , (sk -> sk_state == TCP_LISTEN ) ?
934
+ tcp_rsk (req )-> snt_isn + 1 : tcp_sk (sk )-> snd_nxt ,
935
+ tcp_rsk (req )-> rcv_nxt ,
930
936
req -> rcv_wnd , tcp_time_stamp , req -> ts_recent , sk -> sk_bound_dev_if ,
931
937
tcp_v6_md5_do_lookup (sk , & ipv6_hdr (skb )-> daddr ),
932
938
0 , 0 );
@@ -978,8 +984,10 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
978
984
struct tcp_sock * tp = tcp_sk (sk );
979
985
__u32 isn = TCP_SKB_CB (skb )-> when ;
980
986
struct dst_entry * dst = NULL ;
987
+ struct tcp_fastopen_cookie foc = { .len = -1 };
988
+ bool want_cookie = false, fastopen ;
981
989
struct flowi6 fl6 ;
982
- bool want_cookie = false ;
990
+ int err ;
983
991
984
992
if (skb -> protocol == htons (ETH_P_IP ))
985
993
return tcp_v4_conn_request (sk , skb );
@@ -1010,7 +1018,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1010
1018
tcp_clear_options (& tmp_opt );
1011
1019
tmp_opt .mss_clamp = IPV6_MIN_MTU - sizeof (struct tcphdr ) - sizeof (struct ipv6hdr );
1012
1020
tmp_opt .user_mss = tp -> rx_opt .user_mss ;
1013
- tcp_parse_options (skb , & tmp_opt , 0 , NULL );
1021
+ tcp_parse_options (skb , & tmp_opt , 0 , want_cookie ? NULL : & foc );
1014
1022
1015
1023
if (want_cookie && !tmp_opt .saw_tstamp )
1016
1024
tcp_clear_options (& tmp_opt );
@@ -1083,19 +1091,27 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1083
1091
isn = tcp_v6_init_sequence (skb );
1084
1092
}
1085
1093
have_isn :
1086
- tcp_rsk (req )-> snt_isn = isn ;
1087
1094
1088
1095
if (security_inet_conn_request (sk , skb , req ))
1089
1096
goto drop_and_release ;
1090
1097
1091
- if (tcp_v6_send_synack (sk , dst , & fl6 , req ,
1092
- skb_get_queue_mapping (skb )) ||
1093
- want_cookie )
1098
+ if (!dst && (dst = inet6_csk_route_req (sk , & fl6 , req )) == NULL )
1094
1099
goto drop_and_free ;
1095
1100
1101
+ tcp_rsk (req )-> snt_isn = isn ;
1096
1102
tcp_rsk (req )-> snt_synack = tcp_time_stamp ;
1097
- tcp_rsk (req )-> listener = NULL ;
1098
- inet6_csk_reqsk_queue_hash_add (sk , req , TCP_TIMEOUT_INIT );
1103
+ tcp_openreq_init_rwin (req , sk , dst );
1104
+ fastopen = !want_cookie &&
1105
+ tcp_try_fastopen (sk , skb , req , & foc , dst );
1106
+ err = tcp_v6_send_synack (sk , dst , & fl6 , req ,
1107
+ skb_get_queue_mapping (skb ), & foc );
1108
+ if (!fastopen ) {
1109
+ if (err || want_cookie )
1110
+ goto drop_and_free ;
1111
+
1112
+ tcp_rsk (req )-> listener = NULL ;
1113
+ inet6_csk_reqsk_queue_hash_add (sk , req , TCP_TIMEOUT_INIT );
1114
+ }
1099
1115
return 0 ;
1100
1116
1101
1117
drop_and_release :
0 commit comments