diff options
Diffstat (limited to 'net/bluetooth/l2cap_sock.c')
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 76 |
1 files changed, 46 insertions, 30 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 04e7c172d49c..3bb1611b9d48 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -124,7 +124,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al | |||
124 | return -EINVAL; | 124 | return -EINVAL; |
125 | 125 | ||
126 | err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid), | 126 | err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid), |
127 | &la.l2_bdaddr); | 127 | &la.l2_bdaddr, la.l2_bdaddr_type); |
128 | if (err) | 128 | if (err) |
129 | return err; | 129 | return err; |
130 | 130 | ||
@@ -148,12 +148,16 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) | |||
148 | 148 | ||
149 | lock_sock(sk); | 149 | lock_sock(sk); |
150 | 150 | ||
151 | if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM) | 151 | if (sk->sk_state != BT_BOUND) { |
152 | || sk->sk_state != BT_BOUND) { | ||
153 | err = -EBADFD; | 152 | err = -EBADFD; |
154 | goto done; | 153 | goto done; |
155 | } | 154 | } |
156 | 155 | ||
156 | if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM) { | ||
157 | err = -EINVAL; | ||
158 | goto done; | ||
159 | } | ||
160 | |||
157 | switch (chan->mode) { | 161 | switch (chan->mode) { |
158 | case L2CAP_MODE_BASIC: | 162 | case L2CAP_MODE_BASIC: |
159 | break; | 163 | break; |
@@ -320,8 +324,8 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us | |||
320 | 324 | ||
321 | case L2CAP_CONNINFO: | 325 | case L2CAP_CONNINFO: |
322 | if (sk->sk_state != BT_CONNECTED && | 326 | if (sk->sk_state != BT_CONNECTED && |
323 | !(sk->sk_state == BT_CONNECT2 && | 327 | !(sk->sk_state == BT_CONNECT2 && |
324 | bt_sk(sk)->defer_setup)) { | 328 | test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))) { |
325 | err = -ENOTCONN; | 329 | err = -ENOTCONN; |
326 | break; | 330 | break; |
327 | } | 331 | } |
@@ -375,7 +379,10 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
375 | } | 379 | } |
376 | 380 | ||
377 | memset(&sec, 0, sizeof(sec)); | 381 | memset(&sec, 0, sizeof(sec)); |
378 | sec.level = chan->sec_level; | 382 | if (chan->conn) |
383 | sec.level = chan->conn->hcon->sec_level; | ||
384 | else | ||
385 | sec.level = chan->sec_level; | ||
379 | 386 | ||
380 | if (sk->sk_state == BT_CONNECTED) | 387 | if (sk->sk_state == BT_CONNECTED) |
381 | sec.key_size = chan->conn->hcon->enc_key_size; | 388 | sec.key_size = chan->conn->hcon->enc_key_size; |
@@ -392,7 +399,8 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
392 | break; | 399 | break; |
393 | } | 400 | } |
394 | 401 | ||
395 | if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval)) | 402 | if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags), |
403 | (u32 __user *) optval)) | ||
396 | err = -EFAULT; | 404 | err = -EFAULT; |
397 | 405 | ||
398 | break; | 406 | break; |
@@ -594,10 +602,10 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
594 | 602 | ||
595 | /* or for ACL link */ | 603 | /* or for ACL link */ |
596 | } else if ((sk->sk_state == BT_CONNECT2 && | 604 | } else if ((sk->sk_state == BT_CONNECT2 && |
597 | bt_sk(sk)->defer_setup) || | 605 | test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) || |
598 | sk->sk_state == BT_CONNECTED) { | 606 | sk->sk_state == BT_CONNECTED) { |
599 | if (!l2cap_chan_check_security(chan)) | 607 | if (!l2cap_chan_check_security(chan)) |
600 | bt_sk(sk)->suspended = true; | 608 | set_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags); |
601 | else | 609 | else |
602 | sk->sk_state_change(sk); | 610 | sk->sk_state_change(sk); |
603 | } else { | 611 | } else { |
@@ -616,7 +624,10 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
616 | break; | 624 | break; |
617 | } | 625 | } |
618 | 626 | ||
619 | bt_sk(sk)->defer_setup = opt; | 627 | if (opt) |
628 | set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags); | ||
629 | else | ||
630 | clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags); | ||
620 | break; | 631 | break; |
621 | 632 | ||
622 | case BT_FLUSHABLE: | 633 | case BT_FLUSHABLE: |
@@ -716,16 +727,13 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
716 | if (msg->msg_flags & MSG_OOB) | 727 | if (msg->msg_flags & MSG_OOB) |
717 | return -EOPNOTSUPP; | 728 | return -EOPNOTSUPP; |
718 | 729 | ||
719 | lock_sock(sk); | 730 | if (sk->sk_state != BT_CONNECTED) |
720 | |||
721 | if (sk->sk_state != BT_CONNECTED) { | ||
722 | release_sock(sk); | ||
723 | return -ENOTCONN; | 731 | return -ENOTCONN; |
724 | } | ||
725 | 732 | ||
733 | l2cap_chan_lock(chan); | ||
726 | err = l2cap_chan_send(chan, msg, len, sk->sk_priority); | 734 | err = l2cap_chan_send(chan, msg, len, sk->sk_priority); |
735 | l2cap_chan_unlock(chan); | ||
727 | 736 | ||
728 | release_sock(sk); | ||
729 | return err; | 737 | return err; |
730 | } | 738 | } |
731 | 739 | ||
@@ -737,7 +745,8 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
737 | 745 | ||
738 | lock_sock(sk); | 746 | lock_sock(sk); |
739 | 747 | ||
740 | if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { | 748 | if (sk->sk_state == BT_CONNECT2 && test_bit(BT_SK_DEFER_SETUP, |
749 | &bt_sk(sk)->flags)) { | ||
741 | sk->sk_state = BT_CONFIG; | 750 | sk->sk_state = BT_CONFIG; |
742 | pi->chan->state = BT_CONFIG; | 751 | pi->chan->state = BT_CONFIG; |
743 | 752 | ||
@@ -931,12 +940,19 @@ static void l2cap_sock_state_change_cb(void *data, int state) | |||
931 | } | 940 | } |
932 | 941 | ||
933 | static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan, | 942 | static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan, |
934 | unsigned long len, int nb, | 943 | unsigned long len, int nb) |
935 | int *err) | ||
936 | { | 944 | { |
937 | struct sock *sk = chan->sk; | 945 | struct sk_buff *skb; |
946 | int err; | ||
947 | |||
948 | l2cap_chan_unlock(chan); | ||
949 | skb = bt_skb_send_alloc(chan->sk, len, nb, &err); | ||
950 | l2cap_chan_lock(chan); | ||
951 | |||
952 | if (!skb) | ||
953 | return ERR_PTR(err); | ||
938 | 954 | ||
939 | return bt_skb_send_alloc(sk, len, nb, err); | 955 | return skb; |
940 | } | 956 | } |
941 | 957 | ||
942 | static struct l2cap_ops l2cap_chan_ops = { | 958 | static struct l2cap_ops l2cap_chan_ops = { |
@@ -952,6 +968,7 @@ static void l2cap_sock_destruct(struct sock *sk) | |||
952 | { | 968 | { |
953 | BT_DBG("sk %p", sk); | 969 | BT_DBG("sk %p", sk); |
954 | 970 | ||
971 | l2cap_chan_put(l2cap_pi(sk)->chan); | ||
955 | if (l2cap_pi(sk)->rx_busy_skb) { | 972 | if (l2cap_pi(sk)->rx_busy_skb) { |
956 | kfree_skb(l2cap_pi(sk)->rx_busy_skb); | 973 | kfree_skb(l2cap_pi(sk)->rx_busy_skb); |
957 | l2cap_pi(sk)->rx_busy_skb = NULL; | 974 | l2cap_pi(sk)->rx_busy_skb = NULL; |
@@ -972,7 +989,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
972 | struct l2cap_chan *pchan = l2cap_pi(parent)->chan; | 989 | struct l2cap_chan *pchan = l2cap_pi(parent)->chan; |
973 | 990 | ||
974 | sk->sk_type = parent->sk_type; | 991 | sk->sk_type = parent->sk_type; |
975 | bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup; | 992 | bt_sk(sk)->flags = bt_sk(parent)->flags; |
976 | 993 | ||
977 | chan->chan_type = pchan->chan_type; | 994 | chan->chan_type = pchan->chan_type; |
978 | chan->imtu = pchan->imtu; | 995 | chan->imtu = pchan->imtu; |
@@ -1010,13 +1027,8 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
1010 | } else { | 1027 | } else { |
1011 | chan->mode = L2CAP_MODE_BASIC; | 1028 | chan->mode = L2CAP_MODE_BASIC; |
1012 | } | 1029 | } |
1013 | chan->max_tx = L2CAP_DEFAULT_MAX_TX; | 1030 | |
1014 | chan->fcs = L2CAP_FCS_CRC16; | 1031 | l2cap_chan_set_defaults(chan); |
1015 | chan->tx_win = L2CAP_DEFAULT_TX_WINDOW; | ||
1016 | chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW; | ||
1017 | chan->sec_level = BT_SECURITY_LOW; | ||
1018 | chan->flags = 0; | ||
1019 | set_bit(FLAG_FORCE_ACTIVE, &chan->flags); | ||
1020 | } | 1032 | } |
1021 | 1033 | ||
1022 | /* Default config options */ | 1034 | /* Default config options */ |
@@ -1052,12 +1064,16 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p | |||
1052 | sk->sk_protocol = proto; | 1064 | sk->sk_protocol = proto; |
1053 | sk->sk_state = BT_OPEN; | 1065 | sk->sk_state = BT_OPEN; |
1054 | 1066 | ||
1055 | chan = l2cap_chan_create(sk); | 1067 | chan = l2cap_chan_create(); |
1056 | if (!chan) { | 1068 | if (!chan) { |
1057 | l2cap_sock_kill(sk); | 1069 | l2cap_sock_kill(sk); |
1058 | return NULL; | 1070 | return NULL; |
1059 | } | 1071 | } |
1060 | 1072 | ||
1073 | l2cap_chan_hold(chan); | ||
1074 | |||
1075 | chan->sk = sk; | ||
1076 | |||
1061 | l2cap_pi(sk)->chan = chan; | 1077 | l2cap_pi(sk)->chan = chan; |
1062 | 1078 | ||
1063 | return sk; | 1079 | return sk; |