blob: 5e0976670b9e8cf91a99656ebe6b7bfa04b0dad9 [file] [log] [blame]
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001/*
2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
5 Copyright (C) 2010 Google Inc.
Gustavo F. Padovan590051d2011-12-18 13:39:33 -02006 Copyright (C) 2011 ProFUSION Embedded Systems
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007
8 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License version 2 as
12 published by the Free Software Foundation;
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
17 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
18 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
24 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
25 SOFTWARE IS DISCLAIMED.
26*/
27
28/* Bluetooth L2CAP sockets. */
29
Paul Moore6230c9b2011-10-07 09:40:59 +000030#include <linux/security.h>
31
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020032#include <net/bluetooth/bluetooth.h>
Gustavo F. Padovan33575df2011-02-04 02:48:48 -020033#include <net/bluetooth/hci_core.h>
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020034#include <net/bluetooth/l2cap.h>
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -030035#include <net/bluetooth/smp.h>
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020036
Gustavo F. Padovancf2f90f2011-04-27 18:40:39 -030037static const struct proto_ops l2cap_sock_ops;
Gustavo F. Padovan80808e42011-05-16 17:24:37 -030038static void l2cap_sock_init(struct sock *sk, struct sock *parent);
39static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio);
Gustavo F. Padovancf2f90f2011-04-27 18:40:39 -030040
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -020041static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
42{
43 struct sock *sk = sock->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -030044 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -020045 struct sockaddr_l2 la;
46 int len, err = 0;
47
48 BT_DBG("sk %p", sk);
49
50 if (!addr || addr->sa_family != AF_BLUETOOTH)
51 return -EINVAL;
52
53 memset(&la, 0, sizeof(la));
54 len = min_t(unsigned int, sizeof(la), alen);
55 memcpy(&la, addr, len);
56
Ville Tervob62f3282011-02-10 22:38:50 -030057 if (la.l2_cid && la.l2_psm)
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -020058 return -EINVAL;
59
60 lock_sock(sk);
61
62 if (sk->sk_state != BT_OPEN) {
63 err = -EBADFD;
64 goto done;
65 }
66
67 if (la.l2_psm) {
68 __u16 psm = __le16_to_cpu(la.l2_psm);
69
70 /* PSM must be odd and lsb of upper byte must be 0 */
71 if ((psm & 0x0101) != 0x0001) {
72 err = -EINVAL;
73 goto done;
74 }
75
76 /* Restrict usage of well-known PSMs */
77 if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) {
78 err = -EACCES;
79 goto done;
80 }
81 }
82
Ville Tervob62f3282011-02-10 22:38:50 -030083 if (la.l2_cid)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -030084 err = l2cap_add_scid(chan, la.l2_cid);
85 else
86 err = l2cap_add_psm(chan, &la.l2_bdaddr, la.l2_psm);
Ville Tervob62f3282011-02-10 22:38:50 -030087
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -030088 if (err < 0)
89 goto done;
90
91 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
92 __le16_to_cpu(la.l2_psm) == 0x0003)
93 chan->sec_level = BT_SECURITY_SDP;
94
95 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -030096
97 chan->state = BT_BOUND;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -030098 sk->sk_state = BT_BOUND;
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -020099
100done:
101 release_sock(sk);
102 return err;
103}
104
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200105static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
106{
107 struct sock *sk = sock->sk;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300108 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200109 struct sockaddr_l2 la;
110 int len, err = 0;
111
112 BT_DBG("sk %p", sk);
113
114 if (!addr || alen < sizeof(addr->sa_family) ||
115 addr->sa_family != AF_BLUETOOTH)
116 return -EINVAL;
117
118 memset(&la, 0, sizeof(la));
119 len = min_t(unsigned int, sizeof(la), alen);
120 memcpy(&la, addr, len);
121
Ville Tervoacd7d372011-02-10 22:38:49 -0300122 if (la.l2_cid && la.l2_psm)
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200123 return -EINVAL;
124
Gustavo F. Padovan03a00192011-12-09 04:48:17 -0200125 err = l2cap_chan_connect(chan, la.l2_psm, la.l2_cid, &la.l2_bdaddr);
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200126 if (err)
127 goto done;
128
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200129 err = bt_sock_wait_state(sk, BT_CONNECTED,
130 sock_sndtimeo(sk, flags & O_NONBLOCK));
131done:
Gustavo F. Padovan03a00192011-12-09 04:48:17 -0200132 if (sock_owned_by_user(sk))
133 release_sock(sk);
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200134 return err;
135}
136
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200137static int l2cap_sock_listen(struct socket *sock, int backlog)
138{
139 struct sock *sk = sock->sk;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300140 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200141 int err = 0;
142
143 BT_DBG("sk %p backlog %d", sk, backlog);
144
145 lock_sock(sk);
146
147 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
148 || sk->sk_state != BT_BOUND) {
149 err = -EBADFD;
150 goto done;
151 }
152
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300153 switch (chan->mode) {
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200154 case L2CAP_MODE_BASIC:
155 break;
156 case L2CAP_MODE_ERTM:
157 case L2CAP_MODE_STREAMING:
158 if (!disable_ertm)
159 break;
160 /* fall through */
161 default:
162 err = -ENOTSUPP;
163 goto done;
164 }
165
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200166 sk->sk_max_ack_backlog = backlog;
167 sk->sk_ack_backlog = 0;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300168
169 chan->state = BT_LISTEN;
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200170 sk->sk_state = BT_LISTEN;
171
172done:
173 release_sock(sk);
174 return err;
175}
176
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200177static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
178{
179 DECLARE_WAITQUEUE(wait, current);
180 struct sock *sk = sock->sk, *nsk;
181 long timeo;
182 int err = 0;
183
184 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
185
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200186 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
187
188 BT_DBG("sk %p timeo %ld", sk, timeo);
189
190 /* Wait for an incoming connection. (wake-one). */
191 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Peter Hurleyf9a3c202011-07-24 00:10:52 -0400192 while (1) {
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200193 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200194
195 if (sk->sk_state != BT_LISTEN) {
196 err = -EBADFD;
197 break;
198 }
199
Peter Hurleyf9a3c202011-07-24 00:10:52 -0400200 nsk = bt_accept_dequeue(sk, newsock);
201 if (nsk)
202 break;
203
204 if (!timeo) {
205 err = -EAGAIN;
206 break;
207 }
208
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200209 if (signal_pending(current)) {
210 err = sock_intr_errno(timeo);
211 break;
212 }
Peter Hurleyf9a3c202011-07-24 00:10:52 -0400213
214 release_sock(sk);
215 timeo = schedule_timeout(timeo);
216 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200217 }
Peter Hurleyf9a3c202011-07-24 00:10:52 -0400218 __set_current_state(TASK_RUNNING);
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200219 remove_wait_queue(sk_sleep(sk), &wait);
220
221 if (err)
222 goto done;
223
224 newsock->state = SS_CONNECTED;
225
226 BT_DBG("new socket %p", nsk);
227
228done:
229 release_sock(sk);
230 return err;
231}
232
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200233static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
234{
235 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
236 struct sock *sk = sock->sk;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300237 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200238
239 BT_DBG("sock %p, sk %p", sock, sk);
240
241 addr->sa_family = AF_BLUETOOTH;
242 *len = sizeof(struct sockaddr_l2);
243
244 if (peer) {
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300245 la->l2_psm = chan->psm;
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200246 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300247 la->l2_cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200248 } else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300249 la->l2_psm = chan->sport;
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200250 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300251 la->l2_cid = cpu_to_le16(chan->scid);
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200252 }
253
254 return 0;
255}
256
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200257static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
258{
259 struct sock *sk = sock->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300260 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200261 struct l2cap_options opts;
262 struct l2cap_conninfo cinfo;
263 int len, err = 0;
264 u32 opt;
265
266 BT_DBG("sk %p", sk);
267
268 if (get_user(len, optlen))
269 return -EFAULT;
270
271 lock_sock(sk);
272
273 switch (optname) {
274 case L2CAP_OPTIONS:
Vasiliy Kulikove3fb5922011-02-10 20:59:42 +0300275 memset(&opts, 0, sizeof(opts));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300276 opts.imtu = chan->imtu;
277 opts.omtu = chan->omtu;
278 opts.flush_to = chan->flush_to;
279 opts.mode = chan->mode;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300280 opts.fcs = chan->fcs;
281 opts.max_tx = chan->max_tx;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +0300282 opts.txwin_size = chan->tx_win;
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200283
284 len = min_t(unsigned int, len, sizeof(opts));
285 if (copy_to_user(optval, (char *) &opts, len))
286 err = -EFAULT;
287
288 break;
289
290 case L2CAP_LM:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300291 switch (chan->sec_level) {
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200292 case BT_SECURITY_LOW:
293 opt = L2CAP_LM_AUTH;
294 break;
295 case BT_SECURITY_MEDIUM:
296 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
297 break;
298 case BT_SECURITY_HIGH:
299 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
300 L2CAP_LM_SECURE;
301 break;
302 default:
303 opt = 0;
304 break;
305 }
306
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +0300307 if (test_bit(FLAG_ROLE_SWITCH, &chan->flags))
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200308 opt |= L2CAP_LM_MASTER;
309
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +0300310 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200311 opt |= L2CAP_LM_RELIABLE;
312
313 if (put_user(opt, (u32 __user *) optval))
314 err = -EFAULT;
315 break;
316
317 case L2CAP_CONNINFO:
318 if (sk->sk_state != BT_CONNECTED &&
319 !(sk->sk_state == BT_CONNECT2 &&
320 bt_sk(sk)->defer_setup)) {
321 err = -ENOTCONN;
322 break;
323 }
324
Filip Palian8d03e972011-05-12 19:32:46 +0200325 memset(&cinfo, 0, sizeof(cinfo));
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300326 cinfo.hci_handle = chan->conn->hcon->handle;
327 memcpy(cinfo.dev_class, chan->conn->hcon->dev_class, 3);
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200328
329 len = min_t(unsigned int, len, sizeof(cinfo));
330 if (copy_to_user(optval, (char *) &cinfo, len))
331 err = -EFAULT;
332
333 break;
334
335 default:
336 err = -ENOPROTOOPT;
337 break;
338 }
339
340 release_sock(sk);
341 return err;
342}
343
344static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
345{
346 struct sock *sk = sock->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300347 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200348 struct bt_security sec;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700349 struct bt_power pwr;
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200350 int len, err = 0;
351
352 BT_DBG("sk %p", sk);
353
354 if (level == SOL_L2CAP)
355 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
356
357 if (level != SOL_BLUETOOTH)
358 return -ENOPROTOOPT;
359
360 if (get_user(len, optlen))
361 return -EFAULT;
362
363 lock_sock(sk);
364
365 switch (optname) {
366 case BT_SECURITY:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300367 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
368 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200369 err = -EINVAL;
370 break;
371 }
372
Vinicius Costa Gomes8f360112011-07-08 18:31:46 -0300373 memset(&sec, 0, sizeof(sec));
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300374 sec.level = chan->sec_level;
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200375
Vinicius Costa Gomes8f360112011-07-08 18:31:46 -0300376 if (sk->sk_state == BT_CONNECTED)
377 sec.key_size = chan->conn->hcon->enc_key_size;
378
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200379 len = min_t(unsigned int, len, sizeof(sec));
380 if (copy_to_user(optval, (char *) &sec, len))
381 err = -EFAULT;
382
383 break;
384
385 case BT_DEFER_SETUP:
386 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
387 err = -EINVAL;
388 break;
389 }
390
391 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
392 err = -EFAULT;
393
394 break;
395
396 case BT_FLUSHABLE:
Andrei Emeltchenkod57b0e82011-10-11 14:04:31 +0300397 if (put_user(test_bit(FLAG_FLUSHABLE, &chan->flags),
398 (u32 __user *) optval))
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200399 err = -EFAULT;
400
401 break;
402
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700403 case BT_POWER:
404 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
405 && sk->sk_type != SOCK_RAW) {
406 err = -EINVAL;
407 break;
408 }
409
Andrei Emeltchenko15770b12011-10-11 14:04:33 +0300410 pwr.force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700411
412 len = min_t(unsigned int, len, sizeof(pwr));
413 if (copy_to_user(optval, (char *) &pwr, len))
414 err = -EFAULT;
415
416 break;
417
Mat Martineau2ea66482011-11-02 16:18:30 -0700418 case BT_CHANNEL_POLICY:
419 if (!enable_hs) {
420 err = -ENOPROTOOPT;
421 break;
422 }
423
424 if (put_user(chan->chan_policy, (u32 __user *) optval))
425 err = -EFAULT;
426 break;
427
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200428 default:
429 err = -ENOPROTOOPT;
430 break;
431 }
432
433 release_sock(sk);
434 return err;
435}
436
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200437static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
438{
439 struct sock *sk = sock->sk;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300440 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200441 struct l2cap_options opts;
442 int len, err = 0;
443 u32 opt;
444
445 BT_DBG("sk %p", sk);
446
447 lock_sock(sk);
448
449 switch (optname) {
450 case L2CAP_OPTIONS:
451 if (sk->sk_state == BT_CONNECTED) {
452 err = -EINVAL;
453 break;
454 }
455
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300456 opts.imtu = chan->imtu;
457 opts.omtu = chan->omtu;
458 opts.flush_to = chan->flush_to;
459 opts.mode = chan->mode;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300460 opts.fcs = chan->fcs;
461 opts.max_tx = chan->max_tx;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +0300462 opts.txwin_size = chan->tx_win;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200463
464 len = min_t(unsigned int, sizeof(opts), optlen);
465 if (copy_from_user((char *) &opts, optval, len)) {
466 err = -EFAULT;
467 break;
468 }
469
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +0300470 if (opts.txwin_size > L2CAP_DEFAULT_EXT_WINDOW) {
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200471 err = -EINVAL;
472 break;
473 }
474
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300475 chan->mode = opts.mode;
476 switch (chan->mode) {
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200477 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300478 clear_bit(CONF_STATE2_DEVICE, &chan->conf_state);
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200479 break;
480 case L2CAP_MODE_ERTM:
481 case L2CAP_MODE_STREAMING:
482 if (!disable_ertm)
483 break;
484 /* fall through */
485 default:
486 err = -EINVAL;
487 break;
488 }
489
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300490 chan->imtu = opts.imtu;
491 chan->omtu = opts.omtu;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300492 chan->fcs = opts.fcs;
493 chan->max_tx = opts.max_tx;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +0300494 chan->tx_win = opts.txwin_size;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200495 break;
496
497 case L2CAP_LM:
498 if (get_user(opt, (u32 __user *) optval)) {
499 err = -EFAULT;
500 break;
501 }
502
503 if (opt & L2CAP_LM_AUTH)
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300504 chan->sec_level = BT_SECURITY_LOW;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200505 if (opt & L2CAP_LM_ENCRYPT)
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300506 chan->sec_level = BT_SECURITY_MEDIUM;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200507 if (opt & L2CAP_LM_SECURE)
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300508 chan->sec_level = BT_SECURITY_HIGH;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200509
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +0300510 if (opt & L2CAP_LM_MASTER)
511 set_bit(FLAG_ROLE_SWITCH, &chan->flags);
512 else
513 clear_bit(FLAG_ROLE_SWITCH, &chan->flags);
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +0300514
515 if (opt & L2CAP_LM_RELIABLE)
516 set_bit(FLAG_FORCE_RELIABLE, &chan->flags);
517 else
518 clear_bit(FLAG_FORCE_RELIABLE, &chan->flags);
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200519 break;
520
521 default:
522 err = -ENOPROTOOPT;
523 break;
524 }
525
526 release_sock(sk);
527 return err;
528}
529
530static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
531{
532 struct sock *sk = sock->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300533 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200534 struct bt_security sec;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700535 struct bt_power pwr;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300536 struct l2cap_conn *conn;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200537 int len, err = 0;
538 u32 opt;
539
540 BT_DBG("sk %p", sk);
541
542 if (level == SOL_L2CAP)
543 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
544
545 if (level != SOL_BLUETOOTH)
546 return -ENOPROTOOPT;
547
548 lock_sock(sk);
549
550 switch (optname) {
551 case BT_SECURITY:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300552 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
553 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200554 err = -EINVAL;
555 break;
556 }
557
558 sec.level = BT_SECURITY_LOW;
559
560 len = min_t(unsigned int, sizeof(sec), optlen);
561 if (copy_from_user((char *) &sec, optval, len)) {
562 err = -EFAULT;
563 break;
564 }
565
566 if (sec.level < BT_SECURITY_LOW ||
567 sec.level > BT_SECURITY_HIGH) {
568 err = -EINVAL;
569 break;
570 }
571
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300572 chan->sec_level = sec.level;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300573
Gustavo F. Padovan0bee1d62011-11-05 19:58:31 -0200574 if (!chan->conn)
575 break;
576
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300577 conn = chan->conn;
Gustavo F. Padovan0bee1d62011-11-05 19:58:31 -0200578
579 /*change security for LE channels */
580 if (chan->scid == L2CAP_CID_LE_DATA) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300581 if (!conn->hcon->out) {
582 err = -EINVAL;
583 break;
584 }
585
586 if (smp_conn_security(conn, sec.level))
587 break;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300588 sk->sk_state = BT_CONFIG;
Gustavo F. Padovan0bee1d62011-11-05 19:58:31 -0200589
590 /* or for ACL link, under defer_setup time */
591 } else if (sk->sk_state == BT_CONNECT2 &&
592 bt_sk(sk)->defer_setup) {
593 err = l2cap_chan_check_security(chan);
594 } else {
595 err = -EINVAL;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300596 }
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200597 break;
598
599 case BT_DEFER_SETUP:
600 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
601 err = -EINVAL;
602 break;
603 }
604
605 if (get_user(opt, (u32 __user *) optval)) {
606 err = -EFAULT;
607 break;
608 }
609
610 bt_sk(sk)->defer_setup = opt;
611 break;
612
613 case BT_FLUSHABLE:
614 if (get_user(opt, (u32 __user *) optval)) {
615 err = -EFAULT;
616 break;
617 }
618
619 if (opt > BT_FLUSHABLE_ON) {
620 err = -EINVAL;
621 break;
622 }
623
624 if (opt == BT_FLUSHABLE_OFF) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300625 struct l2cap_conn *conn = chan->conn;
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300626 /* proceed further only when we have l2cap_conn and
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200627 No Flush support in the LM */
628 if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) {
629 err = -EINVAL;
630 break;
631 }
632 }
633
Andrei Emeltchenkod57b0e82011-10-11 14:04:31 +0300634 if (opt)
635 set_bit(FLAG_FLUSHABLE, &chan->flags);
636 else
637 clear_bit(FLAG_FLUSHABLE, &chan->flags);
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200638 break;
639
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700640 case BT_POWER:
641 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
642 chan->chan_type != L2CAP_CHAN_RAW) {
643 err = -EINVAL;
644 break;
645 }
646
647 pwr.force_active = BT_POWER_FORCE_ACTIVE_ON;
648
649 len = min_t(unsigned int, sizeof(pwr), optlen);
650 if (copy_from_user((char *) &pwr, optval, len)) {
651 err = -EFAULT;
652 break;
653 }
Andrei Emeltchenko15770b12011-10-11 14:04:33 +0300654
655 if (pwr.force_active)
656 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
657 else
658 clear_bit(FLAG_FORCE_ACTIVE, &chan->flags);
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700659 break;
660
Mat Martineau2ea66482011-11-02 16:18:30 -0700661 case BT_CHANNEL_POLICY:
662 if (!enable_hs) {
663 err = -ENOPROTOOPT;
664 break;
665 }
666
667 if (get_user(opt, (u32 __user *) optval)) {
668 err = -EFAULT;
669 break;
670 }
671
672 if (opt > BT_CHANNEL_POLICY_AMP_PREFERRED) {
673 err = -EINVAL;
674 break;
675 }
676
677 if (chan->mode != L2CAP_MODE_ERTM &&
678 chan->mode != L2CAP_MODE_STREAMING) {
679 err = -EOPNOTSUPP;
680 break;
681 }
682
683 chan->chan_policy = (u8) opt;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200684 break;
685
686 default:
687 err = -ENOPROTOOPT;
688 break;
689 }
690
691 release_sock(sk);
692 return err;
693}
694
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200695static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
696{
697 struct sock *sk = sock->sk;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300698 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200699 int err;
700
701 BT_DBG("sock %p, sk %p", sock, sk);
702
703 err = sock_error(sk);
704 if (err)
705 return err;
706
707 if (msg->msg_flags & MSG_OOB)
708 return -EOPNOTSUPP;
709
710 lock_sock(sk);
711
712 if (sk->sk_state != BT_CONNECTED) {
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -0300713 release_sock(sk);
714 return -ENOTCONN;
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200715 }
716
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200717 err = l2cap_chan_send(chan, msg, len, sk->sk_priority);
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200718
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200719 release_sock(sk);
720 return err;
721}
722
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200723static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
724{
725 struct sock *sk = sock->sk;
Mat Martineaue3281402011-07-07 09:39:02 -0700726 struct l2cap_pinfo *pi = l2cap_pi(sk);
727 int err;
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200728
729 lock_sock(sk);
730
731 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300732 sk->sk_state = BT_CONFIG;
733
Mat Martineaue3281402011-07-07 09:39:02 -0700734 __l2cap_connect_rsp_defer(pi->chan);
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200735 release_sock(sk);
736 return 0;
737 }
738
739 release_sock(sk);
740
741 if (sock->type == SOCK_STREAM)
Mat Martineaue3281402011-07-07 09:39:02 -0700742 err = bt_sock_stream_recvmsg(iocb, sock, msg, len, flags);
743 else
744 err = bt_sock_recvmsg(iocb, sock, msg, len, flags);
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200745
Mat Martineaue3281402011-07-07 09:39:02 -0700746 if (pi->chan->mode != L2CAP_MODE_ERTM)
747 return err;
748
749 /* Attempt to put pending rx data in the socket buffer */
750
751 lock_sock(sk);
752
753 if (!test_bit(CONN_LOCAL_BUSY, &pi->chan->conn_state))
754 goto done;
755
756 if (pi->rx_busy_skb) {
757 if (!sock_queue_rcv_skb(sk, pi->rx_busy_skb))
758 pi->rx_busy_skb = NULL;
759 else
760 goto done;
761 }
762
763 /* Restore data flow when half of the receive buffer is
764 * available. This avoids resending large numbers of
765 * frames.
766 */
767 if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf >> 1)
768 l2cap_chan_busy(pi->chan, 0);
769
770done:
771 release_sock(sk);
772 return err;
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200773}
774
Gustavo F. Padovan05fc1572011-02-04 03:26:01 -0200775/* Kill socket (only if zapped and orphan)
776 * Must be called on unlocked socket.
777 */
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300778static void l2cap_sock_kill(struct sock *sk)
Gustavo F. Padovan05fc1572011-02-04 03:26:01 -0200779{
780 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
781 return;
782
783 BT_DBG("sk %p state %d", sk, sk->sk_state);
784
785 /* Kill poor orphan */
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300786
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300787 l2cap_chan_destroy(l2cap_pi(sk)->chan);
Gustavo F. Padovan05fc1572011-02-04 03:26:01 -0200788 sock_set_flag(sk, SOCK_DEAD);
789 sock_put(sk);
790}
791
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200792static int l2cap_sock_shutdown(struct socket *sock, int how)
793{
794 struct sock *sk = sock->sk;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300795 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200796 int err = 0;
797
798 BT_DBG("sock %p, sk %p", sock, sk);
799
800 if (!sk)
801 return 0;
802
803 lock_sock(sk);
804 if (!sk->sk_shutdown) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300805 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200806 err = __l2cap_wait_ack(sk);
807
808 sk->sk_shutdown = SHUTDOWN_MASK;
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300809 l2cap_chan_close(chan, 0);
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200810
811 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
812 err = bt_sock_wait_state(sk, BT_CLOSED,
813 sk->sk_lingertime);
814 }
815
816 if (!err && sk->sk_err)
817 err = -sk->sk_err;
818
819 release_sock(sk);
820 return err;
821}
822
Gustavo F. Padovan554f05b2011-02-04 02:36:42 -0200823static int l2cap_sock_release(struct socket *sock)
824{
825 struct sock *sk = sock->sk;
826 int err;
827
828 BT_DBG("sock %p, sk %p", sock, sk);
829
830 if (!sk)
831 return 0;
832
833 err = l2cap_sock_shutdown(sock, 2);
834
835 sock_orphan(sk);
836 l2cap_sock_kill(sk);
837 return err;
838}
839
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300840static struct l2cap_chan *l2cap_sock_new_connection_cb(void *data)
841{
842 struct sock *sk, *parent = data;
843
844 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP,
845 GFP_ATOMIC);
846 if (!sk)
847 return NULL;
848
849 l2cap_sock_init(sk, parent);
850
851 return l2cap_pi(sk)->chan;
852}
853
Gustavo F. Padovan23070492011-05-16 17:57:22 -0300854static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb)
855{
Mat Martineaue3281402011-07-07 09:39:02 -0700856 int err;
Gustavo F. Padovan23070492011-05-16 17:57:22 -0300857 struct sock *sk = data;
Mat Martineaue3281402011-07-07 09:39:02 -0700858 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan23070492011-05-16 17:57:22 -0300859
Mat Martineaue3281402011-07-07 09:39:02 -0700860 if (pi->rx_busy_skb)
861 return -ENOMEM;
862
863 err = sock_queue_rcv_skb(sk, skb);
864
865 /* For ERTM, handle one skb that doesn't fit into the recv
866 * buffer. This is important to do because the data frames
867 * have already been acked, so the skb cannot be discarded.
868 *
869 * Notify the l2cap core that the buffer is full, so the
870 * LOCAL_BUSY state is entered and no more frames are
871 * acked and reassembled until there is buffer space
872 * available.
873 */
874 if (err < 0 && pi->chan->mode == L2CAP_MODE_ERTM) {
875 pi->rx_busy_skb = skb;
876 l2cap_chan_busy(pi->chan, 1);
877 err = 0;
878 }
879
880 return err;
Gustavo F. Padovan23070492011-05-16 17:57:22 -0300881}
882
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300883static void l2cap_sock_close_cb(void *data)
884{
885 struct sock *sk = data;
886
887 l2cap_sock_kill(sk);
888}
889
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300890static void l2cap_sock_state_change_cb(void *data, int state)
891{
892 struct sock *sk = data;
893
894 sk->sk_state = state;
895}
896
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300897static struct l2cap_ops l2cap_chan_ops = {
898 .name = "L2CAP Socket Interface",
899 .new_connection = l2cap_sock_new_connection_cb,
Gustavo F. Padovan23070492011-05-16 17:57:22 -0300900 .recv = l2cap_sock_recv_cb,
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300901 .close = l2cap_sock_close_cb,
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300902 .state_change = l2cap_sock_state_change_cb,
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300903};
904
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200905static void l2cap_sock_destruct(struct sock *sk)
906{
907 BT_DBG("sk %p", sk);
908
Mat Martineaue3281402011-07-07 09:39:02 -0700909 if (l2cap_pi(sk)->rx_busy_skb) {
910 kfree_skb(l2cap_pi(sk)->rx_busy_skb);
911 l2cap_pi(sk)->rx_busy_skb = NULL;
912 }
913
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200914 skb_queue_purge(&sk->sk_receive_queue);
915 skb_queue_purge(&sk->sk_write_queue);
916}
917
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300918static void l2cap_sock_init(struct sock *sk, struct sock *parent)
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200919{
920 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300921 struct l2cap_chan *chan = pi->chan;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200922
923 BT_DBG("sk %p", sk);
924
925 if (parent) {
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300926 struct l2cap_chan *pchan = l2cap_pi(parent)->chan;
927
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200928 sk->sk_type = parent->sk_type;
929 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
930
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300931 chan->chan_type = pchan->chan_type;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300932 chan->imtu = pchan->imtu;
933 chan->omtu = pchan->omtu;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300934 chan->conf_state = pchan->conf_state;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300935 chan->mode = pchan->mode;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300936 chan->fcs = pchan->fcs;
937 chan->max_tx = pchan->max_tx;
938 chan->tx_win = pchan->tx_win;
Andrei Emeltchenko6b3c7102011-11-02 09:57:10 +0200939 chan->tx_win_max = pchan->tx_win_max;
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300940 chan->sec_level = pchan->sec_level;
Andrei Emeltchenkod57b0e82011-10-11 14:04:31 +0300941 chan->flags = pchan->flags;
Paul Moore6230c9b2011-10-07 09:40:59 +0000942
943 security_sk_clone(parent, sk);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200944 } else {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300945
946 switch (sk->sk_type) {
947 case SOCK_RAW:
948 chan->chan_type = L2CAP_CHAN_RAW;
949 break;
950 case SOCK_DGRAM:
951 chan->chan_type = L2CAP_CHAN_CONN_LESS;
952 break;
953 case SOCK_SEQPACKET:
954 case SOCK_STREAM:
955 chan->chan_type = L2CAP_CHAN_CONN_ORIENTED;
956 break;
957 }
958
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300959 chan->imtu = L2CAP_DEFAULT_MTU;
960 chan->omtu = 0;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200961 if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300962 chan->mode = L2CAP_MODE_ERTM;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300963 set_bit(CONF_STATE2_DEVICE, &chan->conf_state);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200964 } else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300965 chan->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200966 }
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300967 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
968 chan->fcs = L2CAP_FCS_CRC16;
969 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenko6b3c7102011-11-02 09:57:10 +0200970 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300971 chan->sec_level = BT_SECURITY_LOW;
Andrei Emeltchenkod57b0e82011-10-11 14:04:31 +0300972 chan->flags = 0;
Andrei Emeltchenko15770b12011-10-11 14:04:33 +0300973 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200974 }
975
976 /* Default config options */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300977 chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300978
979 chan->data = sk;
980 chan->ops = &l2cap_chan_ops;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200981}
982
983static struct proto l2cap_proto = {
984 .name = "L2CAP",
985 .owner = THIS_MODULE,
986 .obj_size = sizeof(struct l2cap_pinfo)
987};
988
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300989static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200990{
991 struct sock *sk;
Gustavo F. Padovandc50a062011-05-16 16:42:01 -0300992 struct l2cap_chan *chan;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200993
994 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
995 if (!sk)
996 return NULL;
997
998 sock_init_data(sock, sk);
999 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
1000
1001 sk->sk_destruct = l2cap_sock_destruct;
Chen Ganir6be6b112011-07-28 15:42:09 +03001002 sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001003
1004 sock_reset_flag(sk, SOCK_ZAPPED);
1005
1006 sk->sk_protocol = proto;
1007 sk->sk_state = BT_OPEN;
1008
Gustavo F. Padovandc50a062011-05-16 16:42:01 -03001009 chan = l2cap_chan_create(sk);
1010 if (!chan) {
1011 l2cap_sock_kill(sk);
1012 return NULL;
1013 }
1014
1015 l2cap_pi(sk)->chan = chan;
1016
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001017 return sk;
1018}
1019
1020static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
1021 int kern)
1022{
1023 struct sock *sk;
1024
1025 BT_DBG("sock %p", sock);
1026
1027 sock->state = SS_UNCONNECTED;
1028
1029 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
1030 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
1031 return -ESOCKTNOSUPPORT;
1032
1033 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
1034 return -EPERM;
1035
1036 sock->ops = &l2cap_sock_ops;
1037
1038 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
1039 if (!sk)
1040 return -ENOMEM;
1041
1042 l2cap_sock_init(sk, NULL);
1043 return 0;
1044}
1045
Gustavo F. Padovancf2f90f2011-04-27 18:40:39 -03001046static const struct proto_ops l2cap_sock_ops = {
Gustavo F. Padovan65390582011-02-04 02:33:56 -02001047 .family = PF_BLUETOOTH,
1048 .owner = THIS_MODULE,
1049 .release = l2cap_sock_release,
1050 .bind = l2cap_sock_bind,
1051 .connect = l2cap_sock_connect,
1052 .listen = l2cap_sock_listen,
1053 .accept = l2cap_sock_accept,
1054 .getname = l2cap_sock_getname,
1055 .sendmsg = l2cap_sock_sendmsg,
1056 .recvmsg = l2cap_sock_recvmsg,
1057 .poll = bt_sock_poll,
1058 .ioctl = bt_sock_ioctl,
1059 .mmap = sock_no_mmap,
1060 .socketpair = sock_no_socketpair,
1061 .shutdown = l2cap_sock_shutdown,
1062 .setsockopt = l2cap_sock_setsockopt,
1063 .getsockopt = l2cap_sock_getsockopt
1064};
1065
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001066static const struct net_proto_family l2cap_sock_family_ops = {
1067 .family = PF_BLUETOOTH,
1068 .owner = THIS_MODULE,
1069 .create = l2cap_sock_create,
1070};
1071
1072int __init l2cap_init_sockets(void)
1073{
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001074 int err;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001075
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001076 err = proto_register(&l2cap_proto, 0);
1077 if (err < 0)
1078 return err;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001079
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001080 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
1081 if (err < 0)
1082 goto error;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001083
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001084 BT_INFO("L2CAP socket layer initialized");
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001085
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001086 return 0;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001087
1088error:
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001089 BT_ERR("L2CAP socket registration failed");
1090 proto_unregister(&l2cap_proto);
1091 return err;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001092}
1093
1094void l2cap_cleanup_sockets(void)
1095{
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001096 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
1097 BT_ERR("L2CAP socket unregistration failed");
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001098
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001099 proto_unregister(&l2cap_proto);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001100}