blob: 6c7d4323e7973501011ed2959de7e658dff46c6f [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.
6
7 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 2 as
11 published by the Free Software Foundation;
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
16 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
17 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
18 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21
22 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
23 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
24 SOFTWARE IS DISCLAIMED.
25*/
26
27/* Bluetooth L2CAP sockets. */
28
Paul Moore6230c9b2011-10-07 09:40:59 +000029#include <linux/security.h>
30
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020031#include <net/bluetooth/bluetooth.h>
Gustavo F. Padovan33575df2011-02-04 02:48:48 -020032#include <net/bluetooth/hci_core.h>
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020033#include <net/bluetooth/l2cap.h>
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -030034#include <net/bluetooth/smp.h>
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020035
Gustavo F. Padovancf2f90f2011-04-27 18:40:39 -030036static const struct proto_ops l2cap_sock_ops;
Gustavo F. Padovan80808e42011-05-16 17:24:37 -030037static void l2cap_sock_init(struct sock *sk, struct sock *parent);
38static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio);
Gustavo F. Padovancf2f90f2011-04-27 18:40:39 -030039
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -020040static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
41{
42 struct sock *sk = sock->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -030043 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -020044 struct sockaddr_l2 la;
45 int len, err = 0;
46
47 BT_DBG("sk %p", sk);
48
49 if (!addr || addr->sa_family != AF_BLUETOOTH)
50 return -EINVAL;
51
52 memset(&la, 0, sizeof(la));
53 len = min_t(unsigned int, sizeof(la), alen);
54 memcpy(&la, addr, len);
55
Ville Tervob62f3282011-02-10 22:38:50 -030056 if (la.l2_cid && la.l2_psm)
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -020057 return -EINVAL;
58
59 lock_sock(sk);
60
61 if (sk->sk_state != BT_OPEN) {
62 err = -EBADFD;
63 goto done;
64 }
65
66 if (la.l2_psm) {
67 __u16 psm = __le16_to_cpu(la.l2_psm);
68
69 /* PSM must be odd and lsb of upper byte must be 0 */
70 if ((psm & 0x0101) != 0x0001) {
71 err = -EINVAL;
72 goto done;
73 }
74
75 /* Restrict usage of well-known PSMs */
76 if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) {
77 err = -EACCES;
78 goto done;
79 }
80 }
81
Ville Tervob62f3282011-02-10 22:38:50 -030082 if (la.l2_cid)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -030083 err = l2cap_add_scid(chan, la.l2_cid);
84 else
85 err = l2cap_add_psm(chan, &la.l2_bdaddr, la.l2_psm);
Ville Tervob62f3282011-02-10 22:38:50 -030086
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -030087 if (err < 0)
88 goto done;
89
90 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
91 __le16_to_cpu(la.l2_psm) == 0x0003)
92 chan->sec_level = BT_SECURITY_SDP;
93
94 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -030095
96 chan->state = BT_BOUND;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -030097 sk->sk_state = BT_BOUND;
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -020098
99done:
100 release_sock(sk);
101 return err;
102}
103
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200104static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
105{
106 struct sock *sk = sock->sk;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300107 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200108 struct sockaddr_l2 la;
109 int len, err = 0;
110
111 BT_DBG("sk %p", sk);
112
113 if (!addr || alen < sizeof(addr->sa_family) ||
114 addr->sa_family != AF_BLUETOOTH)
115 return -EINVAL;
116
117 memset(&la, 0, sizeof(la));
118 len = min_t(unsigned int, sizeof(la), alen);
119 memcpy(&la, addr, len);
120
Ville Tervoacd7d372011-02-10 22:38:49 -0300121 if (la.l2_cid && la.l2_psm)
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200122 return -EINVAL;
123
Gustavo F. Padovan03a00192011-12-09 04:48:17 -0200124 err = l2cap_chan_connect(chan, la.l2_psm, la.l2_cid, &la.l2_bdaddr);
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200125 if (err)
126 goto done;
127
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200128 err = bt_sock_wait_state(sk, BT_CONNECTED,
129 sock_sndtimeo(sk, flags & O_NONBLOCK));
130done:
Gustavo F. Padovan03a00192011-12-09 04:48:17 -0200131 if (sock_owned_by_user(sk))
132 release_sock(sk);
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200133 return err;
134}
135
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200136static int l2cap_sock_listen(struct socket *sock, int backlog)
137{
138 struct sock *sk = sock->sk;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300139 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200140 int err = 0;
141
142 BT_DBG("sk %p backlog %d", sk, backlog);
143
144 lock_sock(sk);
145
146 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
147 || sk->sk_state != BT_BOUND) {
148 err = -EBADFD;
149 goto done;
150 }
151
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300152 switch (chan->mode) {
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200153 case L2CAP_MODE_BASIC:
154 break;
155 case L2CAP_MODE_ERTM:
156 case L2CAP_MODE_STREAMING:
157 if (!disable_ertm)
158 break;
159 /* fall through */
160 default:
161 err = -ENOTSUPP;
162 goto done;
163 }
164
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200165 sk->sk_max_ack_backlog = backlog;
166 sk->sk_ack_backlog = 0;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300167
168 chan->state = BT_LISTEN;
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200169 sk->sk_state = BT_LISTEN;
170
171done:
172 release_sock(sk);
173 return err;
174}
175
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200176static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
177{
178 DECLARE_WAITQUEUE(wait, current);
179 struct sock *sk = sock->sk, *nsk;
180 long timeo;
181 int err = 0;
182
183 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
184
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200185 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
186
187 BT_DBG("sk %p timeo %ld", sk, timeo);
188
189 /* Wait for an incoming connection. (wake-one). */
190 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Peter Hurleyf9a3c202011-07-24 00:10:52 -0400191 while (1) {
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200192 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200193
194 if (sk->sk_state != BT_LISTEN) {
195 err = -EBADFD;
196 break;
197 }
198
Peter Hurleyf9a3c202011-07-24 00:10:52 -0400199 nsk = bt_accept_dequeue(sk, newsock);
200 if (nsk)
201 break;
202
203 if (!timeo) {
204 err = -EAGAIN;
205 break;
206 }
207
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200208 if (signal_pending(current)) {
209 err = sock_intr_errno(timeo);
210 break;
211 }
Peter Hurleyf9a3c202011-07-24 00:10:52 -0400212
213 release_sock(sk);
214 timeo = schedule_timeout(timeo);
215 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200216 }
Peter Hurleyf9a3c202011-07-24 00:10:52 -0400217 __set_current_state(TASK_RUNNING);
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200218 remove_wait_queue(sk_sleep(sk), &wait);
219
220 if (err)
221 goto done;
222
223 newsock->state = SS_CONNECTED;
224
225 BT_DBG("new socket %p", nsk);
226
227done:
228 release_sock(sk);
229 return err;
230}
231
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200232static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
233{
234 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
235 struct sock *sk = sock->sk;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300236 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200237
238 BT_DBG("sock %p, sk %p", sock, sk);
239
240 addr->sa_family = AF_BLUETOOTH;
241 *len = sizeof(struct sockaddr_l2);
242
243 if (peer) {
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300244 la->l2_psm = chan->psm;
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200245 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300246 la->l2_cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200247 } else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300248 la->l2_psm = chan->sport;
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200249 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300250 la->l2_cid = cpu_to_le16(chan->scid);
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200251 }
252
253 return 0;
254}
255
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200256static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
257{
258 struct sock *sk = sock->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300259 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200260 struct l2cap_options opts;
261 struct l2cap_conninfo cinfo;
262 int len, err = 0;
263 u32 opt;
264
265 BT_DBG("sk %p", sk);
266
267 if (get_user(len, optlen))
268 return -EFAULT;
269
270 lock_sock(sk);
271
272 switch (optname) {
273 case L2CAP_OPTIONS:
Vasiliy Kulikove3fb5922011-02-10 20:59:42 +0300274 memset(&opts, 0, sizeof(opts));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300275 opts.imtu = chan->imtu;
276 opts.omtu = chan->omtu;
277 opts.flush_to = chan->flush_to;
278 opts.mode = chan->mode;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300279 opts.fcs = chan->fcs;
280 opts.max_tx = chan->max_tx;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +0300281 opts.txwin_size = chan->tx_win;
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200282
283 len = min_t(unsigned int, len, sizeof(opts));
284 if (copy_to_user(optval, (char *) &opts, len))
285 err = -EFAULT;
286
287 break;
288
289 case L2CAP_LM:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300290 switch (chan->sec_level) {
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200291 case BT_SECURITY_LOW:
292 opt = L2CAP_LM_AUTH;
293 break;
294 case BT_SECURITY_MEDIUM:
295 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
296 break;
297 case BT_SECURITY_HIGH:
298 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
299 L2CAP_LM_SECURE;
300 break;
301 default:
302 opt = 0;
303 break;
304 }
305
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +0300306 if (test_bit(FLAG_ROLE_SWITCH, &chan->flags))
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200307 opt |= L2CAP_LM_MASTER;
308
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +0300309 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200310 opt |= L2CAP_LM_RELIABLE;
311
312 if (put_user(opt, (u32 __user *) optval))
313 err = -EFAULT;
314 break;
315
316 case L2CAP_CONNINFO:
317 if (sk->sk_state != BT_CONNECTED &&
318 !(sk->sk_state == BT_CONNECT2 &&
319 bt_sk(sk)->defer_setup)) {
320 err = -ENOTCONN;
321 break;
322 }
323
Filip Palian8d03e972011-05-12 19:32:46 +0200324 memset(&cinfo, 0, sizeof(cinfo));
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300325 cinfo.hci_handle = chan->conn->hcon->handle;
326 memcpy(cinfo.dev_class, chan->conn->hcon->dev_class, 3);
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200327
328 len = min_t(unsigned int, len, sizeof(cinfo));
329 if (copy_to_user(optval, (char *) &cinfo, len))
330 err = -EFAULT;
331
332 break;
333
334 default:
335 err = -ENOPROTOOPT;
336 break;
337 }
338
339 release_sock(sk);
340 return err;
341}
342
343static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
344{
345 struct sock *sk = sock->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300346 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200347 struct bt_security sec;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700348 struct bt_power pwr;
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200349 int len, err = 0;
350
351 BT_DBG("sk %p", sk);
352
353 if (level == SOL_L2CAP)
354 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
355
356 if (level != SOL_BLUETOOTH)
357 return -ENOPROTOOPT;
358
359 if (get_user(len, optlen))
360 return -EFAULT;
361
362 lock_sock(sk);
363
364 switch (optname) {
365 case BT_SECURITY:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300366 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
367 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200368 err = -EINVAL;
369 break;
370 }
371
Vinicius Costa Gomes8f360112011-07-08 18:31:46 -0300372 memset(&sec, 0, sizeof(sec));
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300373 sec.level = chan->sec_level;
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200374
Vinicius Costa Gomes8f360112011-07-08 18:31:46 -0300375 if (sk->sk_state == BT_CONNECTED)
376 sec.key_size = chan->conn->hcon->enc_key_size;
377
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200378 len = min_t(unsigned int, len, sizeof(sec));
379 if (copy_to_user(optval, (char *) &sec, len))
380 err = -EFAULT;
381
382 break;
383
384 case BT_DEFER_SETUP:
385 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
386 err = -EINVAL;
387 break;
388 }
389
390 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
391 err = -EFAULT;
392
393 break;
394
395 case BT_FLUSHABLE:
Andrei Emeltchenkod57b0e82011-10-11 14:04:31 +0300396 if (put_user(test_bit(FLAG_FLUSHABLE, &chan->flags),
397 (u32 __user *) optval))
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200398 err = -EFAULT;
399
400 break;
401
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700402 case BT_POWER:
403 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
404 && sk->sk_type != SOCK_RAW) {
405 err = -EINVAL;
406 break;
407 }
408
Andrei Emeltchenko15770b12011-10-11 14:04:33 +0300409 pwr.force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700410
411 len = min_t(unsigned int, len, sizeof(pwr));
412 if (copy_to_user(optval, (char *) &pwr, len))
413 err = -EFAULT;
414
415 break;
416
Mat Martineau2ea66482011-11-02 16:18:30 -0700417 case BT_CHANNEL_POLICY:
418 if (!enable_hs) {
419 err = -ENOPROTOOPT;
420 break;
421 }
422
423 if (put_user(chan->chan_policy, (u32 __user *) optval))
424 err = -EFAULT;
425 break;
426
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200427 default:
428 err = -ENOPROTOOPT;
429 break;
430 }
431
432 release_sock(sk);
433 return err;
434}
435
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200436static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
437{
438 struct sock *sk = sock->sk;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300439 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200440 struct l2cap_options opts;
441 int len, err = 0;
442 u32 opt;
443
444 BT_DBG("sk %p", sk);
445
446 lock_sock(sk);
447
448 switch (optname) {
449 case L2CAP_OPTIONS:
450 if (sk->sk_state == BT_CONNECTED) {
451 err = -EINVAL;
452 break;
453 }
454
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300455 opts.imtu = chan->imtu;
456 opts.omtu = chan->omtu;
457 opts.flush_to = chan->flush_to;
458 opts.mode = chan->mode;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300459 opts.fcs = chan->fcs;
460 opts.max_tx = chan->max_tx;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +0300461 opts.txwin_size = chan->tx_win;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200462
463 len = min_t(unsigned int, sizeof(opts), optlen);
464 if (copy_from_user((char *) &opts, optval, len)) {
465 err = -EFAULT;
466 break;
467 }
468
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +0300469 if (opts.txwin_size > L2CAP_DEFAULT_EXT_WINDOW) {
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200470 err = -EINVAL;
471 break;
472 }
473
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300474 chan->mode = opts.mode;
475 switch (chan->mode) {
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200476 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300477 clear_bit(CONF_STATE2_DEVICE, &chan->conf_state);
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200478 break;
479 case L2CAP_MODE_ERTM:
480 case L2CAP_MODE_STREAMING:
481 if (!disable_ertm)
482 break;
483 /* fall through */
484 default:
485 err = -EINVAL;
486 break;
487 }
488
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300489 chan->imtu = opts.imtu;
490 chan->omtu = opts.omtu;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300491 chan->fcs = opts.fcs;
492 chan->max_tx = opts.max_tx;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +0300493 chan->tx_win = opts.txwin_size;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200494 break;
495
496 case L2CAP_LM:
497 if (get_user(opt, (u32 __user *) optval)) {
498 err = -EFAULT;
499 break;
500 }
501
502 if (opt & L2CAP_LM_AUTH)
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300503 chan->sec_level = BT_SECURITY_LOW;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200504 if (opt & L2CAP_LM_ENCRYPT)
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300505 chan->sec_level = BT_SECURITY_MEDIUM;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200506 if (opt & L2CAP_LM_SECURE)
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300507 chan->sec_level = BT_SECURITY_HIGH;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200508
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +0300509 if (opt & L2CAP_LM_MASTER)
510 set_bit(FLAG_ROLE_SWITCH, &chan->flags);
511 else
512 clear_bit(FLAG_ROLE_SWITCH, &chan->flags);
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +0300513
514 if (opt & L2CAP_LM_RELIABLE)
515 set_bit(FLAG_FORCE_RELIABLE, &chan->flags);
516 else
517 clear_bit(FLAG_FORCE_RELIABLE, &chan->flags);
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200518 break;
519
520 default:
521 err = -ENOPROTOOPT;
522 break;
523 }
524
525 release_sock(sk);
526 return err;
527}
528
529static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
530{
531 struct sock *sk = sock->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300532 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200533 struct bt_security sec;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700534 struct bt_power pwr;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300535 struct l2cap_conn *conn;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200536 int len, err = 0;
537 u32 opt;
538
539 BT_DBG("sk %p", sk);
540
541 if (level == SOL_L2CAP)
542 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
543
544 if (level != SOL_BLUETOOTH)
545 return -ENOPROTOOPT;
546
547 lock_sock(sk);
548
549 switch (optname) {
550 case BT_SECURITY:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300551 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
552 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200553 err = -EINVAL;
554 break;
555 }
556
557 sec.level = BT_SECURITY_LOW;
558
559 len = min_t(unsigned int, sizeof(sec), optlen);
560 if (copy_from_user((char *) &sec, optval, len)) {
561 err = -EFAULT;
562 break;
563 }
564
565 if (sec.level < BT_SECURITY_LOW ||
566 sec.level > BT_SECURITY_HIGH) {
567 err = -EINVAL;
568 break;
569 }
570
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300571 chan->sec_level = sec.level;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300572
Gustavo F. Padovan0bee1d62011-11-05 19:58:31 -0200573 if (!chan->conn)
574 break;
575
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300576 conn = chan->conn;
Gustavo F. Padovan0bee1d62011-11-05 19:58:31 -0200577
578 /*change security for LE channels */
579 if (chan->scid == L2CAP_CID_LE_DATA) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300580 if (!conn->hcon->out) {
581 err = -EINVAL;
582 break;
583 }
584
585 if (smp_conn_security(conn, sec.level))
586 break;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300587 sk->sk_state = BT_CONFIG;
Gustavo F. Padovan0bee1d62011-11-05 19:58:31 -0200588
589 /* or for ACL link, under defer_setup time */
590 } else if (sk->sk_state == BT_CONNECT2 &&
591 bt_sk(sk)->defer_setup) {
592 err = l2cap_chan_check_security(chan);
593 } else {
594 err = -EINVAL;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300595 }
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200596 break;
597
598 case BT_DEFER_SETUP:
599 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
600 err = -EINVAL;
601 break;
602 }
603
604 if (get_user(opt, (u32 __user *) optval)) {
605 err = -EFAULT;
606 break;
607 }
608
609 bt_sk(sk)->defer_setup = opt;
610 break;
611
612 case BT_FLUSHABLE:
613 if (get_user(opt, (u32 __user *) optval)) {
614 err = -EFAULT;
615 break;
616 }
617
618 if (opt > BT_FLUSHABLE_ON) {
619 err = -EINVAL;
620 break;
621 }
622
623 if (opt == BT_FLUSHABLE_OFF) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300624 struct l2cap_conn *conn = chan->conn;
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300625 /* proceed further only when we have l2cap_conn and
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200626 No Flush support in the LM */
627 if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) {
628 err = -EINVAL;
629 break;
630 }
631 }
632
Andrei Emeltchenkod57b0e82011-10-11 14:04:31 +0300633 if (opt)
634 set_bit(FLAG_FLUSHABLE, &chan->flags);
635 else
636 clear_bit(FLAG_FLUSHABLE, &chan->flags);
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200637 break;
638
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700639 case BT_POWER:
640 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
641 chan->chan_type != L2CAP_CHAN_RAW) {
642 err = -EINVAL;
643 break;
644 }
645
646 pwr.force_active = BT_POWER_FORCE_ACTIVE_ON;
647
648 len = min_t(unsigned int, sizeof(pwr), optlen);
649 if (copy_from_user((char *) &pwr, optval, len)) {
650 err = -EFAULT;
651 break;
652 }
Andrei Emeltchenko15770b12011-10-11 14:04:33 +0300653
654 if (pwr.force_active)
655 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
656 else
657 clear_bit(FLAG_FORCE_ACTIVE, &chan->flags);
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700658 break;
659
Mat Martineau2ea66482011-11-02 16:18:30 -0700660 case BT_CHANNEL_POLICY:
661 if (!enable_hs) {
662 err = -ENOPROTOOPT;
663 break;
664 }
665
666 if (get_user(opt, (u32 __user *) optval)) {
667 err = -EFAULT;
668 break;
669 }
670
671 if (opt > BT_CHANNEL_POLICY_AMP_PREFERRED) {
672 err = -EINVAL;
673 break;
674 }
675
676 if (chan->mode != L2CAP_MODE_ERTM &&
677 chan->mode != L2CAP_MODE_STREAMING) {
678 err = -EOPNOTSUPP;
679 break;
680 }
681
682 chan->chan_policy = (u8) opt;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200683 break;
684
685 default:
686 err = -ENOPROTOOPT;
687 break;
688 }
689
690 release_sock(sk);
691 return err;
692}
693
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200694static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
695{
696 struct sock *sk = sock->sk;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300697 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200698 int err;
699
700 BT_DBG("sock %p, sk %p", sock, sk);
701
702 err = sock_error(sk);
703 if (err)
704 return err;
705
706 if (msg->msg_flags & MSG_OOB)
707 return -EOPNOTSUPP;
708
709 lock_sock(sk);
710
711 if (sk->sk_state != BT_CONNECTED) {
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -0300712 release_sock(sk);
713 return -ENOTCONN;
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200714 }
715
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200716 err = l2cap_chan_send(chan, msg, len, sk->sk_priority);
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200717
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200718 release_sock(sk);
719 return err;
720}
721
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200722static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
723{
724 struct sock *sk = sock->sk;
Mat Martineaue3281402011-07-07 09:39:02 -0700725 struct l2cap_pinfo *pi = l2cap_pi(sk);
726 int err;
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200727
728 lock_sock(sk);
729
730 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300731 sk->sk_state = BT_CONFIG;
732
Mat Martineaue3281402011-07-07 09:39:02 -0700733 __l2cap_connect_rsp_defer(pi->chan);
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200734 release_sock(sk);
735 return 0;
736 }
737
738 release_sock(sk);
739
740 if (sock->type == SOCK_STREAM)
Mat Martineaue3281402011-07-07 09:39:02 -0700741 err = bt_sock_stream_recvmsg(iocb, sock, msg, len, flags);
742 else
743 err = bt_sock_recvmsg(iocb, sock, msg, len, flags);
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200744
Mat Martineaue3281402011-07-07 09:39:02 -0700745 if (pi->chan->mode != L2CAP_MODE_ERTM)
746 return err;
747
748 /* Attempt to put pending rx data in the socket buffer */
749
750 lock_sock(sk);
751
752 if (!test_bit(CONN_LOCAL_BUSY, &pi->chan->conn_state))
753 goto done;
754
755 if (pi->rx_busy_skb) {
756 if (!sock_queue_rcv_skb(sk, pi->rx_busy_skb))
757 pi->rx_busy_skb = NULL;
758 else
759 goto done;
760 }
761
762 /* Restore data flow when half of the receive buffer is
763 * available. This avoids resending large numbers of
764 * frames.
765 */
766 if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf >> 1)
767 l2cap_chan_busy(pi->chan, 0);
768
769done:
770 release_sock(sk);
771 return err;
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200772}
773
Gustavo F. Padovan05fc1572011-02-04 03:26:01 -0200774/* Kill socket (only if zapped and orphan)
775 * Must be called on unlocked socket.
776 */
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300777static void l2cap_sock_kill(struct sock *sk)
Gustavo F. Padovan05fc1572011-02-04 03:26:01 -0200778{
779 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
780 return;
781
782 BT_DBG("sk %p state %d", sk, sk->sk_state);
783
784 /* Kill poor orphan */
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300785
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300786 l2cap_chan_destroy(l2cap_pi(sk)->chan);
Gustavo F. Padovan05fc1572011-02-04 03:26:01 -0200787 sock_set_flag(sk, SOCK_DEAD);
788 sock_put(sk);
789}
790
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200791static int l2cap_sock_shutdown(struct socket *sock, int how)
792{
793 struct sock *sk = sock->sk;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300794 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200795 int err = 0;
796
797 BT_DBG("sock %p, sk %p", sock, sk);
798
799 if (!sk)
800 return 0;
801
802 lock_sock(sk);
803 if (!sk->sk_shutdown) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300804 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200805 err = __l2cap_wait_ack(sk);
806
807 sk->sk_shutdown = SHUTDOWN_MASK;
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300808 l2cap_chan_close(chan, 0);
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200809
810 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
811 err = bt_sock_wait_state(sk, BT_CLOSED,
812 sk->sk_lingertime);
813 }
814
815 if (!err && sk->sk_err)
816 err = -sk->sk_err;
817
818 release_sock(sk);
819 return err;
820}
821
Gustavo F. Padovan554f05b2011-02-04 02:36:42 -0200822static int l2cap_sock_release(struct socket *sock)
823{
824 struct sock *sk = sock->sk;
825 int err;
826
827 BT_DBG("sock %p, sk %p", sock, sk);
828
829 if (!sk)
830 return 0;
831
832 err = l2cap_sock_shutdown(sock, 2);
833
834 sock_orphan(sk);
835 l2cap_sock_kill(sk);
836 return err;
837}
838
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300839static struct l2cap_chan *l2cap_sock_new_connection_cb(void *data)
840{
841 struct sock *sk, *parent = data;
842
843 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP,
844 GFP_ATOMIC);
845 if (!sk)
846 return NULL;
847
848 l2cap_sock_init(sk, parent);
849
850 return l2cap_pi(sk)->chan;
851}
852
Gustavo F. Padovan23070492011-05-16 17:57:22 -0300853static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb)
854{
Mat Martineaue3281402011-07-07 09:39:02 -0700855 int err;
Gustavo F. Padovan23070492011-05-16 17:57:22 -0300856 struct sock *sk = data;
Mat Martineaue3281402011-07-07 09:39:02 -0700857 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan23070492011-05-16 17:57:22 -0300858
Mat Martineaue3281402011-07-07 09:39:02 -0700859 if (pi->rx_busy_skb)
860 return -ENOMEM;
861
862 err = sock_queue_rcv_skb(sk, skb);
863
864 /* For ERTM, handle one skb that doesn't fit into the recv
865 * buffer. This is important to do because the data frames
866 * have already been acked, so the skb cannot be discarded.
867 *
868 * Notify the l2cap core that the buffer is full, so the
869 * LOCAL_BUSY state is entered and no more frames are
870 * acked and reassembled until there is buffer space
871 * available.
872 */
873 if (err < 0 && pi->chan->mode == L2CAP_MODE_ERTM) {
874 pi->rx_busy_skb = skb;
875 l2cap_chan_busy(pi->chan, 1);
876 err = 0;
877 }
878
879 return err;
Gustavo F. Padovan23070492011-05-16 17:57:22 -0300880}
881
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300882static void l2cap_sock_close_cb(void *data)
883{
884 struct sock *sk = data;
885
886 l2cap_sock_kill(sk);
887}
888
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300889static void l2cap_sock_state_change_cb(void *data, int state)
890{
891 struct sock *sk = data;
892
893 sk->sk_state = state;
894}
895
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300896static struct l2cap_ops l2cap_chan_ops = {
897 .name = "L2CAP Socket Interface",
898 .new_connection = l2cap_sock_new_connection_cb,
Gustavo F. Padovan23070492011-05-16 17:57:22 -0300899 .recv = l2cap_sock_recv_cb,
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300900 .close = l2cap_sock_close_cb,
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300901 .state_change = l2cap_sock_state_change_cb,
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300902};
903
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200904static void l2cap_sock_destruct(struct sock *sk)
905{
906 BT_DBG("sk %p", sk);
907
Mat Martineaue3281402011-07-07 09:39:02 -0700908 if (l2cap_pi(sk)->rx_busy_skb) {
909 kfree_skb(l2cap_pi(sk)->rx_busy_skb);
910 l2cap_pi(sk)->rx_busy_skb = NULL;
911 }
912
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200913 skb_queue_purge(&sk->sk_receive_queue);
914 skb_queue_purge(&sk->sk_write_queue);
915}
916
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300917static void l2cap_sock_init(struct sock *sk, struct sock *parent)
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200918{
919 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300920 struct l2cap_chan *chan = pi->chan;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200921
922 BT_DBG("sk %p", sk);
923
924 if (parent) {
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300925 struct l2cap_chan *pchan = l2cap_pi(parent)->chan;
926
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200927 sk->sk_type = parent->sk_type;
928 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
929
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300930 chan->chan_type = pchan->chan_type;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300931 chan->imtu = pchan->imtu;
932 chan->omtu = pchan->omtu;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300933 chan->conf_state = pchan->conf_state;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300934 chan->mode = pchan->mode;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300935 chan->fcs = pchan->fcs;
936 chan->max_tx = pchan->max_tx;
937 chan->tx_win = pchan->tx_win;
Andrei Emeltchenko6b3c7102011-11-02 09:57:10 +0200938 chan->tx_win_max = pchan->tx_win_max;
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300939 chan->sec_level = pchan->sec_level;
Andrei Emeltchenkod57b0e82011-10-11 14:04:31 +0300940 chan->flags = pchan->flags;
Paul Moore6230c9b2011-10-07 09:40:59 +0000941
942 security_sk_clone(parent, sk);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200943 } else {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300944
945 switch (sk->sk_type) {
946 case SOCK_RAW:
947 chan->chan_type = L2CAP_CHAN_RAW;
948 break;
949 case SOCK_DGRAM:
950 chan->chan_type = L2CAP_CHAN_CONN_LESS;
951 break;
952 case SOCK_SEQPACKET:
953 case SOCK_STREAM:
954 chan->chan_type = L2CAP_CHAN_CONN_ORIENTED;
955 break;
956 }
957
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300958 chan->imtu = L2CAP_DEFAULT_MTU;
959 chan->omtu = 0;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200960 if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300961 chan->mode = L2CAP_MODE_ERTM;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300962 set_bit(CONF_STATE2_DEVICE, &chan->conf_state);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200963 } else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300964 chan->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200965 }
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300966 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
967 chan->fcs = L2CAP_FCS_CRC16;
968 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenko6b3c7102011-11-02 09:57:10 +0200969 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300970 chan->sec_level = BT_SECURITY_LOW;
Andrei Emeltchenkod57b0e82011-10-11 14:04:31 +0300971 chan->flags = 0;
Andrei Emeltchenko15770b12011-10-11 14:04:33 +0300972 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200973 }
974
975 /* Default config options */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300976 chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300977
978 chan->data = sk;
979 chan->ops = &l2cap_chan_ops;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200980}
981
982static struct proto l2cap_proto = {
983 .name = "L2CAP",
984 .owner = THIS_MODULE,
985 .obj_size = sizeof(struct l2cap_pinfo)
986};
987
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300988static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200989{
990 struct sock *sk;
Gustavo F. Padovandc50a062011-05-16 16:42:01 -0300991 struct l2cap_chan *chan;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -0200992
993 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
994 if (!sk)
995 return NULL;
996
997 sock_init_data(sock, sk);
998 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
999
1000 sk->sk_destruct = l2cap_sock_destruct;
Chen Ganir6be6b112011-07-28 15:42:09 +03001001 sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001002
1003 sock_reset_flag(sk, SOCK_ZAPPED);
1004
1005 sk->sk_protocol = proto;
1006 sk->sk_state = BT_OPEN;
1007
Gustavo F. Padovandc50a062011-05-16 16:42:01 -03001008 chan = l2cap_chan_create(sk);
1009 if (!chan) {
1010 l2cap_sock_kill(sk);
1011 return NULL;
1012 }
1013
1014 l2cap_pi(sk)->chan = chan;
1015
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001016 return sk;
1017}
1018
1019static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
1020 int kern)
1021{
1022 struct sock *sk;
1023
1024 BT_DBG("sock %p", sock);
1025
1026 sock->state = SS_UNCONNECTED;
1027
1028 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
1029 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
1030 return -ESOCKTNOSUPPORT;
1031
1032 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
1033 return -EPERM;
1034
1035 sock->ops = &l2cap_sock_ops;
1036
1037 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
1038 if (!sk)
1039 return -ENOMEM;
1040
1041 l2cap_sock_init(sk, NULL);
1042 return 0;
1043}
1044
Gustavo F. Padovancf2f90f2011-04-27 18:40:39 -03001045static const struct proto_ops l2cap_sock_ops = {
Gustavo F. Padovan65390582011-02-04 02:33:56 -02001046 .family = PF_BLUETOOTH,
1047 .owner = THIS_MODULE,
1048 .release = l2cap_sock_release,
1049 .bind = l2cap_sock_bind,
1050 .connect = l2cap_sock_connect,
1051 .listen = l2cap_sock_listen,
1052 .accept = l2cap_sock_accept,
1053 .getname = l2cap_sock_getname,
1054 .sendmsg = l2cap_sock_sendmsg,
1055 .recvmsg = l2cap_sock_recvmsg,
1056 .poll = bt_sock_poll,
1057 .ioctl = bt_sock_ioctl,
1058 .mmap = sock_no_mmap,
1059 .socketpair = sock_no_socketpair,
1060 .shutdown = l2cap_sock_shutdown,
1061 .setsockopt = l2cap_sock_setsockopt,
1062 .getsockopt = l2cap_sock_getsockopt
1063};
1064
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001065static const struct net_proto_family l2cap_sock_family_ops = {
1066 .family = PF_BLUETOOTH,
1067 .owner = THIS_MODULE,
1068 .create = l2cap_sock_create,
1069};
1070
1071int __init l2cap_init_sockets(void)
1072{
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001073 int err;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001074
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001075 err = proto_register(&l2cap_proto, 0);
1076 if (err < 0)
1077 return err;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001078
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001079 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
1080 if (err < 0)
1081 goto error;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001082
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001083 BT_INFO("L2CAP socket layer initialized");
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001084
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001085 return 0;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001086
1087error:
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001088 BT_ERR("L2CAP socket registration failed");
1089 proto_unregister(&l2cap_proto);
1090 return err;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001091}
1092
1093void l2cap_cleanup_sockets(void)
1094{
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001095 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
1096 BT_ERR("L2CAP socket unregistration failed");
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001097
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001098 proto_unregister(&l2cap_proto);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001099}