#include <linux/seq_file.h>
#include <linux/memcontrol.h>
#include <linux/bpf-cgroup.h>
+#include <linux/siphash.h>
extern struct inet_hashinfo tcp_hashinfo;
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,
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;
};
#include <linux/tcp.h>
#include <linux/rcupdate.h>
#include <linux/rculist.h>
-#include <linux/siphash.h>
#include <net/inetpeer.h>
#include <net/tcp.h>
* 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)
}
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;
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;
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;
}
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;
}
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();
}
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;