diff options
author | Antonio Quartulli <antonio@open-mesh.com> | 2014-04-23 08:05:16 -0400 |
---|---|---|
committer | Antonio Quartulli <antonio@meshcoding.com> | 2014-05-15 14:03:17 -0400 |
commit | be181015a189cd141398b761ba4e79d33fe69949 (patch) | |
tree | af62d988abedf59273888c007c3fd03492e37b16 /net/batman-adv/fragmentation.c | |
parent | 16a4142363b11952d3aa76ac78004502c0c2fe6e (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.c | 11 |
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 | |||
487 | out_err: | 489 | out_err: |
488 | return false; | 490 | if (primary_if) |
491 | batadv_hardif_free_ref(primary_if); | ||
492 | |||
493 | return ret; | ||
489 | } | 494 | } |