diff options
-rw-r--r-- | include/linux/tcp.h | 2 | ||||
-rw-r--r-- | include/net/tcp.h | 8 | ||||
-rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 3 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 3 | ||||
-rw-r--r-- | net/ipv4/tcp_fastopen.c | 35 |
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 */ |
60 | struct tcp_fastopen_cookie { | 60 | struct 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 | ||
47 | extern struct inet_hashinfo tcp_hashinfo; | 48 | extern struct inet_hashinfo tcp_hashinfo; |
48 | 49 | ||
@@ -1612,8 +1613,7 @@ void tcp_free_fastopen_req(struct tcp_sock *tp); | |||
1612 | void tcp_fastopen_destroy_cipher(struct sock *sk); | 1613 | void tcp_fastopen_destroy_cipher(struct sock *sk); |
1613 | void tcp_fastopen_ctx_destroy(struct net *net); | 1614 | void tcp_fastopen_ctx_destroy(struct net *net); |
1614 | int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk, | 1615 | int 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); | ||
1617 | void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb); | 1617 | void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb); |
1618 | struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb, | 1618 | struct 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); | |||
1623 | bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss, | 1623 | bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss, |
1624 | struct tcp_fastopen_cookie *cookie); | 1624 | struct tcp_fastopen_cookie *cookie); |
1625 | bool tcp_fastopen_defer_connect(struct sock *sk, int *err); | 1625 | bool 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 */ |
1632 | struct tcp_fastopen_context { | 1632 | struct 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 | ||
372 | bad_key: | 371 | bad_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 | ||
37 | static void tcp_fastopen_ctx_free(struct rcu_head *head) | 36 | static 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 | ||
70 | int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk, | 69 | int 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 | ||
111 | static bool __tcp_fastopen_cookie_gen_cipher(struct request_sock *req, | 111 | static 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; |