1bb58f747SGustavo F. Padovan /*
2bb58f747SGustavo F. Padovan BlueZ - Bluetooth protocol stack for Linux
3bb58f747SGustavo F. Padovan Copyright (C) 2000-2001 Qualcomm Incorporated
4bb58f747SGustavo F. Padovan Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
5bb58f747SGustavo F. Padovan Copyright (C) 2010 Google Inc.
6590051deSGustavo F. Padovan Copyright (C) 2011 ProFUSION Embedded Systems
7bb58f747SGustavo F. Padovan
8bb58f747SGustavo F. Padovan Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
9bb58f747SGustavo F. Padovan
10bb58f747SGustavo F. Padovan This program is free software; you can redistribute it and/or modify
11bb58f747SGustavo F. Padovan it under the terms of the GNU General Public License version 2 as
12bb58f747SGustavo F. Padovan published by the Free Software Foundation;
13bb58f747SGustavo F. Padovan
14bb58f747SGustavo F. Padovan THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15bb58f747SGustavo F. Padovan OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16bb58f747SGustavo F. Padovan FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
17bb58f747SGustavo F. Padovan IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
18bb58f747SGustavo F. Padovan CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
19bb58f747SGustavo F. Padovan WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20bb58f747SGustavo F. Padovan ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21bb58f747SGustavo F. Padovan OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22bb58f747SGustavo F. Padovan
23bb58f747SGustavo F. Padovan ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
24bb58f747SGustavo F. Padovan COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
25bb58f747SGustavo F. Padovan SOFTWARE IS DISCLAIMED.
26bb58f747SGustavo F. Padovan */
27bb58f747SGustavo F. Padovan
28bb58f747SGustavo F. Padovan /* Bluetooth L2CAP sockets. */
29bb58f747SGustavo F. Padovan
309149761aSJohan Hedberg #include <linux/module.h>
31bc3b2d7fSPaul Gortmaker #include <linux/export.h>
32b6459415SJakub Kicinski #include <linux/filter.h>
33174cd4b1SIngo Molnar #include <linux/sched/signal.h>
346230c9b4SPaul Moore
35bb58f747SGustavo F. Padovan #include <net/bluetooth/bluetooth.h>
3633575df7SGustavo F. Padovan #include <net/bluetooth/hci_core.h>
37bb58f747SGustavo F. Padovan #include <net/bluetooth/l2cap.h>
38ac4b7236SMarcel Holtmann
39ac4b7236SMarcel Holtmann #include "smp.h"
40bb58f747SGustavo F. Padovan
415b28d95cSMasatake YAMATO static struct bt_sock_list l2cap_sk_list = {
425b28d95cSMasatake YAMATO .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
435b28d95cSMasatake YAMATO };
445b28d95cSMasatake YAMATO
45cf2f90f5SGustavo F. Padovan static const struct proto_ops l2cap_sock_ops;
4680808e43SGustavo F. Padovan static void l2cap_sock_init(struct sock *sk, struct sock *parent);
472d792818SGustavo Padovan static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
4811aa9c28SEric W. Biederman int proto, gfp_t prio, int kern);
491728137bSSungwoo Kim static void l2cap_sock_cleanup_listen(struct sock *parent);
50cf2f90f5SGustavo F. Padovan
l2cap_is_socket(struct socket * sock)51b3916db3SDavid Herrmann bool l2cap_is_socket(struct socket *sock)
52b3916db3SDavid Herrmann {
53b3916db3SDavid Herrmann return sock && sock->ops == &l2cap_sock_ops;
54b3916db3SDavid Herrmann }
55b3916db3SDavid Herrmann EXPORT_SYMBOL(l2cap_is_socket);
56b3916db3SDavid Herrmann
l2cap_validate_bredr_psm(u16 psm)574946096dSJohan Hedberg static int l2cap_validate_bredr_psm(u16 psm)
584946096dSJohan Hedberg {
594946096dSJohan Hedberg /* PSM must be odd and lsb of upper byte must be 0 */
604946096dSJohan Hedberg if ((psm & 0x0101) != 0x0001)
614946096dSJohan Hedberg return -EINVAL;
624946096dSJohan Hedberg
634946096dSJohan Hedberg /* Restrict usage of well-known PSMs */
64114f9f1eSJohan Hedberg if (psm < L2CAP_PSM_DYN_START && !capable(CAP_NET_BIND_SERVICE))
654946096dSJohan Hedberg return -EACCES;
664946096dSJohan Hedberg
674946096dSJohan Hedberg return 0;
684946096dSJohan Hedberg }
694946096dSJohan Hedberg
l2cap_validate_le_psm(u16 psm)704946096dSJohan Hedberg static int l2cap_validate_le_psm(u16 psm)
714946096dSJohan Hedberg {
724946096dSJohan Hedberg /* Valid LE_PSM ranges are defined only until 0x00ff */
73114f9f1eSJohan Hedberg if (psm > L2CAP_PSM_LE_DYN_END)
744946096dSJohan Hedberg return -EINVAL;
754946096dSJohan Hedberg
764946096dSJohan Hedberg /* Restrict fixed, SIG assigned PSM values to CAP_NET_BIND_SERVICE */
77114f9f1eSJohan Hedberg if (psm < L2CAP_PSM_LE_DYN_START && !capable(CAP_NET_BIND_SERVICE))
784946096dSJohan Hedberg return -EACCES;
794946096dSJohan Hedberg
804946096dSJohan Hedberg return 0;
814946096dSJohan Hedberg }
824946096dSJohan Hedberg
l2cap_sock_bind(struct socket * sock,struct sockaddr * addr,int alen)83af6bcd82SGustavo F. Padovan static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
84af6bcd82SGustavo F. Padovan {
85af6bcd82SGustavo F. Padovan struct sock *sk = sock->sk;
864343478fSGustavo F. Padovan struct l2cap_chan *chan = l2cap_pi(sk)->chan;
87af6bcd82SGustavo F. Padovan struct sockaddr_l2 la;
88af6bcd82SGustavo F. Padovan int len, err = 0;
89af6bcd82SGustavo F. Padovan
90af6bcd82SGustavo F. Padovan BT_DBG("sk %p", sk);
91af6bcd82SGustavo F. Padovan
92d2ecfa76SMateusz Jurczyk if (!addr || alen < offsetofend(struct sockaddr, sa_family) ||
93d2ecfa76SMateusz Jurczyk addr->sa_family != AF_BLUETOOTH)
94af6bcd82SGustavo F. Padovan return -EINVAL;
95af6bcd82SGustavo F. Padovan
96af6bcd82SGustavo F. Padovan memset(&la, 0, sizeof(la));
97af6bcd82SGustavo F. Padovan len = min_t(unsigned int, sizeof(la), alen);
98af6bcd82SGustavo F. Padovan memcpy(&la, addr, len);
99af6bcd82SGustavo F. Padovan
100b62f328bSVille Tervo if (la.l2_cid && la.l2_psm)
101af6bcd82SGustavo F. Padovan return -EINVAL;
102af6bcd82SGustavo F. Padovan
10380c1a2e7SJohan Hedberg if (!bdaddr_type_is_valid(la.l2_bdaddr_type))
10480c1a2e7SJohan Hedberg return -EINVAL;
10580c1a2e7SJohan Hedberg
106bfe4655fSJohan Hedberg if (bdaddr_type_is_le(la.l2_bdaddr_type)) {
107bfe4655fSJohan Hedberg /* We only allow ATT user space socket */
1089149761aSJohan Hedberg if (la.l2_cid &&
109dcf4adbfSJoe Perches la.l2_cid != cpu_to_le16(L2CAP_CID_ATT))
110bfe4655fSJohan Hedberg return -EINVAL;
111bfe4655fSJohan Hedberg }
112bfe4655fSJohan Hedberg
113af6bcd82SGustavo F. Padovan lock_sock(sk);
114af6bcd82SGustavo F. Padovan
115af6bcd82SGustavo F. Padovan if (sk->sk_state != BT_OPEN) {
116af6bcd82SGustavo F. Padovan err = -EBADFD;
117af6bcd82SGustavo F. Padovan goto done;
118af6bcd82SGustavo F. Padovan }
119af6bcd82SGustavo F. Padovan
120af6bcd82SGustavo F. Padovan if (la.l2_psm) {
121af6bcd82SGustavo F. Padovan __u16 psm = __le16_to_cpu(la.l2_psm);
122af6bcd82SGustavo F. Padovan
1234946096dSJohan Hedberg if (la.l2_bdaddr_type == BDADDR_BREDR)
1244946096dSJohan Hedberg err = l2cap_validate_bredr_psm(psm);
1254946096dSJohan Hedberg else
1264946096dSJohan Hedberg err = l2cap_validate_le_psm(psm);
127af6bcd82SGustavo F. Padovan
1284946096dSJohan Hedberg if (err)
129af6bcd82SGustavo F. Padovan goto done;
130af6bcd82SGustavo F. Padovan }
131af6bcd82SGustavo F. Padovan
132a2342c5fSJohan Hedberg bacpy(&chan->src, &la.l2_bdaddr);
133a2342c5fSJohan Hedberg chan->src_type = la.l2_bdaddr_type;
134a2342c5fSJohan Hedberg
1359e4425ffSGustavo F. Padovan if (la.l2_cid)
1366e4aff10SSantosh Nayak err = l2cap_add_scid(chan, __le16_to_cpu(la.l2_cid));
1379e4425ffSGustavo F. Padovan else
1389e4425ffSGustavo F. Padovan err = l2cap_add_psm(chan, &la.l2_bdaddr, la.l2_psm);
139af6bcd82SGustavo F. Padovan
1409e4425ffSGustavo F. Padovan if (err < 0)
1419e4425ffSGustavo F. Padovan goto done;
142af6bcd82SGustavo F. Padovan
1436a974b50SMarcel Holtmann switch (chan->chan_type) {
1443124b843SMarcel Holtmann case L2CAP_CHAN_CONN_LESS:
1453124b843SMarcel Holtmann if (__le16_to_cpu(la.l2_psm) == L2CAP_PSM_3DSP)
1463124b843SMarcel Holtmann chan->sec_level = BT_SECURITY_SDP;
1473124b843SMarcel Holtmann break;
1486a974b50SMarcel Holtmann case L2CAP_CHAN_CONN_ORIENTED:
1492983fd68SAndrei Emeltchenko if (__le16_to_cpu(la.l2_psm) == L2CAP_PSM_SDP ||
1502983fd68SAndrei Emeltchenko __le16_to_cpu(la.l2_psm) == L2CAP_PSM_RFCOMM)
1514343478fSGustavo F. Padovan chan->sec_level = BT_SECURITY_SDP;
1526a974b50SMarcel Holtmann break;
153cb6ca8e1SJohan Hedberg case L2CAP_CHAN_RAW:
154cb6ca8e1SJohan Hedberg chan->sec_level = BT_SECURITY_SDP;
155cb6ca8e1SJohan Hedberg break;
156c16900cfSJohan Hedberg case L2CAP_CHAN_FIXED:
157c16900cfSJohan Hedberg /* Fixed channels default to the L2CAP core not holding a
158c16900cfSJohan Hedberg * hci_conn reference for them. For fixed channels mapping to
159c16900cfSJohan Hedberg * L2CAP sockets we do want to hold a reference so set the
160c16900cfSJohan Hedberg * appropriate flag to request it.
161c16900cfSJohan Hedberg */
162c16900cfSJohan Hedberg set_bit(FLAG_HOLD_HCI_CONN, &chan->flags);
163c16900cfSJohan Hedberg break;
1646a974b50SMarcel Holtmann }
165af6bcd82SGustavo F. Padovan
16630d57722SLuiz Augusto von Dentz /* Use L2CAP_MODE_LE_FLOWCTL (CoC) in case of LE address and
16730d57722SLuiz Augusto von Dentz * L2CAP_MODE_EXT_FLOWCTL (ECRED) has not been set.
16830d57722SLuiz Augusto von Dentz */
16930d57722SLuiz Augusto von Dentz if (chan->psm && bdaddr_type_is_le(chan->src_type) &&
17030d57722SLuiz Augusto von Dentz chan->mode != L2CAP_MODE_EXT_FLOWCTL)
1710ce43ce6SJohan Hedberg chan->mode = L2CAP_MODE_LE_FLOWCTL;
17238319713SJohan Hedberg
17389bc500eSGustavo F. Padovan chan->state = BT_BOUND;
1749e4425ffSGustavo F. Padovan sk->sk_state = BT_BOUND;
175af6bcd82SGustavo F. Padovan
176af6bcd82SGustavo F. Padovan done:
177af6bcd82SGustavo F. Padovan release_sock(sk);
178af6bcd82SGustavo F. Padovan return err;
179af6bcd82SGustavo F. Padovan }
180af6bcd82SGustavo F. Padovan
l2cap_sock_connect(struct socket * sock,struct sockaddr * addr,int alen,int flags)1812d792818SGustavo Padovan static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,
1822d792818SGustavo Padovan int alen, int flags)
1834e34c50bSGustavo F. Padovan {
1844e34c50bSGustavo F. Padovan struct sock *sk = sock->sk;
1850c1bc5c6SGustavo F. Padovan struct l2cap_chan *chan = l2cap_pi(sk)->chan;
1864e34c50bSGustavo F. Padovan struct sockaddr_l2 la;
1874e34c50bSGustavo F. Padovan int len, err = 0;
1883af70b39SArchie Pusaka bool zapped;
1894e34c50bSGustavo F. Padovan
1904e34c50bSGustavo F. Padovan BT_DBG("sk %p", sk);
1914e34c50bSGustavo F. Padovan
1923af70b39SArchie Pusaka lock_sock(sk);
1933af70b39SArchie Pusaka zapped = sock_flag(sk, SOCK_ZAPPED);
1943af70b39SArchie Pusaka release_sock(sk);
1953af70b39SArchie Pusaka
1963af70b39SArchie Pusaka if (zapped)
1973af70b39SArchie Pusaka return -EINVAL;
1983af70b39SArchie Pusaka
199d2ecfa76SMateusz Jurczyk if (!addr || alen < offsetofend(struct sockaddr, sa_family) ||
2004e34c50bSGustavo F. Padovan addr->sa_family != AF_BLUETOOTH)
2014e34c50bSGustavo F. Padovan return -EINVAL;
2024e34c50bSGustavo F. Padovan
2034e34c50bSGustavo F. Padovan memset(&la, 0, sizeof(la));
2044e34c50bSGustavo F. Padovan len = min_t(unsigned int, sizeof(la), alen);
2054e34c50bSGustavo F. Padovan memcpy(&la, addr, len);
2064e34c50bSGustavo F. Padovan
207acd7d370SVille Tervo if (la.l2_cid && la.l2_psm)
2084e34c50bSGustavo F. Padovan return -EINVAL;
2094e34c50bSGustavo F. Padovan
21080c1a2e7SJohan Hedberg if (!bdaddr_type_is_valid(la.l2_bdaddr_type))
21180c1a2e7SJohan Hedberg return -EINVAL;
21280c1a2e7SJohan Hedberg
213eb622495SJohan Hedberg /* Check that the socket wasn't bound to something that
214eb622495SJohan Hedberg * conflicts with the address given to connect(). If chan->src
215eb622495SJohan Hedberg * is BDADDR_ANY it means bind() was never used, in which case
216eb622495SJohan Hedberg * chan->src_type and la.l2_bdaddr_type do not need to match.
217eb622495SJohan Hedberg */
218eb622495SJohan Hedberg if (chan->src_type == BDADDR_BREDR && bacmp(&chan->src, BDADDR_ANY) &&
219eb622495SJohan Hedberg bdaddr_type_is_le(la.l2_bdaddr_type)) {
220eb622495SJohan Hedberg /* Old user space versions will try to incorrectly bind
221eb622495SJohan Hedberg * the ATT socket using BDADDR_BREDR. We need to accept
222eb622495SJohan Hedberg * this and fix up the source address type only when
223eb622495SJohan Hedberg * both the source CID and destination CID indicate
224eb622495SJohan Hedberg * ATT. Anything else is an invalid combination.
225eb622495SJohan Hedberg */
226eb622495SJohan Hedberg if (chan->scid != L2CAP_CID_ATT ||
227dcf4adbfSJoe Perches la.l2_cid != cpu_to_le16(L2CAP_CID_ATT))
2281f209383SJohan Hedberg return -EINVAL;
2291f209383SJohan Hedberg
230eb622495SJohan Hedberg /* We don't have the hdev available here to make a
231eb622495SJohan Hedberg * better decision on random vs public, but since all
232eb622495SJohan Hedberg * user space versions that exhibit this issue anyway do
233eb622495SJohan Hedberg * not support random local addresses assuming public
234eb622495SJohan Hedberg * here is good enough.
235eb622495SJohan Hedberg */
236eb622495SJohan Hedberg chan->src_type = BDADDR_LE_PUBLIC;
237eb622495SJohan Hedberg }
238eb622495SJohan Hedberg
2391f209383SJohan Hedberg if (chan->src_type != BDADDR_BREDR && la.l2_bdaddr_type == BDADDR_BREDR)
2401f209383SJohan Hedberg return -EINVAL;
2411f209383SJohan Hedberg
242bfe4655fSJohan Hedberg if (bdaddr_type_is_le(la.l2_bdaddr_type)) {
243bfe4655fSJohan Hedberg /* We only allow ATT user space socket */
2449149761aSJohan Hedberg if (la.l2_cid &&
245dcf4adbfSJoe Perches la.l2_cid != cpu_to_le16(L2CAP_CID_ATT))
246bfe4655fSJohan Hedberg return -EINVAL;
247bfe4655fSJohan Hedberg }
248bfe4655fSJohan Hedberg
24930d57722SLuiz Augusto von Dentz /* Use L2CAP_MODE_LE_FLOWCTL (CoC) in case of LE address and
25030d57722SLuiz Augusto von Dentz * L2CAP_MODE_EXT_FLOWCTL (ECRED) has not been set.
25130d57722SLuiz Augusto von Dentz */
25230d57722SLuiz Augusto von Dentz if (chan->psm && bdaddr_type_is_le(chan->src_type) &&
25330d57722SLuiz Augusto von Dentz chan->mode != L2CAP_MODE_EXT_FLOWCTL)
2540ce43ce6SJohan Hedberg chan->mode = L2CAP_MODE_LE_FLOWCTL;
25538319713SJohan Hedberg
2566e4aff10SSantosh Nayak err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid),
2578e9f9892SAndre Guedes &la.l2_bdaddr, la.l2_bdaddr_type);
2584e34c50bSGustavo F. Padovan if (err)
259b3fb611eSAndrei Emeltchenko return err;
2604e34c50bSGustavo F. Padovan
2616be36555SAndrei Emeltchenko lock_sock(sk);
2626be36555SAndrei Emeltchenko
2634e34c50bSGustavo F. Padovan err = bt_sock_wait_state(sk, BT_CONNECTED,
2644e34c50bSGustavo F. Padovan sock_sndtimeo(sk, flags & O_NONBLOCK));
265b3fb611eSAndrei Emeltchenko
2664e34c50bSGustavo F. Padovan release_sock(sk);
267b3fb611eSAndrei Emeltchenko
2684e34c50bSGustavo F. Padovan return err;
2694e34c50bSGustavo F. Padovan }
2704e34c50bSGustavo F. Padovan
l2cap_sock_listen(struct socket * sock,int backlog)271af6bcd82SGustavo F. Padovan static int l2cap_sock_listen(struct socket *sock, int backlog)
272af6bcd82SGustavo F. Padovan {
273af6bcd82SGustavo F. Padovan struct sock *sk = sock->sk;
2740c1bc5c6SGustavo F. Padovan struct l2cap_chan *chan = l2cap_pi(sk)->chan;
275af6bcd82SGustavo F. Padovan int err = 0;
276af6bcd82SGustavo F. Padovan
277af6bcd82SGustavo F. Padovan BT_DBG("sk %p backlog %d", sk, backlog);
278af6bcd82SGustavo F. Padovan
279af6bcd82SGustavo F. Padovan lock_sock(sk);
280af6bcd82SGustavo F. Padovan
2816b3af733SMarcel Holtmann if (sk->sk_state != BT_BOUND) {
282af6bcd82SGustavo F. Padovan err = -EBADFD;
283af6bcd82SGustavo F. Padovan goto done;
284af6bcd82SGustavo F. Padovan }
285af6bcd82SGustavo F. Padovan
2866b3af733SMarcel Holtmann if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM) {
2876b3af733SMarcel Holtmann err = -EINVAL;
2886b3af733SMarcel Holtmann goto done;
2896b3af733SMarcel Holtmann }
2906b3af733SMarcel Holtmann
2910c1bc5c6SGustavo F. Padovan switch (chan->mode) {
292af6bcd82SGustavo F. Padovan case L2CAP_MODE_BASIC:
29338319713SJohan Hedberg case L2CAP_MODE_LE_FLOWCTL:
2944be5ca67SLuiz Augusto von Dentz break;
29515f02b91SLuiz Augusto von Dentz case L2CAP_MODE_EXT_FLOWCTL:
2964be5ca67SLuiz Augusto von Dentz if (!enable_ecred) {
2974be5ca67SLuiz Augusto von Dentz err = -EOPNOTSUPP;
2984be5ca67SLuiz Augusto von Dentz goto done;
2994be5ca67SLuiz Augusto von Dentz }
300af6bcd82SGustavo F. Padovan break;
301af6bcd82SGustavo F. Padovan case L2CAP_MODE_ERTM:
302af6bcd82SGustavo F. Padovan case L2CAP_MODE_STREAMING:
303af6bcd82SGustavo F. Padovan if (!disable_ertm)
304af6bcd82SGustavo F. Padovan break;
30519186c7bSGustavo A. R. Silva fallthrough;
306af6bcd82SGustavo F. Padovan default:
307beb19e4cSJohan Hedberg err = -EOPNOTSUPP;
308af6bcd82SGustavo F. Padovan goto done;
309af6bcd82SGustavo F. Padovan }
310af6bcd82SGustavo F. Padovan
311af6bcd82SGustavo F. Padovan sk->sk_max_ack_backlog = backlog;
312af6bcd82SGustavo F. Padovan sk->sk_ack_backlog = 0;
31389bc500eSGustavo F. Padovan
314abe84903SJohan Hedberg /* Listening channels need to use nested locking in order not to
315abe84903SJohan Hedberg * cause lockdep warnings when the created child channels end up
316abe84903SJohan Hedberg * being locked in the same thread as the parent channel.
317abe84903SJohan Hedberg */
318abe84903SJohan Hedberg atomic_set(&chan->nesting, L2CAP_NESTING_PARENT);
319abe84903SJohan Hedberg
32089bc500eSGustavo F. Padovan chan->state = BT_LISTEN;
321af6bcd82SGustavo F. Padovan sk->sk_state = BT_LISTEN;
322af6bcd82SGustavo F. Padovan
323af6bcd82SGustavo F. Padovan done:
324af6bcd82SGustavo F. Padovan release_sock(sk);
325af6bcd82SGustavo F. Padovan return err;
326af6bcd82SGustavo F. Padovan }
327af6bcd82SGustavo F. Padovan
l2cap_sock_accept(struct socket * sock,struct socket * newsock,int flags,bool kern)3282d792818SGustavo Padovan static int l2cap_sock_accept(struct socket *sock, struct socket *newsock,
329cdfbabfbSDavid Howells int flags, bool kern)
330c47b7c72SGustavo F. Padovan {
331dfb2fae7SPeter Hurley DEFINE_WAIT_FUNC(wait, woken_wake_function);
332c47b7c72SGustavo F. Padovan struct sock *sk = sock->sk, *nsk;
333c47b7c72SGustavo F. Padovan long timeo;
334c47b7c72SGustavo F. Padovan int err = 0;
335c47b7c72SGustavo F. Padovan
3363b2ab39eSJohan Hedberg lock_sock_nested(sk, L2CAP_NESTING_PARENT);
337c47b7c72SGustavo F. Padovan
338c47b7c72SGustavo F. Padovan timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
339c47b7c72SGustavo F. Padovan
340c47b7c72SGustavo F. Padovan BT_DBG("sk %p timeo %ld", sk, timeo);
341c47b7c72SGustavo F. Padovan
342c47b7c72SGustavo F. Padovan /* Wait for an incoming connection. (wake-one). */
343c47b7c72SGustavo F. Padovan add_wait_queue_exclusive(sk_sleep(sk), &wait);
344f9a3c20aSPeter Hurley while (1) {
345c47b7c72SGustavo F. Padovan if (sk->sk_state != BT_LISTEN) {
346c47b7c72SGustavo F. Padovan err = -EBADFD;
347c47b7c72SGustavo F. Padovan break;
348c47b7c72SGustavo F. Padovan }
349c47b7c72SGustavo F. Padovan
350f9a3c20aSPeter Hurley nsk = bt_accept_dequeue(sk, newsock);
351f9a3c20aSPeter Hurley if (nsk)
352f9a3c20aSPeter Hurley break;
353f9a3c20aSPeter Hurley
354f9a3c20aSPeter Hurley if (!timeo) {
355f9a3c20aSPeter Hurley err = -EAGAIN;
356f9a3c20aSPeter Hurley break;
357f9a3c20aSPeter Hurley }
358f9a3c20aSPeter Hurley
359c47b7c72SGustavo F. Padovan if (signal_pending(current)) {
360c47b7c72SGustavo F. Padovan err = sock_intr_errno(timeo);
361c47b7c72SGustavo F. Padovan break;
362c47b7c72SGustavo F. Padovan }
363f9a3c20aSPeter Hurley
364f9a3c20aSPeter Hurley release_sock(sk);
365dfb2fae7SPeter Hurley
366dfb2fae7SPeter Hurley timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
367dfb2fae7SPeter Hurley
3683b2ab39eSJohan Hedberg lock_sock_nested(sk, L2CAP_NESTING_PARENT);
369c47b7c72SGustavo F. Padovan }
370c47b7c72SGustavo F. Padovan remove_wait_queue(sk_sleep(sk), &wait);
371c47b7c72SGustavo F. Padovan
372c47b7c72SGustavo F. Padovan if (err)
373c47b7c72SGustavo F. Padovan goto done;
374c47b7c72SGustavo F. Padovan
375c47b7c72SGustavo F. Padovan newsock->state = SS_CONNECTED;
376c47b7c72SGustavo F. Padovan
377c47b7c72SGustavo F. Padovan BT_DBG("new socket %p", nsk);
378c47b7c72SGustavo F. Padovan
379c47b7c72SGustavo F. Padovan done:
380c47b7c72SGustavo F. Padovan release_sock(sk);
381c47b7c72SGustavo F. Padovan return err;
382c47b7c72SGustavo F. Padovan }
383c47b7c72SGustavo F. Padovan
l2cap_sock_getname(struct socket * sock,struct sockaddr * addr,int peer)3842d792818SGustavo Padovan static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
3859b2c45d4SDenys Vlasenko int peer)
386d7175d55SGustavo F. Padovan {
387d7175d55SGustavo F. Padovan struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
388d7175d55SGustavo F. Padovan struct sock *sk = sock->sk;
3890c1bc5c6SGustavo F. Padovan struct l2cap_chan *chan = l2cap_pi(sk)->chan;
390d7175d55SGustavo F. Padovan
391d7175d55SGustavo F. Padovan BT_DBG("sock %p, sk %p", sock, sk);
392d7175d55SGustavo F. Padovan
393e8b1ab9eSJohan Hedberg if (peer && sk->sk_state != BT_CONNECTED &&
394bf19d51bSJohan Hedberg sk->sk_state != BT_CONNECT && sk->sk_state != BT_CONNECT2 &&
395bf19d51bSJohan Hedberg sk->sk_state != BT_CONFIG)
396b783fbc3SJohan Hedberg return -ENOTCONN;
397b783fbc3SJohan Hedberg
398792039c7SMathias Krause memset(la, 0, sizeof(struct sockaddr_l2));
399d7175d55SGustavo F. Padovan addr->sa_family = AF_BLUETOOTH;
400d7175d55SGustavo F. Padovan
401fe4128e0SGustavo F. Padovan la->l2_psm = chan->psm;
402d7e5e76bSJohan Hedberg
403d7e5e76bSJohan Hedberg if (peer) {
4047eafc59eSMarcel Holtmann bacpy(&la->l2_bdaddr, &chan->dst);
405fe4128e0SGustavo F. Padovan la->l2_cid = cpu_to_le16(chan->dcid);
4064f1654e0SMarcel Holtmann la->l2_bdaddr_type = chan->dst_type;
407d7175d55SGustavo F. Padovan } else {
4087eafc59eSMarcel Holtmann bacpy(&la->l2_bdaddr, &chan->src);
409fe4128e0SGustavo F. Padovan la->l2_cid = cpu_to_le16(chan->scid);
4104f1654e0SMarcel Holtmann la->l2_bdaddr_type = chan->src_type;
411d7175d55SGustavo F. Padovan }
412d7175d55SGustavo F. Padovan
4139b2c45d4SDenys Vlasenko return sizeof(struct sockaddr_l2);
414d7175d55SGustavo F. Padovan }
415d7175d55SGustavo F. Padovan
l2cap_get_mode(struct l2cap_chan * chan)4163ee7b7cdSLuiz Augusto von Dentz static int l2cap_get_mode(struct l2cap_chan *chan)
4173ee7b7cdSLuiz Augusto von Dentz {
4183ee7b7cdSLuiz Augusto von Dentz switch (chan->mode) {
4193ee7b7cdSLuiz Augusto von Dentz case L2CAP_MODE_BASIC:
4203ee7b7cdSLuiz Augusto von Dentz return BT_MODE_BASIC;
4213ee7b7cdSLuiz Augusto von Dentz case L2CAP_MODE_ERTM:
4223ee7b7cdSLuiz Augusto von Dentz return BT_MODE_ERTM;
4233ee7b7cdSLuiz Augusto von Dentz case L2CAP_MODE_STREAMING:
4243ee7b7cdSLuiz Augusto von Dentz return BT_MODE_STREAMING;
4253ee7b7cdSLuiz Augusto von Dentz case L2CAP_MODE_LE_FLOWCTL:
4263ee7b7cdSLuiz Augusto von Dentz return BT_MODE_LE_FLOWCTL;
4273ee7b7cdSLuiz Augusto von Dentz case L2CAP_MODE_EXT_FLOWCTL:
4283ee7b7cdSLuiz Augusto von Dentz return BT_MODE_EXT_FLOWCTL;
4293ee7b7cdSLuiz Augusto von Dentz }
4303ee7b7cdSLuiz Augusto von Dentz
4313ee7b7cdSLuiz Augusto von Dentz return -EINVAL;
4323ee7b7cdSLuiz Augusto von Dentz }
4333ee7b7cdSLuiz Augusto von Dentz
l2cap_sock_getsockopt_old(struct socket * sock,int optname,char __user * optval,int __user * optlen)4342d792818SGustavo Padovan static int l2cap_sock_getsockopt_old(struct socket *sock, int optname,
4352d792818SGustavo Padovan char __user *optval, int __user *optlen)
43699f4808dSGustavo F. Padovan {
43799f4808dSGustavo F. Padovan struct sock *sk = sock->sk;
4384343478fSGustavo F. Padovan struct l2cap_chan *chan = l2cap_pi(sk)->chan;
43999f4808dSGustavo F. Padovan struct l2cap_options opts;
44099f4808dSGustavo F. Padovan struct l2cap_conninfo cinfo;
4414eb706b1SNathan Chancellor int err = 0;
4424eb706b1SNathan Chancellor size_t len;
44399f4808dSGustavo F. Padovan u32 opt;
44499f4808dSGustavo F. Padovan
44599f4808dSGustavo F. Padovan BT_DBG("sk %p", sk);
44699f4808dSGustavo F. Padovan
44799f4808dSGustavo F. Padovan if (get_user(len, optlen))
44899f4808dSGustavo F. Padovan return -EFAULT;
44999f4808dSGustavo F. Padovan
45099f4808dSGustavo F. Padovan lock_sock(sk);
45199f4808dSGustavo F. Padovan
45299f4808dSGustavo F. Padovan switch (optname) {
45399f4808dSGustavo F. Padovan case L2CAP_OPTIONS:
45464b4f8dcSJohan Hedberg /* LE sockets should use BT_SNDMTU/BT_RCVMTU, but since
45564b4f8dcSJohan Hedberg * legacy ATT code depends on getsockopt for
45664b4f8dcSJohan Hedberg * L2CAP_OPTIONS we need to let this pass.
45764b4f8dcSJohan Hedberg */
45864b4f8dcSJohan Hedberg if (bdaddr_type_is_le(chan->src_type) &&
45964b4f8dcSJohan Hedberg chan->scid != L2CAP_CID_ATT) {
46064b4f8dcSJohan Hedberg err = -EINVAL;
46164b4f8dcSJohan Hedberg break;
46264b4f8dcSJohan Hedberg }
46364b4f8dcSJohan Hedberg
464b86b0b15SLuiz Augusto von Dentz /* Only BR/EDR modes are supported here */
465b86b0b15SLuiz Augusto von Dentz switch (chan->mode) {
466b86b0b15SLuiz Augusto von Dentz case L2CAP_MODE_BASIC:
467b86b0b15SLuiz Augusto von Dentz case L2CAP_MODE_ERTM:
468b86b0b15SLuiz Augusto von Dentz case L2CAP_MODE_STREAMING:
469b86b0b15SLuiz Augusto von Dentz break;
470b86b0b15SLuiz Augusto von Dentz default:
471b86b0b15SLuiz Augusto von Dentz err = -EINVAL;
472b86b0b15SLuiz Augusto von Dentz break;
473b86b0b15SLuiz Augusto von Dentz }
474b86b0b15SLuiz Augusto von Dentz
475b86b0b15SLuiz Augusto von Dentz if (err < 0)
476b86b0b15SLuiz Augusto von Dentz break;
477b86b0b15SLuiz Augusto von Dentz
478e3fb592bSVasiliy Kulikov memset(&opts, 0, sizeof(opts));
4790c1bc5c6SGustavo F. Padovan opts.imtu = chan->imtu;
4800c1bc5c6SGustavo F. Padovan opts.omtu = chan->omtu;
4810c1bc5c6SGustavo F. Padovan opts.flush_to = chan->flush_to;
4820c1bc5c6SGustavo F. Padovan opts.mode = chan->mode;
48347d1ec61SGustavo F. Padovan opts.fcs = chan->fcs;
48447d1ec61SGustavo F. Padovan opts.max_tx = chan->max_tx;
4856327eb98SAndrei Emeltchenko opts.txwin_size = chan->tx_win;
48699f4808dSGustavo F. Padovan
48715f02b91SLuiz Augusto von Dentz BT_DBG("mode 0x%2.2x", chan->mode);
48815f02b91SLuiz Augusto von Dentz
4894eb706b1SNathan Chancellor len = min(len, sizeof(opts));
49099f4808dSGustavo F. Padovan if (copy_to_user(optval, (char *) &opts, len))
49199f4808dSGustavo F. Padovan err = -EFAULT;
49299f4808dSGustavo F. Padovan
49399f4808dSGustavo F. Padovan break;
49499f4808dSGustavo F. Padovan
49599f4808dSGustavo F. Padovan case L2CAP_LM:
4964343478fSGustavo F. Padovan switch (chan->sec_level) {
49799f4808dSGustavo F. Padovan case BT_SECURITY_LOW:
49899f4808dSGustavo F. Padovan opt = L2CAP_LM_AUTH;
49999f4808dSGustavo F. Padovan break;
50099f4808dSGustavo F. Padovan case BT_SECURITY_MEDIUM:
50199f4808dSGustavo F. Padovan opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
50299f4808dSGustavo F. Padovan break;
50399f4808dSGustavo F. Padovan case BT_SECURITY_HIGH:
50499f4808dSGustavo F. Padovan opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
50599f4808dSGustavo F. Padovan L2CAP_LM_SECURE;
50699f4808dSGustavo F. Padovan break;
5077d513e92SMarcel Holtmann case BT_SECURITY_FIPS:
5087d513e92SMarcel Holtmann opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
5097d513e92SMarcel Holtmann L2CAP_LM_SECURE | L2CAP_LM_FIPS;
5107d513e92SMarcel Holtmann break;
51199f4808dSGustavo F. Padovan default:
51299f4808dSGustavo F. Padovan opt = 0;
51399f4808dSGustavo F. Padovan break;
51499f4808dSGustavo F. Padovan }
51599f4808dSGustavo F. Padovan
51643bd0f32SAndrei Emeltchenko if (test_bit(FLAG_ROLE_SWITCH, &chan->flags))
51799f4808dSGustavo F. Padovan opt |= L2CAP_LM_MASTER;
51899f4808dSGustavo F. Padovan
519ecf61bdbSAndrei Emeltchenko if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
52099f4808dSGustavo F. Padovan opt |= L2CAP_LM_RELIABLE;
52199f4808dSGustavo F. Padovan
52299f4808dSGustavo F. Padovan if (put_user(opt, (u32 __user *) optval))
52399f4808dSGustavo F. Padovan err = -EFAULT;
5247d513e92SMarcel Holtmann
52599f4808dSGustavo F. Padovan break;
52699f4808dSGustavo F. Padovan
52799f4808dSGustavo F. Padovan case L2CAP_CONNINFO:
52899f4808dSGustavo F. Padovan if (sk->sk_state != BT_CONNECTED &&
52999f4808dSGustavo F. Padovan !(sk->sk_state == BT_CONNECT2 &&
530c5daa683SGustavo Padovan test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))) {
53199f4808dSGustavo F. Padovan err = -ENOTCONN;
53299f4808dSGustavo F. Padovan break;
53399f4808dSGustavo F. Padovan }
53499f4808dSGustavo F. Padovan
5358d03e971SFilip Palian memset(&cinfo, 0, sizeof(cinfo));
5368c1d787bSGustavo F. Padovan cinfo.hci_handle = chan->conn->hcon->handle;
5378c1d787bSGustavo F. Padovan memcpy(cinfo.dev_class, chan->conn->hcon->dev_class, 3);
53899f4808dSGustavo F. Padovan
5394eb706b1SNathan Chancellor len = min(len, sizeof(cinfo));
54099f4808dSGustavo F. Padovan if (copy_to_user(optval, (char *) &cinfo, len))
54199f4808dSGustavo F. Padovan err = -EFAULT;
54299f4808dSGustavo F. Padovan
54399f4808dSGustavo F. Padovan break;
54499f4808dSGustavo F. Padovan
54599f4808dSGustavo F. Padovan default:
54699f4808dSGustavo F. Padovan err = -ENOPROTOOPT;
54799f4808dSGustavo F. Padovan break;
54899f4808dSGustavo F. Padovan }
54999f4808dSGustavo F. Padovan
55099f4808dSGustavo F. Padovan release_sock(sk);
55199f4808dSGustavo F. Padovan return err;
55299f4808dSGustavo F. Padovan }
55399f4808dSGustavo F. Padovan
l2cap_sock_getsockopt(struct socket * sock,int level,int optname,char __user * optval,int __user * optlen)5542d792818SGustavo Padovan static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname,
5552d792818SGustavo Padovan char __user *optval, int __user *optlen)
55699f4808dSGustavo F. Padovan {
55799f4808dSGustavo F. Padovan struct sock *sk = sock->sk;
5584343478fSGustavo F. Padovan struct l2cap_chan *chan = l2cap_pi(sk)->chan;
55999f4808dSGustavo F. Padovan struct bt_security sec;
56014b12d0bSJaikumar Ganesh struct bt_power pwr;
561eab2404bSLuiz Augusto von Dentz u32 phys;
5623ee7b7cdSLuiz Augusto von Dentz int len, mode, err = 0;
56399f4808dSGustavo F. Padovan
56499f4808dSGustavo F. Padovan BT_DBG("sk %p", sk);
56599f4808dSGustavo F. Padovan
56699f4808dSGustavo F. Padovan if (level == SOL_L2CAP)
56799f4808dSGustavo F. Padovan return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
56899f4808dSGustavo F. Padovan
56999f4808dSGustavo F. Padovan if (level != SOL_BLUETOOTH)
57099f4808dSGustavo F. Padovan return -ENOPROTOOPT;
57199f4808dSGustavo F. Padovan
57299f4808dSGustavo F. Padovan if (get_user(len, optlen))
57399f4808dSGustavo F. Padovan return -EFAULT;
57499f4808dSGustavo F. Padovan
57599f4808dSGustavo F. Padovan lock_sock(sk);
57699f4808dSGustavo F. Padovan
57799f4808dSGustavo F. Padovan switch (optname) {
57899f4808dSGustavo F. Padovan case BT_SECURITY:
579715ec005SGustavo F. Padovan if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
580e0c888adSJohan Hedberg chan->chan_type != L2CAP_CHAN_FIXED &&
581715ec005SGustavo F. Padovan chan->chan_type != L2CAP_CHAN_RAW) {
58299f4808dSGustavo F. Padovan err = -EINVAL;
58399f4808dSGustavo F. Padovan break;
58499f4808dSGustavo F. Padovan }
58599f4808dSGustavo F. Padovan
5868f360119SVinicius Costa Gomes memset(&sec, 0, sizeof(sec));
58785e34368SAndrei Emeltchenko if (chan->conn) {
588c6585a4dSGustavo Padovan sec.level = chan->conn->hcon->sec_level;
58999f4808dSGustavo F. Padovan
5908f360119SVinicius Costa Gomes if (sk->sk_state == BT_CONNECTED)
5918f360119SVinicius Costa Gomes sec.key_size = chan->conn->hcon->enc_key_size;
59285e34368SAndrei Emeltchenko } else {
59385e34368SAndrei Emeltchenko sec.level = chan->sec_level;
59485e34368SAndrei Emeltchenko }
5958f360119SVinicius Costa Gomes
59699f4808dSGustavo F. Padovan len = min_t(unsigned int, len, sizeof(sec));
59799f4808dSGustavo F. Padovan if (copy_to_user(optval, (char *) &sec, len))
59899f4808dSGustavo F. Padovan err = -EFAULT;
59999f4808dSGustavo F. Padovan
60099f4808dSGustavo F. Padovan break;
60199f4808dSGustavo F. Padovan
60299f4808dSGustavo F. Padovan case BT_DEFER_SETUP:
60399f4808dSGustavo F. Padovan if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
60499f4808dSGustavo F. Padovan err = -EINVAL;
60599f4808dSGustavo F. Padovan break;
60699f4808dSGustavo F. Padovan }
60799f4808dSGustavo F. Padovan
608c5daa683SGustavo Padovan if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
609c5daa683SGustavo Padovan (u32 __user *) optval))
61099f4808dSGustavo F. Padovan err = -EFAULT;
61199f4808dSGustavo F. Padovan
61299f4808dSGustavo F. Padovan break;
61399f4808dSGustavo F. Padovan
61499f4808dSGustavo F. Padovan case BT_FLUSHABLE:
615d57b0e8bSAndrei Emeltchenko if (put_user(test_bit(FLAG_FLUSHABLE, &chan->flags),
616d57b0e8bSAndrei Emeltchenko (u32 __user *) optval))
61799f4808dSGustavo F. Padovan err = -EFAULT;
61899f4808dSGustavo F. Padovan
61999f4808dSGustavo F. Padovan break;
62099f4808dSGustavo F. Padovan
62114b12d0bSJaikumar Ganesh case BT_POWER:
62214b12d0bSJaikumar Ganesh if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
62314b12d0bSJaikumar Ganesh && sk->sk_type != SOCK_RAW) {
62414b12d0bSJaikumar Ganesh err = -EINVAL;
62514b12d0bSJaikumar Ganesh break;
62614b12d0bSJaikumar Ganesh }
62714b12d0bSJaikumar Ganesh
62815770b1aSAndrei Emeltchenko pwr.force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
62914b12d0bSJaikumar Ganesh
63014b12d0bSJaikumar Ganesh len = min_t(unsigned int, len, sizeof(pwr));
63114b12d0bSJaikumar Ganesh if (copy_to_user(optval, (char *) &pwr, len))
63214b12d0bSJaikumar Ganesh err = -EFAULT;
63314b12d0bSJaikumar Ganesh
63414b12d0bSJaikumar Ganesh break;
63514b12d0bSJaikumar Ganesh
6362ea66482SMat Martineau case BT_CHANNEL_POLICY:
6372ea66482SMat Martineau if (put_user(chan->chan_policy, (u32 __user *) optval))
6382ea66482SMat Martineau err = -EFAULT;
6392ea66482SMat Martineau break;
6402ea66482SMat Martineau
6411f435424SJohan Hedberg case BT_SNDMTU:
6421f435424SJohan Hedberg if (!bdaddr_type_is_le(chan->src_type)) {
6431f435424SJohan Hedberg err = -EINVAL;
6441f435424SJohan Hedberg break;
6451f435424SJohan Hedberg }
6461f435424SJohan Hedberg
6471f435424SJohan Hedberg if (sk->sk_state != BT_CONNECTED) {
6481f435424SJohan Hedberg err = -ENOTCONN;
6491f435424SJohan Hedberg break;
6501f435424SJohan Hedberg }
6511f435424SJohan Hedberg
6521f435424SJohan Hedberg if (put_user(chan->omtu, (u16 __user *) optval))
6531f435424SJohan Hedberg err = -EFAULT;
6541f435424SJohan Hedberg break;
6551f435424SJohan Hedberg
6561f435424SJohan Hedberg case BT_RCVMTU:
6571f435424SJohan Hedberg if (!bdaddr_type_is_le(chan->src_type)) {
6581f435424SJohan Hedberg err = -EINVAL;
6591f435424SJohan Hedberg break;
6601f435424SJohan Hedberg }
6611f435424SJohan Hedberg
6621f435424SJohan Hedberg if (put_user(chan->imtu, (u16 __user *) optval))
6631f435424SJohan Hedberg err = -EFAULT;
6641f435424SJohan Hedberg break;
6651f435424SJohan Hedberg
666eab2404bSLuiz Augusto von Dentz case BT_PHY:
667a2a8b0b4SLuiz Augusto von Dentz if (sk->sk_state != BT_CONNECTED) {
668eab2404bSLuiz Augusto von Dentz err = -ENOTCONN;
669eab2404bSLuiz Augusto von Dentz break;
670eab2404bSLuiz Augusto von Dentz }
671eab2404bSLuiz Augusto von Dentz
672eab2404bSLuiz Augusto von Dentz phys = hci_conn_get_phy(chan->conn->hcon);
673eab2404bSLuiz Augusto von Dentz
674eab2404bSLuiz Augusto von Dentz if (put_user(phys, (u32 __user *) optval))
675eab2404bSLuiz Augusto von Dentz err = -EFAULT;
676eab2404bSLuiz Augusto von Dentz break;
677eab2404bSLuiz Augusto von Dentz
6783ee7b7cdSLuiz Augusto von Dentz case BT_MODE:
6793ee7b7cdSLuiz Augusto von Dentz if (!enable_ecred) {
6803ee7b7cdSLuiz Augusto von Dentz err = -ENOPROTOOPT;
6813ee7b7cdSLuiz Augusto von Dentz break;
6823ee7b7cdSLuiz Augusto von Dentz }
6833ee7b7cdSLuiz Augusto von Dentz
6843ee7b7cdSLuiz Augusto von Dentz if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
6853ee7b7cdSLuiz Augusto von Dentz err = -EINVAL;
6863ee7b7cdSLuiz Augusto von Dentz break;
6873ee7b7cdSLuiz Augusto von Dentz }
6883ee7b7cdSLuiz Augusto von Dentz
6893ee7b7cdSLuiz Augusto von Dentz mode = l2cap_get_mode(chan);
6903ee7b7cdSLuiz Augusto von Dentz if (mode < 0) {
6913ee7b7cdSLuiz Augusto von Dentz err = mode;
6923ee7b7cdSLuiz Augusto von Dentz break;
6933ee7b7cdSLuiz Augusto von Dentz }
6943ee7b7cdSLuiz Augusto von Dentz
6953ee7b7cdSLuiz Augusto von Dentz if (put_user(mode, (u8 __user *) optval))
6963ee7b7cdSLuiz Augusto von Dentz err = -EFAULT;
6973ee7b7cdSLuiz Augusto von Dentz break;
6983ee7b7cdSLuiz Augusto von Dentz
69999f4808dSGustavo F. Padovan default:
70099f4808dSGustavo F. Padovan err = -ENOPROTOOPT;
70199f4808dSGustavo F. Padovan break;
70299f4808dSGustavo F. Padovan }
70399f4808dSGustavo F. Padovan
70499f4808dSGustavo F. Padovan release_sock(sk);
70599f4808dSGustavo F. Padovan return err;
70699f4808dSGustavo F. Padovan }
70799f4808dSGustavo F. Padovan
l2cap_valid_mtu(struct l2cap_chan * chan,u16 mtu)708682877c3SAndre Guedes static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu)
709682877c3SAndre Guedes {
710682877c3SAndre Guedes switch (chan->scid) {
711073d1cf3SJohan Hedberg case L2CAP_CID_ATT:
712aa91d540SFedor Pchelkin if (mtu && mtu < L2CAP_LE_MIN_MTU)
713682877c3SAndre Guedes return false;
714682877c3SAndre Guedes break;
715682877c3SAndre Guedes
716682877c3SAndre Guedes default:
717aa91d540SFedor Pchelkin if (mtu && mtu < L2CAP_DEFAULT_MIN_MTU)
718682877c3SAndre Guedes return false;
719682877c3SAndre Guedes }
720682877c3SAndre Guedes
721682877c3SAndre Guedes return true;
722682877c3SAndre Guedes }
723682877c3SAndre Guedes
l2cap_sock_setsockopt_old(struct socket * sock,int optname,sockptr_t optval,unsigned int optlen)7242d792818SGustavo Padovan static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
725a7b75c5aSChristoph Hellwig sockptr_t optval, unsigned int optlen)
72633575df7SGustavo F. Padovan {
72733575df7SGustavo F. Padovan struct sock *sk = sock->sk;
728b4450035SGustavo F. Padovan struct l2cap_chan *chan = l2cap_pi(sk)->chan;
72933575df7SGustavo F. Padovan struct l2cap_options opts;
73028234f8aSLuiz Augusto von Dentz int err = 0;
73133575df7SGustavo F. Padovan u32 opt;
73233575df7SGustavo F. Padovan
73333575df7SGustavo F. Padovan BT_DBG("sk %p", sk);
73433575df7SGustavo F. Padovan
73533575df7SGustavo F. Padovan lock_sock(sk);
73633575df7SGustavo F. Padovan
73733575df7SGustavo F. Padovan switch (optname) {
73833575df7SGustavo F. Padovan case L2CAP_OPTIONS:
73964b4f8dcSJohan Hedberg if (bdaddr_type_is_le(chan->src_type)) {
74064b4f8dcSJohan Hedberg err = -EINVAL;
74164b4f8dcSJohan Hedberg break;
74264b4f8dcSJohan Hedberg }
74364b4f8dcSJohan Hedberg
74433575df7SGustavo F. Padovan if (sk->sk_state == BT_CONNECTED) {
74533575df7SGustavo F. Padovan err = -EINVAL;
74633575df7SGustavo F. Padovan break;
74733575df7SGustavo F. Padovan }
74833575df7SGustavo F. Padovan
7490c1bc5c6SGustavo F. Padovan opts.imtu = chan->imtu;
7500c1bc5c6SGustavo F. Padovan opts.omtu = chan->omtu;
7510c1bc5c6SGustavo F. Padovan opts.flush_to = chan->flush_to;
7520c1bc5c6SGustavo F. Padovan opts.mode = chan->mode;
75347d1ec61SGustavo F. Padovan opts.fcs = chan->fcs;
75447d1ec61SGustavo F. Padovan opts.max_tx = chan->max_tx;
7556327eb98SAndrei Emeltchenko opts.txwin_size = chan->tx_win;
75633575df7SGustavo F. Padovan
75728234f8aSLuiz Augusto von Dentz err = bt_copy_from_sockptr(&opts, sizeof(opts), optval, optlen);
75828234f8aSLuiz Augusto von Dentz if (err)
75933575df7SGustavo F. Padovan break;
76033575df7SGustavo F. Padovan
7616327eb98SAndrei Emeltchenko if (opts.txwin_size > L2CAP_DEFAULT_EXT_WINDOW) {
76233575df7SGustavo F. Padovan err = -EINVAL;
76333575df7SGustavo F. Padovan break;
76433575df7SGustavo F. Padovan }
76533575df7SGustavo F. Padovan
766682877c3SAndre Guedes if (!l2cap_valid_mtu(chan, opts.imtu)) {
767682877c3SAndre Guedes err = -EINVAL;
768682877c3SAndre Guedes break;
769682877c3SAndre Guedes }
770682877c3SAndre Guedes
771b86b0b15SLuiz Augusto von Dentz /* Only BR/EDR modes are supported here */
772b86b0b15SLuiz Augusto von Dentz switch (opts.mode) {
77333575df7SGustavo F. Padovan case L2CAP_MODE_BASIC:
774c1360a1cSGustavo F. Padovan clear_bit(CONF_STATE2_DEVICE, &chan->conf_state);
77533575df7SGustavo F. Padovan break;
77633575df7SGustavo F. Padovan case L2CAP_MODE_ERTM:
77733575df7SGustavo F. Padovan case L2CAP_MODE_STREAMING:
77833575df7SGustavo F. Padovan if (!disable_ertm)
77933575df7SGustavo F. Padovan break;
78019186c7bSGustavo A. R. Silva fallthrough;
78133575df7SGustavo F. Padovan default:
78233575df7SGustavo F. Padovan err = -EINVAL;
78333575df7SGustavo F. Padovan break;
78433575df7SGustavo F. Padovan }
78533575df7SGustavo F. Padovan
786b86b0b15SLuiz Augusto von Dentz if (err < 0)
787b86b0b15SLuiz Augusto von Dentz break;
788b86b0b15SLuiz Augusto von Dentz
789b86b0b15SLuiz Augusto von Dentz chan->mode = opts.mode;
790b86b0b15SLuiz Augusto von Dentz
79115f02b91SLuiz Augusto von Dentz BT_DBG("mode 0x%2.2x", chan->mode);
79215f02b91SLuiz Augusto von Dentz
7930c1bc5c6SGustavo F. Padovan chan->imtu = opts.imtu;
7940c1bc5c6SGustavo F. Padovan chan->omtu = opts.omtu;
79547d1ec61SGustavo F. Padovan chan->fcs = opts.fcs;
79647d1ec61SGustavo F. Padovan chan->max_tx = opts.max_tx;
7976327eb98SAndrei Emeltchenko chan->tx_win = opts.txwin_size;
79812d59781SAndrei Emeltchenko chan->flush_to = opts.flush_to;
79933575df7SGustavo F. Padovan break;
80033575df7SGustavo F. Padovan
80133575df7SGustavo F. Padovan case L2CAP_LM:
80228234f8aSLuiz Augusto von Dentz err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
80328234f8aSLuiz Augusto von Dentz if (err)
80433575df7SGustavo F. Padovan break;
80533575df7SGustavo F. Padovan
8067d513e92SMarcel Holtmann if (opt & L2CAP_LM_FIPS) {
8077d513e92SMarcel Holtmann err = -EINVAL;
8087d513e92SMarcel Holtmann break;
8097d513e92SMarcel Holtmann }
8107d513e92SMarcel Holtmann
81133575df7SGustavo F. Padovan if (opt & L2CAP_LM_AUTH)
8124343478fSGustavo F. Padovan chan->sec_level = BT_SECURITY_LOW;
81333575df7SGustavo F. Padovan if (opt & L2CAP_LM_ENCRYPT)
8144343478fSGustavo F. Padovan chan->sec_level = BT_SECURITY_MEDIUM;
81533575df7SGustavo F. Padovan if (opt & L2CAP_LM_SECURE)
8164343478fSGustavo F. Padovan chan->sec_level = BT_SECURITY_HIGH;
81733575df7SGustavo F. Padovan
81843bd0f32SAndrei Emeltchenko if (opt & L2CAP_LM_MASTER)
81943bd0f32SAndrei Emeltchenko set_bit(FLAG_ROLE_SWITCH, &chan->flags);
82043bd0f32SAndrei Emeltchenko else
82143bd0f32SAndrei Emeltchenko clear_bit(FLAG_ROLE_SWITCH, &chan->flags);
822ecf61bdbSAndrei Emeltchenko
823ecf61bdbSAndrei Emeltchenko if (opt & L2CAP_LM_RELIABLE)
824ecf61bdbSAndrei Emeltchenko set_bit(FLAG_FORCE_RELIABLE, &chan->flags);
825ecf61bdbSAndrei Emeltchenko else
826ecf61bdbSAndrei Emeltchenko clear_bit(FLAG_FORCE_RELIABLE, &chan->flags);
82733575df7SGustavo F. Padovan break;
82833575df7SGustavo F. Padovan
82933575df7SGustavo F. Padovan default:
83033575df7SGustavo F. Padovan err = -ENOPROTOOPT;
83133575df7SGustavo F. Padovan break;
83233575df7SGustavo F. Padovan }
83333575df7SGustavo F. Padovan
83433575df7SGustavo F. Padovan release_sock(sk);
83533575df7SGustavo F. Padovan return err;
83633575df7SGustavo F. Padovan }
83733575df7SGustavo F. Padovan
l2cap_set_mode(struct l2cap_chan * chan,u8 mode)8383ee7b7cdSLuiz Augusto von Dentz static int l2cap_set_mode(struct l2cap_chan *chan, u8 mode)
8393ee7b7cdSLuiz Augusto von Dentz {
8403ee7b7cdSLuiz Augusto von Dentz switch (mode) {
8413ee7b7cdSLuiz Augusto von Dentz case BT_MODE_BASIC:
8423ee7b7cdSLuiz Augusto von Dentz if (bdaddr_type_is_le(chan->src_type))
8433ee7b7cdSLuiz Augusto von Dentz return -EINVAL;
8443ee7b7cdSLuiz Augusto von Dentz mode = L2CAP_MODE_BASIC;
8453ee7b7cdSLuiz Augusto von Dentz clear_bit(CONF_STATE2_DEVICE, &chan->conf_state);
8463ee7b7cdSLuiz Augusto von Dentz break;
8473ee7b7cdSLuiz Augusto von Dentz case BT_MODE_ERTM:
8483ee7b7cdSLuiz Augusto von Dentz if (!disable_ertm || bdaddr_type_is_le(chan->src_type))
8493ee7b7cdSLuiz Augusto von Dentz return -EINVAL;
8503ee7b7cdSLuiz Augusto von Dentz mode = L2CAP_MODE_ERTM;
8513ee7b7cdSLuiz Augusto von Dentz break;
8523ee7b7cdSLuiz Augusto von Dentz case BT_MODE_STREAMING:
8533ee7b7cdSLuiz Augusto von Dentz if (!disable_ertm || bdaddr_type_is_le(chan->src_type))
8543ee7b7cdSLuiz Augusto von Dentz return -EINVAL;
8553ee7b7cdSLuiz Augusto von Dentz mode = L2CAP_MODE_STREAMING;
8563ee7b7cdSLuiz Augusto von Dentz break;
8573ee7b7cdSLuiz Augusto von Dentz case BT_MODE_LE_FLOWCTL:
8583ee7b7cdSLuiz Augusto von Dentz if (!bdaddr_type_is_le(chan->src_type))
8593ee7b7cdSLuiz Augusto von Dentz return -EINVAL;
8603ee7b7cdSLuiz Augusto von Dentz mode = L2CAP_MODE_LE_FLOWCTL;
8613ee7b7cdSLuiz Augusto von Dentz break;
8623ee7b7cdSLuiz Augusto von Dentz case BT_MODE_EXT_FLOWCTL:
8633ee7b7cdSLuiz Augusto von Dentz /* TODO: Add support for ECRED PDUs to BR/EDR */
8643ee7b7cdSLuiz Augusto von Dentz if (!bdaddr_type_is_le(chan->src_type))
8653ee7b7cdSLuiz Augusto von Dentz return -EINVAL;
8663ee7b7cdSLuiz Augusto von Dentz mode = L2CAP_MODE_EXT_FLOWCTL;
8673ee7b7cdSLuiz Augusto von Dentz break;
8683ee7b7cdSLuiz Augusto von Dentz default:
8693ee7b7cdSLuiz Augusto von Dentz return -EINVAL;
8703ee7b7cdSLuiz Augusto von Dentz }
8713ee7b7cdSLuiz Augusto von Dentz
8723ee7b7cdSLuiz Augusto von Dentz chan->mode = mode;
8733ee7b7cdSLuiz Augusto von Dentz
8743ee7b7cdSLuiz Augusto von Dentz return 0;
8753ee7b7cdSLuiz Augusto von Dentz }
8763ee7b7cdSLuiz Augusto von Dentz
l2cap_sock_setsockopt(struct socket * sock,int level,int optname,sockptr_t optval,unsigned int optlen)8772d792818SGustavo Padovan static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
878a7b75c5aSChristoph Hellwig sockptr_t optval, unsigned int optlen)
87933575df7SGustavo F. Padovan {
88033575df7SGustavo F. Padovan struct sock *sk = sock->sk;
8814343478fSGustavo F. Padovan struct l2cap_chan *chan = l2cap_pi(sk)->chan;
88233575df7SGustavo F. Padovan struct bt_security sec;
88314b12d0bSJaikumar Ganesh struct bt_power pwr;
884f1cb9af5SVinicius Costa Gomes struct l2cap_conn *conn;
88528234f8aSLuiz Augusto von Dentz int err = 0;
88633575df7SGustavo F. Padovan u32 opt;
8872b70d4f9SDan Carpenter u16 mtu;
8882b70d4f9SDan Carpenter u8 mode;
88933575df7SGustavo F. Padovan
89033575df7SGustavo F. Padovan BT_DBG("sk %p", sk);
89133575df7SGustavo F. Padovan
89233575df7SGustavo F. Padovan if (level == SOL_L2CAP)
89333575df7SGustavo F. Padovan return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
89433575df7SGustavo F. Padovan
89533575df7SGustavo F. Padovan if (level != SOL_BLUETOOTH)
89633575df7SGustavo F. Padovan return -ENOPROTOOPT;
89733575df7SGustavo F. Padovan
89833575df7SGustavo F. Padovan lock_sock(sk);
89933575df7SGustavo F. Padovan
90033575df7SGustavo F. Padovan switch (optname) {
90133575df7SGustavo F. Padovan case BT_SECURITY:
902715ec005SGustavo F. Padovan if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
903e0c888adSJohan Hedberg chan->chan_type != L2CAP_CHAN_FIXED &&
904715ec005SGustavo F. Padovan chan->chan_type != L2CAP_CHAN_RAW) {
90533575df7SGustavo F. Padovan err = -EINVAL;
90633575df7SGustavo F. Padovan break;
90733575df7SGustavo F. Padovan }
90833575df7SGustavo F. Padovan
90933575df7SGustavo F. Padovan sec.level = BT_SECURITY_LOW;
91033575df7SGustavo F. Padovan
91128234f8aSLuiz Augusto von Dentz err = bt_copy_from_sockptr(&sec, sizeof(sec), optval, optlen);
91228234f8aSLuiz Augusto von Dentz if (err)
91333575df7SGustavo F. Padovan break;
91433575df7SGustavo F. Padovan
91533575df7SGustavo F. Padovan if (sec.level < BT_SECURITY_LOW ||
916a164cee1SPatrik Flykt sec.level > BT_SECURITY_FIPS) {
91733575df7SGustavo F. Padovan err = -EINVAL;
91833575df7SGustavo F. Padovan break;
91933575df7SGustavo F. Padovan }
92033575df7SGustavo F. Padovan
9214343478fSGustavo F. Padovan chan->sec_level = sec.level;
922f1cb9af5SVinicius Costa Gomes
9230bee1d60SGustavo F. Padovan if (!chan->conn)
9240bee1d60SGustavo F. Padovan break;
9250bee1d60SGustavo F. Padovan
926f1cb9af5SVinicius Costa Gomes conn = chan->conn;
9270bee1d60SGustavo F. Padovan
9280bee1d60SGustavo F. Padovan /* change security for LE channels */
929073d1cf3SJohan Hedberg if (chan->scid == L2CAP_CID_ATT) {
930bbb69b37SFugang Duan if (smp_conn_security(conn->hcon, sec.level)) {
931bbb69b37SFugang Duan err = -EINVAL;
932f1cb9af5SVinicius Costa Gomes break;
933bbb69b37SFugang Duan }
934bbb69b37SFugang Duan
935d52deb17SJohan Hedberg set_bit(FLAG_PENDING_SECURITY, &chan->flags);
936f1cb9af5SVinicius Costa Gomes sk->sk_state = BT_CONFIG;
9373542b854SGustavo F. Padovan chan->state = BT_CONFIG;
9380bee1d60SGustavo F. Padovan
939a7d7723aSGustavo Padovan /* or for ACL link */
940a7d7723aSGustavo Padovan } else if ((sk->sk_state == BT_CONNECT2 &&
941c5daa683SGustavo Padovan test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) ||
942a7d7723aSGustavo Padovan sk->sk_state == BT_CONNECTED) {
943e7cafc45SJohan Hedberg if (!l2cap_chan_check_security(chan, true))
944c5daa683SGustavo Padovan set_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
945a7d7723aSGustavo Padovan else
946a7d7723aSGustavo Padovan sk->sk_state_change(sk);
9470bee1d60SGustavo F. Padovan } else {
9480bee1d60SGustavo F. Padovan err = -EINVAL;
949f1cb9af5SVinicius Costa Gomes }
95033575df7SGustavo F. Padovan break;
95133575df7SGustavo F. Padovan
95233575df7SGustavo F. Padovan case BT_DEFER_SETUP:
95333575df7SGustavo F. Padovan if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
95433575df7SGustavo F. Padovan err = -EINVAL;
95533575df7SGustavo F. Padovan break;
95633575df7SGustavo F. Padovan }
95733575df7SGustavo F. Padovan
95828234f8aSLuiz Augusto von Dentz err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
95928234f8aSLuiz Augusto von Dentz if (err)
96033575df7SGustavo F. Padovan break;
96133575df7SGustavo F. Padovan
962bdc25783SMarcel Holtmann if (opt) {
963c5daa683SGustavo Padovan set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
964bdc25783SMarcel Holtmann set_bit(FLAG_DEFER_SETUP, &chan->flags);
965bdc25783SMarcel Holtmann } else {
966c5daa683SGustavo Padovan clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
967bdc25783SMarcel Holtmann clear_bit(FLAG_DEFER_SETUP, &chan->flags);
968bdc25783SMarcel Holtmann }
96933575df7SGustavo F. Padovan break;
97033575df7SGustavo F. Padovan
97133575df7SGustavo F. Padovan case BT_FLUSHABLE:
97228234f8aSLuiz Augusto von Dentz err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
97328234f8aSLuiz Augusto von Dentz if (err)
97433575df7SGustavo F. Padovan break;
97533575df7SGustavo F. Padovan
97633575df7SGustavo F. Padovan if (opt > BT_FLUSHABLE_ON) {
97733575df7SGustavo F. Padovan err = -EINVAL;
97833575df7SGustavo F. Padovan break;
97933575df7SGustavo F. Padovan }
98033575df7SGustavo F. Padovan
98133575df7SGustavo F. Padovan if (opt == BT_FLUSHABLE_OFF) {
982c1f23a2bSJohannes Berg conn = chan->conn;
98325985edcSLucas De Marchi /* proceed further only when we have l2cap_conn and
98433575df7SGustavo F. Padovan No Flush support in the LM */
98533575df7SGustavo F. Padovan if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) {
98633575df7SGustavo F. Padovan err = -EINVAL;
98733575df7SGustavo F. Padovan break;
98833575df7SGustavo F. Padovan }
98933575df7SGustavo F. Padovan }
99033575df7SGustavo F. Padovan
991d57b0e8bSAndrei Emeltchenko if (opt)
992d57b0e8bSAndrei Emeltchenko set_bit(FLAG_FLUSHABLE, &chan->flags);
993d57b0e8bSAndrei Emeltchenko else
994d57b0e8bSAndrei Emeltchenko clear_bit(FLAG_FLUSHABLE, &chan->flags);
99533575df7SGustavo F. Padovan break;
99633575df7SGustavo F. Padovan
99714b12d0bSJaikumar Ganesh case BT_POWER:
99814b12d0bSJaikumar Ganesh if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
99914b12d0bSJaikumar Ganesh chan->chan_type != L2CAP_CHAN_RAW) {
100014b12d0bSJaikumar Ganesh err = -EINVAL;
100114b12d0bSJaikumar Ganesh break;
100214b12d0bSJaikumar Ganesh }
100314b12d0bSJaikumar Ganesh
100414b12d0bSJaikumar Ganesh pwr.force_active = BT_POWER_FORCE_ACTIVE_ON;
100514b12d0bSJaikumar Ganesh
100628234f8aSLuiz Augusto von Dentz err = bt_copy_from_sockptr(&pwr, sizeof(pwr), optval, optlen);
100728234f8aSLuiz Augusto von Dentz if (err)
100814b12d0bSJaikumar Ganesh break;
100915770b1aSAndrei Emeltchenko
101015770b1aSAndrei Emeltchenko if (pwr.force_active)
101115770b1aSAndrei Emeltchenko set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
101215770b1aSAndrei Emeltchenko else
101315770b1aSAndrei Emeltchenko clear_bit(FLAG_FORCE_ACTIVE, &chan->flags);
101414b12d0bSJaikumar Ganesh break;
101514b12d0bSJaikumar Ganesh
10162ea66482SMat Martineau case BT_CHANNEL_POLICY:
101728234f8aSLuiz Augusto von Dentz err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
101828234f8aSLuiz Augusto von Dentz if (err)
10192ea66482SMat Martineau break;
10202ea66482SMat Martineau
10212ea66482SMat Martineau err = -EOPNOTSUPP;
10222ea66482SMat Martineau break;
102333575df7SGustavo F. Padovan
10241f435424SJohan Hedberg case BT_SNDMTU:
10251f435424SJohan Hedberg if (!bdaddr_type_is_le(chan->src_type)) {
10261f435424SJohan Hedberg err = -EINVAL;
10271f435424SJohan Hedberg break;
10281f435424SJohan Hedberg }
10291f435424SJohan Hedberg
10301f435424SJohan Hedberg /* Setting is not supported as it's the remote side that
10311f435424SJohan Hedberg * decides this.
10321f435424SJohan Hedberg */
10331f435424SJohan Hedberg err = -EPERM;
10341f435424SJohan Hedberg break;
10351f435424SJohan Hedberg
10361f435424SJohan Hedberg case BT_RCVMTU:
10371f435424SJohan Hedberg if (!bdaddr_type_is_le(chan->src_type)) {
10381f435424SJohan Hedberg err = -EINVAL;
10391f435424SJohan Hedberg break;
10401f435424SJohan Hedberg }
10411f435424SJohan Hedberg
104215f02b91SLuiz Augusto von Dentz if (chan->mode == L2CAP_MODE_LE_FLOWCTL &&
104315f02b91SLuiz Augusto von Dentz sk->sk_state == BT_CONNECTED) {
10441f435424SJohan Hedberg err = -EISCONN;
10451f435424SJohan Hedberg break;
10461f435424SJohan Hedberg }
10471f435424SJohan Hedberg
104828234f8aSLuiz Augusto von Dentz err = bt_copy_from_sockptr(&mtu, sizeof(mtu), optval, optlen);
104928234f8aSLuiz Augusto von Dentz if (err)
10501f435424SJohan Hedberg break;
10511f435424SJohan Hedberg
105215f02b91SLuiz Augusto von Dentz if (chan->mode == L2CAP_MODE_EXT_FLOWCTL &&
105315f02b91SLuiz Augusto von Dentz sk->sk_state == BT_CONNECTED)
10542b70d4f9SDan Carpenter err = l2cap_chan_reconfigure(chan, mtu);
105515f02b91SLuiz Augusto von Dentz else
10562b70d4f9SDan Carpenter chan->imtu = mtu;
105715f02b91SLuiz Augusto von Dentz
10581f435424SJohan Hedberg break;
10591f435424SJohan Hedberg
10603ee7b7cdSLuiz Augusto von Dentz case BT_MODE:
10613ee7b7cdSLuiz Augusto von Dentz if (!enable_ecred) {
10623ee7b7cdSLuiz Augusto von Dentz err = -ENOPROTOOPT;
10633ee7b7cdSLuiz Augusto von Dentz break;
10643ee7b7cdSLuiz Augusto von Dentz }
10653ee7b7cdSLuiz Augusto von Dentz
10663ee7b7cdSLuiz Augusto von Dentz BT_DBG("sk->sk_state %u", sk->sk_state);
10673ee7b7cdSLuiz Augusto von Dentz
10683ee7b7cdSLuiz Augusto von Dentz if (sk->sk_state != BT_BOUND) {
10693ee7b7cdSLuiz Augusto von Dentz err = -EINVAL;
10703ee7b7cdSLuiz Augusto von Dentz break;
10713ee7b7cdSLuiz Augusto von Dentz }
10723ee7b7cdSLuiz Augusto von Dentz
10733ee7b7cdSLuiz Augusto von Dentz if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
10743ee7b7cdSLuiz Augusto von Dentz err = -EINVAL;
10753ee7b7cdSLuiz Augusto von Dentz break;
10763ee7b7cdSLuiz Augusto von Dentz }
10773ee7b7cdSLuiz Augusto von Dentz
107828234f8aSLuiz Augusto von Dentz err = bt_copy_from_sockptr(&mode, sizeof(mode), optval, optlen);
107928234f8aSLuiz Augusto von Dentz if (err)
10803ee7b7cdSLuiz Augusto von Dentz break;
10813ee7b7cdSLuiz Augusto von Dentz
10822b70d4f9SDan Carpenter BT_DBG("mode %u", mode);
10833ee7b7cdSLuiz Augusto von Dentz
10842b70d4f9SDan Carpenter err = l2cap_set_mode(chan, mode);
10853ee7b7cdSLuiz Augusto von Dentz if (err)
10863ee7b7cdSLuiz Augusto von Dentz break;
10873ee7b7cdSLuiz Augusto von Dentz
10883ee7b7cdSLuiz Augusto von Dentz BT_DBG("mode 0x%2.2x", chan->mode);
10893ee7b7cdSLuiz Augusto von Dentz
10903ee7b7cdSLuiz Augusto von Dentz break;
10913ee7b7cdSLuiz Augusto von Dentz
109233575df7SGustavo F. Padovan default:
109333575df7SGustavo F. Padovan err = -ENOPROTOOPT;
109433575df7SGustavo F. Padovan break;
109533575df7SGustavo F. Padovan }
109633575df7SGustavo F. Padovan
109733575df7SGustavo F. Padovan release_sock(sk);
109833575df7SGustavo F. Padovan return err;
109933575df7SGustavo F. Padovan }
110033575df7SGustavo F. Padovan
l2cap_sock_sendmsg(struct socket * sock,struct msghdr * msg,size_t len)11011b784140SYing Xue static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg,
11021b784140SYing Xue size_t len)
1103fd83ccdbSGustavo F. Padovan {
1104fd83ccdbSGustavo F. Padovan struct sock *sk = sock->sk;
11050c1bc5c6SGustavo F. Padovan struct l2cap_chan *chan = l2cap_pi(sk)->chan;
1106fd83ccdbSGustavo F. Padovan int err;
1107fd83ccdbSGustavo F. Padovan
1108fd83ccdbSGustavo F. Padovan BT_DBG("sock %p, sk %p", sock, sk);
1109fd83ccdbSGustavo F. Padovan
1110fd83ccdbSGustavo F. Padovan err = sock_error(sk);
1111fd83ccdbSGustavo F. Padovan if (err)
1112fd83ccdbSGustavo F. Padovan return err;
1113fd83ccdbSGustavo F. Padovan
1114fd83ccdbSGustavo F. Padovan if (msg->msg_flags & MSG_OOB)
1115fd83ccdbSGustavo F. Padovan return -EOPNOTSUPP;
1116fd83ccdbSGustavo F. Padovan
1117a6a5568cSMat Martineau if (sk->sk_state != BT_CONNECTED)
11189a91a04aSGustavo F. Padovan return -ENOTCONN;
1119fd83ccdbSGustavo F. Padovan
1120e793dcf0SJohan Hedberg lock_sock(sk);
1121e793dcf0SJohan Hedberg err = bt_sock_wait_ready(sk, msg->msg_flags);
1122e793dcf0SJohan Hedberg release_sock(sk);
1123e793dcf0SJohan Hedberg if (err)
1124e793dcf0SJohan Hedberg return err;
1125e793dcf0SJohan Hedberg
1126a6a5568cSMat Martineau l2cap_chan_lock(chan);
11278d46321cSMarcel Holtmann err = l2cap_chan_send(chan, msg, len);
1128a6a5568cSMat Martineau l2cap_chan_unlock(chan);
1129fd83ccdbSGustavo F. Padovan
1130fd83ccdbSGustavo F. Padovan return err;
1131fd83ccdbSGustavo F. Padovan }
1132fd83ccdbSGustavo F. Padovan
l2cap_publish_rx_avail(struct l2cap_chan * chan)1133e2310343SSebastian Urban static void l2cap_publish_rx_avail(struct l2cap_chan *chan)
1134e2310343SSebastian Urban {
1135e2310343SSebastian Urban struct sock *sk = chan->data;
1136e2310343SSebastian Urban ssize_t avail = sk->sk_rcvbuf - atomic_read(&sk->sk_rmem_alloc);
1137e2310343SSebastian Urban int expected_skbs, skb_overhead;
1138e2310343SSebastian Urban
1139e2310343SSebastian Urban if (avail <= 0) {
1140e2310343SSebastian Urban l2cap_chan_rx_avail(chan, 0);
1141e2310343SSebastian Urban return;
1142e2310343SSebastian Urban }
1143e2310343SSebastian Urban
1144e2310343SSebastian Urban if (!chan->mps) {
1145e2310343SSebastian Urban l2cap_chan_rx_avail(chan, -1);
1146e2310343SSebastian Urban return;
1147e2310343SSebastian Urban }
1148e2310343SSebastian Urban
1149e2310343SSebastian Urban /* Correct available memory by estimated sk_buff overhead.
1150e2310343SSebastian Urban * This is significant due to small transfer sizes. However, accept
1151e2310343SSebastian Urban * at least one full packet if receive space is non-zero.
1152e2310343SSebastian Urban */
1153e2310343SSebastian Urban expected_skbs = DIV_ROUND_UP(avail, chan->mps);
1154e2310343SSebastian Urban skb_overhead = expected_skbs * sizeof(struct sk_buff);
1155e2310343SSebastian Urban if (skb_overhead < avail)
1156e2310343SSebastian Urban l2cap_chan_rx_avail(chan, avail - skb_overhead);
1157e2310343SSebastian Urban else
1158e2310343SSebastian Urban l2cap_chan_rx_avail(chan, -1);
1159e2310343SSebastian Urban }
1160e2310343SSebastian Urban
l2cap_sock_recvmsg(struct socket * sock,struct msghdr * msg,size_t len,int flags)11611b784140SYing Xue static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg,
11621b784140SYing Xue size_t len, int flags)
116368983259SGustavo F. Padovan {
116468983259SGustavo F. Padovan struct sock *sk = sock->sk;
1165e328140fSMat Martineau struct l2cap_pinfo *pi = l2cap_pi(sk);
1166e328140fSMat Martineau int err;
116768983259SGustavo F. Padovan
116868983259SGustavo F. Padovan lock_sock(sk);
116968983259SGustavo F. Padovan
1170c5daa683SGustavo Padovan if (sk->sk_state == BT_CONNECT2 && test_bit(BT_SK_DEFER_SETUP,
1171c5daa683SGustavo Padovan &bt_sk(sk)->flags)) {
117215f02b91SLuiz Augusto von Dentz if (pi->chan->mode == L2CAP_MODE_EXT_FLOWCTL) {
117315f02b91SLuiz Augusto von Dentz sk->sk_state = BT_CONNECTED;
117415f02b91SLuiz Augusto von Dentz pi->chan->state = BT_CONNECTED;
117515f02b91SLuiz Augusto von Dentz __l2cap_ecred_conn_rsp_defer(pi->chan);
1176b354e6c1SDan Carpenter } else if (bdaddr_type_is_le(pi->chan->src_type)) {
117738319713SJohan Hedberg sk->sk_state = BT_CONNECTED;
117838319713SJohan Hedberg pi->chan->state = BT_CONNECTED;
117938319713SJohan Hedberg __l2cap_le_connect_rsp_defer(pi->chan);
118038319713SJohan Hedberg } else {
11818c1d787bSGustavo F. Padovan sk->sk_state = BT_CONFIG;
11823542b854SGustavo F. Padovan pi->chan->state = BT_CONFIG;
1183e328140fSMat Martineau __l2cap_connect_rsp_defer(pi->chan);
118438319713SJohan Hedberg }
118538319713SJohan Hedberg
1186970871bcSJohan Hedberg err = 0;
1187970871bcSJohan Hedberg goto done;
118868983259SGustavo F. Padovan }
118968983259SGustavo F. Padovan
119068983259SGustavo F. Padovan release_sock(sk);
119168983259SGustavo F. Padovan
119268983259SGustavo F. Padovan if (sock->type == SOCK_STREAM)
11931b784140SYing Xue err = bt_sock_stream_recvmsg(sock, msg, len, flags);
1194e328140fSMat Martineau else
11951b784140SYing Xue err = bt_sock_recvmsg(sock, msg, len, flags);
119668983259SGustavo F. Padovan
1197e2310343SSebastian Urban if (pi->chan->mode != L2CAP_MODE_ERTM &&
1198e2310343SSebastian Urban pi->chan->mode != L2CAP_MODE_LE_FLOWCTL &&
1199e2310343SSebastian Urban pi->chan->mode != L2CAP_MODE_EXT_FLOWCTL)
1200e328140fSMat Martineau return err;
1201e328140fSMat Martineau
1202e328140fSMat Martineau lock_sock(sk);
1203e328140fSMat Martineau
1204e2310343SSebastian Urban l2cap_publish_rx_avail(pi->chan);
1205e328140fSMat Martineau
1206e2310343SSebastian Urban /* Attempt to put pending rx data in the socket buffer */
1207e2310343SSebastian Urban while (!list_empty(&pi->rx_busy)) {
1208e2310343SSebastian Urban struct l2cap_rx_busy *rx_busy =
1209e2310343SSebastian Urban list_first_entry(&pi->rx_busy,
1210e2310343SSebastian Urban struct l2cap_rx_busy,
1211e2310343SSebastian Urban list);
1212e2310343SSebastian Urban if (__sock_queue_rcv_skb(sk, rx_busy->skb) < 0)
1213e328140fSMat Martineau goto done;
1214e2310343SSebastian Urban list_del(&rx_busy->list);
1215e2310343SSebastian Urban kfree(rx_busy);
1216e328140fSMat Martineau }
1217e328140fSMat Martineau
1218e328140fSMat Martineau /* Restore data flow when half of the receive buffer is
1219e328140fSMat Martineau * available. This avoids resending large numbers of
1220e328140fSMat Martineau * frames.
1221e328140fSMat Martineau */
1222e2310343SSebastian Urban if (test_bit(CONN_LOCAL_BUSY, &pi->chan->conn_state) &&
1223e2310343SSebastian Urban atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf >> 1)
1224e328140fSMat Martineau l2cap_chan_busy(pi->chan, 0);
1225e328140fSMat Martineau
1226e328140fSMat Martineau done:
1227e328140fSMat Martineau release_sock(sk);
1228e328140fSMat Martineau return err;
122968983259SGustavo F. Padovan }
123068983259SGustavo F. Padovan
123105fc1576SGustavo F. Padovan /* Kill socket (only if zapped and orphan)
12326c08fc89SManish Mandlik * Must be called on unlocked socket, with l2cap channel lock.
123305fc1576SGustavo F. Padovan */
l2cap_sock_kill(struct sock * sk)1234ba3bd0eeSGustavo F. Padovan static void l2cap_sock_kill(struct sock *sk)
123505fc1576SGustavo F. Padovan {
123605fc1576SGustavo F. Padovan if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
123705fc1576SGustavo F. Padovan return;
123805fc1576SGustavo F. Padovan
1239e05dcc32SAndrei Emeltchenko BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state));
124005fc1576SGustavo F. Padovan
1241b803f30eSEdward Adam Davis /* Sock is dead, so set chan data to NULL, avoid other task use invalid
1242b803f30eSEdward Adam Davis * sock pointer.
1243b803f30eSEdward Adam Davis */
1244b803f30eSEdward Adam Davis l2cap_pi(sk)->chan->data = NULL;
124505fc1576SGustavo F. Padovan /* Kill poor orphan */
12466ff5abbfSGustavo F. Padovan
12474af66c69SJaganath Kanakkassery l2cap_chan_put(l2cap_pi(sk)->chan);
124805fc1576SGustavo F. Padovan sock_set_flag(sk, SOCK_DEAD);
124905fc1576SGustavo F. Padovan sock_put(sk);
125005fc1576SGustavo F. Padovan }
125105fc1576SGustavo F. Padovan
__l2cap_wait_ack(struct sock * sk,struct l2cap_chan * chan)1252f65468f6SDean Jenkins static int __l2cap_wait_ack(struct sock *sk, struct l2cap_chan *chan)
1253dc25306bSGustavo Padovan {
1254dc25306bSGustavo Padovan DECLARE_WAITQUEUE(wait, current);
1255dc25306bSGustavo Padovan int err = 0;
1256cb02a255SDean Jenkins int timeo = L2CAP_WAIT_ACK_POLL_PERIOD;
1257e432c72cSDean Jenkins /* Timeout to prevent infinite loop */
1258e432c72cSDean Jenkins unsigned long timeout = jiffies + L2CAP_WAIT_ACK_TIMEOUT;
1259dc25306bSGustavo Padovan
1260dc25306bSGustavo Padovan add_wait_queue(sk_sleep(sk), &wait);
1261dc25306bSGustavo Padovan set_current_state(TASK_INTERRUPTIBLE);
1262f65468f6SDean Jenkins do {
1263e432c72cSDean Jenkins BT_DBG("Waiting for %d ACKs, timeout %04d ms",
1264e432c72cSDean Jenkins chan->unacked_frames, time_after(jiffies, timeout) ? 0 :
1265e432c72cSDean Jenkins jiffies_to_msecs(timeout - jiffies));
1266451e4c6cSDean Jenkins
1267dc25306bSGustavo Padovan if (!timeo)
1268cb02a255SDean Jenkins timeo = L2CAP_WAIT_ACK_POLL_PERIOD;
1269dc25306bSGustavo Padovan
1270dc25306bSGustavo Padovan if (signal_pending(current)) {
1271dc25306bSGustavo Padovan err = sock_intr_errno(timeo);
1272dc25306bSGustavo Padovan break;
1273dc25306bSGustavo Padovan }
1274dc25306bSGustavo Padovan
1275dc25306bSGustavo Padovan release_sock(sk);
1276dc25306bSGustavo Padovan timeo = schedule_timeout(timeo);
1277dc25306bSGustavo Padovan lock_sock(sk);
1278dc25306bSGustavo Padovan set_current_state(TASK_INTERRUPTIBLE);
1279dc25306bSGustavo Padovan
1280dc25306bSGustavo Padovan err = sock_error(sk);
1281dc25306bSGustavo Padovan if (err)
1282dc25306bSGustavo Padovan break;
1283f65468f6SDean Jenkins
1284e432c72cSDean Jenkins if (time_after(jiffies, timeout)) {
1285e432c72cSDean Jenkins err = -ENOLINK;
1286e432c72cSDean Jenkins break;
1287e432c72cSDean Jenkins }
1288e432c72cSDean Jenkins
1289f65468f6SDean Jenkins } while (chan->unacked_frames > 0 &&
1290f65468f6SDean Jenkins chan->state == BT_CONNECTED);
1291f65468f6SDean Jenkins
1292dc25306bSGustavo Padovan set_current_state(TASK_RUNNING);
1293dc25306bSGustavo Padovan remove_wait_queue(sk_sleep(sk), &wait);
1294dc25306bSGustavo Padovan return err;
1295dc25306bSGustavo Padovan }
1296dc25306bSGustavo Padovan
l2cap_sock_shutdown(struct socket * sock,int how)1297dcba0dbaSGustavo F. Padovan static int l2cap_sock_shutdown(struct socket *sock, int how)
1298dcba0dbaSGustavo F. Padovan {
1299dcba0dbaSGustavo F. Padovan struct sock *sk = sock->sk;
13007ddb6e0fSAndrei Emeltchenko struct l2cap_chan *chan;
13013df91ea2SAndrei Emeltchenko struct l2cap_conn *conn;
1302dcba0dbaSGustavo F. Padovan int err = 0;
1303dcba0dbaSGustavo F. Padovan
13045b440676SArchie Pusaka BT_DBG("sock %p, sk %p, how %d", sock, sk, how);
13055b440676SArchie Pusaka
13065b440676SArchie Pusaka /* 'how' parameter is mapped to sk_shutdown as follows:
13075b440676SArchie Pusaka * SHUT_RD (0) --> RCV_SHUTDOWN (1)
13085b440676SArchie Pusaka * SHUT_WR (1) --> SEND_SHUTDOWN (2)
13095b440676SArchie Pusaka * SHUT_RDWR (2) --> SHUTDOWN_MASK (3)
13105b440676SArchie Pusaka */
13115b440676SArchie Pusaka how++;
1312dcba0dbaSGustavo F. Padovan
1313dcba0dbaSGustavo F. Padovan if (!sk)
1314dcba0dbaSGustavo F. Padovan return 0;
1315dcba0dbaSGustavo F. Padovan
131604ba72e6SDean Jenkins lock_sock(sk);
131704ba72e6SDean Jenkins
13185b440676SArchie Pusaka if ((sk->sk_shutdown & how) == how)
1319e7456437SDean Jenkins goto shutdown_already;
1320e7456437SDean Jenkins
1321e7456437SDean Jenkins BT_DBG("Handling sock shutdown");
1322e7456437SDean Jenkins
13232baea85dSDean Jenkins /* prevent sk structure from being freed whilst unlocked */
13242baea85dSDean Jenkins sock_hold(sk);
13252baea85dSDean Jenkins
13262baea85dSDean Jenkins /* prevent chan structure from being freed whilst unlocked */
1327*efc30877SLuiz Augusto von Dentz chan = l2cap_chan_hold_unless_zero(l2cap_pi(sk)->chan);
1328*efc30877SLuiz Augusto von Dentz if (!chan)
1329*efc30877SLuiz Augusto von Dentz goto shutdown_already;
13303df91ea2SAndrei Emeltchenko
133149d11741SJohan Hedberg BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
133249d11741SJohan Hedberg
1333f65468f6SDean Jenkins if (chan->mode == L2CAP_MODE_ERTM &&
1334f65468f6SDean Jenkins chan->unacked_frames > 0 &&
13359f7378a9SDean Jenkins chan->state == BT_CONNECTED) {
1336f65468f6SDean Jenkins err = __l2cap_wait_ack(sk, chan);
1337dcba0dbaSGustavo F. Padovan
13389f7378a9SDean Jenkins /* After waiting for ACKs, check whether shutdown
13399f7378a9SDean Jenkins * has already been actioned to close the L2CAP
13409f7378a9SDean Jenkins * link such as by l2cap_disconnection_req().
13419f7378a9SDean Jenkins */
13425b440676SArchie Pusaka if ((sk->sk_shutdown & how) == how)
13435b440676SArchie Pusaka goto shutdown_matched;
13449f7378a9SDean Jenkins }
13459f7378a9SDean Jenkins
13465b440676SArchie Pusaka /* Try setting the RCV_SHUTDOWN bit, return early if SEND_SHUTDOWN
13475b440676SArchie Pusaka * is already set
13485b440676SArchie Pusaka */
13495b440676SArchie Pusaka if ((how & RCV_SHUTDOWN) && !(sk->sk_shutdown & RCV_SHUTDOWN)) {
13505b440676SArchie Pusaka sk->sk_shutdown |= RCV_SHUTDOWN;
13515b440676SArchie Pusaka if ((sk->sk_shutdown & how) == how)
13525b440676SArchie Pusaka goto shutdown_matched;
13535b440676SArchie Pusaka }
13545b440676SArchie Pusaka
13555b440676SArchie Pusaka sk->sk_shutdown |= SEND_SHUTDOWN;
13566be36555SAndrei Emeltchenko release_sock(sk);
135704ba72e6SDean Jenkins
135804ba72e6SDean Jenkins l2cap_chan_lock(chan);
135904ba72e6SDean Jenkins /* prevent conn structure from being freed */
1360*efc30877SLuiz Augusto von Dentz conn = l2cap_conn_hold_unless_zero(chan->conn);
136104ba72e6SDean Jenkins l2cap_chan_unlock(chan);
136204ba72e6SDean Jenkins
136304ba72e6SDean Jenkins if (conn)
136404ba72e6SDean Jenkins /* mutex lock must be taken before l2cap_chan_lock() */
1365*efc30877SLuiz Augusto von Dentz mutex_lock(&conn->lock);
136604ba72e6SDean Jenkins
136704ba72e6SDean Jenkins l2cap_chan_lock(chan);
13680f852724SGustavo F. Padovan l2cap_chan_close(chan, 0);
136904ba72e6SDean Jenkins l2cap_chan_unlock(chan);
137004ba72e6SDean Jenkins
137104ba72e6SDean Jenkins if (conn) {
1372*efc30877SLuiz Augusto von Dentz mutex_unlock(&conn->lock);
137304ba72e6SDean Jenkins l2cap_conn_put(conn);
137404ba72e6SDean Jenkins }
137504ba72e6SDean Jenkins
13766be36555SAndrei Emeltchenko lock_sock(sk);
1377dcba0dbaSGustavo F. Padovan
1378093facf3SVladimir Davydov if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
1379093facf3SVladimir Davydov !(current->flags & PF_EXITING))
1380dcba0dbaSGustavo F. Padovan err = bt_sock_wait_state(sk, BT_CLOSED,
1381dcba0dbaSGustavo F. Padovan sk->sk_lingertime);
1382dcba0dbaSGustavo F. Padovan
13835b440676SArchie Pusaka shutdown_matched:
13842baea85dSDean Jenkins l2cap_chan_put(chan);
13852baea85dSDean Jenkins sock_put(sk);
13862baea85dSDean Jenkins
1387e7456437SDean Jenkins shutdown_already:
138804ba72e6SDean Jenkins if (!err && sk->sk_err)
138904ba72e6SDean Jenkins err = -sk->sk_err;
139004ba72e6SDean Jenkins
139104ba72e6SDean Jenkins release_sock(sk);
139204ba72e6SDean Jenkins
139304ba72e6SDean Jenkins BT_DBG("Sock shutdown complete err: %d", err);
1394451e4c6cSDean Jenkins
1395dcba0dbaSGustavo F. Padovan return err;
1396dcba0dbaSGustavo F. Padovan }
1397dcba0dbaSGustavo F. Padovan
1398554f05bbSGustavo F. Padovan static int l2cap_sock_release(struct socket *sock)
l2cap_sock_release(struct socket * sock)1399554f05bbSGustavo F. Padovan {
1400554f05bbSGustavo F. Padovan struct sock *sk = sock->sk;
1401554f05bbSGustavo F. Padovan int err;
14022a154903SHillf Danton struct l2cap_chan *chan;
1403554f05bbSGustavo F. Padovan
1404554f05bbSGustavo F. Padovan BT_DBG("sock %p, sk %p", sock, sk);
1405554f05bbSGustavo F. Padovan
1406554f05bbSGustavo F. Padovan if (!sk)
1407554f05bbSGustavo F. Padovan return 0;
1408554f05bbSGustavo F. Padovan
14091728137bSSungwoo Kim l2cap_sock_cleanup_listen(sk);
14105b28d95cSMasatake YAMATO bt_sock_unlink(&l2cap_sk_list, sk);
14115b28d95cSMasatake YAMATO
14125b440676SArchie Pusaka err = l2cap_sock_shutdown(sock, SHUT_RDWR);
14132a154903SHillf Danton chan = l2cap_pi(sk)->chan;
1414554f05bbSGustavo F. Padovan
14152a154903SHillf Danton l2cap_chan_hold(chan);
14162a154903SHillf Danton l2cap_chan_lock(chan);
14176c08fc89SManish Mandlik
1418554f05bbSGustavo F. Padovan sock_orphan(sk);
1419554f05bbSGustavo F. Padovan l2cap_sock_kill(sk);
14206c08fc89SManish Mandlik
14212a154903SHillf Danton l2cap_chan_unlock(chan);
14222a154903SHillf Danton l2cap_chan_put(chan);
14236c08fc89SManish Mandlik
1424554f05bbSGustavo F. Padovan return err;
1425554f05bbSGustavo F. Padovan }
1426554f05bbSGustavo F. Padovan
1427c0df7f6eSAndrei Emeltchenko static void l2cap_sock_cleanup_listen(struct sock *parent)
l2cap_sock_cleanup_listen(struct sock * parent)1428c0df7f6eSAndrei Emeltchenko {
1429c0df7f6eSAndrei Emeltchenko struct sock *sk;
1430c0df7f6eSAndrei Emeltchenko
143149d11741SJohan Hedberg BT_DBG("parent %p state %s", parent,
143249d11741SJohan Hedberg state_to_string(parent->sk_state));
1433c0df7f6eSAndrei Emeltchenko
1434c0df7f6eSAndrei Emeltchenko /* Close not yet accepted channels */
1435c0df7f6eSAndrei Emeltchenko while ((sk = bt_accept_dequeue(parent, NULL))) {
1436c0df7f6eSAndrei Emeltchenko struct l2cap_chan *chan = l2cap_pi(sk)->chan;
1437c0df7f6eSAndrei Emeltchenko
143849d11741SJohan Hedberg BT_DBG("child chan %p state %s", chan,
143949d11741SJohan Hedberg state_to_string(chan->state));
144049d11741SJohan Hedberg
14416c08fc89SManish Mandlik l2cap_chan_hold(chan);
1442c0df7f6eSAndrei Emeltchenko l2cap_chan_lock(chan);
14436c08fc89SManish Mandlik
1444c0df7f6eSAndrei Emeltchenko __clear_chan_timer(chan);
1445c0df7f6eSAndrei Emeltchenko l2cap_chan_close(chan, ECONNRESET);
1446c0df7f6eSAndrei Emeltchenko l2cap_sock_kill(sk);
14476c08fc89SManish Mandlik
14486c08fc89SManish Mandlik l2cap_chan_unlock(chan);
14496c08fc89SManish Mandlik l2cap_chan_put(chan);
1450c0df7f6eSAndrei Emeltchenko }
1451c0df7f6eSAndrei Emeltchenko }
1452c0df7f6eSAndrei Emeltchenko
145380b98027SGustavo Padovan static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
l2cap_sock_new_connection_cb(struct l2cap_chan * chan)145480808e43SGustavo F. Padovan {
145580b98027SGustavo Padovan struct sock *sk, *parent = chan->data;
145680808e43SGustavo F. Padovan
14578ffb9290SGustavo Padovan lock_sock(parent);
14588ffb9290SGustavo Padovan
145953826692SGustavo Padovan /* Check for backlog size */
146053826692SGustavo Padovan if (sk_acceptq_is_full(parent)) {
146153826692SGustavo Padovan BT_DBG("backlog full %d", parent->sk_ack_backlog);
14628a96f3cdSJukka Taimisto release_sock(parent);
146353826692SGustavo Padovan return NULL;
146453826692SGustavo Padovan }
146553826692SGustavo Padovan
146680808e43SGustavo F. Padovan sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP,
146711aa9c28SEric W. Biederman GFP_ATOMIC, 0);
14688a96f3cdSJukka Taimisto if (!sk) {
14698a96f3cdSJukka Taimisto release_sock(parent);
147080808e43SGustavo F. Padovan return NULL;
14718a96f3cdSJukka Taimisto }
147280808e43SGustavo F. Padovan
1473d22015aaSOctavian Purdila bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
1474d22015aaSOctavian Purdila
147580808e43SGustavo F. Padovan l2cap_sock_init(sk, parent);
147680808e43SGustavo F. Padovan
1477c4f5627fSMatthias Kaehlcke bt_accept_enqueue(parent, sk, false);
1478644912e1SGustavo Padovan
14798ffb9290SGustavo Padovan release_sock(parent);
14808ffb9290SGustavo Padovan
148180808e43SGustavo F. Padovan return l2cap_pi(sk)->chan;
148280808e43SGustavo F. Padovan }
148380808e43SGustavo F. Padovan
148480b98027SGustavo Padovan static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
l2cap_sock_recv_cb(struct l2cap_chan * chan,struct sk_buff * skb)148523070494SGustavo F. Padovan {
1486b803f30eSEdward Adam Davis struct sock *sk;
1487b803f30eSEdward Adam Davis struct l2cap_pinfo *pi;
148884b34d98SMarcel Holtmann int err;
148923070494SGustavo F. Padovan
1490b803f30eSEdward Adam Davis sk = chan->data;
1491b0fc1bd2SLuiz Augusto von Dentz if (!sk)
1492b803f30eSEdward Adam Davis return -ENXIO;
1493b803f30eSEdward Adam Davis
1494b803f30eSEdward Adam Davis pi = l2cap_pi(sk);
1495b803f30eSEdward Adam Davis lock_sock(sk);
1496e2310343SSebastian Urban if (chan->mode == L2CAP_MODE_ERTM && !list_empty(&pi->rx_busy)) {
14976be36555SAndrei Emeltchenko err = -ENOMEM;
14986be36555SAndrei Emeltchenko goto done;
14996be36555SAndrei Emeltchenko }
1500e328140fSMat Martineau
1501dbb50887SDaniel Borkmann if (chan->mode != L2CAP_MODE_ERTM &&
1502e2310343SSebastian Urban chan->mode != L2CAP_MODE_STREAMING &&
1503e2310343SSebastian Urban chan->mode != L2CAP_MODE_LE_FLOWCTL &&
1504e2310343SSebastian Urban chan->mode != L2CAP_MODE_EXT_FLOWCTL) {
1505dbb50887SDaniel Borkmann /* Even if no filter is attached, we could potentially
1506dbb50887SDaniel Borkmann * get errors from security modules, etc.
1507dbb50887SDaniel Borkmann */
1508dbb50887SDaniel Borkmann err = sk_filter(sk, skb);
1509dbb50887SDaniel Borkmann if (err)
1510dbb50887SDaniel Borkmann goto done;
1511dbb50887SDaniel Borkmann }
1512dbb50887SDaniel Borkmann
1513dbb50887SDaniel Borkmann err = __sock_queue_rcv_skb(sk, skb);
1514e328140fSMat Martineau
1515e2310343SSebastian Urban l2cap_publish_rx_avail(chan);
1516e2310343SSebastian Urban
1517e2310343SSebastian Urban /* For ERTM and LE, handle a skb that doesn't fit into the recv
1518e328140fSMat Martineau * buffer. This is important to do because the data frames
1519e328140fSMat Martineau * have already been acked, so the skb cannot be discarded.
1520e328140fSMat Martineau *
1521e328140fSMat Martineau * Notify the l2cap core that the buffer is full, so the
1522e328140fSMat Martineau * LOCAL_BUSY state is entered and no more frames are
1523e328140fSMat Martineau * acked and reassembled until there is buffer space
1524e328140fSMat Martineau * available.
1525e328140fSMat Martineau */
1526e2310343SSebastian Urban if (err < 0 &&
1527e2310343SSebastian Urban (chan->mode == L2CAP_MODE_ERTM ||
1528e2310343SSebastian Urban chan->mode == L2CAP_MODE_LE_FLOWCTL ||
1529e2310343SSebastian Urban chan->mode == L2CAP_MODE_EXT_FLOWCTL)) {
1530e2310343SSebastian Urban struct l2cap_rx_busy *rx_busy =
1531e2310343SSebastian Urban kmalloc(sizeof(*rx_busy), GFP_KERNEL);
1532e2310343SSebastian Urban if (!rx_busy) {
1533e2310343SSebastian Urban err = -ENOMEM;
1534e2310343SSebastian Urban goto done;
1535e2310343SSebastian Urban }
1536e2310343SSebastian Urban rx_busy->skb = skb;
1537e2310343SSebastian Urban list_add_tail(&rx_busy->list, &pi->rx_busy);
153884b34d98SMarcel Holtmann l2cap_chan_busy(chan, 1);
1539e328140fSMat Martineau err = 0;
1540e328140fSMat Martineau }
1541e328140fSMat Martineau
15426be36555SAndrei Emeltchenko done:
15436be36555SAndrei Emeltchenko release_sock(sk);
15446be36555SAndrei Emeltchenko
1545e328140fSMat Martineau return err;
154623070494SGustavo F. Padovan }
154723070494SGustavo F. Padovan
154880b98027SGustavo Padovan static void l2cap_sock_close_cb(struct l2cap_chan *chan)
l2cap_sock_close_cb(struct l2cap_chan * chan)1549ba3bd0eeSGustavo F. Padovan {
155080b98027SGustavo Padovan struct sock *sk = chan->data;
1551ba3bd0eeSGustavo F. Padovan
15521bff51eaSWang ShaoBo if (!sk)
15531bff51eaSWang ShaoBo return;
15541bff51eaSWang ShaoBo
1555ba3bd0eeSGustavo F. Padovan l2cap_sock_kill(sk);
1556ba3bd0eeSGustavo F. Padovan }
1557ba3bd0eeSGustavo F. Padovan
1558c0df7f6eSAndrei Emeltchenko static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err)
l2cap_sock_teardown_cb(struct l2cap_chan * chan,int err)1559c0df7f6eSAndrei Emeltchenko {
1560c0df7f6eSAndrei Emeltchenko struct sock *sk = chan->data;
1561c0df7f6eSAndrei Emeltchenko struct sock *parent;
1562c0df7f6eSAndrei Emeltchenko
15631bff51eaSWang ShaoBo if (!sk)
15641bff51eaSWang ShaoBo return;
15651bff51eaSWang ShaoBo
156649d11741SJohan Hedberg BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
156749d11741SJohan Hedberg
15683b2ab39eSJohan Hedberg /* This callback can be called both for server (BT_LISTEN)
15693b2ab39eSJohan Hedberg * sockets as well as "normal" ones. To avoid lockdep warnings
15703b2ab39eSJohan Hedberg * with child socket locking (through l2cap_sock_cleanup_listen)
15713b2ab39eSJohan Hedberg * we need separation into separate nesting levels. The simplest
15723b2ab39eSJohan Hedberg * way to accomplish this is to inherit the nesting level used
15733b2ab39eSJohan Hedberg * for the channel.
15743b2ab39eSJohan Hedberg */
15753b2ab39eSJohan Hedberg lock_sock_nested(sk, atomic_read(&chan->nesting));
1576c0df7f6eSAndrei Emeltchenko
1577c0df7f6eSAndrei Emeltchenko parent = bt_sk(sk)->parent;
1578c0df7f6eSAndrei Emeltchenko
1579c0df7f6eSAndrei Emeltchenko switch (chan->state) {
1580c0df7f6eSAndrei Emeltchenko case BT_OPEN:
1581c0df7f6eSAndrei Emeltchenko case BT_BOUND:
1582c0df7f6eSAndrei Emeltchenko case BT_CLOSED:
1583c0df7f6eSAndrei Emeltchenko break;
1584c0df7f6eSAndrei Emeltchenko case BT_LISTEN:
1585c0df7f6eSAndrei Emeltchenko l2cap_sock_cleanup_listen(sk);
1586c0df7f6eSAndrei Emeltchenko sk->sk_state = BT_CLOSED;
1587c0df7f6eSAndrei Emeltchenko chan->state = BT_CLOSED;
1588c0df7f6eSAndrei Emeltchenko
1589c0df7f6eSAndrei Emeltchenko break;
1590c0df7f6eSAndrei Emeltchenko default:
1591c0df7f6eSAndrei Emeltchenko sk->sk_state = BT_CLOSED;
1592c0df7f6eSAndrei Emeltchenko chan->state = BT_CLOSED;
1593c0df7f6eSAndrei Emeltchenko
1594c0df7f6eSAndrei Emeltchenko sk->sk_err = err;
1595c0df7f6eSAndrei Emeltchenko
1596c0df7f6eSAndrei Emeltchenko if (parent) {
1597c0df7f6eSAndrei Emeltchenko bt_accept_unlink(sk);
1598676d2369SDavid S. Miller parent->sk_data_ready(parent);
1599c0df7f6eSAndrei Emeltchenko } else {
1600c0df7f6eSAndrei Emeltchenko sk->sk_state_change(sk);
1601c0df7f6eSAndrei Emeltchenko }
1602c0df7f6eSAndrei Emeltchenko
1603c0df7f6eSAndrei Emeltchenko break;
1604c0df7f6eSAndrei Emeltchenko }
1605c0df7f6eSAndrei Emeltchenko release_sock(sk);
160620ae4089SAbhishek Pandit-Subedi
160720ae4089SAbhishek Pandit-Subedi /* Only zap after cleanup to avoid use after free race */
160820ae4089SAbhishek Pandit-Subedi sock_set_flag(sk, SOCK_ZAPPED);
160920ae4089SAbhishek Pandit-Subedi
1610c0df7f6eSAndrei Emeltchenko }
1611c0df7f6eSAndrei Emeltchenko
161253f52121SGustavo Padovan static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state,
l2cap_sock_state_change_cb(struct l2cap_chan * chan,int state,int err)161353f52121SGustavo Padovan int err)
161489bc500eSGustavo F. Padovan {
161580b98027SGustavo Padovan struct sock *sk = chan->data;
161689bc500eSGustavo F. Padovan
161789bc500eSGustavo F. Padovan sk->sk_state = state;
161853f52121SGustavo Padovan
161953f52121SGustavo Padovan if (err)
162053f52121SGustavo Padovan sk->sk_err = err;
162189bc500eSGustavo F. Padovan }
162289bc500eSGustavo F. Padovan
16232f7719ceSAndrei Emeltchenko static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
l2cap_sock_alloc_skb_cb(struct l2cap_chan * chan,unsigned long hdr_len,unsigned long len,int nb)1624d9fbd02bSMarcel Holtmann unsigned long hdr_len,
162590338947SGustavo Padovan unsigned long len, int nb)
16262f7719ceSAndrei Emeltchenko {
16270f2c6153SGustavo Padovan struct sock *sk = chan->data;
162890338947SGustavo Padovan struct sk_buff *skb;
162990338947SGustavo Padovan int err;
16302f7719ceSAndrei Emeltchenko
1631a6a5568cSMat Martineau l2cap_chan_unlock(chan);
1632d9fbd02bSMarcel Holtmann skb = bt_skb_send_alloc(sk, hdr_len + len, nb, &err);
1633a6a5568cSMat Martineau l2cap_chan_lock(chan);
1634a6a5568cSMat Martineau
163590338947SGustavo Padovan if (!skb)
163690338947SGustavo Padovan return ERR_PTR(err);
163790338947SGustavo Padovan
1638df570334SLuiz Augusto von Dentz /* Channel lock is released before requesting new skb and then
1639df570334SLuiz Augusto von Dentz * reacquired thus we need to recheck channel state.
1640df570334SLuiz Augusto von Dentz */
1641df570334SLuiz Augusto von Dentz if (chan->state != BT_CONNECTED) {
1642df570334SLuiz Augusto von Dentz kfree_skb(skb);
1643df570334SLuiz Augusto von Dentz return ERR_PTR(-ENOTCONN);
1644df570334SLuiz Augusto von Dentz }
1645df570334SLuiz Augusto von Dentz
16468d46321cSMarcel Holtmann skb->priority = sk->sk_priority;
16478d46321cSMarcel Holtmann
1648a4368ff3SJohan Hedberg bt_cb(skb)->l2cap.chan = chan;
16490e790c64SGustavo Padovan
165090338947SGustavo Padovan return skb;
16512f7719ceSAndrei Emeltchenko }
16522f7719ceSAndrei Emeltchenko
165354a59aa2SAndrei Emeltchenko static void l2cap_sock_ready_cb(struct l2cap_chan *chan)
l2cap_sock_ready_cb(struct l2cap_chan * chan)165454a59aa2SAndrei Emeltchenko {
165554a59aa2SAndrei Emeltchenko struct sock *sk = chan->data;
165654a59aa2SAndrei Emeltchenko struct sock *parent;
165754a59aa2SAndrei Emeltchenko
165854a59aa2SAndrei Emeltchenko lock_sock(sk);
165954a59aa2SAndrei Emeltchenko
166054a59aa2SAndrei Emeltchenko parent = bt_sk(sk)->parent;
166154a59aa2SAndrei Emeltchenko
166254a59aa2SAndrei Emeltchenko BT_DBG("sk %p, parent %p", sk, parent);
166354a59aa2SAndrei Emeltchenko
166454a59aa2SAndrei Emeltchenko sk->sk_state = BT_CONNECTED;
166554a59aa2SAndrei Emeltchenko sk->sk_state_change(sk);
166654a59aa2SAndrei Emeltchenko
166754a59aa2SAndrei Emeltchenko if (parent)
1668676d2369SDavid S. Miller parent->sk_data_ready(parent);
166954a59aa2SAndrei Emeltchenko
167054a59aa2SAndrei Emeltchenko release_sock(sk);
167154a59aa2SAndrei Emeltchenko }
167254a59aa2SAndrei Emeltchenko
16732dc4e510SGustavo Padovan static void l2cap_sock_defer_cb(struct l2cap_chan *chan)
l2cap_sock_defer_cb(struct l2cap_chan * chan)16742dc4e510SGustavo Padovan {
1675acdcabf5SGustavo Padovan struct sock *parent, *sk = chan->data;
16762dc4e510SGustavo Padovan
1677acdcabf5SGustavo Padovan lock_sock(sk);
1678acdcabf5SGustavo Padovan
1679acdcabf5SGustavo Padovan parent = bt_sk(sk)->parent;
16802dc4e510SGustavo Padovan if (parent)
1681676d2369SDavid S. Miller parent->sk_data_ready(parent);
1682acdcabf5SGustavo Padovan
1683acdcabf5SGustavo Padovan release_sock(sk);
16842dc4e510SGustavo Padovan }
16852dc4e510SGustavo Padovan
1686d97c899bSMarcel Holtmann static void l2cap_sock_resume_cb(struct l2cap_chan *chan)
l2cap_sock_resume_cb(struct l2cap_chan * chan)1687d97c899bSMarcel Holtmann {
1688d97c899bSMarcel Holtmann struct sock *sk = chan->data;
1689d97c899bSMarcel Holtmann
1690d52deb17SJohan Hedberg if (test_and_clear_bit(FLAG_PENDING_SECURITY, &chan->flags)) {
1691d52deb17SJohan Hedberg sk->sk_state = BT_CONNECTED;
1692d52deb17SJohan Hedberg chan->state = BT_CONNECTED;
1693d52deb17SJohan Hedberg }
1694d52deb17SJohan Hedberg
1695d97c899bSMarcel Holtmann clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
1696d97c899bSMarcel Holtmann sk->sk_state_change(sk);
1697d97c899bSMarcel Holtmann }
1698d97c899bSMarcel Holtmann
16995ec1bbe5SGustavo Padovan static void l2cap_sock_set_shutdown_cb(struct l2cap_chan *chan)
l2cap_sock_set_shutdown_cb(struct l2cap_chan * chan)17005ec1bbe5SGustavo Padovan {
17015ec1bbe5SGustavo Padovan struct sock *sk = chan->data;
17025ec1bbe5SGustavo Padovan
17035ec1bbe5SGustavo Padovan lock_sock(sk);
17045ec1bbe5SGustavo Padovan sk->sk_shutdown = SHUTDOWN_MASK;
17055ec1bbe5SGustavo Padovan release_sock(sk);
17065ec1bbe5SGustavo Padovan }
17075ec1bbe5SGustavo Padovan
17088d836d71SGustavo Padovan static long l2cap_sock_get_sndtimeo_cb(struct l2cap_chan *chan)
l2cap_sock_get_sndtimeo_cb(struct l2cap_chan * chan)17098d836d71SGustavo Padovan {
17108d836d71SGustavo Padovan struct sock *sk = chan->data;
17118d836d71SGustavo Padovan
17128d836d71SGustavo Padovan return sk->sk_sndtimeo;
17138d836d71SGustavo Padovan }
17148d836d71SGustavo Padovan
1715b48596d1SLuiz Augusto von Dentz static struct pid *l2cap_sock_get_peer_pid_cb(struct l2cap_chan *chan)
l2cap_sock_get_peer_pid_cb(struct l2cap_chan * chan)1716b48596d1SLuiz Augusto von Dentz {
1717b48596d1SLuiz Augusto von Dentz struct sock *sk = chan->data;
1718b48596d1SLuiz Augusto von Dentz
1719b48596d1SLuiz Augusto von Dentz return sk->sk_peer_pid;
1720b48596d1SLuiz Augusto von Dentz }
1721b48596d1SLuiz Augusto von Dentz
1722837776f7SJohan Hedberg static void l2cap_sock_suspend_cb(struct l2cap_chan *chan)
l2cap_sock_suspend_cb(struct l2cap_chan * chan)1723837776f7SJohan Hedberg {
1724837776f7SJohan Hedberg struct sock *sk = chan->data;
1725837776f7SJohan Hedberg
1726837776f7SJohan Hedberg set_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
1727837776f7SJohan Hedberg sk->sk_state_change(sk);
1728837776f7SJohan Hedberg }
1729837776f7SJohan Hedberg
1730f1942564SLuiz Augusto von Dentz static int l2cap_sock_filter(struct l2cap_chan *chan, struct sk_buff *skb)
l2cap_sock_filter(struct l2cap_chan * chan,struct sk_buff * skb)1731f1942564SLuiz Augusto von Dentz {
1732f1942564SLuiz Augusto von Dentz struct sock *sk = chan->data;
1733f1942564SLuiz Augusto von Dentz
1734f1942564SLuiz Augusto von Dentz switch (chan->mode) {
1735f1942564SLuiz Augusto von Dentz case L2CAP_MODE_ERTM:
1736f1942564SLuiz Augusto von Dentz case L2CAP_MODE_STREAMING:
1737f1942564SLuiz Augusto von Dentz return sk_filter(sk, skb);
1738f1942564SLuiz Augusto von Dentz }
1739f1942564SLuiz Augusto von Dentz
1740f1942564SLuiz Augusto von Dentz return 0;
1741f1942564SLuiz Augusto von Dentz }
1742f1942564SLuiz Augusto von Dentz
174367f86a45SMarcel Holtmann static const struct l2cap_ops l2cap_chan_ops = {
174480808e43SGustavo F. Padovan .name = "L2CAP Socket Interface",
174580808e43SGustavo F. Padovan .new_connection = l2cap_sock_new_connection_cb,
174623070494SGustavo F. Padovan .recv = l2cap_sock_recv_cb,
1747ba3bd0eeSGustavo F. Padovan .close = l2cap_sock_close_cb,
1748c0df7f6eSAndrei Emeltchenko .teardown = l2cap_sock_teardown_cb,
174989bc500eSGustavo F. Padovan .state_change = l2cap_sock_state_change_cb,
175054a59aa2SAndrei Emeltchenko .ready = l2cap_sock_ready_cb,
17512dc4e510SGustavo Padovan .defer = l2cap_sock_defer_cb,
1752d97c899bSMarcel Holtmann .resume = l2cap_sock_resume_cb,
1753837776f7SJohan Hedberg .suspend = l2cap_sock_suspend_cb,
17545ec1bbe5SGustavo Padovan .set_shutdown = l2cap_sock_set_shutdown_cb,
17558d836d71SGustavo Padovan .get_sndtimeo = l2cap_sock_get_sndtimeo_cb,
1756b48596d1SLuiz Augusto von Dentz .get_peer_pid = l2cap_sock_get_peer_pid_cb,
17572f7719ceSAndrei Emeltchenko .alloc_skb = l2cap_sock_alloc_skb_cb,
1758f1942564SLuiz Augusto von Dentz .filter = l2cap_sock_filter,
175980808e43SGustavo F. Padovan };
176080808e43SGustavo F. Padovan
1761bb58f747SGustavo F. Padovan static void l2cap_sock_destruct(struct sock *sk)
l2cap_sock_destruct(struct sock * sk)1762bb58f747SGustavo F. Padovan {
1763e2310343SSebastian Urban struct l2cap_rx_busy *rx_busy, *next;
1764e2310343SSebastian Urban
1765bb58f747SGustavo F. Padovan BT_DBG("sk %p", sk);
1766bb58f747SGustavo F. Padovan
17671bff51eaSWang ShaoBo if (l2cap_pi(sk)->chan) {
17681bff51eaSWang ShaoBo l2cap_pi(sk)->chan->data = NULL;
176961d6ef3eSMat Martineau l2cap_chan_put(l2cap_pi(sk)->chan);
17701bff51eaSWang ShaoBo }
177184b34d98SMarcel Holtmann
1772e2310343SSebastian Urban list_for_each_entry_safe(rx_busy, next, &l2cap_pi(sk)->rx_busy, list) {
1773e2310343SSebastian Urban kfree_skb(rx_busy->skb);
1774e2310343SSebastian Urban list_del(&rx_busy->list);
1775e2310343SSebastian Urban kfree(rx_busy);
1776e328140fSMat Martineau }
1777e328140fSMat Martineau
1778bb58f747SGustavo F. Padovan skb_queue_purge(&sk->sk_receive_queue);
1779bb58f747SGustavo F. Padovan skb_queue_purge(&sk->sk_write_queue);
1780bb58f747SGustavo F. Padovan }
1781bb58f747SGustavo F. Padovan
17822edf870dSMarcel Holtmann static void l2cap_skb_msg_name(struct sk_buff *skb, void *msg_name,
l2cap_skb_msg_name(struct sk_buff * skb,void * msg_name,int * msg_namelen)17832edf870dSMarcel Holtmann int *msg_namelen)
17842edf870dSMarcel Holtmann {
1785342dfc30SSteffen Hurrle DECLARE_SOCKADDR(struct sockaddr_l2 *, la, msg_name);
17862edf870dSMarcel Holtmann
17872edf870dSMarcel Holtmann memset(la, 0, sizeof(struct sockaddr_l2));
17882edf870dSMarcel Holtmann la->l2_family = AF_BLUETOOTH;
1789a4368ff3SJohan Hedberg la->l2_psm = bt_cb(skb)->l2cap.psm;
1790a4368ff3SJohan Hedberg bacpy(&la->l2_bdaddr, &bt_cb(skb)->l2cap.bdaddr);
17912edf870dSMarcel Holtmann
17922edf870dSMarcel Holtmann *msg_namelen = sizeof(struct sockaddr_l2);
17932edf870dSMarcel Holtmann }
17942edf870dSMarcel Holtmann
179580808e43SGustavo F. Padovan static void l2cap_sock_init(struct sock *sk, struct sock *parent)
l2cap_sock_init(struct sock * sk,struct sock * parent)1796bb58f747SGustavo F. Padovan {
179784b34d98SMarcel Holtmann struct l2cap_chan *chan = l2cap_pi(sk)->chan;
1798bb58f747SGustavo F. Padovan
1799bb58f747SGustavo F. Padovan BT_DBG("sk %p", sk);
1800bb58f747SGustavo F. Padovan
1801bb58f747SGustavo F. Padovan if (parent) {
1802b4450035SGustavo F. Padovan struct l2cap_chan *pchan = l2cap_pi(parent)->chan;
1803b4450035SGustavo F. Padovan
1804bb58f747SGustavo F. Padovan sk->sk_type = parent->sk_type;
1805c5daa683SGustavo Padovan bt_sk(sk)->flags = bt_sk(parent)->flags;
1806bb58f747SGustavo F. Padovan
1807715ec005SGustavo F. Padovan chan->chan_type = pchan->chan_type;
18080c1bc5c6SGustavo F. Padovan chan->imtu = pchan->imtu;
18090c1bc5c6SGustavo F. Padovan chan->omtu = pchan->omtu;
1810b4450035SGustavo F. Padovan chan->conf_state = pchan->conf_state;
18110c1bc5c6SGustavo F. Padovan chan->mode = pchan->mode;
181247d1ec61SGustavo F. Padovan chan->fcs = pchan->fcs;
181347d1ec61SGustavo F. Padovan chan->max_tx = pchan->max_tx;
181447d1ec61SGustavo F. Padovan chan->tx_win = pchan->tx_win;
18156b3c7104SAndrei Emeltchenko chan->tx_win_max = pchan->tx_win_max;
18164343478fSGustavo F. Padovan chan->sec_level = pchan->sec_level;
1817d57b0e8bSAndrei Emeltchenko chan->flags = pchan->flags;
18180cd75f7eSJohan Hedberg chan->tx_credits = pchan->tx_credits;
18190cd75f7eSJohan Hedberg chan->rx_credits = pchan->rx_credits;
18206230c9b4SPaul Moore
18217a8e5a31SJohan Hedberg if (chan->chan_type == L2CAP_CHAN_FIXED) {
18227a8e5a31SJohan Hedberg chan->scid = pchan->scid;
18237a8e5a31SJohan Hedberg chan->dcid = pchan->scid;
18247a8e5a31SJohan Hedberg }
18257a8e5a31SJohan Hedberg
18266230c9b4SPaul Moore security_sk_clone(parent, sk);
1827bb58f747SGustavo F. Padovan } else {
1828715ec005SGustavo F. Padovan switch (sk->sk_type) {
1829715ec005SGustavo F. Padovan case SOCK_RAW:
1830715ec005SGustavo F. Padovan chan->chan_type = L2CAP_CHAN_RAW;
1831715ec005SGustavo F. Padovan break;
1832715ec005SGustavo F. Padovan case SOCK_DGRAM:
1833715ec005SGustavo F. Padovan chan->chan_type = L2CAP_CHAN_CONN_LESS;
18342edf870dSMarcel Holtmann bt_sk(sk)->skb_msg_name = l2cap_skb_msg_name;
1835715ec005SGustavo F. Padovan break;
1836715ec005SGustavo F. Padovan case SOCK_SEQPACKET:
1837715ec005SGustavo F. Padovan case SOCK_STREAM:
1838715ec005SGustavo F. Padovan chan->chan_type = L2CAP_CHAN_CONN_ORIENTED;
1839715ec005SGustavo F. Padovan break;
1840715ec005SGustavo F. Padovan }
1841715ec005SGustavo F. Padovan
18420c1bc5c6SGustavo F. Padovan chan->imtu = L2CAP_DEFAULT_MTU;
18430c1bc5c6SGustavo F. Padovan chan->omtu = 0;
1844bb58f747SGustavo F. Padovan if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
18450c1bc5c6SGustavo F. Padovan chan->mode = L2CAP_MODE_ERTM;
1846c1360a1cSGustavo F. Padovan set_bit(CONF_STATE2_DEVICE, &chan->conf_state);
1847bb58f747SGustavo F. Padovan } else {
18480c1bc5c6SGustavo F. Padovan chan->mode = L2CAP_MODE_BASIC;
1849bb58f747SGustavo F. Padovan }
1850bd4b1653SAndrei Emeltchenko
1851bd4b1653SAndrei Emeltchenko l2cap_chan_set_defaults(chan);
1852bb58f747SGustavo F. Padovan }
1853bb58f747SGustavo F. Padovan
1854bb58f747SGustavo F. Padovan /* Default config options */
18550c1bc5c6SGustavo F. Padovan chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
185680808e43SGustavo F. Padovan
185780808e43SGustavo F. Padovan chan->data = sk;
185880808e43SGustavo F. Padovan chan->ops = &l2cap_chan_ops;
1859e2310343SSebastian Urban
1860e2310343SSebastian Urban l2cap_publish_rx_avail(chan);
1861bb58f747SGustavo F. Padovan }
1862bb58f747SGustavo F. Padovan
1863bb58f747SGustavo F. Padovan static struct proto l2cap_proto = {
1864bb58f747SGustavo F. Padovan .name = "L2CAP",
1865bb58f747SGustavo F. Padovan .owner = THIS_MODULE,
1866bb58f747SGustavo F. Padovan .obj_size = sizeof(struct l2cap_pinfo)
1867bb58f747SGustavo F. Padovan };
1868bb58f747SGustavo F. Padovan
18692d792818SGustavo Padovan static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
l2cap_sock_alloc(struct net * net,struct socket * sock,int proto,gfp_t prio,int kern)187011aa9c28SEric W. Biederman int proto, gfp_t prio, int kern)
1871bb58f747SGustavo F. Padovan {
1872bb58f747SGustavo F. Padovan struct sock *sk;
1873dc50a06dSGustavo F. Padovan struct l2cap_chan *chan;
1874bb58f747SGustavo F. Padovan
18756bfa273eSLuiz Augusto von Dentz sk = bt_sock_alloc(net, sock, &l2cap_proto, proto, prio, kern);
1876bb58f747SGustavo F. Padovan if (!sk)
1877bb58f747SGustavo F. Padovan return NULL;
1878bb58f747SGustavo F. Padovan
1879bb58f747SGustavo F. Padovan sk->sk_destruct = l2cap_sock_destruct;
1880ba13ccd9SMarcel Holtmann sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
1881bb58f747SGustavo F. Padovan
1882e2310343SSebastian Urban INIT_LIST_HEAD(&l2cap_pi(sk)->rx_busy);
1883e2310343SSebastian Urban
1884eef1d9b6SGustavo Padovan chan = l2cap_chan_create();
1885dc50a06dSGustavo F. Padovan if (!chan) {
188649dfbb91SJaganath Kanakkassery sk_free(sk);
1887245d48c1SFedor Pchelkin if (sock)
18888ad09ddcSIgnat Korchagin sock->sk = NULL;
1889dc50a06dSGustavo F. Padovan return NULL;
1890dc50a06dSGustavo F. Padovan }
1891dc50a06dSGustavo F. Padovan
189261d6ef3eSMat Martineau l2cap_chan_hold(chan);
189361d6ef3eSMat Martineau
1894dc50a06dSGustavo F. Padovan l2cap_pi(sk)->chan = chan;
1895dc50a06dSGustavo F. Padovan
1896bb58f747SGustavo F. Padovan return sk;
1897bb58f747SGustavo F. Padovan }
1898bb58f747SGustavo F. Padovan
1899bb58f747SGustavo F. Padovan static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
l2cap_sock_create(struct net * net,struct socket * sock,int protocol,int kern)1900bb58f747SGustavo F. Padovan int kern)
1901bb58f747SGustavo F. Padovan {
1902bb58f747SGustavo F. Padovan struct sock *sk;
1903bb58f747SGustavo F. Padovan
1904bb58f747SGustavo F. Padovan BT_DBG("sock %p", sock);
1905bb58f747SGustavo F. Padovan
1906bb58f747SGustavo F. Padovan sock->state = SS_UNCONNECTED;
1907bb58f747SGustavo F. Padovan
1908bb58f747SGustavo F. Padovan if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
1909bb58f747SGustavo F. Padovan sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
1910bb58f747SGustavo F. Padovan return -ESOCKTNOSUPPORT;
1911bb58f747SGustavo F. Padovan
1912bb58f747SGustavo F. Padovan if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
1913bb58f747SGustavo F. Padovan return -EPERM;
1914bb58f747SGustavo F. Padovan
1915bb58f747SGustavo F. Padovan sock->ops = &l2cap_sock_ops;
1916bb58f747SGustavo F. Padovan
191711aa9c28SEric W. Biederman sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC, kern);
1918bb58f747SGustavo F. Padovan if (!sk)
1919bb58f747SGustavo F. Padovan return -ENOMEM;
1920bb58f747SGustavo F. Padovan
1921bb58f747SGustavo F. Padovan l2cap_sock_init(sk, NULL);
19225b28d95cSMasatake YAMATO bt_sock_link(&l2cap_sk_list, sk);
1923bb58f747SGustavo F. Padovan return 0;
1924bb58f747SGustavo F. Padovan }
1925bb58f747SGustavo F. Padovan
1926cf2f90f5SGustavo F. Padovan static const struct proto_ops l2cap_sock_ops = {
192765390587SGustavo F. Padovan .family = PF_BLUETOOTH,
192865390587SGustavo F. Padovan .owner = THIS_MODULE,
192965390587SGustavo F. Padovan .release = l2cap_sock_release,
193065390587SGustavo F. Padovan .bind = l2cap_sock_bind,
193165390587SGustavo F. Padovan .connect = l2cap_sock_connect,
193265390587SGustavo F. Padovan .listen = l2cap_sock_listen,
193365390587SGustavo F. Padovan .accept = l2cap_sock_accept,
193465390587SGustavo F. Padovan .getname = l2cap_sock_getname,
193565390587SGustavo F. Padovan .sendmsg = l2cap_sock_sendmsg,
193665390587SGustavo F. Padovan .recvmsg = l2cap_sock_recvmsg,
1937a11e1d43SLinus Torvalds .poll = bt_sock_poll,
193865390587SGustavo F. Padovan .ioctl = bt_sock_ioctl,
1939c7cbdbf2SArnd Bergmann .gettstamp = sock_gettstamp,
194065390587SGustavo F. Padovan .mmap = sock_no_mmap,
194165390587SGustavo F. Padovan .socketpair = sock_no_socketpair,
194265390587SGustavo F. Padovan .shutdown = l2cap_sock_shutdown,
194365390587SGustavo F. Padovan .setsockopt = l2cap_sock_setsockopt,
194465390587SGustavo F. Padovan .getsockopt = l2cap_sock_getsockopt
194565390587SGustavo F. Padovan };
194665390587SGustavo F. Padovan
1947bb58f747SGustavo F. Padovan static const struct net_proto_family l2cap_sock_family_ops = {
1948bb58f747SGustavo F. Padovan .family = PF_BLUETOOTH,
1949bb58f747SGustavo F. Padovan .owner = THIS_MODULE,
1950bb58f747SGustavo F. Padovan .create = l2cap_sock_create,
1951bb58f747SGustavo F. Padovan };
1952bb58f747SGustavo F. Padovan
1953bb58f747SGustavo F. Padovan int __init l2cap_init_sockets(void)
l2cap_init_sockets(void)1954bb58f747SGustavo F. Padovan {
1955bb58f747SGustavo F. Padovan int err;
1956bb58f747SGustavo F. Padovan
1957dd625558SMarcel Holtmann BUILD_BUG_ON(sizeof(struct sockaddr_l2) > sizeof(struct sockaddr));
1958dd625558SMarcel Holtmann
1959bb58f747SGustavo F. Padovan err = proto_register(&l2cap_proto, 0);
1960bb58f747SGustavo F. Padovan if (err < 0)
1961bb58f747SGustavo F. Padovan return err;
1962bb58f747SGustavo F. Padovan
1963bb58f747SGustavo F. Padovan err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
19645b28d95cSMasatake YAMATO if (err < 0) {
19655b28d95cSMasatake YAMATO BT_ERR("L2CAP socket registration failed");
1966bb58f747SGustavo F. Padovan goto error;
19675b28d95cSMasatake YAMATO }
19685b28d95cSMasatake YAMATO
1969b0316615SAl Viro err = bt_procfs_init(&init_net, "l2cap", &l2cap_sk_list,
19702d792818SGustavo Padovan NULL);
19715b28d95cSMasatake YAMATO if (err < 0) {
19725b28d95cSMasatake YAMATO BT_ERR("Failed to create L2CAP proc file");
19735b28d95cSMasatake YAMATO bt_sock_unregister(BTPROTO_L2CAP);
19745b28d95cSMasatake YAMATO goto error;
19755b28d95cSMasatake YAMATO }
1976bb58f747SGustavo F. Padovan
1977bb58f747SGustavo F. Padovan BT_INFO("L2CAP socket layer initialized");
1978bb58f747SGustavo F. Padovan
1979bb58f747SGustavo F. Padovan return 0;
1980bb58f747SGustavo F. Padovan
1981bb58f747SGustavo F. Padovan error:
1982bb58f747SGustavo F. Padovan proto_unregister(&l2cap_proto);
1983bb58f747SGustavo F. Padovan return err;
1984bb58f747SGustavo F. Padovan }
1985bb58f747SGustavo F. Padovan
1986bb58f747SGustavo F. Padovan void l2cap_cleanup_sockets(void)
l2cap_cleanup_sockets(void)1987bb58f747SGustavo F. Padovan {
19885b28d95cSMasatake YAMATO bt_procfs_cleanup(&init_net, "l2cap");
19895e9d7f86SDavid Herrmann bt_sock_unregister(BTPROTO_L2CAP);
1990bb58f747SGustavo F. Padovan proto_unregister(&l2cap_proto);
1991bb58f747SGustavo F. Padovan }
1992