Commit 6422ccc5 authored by Atul Gupta's avatar Atul Gupta Committed by David S. Miller
Browse files

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: default avatarAtul Gupta <atul.gupta@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent df9d4a17
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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;
+31 −19
Original line number Diff line number Diff line
@@ -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_free_uld(struct chtls_dev *cdev)