Merge branch 'batman-adv'
authorJo-Philipp Wich <jow@openwrt.org>
Thu, 18 Apr 2013 16:54:45 +0000 (18:54 +0200)
committerJo-Philipp Wich <jow@openwrt.org>
Thu, 18 Apr 2013 16:54:45 +0000 (18:54 +0200)
batman-adv/Config.in [new file with mode: 0644]
batman-adv/Makefile [new file with mode: 0644]
batman-adv/files/etc/config/batman-adv [new file with mode: 0644]
batman-adv/files/etc/hotplug.d/net/99-batman-adv [new file with mode: 0644]
batman-adv/files/lib/batman-adv/config.sh [new file with mode: 0644]
batman-adv/files/lib/netifd/proto/batadv.sh [new file with mode: 0644]
batman-adv/patches/0001-batman-adv-verify-tt-len-does-not-exceed-packet-len.patch [new file with mode: 0644]
batman-adv/patches/0002-batman-adv-hlist-drop-the-node-parameter-from-iterators.patch [new file with mode: 0644]
batman-adv/patches/0003-batman-adv-make-is_my_mac-check-for-the-current-mesh.patch [new file with mode: 0644]

diff --git a/batman-adv/Config.in b/batman-adv/Config.in
new file mode 100644 (file)
index 0000000..b47104f
--- /dev/null
@@ -0,0 +1,24 @@
+
+config KMOD_BATMAN_ADV_DEBUG_LOG
+       bool "enable verbose debug logging"
+       depends on PACKAGE_kmod-batman-adv
+       default n
+
+config KMOD_BATMAN_ADV_BLA
+       bool "enable bridge loop avoidance"
+       depends on PACKAGE_kmod-batman-adv
+       default y
+
+config KMOD_BATMAN_ADV_DAT
+       bool "enable distributed arp table"
+       depends on PACKAGE_kmod-batman-adv
+       default y
+
+config KMOD_BATMAN_ADV_BATCTL
+       bool "enable batctl"
+       depends on PACKAGE_kmod-batman-adv
+       default y
+       help
+         batctl is a more intuitive managment utility for B.A.T.M.A.N.-Advanced.
+         It is an easier method for configuring batman-adv and
+         provides some additional tools for debugging as well.
diff --git a/batman-adv/Makefile b/batman-adv/Makefile
new file mode 100644 (file)
index 0000000..cbb7aac
--- /dev/null
@@ -0,0 +1,121 @@
+#
+# Copyright (C) 2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+# $Id: Makefile 5624 2006-11-23 00:29:07Z nbd $
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=batman-adv
+
+PKG_VERSION:=2013.1.0
+BATCTL_VERSION:=2013.1.0
+PKG_RELEASE:=3
+PKG_MD5SUM:=fe1fd32eddde1f91575d7a7ec21d5782
+BATCTL_MD5SUM:=767bf36c77c517e1d321169bf9a7fae5
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_BATCTL_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/batctl-$(BATCTL_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+define KernelPackage/batman-adv
+  URL:=http://www.open-mesh.org/
+  MAINTAINER:=Marek Lindner <lindner_marek@yahoo.de>
+  SUBMENU:=Network Support
+  DEPENDS:=+kmod-lib-crc16 +kmod-crypto-core +kmod-crypto-crc32c +kmod-lib-crc32c +libc
+  TITLE:=B.A.T.M.A.N. Adv
+  FILES:=$(PKG_BUILD_DIR)/batman-adv.$(LINUX_KMOD_SUFFIX)
+  AUTOLOAD:=$(call AutoLoad,50,batman-adv)
+endef
+
+define KernelPackage/batman-adv/description
+B.A.T.M.A.N. advanced is a kernel module which allows to
+build layer 2 mesh networks. This package contains the
+version $(PKG_VERSION) of the kernel module plus its user space
+configuration & managerment tool batctl.
+endef
+
+define KernelPackage/batman-adv/config
+       source "$(SOURCE)/Config.in"
+endef
+
+MAKE_BATMAN_ADV_ARGS += \
+       CROSS_COMPILE="$(TARGET_CROSS)" \
+       KERNELPATH="$(LINUX_DIR)" \
+       ARCH="$(LINUX_KARCH)" \
+       PATH="$(TARGET_PATH)" \
+       SUBDIRS="$(PKG_BUILD_DIR)" \
+       PWD="$(PKG_BUILD_DIR)" \
+       LINUX_VERSION="$(LINUX_VERSION)" \
+       CONFIG_BATMAN_ADV_DEBUG=$(if $(CONFIG_KMOD_BATMAN_ADV_DEBUG_LOG),y,n) \
+       CONFIG_BATMAN_ADV_BLA=$(if $(CONFIG_KMOD_BATMAN_ADV_BLA),y,n) \
+       CONFIG_BATMAN_ADV_DAT=$(if $(CONFIG_KMOD_BATMAN_ADV_DAT),y,n) \
+       REVISION="" all
+
+MAKE_BATCTL_ARGS += \
+       CFLAGS="$(TARGET_CFLAGS)" \
+       CCFLAGS="$(TARGET_CFLAGS)" \
+       OFLAGS="$(TARGET_CFLAGS)" \
+       REVISION="" \
+       CC="$(TARGET_CC)" \
+       NODEBUG=1 \
+       UNAME="Linux" \
+       DESTDIR="$(PKG_INSTALL_DIR)" \
+       STRIP="/bin/true" \
+       batctl install
+
+ifneq ($(DEVELOPER)$(CONFIG_KMOD_BATMAN_ADV_BATCTL),)
+define Download/batctl
+  FILE:=batctl-$(BATCTL_VERSION).tar.gz
+  URL:=$(PKG_SOURCE_URL)
+  MD5SUM:=$(BATCTL_MD5SUM)
+endef
+$(eval $(call Download,batctl))
+
+BATCTL_EXTRACT = tar xzf "$(DL_DIR)/batctl-$(BATCTL_VERSION).tar.gz" -C "$(BUILD_DIR)/$(PKG_NAME)"
+BATCTL_PATCH = $(call Build/DoPatch,"$(PKG_BATCTL_BUILD_DIR)","$(PATCH_DIR)","*batctl*")
+BATCTL_BUILD = $(MAKE) -C $(PKG_BATCTL_BUILD_DIR) $(MAKE_BATCTL_ARGS)
+BATCTL_INSTALL = $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/local/sbin/batctl $(1)/usr/sbin/
+endif
+
+KPATCH ?= $(PATCH)
+define Build/DoPatch
+       @if [ -d "$(2)" ]; then \
+               if [ "$$$$(ls $(2) | grep -Ec $(3))" -gt 0 ]; then \
+                       $(KPATCH) "$(1)" "$(2)" "$(3)"; \
+               fi; \
+       fi
+endef
+
+define Build/Patch
+       $(call Build/DoPatch,"$(PKG_BUILD_DIR)","$(PATCH_DIR)","*batman*")
+       $(BATCTL_EXTRACT)
+       $(BATCTL_PATCH)
+endef
+
+define Build/Compile
+       $(MAKE) -C "$(PKG_BUILD_DIR)" $(MAKE_BATMAN_ADV_ARGS)
+       $(BATCTL_BUILD)
+endef
+
+define Build/Clean
+        rm -rf $(BUILD_DIR)/$(PKG_NAME)/
+endef
+
+define KernelPackage/batman-adv/install
+       $(INSTALL_DIR) $(1)/etc/config $(1)/etc/hotplug.d/net $(1)/etc/hotplug.d/iface $(1)/lib/batman-adv $(1)/usr/sbin $(1)/lib/netifd/proto
+       $(INSTALL_DATA) ./files/etc/config/batman-adv $(1)/etc/config
+       $(INSTALL_DATA) ./files/lib/batman-adv/config.sh $(1)/lib/batman-adv
+       $(INSTALL_BIN) ./files/etc/hotplug.d/net/99-batman-adv $(1)/etc/hotplug.d/net
+       $(INSTALL_BIN) ./files/lib/netifd/proto/batadv.sh $(1)/lib/netifd/proto
+       $(BATCTL_INSTALL)
+endef
+
+$(eval $(call KernelPackage,batman-adv))
diff --git a/batman-adv/files/etc/config/batman-adv b/batman-adv/files/etc/config/batman-adv
new file mode 100644 (file)
index 0000000..6a62203
--- /dev/null
@@ -0,0 +1,19 @@
+
+config 'mesh' 'bat0'
+       option 'aggregated_ogms'
+       option 'ap_isolation'
+       option 'bonding'
+       option 'fragmentation'
+       option 'gw_bandwidth'
+       option 'gw_mode'
+       option 'gw_sel_class'
+       option 'log_level'
+       option 'orig_interval'
+       option 'vis_mode'
+       option 'bridge_loop_avoidance'
+       option 'distributed_arp_table'
+       option 'hop_penalty'
+
+# yet another batX instance
+# config 'mesh' 'bat5'
+#      option 'interfaces' 'second_mesh'
diff --git a/batman-adv/files/etc/hotplug.d/net/99-batman-adv b/batman-adv/files/etc/hotplug.d/net/99-batman-adv
new file mode 100644 (file)
index 0000000..f0c391f
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+. /lib/batman-adv/config.sh
+
+bat_load_module
+config_load batman-adv
+
+case "$ACTION" in
+       add)
+               [ -d /sys/class/net/$INTERFACE/mesh/ ] && bat_config "$INTERFACE"
+               ;;
+esac
diff --git a/batman-adv/files/lib/batman-adv/config.sh b/batman-adv/files/lib/batman-adv/config.sh
new file mode 100644 (file)
index 0000000..ae102e9
--- /dev/null
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+bat_load_module()
+{
+       [ -d "/sys/module/batman_adv/" ] && return
+
+       . /lib/functions.sh
+       load_modules /etc/modules.d/*-crc16 /etc/modules.d/*-batman-adv*
+}
+
+bat_config()
+{
+       local mesh="$1"
+       local aggregated_ogms ap_isolation bonding bridge_loop_avoidance distributed_arp_table fragmentation
+       local gw_bandwidth gw_mode gw_sel_class hop_penalty log_level orig_interval vis_mode
+
+       config_get aggregated_ogms "$mesh" aggregated_ogms
+       config_get ap_isolation "$mesh" ap_isolation
+       config_get bonding "$mesh" bonding
+       config_get bridge_loop_avoidance "$mesh" bridge_loop_avoidance
+       config_get distributed_arp_table "$mesh" distributed_arp_table
+       config_get fragmentation "$mesh" fragmentation
+       config_get gw_bandwidth "$mesh" gw_bandwidth
+       config_get gw_mode "$mesh" gw_mode
+       config_get gw_sel_class "$mesh" gw_sel_class
+       config_get hop_penalty "$mesh" hop_penalty
+       config_get log_level "$mesh" log_level
+       config_get orig_interval "$mesh" orig_interval
+       config_get vis_mode "$mesh" vis_mode
+
+       [ ! -f "/sys/class/net/$mesh/mesh/orig_interval" ] && echo "batman-adv mesh $mesh does not exist - check your interface configuration" && return 1
+
+       [ -n "$aggregate_ogms" ] && echo $aggregate_ogms > /sys/class/net/$mesh/mesh/aggregate_ogms
+       [ -n "$ap_isolation" ] && echo $ap_isolation > /sys/class/net/$mesh/mesh/ap_isolation
+       [ -n "$bonding" ] && echo $bonding > /sys/class/net/$mesh/mesh/bonding
+       [ -n "$bridge_loop_avoidance" ] && echo $bridge_loop_avoidance > /sys/class/net/$mesh/mesh/bridge_loop_avoidance
+       [ -n "$distributed_arp_table" ] && echo $distributed_arp_table > /sys/class/net/$mesh/mesh/distributed_arp_table
+       [ -n "$fragmentation" ] && echo $fragmentation > /sys/class/net/$mesh/mesh/fragmentation
+       [ -n "$gw_bandwidth" ] && echo $gw_bandwidth > /sys/class/net/$mesh/mesh/gw_bandwidth
+       [ -n "$gw_mode" ] && echo $gw_mode > /sys/class/net/$mesh/mesh/gw_mode
+       [ -n "$gw_sel_class" ] && echo $gw_sel_class > /sys/class/net/$mesh/mesh/gw_sel_class
+       [ -n "$hop_penalty" ] && echo $hop_penalty > /sys/class/net/$mesh/mesh/hop_penalty
+       [ -n "$log_level" ] && echo $log_level > /sys/class/net/$mesh/mesh/log_level 2>&-
+       [ -n "$orig_interval" ] && echo $orig_interval > /sys/class/net/$mesh/mesh/orig_interval
+       [ -n "$vis_mode" ] && echo $vis_mode > /sys/class/net/$mesh/mesh/vis_mode
+}
diff --git a/batman-adv/files/lib/netifd/proto/batadv.sh b/batman-adv/files/lib/netifd/proto/batadv.sh
new file mode 100644 (file)
index 0000000..632a209
--- /dev/null
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. ../netifd-proto.sh
+init_proto "$@"
+
+proto_batadv_init_config() {
+       proto_config_add_string "mesh"
+}
+
+proto_batadv_setup() {
+       local config="$1"
+       local iface="$2"
+
+       local mesh
+       json_get_vars mesh
+
+       echo "$mesh" > "/sys/class/net/$iface/batman_adv/mesh_iface"
+       proto_init_update "$iface" 1
+       proto_send_update "$config"
+}
+
+proto_batadv_teardown() {
+       local config="$1"
+       local iface="$2"
+
+       echo "none" > "/sys/class/net/$iface/batman_adv/mesh_iface" || true
+}
+
+add_protocol batadv
diff --git a/batman-adv/patches/0001-batman-adv-verify-tt-len-does-not-exceed-packet-len.patch b/batman-adv/patches/0001-batman-adv-verify-tt-len-does-not-exceed-packet-len.patch
new file mode 100644 (file)
index 0000000..46b2c8d
--- /dev/null
@@ -0,0 +1,42 @@
+From e56c79f4e863436d0fc6c48fed0db09b7a49e565 Mon Sep 17 00:00:00 2001
+From: Marek Lindner <lindner_marek@yahoo.de>
+Date: Mon, 4 Mar 2013 10:39:49 +0800
+Subject: [PATCH 1/3] batman-adv: verify tt len does not exceed packet len
+
+batadv_iv_ogm_process() accesses the packet using the tt_num_changes
+attribute regardless of the real packet len (assuming the length check
+was done before). Therefore a length check is needed to avoid reading
+random memory.
+
+Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
+---
+ bat_iv_ogm.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c
+index 72fe1bb..d5be889 100644
+--- a/bat_iv_ogm.c
++++ b/bat_iv_ogm.c
+@@ -1292,7 +1292,8 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
+       batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
+       /* unpack the aggregated packets and process them one by one */
+-      do {
++      while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len,
++                                       batadv_ogm_packet->tt_num_changes)) {
+               tt_buff = packet_buff + buff_pos + BATADV_OGM_HLEN;
+               batadv_iv_ogm_process(ethhdr, batadv_ogm_packet, tt_buff,
+@@ -1303,8 +1304,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
+               packet_pos = packet_buff + buff_pos;
+               batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
+-      } while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len,
+-                                         batadv_ogm_packet->tt_num_changes));
++      }
+       kfree_skb(skb);
+       return NET_RX_SUCCESS;
+-- 
+1.7.10.4
+
diff --git a/batman-adv/patches/0002-batman-adv-hlist-drop-the-node-parameter-from-iterators.patch b/batman-adv/patches/0002-batman-adv-hlist-drop-the-node-parameter-from-iterators.patch
new file mode 100644 (file)
index 0000000..71af36a
--- /dev/null
@@ -0,0 +1,1462 @@
+From c506b113c82319c43478ff31c933c4e98f0084d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sasha.levin@oracle.com>
+Date: Wed, 27 Feb 2013 17:06:00 -0800
+Subject: [PATCH 2/3] hlist: drop the node parameter from iterators
+
+I'm not sure why, but the hlist for each entry iterators were conceived
+
+        list_for_each_entry(pos, head, member)
+
+The hlist ones were greedy and wanted an extra parameter:
+
+        hlist_for_each_entry(tpos, pos, head, member)
+
+Why did they need an extra pos parameter? I'm not quite sure. Not only
+they don't really need it, it also prevents the iterator from looking
+exactly like the list iterator, which is unfortunate.
+
+Besides the semantic patch, there was some manual work required:
+
+ - Fix up the actual hlist iterators in linux/list.h
+ - Fix up the declaration of other iterators based on the hlist ones.
+ - A very small amount of places were using the 'node' parameter, this
+ was modified to use 'obj->member' instead.
+ - Coccinelle didn't handle the hlist_for_each_entry_safe iterator
+ properly, so those had to be fixed up manually.
+
+The semantic patch which is mostly the work of Peter Senna Tschudin is here:
+
+@@
+iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
+
+type T;
+expression a,c,d,e;
+identifier b;
+statement S;
+@@
+
+-T b;
+    <+... when != b
+(
+hlist_for_each_entry(a,
+- b,
+c, d) S
+|
+hlist_for_each_entry_continue(a,
+- b,
+c) S
+|
+hlist_for_each_entry_from(a,
+- b,
+c) S
+|
+hlist_for_each_entry_rcu(a,
+- b,
+c, d) S
+|
+hlist_for_each_entry_rcu_bh(a,
+- b,
+c, d) S
+|
+hlist_for_each_entry_continue_rcu_bh(a,
+- b,
+c) S
+|
+for_each_busy_worker(a, c,
+- b,
+d) S
+|
+ax25_uid_for_each(a,
+- b,
+c) S
+|
+ax25_for_each(a,
+- b,
+c) S
+|
+inet_bind_bucket_for_each(a,
+- b,
+c) S
+|
+sctp_for_each_hentry(a,
+- b,
+c) S
+|
+sk_for_each(a,
+- b,
+c) S
+|
+sk_for_each_rcu(a,
+- b,
+c) S
+|
+sk_for_each_from
+-(a, b)
++(a)
+S
++ sk_for_each_from(a) S
+|
+sk_for_each_safe(a,
+- b,
+c, d) S
+|
+sk_for_each_bound(a,
+- b,
+c) S
+|
+hlist_for_each_entry_safe(a,
+- b,
+c, d, e) S
+|
+hlist_for_each_entry_continue_rcu(a,
+- b,
+c) S
+|
+nr_neigh_for_each(a,
+- b,
+c) S
+|
+nr_neigh_for_each_safe(a,
+- b,
+c, d) S
+|
+nr_node_for_each(a,
+- b,
+c) S
+|
+nr_node_for_each_safe(a,
+- b,
+c, d) S
+|
+- for_each_gfn_sp(a, c, d, b) S
++ for_each_gfn_sp(a, c, d) S
+|
+- for_each_gfn_indirect_valid_sp(a, c, d, b) S
++ for_each_gfn_indirect_valid_sp(a, c, d) S
+|
+for_each_host(a,
+- b,
+c) S
+|
+for_each_host_safe(a,
+- b,
+c, d) S
+|
+for_each_mesh_entry(a,
+- b,
+c, d) S
+)
+    ...+>
+
+[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
+[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
+[akpm@linux-foundation.org: checkpatch fixes]
+[akpm@linux-foundation.org: fix warnings]
+[akpm@linux-foudnation.org: redo intrusive kvm changes]
+Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
+Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
+Cc: Wu Fengguang <fengguang.wu@intel.com>
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Cc: Gleb Natapov <gleb@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
+---
+ bat_iv_ogm.c            |   12 +++----
+ bridge_loop_avoidance.c |   39 +++++++++-------------
+ compat.h                |   23 +++++++++++++
+ distributed-arp-table.c |   15 ++++-----
+ gateway_client.c        |   13 +++-----
+ main.c                  |    6 ++--
+ originator.c            |   31 ++++++++----------
+ originator.h            |    3 +-
+ routing.c               |    6 ++--
+ send.c                  |    6 ++--
+ translation-table.c     |   82 ++++++++++++++++++++---------------------------
+ vis.c                   |   38 +++++++++-------------
+ 12 files changed, 125 insertions(+), 149 deletions(-)
+
+diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c
+index d5be889..a5bb0a7 100644
+--- a/bat_iv_ogm.c
++++ b/bat_iv_ogm.c
+@@ -487,7 +487,6 @@ static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
+        */
+       struct batadv_forw_packet *forw_packet_aggr = NULL;
+       struct batadv_forw_packet *forw_packet_pos = NULL;
+-      struct hlist_node *tmp_node;
+       struct batadv_ogm_packet *batadv_ogm_packet;
+       bool direct_link;
+       unsigned long max_aggregation_jiffies;
+@@ -500,7 +499,7 @@ static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
+       spin_lock_bh(&bat_priv->forw_bat_list_lock);
+       /* own packets are not to be aggregated */
+       if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) {
+-              hlist_for_each_entry(forw_packet_pos, tmp_node,
++              hlist_for_each_entry(forw_packet_pos,
+                                    &bat_priv->forw_bat_list, list) {
+                       if (batadv_iv_ogm_can_aggregate(batadv_ogm_packet,
+                                                       bat_priv, packet_len,
+@@ -655,7 +654,6 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
+       struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
+       struct batadv_neigh_node *router = NULL;
+       struct batadv_orig_node *orig_node_tmp;
+-      struct hlist_node *node;
+       int if_num;
+       uint8_t sum_orig, sum_neigh;
+       uint8_t *neigh_addr;
+@@ -665,7 +663,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
+                  "update_originator(): Searching and updating originator entry of received packet\n");
+       rcu_read_lock();
+-      hlist_for_each_entry_rcu(tmp_neigh_node, node,
++      hlist_for_each_entry_rcu(tmp_neigh_node,
+                                &orig_node->neigh_list, list) {
+               neigh_addr = tmp_neigh_node->addr;
+               if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
+@@ -801,7 +799,6 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
+ {
+       struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+       struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node;
+-      struct hlist_node *node;
+       uint8_t total_count;
+       uint8_t orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
+       unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
+@@ -810,7 +807,7 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
+       /* find corresponding one hop neighbor */
+       rcu_read_lock();
+-      hlist_for_each_entry_rcu(tmp_neigh_node, node,
++      hlist_for_each_entry_rcu(tmp_neigh_node,
+                                &orig_neigh_node->neigh_list, list) {
+               if (!batadv_compare_eth(tmp_neigh_node->addr,
+                                       orig_neigh_node->orig))
+@@ -920,7 +917,6 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
+       struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+       struct batadv_orig_node *orig_node;
+       struct batadv_neigh_node *tmp_neigh_node;
+-      struct hlist_node *node;
+       int is_duplicate = 0;
+       int32_t seq_diff;
+       int need_update = 0;
+@@ -943,7 +939,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
+               goto out;
+       rcu_read_lock();
+-      hlist_for_each_entry_rcu(tmp_neigh_node, node,
++      hlist_for_each_entry_rcu(tmp_neigh_node,
+                                &orig_node->neigh_list, list) {
+               is_duplicate |= batadv_test_bit(tmp_neigh_node->real_bits,
+                                               orig_node->last_real_seqno,
+diff --git a/bridge_loop_avoidance.c b/bridge_loop_avoidance.c
+index 30f4652..6a4f728 100644
+--- a/bridge_loop_avoidance.c
++++ b/bridge_loop_avoidance.c
+@@ -144,7 +144,6 @@ static struct batadv_bla_claim
+ {
+       struct batadv_hashtable *hash = bat_priv->bla.claim_hash;
+       struct hlist_head *head;
+-      struct hlist_node *node;
+       struct batadv_bla_claim *claim;
+       struct batadv_bla_claim *claim_tmp = NULL;
+       int index;
+@@ -156,7 +155,7 @@ static struct batadv_bla_claim
+       head = &hash->table[index];
+       rcu_read_lock();
+-      hlist_for_each_entry_rcu(claim, node, head, hash_entry) {
++      hlist_for_each_entry_rcu(claim, head, hash_entry) {
+               if (!batadv_compare_claim(&claim->hash_entry, data))
+                       continue;
+@@ -185,7 +184,6 @@ batadv_backbone_hash_find(struct batadv_priv *bat_priv,
+ {
+       struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
+       struct hlist_head *head;
+-      struct hlist_node *node;
+       struct batadv_bla_backbone_gw search_entry, *backbone_gw;
+       struct batadv_bla_backbone_gw *backbone_gw_tmp = NULL;
+       int index;
+@@ -200,7 +198,7 @@ batadv_backbone_hash_find(struct batadv_priv *bat_priv,
+       head = &hash->table[index];
+       rcu_read_lock();
+-      hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
++      hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
+               if (!batadv_compare_backbone_gw(&backbone_gw->hash_entry,
+                                               &search_entry))
+                       continue;
+@@ -221,7 +219,7 @@ static void
+ batadv_bla_del_backbone_claims(struct batadv_bla_backbone_gw *backbone_gw)
+ {
+       struct batadv_hashtable *hash;
+-      struct hlist_node *node, *node_tmp;
++      struct hlist_node *node_tmp;
+       struct hlist_head *head;
+       struct batadv_bla_claim *claim;
+       int i;
+@@ -236,13 +234,13 @@ batadv_bla_del_backbone_claims(struct batadv_bla_backbone_gw *backbone_gw)
+               list_lock = &hash->list_locks[i];
+               spin_lock_bh(list_lock);
+-              hlist_for_each_entry_safe(claim, node, node_tmp,
++              hlist_for_each_entry_safe(claim, node_tmp,
+                                         head, hash_entry) {
+                       if (claim->backbone_gw != backbone_gw)
+                               continue;
+                       batadv_claim_free_ref(claim);
+-                      hlist_del_rcu(node);
++                      hlist_del_rcu(&claim->hash_entry);
+               }
+               spin_unlock_bh(list_lock);
+       }
+@@ -460,7 +458,6 @@ static void batadv_bla_answer_request(struct batadv_priv *bat_priv,
+                                     struct batadv_hard_iface *primary_if,
+                                     short vid)
+ {
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       struct batadv_hashtable *hash;
+       struct batadv_bla_claim *claim;
+@@ -481,7 +478,7 @@ static void batadv_bla_answer_request(struct batadv_priv *bat_priv,
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(claim, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(claim, head, hash_entry) {
+                       /* only own claims are interesting */
+                       if (claim->backbone_gw != backbone_gw)
+                               continue;
+@@ -958,7 +955,7 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
+ static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now)
+ {
+       struct batadv_bla_backbone_gw *backbone_gw;
+-      struct hlist_node *node, *node_tmp;
++      struct hlist_node *node_tmp;
+       struct hlist_head *head;
+       struct batadv_hashtable *hash;
+       spinlock_t *list_lock;  /* protects write access to the hash lists */
+@@ -973,7 +970,7 @@ static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now)
+               list_lock = &hash->list_locks[i];
+               spin_lock_bh(list_lock);
+-              hlist_for_each_entry_safe(backbone_gw, node, node_tmp,
++              hlist_for_each_entry_safe(backbone_gw, node_tmp,
+                                         head, hash_entry) {
+                       if (now)
+                               goto purge_now;
+@@ -992,7 +989,7 @@ purge_now:
+                       batadv_bla_del_backbone_claims(backbone_gw);
+-                      hlist_del_rcu(node);
++                      hlist_del_rcu(&backbone_gw->hash_entry);
+                       batadv_backbone_gw_free_ref(backbone_gw);
+               }
+               spin_unlock_bh(list_lock);
+@@ -1013,7 +1010,6 @@ static void batadv_bla_purge_claims(struct batadv_priv *bat_priv,
+                                   int now)
+ {
+       struct batadv_bla_claim *claim;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       struct batadv_hashtable *hash;
+       int i;
+@@ -1026,7 +1022,7 @@ static void batadv_bla_purge_claims(struct batadv_priv *bat_priv,
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(claim, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(claim, head, hash_entry) {
+                       if (now)
+                               goto purge_now;
+                       if (!batadv_compare_eth(claim->backbone_gw->orig,
+@@ -1062,7 +1058,6 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
+                                   struct batadv_hard_iface *oldif)
+ {
+       struct batadv_bla_backbone_gw *backbone_gw;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       struct batadv_hashtable *hash;
+       __be16 group;
+@@ -1086,7 +1081,7 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
+                       /* own orig still holds the old value. */
+                       if (!batadv_compare_eth(backbone_gw->orig,
+                                               oldif->net_dev->dev_addr))
+@@ -1112,7 +1107,6 @@ static void batadv_bla_periodic_work(struct work_struct *work)
+       struct delayed_work *delayed_work;
+       struct batadv_priv *bat_priv;
+       struct batadv_priv_bla *priv_bla;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       struct batadv_bla_backbone_gw *backbone_gw;
+       struct batadv_hashtable *hash;
+@@ -1140,7 +1134,7 @@ static void batadv_bla_periodic_work(struct work_struct *work)
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
+                       if (!batadv_compare_eth(backbone_gw->orig,
+                                               primary_if->net_dev->dev_addr))
+                               continue;
+@@ -1322,7 +1316,6 @@ int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig)
+ {
+       struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
+       struct hlist_head *head;
+-      struct hlist_node *node;
+       struct batadv_bla_backbone_gw *backbone_gw;
+       int i;
+@@ -1336,7 +1329,7 @@ int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig)
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
+                       if (batadv_compare_eth(backbone_gw->orig, orig)) {
+                               rcu_read_unlock();
+                               return 1;
+@@ -1607,7 +1600,6 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
+       struct batadv_hashtable *hash = bat_priv->bla.claim_hash;
+       struct batadv_bla_claim *claim;
+       struct batadv_hard_iface *primary_if;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       uint32_t i;
+       bool is_own;
+@@ -1628,7 +1620,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(claim, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(claim, head, hash_entry) {
+                       is_own = batadv_compare_eth(claim->backbone_gw->orig,
+                                                   primary_addr);
+                       seq_printf(seq, " * %pM on % 5d by %pM [%c] (%#.4x)\n",
+@@ -1652,7 +1644,6 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
+       struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
+       struct batadv_bla_backbone_gw *backbone_gw;
+       struct batadv_hard_iface *primary_if;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       int secs, msecs;
+       uint32_t i;
+@@ -1674,7 +1665,7 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
+                       msecs = jiffies_to_msecs(jiffies -
+                                                backbone_gw->lasttime);
+                       secs = msecs / 1000;
+diff --git a/compat.h b/compat.h
+index e21b310..22ab781 100644
+--- a/compat.h
++++ b/compat.h
+@@ -211,6 +211,29 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) \
+ }\
+ static int __batadv_interface_set_mac_addr(x, y)
++#define hlist_entry_safe(ptr, type, member) \
++      (ptr) ? hlist_entry(ptr, type, member) : NULL
++
++#undef hlist_for_each_entry
++#define hlist_for_each_entry(pos, head, member) \
++      for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
++      pos; \
++      pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
++
++#undef hlist_for_each_entry_rcu
++#define hlist_for_each_entry_rcu(pos, head, member) \
++      for (pos = hlist_entry_safe (rcu_dereference_raw(hlist_first_rcu(head)),\
++      typeof(*(pos)), member); \
++      pos; \
++      pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(\
++      &(pos)->member)), typeof(*(pos)), member))
++
++#undef hlist_for_each_entry_safe
++#define hlist_for_each_entry_safe(pos, n, head, member) \
++      for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\
++      pos && ({ n = pos->member.next; 1; }); \
++      pos = hlist_entry_safe(n, typeof(*pos), member))
++
+ #endif /* < KERNEL_VERSION(3, 9, 0) */
+ #endif /* _NET_BATMAN_ADV_COMPAT_H_ */
+diff --git a/distributed-arp-table.c b/distributed-arp-table.c
+index 761a590..d54188a 100644
+--- a/distributed-arp-table.c
++++ b/distributed-arp-table.c
+@@ -83,7 +83,7 @@ static void __batadv_dat_purge(struct batadv_priv *bat_priv,
+ {
+       spinlock_t *list_lock; /* protects write access to the hash lists */
+       struct batadv_dat_entry *dat_entry;
+-      struct hlist_node *node, *node_tmp;
++      struct hlist_node *node_tmp;
+       struct hlist_head *head;
+       uint32_t i;
+@@ -95,7 +95,7 @@ static void __batadv_dat_purge(struct batadv_priv *bat_priv,
+               list_lock = &bat_priv->dat.hash->list_locks[i];
+               spin_lock_bh(list_lock);
+-              hlist_for_each_entry_safe(dat_entry, node, node_tmp, head,
++              hlist_for_each_entry_safe(dat_entry, node_tmp, head,
+                                         hash_entry) {
+                       /* if an helper function has been passed as parameter,
+                        * ask it if the entry has to be purged or not
+@@ -103,7 +103,7 @@ static void __batadv_dat_purge(struct batadv_priv *bat_priv,
+                       if (to_purge && !to_purge(dat_entry))
+                               continue;
+-                      hlist_del_rcu(node);
++                      hlist_del_rcu(&dat_entry->hash_entry);
+                       batadv_dat_entry_free_ref(dat_entry);
+               }
+               spin_unlock_bh(list_lock);
+@@ -235,7 +235,6 @@ static struct batadv_dat_entry *
+ batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip)
+ {
+       struct hlist_head *head;
+-      struct hlist_node *node;
+       struct batadv_dat_entry *dat_entry, *dat_entry_tmp = NULL;
+       struct batadv_hashtable *hash = bat_priv->dat.hash;
+       uint32_t index;
+@@ -247,7 +246,7 @@ batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip)
+       head = &hash->table[index];
+       rcu_read_lock();
+-      hlist_for_each_entry_rcu(dat_entry, node, head, hash_entry) {
++      hlist_for_each_entry_rcu(dat_entry, head, hash_entry) {
+               if (dat_entry->ip != ip)
+                       continue;
+@@ -465,7 +464,6 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv,
+       batadv_dat_addr_t max = 0, tmp_max = 0;
+       struct batadv_orig_node *orig_node, *max_orig_node = NULL;
+       struct batadv_hashtable *hash = bat_priv->orig_hash;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       int i;
+@@ -481,7 +479,7 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv,
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
+                       /* the dht space is a ring and addresses are unsigned */
+                       tmp_max = BATADV_DAT_ADDR_MAX - orig_node->dat_addr +
+                                 ip_key;
+@@ -686,7 +684,6 @@ int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset)
+       struct batadv_hashtable *hash = bat_priv->dat.hash;
+       struct batadv_dat_entry *dat_entry;
+       struct batadv_hard_iface *primary_if;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       unsigned long last_seen_jiffies;
+       int last_seen_msecs, last_seen_secs, last_seen_mins;
+@@ -704,7 +701,7 @@ int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset)
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(dat_entry, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(dat_entry, head, hash_entry) {
+                       last_seen_jiffies = jiffies - dat_entry->last_update;
+                       last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
+                       last_seen_mins = last_seen_msecs / 60000;
+diff --git a/gateway_client.c b/gateway_client.c
+index 074107f..34f99a4 100644
+--- a/gateway_client.c
++++ b/gateway_client.c
+@@ -114,7 +114,6 @@ static struct batadv_gw_node *
+ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
+ {
+       struct batadv_neigh_node *router;
+-      struct hlist_node *node;
+       struct batadv_gw_node *gw_node, *curr_gw = NULL;
+       uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
+       uint32_t gw_divisor;
+@@ -127,7 +126,7 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
+       gw_divisor *= 64;
+       rcu_read_lock();
+-      hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw.list, list) {
++      hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.list, list) {
+               if (gw_node->deleted)
+                       continue;
+@@ -344,7 +343,6 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv,
+                          struct batadv_orig_node *orig_node,
+                          uint8_t new_gwflags)
+ {
+-      struct hlist_node *node;
+       struct batadv_gw_node *gw_node, *curr_gw;
+       /* Note: We don't need a NULL check here, since curr_gw never gets
+@@ -355,7 +353,7 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv,
+       curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
+       rcu_read_lock();
+-      hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw.list, list) {
++      hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.list, list) {
+               if (gw_node->orig_node != orig_node)
+                       continue;
+@@ -403,7 +401,7 @@ void batadv_gw_node_delete(struct batadv_priv *bat_priv,
+ void batadv_gw_node_purge(struct batadv_priv *bat_priv)
+ {
+       struct batadv_gw_node *gw_node, *curr_gw;
+-      struct hlist_node *node, *node_tmp;
++      struct hlist_node *node_tmp;
+       unsigned long timeout = msecs_to_jiffies(2 * BATADV_PURGE_TIMEOUT);
+       int do_deselect = 0;
+@@ -411,7 +409,7 @@ void batadv_gw_node_purge(struct batadv_priv *bat_priv)
+       spin_lock_bh(&bat_priv->gw.list_lock);
+-      hlist_for_each_entry_safe(gw_node, node, node_tmp,
++      hlist_for_each_entry_safe(gw_node, node_tmp,
+                                 &bat_priv->gw.list, list) {
+               if (((!gw_node->deleted) ||
+                    (time_before(jiffies, gw_node->deleted + timeout))) &&
+@@ -476,7 +474,6 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
+       struct batadv_priv *bat_priv = netdev_priv(net_dev);
+       struct batadv_hard_iface *primary_if;
+       struct batadv_gw_node *gw_node;
+-      struct hlist_node *node;
+       int gw_count = 0;
+       primary_if = batadv_seq_print_text_primary_if_get(seq);
+@@ -490,7 +487,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
+                  primary_if->net_dev->dev_addr, net_dev->name);
+       rcu_read_lock();
+-      hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw.list, list) {
++      hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.list, list) {
+               if (gw_node->deleted)
+                       continue;
+diff --git a/main.c b/main.c
+index 21fe698..0488d70 100644
+--- a/main.c
++++ b/main.c
+@@ -345,9 +345,8 @@ void batadv_recv_handler_unregister(uint8_t packet_type)
+ static struct batadv_algo_ops *batadv_algo_get(char *name)
+ {
+       struct batadv_algo_ops *bat_algo_ops = NULL, *bat_algo_ops_tmp;
+-      struct hlist_node *node;
+-      hlist_for_each_entry(bat_algo_ops_tmp, node, &batadv_algo_list, list) {
++      hlist_for_each_entry(bat_algo_ops_tmp, &batadv_algo_list, list) {
+               if (strcmp(bat_algo_ops_tmp->name, name) != 0)
+                       continue;
+@@ -411,11 +410,10 @@ out:
+ int batadv_algo_seq_print_text(struct seq_file *seq, void *offset)
+ {
+       struct batadv_algo_ops *bat_algo_ops;
+-      struct hlist_node *node;
+       seq_printf(seq, "Available routing algorithms:\n");
+-      hlist_for_each_entry(bat_algo_ops, node, &batadv_algo_list, list) {
++      hlist_for_each_entry(bat_algo_ops, &batadv_algo_list, list) {
+               seq_printf(seq, "%s\n", bat_algo_ops->name);
+       }
+diff --git a/originator.c b/originator.c
+index 457ea44..96fb80b 100644
+--- a/originator.c
++++ b/originator.c
+@@ -118,7 +118,7 @@ out:
+ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
+ {
+-      struct hlist_node *node, *node_tmp;
++      struct hlist_node *node_tmp;
+       struct batadv_neigh_node *neigh_node, *tmp_neigh_node;
+       struct batadv_orig_node *orig_node;
+@@ -134,7 +134,7 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
+       }
+       /* for all neighbors towards this originator ... */
+-      hlist_for_each_entry_safe(neigh_node, node, node_tmp,
++      hlist_for_each_entry_safe(neigh_node, node_tmp,
+                                 &orig_node->neigh_list, list) {
+               hlist_del_rcu(&neigh_node->list);
+               batadv_neigh_node_free_ref(neigh_node);
+@@ -161,7 +161,7 @@ void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node)
+ void batadv_originator_free(struct batadv_priv *bat_priv)
+ {
+       struct batadv_hashtable *hash = bat_priv->orig_hash;
+-      struct hlist_node *node, *node_tmp;
++      struct hlist_node *node_tmp;
+       struct hlist_head *head;
+       spinlock_t *list_lock; /* spinlock to protect write access */
+       struct batadv_orig_node *orig_node;
+@@ -179,9 +179,9 @@ void batadv_originator_free(struct batadv_priv *bat_priv)
+               list_lock = &hash->list_locks[i];
+               spin_lock_bh(list_lock);
+-              hlist_for_each_entry_safe(orig_node, node, node_tmp,
++              hlist_for_each_entry_safe(orig_node, node_tmp,
+                                         head, hash_entry) {
+-                      hlist_del_rcu(node);
++                      hlist_del_rcu(&orig_node->hash_entry);
+                       batadv_orig_node_free_ref(orig_node);
+               }
+               spin_unlock_bh(list_lock);
+@@ -274,7 +274,7 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
+                           struct batadv_orig_node *orig_node,
+                           struct batadv_neigh_node **best_neigh_node)
+ {
+-      struct hlist_node *node, *node_tmp;
++      struct hlist_node *node_tmp;
+       struct batadv_neigh_node *neigh_node;
+       bool neigh_purged = false;
+       unsigned long last_seen;
+@@ -285,7 +285,7 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
+       spin_lock_bh(&orig_node->neigh_list_lock);
+       /* for all neighbors towards this originator ... */
+-      hlist_for_each_entry_safe(neigh_node, node, node_tmp,
++      hlist_for_each_entry_safe(neigh_node, node_tmp,
+                                 &orig_node->neigh_list, list) {
+               last_seen = neigh_node->last_seen;
+               if_incoming = neigh_node->if_incoming;
+@@ -348,7 +348,7 @@ static bool batadv_purge_orig_node(struct batadv_priv *bat_priv,
+ static void _batadv_purge_orig(struct batadv_priv *bat_priv)
+ {
+       struct batadv_hashtable *hash = bat_priv->orig_hash;
+-      struct hlist_node *node, *node_tmp;
++      struct hlist_node *node_tmp;
+       struct hlist_head *head;
+       spinlock_t *list_lock; /* spinlock to protect write access */
+       struct batadv_orig_node *orig_node;
+@@ -363,13 +363,13 @@ static void _batadv_purge_orig(struct batadv_priv *bat_priv)
+               list_lock = &hash->list_locks[i];
+               spin_lock_bh(list_lock);
+-              hlist_for_each_entry_safe(orig_node, node, node_tmp,
++              hlist_for_each_entry_safe(orig_node, node_tmp,
+                                         head, hash_entry) {
+                       if (batadv_purge_orig_node(bat_priv, orig_node)) {
+                               if (orig_node->gw_flags)
+                                       batadv_gw_node_delete(bat_priv,
+                                                             orig_node);
+-                              hlist_del_rcu(node);
++                              hlist_del_rcu(&orig_node->hash_entry);
+                               batadv_orig_node_free_ref(orig_node);
+                               continue;
+                       }
+@@ -408,7 +408,6 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset)
+       struct net_device *net_dev = (struct net_device *)seq->private;
+       struct batadv_priv *bat_priv = netdev_priv(net_dev);
+       struct batadv_hashtable *hash = bat_priv->orig_hash;
+-      struct hlist_node *node, *node_tmp;
+       struct hlist_head *head;
+       struct batadv_hard_iface *primary_if;
+       struct batadv_orig_node *orig_node;
+@@ -434,7 +433,7 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset)
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
+                       neigh_node = batadv_orig_node_get_router(orig_node);
+                       if (!neigh_node)
+                               continue;
+@@ -453,7 +452,7 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset)
+                                  neigh_node->addr,
+                                  neigh_node->if_incoming->net_dev->name);
+-                      hlist_for_each_entry_rcu(neigh_node_tmp, node_tmp,
++                      hlist_for_each_entry_rcu(neigh_node_tmp,
+                                                &orig_node->neigh_list, list) {
+                               seq_printf(seq, " %pM (%3i)",
+                                          neigh_node_tmp->addr,
+@@ -511,7 +510,6 @@ int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
+ {
+       struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+       struct batadv_hashtable *hash = bat_priv->orig_hash;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       struct batadv_orig_node *orig_node;
+       uint32_t i;
+@@ -524,7 +522,7 @@ int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
+                       spin_lock_bh(&orig_node->ogm_cnt_lock);
+                       ret = batadv_orig_node_add_if(orig_node, max_if_num);
+                       spin_unlock_bh(&orig_node->ogm_cnt_lock);
+@@ -595,7 +593,6 @@ int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
+ {
+       struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+       struct batadv_hashtable *hash = bat_priv->orig_hash;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       struct batadv_hard_iface *hard_iface_tmp;
+       struct batadv_orig_node *orig_node;
+@@ -609,7 +606,7 @@ int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
+                       spin_lock_bh(&orig_node->ogm_cnt_lock);
+                       ret = batadv_orig_node_del_if(orig_node, max_if_num,
+                                                     hard_iface->if_num);
+diff --git a/originator.h b/originator.h
+index 286bf74..7df48fa 100644
+--- a/originator.h
++++ b/originator.h
+@@ -68,7 +68,6 @@ batadv_orig_hash_find(struct batadv_priv *bat_priv, const void *data)
+ {
+       struct batadv_hashtable *hash = bat_priv->orig_hash;
+       struct hlist_head *head;
+-      struct hlist_node *node;
+       struct batadv_orig_node *orig_node, *orig_node_tmp = NULL;
+       int index;
+@@ -79,7 +78,7 @@ batadv_orig_hash_find(struct batadv_priv *bat_priv, const void *data)
+       head = &hash->table[index];
+       rcu_read_lock();
+-      hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
++      hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
+               if (!batadv_compare_eth(orig_node, data))
+                       continue;
+diff --git a/routing.c b/routing.c
+index 60ba03f..5ee21ce 100644
+--- a/routing.c
++++ b/routing.c
+@@ -37,7 +37,6 @@ void batadv_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
+ {
+       struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+       struct batadv_hashtable *hash = bat_priv->orig_hash;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       struct batadv_orig_node *orig_node;
+       unsigned long *word;
+@@ -49,7 +48,7 @@ void batadv_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
+                       spin_lock_bh(&orig_node->ogm_cnt_lock);
+                       word_index = hard_iface->if_num * BATADV_NUM_WORDS;
+                       word = &(orig_node->bcast_own[word_index]);
+@@ -146,7 +145,6 @@ out:
+ void batadv_bonding_candidate_add(struct batadv_orig_node *orig_node,
+                                 struct batadv_neigh_node *neigh_node)
+ {
+-      struct hlist_node *node;
+       struct batadv_neigh_node *tmp_neigh_node, *router = NULL;
+       uint8_t interference_candidate = 0;
+@@ -169,7 +167,7 @@ void batadv_bonding_candidate_add(struct batadv_orig_node *orig_node,
+        * interface. If we do, we won't select this candidate because of
+        * possible interference.
+        */
+-      hlist_for_each_entry_rcu(tmp_neigh_node, node,
++      hlist_for_each_entry_rcu(tmp_neigh_node,
+                                &orig_node->neigh_list, list) {
+               if (tmp_neigh_node == neigh_node)
+                       continue;
+diff --git a/send.c b/send.c
+index 80ca65f..a67cffd 100644
+--- a/send.c
++++ b/send.c
+@@ -316,7 +316,7 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
+                                const struct batadv_hard_iface *hard_iface)
+ {
+       struct batadv_forw_packet *forw_packet;
+-      struct hlist_node *tmp_node, *safe_tmp_node;
++      struct hlist_node *safe_tmp_node;
+       bool pending;
+       if (hard_iface)
+@@ -329,7 +329,7 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
+       /* free bcast list */
+       spin_lock_bh(&bat_priv->forw_bcast_list_lock);
+-      hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
++      hlist_for_each_entry_safe(forw_packet, safe_tmp_node,
+                                 &bat_priv->forw_bcast_list, list) {
+               /* if purge_outstanding_packets() was called with an argument
+                * we delete only packets belonging to the given interface
+@@ -355,7 +355,7 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
+       /* free batman packet list */
+       spin_lock_bh(&bat_priv->forw_bat_list_lock);
+-      hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
++      hlist_for_each_entry_safe(forw_packet, safe_tmp_node,
+                                 &bat_priv->forw_bat_list, list) {
+               /* if purge_outstanding_packets() was called with an argument
+                * we delete only packets belonging to the given interface
+diff --git a/translation-table.c b/translation-table.c
+index d44672f..98a66a0 100644
+--- a/translation-table.c
++++ b/translation-table.c
+@@ -56,7 +56,6 @@ static struct batadv_tt_common_entry *
+ batadv_tt_hash_find(struct batadv_hashtable *hash, const void *data)
+ {
+       struct hlist_head *head;
+-      struct hlist_node *node;
+       struct batadv_tt_common_entry *tt_common_entry;
+       struct batadv_tt_common_entry *tt_common_entry_tmp = NULL;
+       uint32_t index;
+@@ -68,7 +67,7 @@ batadv_tt_hash_find(struct batadv_hashtable *hash, const void *data)
+       head = &hash->table[index];
+       rcu_read_lock();
+-      hlist_for_each_entry_rcu(tt_common_entry, node, head, hash_entry) {
++      hlist_for_each_entry_rcu(tt_common_entry, head, hash_entry) {
+               if (!batadv_compare_eth(tt_common_entry, data))
+                       continue;
+@@ -257,7 +256,6 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
+       struct batadv_tt_local_entry *tt_local;
+       struct batadv_tt_global_entry *tt_global;
+       struct hlist_head *head;
+-      struct hlist_node *node;
+       struct batadv_tt_orig_list_entry *orig_entry;
+       int hash_added;
+       bool roamed_back = false;
+@@ -339,7 +337,7 @@ check_roaming:
+               /* These node are probably going to update their tt table */
+               head = &tt_global->orig_list;
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(orig_entry, node, head, list) {
++              hlist_for_each_entry_rcu(orig_entry, head, list) {
+                       batadv_send_roam_adv(bat_priv, tt_global->common.addr,
+                                            orig_entry->orig_node);
+               }
+@@ -470,7 +468,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
+       struct batadv_tt_common_entry *tt_common_entry;
+       struct batadv_tt_local_entry *tt_local;
+       struct batadv_hard_iface *primary_if;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       uint32_t i;
+       int last_seen_secs;
+@@ -494,7 +491,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(tt_common_entry, node,
++              hlist_for_each_entry_rcu(tt_common_entry,
+                                        head, hash_entry) {
+                       tt_local = container_of(tt_common_entry,
+                                               struct batadv_tt_local_entry,
+@@ -605,9 +602,9 @@ static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
+ {
+       struct batadv_tt_local_entry *tt_local_entry;
+       struct batadv_tt_common_entry *tt_common_entry;
+-      struct hlist_node *node, *node_tmp;
++      struct hlist_node *node_tmp;
+-      hlist_for_each_entry_safe(tt_common_entry, node, node_tmp, head,
++      hlist_for_each_entry_safe(tt_common_entry, node_tmp, head,
+                                 hash_entry) {
+               tt_local_entry = container_of(tt_common_entry,
+                                             struct batadv_tt_local_entry,
+@@ -651,7 +648,7 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
+       spinlock_t *list_lock; /* protects write access to the hash lists */
+       struct batadv_tt_common_entry *tt_common_entry;
+       struct batadv_tt_local_entry *tt_local;
+-      struct hlist_node *node, *node_tmp;
++      struct hlist_node *node_tmp;
+       struct hlist_head *head;
+       uint32_t i;
+@@ -665,9 +662,9 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
+               list_lock = &hash->list_locks[i];
+               spin_lock_bh(list_lock);
+-              hlist_for_each_entry_safe(tt_common_entry, node, node_tmp,
++              hlist_for_each_entry_safe(tt_common_entry, node_tmp,
+                                         head, hash_entry) {
+-                      hlist_del_rcu(node);
++                      hlist_del_rcu(&tt_common_entry->hash_entry);
+                       tt_local = container_of(tt_common_entry,
+                                               struct batadv_tt_local_entry,
+                                               common);
+@@ -724,11 +721,10 @@ batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
+ {
+       struct batadv_tt_orig_list_entry *tmp_orig_entry, *orig_entry = NULL;
+       const struct hlist_head *head;
+-      struct hlist_node *node;
+       rcu_read_lock();
+       head = &entry->orig_list;
+-      hlist_for_each_entry_rcu(tmp_orig_entry, node, head, list) {
++      hlist_for_each_entry_rcu(tmp_orig_entry, head, list) {
+               if (tmp_orig_entry->orig_node != orig_node)
+                       continue;
+               if (!atomic_inc_not_zero(&tmp_orig_entry->refcount))
+@@ -940,12 +936,11 @@ batadv_transtable_best_orig(struct batadv_tt_global_entry *tt_global_entry)
+ {
+       struct batadv_neigh_node *router = NULL;
+       struct hlist_head *head;
+-      struct hlist_node *node;
+       struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL;
+       int best_tq = 0;
+       head = &tt_global_entry->orig_list;
+-      hlist_for_each_entry_rcu(orig_entry, node, head, list) {
++      hlist_for_each_entry_rcu(orig_entry, head, list) {
+               router = batadv_orig_node_get_router(orig_entry->orig_node);
+               if (!router)
+                       continue;
+@@ -973,7 +968,6 @@ batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
+                            struct seq_file *seq)
+ {
+       struct hlist_head *head;
+-      struct hlist_node *node;
+       struct batadv_tt_orig_list_entry *orig_entry, *best_entry;
+       struct batadv_tt_common_entry *tt_common_entry;
+       uint16_t flags;
+@@ -997,7 +991,7 @@ batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
+       head = &tt_global_entry->orig_list;
+-      hlist_for_each_entry_rcu(orig_entry, node, head, list) {
++      hlist_for_each_entry_rcu(orig_entry, head, list) {
+               if (best_entry == orig_entry)
+                       continue;
+@@ -1020,7 +1014,6 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
+       struct batadv_tt_common_entry *tt_common_entry;
+       struct batadv_tt_global_entry *tt_global;
+       struct batadv_hard_iface *primary_if;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       uint32_t i;
+@@ -1039,7 +1032,7 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(tt_common_entry, node,
++              hlist_for_each_entry_rcu(tt_common_entry,
+                                        head, hash_entry) {
+                       tt_global = container_of(tt_common_entry,
+                                                struct batadv_tt_global_entry,
+@@ -1059,13 +1052,13 @@ static void
+ batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry)
+ {
+       struct hlist_head *head;
+-      struct hlist_node *node, *safe;
++      struct hlist_node *safe;
+       struct batadv_tt_orig_list_entry *orig_entry;
+       spin_lock_bh(&tt_global_entry->list_lock);
+       head = &tt_global_entry->orig_list;
+-      hlist_for_each_entry_safe(orig_entry, node, safe, head, list) {
+-              hlist_del_rcu(node);
++      hlist_for_each_entry_safe(orig_entry, safe, head, list) {
++              hlist_del_rcu(&orig_entry->list);
+               batadv_tt_orig_list_entry_free_ref(orig_entry);
+       }
+       spin_unlock_bh(&tt_global_entry->list_lock);
+@@ -1078,18 +1071,18 @@ batadv_tt_global_del_orig_entry(struct batadv_priv *bat_priv,
+                               const char *message)
+ {
+       struct hlist_head *head;
+-      struct hlist_node *node, *safe;
++      struct hlist_node *safe;
+       struct batadv_tt_orig_list_entry *orig_entry;
+       spin_lock_bh(&tt_global_entry->list_lock);
+       head = &tt_global_entry->orig_list;
+-      hlist_for_each_entry_safe(orig_entry, node, safe, head, list) {
++      hlist_for_each_entry_safe(orig_entry, safe, head, list) {
+               if (orig_entry->orig_node == orig_node) {
+                       batadv_dbg(BATADV_DBG_TT, bat_priv,
+                                  "Deleting %pM from global tt entry %pM: %s\n",
+                                  orig_node->orig,
+                                  tt_global_entry->common.addr, message);
+-                      hlist_del_rcu(node);
++                      hlist_del_rcu(&orig_entry->list);
+                       batadv_tt_orig_list_entry_free_ref(orig_entry);
+               }
+       }
+@@ -1108,7 +1101,6 @@ batadv_tt_global_del_roaming(struct batadv_priv *bat_priv,
+ {
+       bool last_entry = true;
+       struct hlist_head *head;
+-      struct hlist_node *node;
+       struct batadv_tt_orig_list_entry *orig_entry;
+       /* no local entry exists, case 1:
+@@ -1117,7 +1109,7 @@ batadv_tt_global_del_roaming(struct batadv_priv *bat_priv,
+       rcu_read_lock();
+       head = &tt_global_entry->orig_list;
+-      hlist_for_each_entry_rcu(orig_entry, node, head, list) {
++      hlist_for_each_entry_rcu(orig_entry, head, list) {
+               if (orig_entry->orig_node != orig_node) {
+                       last_entry = false;
+                       break;
+@@ -1202,7 +1194,7 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
+       struct batadv_tt_common_entry *tt_common_entry;
+       uint32_t i;
+       struct batadv_hashtable *hash = bat_priv->tt.global_hash;
+-      struct hlist_node *node, *safe;
++      struct hlist_node *safe;
+       struct hlist_head *head;
+       spinlock_t *list_lock; /* protects write access to the hash lists */
+@@ -1214,7 +1206,7 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
+               list_lock = &hash->list_locks[i];
+               spin_lock_bh(list_lock);
+-              hlist_for_each_entry_safe(tt_common_entry, node, safe,
++              hlist_for_each_entry_safe(tt_common_entry, safe,
+                                         head, hash_entry) {
+                       tt_global = container_of(tt_common_entry,
+                                                struct batadv_tt_global_entry,
+@@ -1227,7 +1219,7 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
+                               batadv_dbg(BATADV_DBG_TT, bat_priv,
+                                          "Deleting global tt entry %pM: %s\n",
+                                          tt_global->common.addr, message);
+-                              hlist_del_rcu(node);
++                              hlist_del_rcu(&tt_common_entry->hash_entry);
+                               batadv_tt_global_entry_free_ref(tt_global);
+                       }
+               }
+@@ -1262,7 +1254,7 @@ static void batadv_tt_global_purge(struct batadv_priv *bat_priv)
+ {
+       struct batadv_hashtable *hash = bat_priv->tt.global_hash;
+       struct hlist_head *head;
+-      struct hlist_node *node, *node_tmp;
++      struct hlist_node *node_tmp;
+       spinlock_t *list_lock; /* protects write access to the hash lists */
+       uint32_t i;
+       char *msg = NULL;
+@@ -1274,7 +1266,7 @@ static void batadv_tt_global_purge(struct batadv_priv *bat_priv)
+               list_lock = &hash->list_locks[i];
+               spin_lock_bh(list_lock);
+-              hlist_for_each_entry_safe(tt_common, node, node_tmp, head,
++              hlist_for_each_entry_safe(tt_common, node_tmp, head,
+                                         hash_entry) {
+                       tt_global = container_of(tt_common,
+                                                struct batadv_tt_global_entry,
+@@ -1287,7 +1279,7 @@ static void batadv_tt_global_purge(struct batadv_priv *bat_priv)
+                                  "Deleting global tt entry (%pM): %s\n",
+                                  tt_global->common.addr, msg);
+-                      hlist_del_rcu(node);
++                      hlist_del_rcu(&tt_common->hash_entry);
+                       batadv_tt_global_entry_free_ref(tt_global);
+               }
+@@ -1301,7 +1293,7 @@ static void batadv_tt_global_table_free(struct batadv_priv *bat_priv)
+       spinlock_t *list_lock; /* protects write access to the hash lists */
+       struct batadv_tt_common_entry *tt_common_entry;
+       struct batadv_tt_global_entry *tt_global;
+-      struct hlist_node *node, *node_tmp;
++      struct hlist_node *node_tmp;
+       struct hlist_head *head;
+       uint32_t i;
+@@ -1315,9 +1307,9 @@ static void batadv_tt_global_table_free(struct batadv_priv *bat_priv)
+               list_lock = &hash->list_locks[i];
+               spin_lock_bh(list_lock);
+-              hlist_for_each_entry_safe(tt_common_entry, node, node_tmp,
++              hlist_for_each_entry_safe(tt_common_entry, node_tmp,
+                                         head, hash_entry) {
+-                      hlist_del_rcu(node);
++                      hlist_del_rcu(&tt_common_entry->hash_entry);
+                       tt_global = container_of(tt_common_entry,
+                                                struct batadv_tt_global_entry,
+                                                common);
+@@ -1397,7 +1389,6 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
+       struct batadv_hashtable *hash = bat_priv->tt.global_hash;
+       struct batadv_tt_common_entry *tt_common;
+       struct batadv_tt_global_entry *tt_global;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       uint32_t i;
+       int j;
+@@ -1406,7 +1397,7 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(tt_common, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(tt_common, head, hash_entry) {
+                       tt_global = container_of(tt_common,
+                                                struct batadv_tt_global_entry,
+                                                common);
+@@ -1449,7 +1440,6 @@ static uint16_t batadv_tt_local_crc(struct batadv_priv *bat_priv)
+       uint16_t total = 0, total_one;
+       struct batadv_hashtable *hash = bat_priv->tt.local_hash;
+       struct batadv_tt_common_entry *tt_common;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       uint32_t i;
+       int j;
+@@ -1458,7 +1448,7 @@ static uint16_t batadv_tt_local_crc(struct batadv_priv *bat_priv)
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(tt_common, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(tt_common, head, hash_entry) {
+                       /* not yet committed clients have not to be taken into
+                        * account while computing the CRC
+                        */
+@@ -1597,7 +1587,6 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
+       struct batadv_tt_common_entry *tt_common_entry;
+       struct batadv_tt_query_packet *tt_response;
+       struct batadv_tt_change *tt_change;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       struct sk_buff *skb = NULL;
+       uint16_t tt_tot, tt_count;
+@@ -1627,7 +1616,7 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
+       for (i = 0; i < hash->size; i++) {
+               head = &hash->table[i];
+-              hlist_for_each_entry_rcu(tt_common_entry, node,
++              hlist_for_each_entry_rcu(tt_common_entry,
+                                        head, hash_entry) {
+                       if (tt_count == tt_tot)
+                               break;
+@@ -2307,7 +2296,6 @@ static uint16_t batadv_tt_set_flags(struct batadv_hashtable *hash,
+       uint32_t i;
+       uint16_t changed_num = 0;
+       struct hlist_head *head;
+-      struct hlist_node *node;
+       struct batadv_tt_common_entry *tt_common_entry;
+       if (!hash)
+@@ -2317,7 +2305,7 @@ static uint16_t batadv_tt_set_flags(struct batadv_hashtable *hash,
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(tt_common_entry, node,
++              hlist_for_each_entry_rcu(tt_common_entry,
+                                        head, hash_entry) {
+                       if (enable) {
+                               if ((tt_common_entry->flags & flags) == flags)
+@@ -2342,7 +2330,7 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
+       struct batadv_hashtable *hash = bat_priv->tt.local_hash;
+       struct batadv_tt_common_entry *tt_common;
+       struct batadv_tt_local_entry *tt_local;
+-      struct hlist_node *node, *node_tmp;
++      struct hlist_node *node_tmp;
+       struct hlist_head *head;
+       spinlock_t *list_lock; /* protects write access to the hash lists */
+       uint32_t i;
+@@ -2355,7 +2343,7 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
+               list_lock = &hash->list_locks[i];
+               spin_lock_bh(list_lock);
+-              hlist_for_each_entry_safe(tt_common, node, node_tmp, head,
++              hlist_for_each_entry_safe(tt_common, node_tmp, head,
+                                         hash_entry) {
+                       if (!(tt_common->flags & BATADV_TT_CLIENT_PENDING))
+                               continue;
+@@ -2365,7 +2353,7 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
+                                  tt_common->addr);
+                       atomic_dec(&bat_priv->tt.local_entry_num);
+-                      hlist_del_rcu(node);
++                      hlist_del_rcu(&tt_common->hash_entry);
+                       tt_local = container_of(tt_common,
+                                               struct batadv_tt_local_entry,
+                                               common);
+diff --git a/vis.c b/vis.c
+index 22d2785..c053244 100644
+--- a/vis.c
++++ b/vis.c
+@@ -97,7 +97,6 @@ batadv_vis_hash_find(struct batadv_priv *bat_priv, const void *data)
+ {
+       struct batadv_hashtable *hash = bat_priv->vis.hash;
+       struct hlist_head *head;
+-      struct hlist_node *node;
+       struct batadv_vis_info *vis_info, *vis_info_tmp = NULL;
+       uint32_t index;
+@@ -108,8 +107,8 @@ batadv_vis_hash_find(struct batadv_priv *bat_priv, const void *data)
+       head = &hash->table[index];
+       rcu_read_lock();
+-      hlist_for_each_entry_rcu(vis_info, node, head, hash_entry) {
+-              if (!batadv_vis_info_cmp(node, data))
++      hlist_for_each_entry_rcu(vis_info, head, hash_entry) {
++              if (!batadv_vis_info_cmp(&vis_info->hash_entry, data))
+                       continue;
+               vis_info_tmp = vis_info;
+@@ -128,9 +127,8 @@ static void batadv_vis_data_insert_interface(const uint8_t *interface,
+                                            bool primary)
+ {
+       struct batadv_vis_if_list_entry *entry;
+-      struct hlist_node *pos;
+-      hlist_for_each_entry(entry, pos, if_list, list) {
++      hlist_for_each_entry(entry, if_list, list) {
+               if (batadv_compare_eth(entry->addr, interface))
+                       return;
+       }
+@@ -148,9 +146,8 @@ static void batadv_vis_data_read_prim_sec(struct seq_file *seq,
+                                         const struct hlist_head *if_list)
+ {
+       struct batadv_vis_if_list_entry *entry;
+-      struct hlist_node *pos;
+-      hlist_for_each_entry(entry, pos, if_list, list) {
++      hlist_for_each_entry(entry, if_list, list) {
+               if (entry->primary)
+                       seq_printf(seq, "PRIMARY, ");
+               else
+@@ -198,9 +195,8 @@ static void batadv_vis_data_read_entries(struct seq_file *seq,
+ {
+       int i;
+       struct batadv_vis_if_list_entry *entry;
+-      struct hlist_node *pos;
+-      hlist_for_each_entry(entry, pos, list, list) {
++      hlist_for_each_entry(entry, list, list) {
+               seq_printf(seq, "%pM,", entry->addr);
+               for (i = 0; i < packet->entries; i++)
+@@ -218,17 +214,16 @@ static void batadv_vis_data_read_entries(struct seq_file *seq,
+ static void batadv_vis_seq_print_text_bucket(struct seq_file *seq,
+                                            const struct hlist_head *head)
+ {
+-      struct hlist_node *node;
+       struct batadv_vis_info *info;
+       struct batadv_vis_packet *packet;
+       uint8_t *entries_pos;
+       struct batadv_vis_info_entry *entries;
+       struct batadv_vis_if_list_entry *entry;
+-      struct hlist_node *pos, *n;
++      struct hlist_node *n;
+       HLIST_HEAD(vis_if_list);
+-      hlist_for_each_entry_rcu(info, node, head, hash_entry) {
++      hlist_for_each_entry_rcu(info, head, hash_entry) {
+               packet = (struct batadv_vis_packet *)info->skb_packet->data;
+               entries_pos = (uint8_t *)packet + sizeof(*packet);
+               entries = (struct batadv_vis_info_entry *)entries_pos;
+@@ -240,7 +235,7 @@ static void batadv_vis_seq_print_text_bucket(struct seq_file *seq,
+               batadv_vis_data_read_entries(seq, &vis_if_list, packet,
+                                            entries);
+-              hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
++              hlist_for_each_entry_safe(entry, n, &vis_if_list, list) {
+                       hlist_del(&entry->list);
+                       kfree(entry);
+               }
+@@ -519,7 +514,6 @@ static int batadv_find_best_vis_server(struct batadv_priv *bat_priv,
+ {
+       struct batadv_hashtable *hash = bat_priv->orig_hash;
+       struct batadv_neigh_node *router;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       struct batadv_orig_node *orig_node;
+       struct batadv_vis_packet *packet;
+@@ -532,7 +526,7 @@ static int batadv_find_best_vis_server(struct batadv_priv *bat_priv,
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
+                       router = batadv_orig_node_get_router(orig_node);
+                       if (!router)
+                               continue;
+@@ -571,7 +565,6 @@ static bool batadv_vis_packet_full(const struct batadv_vis_info *info)
+ static int batadv_generate_vis_packet(struct batadv_priv *bat_priv)
+ {
+       struct batadv_hashtable *hash = bat_priv->orig_hash;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       struct batadv_orig_node *orig_node;
+       struct batadv_neigh_node *router;
+@@ -605,7 +598,7 @@ static int batadv_generate_vis_packet(struct batadv_priv *bat_priv)
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
+                       router = batadv_orig_node_get_router(orig_node);
+                       if (!router)
+                               continue;
+@@ -644,7 +637,7 @@ next:
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(tt_common_entry, node, head,
++              hlist_for_each_entry_rcu(tt_common_entry, head,
+                                        hash_entry) {
+                       packet_pos = skb_put(info->skb_packet, sizeof(*entry));
+                       entry = (struct batadv_vis_info_entry *)packet_pos;
+@@ -673,14 +666,14 @@ static void batadv_purge_vis_packets(struct batadv_priv *bat_priv)
+ {
+       uint32_t i;
+       struct batadv_hashtable *hash = bat_priv->vis.hash;
+-      struct hlist_node *node, *node_tmp;
++      struct hlist_node *node_tmp;
+       struct hlist_head *head;
+       struct batadv_vis_info *info;
+       for (i = 0; i < hash->size; i++) {
+               head = &hash->table[i];
+-              hlist_for_each_entry_safe(info, node, node_tmp,
++              hlist_for_each_entry_safe(info, node_tmp,
+                                         head, hash_entry) {
+                       /* never purge own data. */
+                       if (info == bat_priv->vis.my_info)
+@@ -688,7 +681,7 @@ static void batadv_purge_vis_packets(struct batadv_priv *bat_priv)
+                       if (batadv_has_timed_out(info->first_seen,
+                                                BATADV_VIS_TIMEOUT)) {
+-                              hlist_del(node);
++                              hlist_del(&info->hash_entry);
+                               batadv_send_list_del(info);
+                               kref_put(&info->refcount, batadv_free_info);
+                       }
+@@ -700,7 +693,6 @@ static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
+                                       struct batadv_vis_info *info)
+ {
+       struct batadv_hashtable *hash = bat_priv->orig_hash;
+-      struct hlist_node *node;
+       struct hlist_head *head;
+       struct batadv_orig_node *orig_node;
+       struct batadv_vis_packet *packet;
+@@ -715,7 +707,7 @@ static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
+               head = &hash->table[i];
+               rcu_read_lock();
+-              hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
++              hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
+                       /* if it's a vis server and reachable, send it. */
+                       if (!(orig_node->flags & BATADV_VIS_SERVER))
+                               continue;
+-- 
+1.7.10.4
+
diff --git a/batman-adv/patches/0003-batman-adv-make-is_my_mac-check-for-the-current-mesh.patch b/batman-adv/patches/0003-batman-adv-make-is_my_mac-check-for-the-current-mesh.patch
new file mode 100644 (file)
index 0000000..a8dc69a
--- /dev/null
@@ -0,0 +1,250 @@
+From 647d23f3e358d9fa4b1a8f0bb67a3e6bff30d4a1 Mon Sep 17 00:00:00 2001
+From: Antonio Quartulli <ordex@autistici.org>
+Date: Wed, 3 Apr 2013 19:10:26 +0200
+Subject: [PATCH 3/3] batman-adv: make is_my_mac() check for the current mesh
+ only
+
+On a multi-mesh node (a node running more than one batman-adv
+virtual interface) batadv_is_my_mac() has to check MAC
+addresses of hard interfaces belonging to the current mesh
+only.
+
+Signed-off-by: Antonio Quartulli <ordex@autistici.org>
+Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
+---
+ main.c              |    5 ++++-
+ main.h              |    2 +-
+ routing.c           |   38 ++++++++++++++++++++------------------
+ translation-table.c |    2 +-
+ vis.c               |    4 ++--
+ 5 files changed, 28 insertions(+), 23 deletions(-)
+
+diff --git a/main.c b/main.c
+index 0488d70..fa563e4 100644
+--- a/main.c
++++ b/main.c
+@@ -169,7 +169,7 @@ void batadv_mesh_free(struct net_device *soft_iface)
+       atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
+ }
+-int batadv_is_my_mac(const uint8_t *addr)
++int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr)
+ {
+       const struct batadv_hard_iface *hard_iface;
+@@ -178,6 +178,9 @@ int batadv_is_my_mac(const uint8_t *addr)
+               if (hard_iface->if_status != BATADV_IF_ACTIVE)
+                       continue;
++              if (hard_iface->soft_iface != bat_priv->soft_iface)
++                      continue;
++
+               if (batadv_compare_eth(hard_iface->net_dev->dev_addr, addr)) {
+                       rcu_read_unlock();
+                       return 1;
+diff --git a/main.h b/main.h
+index 08c5dd1..fcb5d65 100644
+--- a/main.h
++++ b/main.h
+@@ -164,7 +164,7 @@ extern struct workqueue_struct *batadv_event_workqueue;
+ int batadv_mesh_init(struct net_device *soft_iface);
+ void batadv_mesh_free(struct net_device *soft_iface);
+-int batadv_is_my_mac(const uint8_t *addr);
++int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr);
+ struct batadv_hard_iface *
+ batadv_seq_print_text_primary_if_get(struct seq_file *seq);
+ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
+diff --git a/routing.c b/routing.c
+index 5ee21ce..319f290 100644
+--- a/routing.c
++++ b/routing.c
+@@ -402,7 +402,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
+               goto out;
+       /* not for me */
+-      if (!batadv_is_my_mac(ethhdr->h_dest))
++      if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest))
+               goto out;
+       icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
+@@ -416,7 +416,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
+       }
+       /* packet for me */
+-      if (batadv_is_my_mac(icmp_packet->dst))
++      if (batadv_is_my_mac(bat_priv, icmp_packet->dst))
+               return batadv_recv_my_icmp_packet(bat_priv, skb, hdr_size);
+       /* TTL exceeded */
+@@ -548,7 +548,8 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig,
+       return router;
+ }
+-static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size)
++static int batadv_check_unicast_packet(struct batadv_priv *bat_priv,
++                                     struct sk_buff *skb, int hdr_size)
+ {
+       struct ethhdr *ethhdr;
+@@ -567,7 +568,7 @@ static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size)
+               return -1;
+       /* not for me */
+-      if (!batadv_is_my_mac(ethhdr->h_dest))
++      if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest))
+               return -1;
+       return 0;
+@@ -582,7 +583,7 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
+       char tt_flag;
+       size_t packet_size;
+-      if (batadv_check_unicast_packet(skb, hdr_size) < 0)
++      if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0)
+               return NET_RX_DROP;
+       /* I could need to modify it */
+@@ -614,7 +615,7 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
+       case BATADV_TT_RESPONSE:
+               batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_RX);
+-              if (batadv_is_my_mac(tt_query->dst)) {
++              if (batadv_is_my_mac(bat_priv, tt_query->dst)) {
+                       /* packet needs to be linearized to access the TT
+                        * changes
+                        */
+@@ -657,14 +658,15 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
+       struct batadv_roam_adv_packet *roam_adv_packet;
+       struct batadv_orig_node *orig_node;
+-      if (batadv_check_unicast_packet(skb, sizeof(*roam_adv_packet)) < 0)
++      if (batadv_check_unicast_packet(bat_priv, skb,
++                                      sizeof(*roam_adv_packet)) < 0)
+               goto out;
+       batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX);
+       roam_adv_packet = (struct batadv_roam_adv_packet *)skb->data;
+-      if (!batadv_is_my_mac(roam_adv_packet->dst))
++      if (!batadv_is_my_mac(bat_priv, roam_adv_packet->dst))
+               return batadv_route_unicast_packet(skb, recv_if);
+       /* check if it is a backbone gateway. we don't accept
+@@ -967,7 +969,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
+        * last time) the packet had an updated information or not
+        */
+       curr_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
+-      if (!batadv_is_my_mac(unicast_packet->dest)) {
++      if (!batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
+               orig_node = batadv_orig_hash_find(bat_priv,
+                                                 unicast_packet->dest);
+               /* if it is not possible to find the orig_node representing the
+@@ -1044,14 +1046,14 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
+       if (is4addr)
+               hdr_size = sizeof(*unicast_4addr_packet);
+-      if (batadv_check_unicast_packet(skb, hdr_size) < 0)
++      if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0)
+               return NET_RX_DROP;
+       if (!batadv_check_unicast_ttvn(bat_priv, skb))
+               return NET_RX_DROP;
+       /* packet for me */
+-      if (batadv_is_my_mac(unicast_packet->dest)) {
++      if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
+               if (is4addr) {
+                       batadv_dat_inc_counter(bat_priv,
+                                              unicast_4addr_packet->subtype);
+@@ -1088,7 +1090,7 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
+       struct sk_buff *new_skb = NULL;
+       int ret;
+-      if (batadv_check_unicast_packet(skb, hdr_size) < 0)
++      if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0)
+               return NET_RX_DROP;
+       if (!batadv_check_unicast_ttvn(bat_priv, skb))
+@@ -1097,7 +1099,7 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
+       unicast_packet = (struct batadv_unicast_frag_packet *)skb->data;
+       /* packet for me */
+-      if (batadv_is_my_mac(unicast_packet->dest)) {
++      if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
+               ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb);
+               if (ret == NET_RX_DROP)
+@@ -1151,13 +1153,13 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
+               goto out;
+       /* ignore broadcasts sent by myself */
+-      if (batadv_is_my_mac(ethhdr->h_source))
++      if (batadv_is_my_mac(bat_priv, ethhdr->h_source))
+               goto out;
+       bcast_packet = (struct batadv_bcast_packet *)skb->data;
+       /* ignore broadcasts originated by myself */
+-      if (batadv_is_my_mac(bcast_packet->orig))
++      if (batadv_is_my_mac(bat_priv, bcast_packet->orig))
+               goto out;
+       if (bcast_packet->header.ttl < 2)
+@@ -1243,14 +1245,14 @@ int batadv_recv_vis_packet(struct sk_buff *skb,
+       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       /* not for me */
+-      if (!batadv_is_my_mac(ethhdr->h_dest))
++      if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest))
+               return NET_RX_DROP;
+       /* ignore own packets */
+-      if (batadv_is_my_mac(vis_packet->vis_orig))
++      if (batadv_is_my_mac(bat_priv, vis_packet->vis_orig))
+               return NET_RX_DROP;
+-      if (batadv_is_my_mac(vis_packet->sender_orig))
++      if (batadv_is_my_mac(bat_priv, vis_packet->sender_orig))
+               return NET_RX_DROP;
+       switch (vis_packet->vis_type) {
+diff --git a/translation-table.c b/translation-table.c
+index 98a66a0..7abee19 100644
+--- a/translation-table.c
++++ b/translation-table.c
+@@ -1953,7 +1953,7 @@ out:
+ bool batadv_send_tt_response(struct batadv_priv *bat_priv,
+                            struct batadv_tt_query_packet *tt_request)
+ {
+-      if (batadv_is_my_mac(tt_request->dst)) {
++      if (batadv_is_my_mac(bat_priv, tt_request->dst)) {
+               /* don't answer backbone gws! */
+               if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_request->src))
+                       return true;
+diff --git a/vis.c b/vis.c
+index c053244..6a1e646 100644
+--- a/vis.c
++++ b/vis.c
+@@ -477,7 +477,7 @@ void batadv_receive_client_update_packet(struct batadv_priv *bat_priv,
+       /* Are we the target for this VIS packet? */
+       if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC   &&
+-          batadv_is_my_mac(vis_packet->target_orig))
++          batadv_is_my_mac(bat_priv, vis_packet->target_orig))
+               are_target = 1;
+       spin_lock_bh(&bat_priv->vis.hash_lock);
+@@ -496,7 +496,7 @@ void batadv_receive_client_update_packet(struct batadv_priv *bat_priv,
+               batadv_send_list_add(bat_priv, info);
+               /* ... we're not the recipient (and thus need to forward). */
+-      } else if (!batadv_is_my_mac(packet->target_orig)) {
++      } else if (!batadv_is_my_mac(bat_priv, packet->target_orig)) {
+               batadv_send_list_add(bat_priv, info);
+       }
+-- 
+1.7.10.4
+