From d9fbd02be5c201c1659ee0d79c0820bb68d95c8c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 8 Jun 2014 11:22:28 +0200 Subject: [PATCH] Bluetooth: Use explicit header and body length for L2CAP SKB allocation When allocating the L2CAP SKB for transmission, provide the upper layers with a clear distinction on what is the header and what is the body portion of the SKB. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/l2cap.h | 1 + net/bluetooth/a2mp.c | 3 ++- net/bluetooth/l2cap_core.c | 10 +++++----- net/bluetooth/l2cap_sock.c | 3 ++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 18f4f27..9251103 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -600,6 +600,7 @@ struct l2cap_ops { void (*set_shutdown) (struct l2cap_chan *chan); long (*get_sndtimeo) (struct l2cap_chan *chan); struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan, + unsigned long hdr_len, unsigned long len, int nb); }; diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 1a5b1eb..0fd8d1d 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -693,11 +693,12 @@ static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state, } static struct sk_buff *a2mp_chan_alloc_skb_cb(struct l2cap_chan *chan, + unsigned long hdr_len, unsigned long len, int nb) { struct sk_buff *skb; - skb = bt_skb_alloc(len, GFP_KERNEL); + skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL); if (!skb) return ERR_PTR(-ENOMEM); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 3dca282..ac24614 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2131,7 +2131,7 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan, count = min_t(unsigned int, conn->mtu, len); - tmp = chan->ops->alloc_skb(chan, count, + tmp = chan->ops->alloc_skb(chan, 0, count, msg->msg_flags & MSG_DONTWAIT); if (IS_ERR(tmp)) return PTR_ERR(tmp); @@ -2166,7 +2166,7 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, count = min_t(unsigned int, (conn->mtu - hlen), len); - skb = chan->ops->alloc_skb(chan, count + hlen, + skb = chan->ops->alloc_skb(chan, hlen, count, msg->msg_flags & MSG_DONTWAIT); if (IS_ERR(skb)) return skb; @@ -2197,7 +2197,7 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len); - skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE, + skb = chan->ops->alloc_skb(chan, L2CAP_HDR_SIZE, count, msg->msg_flags & MSG_DONTWAIT); if (IS_ERR(skb)) return skb; @@ -2239,7 +2239,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, count = min_t(unsigned int, (conn->mtu - hlen), len); - skb = chan->ops->alloc_skb(chan, count + hlen, + skb = chan->ops->alloc_skb(chan, hlen, count, msg->msg_flags & MSG_DONTWAIT); if (IS_ERR(skb)) return skb; @@ -2360,7 +2360,7 @@ static struct sk_buff *l2cap_create_le_flowctl_pdu(struct l2cap_chan *chan, count = min_t(unsigned int, (conn->mtu - hlen), len); - skb = chan->ops->alloc_skb(chan, count + hlen, + skb = chan->ops->alloc_skb(chan, hlen, count, msg->msg_flags & MSG_DONTWAIT); if (IS_ERR(skb)) return skb; diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index d95964c..55215eb 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1292,6 +1292,7 @@ static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state, } static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan, + unsigned long hdr_len, unsigned long len, int nb) { struct sock *sk = chan->data; @@ -1299,7 +1300,7 @@ static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan, int err; l2cap_chan_unlock(chan); - skb = bt_skb_send_alloc(sk, len, nb, &err); + skb = bt_skb_send_alloc(sk, hdr_len + len, nb, &err); l2cap_chan_lock(chan); if (!skb) -- 2.7.4