Commit e58133e4 authored by Atul Gupta's avatar Atul Gupta Committed by Greg Kroah-Hartman

crypto/chelsio/chtls: listen fails with multiadapt

[ Upstream commit 6422ccc5 ]

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: default avatarAtul Gupta <atul.gupta@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 48012689
......@@ -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(&notify_mutex);
err = raw_notifier_call_chain(&listen_notify_list,
CHTLS_LISTEN_START, sk);
CHTLS_LISTEN_START, clisten);
mutex_unlock(&notify_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(&notify_mutex);
raw_notifier_call_chain(&listen_notify_list,
CHTLS_LISTEN_STOP, sk);
CHTLS_LISTEN_STOP, clisten);
mutex_unlock(&notify_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_register_dev(struct chtls_dev *cdev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment