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) /* TCP Fast Open Cookie as stored in memory */ struct tcp_fastopen_cookie { - u64 val[TCP_FASTOPEN_COOKIE_MAX / sizeof(u64)]; + __le64 val[DIV_ROUND_UP(TCP_FASTOPEN_COOKIE_MAX, sizeof(u64))]; s8 len; bool exp; /* In RFC6994 experimental option format */ }; 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 @@ #include <linux/seq_file.h> #include <linux/memcontrol.h> #include <linux/bpf-cgroup.h> +#include <linux/siphash.h> extern struct inet_hashinfo tcp_hashinfo; @@ -1612,8 +1613,7 @@ void tcp_free_fastopen_req(struct tcp_sock *tp); void tcp_fastopen_destroy_cipher(struct sock *sk); void tcp_fastopen_ctx_destroy(struct net *net); int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk, - void *primary_key, void *backup_key, - unsigned int len); + void *primary_key, void *backup_key); void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb); struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb, struct request_sock *req, @@ -1623,14 +1623,14 @@ void tcp_fastopen_init_key_once(struct net *net); bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss, struct tcp_fastopen_cookie *cookie); bool tcp_fastopen_defer_connect(struct sock *sk, int *err); -#define TCP_FASTOPEN_KEY_LENGTH 16 +#define TCP_FASTOPEN_KEY_LENGTH sizeof(siphash_key_t) #define TCP_FASTOPEN_KEY_MAX 2 #define TCP_FASTOPEN_KEY_BUF_LENGTH \ (TCP_FASTOPEN_KEY_LENGTH * TCP_FASTOPEN_KEY_MAX) /* Fastopen key context */ struct tcp_fastopen_context { - __u8 key[TCP_FASTOPEN_KEY_MAX][TCP_FASTOPEN_KEY_LENGTH]; + siphash_key_t key[TCP_FASTOPEN_KEY_MAX]; int num; struct rcu_head rcu; }; 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, } } tcp_fastopen_reset_cipher(net, NULL, key, - backup_data ? key + 4 : NULL, - TCP_FASTOPEN_KEY_LENGTH); + backup_data ? key + 4 : NULL); } 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, if (optlen == TCP_FASTOPEN_KEY_BUF_LENGTH) backup_key = key + TCP_FASTOPEN_KEY_LENGTH; - return tcp_fastopen_reset_cipher(net, sk, key, backup_key, - TCP_FASTOPEN_KEY_LENGTH); + return tcp_fastopen_reset_cipher(net, sk, key, backup_key); } default: /* 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 @@ #include <linux/tcp.h> #include <linux/rcupdate.h> #include <linux/rculist.h> -#include <linux/siphash.h> #include <net/inetpeer.h> #include <net/tcp.h> @@ -31,7 +30,7 @@ void tcp_fastopen_init_key_once(struct net *net) * for a valid cookie, so this is an acceptable risk. */ get_random_bytes(key, sizeof(key)); - tcp_fastopen_reset_cipher(net, NULL, key, NULL, sizeof(key)); + tcp_fastopen_reset_cipher(net, NULL, key, NULL); } static void tcp_fastopen_ctx_free(struct rcu_head *head) @@ -68,8 +67,7 @@ void tcp_fastopen_ctx_destroy(struct net *net) } int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk, - void *primary_key, void *backup_key, - unsigned int len) + void *primary_key, void *backup_key) { struct tcp_fastopen_context *ctx, *octx; struct fastopen_queue *q; @@ -81,9 +79,11 @@ int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk, goto out; } - memcpy(ctx->key[0], primary_key, len); + ctx->key[0].key[0] = get_unaligned_le64(primary_key); + ctx->key[0].key[1] = get_unaligned_le64(primary_key + 8); if (backup_key) { - memcpy(ctx->key[1], backup_key, len); + ctx->key[1].key[0] = get_unaligned_le64(backup_key); + ctx->key[1].key[1] = get_unaligned_le64(backup_key + 8); ctx->num = 2; } else { ctx->num = 1; @@ -110,19 +110,18 @@ out: static bool __tcp_fastopen_cookie_gen_cipher(struct request_sock *req, struct sk_buff *syn, - const u8 *key, + const siphash_key_t *key, struct tcp_fastopen_cookie *foc) { - BUILD_BUG_ON(TCP_FASTOPEN_KEY_LENGTH != sizeof(siphash_key_t)); BUILD_BUG_ON(TCP_FASTOPEN_COOKIE_SIZE != sizeof(u64)); if (req->rsk_ops->family == AF_INET) { const struct iphdr *iph = ip_hdr(syn); - foc->val[0] = siphash(&iph->saddr, - sizeof(iph->saddr) + - sizeof(iph->daddr), - (const siphash_key_t *)key); + foc->val[0] = cpu_to_le64(siphash(&iph->saddr, + sizeof(iph->saddr) + + sizeof(iph->daddr), + key)); foc->len = TCP_FASTOPEN_COOKIE_SIZE; return true; } @@ -130,10 +129,10 @@ static bool __tcp_fastopen_cookie_gen_cipher(struct request_sock *req, if (req->rsk_ops->family == AF_INET6) { const struct ipv6hdr *ip6h = ipv6_hdr(syn); - foc->val[0] = siphash(&ip6h->saddr, - sizeof(ip6h->saddr) + - sizeof(ip6h->daddr), - (const siphash_key_t *)key); + foc->val[0] = cpu_to_le64(siphash(&ip6h->saddr, + sizeof(ip6h->saddr) + + sizeof(ip6h->daddr), + key)); foc->len = TCP_FASTOPEN_COOKIE_SIZE; return true; } @@ -154,7 +153,7 @@ static void tcp_fastopen_cookie_gen(struct sock *sk, rcu_read_lock(); ctx = tcp_fastopen_get_ctx(sk); if (ctx) - __tcp_fastopen_cookie_gen_cipher(req, syn, ctx->key[0], foc); + __tcp_fastopen_cookie_gen_cipher(req, syn, &ctx->key[0], foc); rcu_read_unlock(); } @@ -218,7 +217,7 @@ static int tcp_fastopen_cookie_gen_check(struct sock *sk, if (!ctx) goto out; for (i = 0; i < tcp_fastopen_context_len(ctx); i++) { - __tcp_fastopen_cookie_gen_cipher(req, syn, ctx->key[i], foc); + __tcp_fastopen_cookie_gen_cipher(req, syn, &ctx->key[i], foc); if (tcp_fastopen_cookie_match(foc, orig)) { ret = i + 1; goto out; |