[next,v2,2/4] batman-adv: Don't propagate negative dev_queue_xmit return values
Commit Message
batadv_send_skb_packet used by batadv_send_skb_to_orig and its return value
is given directly to callers of batadv_send_skb_packet.
batadv_send_skb_to_orig
-> batadv_send_unicast_skb
-> batadv_send_skb_packet
-> dev_queue_xmit
These callers of batadv_send_skb_to_orig expect that the skb isn't consumed
when they receive a -1. But dev_queue_xmit may still have consumed it and
still returned -1. Thus the free for the skb would be called twice.
Fixes: e3b8acbff9c8 ("batman-adv: return netdev status in the TX path")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
v2:
- rebased on current master
- added patch to a common set of related patches
net/batman-adv/send.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
Comments
On Monday, June 20, 2016 19:53:28 Sven Eckelmann wrote:
> batadv_send_skb_packet used by batadv_send_skb_to_orig and its return value
> is given directly to callers of batadv_send_skb_packet.
>
> batadv_send_skb_to_orig
> -> batadv_send_unicast_skb
> -> batadv_send_skb_packet
> -> dev_queue_xmit
>
> These callers of batadv_send_skb_to_orig expect that the skb isn't consumed
> when they receive a -1. But dev_queue_xmit may still have consumed it and
> still returned -1. Thus the free for the skb would be called twice.
>
> Fixes: e3b8acbff9c8 ("batman-adv: return netdev status in the TX path")
> Signed-off-by: Sven Eckelmann <sven@narfation.org>
> ---
> v2:
> - rebased on current master
> - added patch to a common set of related patches
>
> net/batman-adv/send.c | 10 +++++++++-
> 1 file changed, 9 insertions(+), 1 deletion(-)
Applied in revision a20149c.
Thanks,
Marek
@@ -72,6 +72,7 @@ int batadv_send_skb_packet(struct sk_buff *skb,
{
struct batadv_priv *bat_priv;
struct ethhdr *ethhdr;
+ int ret;
bat_priv = netdev_priv(hard_iface->soft_iface);
@@ -109,8 +110,15 @@ int batadv_send_skb_packet(struct sk_buff *skb,
/* dev_queue_xmit() returns a negative result on error. However on
* congestion and traffic shaping, it drops and returns NET_XMIT_DROP
* (which is > 0). This will not be treated as an error.
+ *
+ * a negative value cannot be returned because it could be interepreted
+ * as not consumed skb by callers of batadv_send_skb_to_orig.
*/
- return dev_queue_xmit(skb);
+ ret = dev_queue_xmit(skb);
+ if (ret < 0)
+ ret = NET_XMIT_DROP;
+
+ return ret;
send_skb_err:
kfree_skb(skb);
return NET_XMIT_DROP;