linux/net/ipv4/tcp_fastopen.c
<<
>>
Prefs
   1#include <linux/err.h>
   2#include <linux/init.h>
   3#include <linux/kernel.h>
   4#include <linux/list.h>
   5#include <linux/tcp.h>
   6#include <linux/rcupdate.h>
   7#include <linux/rculist.h>
   8#include <net/inetpeer.h>
   9#include <net/tcp.h>
  10
  11int sysctl_tcp_fastopen __read_mostly;
  12
  13struct tcp_fastopen_context __rcu *tcp_fastopen_ctx;
  14
  15static DEFINE_SPINLOCK(tcp_fastopen_ctx_lock);
  16
  17static void tcp_fastopen_ctx_free(struct rcu_head *head)
  18{
  19        struct tcp_fastopen_context *ctx =
  20            container_of(head, struct tcp_fastopen_context, rcu);
  21        crypto_free_cipher(ctx->tfm);
  22        kfree(ctx);
  23}
  24
  25int tcp_fastopen_reset_cipher(void *key, unsigned int len)
  26{
  27        int err;
  28        struct tcp_fastopen_context *ctx, *octx;
  29
  30        ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
  31        if (!ctx)
  32                return -ENOMEM;
  33        ctx->tfm = crypto_alloc_cipher("aes", 0, 0);
  34
  35        if (IS_ERR(ctx->tfm)) {
  36                err = PTR_ERR(ctx->tfm);
  37error:          kfree(ctx);
  38                pr_err("TCP: TFO aes cipher alloc error: %d\n", err);
  39                return err;
  40        }
  41        err = crypto_cipher_setkey(ctx->tfm, key, len);
  42        if (err) {
  43                pr_err("TCP: TFO cipher key error: %d\n", err);
  44                crypto_free_cipher(ctx->tfm);
  45                goto error;
  46        }
  47        memcpy(ctx->key, key, len);
  48
  49        spin_lock(&tcp_fastopen_ctx_lock);
  50
  51        octx = rcu_dereference_protected(tcp_fastopen_ctx,
  52                                lockdep_is_held(&tcp_fastopen_ctx_lock));
  53        rcu_assign_pointer(tcp_fastopen_ctx, ctx);
  54        spin_unlock(&tcp_fastopen_ctx_lock);
  55
  56        if (octx)
  57                call_rcu(&octx->rcu, tcp_fastopen_ctx_free);
  58        return err;
  59}
  60
  61/* Computes the fastopen cookie for the IP path.
  62 * The path is a 128 bits long (pad with zeros for IPv4).
  63 *
  64 * The caller must check foc->len to determine if a valid cookie
  65 * has been generated successfully.
  66*/
  67void tcp_fastopen_cookie_gen(__be32 src, __be32 dst,
  68                             struct tcp_fastopen_cookie *foc)
  69{
  70        __be32 path[4] = { src, dst, 0, 0 };
  71        struct tcp_fastopen_context *ctx;
  72
  73        rcu_read_lock();
  74        ctx = rcu_dereference(tcp_fastopen_ctx);
  75        if (ctx) {
  76                crypto_cipher_encrypt_one(ctx->tfm, foc->val, (__u8 *)path);
  77                foc->len = TCP_FASTOPEN_COOKIE_SIZE;
  78        }
  79        rcu_read_unlock();
  80}
  81
  82static int __init tcp_fastopen_init(void)
  83{
  84        __u8 key[TCP_FASTOPEN_KEY_LENGTH];
  85
  86        get_random_bytes(key, sizeof(key));
  87        tcp_fastopen_reset_cipher(key, sizeof(key));
  88        return 0;
  89}
  90
  91late_initcall(tcp_fastopen_init);
  92