aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/tcp_fastopen.c57
-rw-r--r--net/ipv6/tcp_ipv6.c40
2 files changed, 71 insertions, 26 deletions
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index 9b947a9aaf6e..62e48cf84e60 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -72,27 +72,58 @@ error: kfree(ctx);
72 return err; 72 return err;
73} 73}
74 74
75/* Computes the fastopen cookie for the IP path. 75static bool __tcp_fastopen_cookie_gen(const void *path,
76 * The path is a 128 bits long (pad with zeros for IPv4). 76 struct tcp_fastopen_cookie *foc)
77 *
78 * The caller must check foc->len to determine if a valid cookie
79 * has been generated successfully.
80*/
81void tcp_fastopen_cookie_gen(__be32 src, __be32 dst,
82 struct tcp_fastopen_cookie *foc)
83{ 77{
84 __be32 path[4] = { src, dst, 0, 0 };
85 struct tcp_fastopen_context *ctx; 78 struct tcp_fastopen_context *ctx;
79 bool ok = false;
86 80
87 tcp_fastopen_init_key_once(true); 81 tcp_fastopen_init_key_once(true);
88 82
89 rcu_read_lock(); 83 rcu_read_lock();
90 ctx = rcu_dereference(tcp_fastopen_ctx); 84 ctx = rcu_dereference(tcp_fastopen_ctx);
91 if (ctx) { 85 if (ctx) {
92 crypto_cipher_encrypt_one(ctx->tfm, foc->val, (__u8 *)path); 86 crypto_cipher_encrypt_one(ctx->tfm, foc->val, path);
93 foc->len = TCP_FASTOPEN_COOKIE_SIZE; 87 foc->len = TCP_FASTOPEN_COOKIE_SIZE;
88 ok = true;
94 } 89 }
95 rcu_read_unlock(); 90 rcu_read_unlock();
91 return ok;
92}
93
94/* Generate the fastopen cookie by doing aes128 encryption on both
95 * the source and destination addresses. Pad 0s for IPv4 or IPv4-mapped-IPv6
96 * addresses. For the longer IPv6 addresses use CBC-MAC.
97 *
98 * XXX (TFO) - refactor when TCP_FASTOPEN_COOKIE_SIZE != AES_BLOCK_SIZE.
99 */
100static bool tcp_fastopen_cookie_gen(struct request_sock *req,
101 struct sk_buff *syn,
102 struct tcp_fastopen_cookie *foc)
103{
104 if (req->rsk_ops->family == AF_INET) {
105 const struct iphdr *iph = ip_hdr(syn);
106
107 __be32 path[4] = { iph->saddr, iph->daddr, 0, 0 };
108 return __tcp_fastopen_cookie_gen(path, foc);
109 }
110
111#if IS_ENABLED(CONFIG_IPV6)
112 if (req->rsk_ops->family == AF_INET6) {
113 const struct ipv6hdr *ip6h = ipv6_hdr(syn);
114 struct tcp_fastopen_cookie tmp;
115
116 if (__tcp_fastopen_cookie_gen(&ip6h->saddr, &tmp)) {
117 struct in6_addr *buf = (struct in6_addr *) tmp.val;
118 int i = 4;
119
120 for (i = 0; i < 4; i++)
121 buf->s6_addr32[i] ^= ip6h->daddr.s6_addr32[i];
122 return __tcp_fastopen_cookie_gen(buf, foc);
123 }
124 }
125#endif
126 return false;
96} 127}
97 128
98static bool tcp_fastopen_create_child(struct sock *sk, 129static bool tcp_fastopen_create_child(struct sock *sk,
@@ -234,10 +265,8 @@ bool tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
234 if (syn_data && (sysctl_tcp_fastopen & TFO_SERVER_COOKIE_NOT_REQD)) 265 if (syn_data && (sysctl_tcp_fastopen & TFO_SERVER_COOKIE_NOT_REQD))
235 goto fastopen; 266 goto fastopen;
236 267
237 tcp_fastopen_cookie_gen(ip_hdr(skb)->saddr, 268 if (tcp_fastopen_cookie_gen(req, skb, &valid_foc) &&
238 ip_hdr(skb)->daddr, &valid_foc); 269 foc->len == TCP_FASTOPEN_COOKIE_SIZE &&
239
240 if (foc->len == TCP_FASTOPEN_COOKIE_SIZE &&
241 foc->len == valid_foc.len && 270 foc->len == valid_foc.len &&
242 !memcmp(foc->val, valid_foc.val, foc->len)) { 271 !memcmp(foc->val, valid_foc.val, foc->len)) {
243 /* Cookie is valid. Create a (full) child socket to accept 272 /* Cookie is valid. Create a (full) child socket to accept
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index a7a62ce12b3f..3a267bf14f2f 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -472,7 +472,8 @@ out:
472static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst, 472static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst,
473 struct flowi6 *fl6, 473 struct flowi6 *fl6,
474 struct request_sock *req, 474 struct request_sock *req,
475 u16 queue_mapping) 475 u16 queue_mapping,
476 struct tcp_fastopen_cookie *foc)
476{ 477{
477 struct inet_request_sock *ireq = inet_rsk(req); 478 struct inet_request_sock *ireq = inet_rsk(req);
478 struct ipv6_pinfo *np = inet6_sk(sk); 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 if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL) 484 if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL)
484 goto done; 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 if (skb) { 489 if (skb) {
489 __tcp_v6_send_check(skb, &ireq->ir_v6_loc_addr, 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 struct flowi6 fl6; 508 struct flowi6 fl6;
508 int res; 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 if (!res) { 512 if (!res) {
512 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); 513 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
513 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSYNRETRANS); 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)
926static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, 927static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
927 struct request_sock *req) 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 req->rcv_wnd, tcp_time_stamp, req->ts_recent, sk->sk_bound_dev_if, 936 req->rcv_wnd, tcp_time_stamp, req->ts_recent, sk->sk_bound_dev_if,
931 tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr), 937 tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr),
932 0, 0); 938 0, 0);
@@ -978,8 +984,10 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
978 struct tcp_sock *tp = tcp_sk(sk); 984 struct tcp_sock *tp = tcp_sk(sk);
979 __u32 isn = TCP_SKB_CB(skb)->when; 985 __u32 isn = TCP_SKB_CB(skb)->when;
980 struct dst_entry *dst = NULL; 986 struct dst_entry *dst = NULL;
987 struct tcp_fastopen_cookie foc = { .len = -1 };
988 bool want_cookie = false, fastopen;
981 struct flowi6 fl6; 989 struct flowi6 fl6;
982 bool want_cookie = false; 990 int err;
983 991
984 if (skb->protocol == htons(ETH_P_IP)) 992 if (skb->protocol == htons(ETH_P_IP))
985 return tcp_v4_conn_request(sk, skb); 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 tcp_clear_options(&tmp_opt); 1018 tcp_clear_options(&tmp_opt);
1011 tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); 1019 tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
1012 tmp_opt.user_mss = tp->rx_opt.user_mss; 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 if (want_cookie && !tmp_opt.saw_tstamp) 1023 if (want_cookie && !tmp_opt.saw_tstamp)
1016 tcp_clear_options(&tmp_opt); 1024 tcp_clear_options(&tmp_opt);
@@ -1083,19 +1091,27 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1083 isn = tcp_v6_init_sequence(skb); 1091 isn = tcp_v6_init_sequence(skb);
1084 } 1092 }
1085have_isn: 1093have_isn:
1086 tcp_rsk(req)->snt_isn = isn;
1087 1094
1088 if (security_inet_conn_request(sk, skb, req)) 1095 if (security_inet_conn_request(sk, skb, req))
1089 goto drop_and_release; 1096 goto drop_and_release;
1090 1097
1091 if (tcp_v6_send_synack(sk, dst, &fl6, req, 1098 if (!dst && (dst = inet6_csk_route_req(sk, &fl6, req)) == NULL)
1092 skb_get_queue_mapping(skb)) ||
1093 want_cookie)
1094 goto drop_and_free; 1099 goto drop_and_free;
1095 1100
1101 tcp_rsk(req)->snt_isn = isn;
1096 tcp_rsk(req)->snt_synack = tcp_time_stamp; 1102 tcp_rsk(req)->snt_synack = tcp_time_stamp;
1097 tcp_rsk(req)->listener = NULL; 1103 tcp_openreq_init_rwin(req, sk, dst);
1098 inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); 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 return 0; 1115 return 0;
1100 1116
1101drop_and_release: 1117drop_and_release: