diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2010-12-08 00:21:07 +0200 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2010-12-07 23:03:39 -0200 |
commit | a40c406cbdd28dcca3483065bc2ba794cf5aaab7 (patch) | |
tree | 30c0242aea1c7a5acdaab1e7a4493ff5245e98fa /net/bluetooth/hci_sock.c | |
parent | 0381101fd6a73c7d6b545044dc1472d019fc64e3 (diff) | |
download | linux-stable-a40c406cbdd28dcca3483065bc2ba794cf5aaab7.tar.gz linux-stable-a40c406cbdd28dcca3483065bc2ba794cf5aaab7.tar.bz2 linux-stable-a40c406cbdd28dcca3483065bc2ba794cf5aaab7.zip |
Bluetooth: Make hci_send_to_sock usable for management control sockets
In order to send data to management control sockets the function should:
- skip checks intended for raw HCI data and stack internal events
- make sure RAW HCI data or stack internal events don't go to
management control sockets
In order to accomplish this the patch adds a new member to the bluetooth
skb private data to flag skb's that are destined for management control
sockets.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/hci_sock.c')
-rw-r--r-- | net/bluetooth/hci_sock.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 207be7abda9f..f6c18abab797 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -104,6 +104,12 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) if (skb->sk == sk) continue; + if (bt_cb(skb)->channel != hci_pi(sk)->channel) + continue; + + if (bt_cb(skb)->channel == HCI_CHANNEL_CONTROL) + goto clone; + /* Apply filter */ flt = &hci_pi(sk)->filter; @@ -127,12 +133,14 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) continue; } +clone: nskb = skb_clone(skb, GFP_ATOMIC); if (!nskb) continue; /* Put type byte before the data */ - memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1); + if (bt_cb(skb)->channel == HCI_CHANNEL_RAW) + memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1); if (sock_queue_rcv_skb(sk, nskb)) kfree_skb(nskb); |