aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2011-02-03 17:50:35 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-02-07 22:43:30 -0500
commitbb58f747e519aba07a6f05a78d58cf8a0788e2d5 (patch)
treed65743650d5f1a164bbb709a8aa7df4b13250623
parent0a708f8fc46fde3be2116b8d79f7469a24097c90 (diff)
Bluetooth: Initial work for L2CAP split.
This patch tries to do the minimal to move l2cap_sock_create() and its dependencies to l2cap_sock.c. It create a API to initialize and cleanup the L2CAP sockets from l2cap_core.c through l2cap_init_sockets() and l2cap_cleanup_sockets(). Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r--include/net/bluetooth/l2cap.h15
-rw-r--r--net/bluetooth/Makefile2
-rw-r--r--net/bluetooth/l2cap_core.c187
-rw-r--r--net/bluetooth/l2cap_sock.c213
4 files changed, 240 insertions, 177 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 7f88a87d7a46..fce5274a4f7b 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -424,6 +424,21 @@ static inline int l2cap_tx_window_full(struct sock *sk)
424#define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE) 424#define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE)
425#define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START) 425#define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START)
426 426
427extern int disable_ertm;
428extern const struct proto_ops l2cap_sock_ops;
429extern struct bt_sock_list l2cap_sk_list;
430
431int l2cap_init_sockets(void);
432void l2cap_cleanup_sockets(void);
433
434void l2cap_sock_set_timer(struct sock *sk, long timeout);
435void __l2cap_sock_close(struct sock *sk, int reason);
436void l2cap_sock_kill(struct sock *sk);
437void l2cap_sock_init(struct sock *sk, struct sock *parent);
438struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
439 int proto, gfp_t prio);
440
441
427void l2cap_load(void); 442void l2cap_load(void);
428 443
429#endif /* __L2CAP_H */ 444#endif /* __L2CAP_H */
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index bf2945e1d9ef..339b42932b33 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -11,4 +11,4 @@ obj-$(CONFIG_BT_CMTP) += cmtp/
11obj-$(CONFIG_BT_HIDP) += hidp/ 11obj-$(CONFIG_BT_HIDP) += hidp/
12 12
13bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o 13bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o
14l2cap-y := l2cap_core.o 14l2cap-y := l2cap_core.o l2cap_sock.o
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 28d2954f94a4..af678efec15f 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -24,7 +24,7 @@
24 SOFTWARE IS DISCLAIMED. 24 SOFTWARE IS DISCLAIMED.
25*/ 25*/
26 26
27/* Bluetooth L2CAP core and sockets. */ 27/* Bluetooth L2CAP core. */
28 28
29#include <linux/module.h> 29#include <linux/module.h>
30 30
@@ -57,24 +57,20 @@
57 57
58#define VERSION "2.15" 58#define VERSION "2.15"
59 59
60static int disable_ertm; 60int disable_ertm;
61 61
62static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; 62static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
63static u8 l2cap_fixed_chan[8] = { 0x02, }; 63static u8 l2cap_fixed_chan[8] = { 0x02, };
64 64
65static const struct proto_ops l2cap_sock_ops;
66
67static struct workqueue_struct *_busy_wq; 65static struct workqueue_struct *_busy_wq;
68 66
69static struct bt_sock_list l2cap_sk_list = { 67struct bt_sock_list l2cap_sk_list = {
70 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock) 68 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
71}; 69};
72 70
73static void l2cap_busy_work(struct work_struct *work); 71static void l2cap_busy_work(struct work_struct *work);
74 72
75static void __l2cap_sock_close(struct sock *sk, int reason);
76static void l2cap_sock_close(struct sock *sk); 73static void l2cap_sock_close(struct sock *sk);
77static void l2cap_sock_kill(struct sock *sk);
78 74
79static int l2cap_build_conf_req(struct sock *sk, void *data); 75static int l2cap_build_conf_req(struct sock *sk, void *data);
80static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, 76static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
@@ -83,7 +79,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
83static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); 79static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
84 80
85/* ---- L2CAP timers ---- */ 81/* ---- L2CAP timers ---- */
86static void l2cap_sock_set_timer(struct sock *sk, long timeout) 82void l2cap_sock_set_timer(struct sock *sk, long timeout)
87{ 83{
88 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout); 84 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
89 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); 85 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
@@ -95,39 +91,6 @@ static void l2cap_sock_clear_timer(struct sock *sk)
95 sk_stop_timer(sk, &sk->sk_timer); 91 sk_stop_timer(sk, &sk->sk_timer);
96} 92}
97 93
98static void l2cap_sock_timeout(unsigned long arg)
99{
100 struct sock *sk = (struct sock *) arg;
101 int reason;
102
103 BT_DBG("sock %p state %d", sk, sk->sk_state);
104
105 bh_lock_sock(sk);
106
107 if (sock_owned_by_user(sk)) {
108 /* sk is owned by user. Try again later */
109 l2cap_sock_set_timer(sk, HZ / 5);
110 bh_unlock_sock(sk);
111 sock_put(sk);
112 return;
113 }
114
115 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
116 reason = ECONNREFUSED;
117 else if (sk->sk_state == BT_CONNECT &&
118 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
119 reason = ECONNREFUSED;
120 else
121 reason = ETIMEDOUT;
122
123 __l2cap_sock_close(sk, reason);
124
125 bh_unlock_sock(sk);
126
127 l2cap_sock_kill(sk);
128 sock_put(sk);
129}
130
131/* ---- L2CAP channels ---- */ 94/* ---- L2CAP channels ---- */
132static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid) 95static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
133{ 96{
@@ -801,14 +764,6 @@ static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
801 return node ? sk : sk1; 764 return node ? sk : sk1;
802} 765}
803 766
804static void l2cap_sock_destruct(struct sock *sk)
805{
806 BT_DBG("sk %p", sk);
807
808 skb_queue_purge(&sk->sk_receive_queue);
809 skb_queue_purge(&sk->sk_write_queue);
810}
811
812static void l2cap_sock_cleanup_listen(struct sock *parent) 767static void l2cap_sock_cleanup_listen(struct sock *parent)
813{ 768{
814 struct sock *sk; 769 struct sock *sk;
@@ -826,7 +781,7 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
826/* Kill socket (only if zapped and orphan) 781/* Kill socket (only if zapped and orphan)
827 * Must be called on unlocked socket. 782 * Must be called on unlocked socket.
828 */ 783 */
829static void l2cap_sock_kill(struct sock *sk) 784void l2cap_sock_kill(struct sock *sk)
830{ 785{
831 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) 786 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
832 return; 787 return;
@@ -839,7 +794,7 @@ static void l2cap_sock_kill(struct sock *sk)
839 sock_put(sk); 794 sock_put(sk);
840} 795}
841 796
842static void __l2cap_sock_close(struct sock *sk, int reason) 797void __l2cap_sock_close(struct sock *sk, int reason)
843{ 798{
844 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); 799 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
845 800
@@ -904,111 +859,6 @@ static void l2cap_sock_close(struct sock *sk)
904 l2cap_sock_kill(sk); 859 l2cap_sock_kill(sk);
905} 860}
906 861
907static void l2cap_sock_init(struct sock *sk, struct sock *parent)
908{
909 struct l2cap_pinfo *pi = l2cap_pi(sk);
910
911 BT_DBG("sk %p", sk);
912
913 if (parent) {
914 sk->sk_type = parent->sk_type;
915 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
916
917 pi->imtu = l2cap_pi(parent)->imtu;
918 pi->omtu = l2cap_pi(parent)->omtu;
919 pi->conf_state = l2cap_pi(parent)->conf_state;
920 pi->mode = l2cap_pi(parent)->mode;
921 pi->fcs = l2cap_pi(parent)->fcs;
922 pi->max_tx = l2cap_pi(parent)->max_tx;
923 pi->tx_win = l2cap_pi(parent)->tx_win;
924 pi->sec_level = l2cap_pi(parent)->sec_level;
925 pi->role_switch = l2cap_pi(parent)->role_switch;
926 pi->force_reliable = l2cap_pi(parent)->force_reliable;
927 pi->flushable = l2cap_pi(parent)->flushable;
928 } else {
929 pi->imtu = L2CAP_DEFAULT_MTU;
930 pi->omtu = 0;
931 if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
932 pi->mode = L2CAP_MODE_ERTM;
933 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
934 } else {
935 pi->mode = L2CAP_MODE_BASIC;
936 }
937 pi->max_tx = L2CAP_DEFAULT_MAX_TX;
938 pi->fcs = L2CAP_FCS_CRC16;
939 pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
940 pi->sec_level = BT_SECURITY_LOW;
941 pi->role_switch = 0;
942 pi->force_reliable = 0;
943 pi->flushable = BT_FLUSHABLE_OFF;
944 }
945
946 /* Default config options */
947 pi->conf_len = 0;
948 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
949 skb_queue_head_init(TX_QUEUE(sk));
950 skb_queue_head_init(SREJ_QUEUE(sk));
951 skb_queue_head_init(BUSY_QUEUE(sk));
952 INIT_LIST_HEAD(SREJ_LIST(sk));
953}
954
955static struct proto l2cap_proto = {
956 .name = "L2CAP",
957 .owner = THIS_MODULE,
958 .obj_size = sizeof(struct l2cap_pinfo)
959};
960
961static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
962{
963 struct sock *sk;
964
965 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
966 if (!sk)
967 return NULL;
968
969 sock_init_data(sock, sk);
970 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
971
972 sk->sk_destruct = l2cap_sock_destruct;
973 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
974
975 sock_reset_flag(sk, SOCK_ZAPPED);
976
977 sk->sk_protocol = proto;
978 sk->sk_state = BT_OPEN;
979
980 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
981
982 bt_sock_link(&l2cap_sk_list, sk);
983 return sk;
984}
985
986static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
987 int kern)
988{
989 struct sock *sk;
990
991 BT_DBG("sock %p", sock);
992
993 sock->state = SS_UNCONNECTED;
994
995 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
996 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
997 return -ESOCKTNOSUPPORT;
998
999 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
1000 return -EPERM;
1001
1002 sock->ops = &l2cap_sock_ops;
1003
1004 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
1005 if (!sk)
1006 return -ENOMEM;
1007
1008 l2cap_sock_init(sk, NULL);
1009 return 0;
1010}
1011
1012static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) 862static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
1013{ 863{
1014 struct sock *sk = sock->sk; 864 struct sock *sk = sock->sk;
@@ -4865,7 +4715,7 @@ static const struct file_operations l2cap_debugfs_fops = {
4865 4715
4866static struct dentry *l2cap_debugfs; 4716static struct dentry *l2cap_debugfs;
4867 4717
4868static const struct proto_ops l2cap_sock_ops = { 4718const struct proto_ops l2cap_sock_ops = {
4869 .family = PF_BLUETOOTH, 4719 .family = PF_BLUETOOTH,
4870 .owner = THIS_MODULE, 4720 .owner = THIS_MODULE,
4871 .release = l2cap_sock_release, 4721 .release = l2cap_sock_release,
@@ -4885,12 +4735,6 @@ static const struct proto_ops l2cap_sock_ops = {
4885 .getsockopt = l2cap_sock_getsockopt 4735 .getsockopt = l2cap_sock_getsockopt
4886}; 4736};
4887 4737
4888static const struct net_proto_family l2cap_sock_family_ops = {
4889 .family = PF_BLUETOOTH,
4890 .owner = THIS_MODULE,
4891 .create = l2cap_sock_create,
4892};
4893
4894static struct hci_proto l2cap_hci_proto = { 4738static struct hci_proto l2cap_hci_proto = {
4895 .name = "L2CAP", 4739 .name = "L2CAP",
4896 .id = HCI_PROTO_L2CAP, 4740 .id = HCI_PROTO_L2CAP,
@@ -4906,19 +4750,13 @@ static int __init l2cap_init(void)
4906{ 4750{
4907 int err; 4751 int err;
4908 4752
4909 err = proto_register(&l2cap_proto, 0); 4753 err = l2cap_init_sockets();
4910 if (err < 0) 4754 if (err < 0)
4911 return err; 4755 return err;
4912 4756
4913 _busy_wq = create_singlethread_workqueue("l2cap"); 4757 _busy_wq = create_singlethread_workqueue("l2cap");
4914 if (!_busy_wq) { 4758 if (!_busy_wq) {
4915 proto_unregister(&l2cap_proto); 4759 err = -ENOMEM;
4916 return -ENOMEM;
4917 }
4918
4919 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4920 if (err < 0) {
4921 BT_ERR("L2CAP socket registration failed");
4922 goto error; 4760 goto error;
4923 } 4761 }
4924 4762
@@ -4943,7 +4781,7 @@ static int __init l2cap_init(void)
4943 4781
4944error: 4782error:
4945 destroy_workqueue(_busy_wq); 4783 destroy_workqueue(_busy_wq);
4946 proto_unregister(&l2cap_proto); 4784 l2cap_cleanup_sockets();
4947 return err; 4785 return err;
4948} 4786}
4949 4787
@@ -4954,13 +4792,10 @@ static void __exit l2cap_exit(void)
4954 flush_workqueue(_busy_wq); 4792 flush_workqueue(_busy_wq);
4955 destroy_workqueue(_busy_wq); 4793 destroy_workqueue(_busy_wq);
4956 4794
4957 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4958 BT_ERR("L2CAP socket unregistration failed");
4959
4960 if (hci_unregister_proto(&l2cap_hci_proto) < 0) 4795 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4961 BT_ERR("L2CAP protocol unregistration failed"); 4796 BT_ERR("L2CAP protocol unregistration failed");
4962 4797
4963 proto_unregister(&l2cap_proto); 4798 l2cap_cleanup_sockets();
4964} 4799}
4965 4800
4966void l2cap_load(void) 4801void l2cap_load(void)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
new file mode 100644
index 000000000000..6ea1894cecb7
--- /dev/null
+++ b/net/bluetooth/l2cap_sock.c
@@ -0,0 +1,213 @@
1/*
2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
5 Copyright (C) 2010 Google Inc.
6
7 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 2 as
11 published by the Free Software Foundation;
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
16 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
17 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
18 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21
22 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
23 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
24 SOFTWARE IS DISCLAIMED.
25*/
26
27/* Bluetooth L2CAP sockets. */
28
29#include <net/bluetooth/bluetooth.h>
30#include <net/bluetooth/l2cap.h>
31
32static void l2cap_sock_timeout(unsigned long arg)
33{
34 struct sock *sk = (struct sock *) arg;
35 int reason;
36
37 BT_DBG("sock %p state %d", sk, sk->sk_state);
38
39 bh_lock_sock(sk);
40
41 if (sock_owned_by_user(sk)) {
42 /* sk is owned by user. Try again later */
43 l2cap_sock_set_timer(sk, HZ / 5);
44 bh_unlock_sock(sk);
45 sock_put(sk);
46 return;
47 }
48
49 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
50 reason = ECONNREFUSED;
51 else if (sk->sk_state == BT_CONNECT &&
52 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
53 reason = ECONNREFUSED;
54 else
55 reason = ETIMEDOUT;
56
57 __l2cap_sock_close(sk, reason);
58
59 bh_unlock_sock(sk);
60
61 l2cap_sock_kill(sk);
62 sock_put(sk);
63}
64
65
66static void l2cap_sock_destruct(struct sock *sk)
67{
68 BT_DBG("sk %p", sk);
69
70 skb_queue_purge(&sk->sk_receive_queue);
71 skb_queue_purge(&sk->sk_write_queue);
72}
73
74void l2cap_sock_init(struct sock *sk, struct sock *parent)
75{
76 struct l2cap_pinfo *pi = l2cap_pi(sk);
77
78 BT_DBG("sk %p", sk);
79
80 if (parent) {
81 sk->sk_type = parent->sk_type;
82 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
83
84 pi->imtu = l2cap_pi(parent)->imtu;
85 pi->omtu = l2cap_pi(parent)->omtu;
86 pi->conf_state = l2cap_pi(parent)->conf_state;
87 pi->mode = l2cap_pi(parent)->mode;
88 pi->fcs = l2cap_pi(parent)->fcs;
89 pi->max_tx = l2cap_pi(parent)->max_tx;
90 pi->tx_win = l2cap_pi(parent)->tx_win;
91 pi->sec_level = l2cap_pi(parent)->sec_level;
92 pi->role_switch = l2cap_pi(parent)->role_switch;
93 pi->force_reliable = l2cap_pi(parent)->force_reliable;
94 pi->flushable = l2cap_pi(parent)->flushable;
95 } else {
96 pi->imtu = L2CAP_DEFAULT_MTU;
97 pi->omtu = 0;
98 if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
99 pi->mode = L2CAP_MODE_ERTM;
100 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
101 } else {
102 pi->mode = L2CAP_MODE_BASIC;
103 }
104 pi->max_tx = L2CAP_DEFAULT_MAX_TX;
105 pi->fcs = L2CAP_FCS_CRC16;
106 pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
107 pi->sec_level = BT_SECURITY_LOW;
108 pi->role_switch = 0;
109 pi->force_reliable = 0;
110 pi->flushable = BT_FLUSHABLE_OFF;
111 }
112
113 /* Default config options */
114 pi->conf_len = 0;
115 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
116 skb_queue_head_init(TX_QUEUE(sk));
117 skb_queue_head_init(SREJ_QUEUE(sk));
118 skb_queue_head_init(BUSY_QUEUE(sk));
119 INIT_LIST_HEAD(SREJ_LIST(sk));
120}
121
122static struct proto l2cap_proto = {
123 .name = "L2CAP",
124 .owner = THIS_MODULE,
125 .obj_size = sizeof(struct l2cap_pinfo)
126};
127
128struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
129{
130 struct sock *sk;
131
132 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
133 if (!sk)
134 return NULL;
135
136 sock_init_data(sock, sk);
137 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
138
139 sk->sk_destruct = l2cap_sock_destruct;
140 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
141
142 sock_reset_flag(sk, SOCK_ZAPPED);
143
144 sk->sk_protocol = proto;
145 sk->sk_state = BT_OPEN;
146
147 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
148
149 bt_sock_link(&l2cap_sk_list, sk);
150 return sk;
151}
152
153static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
154 int kern)
155{
156 struct sock *sk;
157
158 BT_DBG("sock %p", sock);
159
160 sock->state = SS_UNCONNECTED;
161
162 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
163 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
164 return -ESOCKTNOSUPPORT;
165
166 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
167 return -EPERM;
168
169 sock->ops = &l2cap_sock_ops;
170
171 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
172 if (!sk)
173 return -ENOMEM;
174
175 l2cap_sock_init(sk, NULL);
176 return 0;
177}
178
179static const struct net_proto_family l2cap_sock_family_ops = {
180 .family = PF_BLUETOOTH,
181 .owner = THIS_MODULE,
182 .create = l2cap_sock_create,
183};
184
185int __init l2cap_init_sockets(void)
186{
187 int err;
188
189 err = proto_register(&l2cap_proto, 0);
190 if (err < 0)
191 return err;
192
193 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
194 if (err < 0)
195 goto error;
196
197 BT_INFO("L2CAP socket layer initialized");
198
199 return 0;
200
201error:
202 BT_ERR("L2CAP socket registration failed");
203 proto_unregister(&l2cap_proto);
204 return err;
205}
206
207void l2cap_cleanup_sockets(void)
208{
209 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
210 BT_ERR("L2CAP socket unregistration failed");
211
212 proto_unregister(&l2cap_proto);
213}