aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/fragmentation.c
diff options
context:
space:
mode:
authorAntonio Quartulli <antonio@open-mesh.com>2014-04-23 08:05:16 -0400
committerAntonio Quartulli <antonio@meshcoding.com>2014-05-15 14:03:17 -0400
commitbe181015a189cd141398b761ba4e79d33fe69949 (patch)
treeaf62d988abedf59273888c007c3fd03492e37b16 /net/batman-adv/fragmentation.c
parent16a4142363b11952d3aa76ac78004502c0c2fe6e (diff)
batman-adv: fix reference counting imbalance while sending fragment
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>
Diffstat (limited to 'net/batman-adv/fragmentation.c')
-rw-r--r--net/batman-adv/fragmentation.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
index bcc4bea632fa..f14e54a05691 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,
418 struct batadv_neigh_node *neigh_node) 418 struct batadv_neigh_node *neigh_node)
419{ 419{
420 struct batadv_priv *bat_priv; 420 struct batadv_priv *bat_priv;
421 struct batadv_hard_iface *primary_if; 421 struct batadv_hard_iface *primary_if = NULL;
422 struct batadv_frag_packet frag_header; 422 struct batadv_frag_packet frag_header;
423 struct sk_buff *skb_fragment; 423 struct sk_buff *skb_fragment;
424 unsigned mtu = neigh_node->if_incoming->net_dev->mtu; 424 unsigned mtu = neigh_node->if_incoming->net_dev->mtu;
425 unsigned header_size = sizeof(frag_header); 425 unsigned header_size = sizeof(frag_header);
426 unsigned max_fragment_size, max_packet_size; 426 unsigned max_fragment_size, max_packet_size;
427 bool ret = false;
427 428
428 /* To avoid merge and refragmentation at next-hops we never send 429 /* To avoid merge and refragmentation at next-hops we never send
429 * fragments larger than BATADV_FRAG_MAX_FRAG_SIZE 430 * fragments larger than BATADV_FRAG_MAX_FRAG_SIZE
@@ -483,7 +484,11 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
483 skb->len + ETH_HLEN); 484 skb->len + ETH_HLEN);
484 batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 485 batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
485 486
486 return true; 487 ret = true;
488
487out_err: 489out_err:
488 return false; 490 if (primary_if)
491 batadv_hardif_free_ref(primary_if);
492
493 return ret;
489} 494}