Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NFC: Purge LLCP socket Tx queues when being disconnected

The Tx queues are no longer valid when we receive a disconnection or when
the LLCP link goes down. In the later case we also purge the entire local
Tx queue.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

+31
+31
net/nfc/llcp/llcp.c
··· 45 45 write_unlock(&l->lock); 46 46 } 47 47 48 + static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock) 49 + { 50 + struct nfc_llcp_local *local = sock->local; 51 + struct sk_buff *s, *tmp; 52 + 53 + pr_debug("%p\n", &sock->sk); 54 + 55 + skb_queue_purge(&sock->tx_queue); 56 + skb_queue_purge(&sock->tx_pending_queue); 57 + skb_queue_purge(&sock->tx_backlog_queue); 58 + 59 + if (local == NULL) 60 + return; 61 + 62 + /* Search for local pending SKBs that are related to this socket */ 63 + skb_queue_walk_safe(&local->tx_queue, s, tmp) { 64 + if (s->sk != &sock->sk) 65 + continue; 66 + 67 + skb_unlink(s, &local->tx_queue); 68 + kfree_skb(s); 69 + } 70 + } 71 + 48 72 static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) 49 73 { 50 74 struct sock *sk; 51 75 struct hlist_node *node, *tmp; 52 76 struct nfc_llcp_sock *llcp_sock; 77 + 78 + skb_queue_purge(&local->tx_queue); 53 79 54 80 write_lock(&local->sockets.lock); 55 81 ··· 83 57 llcp_sock = nfc_llcp_sock(sk); 84 58 85 59 bh_lock_sock(sk); 60 + 61 + nfc_llcp_socket_purge(llcp_sock); 86 62 87 63 if (sk->sk_state == LLCP_CONNECTED) 88 64 nfc_put_device(llcp_sock->dev); ··· 1030 1002 1031 1003 sk = &llcp_sock->sk; 1032 1004 lock_sock(sk); 1005 + 1006 + nfc_llcp_socket_purge(llcp_sock); 1007 + 1033 1008 if (sk->sk_state == LLCP_CLOSED) { 1034 1009 release_sock(sk); 1035 1010 nfc_llcp_sock_put(llcp_sock);