xref: /linux/net/bluetooth/l2cap_sock.c (revision 033771c085c2ed73cb29dd25e1ec8c4b2991cad9)
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),
257bf98feeaSLuiz Augusto von Dentz 				 &la.l2_bdaddr, la.l2_bdaddr_type,
258bf98feeaSLuiz Augusto von Dentz 				 sk->sk_sndtimeo);
2594e34c50bSGustavo F. Padovan 	if (err)
260b3fb611eSAndrei Emeltchenko 		return err;
2614e34c50bSGustavo F. Padovan 
2626be36555SAndrei Emeltchenko 	lock_sock(sk);
2636be36555SAndrei Emeltchenko 
2644e34c50bSGustavo F. Padovan 	err = bt_sock_wait_state(sk, BT_CONNECTED,
2654e34c50bSGustavo F. Padovan 				 sock_sndtimeo(sk, flags & O_NONBLOCK));
266b3fb611eSAndrei Emeltchenko 
2674e34c50bSGustavo F. Padovan 	release_sock(sk);
268b3fb611eSAndrei Emeltchenko 
2694e34c50bSGustavo F. Padovan 	return err;
2704e34c50bSGustavo F. Padovan }
2714e34c50bSGustavo F. Padovan 
l2cap_sock_listen(struct socket * sock,int backlog)272af6bcd82SGustavo F. Padovan static int l2cap_sock_listen(struct socket *sock, int backlog)
273af6bcd82SGustavo F. Padovan {
274af6bcd82SGustavo F. Padovan 	struct sock *sk = sock->sk;
2750c1bc5c6SGustavo F. Padovan 	struct l2cap_chan *chan = l2cap_pi(sk)->chan;
276af6bcd82SGustavo F. Padovan 	int err = 0;
277af6bcd82SGustavo F. Padovan 
278af6bcd82SGustavo F. Padovan 	BT_DBG("sk %p backlog %d", sk, backlog);
279af6bcd82SGustavo F. Padovan 
280af6bcd82SGustavo F. Padovan 	lock_sock(sk);
281af6bcd82SGustavo F. Padovan 
2826b3af733SMarcel Holtmann 	if (sk->sk_state != BT_BOUND) {
283af6bcd82SGustavo F. Padovan 		err = -EBADFD;
284af6bcd82SGustavo F. Padovan 		goto done;
285af6bcd82SGustavo F. Padovan 	}
286af6bcd82SGustavo F. Padovan 
2876b3af733SMarcel Holtmann 	if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM) {
2886b3af733SMarcel Holtmann 		err = -EINVAL;
2896b3af733SMarcel Holtmann 		goto done;
2906b3af733SMarcel Holtmann 	}
2916b3af733SMarcel Holtmann 
2920c1bc5c6SGustavo F. Padovan 	switch (chan->mode) {
293af6bcd82SGustavo F. Padovan 	case L2CAP_MODE_BASIC:
29438319713SJohan Hedberg 	case L2CAP_MODE_LE_FLOWCTL:
2954be5ca67SLuiz Augusto von Dentz 		break;
29615f02b91SLuiz Augusto von Dentz 	case L2CAP_MODE_EXT_FLOWCTL:
2974be5ca67SLuiz Augusto von Dentz 		if (!enable_ecred) {
2984be5ca67SLuiz Augusto von Dentz 			err = -EOPNOTSUPP;
2994be5ca67SLuiz Augusto von Dentz 			goto done;
3004be5ca67SLuiz Augusto von Dentz 		}
301af6bcd82SGustavo F. Padovan 		break;
302af6bcd82SGustavo F. Padovan 	case L2CAP_MODE_ERTM:
303af6bcd82SGustavo F. Padovan 	case L2CAP_MODE_STREAMING:
304af6bcd82SGustavo F. Padovan 		if (!disable_ertm)
305af6bcd82SGustavo F. Padovan 			break;
30619186c7bSGustavo A. R. Silva 		fallthrough;
307af6bcd82SGustavo F. Padovan 	default:
308beb19e4cSJohan Hedberg 		err = -EOPNOTSUPP;
309af6bcd82SGustavo F. Padovan 		goto done;
310af6bcd82SGustavo F. Padovan 	}
311af6bcd82SGustavo F. Padovan 
312af6bcd82SGustavo F. Padovan 	sk->sk_max_ack_backlog = backlog;
313af6bcd82SGustavo F. Padovan 	sk->sk_ack_backlog = 0;
31489bc500eSGustavo F. Padovan 
315abe84903SJohan Hedberg 	/* Listening channels need to use nested locking in order not to
316abe84903SJohan Hedberg 	 * cause lockdep warnings when the created child channels end up
317abe84903SJohan Hedberg 	 * being locked in the same thread as the parent channel.
318abe84903SJohan Hedberg 	 */
319abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_PARENT);
320abe84903SJohan Hedberg 
32189bc500eSGustavo F. Padovan 	chan->state = BT_LISTEN;
322af6bcd82SGustavo F. Padovan 	sk->sk_state = BT_LISTEN;
323af6bcd82SGustavo F. Padovan 
324af6bcd82SGustavo F. Padovan done:
325af6bcd82SGustavo F. Padovan 	release_sock(sk);
326af6bcd82SGustavo F. Padovan 	return err;
327af6bcd82SGustavo F. Padovan }
328af6bcd82SGustavo F. Padovan 
l2cap_sock_accept(struct socket * sock,struct socket * newsock,struct proto_accept_arg * arg)3292d792818SGustavo Padovan static int l2cap_sock_accept(struct socket *sock, struct socket *newsock,
33092ef0fd5SJens Axboe 			     struct proto_accept_arg *arg)
331c47b7c72SGustavo F. Padovan {
332dfb2fae7SPeter Hurley 	DEFINE_WAIT_FUNC(wait, woken_wake_function);
333c47b7c72SGustavo F. Padovan 	struct sock *sk = sock->sk, *nsk;
334c47b7c72SGustavo F. Padovan 	long timeo;
335c47b7c72SGustavo F. Padovan 	int err = 0;
336c47b7c72SGustavo F. Padovan 
3373b2ab39eSJohan Hedberg 	lock_sock_nested(sk, L2CAP_NESTING_PARENT);
338c47b7c72SGustavo F. Padovan 
33992ef0fd5SJens Axboe 	timeo = sock_rcvtimeo(sk, arg->flags & O_NONBLOCK);
340c47b7c72SGustavo F. Padovan 
341c47b7c72SGustavo F. Padovan 	BT_DBG("sk %p timeo %ld", sk, timeo);
342c47b7c72SGustavo F. Padovan 
343c47b7c72SGustavo F. Padovan 	/* Wait for an incoming connection. (wake-one). */
344c47b7c72SGustavo F. Padovan 	add_wait_queue_exclusive(sk_sleep(sk), &wait);
345f9a3c20aSPeter Hurley 	while (1) {
346c47b7c72SGustavo F. Padovan 		if (sk->sk_state != BT_LISTEN) {
347c47b7c72SGustavo F. Padovan 			err = -EBADFD;
348c47b7c72SGustavo F. Padovan 			break;
349c47b7c72SGustavo F. Padovan 		}
350c47b7c72SGustavo F. Padovan 
351f9a3c20aSPeter Hurley 		nsk = bt_accept_dequeue(sk, newsock);
352f9a3c20aSPeter Hurley 		if (nsk)
353f9a3c20aSPeter Hurley 			break;
354f9a3c20aSPeter Hurley 
355f9a3c20aSPeter Hurley 		if (!timeo) {
356f9a3c20aSPeter Hurley 			err = -EAGAIN;
357f9a3c20aSPeter Hurley 			break;
358f9a3c20aSPeter Hurley 		}
359f9a3c20aSPeter Hurley 
360c47b7c72SGustavo F. Padovan 		if (signal_pending(current)) {
361c47b7c72SGustavo F. Padovan 			err = sock_intr_errno(timeo);
362c47b7c72SGustavo F. Padovan 			break;
363c47b7c72SGustavo F. Padovan 		}
364f9a3c20aSPeter Hurley 
365f9a3c20aSPeter Hurley 		release_sock(sk);
366dfb2fae7SPeter Hurley 
367dfb2fae7SPeter Hurley 		timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
368dfb2fae7SPeter Hurley 
3693b2ab39eSJohan Hedberg 		lock_sock_nested(sk, L2CAP_NESTING_PARENT);
370c47b7c72SGustavo F. Padovan 	}
371c47b7c72SGustavo F. Padovan 	remove_wait_queue(sk_sleep(sk), &wait);
372c47b7c72SGustavo F. Padovan 
373c47b7c72SGustavo F. Padovan 	if (err)
374c47b7c72SGustavo F. Padovan 		goto done;
375c47b7c72SGustavo F. Padovan 
376c47b7c72SGustavo F. Padovan 	newsock->state = SS_CONNECTED;
377c47b7c72SGustavo F. Padovan 
378c47b7c72SGustavo F. Padovan 	BT_DBG("new socket %p", nsk);
379c47b7c72SGustavo F. Padovan 
380c47b7c72SGustavo F. Padovan done:
381c47b7c72SGustavo F. Padovan 	release_sock(sk);
382c47b7c72SGustavo F. Padovan 	return err;
383c47b7c72SGustavo F. Padovan }
384c47b7c72SGustavo F. Padovan 
l2cap_sock_getname(struct socket * sock,struct sockaddr * addr,int peer)3852d792818SGustavo Padovan static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
3869b2c45d4SDenys Vlasenko 			      int peer)
387d7175d55SGustavo F. Padovan {
388d7175d55SGustavo F. Padovan 	struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
389d7175d55SGustavo F. Padovan 	struct sock *sk = sock->sk;
3900c1bc5c6SGustavo F. Padovan 	struct l2cap_chan *chan = l2cap_pi(sk)->chan;
391d7175d55SGustavo F. Padovan 
392d7175d55SGustavo F. Padovan 	BT_DBG("sock %p, sk %p", sock, sk);
393d7175d55SGustavo F. Padovan 
394e8b1ab9eSJohan Hedberg 	if (peer && sk->sk_state != BT_CONNECTED &&
395bf19d51bSJohan Hedberg 	    sk->sk_state != BT_CONNECT && sk->sk_state != BT_CONNECT2 &&
396bf19d51bSJohan Hedberg 	    sk->sk_state != BT_CONFIG)
397b783fbc3SJohan Hedberg 		return -ENOTCONN;
398b783fbc3SJohan Hedberg 
399792039c7SMathias Krause 	memset(la, 0, sizeof(struct sockaddr_l2));
400d7175d55SGustavo F. Padovan 	addr->sa_family = AF_BLUETOOTH;
401d7175d55SGustavo F. Padovan 
402fe4128e0SGustavo F. Padovan 	la->l2_psm = chan->psm;
403d7e5e76bSJohan Hedberg 
404d7e5e76bSJohan Hedberg 	if (peer) {
4057eafc59eSMarcel Holtmann 		bacpy(&la->l2_bdaddr, &chan->dst);
406fe4128e0SGustavo F. Padovan 		la->l2_cid = cpu_to_le16(chan->dcid);
4074f1654e0SMarcel Holtmann 		la->l2_bdaddr_type = chan->dst_type;
408d7175d55SGustavo F. Padovan 	} else {
4097eafc59eSMarcel Holtmann 		bacpy(&la->l2_bdaddr, &chan->src);
410fe4128e0SGustavo F. Padovan 		la->l2_cid = cpu_to_le16(chan->scid);
4114f1654e0SMarcel Holtmann 		la->l2_bdaddr_type = chan->src_type;
412d7175d55SGustavo F. Padovan 	}
413d7175d55SGustavo F. Padovan 
4149b2c45d4SDenys Vlasenko 	return sizeof(struct sockaddr_l2);
415d7175d55SGustavo F. Padovan }
416d7175d55SGustavo F. Padovan 
l2cap_get_mode(struct l2cap_chan * chan)4173ee7b7cdSLuiz Augusto von Dentz static int l2cap_get_mode(struct l2cap_chan *chan)
4183ee7b7cdSLuiz Augusto von Dentz {
4193ee7b7cdSLuiz Augusto von Dentz 	switch (chan->mode) {
4203ee7b7cdSLuiz Augusto von Dentz 	case L2CAP_MODE_BASIC:
4213ee7b7cdSLuiz Augusto von Dentz 		return BT_MODE_BASIC;
4223ee7b7cdSLuiz Augusto von Dentz 	case L2CAP_MODE_ERTM:
4233ee7b7cdSLuiz Augusto von Dentz 		return BT_MODE_ERTM;
4243ee7b7cdSLuiz Augusto von Dentz 	case L2CAP_MODE_STREAMING:
4253ee7b7cdSLuiz Augusto von Dentz 		return BT_MODE_STREAMING;
4263ee7b7cdSLuiz Augusto von Dentz 	case L2CAP_MODE_LE_FLOWCTL:
4273ee7b7cdSLuiz Augusto von Dentz 		return BT_MODE_LE_FLOWCTL;
4283ee7b7cdSLuiz Augusto von Dentz 	case L2CAP_MODE_EXT_FLOWCTL:
4293ee7b7cdSLuiz Augusto von Dentz 		return BT_MODE_EXT_FLOWCTL;
4303ee7b7cdSLuiz Augusto von Dentz 	}
4313ee7b7cdSLuiz Augusto von Dentz 
4323ee7b7cdSLuiz Augusto von Dentz 	return -EINVAL;
4333ee7b7cdSLuiz Augusto von Dentz }
4343ee7b7cdSLuiz Augusto von Dentz 
l2cap_sock_getsockopt_old(struct socket * sock,int optname,char __user * optval,int __user * optlen)4352d792818SGustavo Padovan static int l2cap_sock_getsockopt_old(struct socket *sock, int optname,
4362d792818SGustavo Padovan 				     char __user *optval, int __user *optlen)
43799f4808dSGustavo F. Padovan {
43899f4808dSGustavo F. Padovan 	struct sock *sk = sock->sk;
4394343478fSGustavo F. Padovan 	struct l2cap_chan *chan = l2cap_pi(sk)->chan;
44099f4808dSGustavo F. Padovan 	struct l2cap_options opts;
44199f4808dSGustavo F. Padovan 	struct l2cap_conninfo cinfo;
4429bf4e919SNathan Chancellor 	int err = 0;
4439bf4e919SNathan Chancellor 	size_t len;
44499f4808dSGustavo F. Padovan 	u32 opt;
44599f4808dSGustavo F. Padovan 
44699f4808dSGustavo F. Padovan 	BT_DBG("sk %p", sk);
44799f4808dSGustavo F. Padovan 
44899f4808dSGustavo F. Padovan 	if (get_user(len, optlen))
44999f4808dSGustavo F. Padovan 		return -EFAULT;
45099f4808dSGustavo F. Padovan 
45199f4808dSGustavo F. Padovan 	lock_sock(sk);
45299f4808dSGustavo F. Padovan 
45399f4808dSGustavo F. Padovan 	switch (optname) {
45499f4808dSGustavo F. Padovan 	case L2CAP_OPTIONS:
45564b4f8dcSJohan Hedberg 		/* LE sockets should use BT_SNDMTU/BT_RCVMTU, but since
45664b4f8dcSJohan Hedberg 		 * legacy ATT code depends on getsockopt for
45764b4f8dcSJohan Hedberg 		 * L2CAP_OPTIONS we need to let this pass.
45864b4f8dcSJohan Hedberg 		 */
45964b4f8dcSJohan Hedberg 		if (bdaddr_type_is_le(chan->src_type) &&
46064b4f8dcSJohan Hedberg 		    chan->scid != L2CAP_CID_ATT) {
46164b4f8dcSJohan Hedberg 			err = -EINVAL;
46264b4f8dcSJohan Hedberg 			break;
46364b4f8dcSJohan Hedberg 		}
46464b4f8dcSJohan Hedberg 
465b86b0b15SLuiz Augusto von Dentz 		/* Only BR/EDR modes are supported here */
466b86b0b15SLuiz Augusto von Dentz 		switch (chan->mode) {
467b86b0b15SLuiz Augusto von Dentz 		case L2CAP_MODE_BASIC:
468b86b0b15SLuiz Augusto von Dentz 		case L2CAP_MODE_ERTM:
469b86b0b15SLuiz Augusto von Dentz 		case L2CAP_MODE_STREAMING:
470b86b0b15SLuiz Augusto von Dentz 			break;
471b86b0b15SLuiz Augusto von Dentz 		default:
472b86b0b15SLuiz Augusto von Dentz 			err = -EINVAL;
473b86b0b15SLuiz Augusto von Dentz 			break;
474b86b0b15SLuiz Augusto von Dentz 		}
475b86b0b15SLuiz Augusto von Dentz 
476b86b0b15SLuiz Augusto von Dentz 		if (err < 0)
477b86b0b15SLuiz Augusto von Dentz 			break;
478b86b0b15SLuiz Augusto von Dentz 
479e3fb592bSVasiliy Kulikov 		memset(&opts, 0, sizeof(opts));
4800c1bc5c6SGustavo F. Padovan 		opts.imtu     = chan->imtu;
4810c1bc5c6SGustavo F. Padovan 		opts.omtu     = chan->omtu;
4820c1bc5c6SGustavo F. Padovan 		opts.flush_to = chan->flush_to;
4830c1bc5c6SGustavo F. Padovan 		opts.mode     = chan->mode;
48447d1ec61SGustavo F. Padovan 		opts.fcs      = chan->fcs;
48547d1ec61SGustavo F. Padovan 		opts.max_tx   = chan->max_tx;
4866327eb98SAndrei Emeltchenko 		opts.txwin_size = chan->tx_win;
48799f4808dSGustavo F. Padovan 
48815f02b91SLuiz Augusto von Dentz 		BT_DBG("mode 0x%2.2x", chan->mode);
48915f02b91SLuiz Augusto von Dentz 
4909bf4e919SNathan Chancellor 		len = min(len, sizeof(opts));
49199f4808dSGustavo F. Padovan 		if (copy_to_user(optval, (char *) &opts, len))
49299f4808dSGustavo F. Padovan 			err = -EFAULT;
49399f4808dSGustavo F. Padovan 
49499f4808dSGustavo F. Padovan 		break;
49599f4808dSGustavo F. Padovan 
49699f4808dSGustavo F. Padovan 	case L2CAP_LM:
4974343478fSGustavo F. Padovan 		switch (chan->sec_level) {
49899f4808dSGustavo F. Padovan 		case BT_SECURITY_LOW:
49999f4808dSGustavo F. Padovan 			opt = L2CAP_LM_AUTH;
50099f4808dSGustavo F. Padovan 			break;
50199f4808dSGustavo F. Padovan 		case BT_SECURITY_MEDIUM:
50299f4808dSGustavo F. Padovan 			opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
50399f4808dSGustavo F. Padovan 			break;
50499f4808dSGustavo F. Padovan 		case BT_SECURITY_HIGH:
50599f4808dSGustavo F. Padovan 			opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
50699f4808dSGustavo F. Padovan 			      L2CAP_LM_SECURE;
50799f4808dSGustavo F. Padovan 			break;
5087d513e92SMarcel Holtmann 		case BT_SECURITY_FIPS:
5097d513e92SMarcel Holtmann 			opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
5107d513e92SMarcel Holtmann 			      L2CAP_LM_SECURE | L2CAP_LM_FIPS;
5117d513e92SMarcel Holtmann 			break;
51299f4808dSGustavo F. Padovan 		default:
51399f4808dSGustavo F. Padovan 			opt = 0;
51499f4808dSGustavo F. Padovan 			break;
51599f4808dSGustavo F. Padovan 		}
51699f4808dSGustavo F. Padovan 
51743bd0f32SAndrei Emeltchenko 		if (test_bit(FLAG_ROLE_SWITCH, &chan->flags))
51899f4808dSGustavo F. Padovan 			opt |= L2CAP_LM_MASTER;
51999f4808dSGustavo F. Padovan 
520ecf61bdbSAndrei Emeltchenko 		if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
52199f4808dSGustavo F. Padovan 			opt |= L2CAP_LM_RELIABLE;
52299f4808dSGustavo F. Padovan 
52399f4808dSGustavo F. Padovan 		if (put_user(opt, (u32 __user *) optval))
52499f4808dSGustavo F. Padovan 			err = -EFAULT;
5257d513e92SMarcel Holtmann 
52699f4808dSGustavo F. Padovan 		break;
52799f4808dSGustavo F. Padovan 
52899f4808dSGustavo F. Padovan 	case L2CAP_CONNINFO:
52999f4808dSGustavo F. Padovan 		if (sk->sk_state != BT_CONNECTED &&
53099f4808dSGustavo F. Padovan 		    !(sk->sk_state == BT_CONNECT2 &&
531c5daa683SGustavo Padovan 		      test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))) {
53299f4808dSGustavo F. Padovan 			err = -ENOTCONN;
53399f4808dSGustavo F. Padovan 			break;
53499f4808dSGustavo F. Padovan 		}
53599f4808dSGustavo F. Padovan 
5368d03e971SFilip Palian 		memset(&cinfo, 0, sizeof(cinfo));
5378c1d787bSGustavo F. Padovan 		cinfo.hci_handle = chan->conn->hcon->handle;
5388c1d787bSGustavo F. Padovan 		memcpy(cinfo.dev_class, chan->conn->hcon->dev_class, 3);
53999f4808dSGustavo F. Padovan 
5409bf4e919SNathan Chancellor 		len = min(len, sizeof(cinfo));
54199f4808dSGustavo F. Padovan 		if (copy_to_user(optval, (char *) &cinfo, len))
54299f4808dSGustavo F. Padovan 			err = -EFAULT;
54399f4808dSGustavo F. Padovan 
54499f4808dSGustavo F. Padovan 		break;
54599f4808dSGustavo F. Padovan 
54699f4808dSGustavo F. Padovan 	default:
54799f4808dSGustavo F. Padovan 		err = -ENOPROTOOPT;
54899f4808dSGustavo F. Padovan 		break;
54999f4808dSGustavo F. Padovan 	}
55099f4808dSGustavo F. Padovan 
55199f4808dSGustavo F. Padovan 	release_sock(sk);
55299f4808dSGustavo F. Padovan 	return err;
55399f4808dSGustavo F. Padovan }
55499f4808dSGustavo F. Padovan 
l2cap_sock_getsockopt(struct socket * sock,int level,int optname,char __user * optval,int __user * optlen)5552d792818SGustavo Padovan static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname,
5562d792818SGustavo Padovan 				 char __user *optval, int __user *optlen)
55799f4808dSGustavo F. Padovan {
55899f4808dSGustavo F. Padovan 	struct sock *sk = sock->sk;
5594343478fSGustavo F. Padovan 	struct l2cap_chan *chan = l2cap_pi(sk)->chan;
56099f4808dSGustavo F. Padovan 	struct bt_security sec;
56114b12d0bSJaikumar Ganesh 	struct bt_power pwr;
562eab2404bSLuiz Augusto von Dentz 	u32 phys;
5633ee7b7cdSLuiz Augusto von Dentz 	int len, mode, err = 0;
56499f4808dSGustavo F. Padovan 
56599f4808dSGustavo F. Padovan 	BT_DBG("sk %p", sk);
56699f4808dSGustavo F. Padovan 
56799f4808dSGustavo F. Padovan 	if (level == SOL_L2CAP)
56899f4808dSGustavo F. Padovan 		return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
56999f4808dSGustavo F. Padovan 
57099f4808dSGustavo F. Padovan 	if (level != SOL_BLUETOOTH)
57199f4808dSGustavo F. Padovan 		return -ENOPROTOOPT;
57299f4808dSGustavo F. Padovan 
57399f4808dSGustavo F. Padovan 	if (get_user(len, optlen))
57499f4808dSGustavo F. Padovan 		return -EFAULT;
57599f4808dSGustavo F. Padovan 
57699f4808dSGustavo F. Padovan 	lock_sock(sk);
57799f4808dSGustavo F. Padovan 
57899f4808dSGustavo F. Padovan 	switch (optname) {
57999f4808dSGustavo F. Padovan 	case BT_SECURITY:
580715ec005SGustavo F. Padovan 		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
581e0c888adSJohan Hedberg 		    chan->chan_type != L2CAP_CHAN_FIXED &&
582715ec005SGustavo F. Padovan 		    chan->chan_type != L2CAP_CHAN_RAW) {
58399f4808dSGustavo F. Padovan 			err = -EINVAL;
58499f4808dSGustavo F. Padovan 			break;
58599f4808dSGustavo F. Padovan 		}
58699f4808dSGustavo F. Padovan 
5878f360119SVinicius Costa Gomes 		memset(&sec, 0, sizeof(sec));
58885e34368SAndrei Emeltchenko 		if (chan->conn) {
589c6585a4dSGustavo Padovan 			sec.level = chan->conn->hcon->sec_level;
59099f4808dSGustavo F. Padovan 
5918f360119SVinicius Costa Gomes 			if (sk->sk_state == BT_CONNECTED)
5928f360119SVinicius Costa Gomes 				sec.key_size = chan->conn->hcon->enc_key_size;
59385e34368SAndrei Emeltchenko 		} else {
59485e34368SAndrei Emeltchenko 			sec.level = chan->sec_level;
59585e34368SAndrei Emeltchenko 		}
5968f360119SVinicius Costa Gomes 
59799f4808dSGustavo F. Padovan 		len = min_t(unsigned int, len, sizeof(sec));
59899f4808dSGustavo F. Padovan 		if (copy_to_user(optval, (char *) &sec, len))
59999f4808dSGustavo F. Padovan 			err = -EFAULT;
60099f4808dSGustavo F. Padovan 
60199f4808dSGustavo F. Padovan 		break;
60299f4808dSGustavo F. Padovan 
60399f4808dSGustavo F. Padovan 	case BT_DEFER_SETUP:
60499f4808dSGustavo F. Padovan 		if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
60599f4808dSGustavo F. Padovan 			err = -EINVAL;
60699f4808dSGustavo F. Padovan 			break;
60799f4808dSGustavo F. Padovan 		}
60899f4808dSGustavo F. Padovan 
609c5daa683SGustavo Padovan 		if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
610c5daa683SGustavo Padovan 			     (u32 __user *) optval))
61199f4808dSGustavo F. Padovan 			err = -EFAULT;
61299f4808dSGustavo F. Padovan 
61399f4808dSGustavo F. Padovan 		break;
61499f4808dSGustavo F. Padovan 
61599f4808dSGustavo F. Padovan 	case BT_FLUSHABLE:
616d57b0e8bSAndrei Emeltchenko 		if (put_user(test_bit(FLAG_FLUSHABLE, &chan->flags),
617d57b0e8bSAndrei Emeltchenko 			     (u32 __user *) optval))
61899f4808dSGustavo F. Padovan 			err = -EFAULT;
61999f4808dSGustavo F. Padovan 
62099f4808dSGustavo F. Padovan 		break;
62199f4808dSGustavo F. Padovan 
62214b12d0bSJaikumar Ganesh 	case BT_POWER:
62314b12d0bSJaikumar Ganesh 		if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
62414b12d0bSJaikumar Ganesh 		    && sk->sk_type != SOCK_RAW) {
62514b12d0bSJaikumar Ganesh 			err = -EINVAL;
62614b12d0bSJaikumar Ganesh 			break;
62714b12d0bSJaikumar Ganesh 		}
62814b12d0bSJaikumar Ganesh 
62915770b1aSAndrei Emeltchenko 		pwr.force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
63014b12d0bSJaikumar Ganesh 
63114b12d0bSJaikumar Ganesh 		len = min_t(unsigned int, len, sizeof(pwr));
63214b12d0bSJaikumar Ganesh 		if (copy_to_user(optval, (char *) &pwr, len))
63314b12d0bSJaikumar Ganesh 			err = -EFAULT;
63414b12d0bSJaikumar Ganesh 
63514b12d0bSJaikumar Ganesh 		break;
63614b12d0bSJaikumar Ganesh 
6372ea66482SMat Martineau 	case BT_CHANNEL_POLICY:
6382ea66482SMat Martineau 		if (put_user(chan->chan_policy, (u32 __user *) optval))
6392ea66482SMat Martineau 			err = -EFAULT;
6402ea66482SMat Martineau 		break;
6412ea66482SMat Martineau 
6421f435424SJohan Hedberg 	case BT_SNDMTU:
6431f435424SJohan Hedberg 		if (!bdaddr_type_is_le(chan->src_type)) {
6441f435424SJohan Hedberg 			err = -EINVAL;
6451f435424SJohan Hedberg 			break;
6461f435424SJohan Hedberg 		}
6471f435424SJohan Hedberg 
6481f435424SJohan Hedberg 		if (sk->sk_state != BT_CONNECTED) {
6491f435424SJohan Hedberg 			err = -ENOTCONN;
6501f435424SJohan Hedberg 			break;
6511f435424SJohan Hedberg 		}
6521f435424SJohan Hedberg 
6531f435424SJohan Hedberg 		if (put_user(chan->omtu, (u16 __user *) optval))
6541f435424SJohan Hedberg 			err = -EFAULT;
6551f435424SJohan Hedberg 		break;
6561f435424SJohan Hedberg 
6571f435424SJohan Hedberg 	case BT_RCVMTU:
6581f435424SJohan Hedberg 		if (!bdaddr_type_is_le(chan->src_type)) {
6591f435424SJohan Hedberg 			err = -EINVAL;
6601f435424SJohan Hedberg 			break;
6611f435424SJohan Hedberg 		}
6621f435424SJohan Hedberg 
6631f435424SJohan Hedberg 		if (put_user(chan->imtu, (u16 __user *) optval))
6641f435424SJohan Hedberg 			err = -EFAULT;
6651f435424SJohan Hedberg 		break;
6661f435424SJohan Hedberg 
667eab2404bSLuiz Augusto von Dentz 	case BT_PHY:
668a2a8b0b4SLuiz Augusto von Dentz 		if (sk->sk_state != BT_CONNECTED) {
669eab2404bSLuiz Augusto von Dentz 			err = -ENOTCONN;
670eab2404bSLuiz Augusto von Dentz 			break;
671eab2404bSLuiz Augusto von Dentz 		}
672eab2404bSLuiz Augusto von Dentz 
673eab2404bSLuiz Augusto von Dentz 		phys = hci_conn_get_phy(chan->conn->hcon);
674eab2404bSLuiz Augusto von Dentz 
675eab2404bSLuiz Augusto von Dentz 		if (put_user(phys, (u32 __user *) optval))
676eab2404bSLuiz Augusto von Dentz 			err = -EFAULT;
677eab2404bSLuiz Augusto von Dentz 		break;
678eab2404bSLuiz Augusto von Dentz 
6793ee7b7cdSLuiz Augusto von Dentz 	case BT_MODE:
6803ee7b7cdSLuiz Augusto von Dentz 		if (!enable_ecred) {
6813ee7b7cdSLuiz Augusto von Dentz 			err = -ENOPROTOOPT;
6823ee7b7cdSLuiz Augusto von Dentz 			break;
6833ee7b7cdSLuiz Augusto von Dentz 		}
6843ee7b7cdSLuiz Augusto von Dentz 
6853ee7b7cdSLuiz Augusto von Dentz 		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
6863ee7b7cdSLuiz Augusto von Dentz 			err = -EINVAL;
6873ee7b7cdSLuiz Augusto von Dentz 			break;
6883ee7b7cdSLuiz Augusto von Dentz 		}
6893ee7b7cdSLuiz Augusto von Dentz 
6903ee7b7cdSLuiz Augusto von Dentz 		mode = l2cap_get_mode(chan);
6913ee7b7cdSLuiz Augusto von Dentz 		if (mode < 0) {
6923ee7b7cdSLuiz Augusto von Dentz 			err = mode;
6933ee7b7cdSLuiz Augusto von Dentz 			break;
6943ee7b7cdSLuiz Augusto von Dentz 		}
6953ee7b7cdSLuiz Augusto von Dentz 
6963ee7b7cdSLuiz Augusto von Dentz 		if (put_user(mode, (u8 __user *) optval))
6973ee7b7cdSLuiz Augusto von Dentz 			err = -EFAULT;
6983ee7b7cdSLuiz Augusto von Dentz 		break;
6993ee7b7cdSLuiz Augusto von Dentz 
70099f4808dSGustavo F. Padovan 	default:
70199f4808dSGustavo F. Padovan 		err = -ENOPROTOOPT;
70299f4808dSGustavo F. Padovan 		break;
70399f4808dSGustavo F. Padovan 	}
70499f4808dSGustavo F. Padovan 
70599f4808dSGustavo F. Padovan 	release_sock(sk);
70699f4808dSGustavo F. Padovan 	return err;
70799f4808dSGustavo F. Padovan }
70899f4808dSGustavo F. Padovan 
l2cap_valid_mtu(struct l2cap_chan * chan,u16 mtu)709682877c3SAndre Guedes static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu)
710682877c3SAndre Guedes {
711682877c3SAndre Guedes 	switch (chan->scid) {
712073d1cf3SJohan Hedberg 	case L2CAP_CID_ATT:
7138c3a4f00SAndre Guedes 		if (mtu < L2CAP_LE_MIN_MTU)
714682877c3SAndre Guedes 			return false;
715682877c3SAndre Guedes 		break;
716682877c3SAndre Guedes 
717682877c3SAndre Guedes 	default:
718682877c3SAndre Guedes 		if (mtu < L2CAP_DEFAULT_MIN_MTU)
719682877c3SAndre Guedes 			return false;
720682877c3SAndre Guedes 	}
721682877c3SAndre Guedes 
722682877c3SAndre Guedes 	return true;
723682877c3SAndre Guedes }
724682877c3SAndre Guedes 
l2cap_sock_setsockopt_old(struct socket * sock,int optname,sockptr_t optval,unsigned int optlen)7252d792818SGustavo Padovan static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
726a7b75c5aSChristoph Hellwig 				     sockptr_t optval, unsigned int optlen)
72733575df7SGustavo F. Padovan {
72833575df7SGustavo F. Padovan 	struct sock *sk = sock->sk;
729b4450035SGustavo F. Padovan 	struct l2cap_chan *chan = l2cap_pi(sk)->chan;
73033575df7SGustavo F. Padovan 	struct l2cap_options opts;
7314f395124SLuiz Augusto von Dentz 	int err = 0;
73233575df7SGustavo F. Padovan 	u32 opt;
73333575df7SGustavo F. Padovan 
73433575df7SGustavo F. Padovan 	BT_DBG("sk %p", sk);
73533575df7SGustavo F. Padovan 
73633575df7SGustavo F. Padovan 	lock_sock(sk);
73733575df7SGustavo F. Padovan 
73833575df7SGustavo F. Padovan 	switch (optname) {
73933575df7SGustavo F. Padovan 	case L2CAP_OPTIONS:
74064b4f8dcSJohan Hedberg 		if (bdaddr_type_is_le(chan->src_type)) {
74164b4f8dcSJohan Hedberg 			err = -EINVAL;
74264b4f8dcSJohan Hedberg 			break;
74364b4f8dcSJohan Hedberg 		}
74464b4f8dcSJohan Hedberg 
74533575df7SGustavo F. Padovan 		if (sk->sk_state == BT_CONNECTED) {
74633575df7SGustavo F. Padovan 			err = -EINVAL;
74733575df7SGustavo F. Padovan 			break;
74833575df7SGustavo F. Padovan 		}
74933575df7SGustavo F. Padovan 
7500c1bc5c6SGustavo F. Padovan 		opts.imtu     = chan->imtu;
7510c1bc5c6SGustavo F. Padovan 		opts.omtu     = chan->omtu;
7520c1bc5c6SGustavo F. Padovan 		opts.flush_to = chan->flush_to;
7530c1bc5c6SGustavo F. Padovan 		opts.mode     = chan->mode;
75447d1ec61SGustavo F. Padovan 		opts.fcs      = chan->fcs;
75547d1ec61SGustavo F. Padovan 		opts.max_tx   = chan->max_tx;
7566327eb98SAndrei Emeltchenko 		opts.txwin_size = chan->tx_win;
75733575df7SGustavo F. Padovan 
7584f395124SLuiz Augusto von Dentz 		err = bt_copy_from_sockptr(&opts, sizeof(opts), optval, optlen);
7594f395124SLuiz Augusto von Dentz 		if (err)
76033575df7SGustavo F. Padovan 			break;
76133575df7SGustavo F. Padovan 
7626327eb98SAndrei Emeltchenko 		if (opts.txwin_size > L2CAP_DEFAULT_EXT_WINDOW) {
76333575df7SGustavo F. Padovan 			err = -EINVAL;
76433575df7SGustavo F. Padovan 			break;
76533575df7SGustavo F. Padovan 		}
76633575df7SGustavo F. Padovan 
767682877c3SAndre Guedes 		if (!l2cap_valid_mtu(chan, opts.imtu)) {
768682877c3SAndre Guedes 			err = -EINVAL;
769682877c3SAndre Guedes 			break;
770682877c3SAndre Guedes 		}
771682877c3SAndre Guedes 
772b86b0b15SLuiz Augusto von Dentz 		/* Only BR/EDR modes are supported here */
773b86b0b15SLuiz Augusto von Dentz 		switch (opts.mode) {
77433575df7SGustavo F. Padovan 		case L2CAP_MODE_BASIC:
775c1360a1cSGustavo F. Padovan 			clear_bit(CONF_STATE2_DEVICE, &chan->conf_state);
77633575df7SGustavo F. Padovan 			break;
77733575df7SGustavo F. Padovan 		case L2CAP_MODE_ERTM:
77833575df7SGustavo F. Padovan 		case L2CAP_MODE_STREAMING:
77933575df7SGustavo F. Padovan 			if (!disable_ertm)
78033575df7SGustavo F. Padovan 				break;
78119186c7bSGustavo A. R. Silva 			fallthrough;
78233575df7SGustavo F. Padovan 		default:
78333575df7SGustavo F. Padovan 			err = -EINVAL;
78433575df7SGustavo F. Padovan 			break;
78533575df7SGustavo F. Padovan 		}
78633575df7SGustavo F. Padovan 
787b86b0b15SLuiz Augusto von Dentz 		if (err < 0)
788b86b0b15SLuiz Augusto von Dentz 			break;
789b86b0b15SLuiz Augusto von Dentz 
790b86b0b15SLuiz Augusto von Dentz 		chan->mode = opts.mode;
791b86b0b15SLuiz Augusto von Dentz 
79215f02b91SLuiz Augusto von Dentz 		BT_DBG("mode 0x%2.2x", chan->mode);
79315f02b91SLuiz Augusto von Dentz 
7940c1bc5c6SGustavo F. Padovan 		chan->imtu = opts.imtu;
7950c1bc5c6SGustavo F. Padovan 		chan->omtu = opts.omtu;
79647d1ec61SGustavo F. Padovan 		chan->fcs  = opts.fcs;
79747d1ec61SGustavo F. Padovan 		chan->max_tx = opts.max_tx;
7986327eb98SAndrei Emeltchenko 		chan->tx_win = opts.txwin_size;
79912d59781SAndrei Emeltchenko 		chan->flush_to = opts.flush_to;
80033575df7SGustavo F. Padovan 		break;
80133575df7SGustavo F. Padovan 
80233575df7SGustavo F. Padovan 	case L2CAP_LM:
8034f395124SLuiz Augusto von Dentz 		err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
8044f395124SLuiz Augusto von Dentz 		if (err)
80533575df7SGustavo F. Padovan 			break;
80633575df7SGustavo F. Padovan 
8077d513e92SMarcel Holtmann 		if (opt & L2CAP_LM_FIPS) {
8087d513e92SMarcel Holtmann 			err = -EINVAL;
8097d513e92SMarcel Holtmann 			break;
8107d513e92SMarcel Holtmann 		}
8117d513e92SMarcel Holtmann 
81233575df7SGustavo F. Padovan 		if (opt & L2CAP_LM_AUTH)
8134343478fSGustavo F. Padovan 			chan->sec_level = BT_SECURITY_LOW;
81433575df7SGustavo F. Padovan 		if (opt & L2CAP_LM_ENCRYPT)
8154343478fSGustavo F. Padovan 			chan->sec_level = BT_SECURITY_MEDIUM;
81633575df7SGustavo F. Padovan 		if (opt & L2CAP_LM_SECURE)
8174343478fSGustavo F. Padovan 			chan->sec_level = BT_SECURITY_HIGH;
81833575df7SGustavo F. Padovan 
81943bd0f32SAndrei Emeltchenko 		if (opt & L2CAP_LM_MASTER)
82043bd0f32SAndrei Emeltchenko 			set_bit(FLAG_ROLE_SWITCH, &chan->flags);
82143bd0f32SAndrei Emeltchenko 		else
82243bd0f32SAndrei Emeltchenko 			clear_bit(FLAG_ROLE_SWITCH, &chan->flags);
823ecf61bdbSAndrei Emeltchenko 
824ecf61bdbSAndrei Emeltchenko 		if (opt & L2CAP_LM_RELIABLE)
825ecf61bdbSAndrei Emeltchenko 			set_bit(FLAG_FORCE_RELIABLE, &chan->flags);
826ecf61bdbSAndrei Emeltchenko 		else
827ecf61bdbSAndrei Emeltchenko 			clear_bit(FLAG_FORCE_RELIABLE, &chan->flags);
82833575df7SGustavo F. Padovan 		break;
82933575df7SGustavo F. Padovan 
83033575df7SGustavo F. Padovan 	default:
83133575df7SGustavo F. Padovan 		err = -ENOPROTOOPT;
83233575df7SGustavo F. Padovan 		break;
83333575df7SGustavo F. Padovan 	}
83433575df7SGustavo F. Padovan 
83533575df7SGustavo F. Padovan 	release_sock(sk);
83633575df7SGustavo F. Padovan 	return err;
83733575df7SGustavo F. Padovan }
83833575df7SGustavo F. Padovan 
l2cap_set_mode(struct l2cap_chan * chan,u8 mode)8393ee7b7cdSLuiz Augusto von Dentz static int l2cap_set_mode(struct l2cap_chan *chan, u8 mode)
8403ee7b7cdSLuiz Augusto von Dentz {
8413ee7b7cdSLuiz Augusto von Dentz 	switch (mode) {
8423ee7b7cdSLuiz Augusto von Dentz 	case BT_MODE_BASIC:
8433ee7b7cdSLuiz Augusto von Dentz 		if (bdaddr_type_is_le(chan->src_type))
8443ee7b7cdSLuiz Augusto von Dentz 			return -EINVAL;
8453ee7b7cdSLuiz Augusto von Dentz 		mode = L2CAP_MODE_BASIC;
8463ee7b7cdSLuiz Augusto von Dentz 		clear_bit(CONF_STATE2_DEVICE, &chan->conf_state);
8473ee7b7cdSLuiz Augusto von Dentz 		break;
8483ee7b7cdSLuiz Augusto von Dentz 	case BT_MODE_ERTM:
8493ee7b7cdSLuiz Augusto von Dentz 		if (!disable_ertm || bdaddr_type_is_le(chan->src_type))
8503ee7b7cdSLuiz Augusto von Dentz 			return -EINVAL;
8513ee7b7cdSLuiz Augusto von Dentz 		mode = L2CAP_MODE_ERTM;
8523ee7b7cdSLuiz Augusto von Dentz 		break;
8533ee7b7cdSLuiz Augusto von Dentz 	case BT_MODE_STREAMING:
8543ee7b7cdSLuiz Augusto von Dentz 		if (!disable_ertm || bdaddr_type_is_le(chan->src_type))
8553ee7b7cdSLuiz Augusto von Dentz 			return -EINVAL;
8563ee7b7cdSLuiz Augusto von Dentz 		mode = L2CAP_MODE_STREAMING;
8573ee7b7cdSLuiz Augusto von Dentz 		break;
8583ee7b7cdSLuiz Augusto von Dentz 	case BT_MODE_LE_FLOWCTL:
8593ee7b7cdSLuiz Augusto von Dentz 		if (!bdaddr_type_is_le(chan->src_type))
8603ee7b7cdSLuiz Augusto von Dentz 			return -EINVAL;
8613ee7b7cdSLuiz Augusto von Dentz 		mode = L2CAP_MODE_LE_FLOWCTL;
8623ee7b7cdSLuiz Augusto von Dentz 		break;
8633ee7b7cdSLuiz Augusto von Dentz 	case BT_MODE_EXT_FLOWCTL:
8643ee7b7cdSLuiz Augusto von Dentz 		/* TODO: Add support for ECRED PDUs to BR/EDR */
8653ee7b7cdSLuiz Augusto von Dentz 		if (!bdaddr_type_is_le(chan->src_type))
8663ee7b7cdSLuiz Augusto von Dentz 			return -EINVAL;
8673ee7b7cdSLuiz Augusto von Dentz 		mode = L2CAP_MODE_EXT_FLOWCTL;
8683ee7b7cdSLuiz Augusto von Dentz 		break;
8693ee7b7cdSLuiz Augusto von Dentz 	default:
8703ee7b7cdSLuiz Augusto von Dentz 		return -EINVAL;
8713ee7b7cdSLuiz Augusto von Dentz 	}
8723ee7b7cdSLuiz Augusto von Dentz 
8733ee7b7cdSLuiz Augusto von Dentz 	chan->mode = mode;
8743ee7b7cdSLuiz Augusto von Dentz 
8753ee7b7cdSLuiz Augusto von Dentz 	return 0;
8763ee7b7cdSLuiz Augusto von Dentz }
8773ee7b7cdSLuiz Augusto von Dentz 
l2cap_sock_setsockopt(struct socket * sock,int level,int optname,sockptr_t optval,unsigned int optlen)8782d792818SGustavo Padovan static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
879a7b75c5aSChristoph Hellwig 				 sockptr_t optval, unsigned int optlen)
88033575df7SGustavo F. Padovan {
88133575df7SGustavo F. Padovan 	struct sock *sk = sock->sk;
8824343478fSGustavo F. Padovan 	struct l2cap_chan *chan = l2cap_pi(sk)->chan;
88333575df7SGustavo F. Padovan 	struct bt_security sec;
88414b12d0bSJaikumar Ganesh 	struct bt_power pwr;
885f1cb9af5SVinicius Costa Gomes 	struct l2cap_conn *conn;
8864f395124SLuiz Augusto von Dentz 	int err = 0;
88733575df7SGustavo F. Padovan 	u32 opt;
8882b70d4f9SDan Carpenter 	u16 mtu;
8892b70d4f9SDan Carpenter 	u8 mode;
89033575df7SGustavo F. Padovan 
89133575df7SGustavo F. Padovan 	BT_DBG("sk %p", sk);
89233575df7SGustavo F. Padovan 
89333575df7SGustavo F. Padovan 	if (level == SOL_L2CAP)
89433575df7SGustavo F. Padovan 		return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
89533575df7SGustavo F. Padovan 
89633575df7SGustavo F. Padovan 	if (level != SOL_BLUETOOTH)
89733575df7SGustavo F. Padovan 		return -ENOPROTOOPT;
89833575df7SGustavo F. Padovan 
89933575df7SGustavo F. Padovan 	lock_sock(sk);
90033575df7SGustavo F. Padovan 
90133575df7SGustavo F. Padovan 	switch (optname) {
90233575df7SGustavo F. Padovan 	case BT_SECURITY:
903715ec005SGustavo F. Padovan 		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
904e0c888adSJohan Hedberg 		    chan->chan_type != L2CAP_CHAN_FIXED &&
905715ec005SGustavo F. Padovan 		    chan->chan_type != L2CAP_CHAN_RAW) {
90633575df7SGustavo F. Padovan 			err = -EINVAL;
90733575df7SGustavo F. Padovan 			break;
90833575df7SGustavo F. Padovan 		}
90933575df7SGustavo F. Padovan 
91033575df7SGustavo F. Padovan 		sec.level = BT_SECURITY_LOW;
91133575df7SGustavo F. Padovan 
9124f395124SLuiz Augusto von Dentz 		err = bt_copy_from_sockptr(&sec, sizeof(sec), optval, optlen);
9134f395124SLuiz Augusto von Dentz 		if (err)
91433575df7SGustavo F. Padovan 			break;
91533575df7SGustavo F. Padovan 
91633575df7SGustavo F. Padovan 		if (sec.level < BT_SECURITY_LOW ||
917a164cee1SPatrik Flykt 		    sec.level > BT_SECURITY_FIPS) {
91833575df7SGustavo F. Padovan 			err = -EINVAL;
91933575df7SGustavo F. Padovan 			break;
92033575df7SGustavo F. Padovan 		}
92133575df7SGustavo F. Padovan 
9224343478fSGustavo F. Padovan 		chan->sec_level = sec.level;
923f1cb9af5SVinicius Costa Gomes 
9240bee1d60SGustavo F. Padovan 		if (!chan->conn)
9250bee1d60SGustavo F. Padovan 			break;
9260bee1d60SGustavo F. Padovan 
927f1cb9af5SVinicius Costa Gomes 		conn = chan->conn;
9280bee1d60SGustavo F. Padovan 
9290bee1d60SGustavo F. Padovan 		/* change security for LE channels */
930073d1cf3SJohan Hedberg 		if (chan->scid == L2CAP_CID_ATT) {
931bbb69b37SFugang Duan 			if (smp_conn_security(conn->hcon, sec.level)) {
932bbb69b37SFugang Duan 				err = -EINVAL;
933f1cb9af5SVinicius Costa Gomes 				break;
934bbb69b37SFugang Duan 			}
935bbb69b37SFugang Duan 
936d52deb17SJohan Hedberg 			set_bit(FLAG_PENDING_SECURITY, &chan->flags);
937f1cb9af5SVinicius Costa Gomes 			sk->sk_state = BT_CONFIG;
9383542b854SGustavo F. Padovan 			chan->state = BT_CONFIG;
9390bee1d60SGustavo F. Padovan 
940a7d7723aSGustavo Padovan 		/* or for ACL link */
941a7d7723aSGustavo Padovan 		} else if ((sk->sk_state == BT_CONNECT2 &&
942c5daa683SGustavo Padovan 			    test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) ||
943a7d7723aSGustavo Padovan 			   sk->sk_state == BT_CONNECTED) {
944e7cafc45SJohan Hedberg 			if (!l2cap_chan_check_security(chan, true))
945c5daa683SGustavo Padovan 				set_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
946a7d7723aSGustavo Padovan 			else
947a7d7723aSGustavo Padovan 				sk->sk_state_change(sk);
9480bee1d60SGustavo F. Padovan 		} else {
9490bee1d60SGustavo F. Padovan 			err = -EINVAL;
950f1cb9af5SVinicius Costa Gomes 		}
95133575df7SGustavo F. Padovan 		break;
95233575df7SGustavo F. Padovan 
95333575df7SGustavo F. Padovan 	case BT_DEFER_SETUP:
95433575df7SGustavo F. Padovan 		if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
95533575df7SGustavo F. Padovan 			err = -EINVAL;
95633575df7SGustavo F. Padovan 			break;
95733575df7SGustavo F. Padovan 		}
95833575df7SGustavo F. Padovan 
9594f395124SLuiz Augusto von Dentz 		err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
9604f395124SLuiz Augusto von Dentz 		if (err)
96133575df7SGustavo F. Padovan 			break;
96233575df7SGustavo F. Padovan 
963bdc25783SMarcel Holtmann 		if (opt) {
964c5daa683SGustavo Padovan 			set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
965bdc25783SMarcel Holtmann 			set_bit(FLAG_DEFER_SETUP, &chan->flags);
966bdc25783SMarcel Holtmann 		} else {
967c5daa683SGustavo Padovan 			clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
968bdc25783SMarcel Holtmann 			clear_bit(FLAG_DEFER_SETUP, &chan->flags);
969bdc25783SMarcel Holtmann 		}
97033575df7SGustavo F. Padovan 		break;
97133575df7SGustavo F. Padovan 
97233575df7SGustavo F. Padovan 	case BT_FLUSHABLE:
9734f395124SLuiz Augusto von Dentz 		err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
9744f395124SLuiz Augusto von Dentz 		if (err)
97533575df7SGustavo F. Padovan 			break;
97633575df7SGustavo F. Padovan 
97733575df7SGustavo F. Padovan 		if (opt > BT_FLUSHABLE_ON) {
97833575df7SGustavo F. Padovan 			err = -EINVAL;
97933575df7SGustavo F. Padovan 			break;
98033575df7SGustavo F. Padovan 		}
98133575df7SGustavo F. Padovan 
98233575df7SGustavo F. Padovan 		if (opt == BT_FLUSHABLE_OFF) {
983c1f23a2bSJohannes Berg 			conn = chan->conn;
98425985edcSLucas De Marchi 			/* proceed further only when we have l2cap_conn and
98533575df7SGustavo F. Padovan 			   No Flush support in the LM */
98633575df7SGustavo F. Padovan 			if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) {
98733575df7SGustavo F. Padovan 				err = -EINVAL;
98833575df7SGustavo F. Padovan 				break;
98933575df7SGustavo F. Padovan 			}
99033575df7SGustavo F. Padovan 		}
99133575df7SGustavo F. Padovan 
992d57b0e8bSAndrei Emeltchenko 		if (opt)
993d57b0e8bSAndrei Emeltchenko 			set_bit(FLAG_FLUSHABLE, &chan->flags);
994d57b0e8bSAndrei Emeltchenko 		else
995d57b0e8bSAndrei Emeltchenko 			clear_bit(FLAG_FLUSHABLE, &chan->flags);
99633575df7SGustavo F. Padovan 		break;
99733575df7SGustavo F. Padovan 
99814b12d0bSJaikumar Ganesh 	case BT_POWER:
99914b12d0bSJaikumar Ganesh 		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
100014b12d0bSJaikumar Ganesh 		    chan->chan_type != L2CAP_CHAN_RAW) {
100114b12d0bSJaikumar Ganesh 			err = -EINVAL;
100214b12d0bSJaikumar Ganesh 			break;
100314b12d0bSJaikumar Ganesh 		}
100414b12d0bSJaikumar Ganesh 
100514b12d0bSJaikumar Ganesh 		pwr.force_active = BT_POWER_FORCE_ACTIVE_ON;
100614b12d0bSJaikumar Ganesh 
10074f395124SLuiz Augusto von Dentz 		err = bt_copy_from_sockptr(&pwr, sizeof(pwr), optval, optlen);
10084f395124SLuiz Augusto von Dentz 		if (err)
100914b12d0bSJaikumar Ganesh 			break;
101015770b1aSAndrei Emeltchenko 
101115770b1aSAndrei Emeltchenko 		if (pwr.force_active)
101215770b1aSAndrei Emeltchenko 			set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
101315770b1aSAndrei Emeltchenko 		else
101415770b1aSAndrei Emeltchenko 			clear_bit(FLAG_FORCE_ACTIVE, &chan->flags);
101514b12d0bSJaikumar Ganesh 		break;
101614b12d0bSJaikumar Ganesh 
10172ea66482SMat Martineau 	case BT_CHANNEL_POLICY:
10184f395124SLuiz Augusto von Dentz 		err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
10194f395124SLuiz Augusto von Dentz 		if (err)
10202ea66482SMat Martineau 			break;
10212ea66482SMat Martineau 
10222ea66482SMat Martineau 		err = -EOPNOTSUPP;
10232ea66482SMat Martineau 		break;
102433575df7SGustavo F. Padovan 
10251f435424SJohan Hedberg 	case BT_SNDMTU:
10261f435424SJohan Hedberg 		if (!bdaddr_type_is_le(chan->src_type)) {
10271f435424SJohan Hedberg 			err = -EINVAL;
10281f435424SJohan Hedberg 			break;
10291f435424SJohan Hedberg 		}
10301f435424SJohan Hedberg 
10311f435424SJohan Hedberg 		/* Setting is not supported as it's the remote side that
10321f435424SJohan Hedberg 		 * decides this.
10331f435424SJohan Hedberg 		 */
10341f435424SJohan Hedberg 		err = -EPERM;
10351f435424SJohan Hedberg 		break;
10361f435424SJohan Hedberg 
10371f435424SJohan Hedberg 	case BT_RCVMTU:
10381f435424SJohan Hedberg 		if (!bdaddr_type_is_le(chan->src_type)) {
10391f435424SJohan Hedberg 			err = -EINVAL;
10401f435424SJohan Hedberg 			break;
10411f435424SJohan Hedberg 		}
10421f435424SJohan Hedberg 
104315f02b91SLuiz Augusto von Dentz 		if (chan->mode == L2CAP_MODE_LE_FLOWCTL &&
104415f02b91SLuiz Augusto von Dentz 		    sk->sk_state == BT_CONNECTED) {
10451f435424SJohan Hedberg 			err = -EISCONN;
10461f435424SJohan Hedberg 			break;
10471f435424SJohan Hedberg 		}
10481f435424SJohan Hedberg 
10494f395124SLuiz Augusto von Dentz 		err = bt_copy_from_sockptr(&mtu, sizeof(mtu), optval, optlen);
10504f395124SLuiz Augusto von Dentz 		if (err)
10511f435424SJohan Hedberg 			break;
10521f435424SJohan Hedberg 
105315f02b91SLuiz Augusto von Dentz 		if (chan->mode == L2CAP_MODE_EXT_FLOWCTL &&
105415f02b91SLuiz Augusto von Dentz 		    sk->sk_state == BT_CONNECTED)
10552b70d4f9SDan Carpenter 			err = l2cap_chan_reconfigure(chan, mtu);
105615f02b91SLuiz Augusto von Dentz 		else
10572b70d4f9SDan Carpenter 			chan->imtu = mtu;
105815f02b91SLuiz Augusto von Dentz 
10591f435424SJohan Hedberg 		break;
10601f435424SJohan Hedberg 
10613ee7b7cdSLuiz Augusto von Dentz 	case BT_MODE:
10623ee7b7cdSLuiz Augusto von Dentz 		if (!enable_ecred) {
10633ee7b7cdSLuiz Augusto von Dentz 			err = -ENOPROTOOPT;
10643ee7b7cdSLuiz Augusto von Dentz 			break;
10653ee7b7cdSLuiz Augusto von Dentz 		}
10663ee7b7cdSLuiz Augusto von Dentz 
10673ee7b7cdSLuiz Augusto von Dentz 		BT_DBG("sk->sk_state %u", sk->sk_state);
10683ee7b7cdSLuiz Augusto von Dentz 
10693ee7b7cdSLuiz Augusto von Dentz 		if (sk->sk_state != BT_BOUND) {
10703ee7b7cdSLuiz Augusto von Dentz 			err = -EINVAL;
10713ee7b7cdSLuiz Augusto von Dentz 			break;
10723ee7b7cdSLuiz Augusto von Dentz 		}
10733ee7b7cdSLuiz Augusto von Dentz 
10743ee7b7cdSLuiz Augusto von Dentz 		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
10753ee7b7cdSLuiz Augusto von Dentz 			err = -EINVAL;
10763ee7b7cdSLuiz Augusto von Dentz 			break;
10773ee7b7cdSLuiz Augusto von Dentz 		}
10783ee7b7cdSLuiz Augusto von Dentz 
10794f395124SLuiz Augusto von Dentz 		err = bt_copy_from_sockptr(&mode, sizeof(mode), optval, optlen);
10804f395124SLuiz Augusto von Dentz 		if (err)
10813ee7b7cdSLuiz Augusto von Dentz 			break;
10823ee7b7cdSLuiz Augusto von Dentz 
10832b70d4f9SDan Carpenter 		BT_DBG("mode %u", mode);
10843ee7b7cdSLuiz Augusto von Dentz 
10852b70d4f9SDan Carpenter 		err = l2cap_set_mode(chan, mode);
10863ee7b7cdSLuiz Augusto von Dentz 		if (err)
10873ee7b7cdSLuiz Augusto von Dentz 			break;
10883ee7b7cdSLuiz Augusto von Dentz 
10893ee7b7cdSLuiz Augusto von Dentz 		BT_DBG("mode 0x%2.2x", chan->mode);
10903ee7b7cdSLuiz Augusto von Dentz 
10913ee7b7cdSLuiz Augusto von Dentz 		break;
10923ee7b7cdSLuiz Augusto von Dentz 
109333575df7SGustavo F. Padovan 	default:
109433575df7SGustavo F. Padovan 		err = -ENOPROTOOPT;
109533575df7SGustavo F. Padovan 		break;
109633575df7SGustavo F. Padovan 	}
109733575df7SGustavo F. Padovan 
109833575df7SGustavo F. Padovan 	release_sock(sk);
109933575df7SGustavo F. Padovan 	return err;
110033575df7SGustavo F. Padovan }
110133575df7SGustavo F. Padovan 
l2cap_sock_sendmsg(struct socket * sock,struct msghdr * msg,size_t len)11021b784140SYing Xue static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg,
11031b784140SYing Xue 			      size_t len)
1104fd83ccdbSGustavo F. Padovan {
1105fd83ccdbSGustavo F. Padovan 	struct sock *sk = sock->sk;
11060c1bc5c6SGustavo F. Padovan 	struct l2cap_chan *chan = l2cap_pi(sk)->chan;
1107fd83ccdbSGustavo F. Padovan 	int err;
1108fd83ccdbSGustavo F. Padovan 
1109fd83ccdbSGustavo F. Padovan 	BT_DBG("sock %p, sk %p", sock, sk);
1110fd83ccdbSGustavo F. Padovan 
1111fd83ccdbSGustavo F. Padovan 	err = sock_error(sk);
1112fd83ccdbSGustavo F. Padovan 	if (err)
1113fd83ccdbSGustavo F. Padovan 		return err;
1114fd83ccdbSGustavo F. Padovan 
1115fd83ccdbSGustavo F. Padovan 	if (msg->msg_flags & MSG_OOB)
1116fd83ccdbSGustavo F. Padovan 		return -EOPNOTSUPP;
1117fd83ccdbSGustavo F. Padovan 
1118a6a5568cSMat Martineau 	if (sk->sk_state != BT_CONNECTED)
11199a91a04aSGustavo F. Padovan 		return -ENOTCONN;
1120fd83ccdbSGustavo F. Padovan 
1121e793dcf0SJohan Hedberg 	lock_sock(sk);
1122e793dcf0SJohan Hedberg 	err = bt_sock_wait_ready(sk, msg->msg_flags);
1123e793dcf0SJohan Hedberg 	release_sock(sk);
1124e793dcf0SJohan Hedberg 	if (err)
1125e793dcf0SJohan Hedberg 		return err;
1126e793dcf0SJohan Hedberg 
1127a6a5568cSMat Martineau 	l2cap_chan_lock(chan);
11288d46321cSMarcel Holtmann 	err = l2cap_chan_send(chan, msg, len);
1129a6a5568cSMat Martineau 	l2cap_chan_unlock(chan);
1130fd83ccdbSGustavo F. Padovan 
1131fd83ccdbSGustavo F. Padovan 	return err;
1132fd83ccdbSGustavo F. Padovan }
1133fd83ccdbSGustavo F. Padovan 
l2cap_publish_rx_avail(struct l2cap_chan * chan)1134ce60b923SSebastian Urban static void l2cap_publish_rx_avail(struct l2cap_chan *chan)
1135ce60b923SSebastian Urban {
1136ce60b923SSebastian Urban 	struct sock *sk = chan->data;
1137ce60b923SSebastian Urban 	ssize_t avail = sk->sk_rcvbuf - atomic_read(&sk->sk_rmem_alloc);
1138ce60b923SSebastian Urban 	int expected_skbs, skb_overhead;
1139ce60b923SSebastian Urban 
1140ce60b923SSebastian Urban 	if (avail <= 0) {
1141ce60b923SSebastian Urban 		l2cap_chan_rx_avail(chan, 0);
1142ce60b923SSebastian Urban 		return;
1143ce60b923SSebastian Urban 	}
1144ce60b923SSebastian Urban 
1145ce60b923SSebastian Urban 	if (!chan->mps) {
1146ce60b923SSebastian Urban 		l2cap_chan_rx_avail(chan, -1);
1147ce60b923SSebastian Urban 		return;
1148ce60b923SSebastian Urban 	}
1149ce60b923SSebastian Urban 
1150ce60b923SSebastian Urban 	/* Correct available memory by estimated sk_buff overhead.
1151ce60b923SSebastian Urban 	 * This is significant due to small transfer sizes. However, accept
1152ce60b923SSebastian Urban 	 * at least one full packet if receive space is non-zero.
1153ce60b923SSebastian Urban 	 */
1154ce60b923SSebastian Urban 	expected_skbs = DIV_ROUND_UP(avail, chan->mps);
1155ce60b923SSebastian Urban 	skb_overhead = expected_skbs * sizeof(struct sk_buff);
1156ce60b923SSebastian Urban 	if (skb_overhead < avail)
1157ce60b923SSebastian Urban 		l2cap_chan_rx_avail(chan, avail - skb_overhead);
1158ce60b923SSebastian Urban 	else
1159ce60b923SSebastian Urban 		l2cap_chan_rx_avail(chan, -1);
1160ce60b923SSebastian Urban }
1161ce60b923SSebastian Urban 
l2cap_sock_recvmsg(struct socket * sock,struct msghdr * msg,size_t len,int flags)11621b784140SYing Xue static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg,
11631b784140SYing Xue 			      size_t len, int flags)
116468983259SGustavo F. Padovan {
116568983259SGustavo F. Padovan 	struct sock *sk = sock->sk;
1166e328140fSMat Martineau 	struct l2cap_pinfo *pi = l2cap_pi(sk);
1167e328140fSMat Martineau 	int err;
116868983259SGustavo F. Padovan 
116968983259SGustavo F. Padovan 	lock_sock(sk);
117068983259SGustavo F. Padovan 
1171c5daa683SGustavo Padovan 	if (sk->sk_state == BT_CONNECT2 && test_bit(BT_SK_DEFER_SETUP,
1172c5daa683SGustavo Padovan 						    &bt_sk(sk)->flags)) {
117315f02b91SLuiz Augusto von Dentz 		if (pi->chan->mode == L2CAP_MODE_EXT_FLOWCTL) {
117415f02b91SLuiz Augusto von Dentz 			sk->sk_state = BT_CONNECTED;
117515f02b91SLuiz Augusto von Dentz 			pi->chan->state = BT_CONNECTED;
117615f02b91SLuiz Augusto von Dentz 			__l2cap_ecred_conn_rsp_defer(pi->chan);
1177b354e6c1SDan Carpenter 		} else if (bdaddr_type_is_le(pi->chan->src_type)) {
117838319713SJohan Hedberg 			sk->sk_state = BT_CONNECTED;
117938319713SJohan Hedberg 			pi->chan->state = BT_CONNECTED;
118038319713SJohan Hedberg 			__l2cap_le_connect_rsp_defer(pi->chan);
118138319713SJohan Hedberg 		} else {
11828c1d787bSGustavo F. Padovan 			sk->sk_state = BT_CONFIG;
11833542b854SGustavo F. Padovan 			pi->chan->state = BT_CONFIG;
1184e328140fSMat Martineau 			__l2cap_connect_rsp_defer(pi->chan);
118538319713SJohan Hedberg 		}
118638319713SJohan Hedberg 
1187970871bcSJohan Hedberg 		err = 0;
1188970871bcSJohan Hedberg 		goto done;
118968983259SGustavo F. Padovan 	}
119068983259SGustavo F. Padovan 
119168983259SGustavo F. Padovan 	release_sock(sk);
119268983259SGustavo F. Padovan 
119368983259SGustavo F. Padovan 	if (sock->type == SOCK_STREAM)
11941b784140SYing Xue 		err = bt_sock_stream_recvmsg(sock, msg, len, flags);
1195e328140fSMat Martineau 	else
11961b784140SYing Xue 		err = bt_sock_recvmsg(sock, msg, len, flags);
119768983259SGustavo F. Padovan 
1198ce60b923SSebastian Urban 	if (pi->chan->mode != L2CAP_MODE_ERTM &&
1199ce60b923SSebastian Urban 	    pi->chan->mode != L2CAP_MODE_LE_FLOWCTL &&
1200ce60b923SSebastian Urban 	    pi->chan->mode != L2CAP_MODE_EXT_FLOWCTL)
1201e328140fSMat Martineau 		return err;
1202e328140fSMat Martineau 
1203e328140fSMat Martineau 	lock_sock(sk);
1204e328140fSMat Martineau 
1205ce60b923SSebastian Urban 	l2cap_publish_rx_avail(pi->chan);
1206e328140fSMat Martineau 
1207ce60b923SSebastian Urban 	/* Attempt to put pending rx data in the socket buffer */
1208ce60b923SSebastian Urban 	while (!list_empty(&pi->rx_busy)) {
1209ce60b923SSebastian Urban 		struct l2cap_rx_busy *rx_busy =
1210ce60b923SSebastian Urban 			list_first_entry(&pi->rx_busy,
1211ce60b923SSebastian Urban 					 struct l2cap_rx_busy,
1212ce60b923SSebastian Urban 					 list);
1213ce60b923SSebastian Urban 		if (__sock_queue_rcv_skb(sk, rx_busy->skb) < 0)
1214e328140fSMat Martineau 			goto done;
1215ce60b923SSebastian Urban 		list_del(&rx_busy->list);
1216ce60b923SSebastian Urban 		kfree(rx_busy);
1217e328140fSMat Martineau 	}
1218e328140fSMat Martineau 
1219e328140fSMat Martineau 	/* Restore data flow when half of the receive buffer is
1220e328140fSMat Martineau 	 * available.  This avoids resending large numbers of
1221e328140fSMat Martineau 	 * frames.
1222e328140fSMat Martineau 	 */
1223ce60b923SSebastian Urban 	if (test_bit(CONN_LOCAL_BUSY, &pi->chan->conn_state) &&
1224ce60b923SSebastian Urban 	    atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf >> 1)
1225e328140fSMat Martineau 		l2cap_chan_busy(pi->chan, 0);
1226e328140fSMat Martineau 
1227e328140fSMat Martineau done:
1228e328140fSMat Martineau 	release_sock(sk);
1229e328140fSMat Martineau 	return err;
123068983259SGustavo F. Padovan }
123168983259SGustavo F. Padovan 
123205fc1576SGustavo F. Padovan /* Kill socket (only if zapped and orphan)
12336c08fc89SManish Mandlik  * Must be called on unlocked socket, with l2cap channel lock.
123405fc1576SGustavo F. Padovan  */
l2cap_sock_kill(struct sock * sk)1235ba3bd0eeSGustavo F. Padovan static void l2cap_sock_kill(struct sock *sk)
123605fc1576SGustavo F. Padovan {
123705fc1576SGustavo F. Padovan 	if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
123805fc1576SGustavo F. Padovan 		return;
123905fc1576SGustavo F. Padovan 
1240e05dcc32SAndrei Emeltchenko 	BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state));
124105fc1576SGustavo F. Padovan 
124289e856e1SEdward Adam Davis 	/* Sock is dead, so set chan data to NULL, avoid other task use invalid
124389e856e1SEdward Adam Davis 	 * sock pointer.
124489e856e1SEdward Adam Davis 	 */
124589e856e1SEdward Adam Davis 	l2cap_pi(sk)->chan->data = NULL;
124605fc1576SGustavo F. Padovan 	/* Kill poor orphan */
12476ff5abbfSGustavo F. Padovan 
12484af66c69SJaganath Kanakkassery 	l2cap_chan_put(l2cap_pi(sk)->chan);
124905fc1576SGustavo F. Padovan 	sock_set_flag(sk, SOCK_DEAD);
125005fc1576SGustavo F. Padovan 	sock_put(sk);
125105fc1576SGustavo F. Padovan }
125205fc1576SGustavo F. Padovan 
__l2cap_wait_ack(struct sock * sk,struct l2cap_chan * chan)1253f65468f6SDean Jenkins static int __l2cap_wait_ack(struct sock *sk, struct l2cap_chan *chan)
1254dc25306bSGustavo Padovan {
1255dc25306bSGustavo Padovan 	DECLARE_WAITQUEUE(wait, current);
1256dc25306bSGustavo Padovan 	int err = 0;
1257cb02a255SDean Jenkins 	int timeo = L2CAP_WAIT_ACK_POLL_PERIOD;
1258e432c72cSDean Jenkins 	/* Timeout to prevent infinite loop */
1259e432c72cSDean Jenkins 	unsigned long timeout = jiffies + L2CAP_WAIT_ACK_TIMEOUT;
1260dc25306bSGustavo Padovan 
1261dc25306bSGustavo Padovan 	add_wait_queue(sk_sleep(sk), &wait);
1262dc25306bSGustavo Padovan 	set_current_state(TASK_INTERRUPTIBLE);
1263f65468f6SDean Jenkins 	do {
1264e432c72cSDean Jenkins 		BT_DBG("Waiting for %d ACKs, timeout %04d ms",
1265e432c72cSDean Jenkins 		       chan->unacked_frames, time_after(jiffies, timeout) ? 0 :
1266e432c72cSDean Jenkins 		       jiffies_to_msecs(timeout - jiffies));
1267451e4c6cSDean Jenkins 
1268dc25306bSGustavo Padovan 		if (!timeo)
1269cb02a255SDean Jenkins 			timeo = L2CAP_WAIT_ACK_POLL_PERIOD;
1270dc25306bSGustavo Padovan 
1271dc25306bSGustavo Padovan 		if (signal_pending(current)) {
1272dc25306bSGustavo Padovan 			err = sock_intr_errno(timeo);
1273dc25306bSGustavo Padovan 			break;
1274dc25306bSGustavo Padovan 		}
1275dc25306bSGustavo Padovan 
1276dc25306bSGustavo Padovan 		release_sock(sk);
1277dc25306bSGustavo Padovan 		timeo = schedule_timeout(timeo);
1278dc25306bSGustavo Padovan 		lock_sock(sk);
1279dc25306bSGustavo Padovan 		set_current_state(TASK_INTERRUPTIBLE);
1280dc25306bSGustavo Padovan 
1281dc25306bSGustavo Padovan 		err = sock_error(sk);
1282dc25306bSGustavo Padovan 		if (err)
1283dc25306bSGustavo Padovan 			break;
1284f65468f6SDean Jenkins 
1285e432c72cSDean Jenkins 		if (time_after(jiffies, timeout)) {
1286e432c72cSDean Jenkins 			err = -ENOLINK;
1287e432c72cSDean Jenkins 			break;
1288e432c72cSDean Jenkins 		}
1289e432c72cSDean Jenkins 
1290f65468f6SDean Jenkins 	} while (chan->unacked_frames > 0 &&
1291f65468f6SDean Jenkins 		 chan->state == BT_CONNECTED);
1292f65468f6SDean Jenkins 
1293dc25306bSGustavo Padovan 	set_current_state(TASK_RUNNING);
1294dc25306bSGustavo Padovan 	remove_wait_queue(sk_sleep(sk), &wait);
1295dc25306bSGustavo Padovan 	return err;
1296dc25306bSGustavo Padovan }
1297dc25306bSGustavo Padovan 
l2cap_sock_shutdown(struct socket * sock,int how)1298dcba0dbaSGustavo F. Padovan static int l2cap_sock_shutdown(struct socket *sock, int how)
1299dcba0dbaSGustavo F. Padovan {
1300dcba0dbaSGustavo F. Padovan 	struct sock *sk = sock->sk;
13017ddb6e0fSAndrei Emeltchenko 	struct l2cap_chan *chan;
13023df91ea2SAndrei Emeltchenko 	struct l2cap_conn *conn;
1303dcba0dbaSGustavo F. Padovan 	int err = 0;
1304dcba0dbaSGustavo F. Padovan 
13055b440676SArchie Pusaka 	BT_DBG("sock %p, sk %p, how %d", sock, sk, how);
13065b440676SArchie Pusaka 
13075b440676SArchie Pusaka 	/* 'how' parameter is mapped to sk_shutdown as follows:
13085b440676SArchie Pusaka 	 * SHUT_RD   (0) --> RCV_SHUTDOWN  (1)
13095b440676SArchie Pusaka 	 * SHUT_WR   (1) --> SEND_SHUTDOWN (2)
13105b440676SArchie Pusaka 	 * SHUT_RDWR (2) --> SHUTDOWN_MASK (3)
13115b440676SArchie Pusaka 	 */
13125b440676SArchie Pusaka 	how++;
1313dcba0dbaSGustavo F. Padovan 
1314dcba0dbaSGustavo F. Padovan 	if (!sk)
1315dcba0dbaSGustavo F. Padovan 		return 0;
1316dcba0dbaSGustavo F. Padovan 
131704ba72e6SDean Jenkins 	lock_sock(sk);
131804ba72e6SDean Jenkins 
13195b440676SArchie Pusaka 	if ((sk->sk_shutdown & how) == how)
1320e7456437SDean Jenkins 		goto shutdown_already;
1321e7456437SDean Jenkins 
1322e7456437SDean Jenkins 	BT_DBG("Handling sock shutdown");
1323e7456437SDean Jenkins 
13242baea85dSDean Jenkins 	/* prevent sk structure from being freed whilst unlocked */
13252baea85dSDean Jenkins 	sock_hold(sk);
13262baea85dSDean Jenkins 
13277ddb6e0fSAndrei Emeltchenko 	chan = l2cap_pi(sk)->chan;
13282baea85dSDean Jenkins 	/* prevent chan structure from being freed whilst unlocked */
13292baea85dSDean Jenkins 	l2cap_chan_hold(chan);
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 	conn = chan->conn;
136004ba72e6SDean Jenkins 	if (conn)
136104ba72e6SDean Jenkins 		/* prevent conn structure from being freed */
136204ba72e6SDean Jenkins 		l2cap_conn_get(conn);
136304ba72e6SDean Jenkins 	l2cap_chan_unlock(chan);
136404ba72e6SDean Jenkins 
136504ba72e6SDean Jenkins 	if (conn)
136604ba72e6SDean Jenkins 		/* mutex lock must be taken before l2cap_chan_lock() */
136704ba72e6SDean Jenkins 		mutex_lock(&conn->chan_lock);
136804ba72e6SDean Jenkins 
136904ba72e6SDean Jenkins 	l2cap_chan_lock(chan);
13700f852724SGustavo F. Padovan 	l2cap_chan_close(chan, 0);
137104ba72e6SDean Jenkins 	l2cap_chan_unlock(chan);
137204ba72e6SDean Jenkins 
137304ba72e6SDean Jenkins 	if (conn) {
137404ba72e6SDean Jenkins 		mutex_unlock(&conn->chan_lock);
137504ba72e6SDean Jenkins 		l2cap_conn_put(conn);
137604ba72e6SDean Jenkins 	}
137704ba72e6SDean Jenkins 
13786be36555SAndrei Emeltchenko 	lock_sock(sk);
1379dcba0dbaSGustavo F. Padovan 
1380093facf3SVladimir Davydov 	if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
1381093facf3SVladimir Davydov 	    !(current->flags & PF_EXITING))
1382dcba0dbaSGustavo F. Padovan 		err = bt_sock_wait_state(sk, BT_CLOSED,
1383dcba0dbaSGustavo F. Padovan 					 sk->sk_lingertime);
1384dcba0dbaSGustavo F. Padovan 
13855b440676SArchie Pusaka shutdown_matched:
13862baea85dSDean Jenkins 	l2cap_chan_put(chan);
13872baea85dSDean Jenkins 	sock_put(sk);
13882baea85dSDean Jenkins 
1389e7456437SDean Jenkins shutdown_already:
139004ba72e6SDean Jenkins 	if (!err && sk->sk_err)
139104ba72e6SDean Jenkins 		err = -sk->sk_err;
139204ba72e6SDean Jenkins 
139304ba72e6SDean Jenkins 	release_sock(sk);
139404ba72e6SDean Jenkins 
139504ba72e6SDean Jenkins 	BT_DBG("Sock shutdown complete err: %d", err);
1396451e4c6cSDean Jenkins 
1397dcba0dbaSGustavo F. Padovan 	return err;
1398dcba0dbaSGustavo F. Padovan }
1399dcba0dbaSGustavo F. Padovan 
l2cap_sock_release(struct socket * sock)1400554f05bbSGustavo F. Padovan static int l2cap_sock_release(struct socket *sock)
1401554f05bbSGustavo F. Padovan {
1402554f05bbSGustavo F. Padovan 	struct sock *sk = sock->sk;
1403554f05bbSGustavo F. Padovan 	int err;
14042a154903SHillf Danton 	struct l2cap_chan *chan;
1405554f05bbSGustavo F. Padovan 
1406554f05bbSGustavo F. Padovan 	BT_DBG("sock %p, sk %p", sock, sk);
1407554f05bbSGustavo F. Padovan 
1408554f05bbSGustavo F. Padovan 	if (!sk)
1409554f05bbSGustavo F. Padovan 		return 0;
1410554f05bbSGustavo F. Padovan 
14111728137bSSungwoo Kim 	l2cap_sock_cleanup_listen(sk);
14125b28d95cSMasatake YAMATO 	bt_sock_unlink(&l2cap_sk_list, sk);
14135b28d95cSMasatake YAMATO 
14145b440676SArchie Pusaka 	err = l2cap_sock_shutdown(sock, SHUT_RDWR);
14152a154903SHillf Danton 	chan = l2cap_pi(sk)->chan;
1416554f05bbSGustavo F. Padovan 
14172a154903SHillf Danton 	l2cap_chan_hold(chan);
14182a154903SHillf Danton 	l2cap_chan_lock(chan);
14196c08fc89SManish Mandlik 
1420554f05bbSGustavo F. Padovan 	sock_orphan(sk);
1421554f05bbSGustavo F. Padovan 	l2cap_sock_kill(sk);
14226c08fc89SManish Mandlik 
14232a154903SHillf Danton 	l2cap_chan_unlock(chan);
14242a154903SHillf Danton 	l2cap_chan_put(chan);
14256c08fc89SManish Mandlik 
1426554f05bbSGustavo F. Padovan 	return err;
1427554f05bbSGustavo F. Padovan }
1428554f05bbSGustavo F. Padovan 
l2cap_sock_cleanup_listen(struct sock * parent)1429c0df7f6eSAndrei Emeltchenko static void l2cap_sock_cleanup_listen(struct sock *parent)
1430c0df7f6eSAndrei Emeltchenko {
1431c0df7f6eSAndrei Emeltchenko 	struct sock *sk;
1432c0df7f6eSAndrei Emeltchenko 
143349d11741SJohan Hedberg 	BT_DBG("parent %p state %s", parent,
143449d11741SJohan Hedberg 	       state_to_string(parent->sk_state));
1435c0df7f6eSAndrei Emeltchenko 
1436c0df7f6eSAndrei Emeltchenko 	/* Close not yet accepted channels */
1437c0df7f6eSAndrei Emeltchenko 	while ((sk = bt_accept_dequeue(parent, NULL))) {
1438c0df7f6eSAndrei Emeltchenko 		struct l2cap_chan *chan = l2cap_pi(sk)->chan;
1439c0df7f6eSAndrei Emeltchenko 
144049d11741SJohan Hedberg 		BT_DBG("child chan %p state %s", chan,
144149d11741SJohan Hedberg 		       state_to_string(chan->state));
144249d11741SJohan Hedberg 
14436c08fc89SManish Mandlik 		l2cap_chan_hold(chan);
1444c0df7f6eSAndrei Emeltchenko 		l2cap_chan_lock(chan);
14456c08fc89SManish Mandlik 
1446c0df7f6eSAndrei Emeltchenko 		__clear_chan_timer(chan);
1447c0df7f6eSAndrei Emeltchenko 		l2cap_chan_close(chan, ECONNRESET);
1448c0df7f6eSAndrei Emeltchenko 		l2cap_sock_kill(sk);
14496c08fc89SManish Mandlik 
14506c08fc89SManish Mandlik 		l2cap_chan_unlock(chan);
14516c08fc89SManish Mandlik 		l2cap_chan_put(chan);
1452c0df7f6eSAndrei Emeltchenko 	}
1453c0df7f6eSAndrei Emeltchenko }
1454c0df7f6eSAndrei Emeltchenko 
l2cap_sock_new_connection_cb(struct l2cap_chan * chan)145580b98027SGustavo Padovan static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
145680808e43SGustavo F. Padovan {
145780b98027SGustavo Padovan 	struct sock *sk, *parent = chan->data;
145880808e43SGustavo F. Padovan 
14598ffb9290SGustavo Padovan 	lock_sock(parent);
14608ffb9290SGustavo Padovan 
146153826692SGustavo Padovan 	/* Check for backlog size */
146253826692SGustavo Padovan 	if (sk_acceptq_is_full(parent)) {
146353826692SGustavo Padovan 		BT_DBG("backlog full %d", parent->sk_ack_backlog);
14648a96f3cdSJukka Taimisto 		release_sock(parent);
146553826692SGustavo Padovan 		return NULL;
146653826692SGustavo Padovan 	}
146753826692SGustavo Padovan 
146880808e43SGustavo F. Padovan 	sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP,
146911aa9c28SEric W. Biederman 			      GFP_ATOMIC, 0);
14708a96f3cdSJukka Taimisto 	if (!sk) {
14718a96f3cdSJukka Taimisto 		release_sock(parent);
147280808e43SGustavo F. Padovan 		return NULL;
14738a96f3cdSJukka Taimisto         }
147480808e43SGustavo F. Padovan 
1475d22015aaSOctavian Purdila 	bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
1476d22015aaSOctavian Purdila 
147780808e43SGustavo F. Padovan 	l2cap_sock_init(sk, parent);
147880808e43SGustavo F. Padovan 
1479c4f5627fSMatthias Kaehlcke 	bt_accept_enqueue(parent, sk, false);
1480644912e1SGustavo Padovan 
14818ffb9290SGustavo Padovan 	release_sock(parent);
14828ffb9290SGustavo Padovan 
148380808e43SGustavo F. Padovan 	return l2cap_pi(sk)->chan;
148480808e43SGustavo F. Padovan }
148580808e43SGustavo F. Padovan 
l2cap_sock_recv_cb(struct l2cap_chan * chan,struct sk_buff * skb)148680b98027SGustavo Padovan static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
148723070494SGustavo F. Padovan {
148889e856e1SEdward Adam Davis 	struct sock *sk;
148989e856e1SEdward Adam Davis 	struct l2cap_pinfo *pi;
149084b34d98SMarcel Holtmann 	int err;
149123070494SGustavo F. Padovan 
149289e856e1SEdward Adam Davis 	sk = chan->data;
1493*f1a8f402SLuiz Augusto von Dentz 	if (!sk)
149489e856e1SEdward Adam Davis 		return -ENXIO;
149589e856e1SEdward Adam Davis 
149689e856e1SEdward Adam Davis 	pi = l2cap_pi(sk);
149789e856e1SEdward Adam Davis 	lock_sock(sk);
1498ce60b923SSebastian Urban 	if (chan->mode == L2CAP_MODE_ERTM && !list_empty(&pi->rx_busy)) {
14996be36555SAndrei Emeltchenko 		err = -ENOMEM;
15006be36555SAndrei Emeltchenko 		goto done;
15016be36555SAndrei Emeltchenko 	}
1502e328140fSMat Martineau 
1503dbb50887SDaniel Borkmann 	if (chan->mode != L2CAP_MODE_ERTM &&
1504ce60b923SSebastian Urban 	    chan->mode != L2CAP_MODE_STREAMING &&
1505ce60b923SSebastian Urban 	    chan->mode != L2CAP_MODE_LE_FLOWCTL &&
1506ce60b923SSebastian Urban 	    chan->mode != L2CAP_MODE_EXT_FLOWCTL) {
1507dbb50887SDaniel Borkmann 		/* Even if no filter is attached, we could potentially
1508dbb50887SDaniel Borkmann 		 * get errors from security modules, etc.
1509dbb50887SDaniel Borkmann 		 */
1510dbb50887SDaniel Borkmann 		err = sk_filter(sk, skb);
1511dbb50887SDaniel Borkmann 		if (err)
1512dbb50887SDaniel Borkmann 			goto done;
1513dbb50887SDaniel Borkmann 	}
1514dbb50887SDaniel Borkmann 
1515dbb50887SDaniel Borkmann 	err = __sock_queue_rcv_skb(sk, skb);
1516e328140fSMat Martineau 
1517ce60b923SSebastian Urban 	l2cap_publish_rx_avail(chan);
1518ce60b923SSebastian Urban 
1519ce60b923SSebastian Urban 	/* For ERTM and LE, handle a skb that doesn't fit into the recv
1520e328140fSMat Martineau 	 * buffer.  This is important to do because the data frames
1521e328140fSMat Martineau 	 * have already been acked, so the skb cannot be discarded.
1522e328140fSMat Martineau 	 *
1523e328140fSMat Martineau 	 * Notify the l2cap core that the buffer is full, so the
1524e328140fSMat Martineau 	 * LOCAL_BUSY state is entered and no more frames are
1525e328140fSMat Martineau 	 * acked and reassembled until there is buffer space
1526e328140fSMat Martineau 	 * available.
1527e328140fSMat Martineau 	 */
1528ce60b923SSebastian Urban 	if (err < 0 &&
1529ce60b923SSebastian Urban 	    (chan->mode == L2CAP_MODE_ERTM ||
1530ce60b923SSebastian Urban 	     chan->mode == L2CAP_MODE_LE_FLOWCTL ||
1531ce60b923SSebastian Urban 	     chan->mode == L2CAP_MODE_EXT_FLOWCTL)) {
1532ce60b923SSebastian Urban 		struct l2cap_rx_busy *rx_busy =
1533ce60b923SSebastian Urban 			kmalloc(sizeof(*rx_busy), GFP_KERNEL);
1534ce60b923SSebastian Urban 		if (!rx_busy) {
1535ce60b923SSebastian Urban 			err = -ENOMEM;
1536ce60b923SSebastian Urban 			goto done;
1537ce60b923SSebastian Urban 		}
1538ce60b923SSebastian Urban 		rx_busy->skb = skb;
1539ce60b923SSebastian Urban 		list_add_tail(&rx_busy->list, &pi->rx_busy);
154084b34d98SMarcel Holtmann 		l2cap_chan_busy(chan, 1);
1541e328140fSMat Martineau 		err = 0;
1542e328140fSMat Martineau 	}
1543e328140fSMat Martineau 
15446be36555SAndrei Emeltchenko done:
15456be36555SAndrei Emeltchenko 	release_sock(sk);
15466be36555SAndrei Emeltchenko 
1547e328140fSMat Martineau 	return err;
154823070494SGustavo F. Padovan }
154923070494SGustavo F. Padovan 
l2cap_sock_close_cb(struct l2cap_chan * chan)155080b98027SGustavo Padovan static void l2cap_sock_close_cb(struct l2cap_chan *chan)
1551ba3bd0eeSGustavo F. Padovan {
155280b98027SGustavo Padovan 	struct sock *sk = chan->data;
1553ba3bd0eeSGustavo F. Padovan 
15541bff51eaSWang ShaoBo 	if (!sk)
15551bff51eaSWang ShaoBo 		return;
15561bff51eaSWang ShaoBo 
1557ba3bd0eeSGustavo F. Padovan 	l2cap_sock_kill(sk);
1558ba3bd0eeSGustavo F. Padovan }
1559ba3bd0eeSGustavo F. Padovan 
l2cap_sock_teardown_cb(struct l2cap_chan * chan,int err)1560c0df7f6eSAndrei Emeltchenko static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err)
1561c0df7f6eSAndrei Emeltchenko {
1562c0df7f6eSAndrei Emeltchenko 	struct sock *sk = chan->data;
1563c0df7f6eSAndrei Emeltchenko 	struct sock *parent;
1564c0df7f6eSAndrei Emeltchenko 
15651bff51eaSWang ShaoBo 	if (!sk)
15661bff51eaSWang ShaoBo 		return;
15671bff51eaSWang ShaoBo 
156849d11741SJohan Hedberg 	BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
156949d11741SJohan Hedberg 
15703b2ab39eSJohan Hedberg 	/* This callback can be called both for server (BT_LISTEN)
15713b2ab39eSJohan Hedberg 	 * sockets as well as "normal" ones. To avoid lockdep warnings
15723b2ab39eSJohan Hedberg 	 * with child socket locking (through l2cap_sock_cleanup_listen)
15733b2ab39eSJohan Hedberg 	 * we need separation into separate nesting levels. The simplest
15743b2ab39eSJohan Hedberg 	 * way to accomplish this is to inherit the nesting level used
15753b2ab39eSJohan Hedberg 	 * for the channel.
15763b2ab39eSJohan Hedberg 	 */
15773b2ab39eSJohan Hedberg 	lock_sock_nested(sk, atomic_read(&chan->nesting));
1578c0df7f6eSAndrei Emeltchenko 
1579c0df7f6eSAndrei Emeltchenko 	parent = bt_sk(sk)->parent;
1580c0df7f6eSAndrei Emeltchenko 
1581c0df7f6eSAndrei Emeltchenko 	switch (chan->state) {
1582c0df7f6eSAndrei Emeltchenko 	case BT_OPEN:
1583c0df7f6eSAndrei Emeltchenko 	case BT_BOUND:
1584c0df7f6eSAndrei Emeltchenko 	case BT_CLOSED:
1585c0df7f6eSAndrei Emeltchenko 		break;
1586c0df7f6eSAndrei Emeltchenko 	case BT_LISTEN:
1587c0df7f6eSAndrei Emeltchenko 		l2cap_sock_cleanup_listen(sk);
1588c0df7f6eSAndrei Emeltchenko 		sk->sk_state = BT_CLOSED;
1589c0df7f6eSAndrei Emeltchenko 		chan->state = BT_CLOSED;
1590c0df7f6eSAndrei Emeltchenko 
1591c0df7f6eSAndrei Emeltchenko 		break;
1592c0df7f6eSAndrei Emeltchenko 	default:
1593c0df7f6eSAndrei Emeltchenko 		sk->sk_state = BT_CLOSED;
1594c0df7f6eSAndrei Emeltchenko 		chan->state = BT_CLOSED;
1595c0df7f6eSAndrei Emeltchenko 
1596c0df7f6eSAndrei Emeltchenko 		sk->sk_err = err;
1597c0df7f6eSAndrei Emeltchenko 
1598c0df7f6eSAndrei Emeltchenko 		if (parent) {
1599c0df7f6eSAndrei Emeltchenko 			bt_accept_unlink(sk);
1600676d2369SDavid S. Miller 			parent->sk_data_ready(parent);
1601c0df7f6eSAndrei Emeltchenko 		} else {
1602c0df7f6eSAndrei Emeltchenko 			sk->sk_state_change(sk);
1603c0df7f6eSAndrei Emeltchenko 		}
1604c0df7f6eSAndrei Emeltchenko 
1605c0df7f6eSAndrei Emeltchenko 		break;
1606c0df7f6eSAndrei Emeltchenko 	}
1607c0df7f6eSAndrei Emeltchenko 	release_sock(sk);
160820ae4089SAbhishek Pandit-Subedi 
160920ae4089SAbhishek Pandit-Subedi 	/* Only zap after cleanup to avoid use after free race */
161020ae4089SAbhishek Pandit-Subedi 	sock_set_flag(sk, SOCK_ZAPPED);
161120ae4089SAbhishek Pandit-Subedi 
1612c0df7f6eSAndrei Emeltchenko }
1613c0df7f6eSAndrei Emeltchenko 
l2cap_sock_state_change_cb(struct l2cap_chan * chan,int state,int err)161453f52121SGustavo Padovan static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state,
161553f52121SGustavo Padovan 				       int err)
161689bc500eSGustavo F. Padovan {
161780b98027SGustavo Padovan 	struct sock *sk = chan->data;
161889bc500eSGustavo F. Padovan 
161989bc500eSGustavo F. Padovan 	sk->sk_state = state;
162053f52121SGustavo Padovan 
162153f52121SGustavo Padovan 	if (err)
162253f52121SGustavo Padovan 		sk->sk_err = err;
162389bc500eSGustavo F. Padovan }
162489bc500eSGustavo F. Padovan 
l2cap_sock_alloc_skb_cb(struct l2cap_chan * chan,unsigned long hdr_len,unsigned long len,int nb)16252f7719ceSAndrei Emeltchenko static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
1626d9fbd02bSMarcel Holtmann 					       unsigned long hdr_len,
162790338947SGustavo Padovan 					       unsigned long len, int nb)
16282f7719ceSAndrei Emeltchenko {
16290f2c6153SGustavo Padovan 	struct sock *sk = chan->data;
163090338947SGustavo Padovan 	struct sk_buff *skb;
163190338947SGustavo Padovan 	int err;
16322f7719ceSAndrei Emeltchenko 
1633a6a5568cSMat Martineau 	l2cap_chan_unlock(chan);
1634d9fbd02bSMarcel Holtmann 	skb = bt_skb_send_alloc(sk, hdr_len + len, nb, &err);
1635a6a5568cSMat Martineau 	l2cap_chan_lock(chan);
1636a6a5568cSMat Martineau 
163790338947SGustavo Padovan 	if (!skb)
163890338947SGustavo Padovan 		return ERR_PTR(err);
163990338947SGustavo Padovan 
1640df570334SLuiz Augusto von Dentz 	/* Channel lock is released before requesting new skb and then
1641df570334SLuiz Augusto von Dentz 	 * reacquired thus we need to recheck channel state.
1642df570334SLuiz Augusto von Dentz 	 */
1643df570334SLuiz Augusto von Dentz 	if (chan->state != BT_CONNECTED) {
1644df570334SLuiz Augusto von Dentz 		kfree_skb(skb);
1645df570334SLuiz Augusto von Dentz 		return ERR_PTR(-ENOTCONN);
1646df570334SLuiz Augusto von Dentz 	}
1647df570334SLuiz Augusto von Dentz 
164810bbf165SEric Dumazet 	skb->priority = READ_ONCE(sk->sk_priority);
16498d46321cSMarcel Holtmann 
1650a4368ff3SJohan Hedberg 	bt_cb(skb)->l2cap.chan = chan;
16510e790c64SGustavo Padovan 
165290338947SGustavo Padovan 	return skb;
16532f7719ceSAndrei Emeltchenko }
16542f7719ceSAndrei Emeltchenko 
l2cap_sock_ready_cb(struct l2cap_chan * chan)165554a59aa2SAndrei Emeltchenko static void l2cap_sock_ready_cb(struct l2cap_chan *chan)
165654a59aa2SAndrei Emeltchenko {
165754a59aa2SAndrei Emeltchenko 	struct sock *sk = chan->data;
165854a59aa2SAndrei Emeltchenko 	struct sock *parent;
165954a59aa2SAndrei Emeltchenko 
166054a59aa2SAndrei Emeltchenko 	lock_sock(sk);
166154a59aa2SAndrei Emeltchenko 
166254a59aa2SAndrei Emeltchenko 	parent = bt_sk(sk)->parent;
166354a59aa2SAndrei Emeltchenko 
166454a59aa2SAndrei Emeltchenko 	BT_DBG("sk %p, parent %p", sk, parent);
166554a59aa2SAndrei Emeltchenko 
166654a59aa2SAndrei Emeltchenko 	sk->sk_state = BT_CONNECTED;
166754a59aa2SAndrei Emeltchenko 	sk->sk_state_change(sk);
166854a59aa2SAndrei Emeltchenko 
166954a59aa2SAndrei Emeltchenko 	if (parent)
1670676d2369SDavid S. Miller 		parent->sk_data_ready(parent);
167154a59aa2SAndrei Emeltchenko 
167254a59aa2SAndrei Emeltchenko 	release_sock(sk);
167354a59aa2SAndrei Emeltchenko }
167454a59aa2SAndrei Emeltchenko 
l2cap_sock_defer_cb(struct l2cap_chan * chan)16752dc4e510SGustavo Padovan static void l2cap_sock_defer_cb(struct l2cap_chan *chan)
16762dc4e510SGustavo Padovan {
1677acdcabf5SGustavo Padovan 	struct sock *parent, *sk = chan->data;
16782dc4e510SGustavo Padovan 
1679acdcabf5SGustavo Padovan 	lock_sock(sk);
1680acdcabf5SGustavo Padovan 
1681acdcabf5SGustavo Padovan 	parent = bt_sk(sk)->parent;
16822dc4e510SGustavo Padovan 	if (parent)
1683676d2369SDavid S. Miller 		parent->sk_data_ready(parent);
1684acdcabf5SGustavo Padovan 
1685acdcabf5SGustavo Padovan 	release_sock(sk);
16862dc4e510SGustavo Padovan }
16872dc4e510SGustavo Padovan 
l2cap_sock_resume_cb(struct l2cap_chan * chan)1688d97c899bSMarcel Holtmann static void l2cap_sock_resume_cb(struct l2cap_chan *chan)
1689d97c899bSMarcel Holtmann {
1690d97c899bSMarcel Holtmann 	struct sock *sk = chan->data;
1691d97c899bSMarcel Holtmann 
1692d52deb17SJohan Hedberg 	if (test_and_clear_bit(FLAG_PENDING_SECURITY, &chan->flags)) {
1693d52deb17SJohan Hedberg 		sk->sk_state = BT_CONNECTED;
1694d52deb17SJohan Hedberg 		chan->state = BT_CONNECTED;
1695d52deb17SJohan Hedberg 	}
1696d52deb17SJohan Hedberg 
1697d97c899bSMarcel Holtmann 	clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
1698d97c899bSMarcel Holtmann 	sk->sk_state_change(sk);
1699d97c899bSMarcel Holtmann }
1700d97c899bSMarcel Holtmann 
l2cap_sock_set_shutdown_cb(struct l2cap_chan * chan)17015ec1bbe5SGustavo Padovan static void l2cap_sock_set_shutdown_cb(struct l2cap_chan *chan)
17025ec1bbe5SGustavo Padovan {
17035ec1bbe5SGustavo Padovan 	struct sock *sk = chan->data;
17045ec1bbe5SGustavo Padovan 
17055ec1bbe5SGustavo Padovan 	lock_sock(sk);
17065ec1bbe5SGustavo Padovan 	sk->sk_shutdown = SHUTDOWN_MASK;
17075ec1bbe5SGustavo Padovan 	release_sock(sk);
17085ec1bbe5SGustavo Padovan }
17095ec1bbe5SGustavo Padovan 
l2cap_sock_get_sndtimeo_cb(struct l2cap_chan * chan)17108d836d71SGustavo Padovan static long l2cap_sock_get_sndtimeo_cb(struct l2cap_chan *chan)
17118d836d71SGustavo Padovan {
17128d836d71SGustavo Padovan 	struct sock *sk = chan->data;
17138d836d71SGustavo Padovan 
17148d836d71SGustavo Padovan 	return sk->sk_sndtimeo;
17158d836d71SGustavo Padovan }
17168d836d71SGustavo Padovan 
l2cap_sock_get_peer_pid_cb(struct l2cap_chan * chan)1717b48596d1SLuiz Augusto von Dentz static struct pid *l2cap_sock_get_peer_pid_cb(struct l2cap_chan *chan)
1718b48596d1SLuiz Augusto von Dentz {
1719b48596d1SLuiz Augusto von Dentz 	struct sock *sk = chan->data;
1720b48596d1SLuiz Augusto von Dentz 
1721b48596d1SLuiz Augusto von Dentz 	return sk->sk_peer_pid;
1722b48596d1SLuiz Augusto von Dentz }
1723b48596d1SLuiz Augusto von Dentz 
l2cap_sock_suspend_cb(struct l2cap_chan * chan)1724837776f7SJohan Hedberg static void l2cap_sock_suspend_cb(struct l2cap_chan *chan)
1725837776f7SJohan Hedberg {
1726837776f7SJohan Hedberg 	struct sock *sk = chan->data;
1727837776f7SJohan Hedberg 
1728837776f7SJohan Hedberg 	set_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
1729837776f7SJohan Hedberg 	sk->sk_state_change(sk);
1730837776f7SJohan Hedberg }
1731837776f7SJohan Hedberg 
l2cap_sock_filter(struct l2cap_chan * chan,struct sk_buff * skb)1732f1942564SLuiz Augusto von Dentz static int l2cap_sock_filter(struct l2cap_chan *chan, struct sk_buff *skb)
1733f1942564SLuiz Augusto von Dentz {
1734f1942564SLuiz Augusto von Dentz 	struct sock *sk = chan->data;
1735f1942564SLuiz Augusto von Dentz 
1736f1942564SLuiz Augusto von Dentz 	switch (chan->mode) {
1737f1942564SLuiz Augusto von Dentz 	case L2CAP_MODE_ERTM:
1738f1942564SLuiz Augusto von Dentz 	case L2CAP_MODE_STREAMING:
1739f1942564SLuiz Augusto von Dentz 		return sk_filter(sk, skb);
1740f1942564SLuiz Augusto von Dentz 	}
1741f1942564SLuiz Augusto von Dentz 
1742f1942564SLuiz Augusto von Dentz 	return 0;
1743f1942564SLuiz Augusto von Dentz }
1744f1942564SLuiz Augusto von Dentz 
174567f86a45SMarcel Holtmann static const struct l2cap_ops l2cap_chan_ops = {
174680808e43SGustavo F. Padovan 	.name			= "L2CAP Socket Interface",
174780808e43SGustavo F. Padovan 	.new_connection		= l2cap_sock_new_connection_cb,
174823070494SGustavo F. Padovan 	.recv			= l2cap_sock_recv_cb,
1749ba3bd0eeSGustavo F. Padovan 	.close			= l2cap_sock_close_cb,
1750c0df7f6eSAndrei Emeltchenko 	.teardown		= l2cap_sock_teardown_cb,
175189bc500eSGustavo F. Padovan 	.state_change		= l2cap_sock_state_change_cb,
175254a59aa2SAndrei Emeltchenko 	.ready			= l2cap_sock_ready_cb,
17532dc4e510SGustavo Padovan 	.defer			= l2cap_sock_defer_cb,
1754d97c899bSMarcel Holtmann 	.resume			= l2cap_sock_resume_cb,
1755837776f7SJohan Hedberg 	.suspend		= l2cap_sock_suspend_cb,
17565ec1bbe5SGustavo Padovan 	.set_shutdown		= l2cap_sock_set_shutdown_cb,
17578d836d71SGustavo Padovan 	.get_sndtimeo		= l2cap_sock_get_sndtimeo_cb,
1758b48596d1SLuiz Augusto von Dentz 	.get_peer_pid		= l2cap_sock_get_peer_pid_cb,
17592f7719ceSAndrei Emeltchenko 	.alloc_skb		= l2cap_sock_alloc_skb_cb,
1760f1942564SLuiz Augusto von Dentz 	.filter			= l2cap_sock_filter,
176180808e43SGustavo F. Padovan };
176280808e43SGustavo F. Padovan 
l2cap_sock_destruct(struct sock * sk)1763bb58f747SGustavo F. Padovan static void l2cap_sock_destruct(struct sock *sk)
1764bb58f747SGustavo F. Padovan {
1765ce60b923SSebastian Urban 	struct l2cap_rx_busy *rx_busy, *next;
1766ce60b923SSebastian Urban 
1767bb58f747SGustavo F. Padovan 	BT_DBG("sk %p", sk);
1768bb58f747SGustavo F. Padovan 
17691bff51eaSWang ShaoBo 	if (l2cap_pi(sk)->chan) {
17701bff51eaSWang ShaoBo 		l2cap_pi(sk)->chan->data = NULL;
177161d6ef3eSMat Martineau 		l2cap_chan_put(l2cap_pi(sk)->chan);
17721bff51eaSWang ShaoBo 	}
177384b34d98SMarcel Holtmann 
1774ce60b923SSebastian Urban 	list_for_each_entry_safe(rx_busy, next, &l2cap_pi(sk)->rx_busy, list) {
1775ce60b923SSebastian Urban 		kfree_skb(rx_busy->skb);
1776ce60b923SSebastian Urban 		list_del(&rx_busy->list);
1777ce60b923SSebastian Urban 		kfree(rx_busy);
1778e328140fSMat Martineau 	}
1779e328140fSMat Martineau 
1780bb58f747SGustavo F. Padovan 	skb_queue_purge(&sk->sk_receive_queue);
1781bb58f747SGustavo F. Padovan 	skb_queue_purge(&sk->sk_write_queue);
1782bb58f747SGustavo F. Padovan }
1783bb58f747SGustavo F. Padovan 
l2cap_skb_msg_name(struct sk_buff * skb,void * msg_name,int * msg_namelen)17842edf870dSMarcel Holtmann static void l2cap_skb_msg_name(struct sk_buff *skb, void *msg_name,
17852edf870dSMarcel Holtmann 			       int *msg_namelen)
17862edf870dSMarcel Holtmann {
1787342dfc30SSteffen Hurrle 	DECLARE_SOCKADDR(struct sockaddr_l2 *, la, msg_name);
17882edf870dSMarcel Holtmann 
17892edf870dSMarcel Holtmann 	memset(la, 0, sizeof(struct sockaddr_l2));
17902edf870dSMarcel Holtmann 	la->l2_family = AF_BLUETOOTH;
1791a4368ff3SJohan Hedberg 	la->l2_psm = bt_cb(skb)->l2cap.psm;
1792a4368ff3SJohan Hedberg 	bacpy(&la->l2_bdaddr, &bt_cb(skb)->l2cap.bdaddr);
17932edf870dSMarcel Holtmann 
17942edf870dSMarcel Holtmann 	*msg_namelen = sizeof(struct sockaddr_l2);
17952edf870dSMarcel Holtmann }
17962edf870dSMarcel Holtmann 
l2cap_sock_init(struct sock * sk,struct sock * parent)179780808e43SGustavo F. Padovan static void l2cap_sock_init(struct sock *sk, struct sock *parent)
1798bb58f747SGustavo F. Padovan {
179984b34d98SMarcel Holtmann 	struct l2cap_chan *chan = l2cap_pi(sk)->chan;
1800bb58f747SGustavo F. Padovan 
1801bb58f747SGustavo F. Padovan 	BT_DBG("sk %p", sk);
1802bb58f747SGustavo F. Padovan 
1803bb58f747SGustavo F. Padovan 	if (parent) {
1804b4450035SGustavo F. Padovan 		struct l2cap_chan *pchan = l2cap_pi(parent)->chan;
1805b4450035SGustavo F. Padovan 
1806bb58f747SGustavo F. Padovan 		sk->sk_type = parent->sk_type;
1807c5daa683SGustavo Padovan 		bt_sk(sk)->flags = bt_sk(parent)->flags;
1808bb58f747SGustavo F. Padovan 
1809715ec005SGustavo F. Padovan 		chan->chan_type = pchan->chan_type;
18100c1bc5c6SGustavo F. Padovan 		chan->imtu = pchan->imtu;
18110c1bc5c6SGustavo F. Padovan 		chan->omtu = pchan->omtu;
1812b4450035SGustavo F. Padovan 		chan->conf_state = pchan->conf_state;
18130c1bc5c6SGustavo F. Padovan 		chan->mode = pchan->mode;
181447d1ec61SGustavo F. Padovan 		chan->fcs  = pchan->fcs;
181547d1ec61SGustavo F. Padovan 		chan->max_tx = pchan->max_tx;
181647d1ec61SGustavo F. Padovan 		chan->tx_win = pchan->tx_win;
18176b3c7104SAndrei Emeltchenko 		chan->tx_win_max = pchan->tx_win_max;
18184343478fSGustavo F. Padovan 		chan->sec_level = pchan->sec_level;
1819d57b0e8bSAndrei Emeltchenko 		chan->flags = pchan->flags;
18200cd75f7eSJohan Hedberg 		chan->tx_credits = pchan->tx_credits;
18210cd75f7eSJohan Hedberg 		chan->rx_credits = pchan->rx_credits;
18226230c9b4SPaul Moore 
18237a8e5a31SJohan Hedberg 		if (chan->chan_type == L2CAP_CHAN_FIXED) {
18247a8e5a31SJohan Hedberg 			chan->scid = pchan->scid;
18257a8e5a31SJohan Hedberg 			chan->dcid = pchan->scid;
18267a8e5a31SJohan Hedberg 		}
18277a8e5a31SJohan Hedberg 
18286230c9b4SPaul Moore 		security_sk_clone(parent, sk);
1829bb58f747SGustavo F. Padovan 	} else {
1830715ec005SGustavo F. Padovan 		switch (sk->sk_type) {
1831715ec005SGustavo F. Padovan 		case SOCK_RAW:
1832715ec005SGustavo F. Padovan 			chan->chan_type = L2CAP_CHAN_RAW;
1833715ec005SGustavo F. Padovan 			break;
1834715ec005SGustavo F. Padovan 		case SOCK_DGRAM:
1835715ec005SGustavo F. Padovan 			chan->chan_type = L2CAP_CHAN_CONN_LESS;
18362edf870dSMarcel Holtmann 			bt_sk(sk)->skb_msg_name = l2cap_skb_msg_name;
1837715ec005SGustavo F. Padovan 			break;
1838715ec005SGustavo F. Padovan 		case SOCK_SEQPACKET:
1839715ec005SGustavo F. Padovan 		case SOCK_STREAM:
1840715ec005SGustavo F. Padovan 			chan->chan_type = L2CAP_CHAN_CONN_ORIENTED;
1841715ec005SGustavo F. Padovan 			break;
1842715ec005SGustavo F. Padovan 		}
1843715ec005SGustavo F. Padovan 
18440c1bc5c6SGustavo F. Padovan 		chan->imtu = L2CAP_DEFAULT_MTU;
18450c1bc5c6SGustavo F. Padovan 		chan->omtu = 0;
1846bb58f747SGustavo F. Padovan 		if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
18470c1bc5c6SGustavo F. Padovan 			chan->mode = L2CAP_MODE_ERTM;
1848c1360a1cSGustavo F. Padovan 			set_bit(CONF_STATE2_DEVICE, &chan->conf_state);
1849bb58f747SGustavo F. Padovan 		} else {
18500c1bc5c6SGustavo F. Padovan 			chan->mode = L2CAP_MODE_BASIC;
1851bb58f747SGustavo F. Padovan 		}
1852bd4b1653SAndrei Emeltchenko 
1853bd4b1653SAndrei Emeltchenko 		l2cap_chan_set_defaults(chan);
1854bb58f747SGustavo F. Padovan 	}
1855bb58f747SGustavo F. Padovan 
1856bb58f747SGustavo F. Padovan 	/* Default config options */
18570c1bc5c6SGustavo F. Padovan 	chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
185880808e43SGustavo F. Padovan 
185980808e43SGustavo F. Padovan 	chan->data = sk;
186080808e43SGustavo F. Padovan 	chan->ops = &l2cap_chan_ops;
1861ce60b923SSebastian Urban 
1862ce60b923SSebastian Urban 	l2cap_publish_rx_avail(chan);
1863bb58f747SGustavo F. Padovan }
1864bb58f747SGustavo F. Padovan 
1865bb58f747SGustavo F. Padovan static struct proto l2cap_proto = {
1866bb58f747SGustavo F. Padovan 	.name		= "L2CAP",
1867bb58f747SGustavo F. Padovan 	.owner		= THIS_MODULE,
1868bb58f747SGustavo F. Padovan 	.obj_size	= sizeof(struct l2cap_pinfo)
1869bb58f747SGustavo F. Padovan };
1870bb58f747SGustavo F. Padovan 
l2cap_sock_alloc(struct net * net,struct socket * sock,int proto,gfp_t prio,int kern)18712d792818SGustavo Padovan static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
187211aa9c28SEric W. Biederman 				     int proto, gfp_t prio, int kern)
1873bb58f747SGustavo F. Padovan {
1874bb58f747SGustavo F. Padovan 	struct sock *sk;
1875dc50a06dSGustavo F. Padovan 	struct l2cap_chan *chan;
1876bb58f747SGustavo F. Padovan 
18776bfa273eSLuiz Augusto von Dentz 	sk = bt_sock_alloc(net, sock, &l2cap_proto, proto, prio, kern);
1878bb58f747SGustavo F. Padovan 	if (!sk)
1879bb58f747SGustavo F. Padovan 		return NULL;
1880bb58f747SGustavo F. Padovan 
1881bb58f747SGustavo F. Padovan 	sk->sk_destruct = l2cap_sock_destruct;
1882ba13ccd9SMarcel Holtmann 	sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
1883bb58f747SGustavo F. Padovan 
1884ce60b923SSebastian Urban 	INIT_LIST_HEAD(&l2cap_pi(sk)->rx_busy);
1885ce60b923SSebastian Urban 
1886eef1d9b6SGustavo Padovan 	chan = l2cap_chan_create();
1887dc50a06dSGustavo F. Padovan 	if (!chan) {
188849dfbb91SJaganath Kanakkassery 		sk_free(sk);
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 
l2cap_sock_create(struct net * net,struct socket * sock,int protocol,int kern)1899bb58f747SGustavo F. Padovan static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
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 
l2cap_init_sockets(void)1953bb58f747SGustavo F. Padovan int __init 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 
l2cap_cleanup_sockets(void)1986bb58f747SGustavo F. Padovan 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