blob: f2d30d1156c92ed7cb8c05dfbe737f1615ad50a7 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI sockets. */
26
Gustavo Padovan8c520a52012-05-23 04:04:22 -030027#include <linux/export.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <asm/unaligned.h>
29
30#include <net/bluetooth/bluetooth.h>
31#include <net/bluetooth/hci_core.h>
Marcel Holtmanncd82e612012-02-20 20:34:38 +010032#include <net/bluetooth/hci_mon.h>
Johan Hedbergfa4335d2015-03-17 13:48:50 +020033#include <net/bluetooth/mgmt.h>
34
35#include "mgmt_util.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070036
Johan Hedberg801c1e82015-03-06 21:08:50 +020037static LIST_HEAD(mgmt_chan_list);
38static DEFINE_MUTEX(mgmt_chan_list_lock);
39
Marcel Holtmanncd82e612012-02-20 20:34:38 +010040static atomic_t monitor_promisc = ATOMIC_INIT(0);
41
Linus Torvalds1da177e2005-04-16 15:20:36 -070042/* ----- HCI socket interface ----- */
43
Marcel Holtmann863def52014-07-11 05:41:00 +020044/* Socket info */
45#define hci_pi(sk) ((struct hci_pinfo *) sk)
46
47struct hci_pinfo {
48 struct bt_sock bt;
49 struct hci_dev *hdev;
50 struct hci_filter filter;
51 __u32 cmsg_mask;
52 unsigned short channel;
Marcel Holtmann6befc642015-03-14 19:27:53 -070053 unsigned long flags;
Marcel Holtmann863def52014-07-11 05:41:00 +020054};
55
Marcel Holtmann6befc642015-03-14 19:27:53 -070056void hci_sock_set_flag(struct sock *sk, int nr)
57{
58 set_bit(nr, &hci_pi(sk)->flags);
59}
60
61void hci_sock_clear_flag(struct sock *sk, int nr)
62{
63 clear_bit(nr, &hci_pi(sk)->flags);
64}
65
Marcel Holtmannc85be542015-03-14 19:28:00 -070066int hci_sock_test_flag(struct sock *sk, int nr)
67{
68 return test_bit(nr, &hci_pi(sk)->flags);
69}
70
Johan Hedbergd0f172b2015-03-17 13:48:46 +020071unsigned short hci_sock_get_channel(struct sock *sk)
72{
73 return hci_pi(sk)->channel;
74}
75
Jiri Slaby93919762015-02-19 15:20:43 +010076static inline int hci_test_bit(int nr, const void *addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -070077{
Jiri Slaby93919762015-02-19 15:20:43 +010078 return *((const __u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
Linus Torvalds1da177e2005-04-16 15:20:36 -070079}
80
81/* Security filter */
Marcel Holtmann3ad254f2014-07-11 05:36:39 +020082#define HCI_SFLT_MAX_OGF 5
83
84struct hci_sec_filter {
85 __u32 type_mask;
86 __u32 event_mask[2];
87 __u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4];
88};
89
Marcel Holtmann7e67c112014-07-11 05:36:40 +020090static const struct hci_sec_filter hci_sec_filter = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070091 /* Packet types */
92 0x10,
93 /* Events */
Marcel Holtmanndd7f5522005-10-28 19:20:53 +020094 { 0x1000d9fe, 0x0000b00c },
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 /* Commands */
96 {
97 { 0x0 },
98 /* OGF_LINK_CTL */
Marcel Holtmann7c631a62007-09-09 08:39:43 +020099 { 0xbe000006, 0x00000001, 0x00000000, 0x00 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100 /* OGF_LINK_POLICY */
Marcel Holtmann7c631a62007-09-09 08:39:43 +0200101 { 0x00005200, 0x00000000, 0x00000000, 0x00 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 /* OGF_HOST_CTL */
Marcel Holtmann7c631a62007-09-09 08:39:43 +0200103 { 0xaab00200, 0x2b402aaa, 0x05220154, 0x00 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 /* OGF_INFO_PARAM */
Marcel Holtmann7c631a62007-09-09 08:39:43 +0200105 { 0x000002be, 0x00000000, 0x00000000, 0x00 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 /* OGF_STATUS_PARAM */
Marcel Holtmann7c631a62007-09-09 08:39:43 +0200107 { 0x000000ea, 0x00000000, 0x00000000, 0x00 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 }
109};
110
111static struct bt_sock_list hci_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -0700112 .lock = __RW_LOCK_UNLOCKED(hci_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113};
114
Marcel Holtmannf81fe642013-08-25 23:25:15 -0700115static bool is_filtered_packet(struct sock *sk, struct sk_buff *skb)
116{
117 struct hci_filter *flt;
118 int flt_type, flt_event;
119
120 /* Apply filter */
121 flt = &hci_pi(sk)->filter;
122
123 if (bt_cb(skb)->pkt_type == HCI_VENDOR_PKT)
124 flt_type = 0;
125 else
126 flt_type = bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS;
127
128 if (!test_bit(flt_type, &flt->type_mask))
129 return true;
130
131 /* Extra filter for event packets only */
132 if (bt_cb(skb)->pkt_type != HCI_EVENT_PKT)
133 return false;
134
135 flt_event = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
136
137 if (!hci_test_bit(flt_event, &flt->event_mask))
138 return true;
139
140 /* Check filter only when opcode is set */
141 if (!flt->opcode)
142 return false;
143
144 if (flt_event == HCI_EV_CMD_COMPLETE &&
145 flt->opcode != get_unaligned((__le16 *)(skb->data + 3)))
146 return true;
147
148 if (flt_event == HCI_EV_CMD_STATUS &&
149 flt->opcode != get_unaligned((__le16 *)(skb->data + 4)))
150 return true;
151
152 return false;
153}
154
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155/* Send frame to RAW socket */
Marcel Holtmann470fe1b2012-02-20 14:50:30 +0100156void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157{
158 struct sock *sk;
Marcel Holtmanne0edf372012-02-20 14:50:36 +0100159 struct sk_buff *skb_copy = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160
161 BT_DBG("hdev %p len %d", hdev, skb->len);
162
163 read_lock(&hci_sk_list.lock);
Marcel Holtmann470fe1b2012-02-20 14:50:30 +0100164
Sasha Levinb67bfe02013-02-27 17:06:00 -0800165 sk_for_each(sk, &hci_sk_list.head) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 struct sk_buff *nskb;
167
168 if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev)
169 continue;
170
171 /* Don't send frame to the socket it came from */
172 if (skb->sk == sk)
173 continue;
174
Marcel Holtmann23500182013-08-26 21:40:52 -0700175 if (hci_pi(sk)->channel == HCI_CHANNEL_RAW) {
176 if (is_filtered_packet(sk, skb))
177 continue;
178 } else if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
179 if (!bt_cb(skb)->incoming)
180 continue;
181 if (bt_cb(skb)->pkt_type != HCI_EVENT_PKT &&
182 bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT &&
183 bt_cb(skb)->pkt_type != HCI_SCODATA_PKT)
184 continue;
185 } else {
186 /* Don't send frame to other channel types */
Johan Hedberga40c4062010-12-08 00:21:07 +0200187 continue;
Marcel Holtmann23500182013-08-26 21:40:52 -0700188 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189
Marcel Holtmanne0edf372012-02-20 14:50:36 +0100190 if (!skb_copy) {
191 /* Create a private copy with headroom */
Octavian Purdilabad93e92014-06-12 01:36:26 +0300192 skb_copy = __pskb_copy_fclone(skb, 1, GFP_ATOMIC, true);
Marcel Holtmanne0edf372012-02-20 14:50:36 +0100193 if (!skb_copy)
194 continue;
195
196 /* Put type byte before the data */
197 memcpy(skb_push(skb_copy, 1), &bt_cb(skb)->pkt_type, 1);
198 }
199
200 nskb = skb_clone(skb_copy, GFP_ATOMIC);
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200201 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 continue;
203
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204 if (sock_queue_rcv_skb(sk, nskb))
205 kfree_skb(nskb);
206 }
Marcel Holtmann470fe1b2012-02-20 14:50:30 +0100207
208 read_unlock(&hci_sk_list.lock);
Marcel Holtmanne0edf372012-02-20 14:50:36 +0100209
210 kfree_skb(skb_copy);
Marcel Holtmann470fe1b2012-02-20 14:50:30 +0100211}
212
Johan Hedberg71290692015-02-20 13:26:23 +0200213/* Send frame to sockets with specific channel */
214void hci_send_to_channel(unsigned short channel, struct sk_buff *skb,
Marcel Holtmannc08b1a12015-03-14 19:27:59 -0700215 int flag, struct sock *skip_sk)
Marcel Holtmann470fe1b2012-02-20 14:50:30 +0100216{
217 struct sock *sk;
Marcel Holtmann470fe1b2012-02-20 14:50:30 +0100218
Johan Hedberg71290692015-02-20 13:26:23 +0200219 BT_DBG("channel %u len %d", channel, skb->len);
Marcel Holtmann470fe1b2012-02-20 14:50:30 +0100220
221 read_lock(&hci_sk_list.lock);
222
Sasha Levinb67bfe02013-02-27 17:06:00 -0800223 sk_for_each(sk, &hci_sk_list.head) {
Marcel Holtmann470fe1b2012-02-20 14:50:30 +0100224 struct sk_buff *nskb;
225
Marcel Holtmannc08b1a12015-03-14 19:27:59 -0700226 /* Ignore socket without the flag set */
Marcel Holtmannc85be542015-03-14 19:28:00 -0700227 if (!hci_sock_test_flag(sk, flag))
Marcel Holtmannc08b1a12015-03-14 19:27:59 -0700228 continue;
229
Marcel Holtmann470fe1b2012-02-20 14:50:30 +0100230 /* Skip the original socket */
231 if (sk == skip_sk)
232 continue;
233
234 if (sk->sk_state != BT_BOUND)
235 continue;
236
Johan Hedberg71290692015-02-20 13:26:23 +0200237 if (hci_pi(sk)->channel != channel)
Marcel Holtmannd7f72f62015-01-11 19:33:32 -0800238 continue;
239
240 nskb = skb_clone(skb, GFP_ATOMIC);
241 if (!nskb)
242 continue;
243
244 if (sock_queue_rcv_skb(sk, nskb))
245 kfree_skb(nskb);
246 }
247
248 read_unlock(&hci_sk_list.lock);
249}
250
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100251/* Send frame to monitor socket */
252void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
253{
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100254 struct sk_buff *skb_copy = NULL;
Marcel Holtmann2b531292015-01-11 19:33:31 -0800255 struct hci_mon_hdr *hdr;
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100256 __le16 opcode;
257
258 if (!atomic_read(&monitor_promisc))
259 return;
260
261 BT_DBG("hdev %p len %d", hdev, skb->len);
262
263 switch (bt_cb(skb)->pkt_type) {
264 case HCI_COMMAND_PKT:
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700265 opcode = cpu_to_le16(HCI_MON_COMMAND_PKT);
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100266 break;
267 case HCI_EVENT_PKT:
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700268 opcode = cpu_to_le16(HCI_MON_EVENT_PKT);
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100269 break;
270 case HCI_ACLDATA_PKT:
271 if (bt_cb(skb)->incoming)
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700272 opcode = cpu_to_le16(HCI_MON_ACL_RX_PKT);
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100273 else
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700274 opcode = cpu_to_le16(HCI_MON_ACL_TX_PKT);
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100275 break;
276 case HCI_SCODATA_PKT:
277 if (bt_cb(skb)->incoming)
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700278 opcode = cpu_to_le16(HCI_MON_SCO_RX_PKT);
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100279 else
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700280 opcode = cpu_to_le16(HCI_MON_SCO_TX_PKT);
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100281 break;
282 default:
283 return;
284 }
285
Marcel Holtmann2b531292015-01-11 19:33:31 -0800286 /* Create a private copy with headroom */
287 skb_copy = __pskb_copy_fclone(skb, HCI_MON_HDR_SIZE, GFP_ATOMIC, true);
288 if (!skb_copy)
289 return;
290
291 /* Put header before the data */
292 hdr = (void *) skb_push(skb_copy, HCI_MON_HDR_SIZE);
293 hdr->opcode = opcode;
294 hdr->index = cpu_to_le16(hdev->id);
295 hdr->len = cpu_to_le16(skb->len);
296
Marcel Holtmannc08b1a12015-03-14 19:27:59 -0700297 hci_send_to_channel(HCI_CHANNEL_MONITOR, skb_copy,
298 HCI_SOCK_TRUSTED, NULL);
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100299 kfree_skb(skb_copy);
300}
301
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100302static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event)
303{
304 struct hci_mon_hdr *hdr;
305 struct hci_mon_new_index *ni;
306 struct sk_buff *skb;
307 __le16 opcode;
308
309 switch (event) {
310 case HCI_DEV_REG:
311 skb = bt_skb_alloc(HCI_MON_NEW_INDEX_SIZE, GFP_ATOMIC);
312 if (!skb)
313 return NULL;
314
315 ni = (void *) skb_put(skb, HCI_MON_NEW_INDEX_SIZE);
316 ni->type = hdev->dev_type;
317 ni->bus = hdev->bus;
318 bacpy(&ni->bdaddr, &hdev->bdaddr);
319 memcpy(ni->name, hdev->name, 8);
320
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700321 opcode = cpu_to_le16(HCI_MON_NEW_INDEX);
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100322 break;
323
324 case HCI_DEV_UNREG:
325 skb = bt_skb_alloc(0, GFP_ATOMIC);
326 if (!skb)
327 return NULL;
328
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700329 opcode = cpu_to_le16(HCI_MON_DEL_INDEX);
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100330 break;
331
332 default:
333 return NULL;
334 }
335
336 __net_timestamp(skb);
337
338 hdr = (void *) skb_push(skb, HCI_MON_HDR_SIZE);
339 hdr->opcode = opcode;
340 hdr->index = cpu_to_le16(hdev->id);
341 hdr->len = cpu_to_le16(skb->len - HCI_MON_HDR_SIZE);
342
343 return skb;
344}
345
346static void send_monitor_replay(struct sock *sk)
347{
348 struct hci_dev *hdev;
349
350 read_lock(&hci_dev_list_lock);
351
352 list_for_each_entry(hdev, &hci_dev_list, list) {
353 struct sk_buff *skb;
354
355 skb = create_monitor_event(hdev, HCI_DEV_REG);
356 if (!skb)
357 continue;
358
359 if (sock_queue_rcv_skb(sk, skb))
360 kfree_skb(skb);
361 }
362
363 read_unlock(&hci_dev_list_lock);
364}
365
Marcel Holtmann040030e2012-02-20 14:50:37 +0100366/* Generate internal stack event */
367static void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
368{
369 struct hci_event_hdr *hdr;
370 struct hci_ev_stack_internal *ev;
371 struct sk_buff *skb;
372
373 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
374 if (!skb)
375 return;
376
377 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
378 hdr->evt = HCI_EV_STACK_INTERNAL;
379 hdr->plen = sizeof(*ev) + dlen;
380
381 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
382 ev->type = type;
383 memcpy(ev->data, data, dlen);
384
385 bt_cb(skb)->incoming = 1;
386 __net_timestamp(skb);
387
388 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Marcel Holtmann040030e2012-02-20 14:50:37 +0100389 hci_send_to_sock(hdev, skb);
390 kfree_skb(skb);
391}
392
393void hci_sock_dev_event(struct hci_dev *hdev, int event)
394{
395 struct hci_ev_si_device ev;
396
397 BT_DBG("hdev %s event %d", hdev->name, event);
398
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100399 /* Send event to monitor */
400 if (atomic_read(&monitor_promisc)) {
401 struct sk_buff *skb;
402
403 skb = create_monitor_event(hdev, event);
404 if (skb) {
Marcel Holtmannc08b1a12015-03-14 19:27:59 -0700405 hci_send_to_channel(HCI_CHANNEL_MONITOR, skb,
406 HCI_SOCK_TRUSTED, NULL);
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100407 kfree_skb(skb);
408 }
409 }
410
Marcel Holtmann040030e2012-02-20 14:50:37 +0100411 /* Send event to sockets */
412 ev.event = event;
413 ev.dev_id = hdev->id;
414 hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
415
416 if (event == HCI_DEV_UNREG) {
417 struct sock *sk;
Marcel Holtmann040030e2012-02-20 14:50:37 +0100418
419 /* Detach sockets from device */
420 read_lock(&hci_sk_list.lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -0800421 sk_for_each(sk, &hci_sk_list.head) {
Marcel Holtmann040030e2012-02-20 14:50:37 +0100422 bh_lock_sock_nested(sk);
423 if (hci_pi(sk)->hdev == hdev) {
424 hci_pi(sk)->hdev = NULL;
425 sk->sk_err = EPIPE;
426 sk->sk_state = BT_OPEN;
427 sk->sk_state_change(sk);
428
429 hci_dev_put(hdev);
430 }
431 bh_unlock_sock(sk);
432 }
433 read_unlock(&hci_sk_list.lock);
434 }
435}
436
Johan Hedberg801c1e82015-03-06 21:08:50 +0200437static struct hci_mgmt_chan *__hci_mgmt_chan_find(unsigned short channel)
438{
439 struct hci_mgmt_chan *c;
440
441 list_for_each_entry(c, &mgmt_chan_list, list) {
442 if (c->channel == channel)
443 return c;
444 }
445
446 return NULL;
447}
448
449static struct hci_mgmt_chan *hci_mgmt_chan_find(unsigned short channel)
450{
451 struct hci_mgmt_chan *c;
452
453 mutex_lock(&mgmt_chan_list_lock);
454 c = __hci_mgmt_chan_find(channel);
455 mutex_unlock(&mgmt_chan_list_lock);
456
457 return c;
458}
459
460int hci_mgmt_chan_register(struct hci_mgmt_chan *c)
461{
462 if (c->channel < HCI_CHANNEL_CONTROL)
463 return -EINVAL;
464
465 mutex_lock(&mgmt_chan_list_lock);
466 if (__hci_mgmt_chan_find(c->channel)) {
467 mutex_unlock(&mgmt_chan_list_lock);
468 return -EALREADY;
469 }
470
471 list_add_tail(&c->list, &mgmt_chan_list);
472
473 mutex_unlock(&mgmt_chan_list_lock);
474
475 return 0;
476}
477EXPORT_SYMBOL(hci_mgmt_chan_register);
478
479void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c)
480{
481 mutex_lock(&mgmt_chan_list_lock);
482 list_del(&c->list);
483 mutex_unlock(&mgmt_chan_list_lock);
484}
485EXPORT_SYMBOL(hci_mgmt_chan_unregister);
486
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487static int hci_sock_release(struct socket *sock)
488{
489 struct sock *sk = sock->sk;
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100490 struct hci_dev *hdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491
492 BT_DBG("sock %p sk %p", sock, sk);
493
494 if (!sk)
495 return 0;
496
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100497 hdev = hci_pi(sk)->hdev;
498
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100499 if (hci_pi(sk)->channel == HCI_CHANNEL_MONITOR)
500 atomic_dec(&monitor_promisc);
501
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502 bt_sock_unlink(&hci_sk_list, sk);
503
504 if (hdev) {
Marcel Holtmann23500182013-08-26 21:40:52 -0700505 if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
Marcel Holtmann23500182013-08-26 21:40:52 -0700506 hci_dev_close(hdev->id);
Loic Poulain9380f9e2015-05-21 16:46:41 +0200507 hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
508 mgmt_index_added(hdev);
Marcel Holtmann23500182013-08-26 21:40:52 -0700509 }
510
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 atomic_dec(&hdev->promisc);
512 hci_dev_put(hdev);
513 }
514
515 sock_orphan(sk);
516
517 skb_queue_purge(&sk->sk_receive_queue);
518 skb_queue_purge(&sk->sk_write_queue);
519
520 sock_put(sk);
521 return 0;
522}
523
Antti Julkub2a66aa2011-06-15 12:01:14 +0300524static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg)
Johan Hedbergf0358562010-05-18 13:20:32 +0200525{
526 bdaddr_t bdaddr;
Antti Julku5e762442011-08-25 16:48:02 +0300527 int err;
Johan Hedbergf0358562010-05-18 13:20:32 +0200528
529 if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
530 return -EFAULT;
531
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300532 hci_dev_lock(hdev);
Antti Julku5e762442011-08-25 16:48:02 +0300533
Johan Hedbergdcc36c12014-07-09 12:59:13 +0300534 err = hci_bdaddr_list_add(&hdev->blacklist, &bdaddr, BDADDR_BREDR);
Antti Julku5e762442011-08-25 16:48:02 +0300535
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300536 hci_dev_unlock(hdev);
Antti Julku5e762442011-08-25 16:48:02 +0300537
538 return err;
Johan Hedbergf0358562010-05-18 13:20:32 +0200539}
540
Antti Julkub2a66aa2011-06-15 12:01:14 +0300541static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg)
Johan Hedbergf0358562010-05-18 13:20:32 +0200542{
543 bdaddr_t bdaddr;
Antti Julku5e762442011-08-25 16:48:02 +0300544 int err;
Johan Hedbergf0358562010-05-18 13:20:32 +0200545
546 if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
547 return -EFAULT;
548
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300549 hci_dev_lock(hdev);
Antti Julku5e762442011-08-25 16:48:02 +0300550
Johan Hedbergdcc36c12014-07-09 12:59:13 +0300551 err = hci_bdaddr_list_del(&hdev->blacklist, &bdaddr, BDADDR_BREDR);
Antti Julku5e762442011-08-25 16:48:02 +0300552
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300553 hci_dev_unlock(hdev);
Antti Julku5e762442011-08-25 16:48:02 +0300554
555 return err;
Johan Hedbergf0358562010-05-18 13:20:32 +0200556}
557
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900558/* Ioctls that require bound socket */
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300559static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
560 unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561{
562 struct hci_dev *hdev = hci_pi(sk)->hdev;
563
564 if (!hdev)
565 return -EBADFD;
566
Marcel Holtmannd7a5a112015-03-13 02:11:00 -0700567 if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
Marcel Holtmann0736cfa2013-08-26 21:40:51 -0700568 return -EBUSY;
569
Marcel Holtmannd7a5a112015-03-13 02:11:00 -0700570 if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
Marcel Holtmannfee746b2014-06-29 12:13:05 +0200571 return -EOPNOTSUPP;
572
Marcel Holtmann5b69bef52013-10-10 10:02:08 -0700573 if (hdev->dev_type != HCI_BREDR)
574 return -EOPNOTSUPP;
575
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 switch (cmd) {
577 case HCISETRAW:
578 if (!capable(CAP_NET_ADMIN))
Zhao Hongjiangbf5b30b2012-09-20 22:37:25 +0000579 return -EPERM;
Marcel Holtmanndb596682014-04-16 20:04:38 -0700580 return -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 case HCIGETCONNINFO:
Marcel Holtmann40be4922008-07-14 20:13:50 +0200583 return hci_get_conn_info(hdev, (void __user *) arg);
584
585 case HCIGETAUTHINFO:
586 return hci_get_auth_info(hdev, (void __user *) arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587
Johan Hedbergf0358562010-05-18 13:20:32 +0200588 case HCIBLOCKADDR:
589 if (!capable(CAP_NET_ADMIN))
Zhao Hongjiangbf5b30b2012-09-20 22:37:25 +0000590 return -EPERM;
Antti Julkub2a66aa2011-06-15 12:01:14 +0300591 return hci_sock_blacklist_add(hdev, (void __user *) arg);
Johan Hedbergf0358562010-05-18 13:20:32 +0200592
593 case HCIUNBLOCKADDR:
594 if (!capable(CAP_NET_ADMIN))
Zhao Hongjiangbf5b30b2012-09-20 22:37:25 +0000595 return -EPERM;
Antti Julkub2a66aa2011-06-15 12:01:14 +0300596 return hci_sock_blacklist_del(hdev, (void __user *) arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 }
Marcel Holtmann0736cfa2013-08-26 21:40:51 -0700598
Marcel Holtmann324d36e2013-10-10 10:50:06 -0700599 return -ENOIOCTLCMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600}
601
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300602static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
603 unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604{
Marcel Holtmann40be4922008-07-14 20:13:50 +0200605 void __user *argp = (void __user *) arg;
Marcel Holtmann0736cfa2013-08-26 21:40:51 -0700606 struct sock *sk = sock->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 int err;
608
609 BT_DBG("cmd %x arg %lx", cmd, arg);
610
Marcel Holtmannc1c4f952013-08-26 09:39:55 -0700611 lock_sock(sk);
612
613 if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
614 err = -EBADFD;
615 goto done;
616 }
617
618 release_sock(sk);
619
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 switch (cmd) {
621 case HCIGETDEVLIST:
622 return hci_get_dev_list(argp);
623
624 case HCIGETDEVINFO:
625 return hci_get_dev_info(argp);
626
627 case HCIGETCONNLIST:
628 return hci_get_conn_list(argp);
629
630 case HCIDEVUP:
631 if (!capable(CAP_NET_ADMIN))
Zhao Hongjiangbf5b30b2012-09-20 22:37:25 +0000632 return -EPERM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 return hci_dev_open(arg);
634
635 case HCIDEVDOWN:
636 if (!capable(CAP_NET_ADMIN))
Zhao Hongjiangbf5b30b2012-09-20 22:37:25 +0000637 return -EPERM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638 return hci_dev_close(arg);
639
640 case HCIDEVRESET:
641 if (!capable(CAP_NET_ADMIN))
Zhao Hongjiangbf5b30b2012-09-20 22:37:25 +0000642 return -EPERM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643 return hci_dev_reset(arg);
644
645 case HCIDEVRESTAT:
646 if (!capable(CAP_NET_ADMIN))
Zhao Hongjiangbf5b30b2012-09-20 22:37:25 +0000647 return -EPERM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648 return hci_dev_reset_stat(arg);
649
650 case HCISETSCAN:
651 case HCISETAUTH:
652 case HCISETENCRYPT:
653 case HCISETPTYPE:
654 case HCISETLINKPOL:
655 case HCISETLINKMODE:
656 case HCISETACLMTU:
657 case HCISETSCOMTU:
658 if (!capable(CAP_NET_ADMIN))
Zhao Hongjiangbf5b30b2012-09-20 22:37:25 +0000659 return -EPERM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 return hci_dev_cmd(cmd, argp);
661
662 case HCIINQUIRY:
663 return hci_inquiry(argp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 }
Marcel Holtmannc1c4f952013-08-26 09:39:55 -0700665
666 lock_sock(sk);
667
668 err = hci_sock_bound_ioctl(sk, cmd, arg);
669
670done:
671 release_sock(sk);
672 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673}
674
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300675static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
676 int addr_len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677{
Johan Hedberg03811012010-12-08 00:21:06 +0200678 struct sockaddr_hci haddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 struct sock *sk = sock->sk;
680 struct hci_dev *hdev = NULL;
Johan Hedberg03811012010-12-08 00:21:06 +0200681 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682
683 BT_DBG("sock %p sk %p", sock, sk);
684
Johan Hedberg03811012010-12-08 00:21:06 +0200685 if (!addr)
686 return -EINVAL;
687
688 memset(&haddr, 0, sizeof(haddr));
689 len = min_t(unsigned int, sizeof(haddr), addr_len);
690 memcpy(&haddr, addr, len);
691
692 if (haddr.hci_family != AF_BLUETOOTH)
693 return -EINVAL;
694
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695 lock_sock(sk);
696
Marcel Holtmann7cc2ade2012-02-20 14:50:35 +0100697 if (sk->sk_state == BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698 err = -EALREADY;
699 goto done;
700 }
701
Marcel Holtmann7cc2ade2012-02-20 14:50:35 +0100702 switch (haddr.hci_channel) {
703 case HCI_CHANNEL_RAW:
704 if (hci_pi(sk)->hdev) {
705 err = -EALREADY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706 goto done;
707 }
708
Marcel Holtmann7cc2ade2012-02-20 14:50:35 +0100709 if (haddr.hci_dev != HCI_DEV_NONE) {
710 hdev = hci_dev_get(haddr.hci_dev);
711 if (!hdev) {
712 err = -ENODEV;
713 goto done;
714 }
715
716 atomic_inc(&hdev->promisc);
717 }
718
719 hci_pi(sk)->hdev = hdev;
720 break;
721
Marcel Holtmann23500182013-08-26 21:40:52 -0700722 case HCI_CHANNEL_USER:
723 if (hci_pi(sk)->hdev) {
724 err = -EALREADY;
725 goto done;
726 }
727
728 if (haddr.hci_dev == HCI_DEV_NONE) {
729 err = -EINVAL;
730 goto done;
731 }
732
Marcel Holtmann10a8b862013-10-01 22:59:24 -0700733 if (!capable(CAP_NET_ADMIN)) {
Marcel Holtmann23500182013-08-26 21:40:52 -0700734 err = -EPERM;
735 goto done;
736 }
737
738 hdev = hci_dev_get(haddr.hci_dev);
739 if (!hdev) {
740 err = -ENODEV;
741 goto done;
742 }
743
Marcel Holtmann781f8992015-06-06 06:06:49 +0200744 if (test_bit(HCI_INIT, &hdev->flags) ||
Marcel Holtmannd7a5a112015-03-13 02:11:00 -0700745 hci_dev_test_flag(hdev, HCI_SETUP) ||
Marcel Holtmann781f8992015-06-06 06:06:49 +0200746 hci_dev_test_flag(hdev, HCI_CONFIG) ||
747 (!hci_dev_test_flag(hdev, HCI_AUTO_OFF) &&
748 test_bit(HCI_UP, &hdev->flags))) {
Marcel Holtmann23500182013-08-26 21:40:52 -0700749 err = -EBUSY;
750 hci_dev_put(hdev);
751 goto done;
752 }
753
Marcel Holtmann238be782015-03-13 02:11:06 -0700754 if (hci_dev_test_and_set_flag(hdev, HCI_USER_CHANNEL)) {
Marcel Holtmann23500182013-08-26 21:40:52 -0700755 err = -EUSERS;
756 hci_dev_put(hdev);
757 goto done;
758 }
759
Marcel Holtmann0602a8a2014-07-02 21:30:54 +0200760 mgmt_index_removed(hdev);
Marcel Holtmann23500182013-08-26 21:40:52 -0700761
762 err = hci_dev_open(hdev->id);
763 if (err) {
Marcel Holtmann781f8992015-06-06 06:06:49 +0200764 if (err == -EALREADY) {
765 /* In case the transport is already up and
766 * running, clear the error here.
767 *
768 * This can happen when opening an user
769 * channel and HCI_AUTO_OFF grace period
770 * is still active.
771 */
772 err = 0;
773 } else {
774 hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
775 mgmt_index_added(hdev);
776 hci_dev_put(hdev);
777 goto done;
778 }
Marcel Holtmann23500182013-08-26 21:40:52 -0700779 }
780
781 atomic_inc(&hdev->promisc);
782
783 hci_pi(sk)->hdev = hdev;
784 break;
785
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100786 case HCI_CHANNEL_MONITOR:
787 if (haddr.hci_dev != HCI_DEV_NONE) {
788 err = -EINVAL;
789 goto done;
790 }
791
792 if (!capable(CAP_NET_RAW)) {
793 err = -EPERM;
794 goto done;
795 }
796
Marcel Holtmann50ebc052015-03-14 19:27:58 -0700797 /* The monitor interface is restricted to CAP_NET_RAW
798 * capabilities and with that implicitly trusted.
799 */
800 hci_sock_set_flag(sk, HCI_SOCK_TRUSTED);
801
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100802 send_monitor_replay(sk);
803
804 atomic_inc(&monitor_promisc);
805 break;
806
Marcel Holtmann7cc2ade2012-02-20 14:50:35 +0100807 default:
Johan Hedberg801c1e82015-03-06 21:08:50 +0200808 if (!hci_mgmt_chan_find(haddr.hci_channel)) {
809 err = -EINVAL;
810 goto done;
811 }
812
813 if (haddr.hci_dev != HCI_DEV_NONE) {
814 err = -EINVAL;
815 goto done;
816 }
817
Marcel Holtmann1195fbb2015-03-14 19:28:04 -0700818 /* Users with CAP_NET_ADMIN capabilities are allowed
819 * access to all management commands and events. For
820 * untrusted users the interface is restricted and
821 * also only untrusted events are sent.
Marcel Holtmann50ebc052015-03-14 19:27:58 -0700822 */
Marcel Holtmann1195fbb2015-03-14 19:28:04 -0700823 if (capable(CAP_NET_ADMIN))
824 hci_sock_set_flag(sk, HCI_SOCK_TRUSTED);
Marcel Holtmann50ebc052015-03-14 19:27:58 -0700825
Marcel Holtmannf9207332015-03-14 19:27:55 -0700826 /* At the moment the index and unconfigured index events
827 * are enabled unconditionally. Setting them on each
828 * socket when binding keeps this functionality. They
829 * however might be cleared later and then sending of these
830 * events will be disabled, but that is then intentional.
Marcel Holtmannf6b77122015-03-14 19:28:05 -0700831 *
832 * This also enables generic events that are safe to be
833 * received by untrusted users. Example for such events
834 * are changes to settings, class of device, name etc.
Marcel Holtmannf9207332015-03-14 19:27:55 -0700835 */
836 if (haddr.hci_channel == HCI_CHANNEL_CONTROL) {
837 hci_sock_set_flag(sk, HCI_MGMT_INDEX_EVENTS);
838 hci_sock_set_flag(sk, HCI_MGMT_UNCONF_INDEX_EVENTS);
Marcel Holtmannf6b77122015-03-14 19:28:05 -0700839 hci_sock_set_flag(sk, HCI_MGMT_GENERIC_EVENTS);
Marcel Holtmannf9207332015-03-14 19:27:55 -0700840 }
Johan Hedberg801c1e82015-03-06 21:08:50 +0200841 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842 }
843
Marcel Holtmann7cc2ade2012-02-20 14:50:35 +0100844
Johan Hedberg03811012010-12-08 00:21:06 +0200845 hci_pi(sk)->channel = haddr.hci_channel;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 sk->sk_state = BT_BOUND;
847
848done:
849 release_sock(sk);
850 return err;
851}
852
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300853static int hci_sock_getname(struct socket *sock, struct sockaddr *addr,
854 int *addr_len, int peer)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855{
856 struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
857 struct sock *sk = sock->sk;
Marcel Holtmann9d4b68b2013-08-26 00:20:37 -0700858 struct hci_dev *hdev;
859 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860
861 BT_DBG("sock %p sk %p", sock, sk);
862
Marcel Holtmann06f43cb2013-08-26 00:06:30 -0700863 if (peer)
864 return -EOPNOTSUPP;
865
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 lock_sock(sk);
867
Marcel Holtmann9d4b68b2013-08-26 00:20:37 -0700868 hdev = hci_pi(sk)->hdev;
869 if (!hdev) {
870 err = -EBADFD;
871 goto done;
872 }
873
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 *addr_len = sizeof(*haddr);
875 haddr->hci_family = AF_BLUETOOTH;
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100876 haddr->hci_dev = hdev->id;
Marcel Holtmann9d4b68b2013-08-26 00:20:37 -0700877 haddr->hci_channel= hci_pi(sk)->channel;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878
Marcel Holtmann9d4b68b2013-08-26 00:20:37 -0700879done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880 release_sock(sk);
Marcel Holtmann9d4b68b2013-08-26 00:20:37 -0700881 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882}
883
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300884static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg,
885 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886{
887 __u32 mask = hci_pi(sk)->cmsg_mask;
888
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700889 if (mask & HCI_CMSG_DIR) {
890 int incoming = bt_cb(skb)->incoming;
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300891 put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(incoming),
892 &incoming);
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700893 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700895 if (mask & HCI_CMSG_TSTAMP) {
Johann Felix Sodenf6e623a2010-02-15 22:23:48 +0100896#ifdef CONFIG_COMPAT
897 struct compat_timeval ctv;
898#endif
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700899 struct timeval tv;
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200900 void *data;
901 int len;
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700902
903 skb_get_timestamp(skb, &tv);
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200904
David S. Miller1da97f82007-09-12 14:10:58 +0200905 data = &tv;
906 len = sizeof(tv);
907#ifdef CONFIG_COMPAT
H. J. Luda88cea2012-02-10 14:12:15 -0800908 if (!COMPAT_USE_64BIT_TIME &&
909 (msg->msg_flags & MSG_CMSG_COMPAT)) {
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200910 ctv.tv_sec = tv.tv_sec;
911 ctv.tv_usec = tv.tv_usec;
912 data = &ctv;
913 len = sizeof(ctv);
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200914 }
David S. Miller1da97f82007-09-12 14:10:58 +0200915#endif
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200916
917 put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, len, data);
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700918 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919}
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900920
Ying Xue1b784142015-03-02 15:37:48 +0800921static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
922 int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923{
924 int noblock = flags & MSG_DONTWAIT;
925 struct sock *sk = sock->sk;
926 struct sk_buff *skb;
927 int copied, err;
928
929 BT_DBG("sock %p, sk %p", sock, sk);
930
931 if (flags & (MSG_OOB))
932 return -EOPNOTSUPP;
933
934 if (sk->sk_state == BT_CLOSED)
935 return 0;
936
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200937 skb = skb_recv_datagram(sk, flags, noblock, &err);
938 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939 return err;
940
Linus Torvalds1da177e2005-04-16 15:20:36 -0700941 copied = skb->len;
942 if (len < copied) {
943 msg->msg_flags |= MSG_TRUNC;
944 copied = len;
945 }
946
Arnaldo Carvalho de Melobadff6d2007-03-13 13:06:52 -0300947 skb_reset_transport_header(skb);
David S. Miller51f3d022014-11-05 16:46:40 -0500948 err = skb_copy_datagram_msg(skb, 0, msg, copied);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949
Marcel Holtmann3a208622012-02-20 14:50:34 +0100950 switch (hci_pi(sk)->channel) {
951 case HCI_CHANNEL_RAW:
952 hci_sock_cmsg(sk, msg, skb);
953 break;
Marcel Holtmann23500182013-08-26 21:40:52 -0700954 case HCI_CHANNEL_USER:
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100955 case HCI_CHANNEL_MONITOR:
956 sock_recv_timestamp(msg, sk, skb);
957 break;
Johan Hedberg801c1e82015-03-06 21:08:50 +0200958 default:
959 if (hci_mgmt_chan_find(hci_pi(sk)->channel))
960 sock_recv_timestamp(msg, sk, skb);
961 break;
Marcel Holtmann3a208622012-02-20 14:50:34 +0100962 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963
964 skb_free_datagram(sk, skb);
965
966 return err ? : copied;
967}
968
Johan Hedbergfa4335d2015-03-17 13:48:50 +0200969static int hci_mgmt_cmd(struct hci_mgmt_chan *chan, struct sock *sk,
970 struct msghdr *msg, size_t msglen)
971{
972 void *buf;
973 u8 *cp;
974 struct mgmt_hdr *hdr;
975 u16 opcode, index, len;
976 struct hci_dev *hdev = NULL;
977 const struct hci_mgmt_handler *handler;
978 bool var_len, no_hdev;
979 int err;
980
981 BT_DBG("got %zu bytes", msglen);
982
983 if (msglen < sizeof(*hdr))
984 return -EINVAL;
985
986 buf = kmalloc(msglen, GFP_KERNEL);
987 if (!buf)
988 return -ENOMEM;
989
990 if (memcpy_from_msg(buf, msg, msglen)) {
991 err = -EFAULT;
992 goto done;
993 }
994
995 hdr = buf;
996 opcode = __le16_to_cpu(hdr->opcode);
997 index = __le16_to_cpu(hdr->index);
998 len = __le16_to_cpu(hdr->len);
999
1000 if (len != msglen - sizeof(*hdr)) {
1001 err = -EINVAL;
1002 goto done;
1003 }
1004
1005 if (opcode >= chan->handler_count ||
1006 chan->handlers[opcode].func == NULL) {
1007 BT_DBG("Unknown op %u", opcode);
1008 err = mgmt_cmd_status(sk, index, opcode,
1009 MGMT_STATUS_UNKNOWN_COMMAND);
1010 goto done;
1011 }
1012
1013 handler = &chan->handlers[opcode];
1014
1015 if (!hci_sock_test_flag(sk, HCI_SOCK_TRUSTED) &&
1016 !(handler->flags & HCI_MGMT_UNTRUSTED)) {
1017 err = mgmt_cmd_status(sk, index, opcode,
1018 MGMT_STATUS_PERMISSION_DENIED);
1019 goto done;
1020 }
1021
1022 if (index != MGMT_INDEX_NONE) {
1023 hdev = hci_dev_get(index);
1024 if (!hdev) {
1025 err = mgmt_cmd_status(sk, index, opcode,
1026 MGMT_STATUS_INVALID_INDEX);
1027 goto done;
1028 }
1029
1030 if (hci_dev_test_flag(hdev, HCI_SETUP) ||
1031 hci_dev_test_flag(hdev, HCI_CONFIG) ||
1032 hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
1033 err = mgmt_cmd_status(sk, index, opcode,
1034 MGMT_STATUS_INVALID_INDEX);
1035 goto done;
1036 }
1037
1038 if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1039 !(handler->flags & HCI_MGMT_UNCONFIGURED)) {
1040 err = mgmt_cmd_status(sk, index, opcode,
1041 MGMT_STATUS_INVALID_INDEX);
1042 goto done;
1043 }
1044 }
1045
1046 no_hdev = (handler->flags & HCI_MGMT_NO_HDEV);
1047 if (no_hdev != !hdev) {
1048 err = mgmt_cmd_status(sk, index, opcode,
1049 MGMT_STATUS_INVALID_INDEX);
1050 goto done;
1051 }
1052
1053 var_len = (handler->flags & HCI_MGMT_VAR_LEN);
1054 if ((var_len && len < handler->data_len) ||
1055 (!var_len && len != handler->data_len)) {
1056 err = mgmt_cmd_status(sk, index, opcode,
1057 MGMT_STATUS_INVALID_PARAMS);
1058 goto done;
1059 }
1060
1061 if (hdev && chan->hdev_init)
1062 chan->hdev_init(sk, hdev);
1063
1064 cp = buf + sizeof(*hdr);
1065
1066 err = handler->func(sk, hdev, cp, len);
1067 if (err < 0)
1068 goto done;
1069
1070 err = msglen;
1071
1072done:
1073 if (hdev)
1074 hci_dev_put(hdev);
1075
1076 kfree(buf);
1077 return err;
1078}
1079
Ying Xue1b784142015-03-02 15:37:48 +08001080static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
1081 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082{
1083 struct sock *sk = sock->sk;
Johan Hedberg801c1e82015-03-06 21:08:50 +02001084 struct hci_mgmt_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 struct hci_dev *hdev;
1086 struct sk_buff *skb;
1087 int err;
1088
1089 BT_DBG("sock %p sk %p", sock, sk);
1090
1091 if (msg->msg_flags & MSG_OOB)
1092 return -EOPNOTSUPP;
1093
1094 if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
1095 return -EINVAL;
1096
1097 if (len < 4 || len > HCI_MAX_FRAME_SIZE)
1098 return -EINVAL;
1099
1100 lock_sock(sk);
1101
Johan Hedberg03811012010-12-08 00:21:06 +02001102 switch (hci_pi(sk)->channel) {
1103 case HCI_CHANNEL_RAW:
Marcel Holtmann23500182013-08-26 21:40:52 -07001104 case HCI_CHANNEL_USER:
Johan Hedberg03811012010-12-08 00:21:06 +02001105 break;
Marcel Holtmanncd82e612012-02-20 20:34:38 +01001106 case HCI_CHANNEL_MONITOR:
1107 err = -EOPNOTSUPP;
1108 goto done;
Johan Hedberg03811012010-12-08 00:21:06 +02001109 default:
Johan Hedberg801c1e82015-03-06 21:08:50 +02001110 mutex_lock(&mgmt_chan_list_lock);
1111 chan = __hci_mgmt_chan_find(hci_pi(sk)->channel);
1112 if (chan)
Johan Hedbergfa4335d2015-03-17 13:48:50 +02001113 err = hci_mgmt_cmd(chan, sk, msg, len);
Johan Hedberg801c1e82015-03-06 21:08:50 +02001114 else
1115 err = -EINVAL;
1116
1117 mutex_unlock(&mgmt_chan_list_lock);
Johan Hedberg03811012010-12-08 00:21:06 +02001118 goto done;
1119 }
1120
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001121 hdev = hci_pi(sk)->hdev;
1122 if (!hdev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123 err = -EBADFD;
1124 goto done;
1125 }
1126
Marcel Holtmann7e21add2009-11-18 01:05:00 +01001127 if (!test_bit(HCI_UP, &hdev->flags)) {
1128 err = -ENETDOWN;
1129 goto done;
1130 }
1131
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001132 skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
1133 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 goto done;
1135
Al Viro6ce8e9c2014-04-06 21:25:44 -04001136 if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137 err = -EFAULT;
1138 goto drop;
1139 }
1140
Marcel Holtmann0d48d932005-08-09 20:30:28 -07001141 bt_cb(skb)->pkt_type = *((unsigned char *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142 skb_pull(skb, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143
Marcel Holtmann1bc5ad12013-12-17 03:21:25 -08001144 if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
1145 /* No permission check is needed for user channel
1146 * since that gets enforced when binding the socket.
1147 *
1148 * However check that the packet type is valid.
1149 */
1150 if (bt_cb(skb)->pkt_type != HCI_COMMAND_PKT &&
1151 bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT &&
1152 bt_cb(skb)->pkt_type != HCI_SCODATA_PKT) {
1153 err = -EINVAL;
1154 goto drop;
1155 }
1156
1157 skb_queue_tail(&hdev->raw_q, skb);
1158 queue_work(hdev->workqueue, &hdev->tx_work);
1159 } else if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
Harvey Harrison83985312008-05-02 16:25:46 -07001160 u16 opcode = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 u16 ogf = hci_opcode_ogf(opcode);
1162 u16 ocf = hci_opcode_ocf(opcode);
1163
1164 if (((ogf > HCI_SFLT_MAX_OGF) ||
Gustavo Padovan3bb3c752012-05-17 00:36:22 -03001165 !hci_test_bit(ocf & HCI_FLT_OCF_BITS,
1166 &hci_sec_filter.ocf_mask[ogf])) &&
1167 !capable(CAP_NET_RAW)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168 err = -EPERM;
1169 goto drop;
1170 }
1171
Marcel Holtmannfee746b2014-06-29 12:13:05 +02001172 if (ogf == 0x3f) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173 skb_queue_tail(&hdev->raw_q, skb);
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02001174 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175 } else {
Stephen Hemminger49c922b2014-10-27 21:12:20 -07001176 /* Stand-alone HCI commands must be flagged as
Johan Hedberg11714b32013-03-05 20:37:47 +02001177 * single-command requests.
1178 */
Johan Hedbergdb6e3e82015-03-30 23:21:02 +03001179 bt_cb(skb)->req.start = true;
Johan Hedberg11714b32013-03-05 20:37:47 +02001180
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 skb_queue_tail(&hdev->cmd_q, skb);
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02001182 queue_work(hdev->workqueue, &hdev->cmd_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183 }
1184 } else {
1185 if (!capable(CAP_NET_RAW)) {
1186 err = -EPERM;
1187 goto drop;
1188 }
1189
1190 skb_queue_tail(&hdev->raw_q, skb);
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02001191 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192 }
1193
1194 err = len;
1195
1196done:
1197 release_sock(sk);
1198 return err;
1199
1200drop:
1201 kfree_skb(skb);
1202 goto done;
1203}
1204
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001205static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
1206 char __user *optval, unsigned int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207{
1208 struct hci_ufilter uf = { .opcode = 0 };
1209 struct sock *sk = sock->sk;
1210 int err = 0, opt = 0;
1211
1212 BT_DBG("sk %p, opt %d", sk, optname);
1213
1214 lock_sock(sk);
1215
Marcel Holtmann2f39cdb2012-02-20 14:50:32 +01001216 if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
Marcel Holtmannc2371e82013-08-26 09:29:39 -07001217 err = -EBADFD;
Marcel Holtmann2f39cdb2012-02-20 14:50:32 +01001218 goto done;
1219 }
1220
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 switch (optname) {
1222 case HCI_DATA_DIR:
1223 if (get_user(opt, (int __user *)optval)) {
1224 err = -EFAULT;
1225 break;
1226 }
1227
1228 if (opt)
1229 hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
1230 else
1231 hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
1232 break;
1233
1234 case HCI_TIME_STAMP:
1235 if (get_user(opt, (int __user *)optval)) {
1236 err = -EFAULT;
1237 break;
1238 }
1239
1240 if (opt)
1241 hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
1242 else
1243 hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
1244 break;
1245
1246 case HCI_FILTER:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001247 {
1248 struct hci_filter *f = &hci_pi(sk)->filter;
1249
1250 uf.type_mask = f->type_mask;
1251 uf.opcode = f->opcode;
1252 uf.event_mask[0] = *((u32 *) f->event_mask + 0);
1253 uf.event_mask[1] = *((u32 *) f->event_mask + 1);
1254 }
1255
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256 len = min_t(unsigned int, len, sizeof(uf));
1257 if (copy_from_user(&uf, optval, len)) {
1258 err = -EFAULT;
1259 break;
1260 }
1261
1262 if (!capable(CAP_NET_RAW)) {
1263 uf.type_mask &= hci_sec_filter.type_mask;
1264 uf.event_mask[0] &= *((u32 *) hci_sec_filter.event_mask + 0);
1265 uf.event_mask[1] &= *((u32 *) hci_sec_filter.event_mask + 1);
1266 }
1267
1268 {
1269 struct hci_filter *f = &hci_pi(sk)->filter;
1270
1271 f->type_mask = uf.type_mask;
1272 f->opcode = uf.opcode;
1273 *((u32 *) f->event_mask + 0) = uf.event_mask[0];
1274 *((u32 *) f->event_mask + 1) = uf.event_mask[1];
1275 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001276 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277
1278 default:
1279 err = -ENOPROTOOPT;
1280 break;
1281 }
1282
Marcel Holtmann2f39cdb2012-02-20 14:50:32 +01001283done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 release_sock(sk);
1285 return err;
1286}
1287
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001288static int hci_sock_getsockopt(struct socket *sock, int level, int optname,
1289 char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290{
1291 struct hci_ufilter uf;
1292 struct sock *sk = sock->sk;
Marcel Holtmanncedc5462012-02-20 14:50:33 +01001293 int len, opt, err = 0;
1294
1295 BT_DBG("sk %p, opt %d", sk, optname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296
1297 if (get_user(len, optlen))
1298 return -EFAULT;
1299
Marcel Holtmanncedc5462012-02-20 14:50:33 +01001300 lock_sock(sk);
1301
1302 if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
Marcel Holtmannc2371e82013-08-26 09:29:39 -07001303 err = -EBADFD;
Marcel Holtmanncedc5462012-02-20 14:50:33 +01001304 goto done;
1305 }
1306
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307 switch (optname) {
1308 case HCI_DATA_DIR:
1309 if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
1310 opt = 1;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001311 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312 opt = 0;
1313
1314 if (put_user(opt, optval))
Marcel Holtmanncedc5462012-02-20 14:50:33 +01001315 err = -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 break;
1317
1318 case HCI_TIME_STAMP:
1319 if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
1320 opt = 1;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001321 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322 opt = 0;
1323
1324 if (put_user(opt, optval))
Marcel Holtmanncedc5462012-02-20 14:50:33 +01001325 err = -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326 break;
1327
1328 case HCI_FILTER:
1329 {
1330 struct hci_filter *f = &hci_pi(sk)->filter;
1331
Mathias Krausee15ca9a2012-08-15 11:31:46 +00001332 memset(&uf, 0, sizeof(uf));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333 uf.type_mask = f->type_mask;
1334 uf.opcode = f->opcode;
1335 uf.event_mask[0] = *((u32 *) f->event_mask + 0);
1336 uf.event_mask[1] = *((u32 *) f->event_mask + 1);
1337 }
1338
1339 len = min_t(unsigned int, len, sizeof(uf));
1340 if (copy_to_user(optval, &uf, len))
Marcel Holtmanncedc5462012-02-20 14:50:33 +01001341 err = -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342 break;
1343
1344 default:
Marcel Holtmanncedc5462012-02-20 14:50:33 +01001345 err = -ENOPROTOOPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346 break;
1347 }
1348
Marcel Holtmanncedc5462012-02-20 14:50:33 +01001349done:
1350 release_sock(sk);
1351 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352}
1353
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08001354static const struct proto_ops hci_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355 .family = PF_BLUETOOTH,
1356 .owner = THIS_MODULE,
1357 .release = hci_sock_release,
1358 .bind = hci_sock_bind,
1359 .getname = hci_sock_getname,
1360 .sendmsg = hci_sock_sendmsg,
1361 .recvmsg = hci_sock_recvmsg,
1362 .ioctl = hci_sock_ioctl,
1363 .poll = datagram_poll,
1364 .listen = sock_no_listen,
1365 .shutdown = sock_no_shutdown,
1366 .setsockopt = hci_sock_setsockopt,
1367 .getsockopt = hci_sock_getsockopt,
1368 .connect = sock_no_connect,
1369 .socketpair = sock_no_socketpair,
1370 .accept = sock_no_accept,
1371 .mmap = sock_no_mmap
1372};
1373
1374static struct proto hci_sk_proto = {
1375 .name = "HCI",
1376 .owner = THIS_MODULE,
1377 .obj_size = sizeof(struct hci_pinfo)
1378};
1379
Eric Paris3f378b62009-11-05 22:18:14 -08001380static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
1381 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382{
1383 struct sock *sk;
1384
1385 BT_DBG("sock %p", sock);
1386
1387 if (sock->type != SOCK_RAW)
1388 return -ESOCKTNOSUPPORT;
1389
1390 sock->ops = &hci_sock_ops;
1391
Eric W. Biederman11aa9c22015-05-08 21:09:13 -05001392 sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, kern);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 if (!sk)
1394 return -ENOMEM;
1395
1396 sock_init_data(sock, sk);
1397
1398 sock_reset_flag(sk, SOCK_ZAPPED);
1399
1400 sk->sk_protocol = protocol;
1401
1402 sock->state = SS_UNCONNECTED;
1403 sk->sk_state = BT_OPEN;
1404
1405 bt_sock_link(&hci_sk_list, sk);
1406 return 0;
1407}
1408
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00001409static const struct net_proto_family hci_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410 .family = PF_BLUETOOTH,
1411 .owner = THIS_MODULE,
1412 .create = hci_sock_create,
1413};
1414
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415int __init hci_sock_init(void)
1416{
1417 int err;
1418
Marcel Holtmannb0a8e282015-01-11 15:18:17 -08001419 BUILD_BUG_ON(sizeof(struct sockaddr_hci) > sizeof(struct sockaddr));
1420
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421 err = proto_register(&hci_sk_proto, 0);
1422 if (err < 0)
1423 return err;
1424
1425 err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
Masatake YAMATOf7c86632012-07-26 01:28:36 +09001426 if (err < 0) {
1427 BT_ERR("HCI socket registration failed");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428 goto error;
Masatake YAMATOf7c86632012-07-26 01:28:36 +09001429 }
1430
Al Virob0316612013-04-04 19:14:33 -04001431 err = bt_procfs_init(&init_net, "hci", &hci_sk_list, NULL);
Masatake YAMATOf7c86632012-07-26 01:28:36 +09001432 if (err < 0) {
1433 BT_ERR("Failed to create HCI proc file");
1434 bt_sock_unregister(BTPROTO_HCI);
1435 goto error;
1436 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438 BT_INFO("HCI socket layer initialized");
1439
1440 return 0;
1441
1442error:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 proto_unregister(&hci_sk_proto);
1444 return err;
1445}
1446
Anand Gadiyarb7440a142011-02-22 12:43:09 +05301447void hci_sock_cleanup(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448{
Masatake YAMATOf7c86632012-07-26 01:28:36 +09001449 bt_procfs_cleanup(&init_net, "hci");
David Herrmann5e9d7f82013-02-24 19:36:51 +01001450 bt_sock_unregister(BTPROTO_HCI);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451 proto_unregister(&hci_sk_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452}