summaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2013-12-02 15:34:18 +0100
committerMarcel Holtmann <marcel@holtmann.org>2013-12-05 16:05:34 +0100
commit1f435424ce2c93c31c3887ec67e3afb6056f18f6 (patch)
tree93a7aed7a02b6984dfb3b4adfe45a4e4142eb8dd /net/bluetooth
parentBluetooth: Limit L2CAP_OPTIONS socket option usage with LE (diff)
downloadlinux-1f435424ce2c93c31c3887ec67e3afb6056f18f6.tar.xz
linux-1f435424ce2c93c31c3887ec67e3afb6056f18f6.zip
Bluetooth: Add new BT_SNDMTU and BT_RCVMTU socket options
This patch adds new socket options for LE sockets since the existing L2CAP_OPTIONS socket option is not usable for LE. For now, the new socket options also require LE CoC support to be explicitly enabled to leave some playroom in case something needs to be changed in a backwards incompatible way. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/l2cap_sock.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index a20fcc3ddcd9..01d65bc99b0c 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -534,6 +534,41 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname,
err = -EFAULT;
break;
+ case BT_SNDMTU:
+ if (!enable_lecoc) {
+ err = -EPROTONOSUPPORT;
+ break;
+ }
+
+ if (!bdaddr_type_is_le(chan->src_type)) {
+ err = -EINVAL;
+ break;
+ }
+
+ if (sk->sk_state != BT_CONNECTED) {
+ err = -ENOTCONN;
+ break;
+ }
+
+ if (put_user(chan->omtu, (u16 __user *) optval))
+ err = -EFAULT;
+ break;
+
+ case BT_RCVMTU:
+ if (!enable_lecoc) {
+ err = -EPROTONOSUPPORT;
+ break;
+ }
+
+ if (!bdaddr_type_is_le(chan->src_type)) {
+ err = -EINVAL;
+ break;
+ }
+
+ if (put_user(chan->imtu, (u16 __user *) optval))
+ err = -EFAULT;
+ break;
+
default:
err = -ENOPROTOOPT;
break;
@@ -834,6 +869,47 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
break;
+ case BT_SNDMTU:
+ if (!enable_lecoc) {
+ err = -EPROTONOSUPPORT;
+ break;
+ }
+
+ if (!bdaddr_type_is_le(chan->src_type)) {
+ err = -EINVAL;
+ break;
+ }
+
+ /* Setting is not supported as it's the remote side that
+ * decides this.
+ */
+ err = -EPERM;
+ break;
+
+ case BT_RCVMTU:
+ if (!enable_lecoc) {
+ err = -EPROTONOSUPPORT;
+ break;
+ }
+
+ if (!bdaddr_type_is_le(chan->src_type)) {
+ err = -EINVAL;
+ break;
+ }
+
+ if (sk->sk_state == BT_CONNECTED) {
+ err = -EISCONN;
+ break;
+ }
+
+ if (get_user(opt, (u32 __user *) optval)) {
+ err = -EFAULT;
+ break;
+ }
+
+ chan->imtu = opt;
+ break;
+
default:
err = -ENOPROTOOPT;
break;