diff options
author | Antonio Quartulli <antonio@open-mesh.com> | 2014-04-23 14:05:16 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-05-31 13:20:38 -0700 |
commit | e450a9b46e0d1c6d0b94a63d0d5fd4273d45de24 (patch) | |
tree | 6dec7c2f817976866ce49d1b74cedbc159ff002e | |
parent | b6bc7a13cab3966f03d3efd79892c8d2f085b919 (diff) | |
download | kernel-common-e450a9b46e0d1c6d0b94a63d0d5fd4273d45de24.tar.gz kernel-common-e450a9b46e0d1c6d0b94a63d0d5fd4273d45de24.tar.bz2 kernel-common-e450a9b46e0d1c6d0b94a63d0d5fd4273d45de24.zip |
batman-adv: fix reference counting imbalance while sending fragment
[ Upstream commit be181015a189cd141398b761ba4e79d33fe69949 ]
In the new fragmentation code the batadv_frag_send_packet()
function obtains a reference to the primary_if, but it does
not release it upon return.
This reference imbalance prevents the primary_if (and then
the related netdevice) to be properly released on shut down.
Fix this by releasing the primary_if in batadv_frag_send_packet().
Introduced by ee75ed88879af88558818a5c6609d85f60ff0df4
("batman-adv: Fragment and send skbs larger than mtu")
Cc: Martin Hundebøll <martin@hundeboll.net>
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Acked-by: Martin Hundebøll <martin@hundeboll.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | net/batman-adv/fragmentation.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index 88df9b1d552d..cc1cfd60c094 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c @@ -418,12 +418,13 @@ bool batadv_frag_send_packet(struct sk_buff *skb, struct batadv_neigh_node *neigh_node) { struct batadv_priv *bat_priv; - struct batadv_hard_iface *primary_if; + struct batadv_hard_iface *primary_if = NULL; struct batadv_frag_packet frag_header; struct sk_buff *skb_fragment; unsigned mtu = neigh_node->if_incoming->net_dev->mtu; unsigned header_size = sizeof(frag_header); unsigned max_fragment_size, max_packet_size; + bool ret = false; /* To avoid merge and refragmentation at next-hops we never send * fragments larger than BATADV_FRAG_MAX_FRAG_SIZE @@ -483,7 +484,11 @@ bool batadv_frag_send_packet(struct sk_buff *skb, skb->len + ETH_HLEN); batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); - return true; + ret = true; + out_err: - return false; + if (primary_if) + batadv_hardif_free_ref(primary_if); + + return ret; } |