0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <linux/list.h>
0035 #include <linux/rcupdate.h>
0036 #include <linux/spinlock.h>
0037 #include <net/inet_connection_sock.h>
0038 #include <net/tls.h>
0039 #include <net/tls_toe.h>
0040
0041 #include "tls.h"
0042
0043 static LIST_HEAD(device_list);
0044 static DEFINE_SPINLOCK(device_spinlock);
0045
0046 static void tls_toe_sk_destruct(struct sock *sk)
0047 {
0048 struct inet_connection_sock *icsk = inet_csk(sk);
0049 struct tls_context *ctx = tls_get_ctx(sk);
0050
0051 ctx->sk_destruct(sk);
0052
0053 rcu_assign_pointer(icsk->icsk_ulp_data, NULL);
0054 tls_ctx_free(sk, ctx);
0055 }
0056
0057 int tls_toe_bypass(struct sock *sk)
0058 {
0059 struct tls_toe_device *dev;
0060 struct tls_context *ctx;
0061 int rc = 0;
0062
0063 spin_lock_bh(&device_spinlock);
0064 list_for_each_entry(dev, &device_list, dev_list) {
0065 if (dev->feature && dev->feature(dev)) {
0066 ctx = tls_ctx_create(sk);
0067 if (!ctx)
0068 goto out;
0069
0070 ctx->sk_destruct = sk->sk_destruct;
0071 sk->sk_destruct = tls_toe_sk_destruct;
0072 ctx->rx_conf = TLS_HW_RECORD;
0073 ctx->tx_conf = TLS_HW_RECORD;
0074 update_sk_prot(sk, ctx);
0075 rc = 1;
0076 break;
0077 }
0078 }
0079 out:
0080 spin_unlock_bh(&device_spinlock);
0081 return rc;
0082 }
0083
0084 void tls_toe_unhash(struct sock *sk)
0085 {
0086 struct tls_context *ctx = tls_get_ctx(sk);
0087 struct tls_toe_device *dev;
0088
0089 spin_lock_bh(&device_spinlock);
0090 list_for_each_entry(dev, &device_list, dev_list) {
0091 if (dev->unhash) {
0092 kref_get(&dev->kref);
0093 spin_unlock_bh(&device_spinlock);
0094 dev->unhash(dev, sk);
0095 kref_put(&dev->kref, dev->release);
0096 spin_lock_bh(&device_spinlock);
0097 }
0098 }
0099 spin_unlock_bh(&device_spinlock);
0100 ctx->sk_proto->unhash(sk);
0101 }
0102
0103 int tls_toe_hash(struct sock *sk)
0104 {
0105 struct tls_context *ctx = tls_get_ctx(sk);
0106 struct tls_toe_device *dev;
0107 int err;
0108
0109 err = ctx->sk_proto->hash(sk);
0110 spin_lock_bh(&device_spinlock);
0111 list_for_each_entry(dev, &device_list, dev_list) {
0112 if (dev->hash) {
0113 kref_get(&dev->kref);
0114 spin_unlock_bh(&device_spinlock);
0115 err |= dev->hash(dev, sk);
0116 kref_put(&dev->kref, dev->release);
0117 spin_lock_bh(&device_spinlock);
0118 }
0119 }
0120 spin_unlock_bh(&device_spinlock);
0121
0122 if (err)
0123 tls_toe_unhash(sk);
0124 return err;
0125 }
0126
0127 void tls_toe_register_device(struct tls_toe_device *device)
0128 {
0129 spin_lock_bh(&device_spinlock);
0130 list_add_tail(&device->dev_list, &device_list);
0131 spin_unlock_bh(&device_spinlock);
0132 }
0133 EXPORT_SYMBOL(tls_toe_register_device);
0134
0135 void tls_toe_unregister_device(struct tls_toe_device *device)
0136 {
0137 spin_lock_bh(&device_spinlock);
0138 list_del(&device->dev_list);
0139 spin_unlock_bh(&device_spinlock);
0140 }
0141 EXPORT_SYMBOL(tls_toe_unregister_device);