Hi,
I noticed some issues in 6LoWPAN multicast support and this set
should fix them.
Patch 1 removes the restriction that we skip EAGAIN error code
for multicast packets. The extra check are actually useless as
we can treat multicast packets the same way as unicast ones.
Patch 2 adds error checks when sending multicast packet, if
multicast packet sending fails, we return error to the user
space.
Cheers,
Jukka
Jukka Rissanen (2):
Bluetooth: 6lowpan: Return EAGAIN error also for multicast packets
Bluetooth: 6lowpan: Check transmit errors for multicast packets
net/bluetooth/6lowpan.c | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
--
1.8.3.1
Hi Jukka,
On Wed, Oct 01, 2014, Jukka Rissanen wrote:
> I noticed some issues in 6LoWPAN multicast support and this set
> should fix them.
>
> Patch 1 removes the restriction that we skip EAGAIN error code
> for multicast packets. The extra check are actually useless as
> we can treat multicast packets the same way as unicast ones.
>
> Patch 2 adds error checks when sending multicast packet, if
> multicast packet sending fails, we return error to the user
> space.
>
> Cheers,
> Jukka
>
>
> Jukka Rissanen (2):
> Bluetooth: 6lowpan: Return EAGAIN error also for multicast packets
> Bluetooth: 6lowpan: Check transmit errors for multicast packets
>
> net/bluetooth/6lowpan.c | 27 ++++++++++++++-------------
> 1 file changed, 14 insertions(+), 13 deletions(-)
Both patches have been applied to bluetooth-next. Thanks.
Johan
Make sure that we are able to return EAGAIN from l2cap_chan_send()
even for multicast packets. The error code was ignored unncessarily.
Signed-off-by: Jukka Rissanen <[email protected]>
---
net/bluetooth/6lowpan.c | 16 +++++-----------
1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 44eaad7..fcfaa70 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -509,21 +509,16 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev,
/* Packet to BT LE device */
static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb,
- struct net_device *netdev, bool is_mcast)
+ struct net_device *netdev)
{
struct msghdr msg;
struct kvec iv;
int err;
/* Remember the skb so that we can send EAGAIN to the caller if
- * we run out of credits. This is not done for multicast packets
- * because we generate mcast packet in this module and are not
- * really able to remember the skb after this packet is sent.
+ * we run out of credits.
*/
- if (is_mcast)
- chan->data = NULL;
- else
- chan->data = skb;
+ chan->data = skb;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = (struct iovec *) &iv;
@@ -575,7 +570,7 @@ static void send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
netdev->name,
&pentry->chan->dst, pentry->chan->dst_type,
&pentry->peer_addr, pentry->chan);
- send_pkt(pentry->chan, local_skb, netdev, true);
+ send_pkt(pentry->chan, local_skb, netdev);
kfree_skb(local_skb);
}
@@ -617,8 +612,7 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev)
BT_DBG("xmit %s to %pMR type %d IP %pI6c chan %p",
netdev->name, &addr, addr_type,
&lowpan_cb(skb)->addr, lowpan_cb(skb)->chan);
- err = send_pkt(lowpan_cb(skb)->chan, skb, netdev,
- false);
+ err = send_pkt(lowpan_cb(skb)->chan, skb, netdev);
} else {
err = -ENOENT;
}
--
1.8.3.1
We did not return error if multicast packet transmit failed.
This might not be desired so return error also in this case.
If there are multiple 6lowpan devices where the multicast packet
is sent, then return error even if sending to only one of them fails.
Signed-off-by: Jukka Rissanen <[email protected]>
---
net/bluetooth/6lowpan.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index fcfaa70..c2e0d14 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -546,11 +546,12 @@ static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb,
return err;
}
-static void send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
+static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
{
struct sk_buff *local_skb;
struct lowpan_dev *entry, *tmp;
unsigned long flags;
+ int err = 0;
read_lock_irqsave(&devices_lock, flags);
@@ -564,19 +565,25 @@ static void send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
dev = lowpan_dev(entry->netdev);
list_for_each_entry_safe(pentry, ptmp, &dev->peers, list) {
+ int ret;
+
local_skb = skb_clone(skb, GFP_ATOMIC);
BT_DBG("xmit %s to %pMR type %d IP %pI6c chan %p",
netdev->name,
&pentry->chan->dst, pentry->chan->dst_type,
&pentry->peer_addr, pentry->chan);
- send_pkt(pentry->chan, local_skb, netdev);
+ ret = send_pkt(pentry->chan, local_skb, netdev);
+ if (ret < 0)
+ err = ret;
kfree_skb(local_skb);
}
}
read_unlock_irqrestore(&devices_lock, flags);
+
+ return err;
}
static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev)
@@ -620,7 +627,7 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev)
/* We need to send the packet to every device behind this
* interface.
*/
- send_mcast_pkt(skb, netdev);
+ err = send_mcast_pkt(skb, netdev);
}
dev_kfree_skb(skb);
--
1.8.3.1