aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/bluetooth.h1
-rw-r--r--net/bluetooth/hci_sock.c10
2 files changed, 10 insertions, 1 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index d81ea7997701..0c5e72503b77 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -144,6 +144,7 @@ struct bt_skb_cb {
144 __u8 tx_seq; 144 __u8 tx_seq;
145 __u8 retries; 145 __u8 retries;
146 __u8 sar; 146 __u8 sar;
147 unsigned short channel;
147}; 148};
148#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) 149#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
149 150
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)
104 if (skb->sk == sk) 104 if (skb->sk == sk)
105 continue; 105 continue;
106 106
107 if (bt_cb(skb)->channel != hci_pi(sk)->channel)
108 continue;
109
110 if (bt_cb(skb)->channel == HCI_CHANNEL_CONTROL)
111 goto clone;
112
107 /* Apply filter */ 113 /* Apply filter */
108 flt = &hci_pi(sk)->filter; 114 flt = &hci_pi(sk)->filter;
109 115
@@ -127,12 +133,14 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
127 continue; 133 continue;
128 } 134 }
129 135
136clone:
130 nskb = skb_clone(skb, GFP_ATOMIC); 137 nskb = skb_clone(skb, GFP_ATOMIC);
131 if (!nskb) 138 if (!nskb)
132 continue; 139 continue;
133 140
134 /* Put type byte before the data */ 141 /* Put type byte before the data */
135 memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1); 142 if (bt_cb(skb)->channel == HCI_CHANNEL_RAW)
143 memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1);
136 144
137 if (sock_queue_rcv_skb(sk, nskb)) 145 if (sock_queue_rcv_skb(sk, nskb))
138 kfree_skb(nskb); 146 kfree_skb(nskb);