Bluetooth: Make hci_send_to_sock usable for management control sockets
authorJohan Hedberg <johan.hedberg@nokia.com>
Tue, 7 Dec 2010 22:21:07 +0000 (00:21 +0200)
committerGustavo F. Padovan <padovan@profusion.mobi>
Wed, 8 Dec 2010 01:03:39 +0000 (23:03 -0200)
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>
include/net/bluetooth/bluetooth.h
net/bluetooth/hci_sock.c

index d81ea799770196be373d3304c25a7837097479a0..0c5e72503b775282bda667771c54ca8c3a448e6c 100644 (file)
@@ -144,6 +144,7 @@ struct bt_skb_cb {
        __u8 tx_seq;
        __u8 retries;
        __u8 sar;
+       unsigned short channel;
 };
 #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
 
index 207be7abda9fb283bb18711169be5b73c81c5e2e..f6c18abab797872daf9ba688216e254236116e63 100644 (file)
@@ -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);