summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/tcp.h2
-rw-r--r--include/net/tcp.h8
-rw-r--r--net/ipv4/sysctl_net_ipv4.c3
-rw-r--r--net/ipv4/tcp.c3
-rw-r--r--net/ipv4/tcp_fastopen.c35
5 files changed, 24 insertions, 27 deletions
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 2689b0b0b68a..f3a85a7fb4b1 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -58,7 +58,7 @@ static inline unsigned int tcp_optlen(const struct sk_buff *skb)
58 58
59/* TCP Fast Open Cookie as stored in memory */ 59/* TCP Fast Open Cookie as stored in memory */
60struct tcp_fastopen_cookie { 60struct tcp_fastopen_cookie {
61 u64 val[TCP_FASTOPEN_COOKIE_MAX / sizeof(u64)]; 61 __le64 val[DIV_ROUND_UP(TCP_FASTOPEN_COOKIE_MAX, sizeof(u64))];
62 s8 len; 62 s8 len;
63 bool exp; /* In RFC6994 experimental option format */ 63 bool exp; /* In RFC6994 experimental option format */
64}; 64};
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 573c9e9b0d72..9d36cc88d043 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -43,6 +43,7 @@
43#include <linux/seq_file.h> 43#include <linux/seq_file.h>
44#include <linux/memcontrol.h> 44#include <linux/memcontrol.h>
45#include <linux/bpf-cgroup.h> 45#include <linux/bpf-cgroup.h>
46#include <linux/siphash.h>
46 47
47extern struct inet_hashinfo tcp_hashinfo; 48extern struct inet_hashinfo tcp_hashinfo;
48 49
@@ -1612,8 +1613,7 @@ void tcp_free_fastopen_req(struct tcp_sock *tp);
1612void tcp_fastopen_destroy_cipher(struct sock *sk); 1613void tcp_fastopen_destroy_cipher(struct sock *sk);
1613void tcp_fastopen_ctx_destroy(struct net *net); 1614void tcp_fastopen_ctx_destroy(struct net *net);
1614int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk, 1615int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk,
1615 void *primary_key, void *backup_key, 1616 void *primary_key, void *backup_key);
1616 unsigned int len);
1617void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb); 1617void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb);
1618struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb, 1618struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
1619 struct request_sock *req, 1619 struct request_sock *req,
@@ -1623,14 +1623,14 @@ void tcp_fastopen_init_key_once(struct net *net);
1623bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss, 1623bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss,
1624 struct tcp_fastopen_cookie *cookie); 1624 struct tcp_fastopen_cookie *cookie);
1625bool tcp_fastopen_defer_connect(struct sock *sk, int *err); 1625bool tcp_fastopen_defer_connect(struct sock *sk, int *err);
1626#define TCP_FASTOPEN_KEY_LENGTH 16 1626#define TCP_FASTOPEN_KEY_LENGTH sizeof(siphash_key_t)
1627#define TCP_FASTOPEN_KEY_MAX 2 1627#define TCP_FASTOPEN_KEY_MAX 2
1628#define TCP_FASTOPEN_KEY_BUF_LENGTH \ 1628#define TCP_FASTOPEN_KEY_BUF_LENGTH \
1629 (TCP_FASTOPEN_KEY_LENGTH * TCP_FASTOPEN_KEY_MAX) 1629 (TCP_FASTOPEN_KEY_LENGTH * TCP_FASTOPEN_KEY_MAX)
1630 1630
1631/* Fastopen key context */ 1631/* Fastopen key context */
1632struct tcp_fastopen_context { 1632struct tcp_fastopen_context {
1633 __u8 key[TCP_FASTOPEN_KEY_MAX][TCP_FASTOPEN_KEY_LENGTH]; 1633 siphash_key_t key[TCP_FASTOPEN_KEY_MAX];
1634 int num; 1634 int num;
1635 struct rcu_head rcu; 1635 struct rcu_head rcu;
1636}; 1636};
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 7d802acde040..7d66306b5f39 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -365,8 +365,7 @@ static int proc_tcp_fastopen_key(struct ctl_table *table, int write,
365 } 365 }
366 } 366 }
367 tcp_fastopen_reset_cipher(net, NULL, key, 367 tcp_fastopen_reset_cipher(net, NULL, key,
368 backup_data ? key + 4 : NULL, 368 backup_data ? key + 4 : NULL);
369 TCP_FASTOPEN_KEY_LENGTH);
370 } 369 }
371 370
372bad_key: 371bad_key:
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index efd7f2b1d1f0..47c217905864 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2822,8 +2822,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
2822 if (optlen == TCP_FASTOPEN_KEY_BUF_LENGTH) 2822 if (optlen == TCP_FASTOPEN_KEY_BUF_LENGTH)
2823 backup_key = key + TCP_FASTOPEN_KEY_LENGTH; 2823 backup_key = key + TCP_FASTOPEN_KEY_LENGTH;
2824 2824
2825 return tcp_fastopen_reset_cipher(net, sk, key, backup_key, 2825 return tcp_fastopen_reset_cipher(net, sk, key, backup_key);
2826 TCP_FASTOPEN_KEY_LENGTH);
2827 } 2826 }
2828 default: 2827 default:
2829 /* fallthru */ 2828 /* fallthru */
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index f918599181dd..3fd451271a70 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -7,7 +7,6 @@
7#include <linux/tcp.h> 7#include <linux/tcp.h>
8#include <linux/rcupdate.h> 8#include <linux/rcupdate.h>
9#include <linux/rculist.h> 9#include <linux/rculist.h>
10#include <linux/siphash.h>
11#include <net/inetpeer.h> 10#include <net/inetpeer.h>
12#include <net/tcp.h> 11#include <net/tcp.h>
13 12
@@ -31,7 +30,7 @@ void tcp_fastopen_init_key_once(struct net *net)
31 * for a valid cookie, so this is an acceptable risk. 30 * for a valid cookie, so this is an acceptable risk.
32 */ 31 */
33 get_random_bytes(key, sizeof(key)); 32 get_random_bytes(key, sizeof(key));
34 tcp_fastopen_reset_cipher(net, NULL, key, NULL, sizeof(key)); 33 tcp_fastopen_reset_cipher(net, NULL, key, NULL);
35} 34}
36 35
37static void tcp_fastopen_ctx_free(struct rcu_head *head) 36static void tcp_fastopen_ctx_free(struct rcu_head *head)
@@ -68,8 +67,7 @@ void tcp_fastopen_ctx_destroy(struct net *net)
68} 67}
69 68
70int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk, 69int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk,
71 void *primary_key, void *backup_key, 70 void *primary_key, void *backup_key)
72 unsigned int len)
73{ 71{
74 struct tcp_fastopen_context *ctx, *octx; 72 struct tcp_fastopen_context *ctx, *octx;
75 struct fastopen_queue *q; 73 struct fastopen_queue *q;
@@ -81,9 +79,11 @@ int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk,
81 goto out; 79 goto out;
82 } 80 }
83 81
84 memcpy(ctx->key[0], primary_key, len); 82 ctx->key[0].key[0] = get_unaligned_le64(primary_key);
83 ctx->key[0].key[1] = get_unaligned_le64(primary_key + 8);
85 if (backup_key) { 84 if (backup_key) {
86 memcpy(ctx->key[1], backup_key, len); 85 ctx->key[1].key[0] = get_unaligned_le64(backup_key);
86 ctx->key[1].key[1] = get_unaligned_le64(backup_key + 8);
87 ctx->num = 2; 87 ctx->num = 2;
88 } else { 88 } else {
89 ctx->num = 1; 89 ctx->num = 1;
@@ -110,19 +110,18 @@ out:
110 110
111static bool __tcp_fastopen_cookie_gen_cipher(struct request_sock *req, 111static bool __tcp_fastopen_cookie_gen_cipher(struct request_sock *req,
112 struct sk_buff *syn, 112 struct sk_buff *syn,
113 const u8 *key, 113 const siphash_key_t *key,
114 struct tcp_fastopen_cookie *foc) 114 struct tcp_fastopen_cookie *foc)
115{ 115{
116 BUILD_BUG_ON(TCP_FASTOPEN_KEY_LENGTH != sizeof(siphash_key_t));
117 BUILD_BUG_ON(TCP_FASTOPEN_COOKIE_SIZE != sizeof(u64)); 116 BUILD_BUG_ON(TCP_FASTOPEN_COOKIE_SIZE != sizeof(u64));
118 117
119 if (req->rsk_ops->family == AF_INET) { 118 if (req->rsk_ops->family == AF_INET) {
120 const struct iphdr *iph = ip_hdr(syn); 119 const struct iphdr *iph = ip_hdr(syn);
121 120
122 foc->val[0] = siphash(&iph->saddr, 121 foc->val[0] = cpu_to_le64(siphash(&iph->saddr,
123 sizeof(iph->saddr) + 122 sizeof(iph->saddr) +
124 sizeof(iph->daddr), 123 sizeof(iph->daddr),
125 (const siphash_key_t *)key); 124 key));
126 foc->len = TCP_FASTOPEN_COOKIE_SIZE; 125 foc->len = TCP_FASTOPEN_COOKIE_SIZE;
127 return true; 126 return true;
128 } 127 }
@@ -130,10 +129,10 @@ static bool __tcp_fastopen_cookie_gen_cipher(struct request_sock *req,
130 if (req->rsk_ops->family == AF_INET6) { 129 if (req->rsk_ops->family == AF_INET6) {
131 const struct ipv6hdr *ip6h = ipv6_hdr(syn); 130 const struct ipv6hdr *ip6h = ipv6_hdr(syn);
132 131
133 foc->val[0] = siphash(&ip6h->saddr, 132 foc->val[0] = cpu_to_le64(siphash(&ip6h->saddr,
134 sizeof(ip6h->saddr) + 133 sizeof(ip6h->saddr) +
135 sizeof(ip6h->daddr), 134 sizeof(ip6h->daddr),
136 (const siphash_key_t *)key); 135 key));
137 foc->len = TCP_FASTOPEN_COOKIE_SIZE; 136 foc->len = TCP_FASTOPEN_COOKIE_SIZE;
138 return true; 137 return true;
139 } 138 }
@@ -154,7 +153,7 @@ static void tcp_fastopen_cookie_gen(struct sock *sk,
154 rcu_read_lock(); 153 rcu_read_lock();
155 ctx = tcp_fastopen_get_ctx(sk); 154 ctx = tcp_fastopen_get_ctx(sk);
156 if (ctx) 155 if (ctx)
157 __tcp_fastopen_cookie_gen_cipher(req, syn, ctx->key[0], foc); 156 __tcp_fastopen_cookie_gen_cipher(req, syn, &ctx->key[0], foc);
158 rcu_read_unlock(); 157 rcu_read_unlock();
159} 158}
160 159
@@ -218,7 +217,7 @@ static int tcp_fastopen_cookie_gen_check(struct sock *sk,
218 if (!ctx) 217 if (!ctx)
219 goto out; 218 goto out;
220 for (i = 0; i < tcp_fastopen_context_len(ctx); i++) { 219 for (i = 0; i < tcp_fastopen_context_len(ctx); i++) {
221 __tcp_fastopen_cookie_gen_cipher(req, syn, ctx->key[i], foc); 220 __tcp_fastopen_cookie_gen_cipher(req, syn, &ctx->key[i], foc);
222 if (tcp_fastopen_cookie_match(foc, orig)) { 221 if (tcp_fastopen_cookie_match(foc, orig)) {
223 ret = i + 1; 222 ret = i + 1;
224 goto out; 223 goto out;