diff options
Diffstat (limited to 'net/bluetooth/l2cap_sock.c')
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index a4bb27e8427e..083f2bf065d4 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -34,6 +34,10 @@ | |||
34 | #include <net/bluetooth/l2cap.h> | 34 | #include <net/bluetooth/l2cap.h> |
35 | #include <net/bluetooth/smp.h> | 35 | #include <net/bluetooth/smp.h> |
36 | 36 | ||
37 | static struct bt_sock_list l2cap_sk_list = { | ||
38 | .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock) | ||
39 | }; | ||
40 | |||
37 | static const struct proto_ops l2cap_sock_ops; | 41 | static const struct proto_ops l2cap_sock_ops; |
38 | static void l2cap_sock_init(struct sock *sk, struct sock *parent); | 42 | static void l2cap_sock_init(struct sock *sk, struct sock *parent); |
39 | static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio); | 43 | static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio); |
@@ -245,6 +249,7 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l | |||
245 | 249 | ||
246 | BT_DBG("sock %p, sk %p", sock, sk); | 250 | BT_DBG("sock %p, sk %p", sock, sk); |
247 | 251 | ||
252 | memset(la, 0, sizeof(struct sockaddr_l2)); | ||
248 | addr->sa_family = AF_BLUETOOTH; | 253 | addr->sa_family = AF_BLUETOOTH; |
249 | *len = sizeof(struct sockaddr_l2); | 254 | *len = sizeof(struct sockaddr_l2); |
250 | 255 | ||
@@ -615,7 +620,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
615 | break; | 620 | break; |
616 | } | 621 | } |
617 | 622 | ||
618 | if (smp_conn_security(conn, sec.level)) | 623 | if (smp_conn_security(conn->hcon, sec.level)) |
619 | break; | 624 | break; |
620 | sk->sk_state = BT_CONFIG; | 625 | sk->sk_state = BT_CONFIG; |
621 | chan->state = BT_CONFIG; | 626 | chan->state = BT_CONFIG; |
@@ -823,7 +828,7 @@ static void l2cap_sock_kill(struct sock *sk) | |||
823 | 828 | ||
824 | /* Kill poor orphan */ | 829 | /* Kill poor orphan */ |
825 | 830 | ||
826 | l2cap_chan_destroy(l2cap_pi(sk)->chan); | 831 | l2cap_chan_put(l2cap_pi(sk)->chan); |
827 | sock_set_flag(sk, SOCK_DEAD); | 832 | sock_set_flag(sk, SOCK_DEAD); |
828 | sock_put(sk); | 833 | sock_put(sk); |
829 | } | 834 | } |
@@ -886,6 +891,8 @@ static int l2cap_sock_release(struct socket *sock) | |||
886 | if (!sk) | 891 | if (!sk) |
887 | return 0; | 892 | return 0; |
888 | 893 | ||
894 | bt_sock_unlink(&l2cap_sk_list, sk); | ||
895 | |||
889 | err = l2cap_sock_shutdown(sock, 2); | 896 | err = l2cap_sock_shutdown(sock, 2); |
890 | 897 | ||
891 | sock_orphan(sk); | 898 | sock_orphan(sk); |
@@ -1174,7 +1181,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p | |||
1174 | 1181 | ||
1175 | chan = l2cap_chan_create(); | 1182 | chan = l2cap_chan_create(); |
1176 | if (!chan) { | 1183 | if (!chan) { |
1177 | l2cap_sock_kill(sk); | 1184 | sk_free(sk); |
1178 | return NULL; | 1185 | return NULL; |
1179 | } | 1186 | } |
1180 | 1187 | ||
@@ -1210,6 +1217,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, | |||
1210 | return -ENOMEM; | 1217 | return -ENOMEM; |
1211 | 1218 | ||
1212 | l2cap_sock_init(sk, NULL); | 1219 | l2cap_sock_init(sk, NULL); |
1220 | bt_sock_link(&l2cap_sk_list, sk); | ||
1213 | return 0; | 1221 | return 0; |
1214 | } | 1222 | } |
1215 | 1223 | ||
@@ -1248,21 +1256,30 @@ int __init l2cap_init_sockets(void) | |||
1248 | return err; | 1256 | return err; |
1249 | 1257 | ||
1250 | err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops); | 1258 | err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops); |
1251 | if (err < 0) | 1259 | if (err < 0) { |
1260 | BT_ERR("L2CAP socket registration failed"); | ||
1252 | goto error; | 1261 | goto error; |
1262 | } | ||
1263 | |||
1264 | err = bt_procfs_init(THIS_MODULE, &init_net, "l2cap", &l2cap_sk_list, NULL); | ||
1265 | if (err < 0) { | ||
1266 | BT_ERR("Failed to create L2CAP proc file"); | ||
1267 | bt_sock_unregister(BTPROTO_L2CAP); | ||
1268 | goto error; | ||
1269 | } | ||
1253 | 1270 | ||
1254 | BT_INFO("L2CAP socket layer initialized"); | 1271 | BT_INFO("L2CAP socket layer initialized"); |
1255 | 1272 | ||
1256 | return 0; | 1273 | return 0; |
1257 | 1274 | ||
1258 | error: | 1275 | error: |
1259 | BT_ERR("L2CAP socket registration failed"); | ||
1260 | proto_unregister(&l2cap_proto); | 1276 | proto_unregister(&l2cap_proto); |
1261 | return err; | 1277 | return err; |
1262 | } | 1278 | } |
1263 | 1279 | ||
1264 | void l2cap_cleanup_sockets(void) | 1280 | void l2cap_cleanup_sockets(void) |
1265 | { | 1281 | { |
1282 | bt_procfs_cleanup(&init_net, "l2cap"); | ||
1266 | if (bt_sock_unregister(BTPROTO_L2CAP) < 0) | 1283 | if (bt_sock_unregister(BTPROTO_L2CAP) < 0) |
1267 | BT_ERR("L2CAP socket unregistration failed"); | 1284 | BT_ERR("L2CAP socket unregistration failed"); |
1268 | 1285 | ||