mirror of https://gitee.com/openkylin/linux.git
crypto/chelsio/chtls: listen fails with multiadapt
listen fails when more than one tls capable device is registered. tls_hw_hash is called for each dev which loops again for each cdev_list causing listen failure. Hence call chtls_listen_start/stop for specific device than loop over all devices. Signed-off-by: Atul Gupta <atul.gupta@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
df9d4a1780
commit
6422ccc5fb
|
@ -153,6 +153,11 @@ struct chtls_dev {
|
|||
unsigned int cdev_state;
|
||||
};
|
||||
|
||||
struct chtls_listen {
|
||||
struct chtls_dev *cdev;
|
||||
struct sock *sk;
|
||||
};
|
||||
|
||||
struct chtls_hws {
|
||||
struct sk_buff_head sk_recv_queue;
|
||||
u8 txqid;
|
||||
|
|
|
@ -55,24 +55,19 @@ static void unregister_listen_notifier(struct notifier_block *nb)
|
|||
static int listen_notify_handler(struct notifier_block *this,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
struct chtls_dev *cdev;
|
||||
struct sock *sk;
|
||||
int ret;
|
||||
struct chtls_listen *clisten;
|
||||
int ret = NOTIFY_DONE;
|
||||
|
||||
sk = data;
|
||||
ret = NOTIFY_DONE;
|
||||
clisten = (struct chtls_listen *)data;
|
||||
|
||||
switch (event) {
|
||||
case CHTLS_LISTEN_START:
|
||||
ret = chtls_listen_start(clisten->cdev, clisten->sk);
|
||||
kfree(clisten);
|
||||
break;
|
||||
case CHTLS_LISTEN_STOP:
|
||||
mutex_lock(&cdev_list_lock);
|
||||
list_for_each_entry(cdev, &cdev_list, list) {
|
||||
if (event == CHTLS_LISTEN_START)
|
||||
ret = chtls_listen_start(cdev, sk);
|
||||
else
|
||||
chtls_listen_stop(cdev, sk);
|
||||
}
|
||||
mutex_unlock(&cdev_list_lock);
|
||||
chtls_listen_stop(clisten->cdev, clisten->sk);
|
||||
kfree(clisten);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
|
@ -90,8 +85,9 @@ static int listen_backlog_rcv(struct sock *sk, struct sk_buff *skb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int chtls_start_listen(struct sock *sk)
|
||||
static int chtls_start_listen(struct chtls_dev *cdev, struct sock *sk)
|
||||
{
|
||||
struct chtls_listen *clisten;
|
||||
int err;
|
||||
|
||||
if (sk->sk_protocol != IPPROTO_TCP)
|
||||
|
@ -102,21 +98,33 @@ static int chtls_start_listen(struct sock *sk)
|
|||
return -EADDRNOTAVAIL;
|
||||
|
||||
sk->sk_backlog_rcv = listen_backlog_rcv;
|
||||
clisten = kmalloc(sizeof(*clisten), GFP_KERNEL);
|
||||
if (!clisten)
|
||||
return -ENOMEM;
|
||||
clisten->cdev = cdev;
|
||||
clisten->sk = sk;
|
||||
mutex_lock(¬ify_mutex);
|
||||
err = raw_notifier_call_chain(&listen_notify_list,
|
||||
CHTLS_LISTEN_START, sk);
|
||||
CHTLS_LISTEN_START, clisten);
|
||||
mutex_unlock(¬ify_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void chtls_stop_listen(struct sock *sk)
|
||||
static void chtls_stop_listen(struct chtls_dev *cdev, struct sock *sk)
|
||||
{
|
||||
struct chtls_listen *clisten;
|
||||
|
||||
if (sk->sk_protocol != IPPROTO_TCP)
|
||||
return;
|
||||
|
||||
clisten = kmalloc(sizeof(*clisten), GFP_KERNEL);
|
||||
if (!clisten)
|
||||
return;
|
||||
clisten->cdev = cdev;
|
||||
clisten->sk = sk;
|
||||
mutex_lock(¬ify_mutex);
|
||||
raw_notifier_call_chain(&listen_notify_list,
|
||||
CHTLS_LISTEN_STOP, sk);
|
||||
CHTLS_LISTEN_STOP, clisten);
|
||||
mutex_unlock(¬ify_mutex);
|
||||
}
|
||||
|
||||
|
@ -138,15 +146,19 @@ static int chtls_inline_feature(struct tls_device *dev)
|
|||
|
||||
static int chtls_create_hash(struct tls_device *dev, struct sock *sk)
|
||||
{
|
||||
struct chtls_dev *cdev = to_chtls_dev(dev);
|
||||
|
||||
if (sk->sk_state == TCP_LISTEN)
|
||||
return chtls_start_listen(sk);
|
||||
return chtls_start_listen(cdev, sk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void chtls_destroy_hash(struct tls_device *dev, struct sock *sk)
|
||||
{
|
||||
struct chtls_dev *cdev = to_chtls_dev(dev);
|
||||
|
||||
if (sk->sk_state == TCP_LISTEN)
|
||||
chtls_stop_listen(sk);
|
||||
chtls_stop_listen(cdev, sk);
|
||||
}
|
||||
|
||||
static void chtls_free_uld(struct chtls_dev *cdev)
|
||||
|
|
Loading…
Reference in New Issue