summaryrefslogtreecommitdiffstats
path: root/net/batman-adv/bat_v_ogm.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/bat_v_ogm.c')
-rw-r--r--net/batman-adv/bat_v_ogm.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
index 4155fa57cf6d..473ebb9a0e73 100644
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
@@ -26,6 +26,7 @@
#include <linux/if_ether.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
+#include <linux/kref.h>
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/random.h>
@@ -176,6 +177,9 @@ static void batadv_v_ogm_send(struct work_struct *work)
if (hard_iface->soft_iface != bat_priv->soft_iface)
continue;
+ if (!kref_get_unless_zero(&hard_iface->refcount))
+ continue;
+
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Sending own OGM2 packet (originator %pM, seqno %u, throughput %u, TTL %d) on interface %s [%pM]\n",
ogm_packet->orig, ntohl(ogm_packet->seqno),
@@ -185,10 +189,13 @@ static void batadv_v_ogm_send(struct work_struct *work)
/* this skb gets consumed by batadv_v_ogm_send_to_if() */
skb_tmp = skb_clone(skb, GFP_ATOMIC);
- if (!skb_tmp)
+ if (!skb_tmp) {
+ batadv_hardif_put(hard_iface);
break;
+ }
batadv_v_ogm_send_to_if(skb_tmp, hard_iface);
+ batadv_hardif_put(hard_iface);
}
rcu_read_unlock();
@@ -704,9 +711,14 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset,
if (hard_iface->soft_iface != bat_priv->soft_iface)
continue;
+ if (!kref_get_unless_zero(&hard_iface->refcount))
+ continue;
+
batadv_v_ogm_process_per_outif(bat_priv, ethhdr, ogm_packet,
orig_node, neigh_node,
if_incoming, hard_iface);
+
+ batadv_hardif_put(hard_iface);
}
rcu_read_unlock();
out: