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 d81ea79..0c5e725 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 207be7a..f6c18ab 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);