PKG_NAME:=batman-adv
PKG_VERSION:=2016.1
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_MD5SUM:=8c8e449009b4d29512d26ee308960bb5
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
--- /dev/null
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sat, 7 May 2016 09:50:44 +0200
+Subject: [PATCH] batman-adv: Add missing include for batadv_v_neigh_is_sob
+
+batadv_v_neigh_is_sob started to use false which is defined in
+linux/stddef.h.
+
+Fixes: 036aa7b7181e ("batman-adv: Avoid nullptr derefence in batadv_v_neigh_is_sob")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/9685688ae7dd85804aec2f6ce760611551fe9635
+---
+ net/batman-adv/bat_v.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
+index 0caca2f..1f960c9 100644
+--- a/net/batman-adv/bat_v.c
++++ b/net/batman-adv/bat_v.c
+@@ -27,6 +27,7 @@
+ #include <linux/rculist.h>
+ #include <linux/rcupdate.h>
+ #include <linux/seq_file.h>
++#include <linux/stddef.h>
+ #include <linux/types.h>
+ #include <linux/workqueue.h>
+
--- /dev/null
+From: Florian Westphal <fw@strlen.de>
+Date: Tue, 10 May 2016 23:17:59 +0200
+Subject: [PATCH] batman-adv: fix skb deref after free
+
+batadv_send_skb_to_orig() calls dev_queue_xmit() so we can't use skb->len.
+
+Fixes: d28785996ad8 ("batman-adv: network coding - buffer unicast packets before forward")
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Reviewed-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/6863d3b59fd1f1bef3c4b86707a0b1c5d21e0a07
+---
+ net/batman-adv/routing.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
+index b781bf7..0c0c30e 100644
+--- a/net/batman-adv/routing.c
++++ b/net/batman-adv/routing.c
+@@ -601,6 +601,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
+ struct batadv_unicast_packet *unicast_packet;
+ struct ethhdr *ethhdr = eth_hdr(skb);
+ int res, hdr_len, ret = NET_RX_DROP;
++ unsigned int len;
+
+ unicast_packet = (struct batadv_unicast_packet *)skb->data;
+
+@@ -641,6 +642,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
+ if (hdr_len > 0)
+ batadv_skb_set_priority(skb, hdr_len);
+
++ len = skb->len;
+ res = batadv_send_skb_to_orig(skb, orig_node, recv_if);
+
+ /* translate transmit result into receive result */
+@@ -648,7 +650,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
+ /* skb was transmitted and consumed */
+ batadv_inc_counter(bat_priv, BATADV_CNT_FORWARD);
+ batadv_add_counter(bat_priv, BATADV_CNT_FORWARD_BYTES,
+- skb->len + ETH_HLEN);
++ len + ETH_HLEN);
+
+ ret = NET_RX_SUCCESS;
+ } else if (res == NET_XMIT_POLICED) {
--- /dev/null
+From: Simon Wunderlich <sw@simonwunderlich.de>
+Date: Thu, 12 May 2016 18:52:03 +0200
+Subject: [PATCH] batman-adv: replace WARN with rate limited output on non-existing VLAN
+
+If a VLAN tagged frame is received and the corresponding VLAN is not
+configured on the soft interface, it will splat a WARN on every packet
+received. This is a quite annoying behaviour for some scenarios, e.g. if
+bat0 is bridged with eth0, and there are arbitrary VLAN tagged frames
+from Ethernet coming in without having any VLAN configuration on bat0.
+
+The code should probably create vlan objects on the fly and
+transparently transport these VLAN-tagged Ethernet frames, but until
+this is done, at least the WARN splat should be replaced by a rate
+limited output.
+
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/04792115d24408a72bf8fccd5c4059478fc15eae
+---
+ net/batman-adv/translation-table.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
+index 9b4551a..48adb91 100644
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -650,8 +650,10 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr,
+
+ /* increase the refcounter of the related vlan */
+ vlan = batadv_softif_vlan_get(bat_priv, vid);
+- if (WARN(!vlan, "adding TT local entry %pM to non-existent VLAN %d",
+- addr, BATADV_PRINT_VID(vid))) {
++ if (!vlan) {
++ net_ratelimited_function(batadv_info, soft_iface,
++ "adding TT local entry %pM to non-existent VLAN %d\n",
++ addr, BATADV_PRINT_VID(vid));
+ kfree(tt_local);
+ tt_local = NULL;
+ goto out;
--- /dev/null
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sat, 28 May 2016 10:32:48 +0200
+Subject: [PATCH] batman-adv: Fix build against recent Debian Stretch kernels
+
+The kernels for Debian stretch require some special CFLAGS settings which
+are only correctly defined when NOSTDINC_FLAGS is defined inside the
+execution of the Makefile via kbuild. But batman-adv sets it currently
+outside to insert compatibility include headers and compat-sources.
+
+This can be avoided by making the top Makefile kbuild compatible and
+redefining the NOSTDINC_FLAGS when kbuild include this Makefile. The actual
+build of the batman-adv module is then done by adding the subdirectory to
+obj-y.
+
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Tested-by: Martin Weinelt <martin@darmstadt.freifunk.net>
+
+Origin: https://git.open-mesh.org/batman-adv.git/commit/f8fd441e1e30f3a274c9bf44cc33372d4065cbb6
+---
+ Makefile | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 5d2c058..2568fb2 100644
+--- a/Makefile
++++ b/Makefile
+@@ -43,7 +43,7 @@ RM ?= rm -f
+ REVISION= $(shell if [ -d "$(PWD)/.git" ]; then \
+ echo $$(git --git-dir="$(PWD)/.git" describe --always --dirty --match "v*" |sed 's/^v//' 2> /dev/null || echo "[unknown]"); \
+ fi)
+-export NOSTDINC_FLAGS := \
++NOSTDINC_FLAGS += \
+ -I$(PWD)/compat-include/ \
+ -include $(PWD)/compat.h \
+ $(CFLAGS)
+@@ -52,8 +52,12 @@ ifneq ($(REVISION),)
+ NOSTDINC_FLAGS += -DBATADV_SOURCE_VERSION=\"$(REVISION)\"
+ endif
+
++obj-y += net/batman-adv/
++
+ BUILD_FLAGS := \
+- M=$(PWD)/net/batman-adv \
++ M=$(PWD) \
++ PWD=$(PWD) \
++ REVISION=$(REVISION) \
+ CONFIG_BATMAN_ADV=m \
+ CONFIG_BATMAN_ADV_DEBUG=$(CONFIG_BATMAN_ADV_DEBUG) \
+ CONFIG_BATMAN_ADV_BLA=$(CONFIG_BATMAN_ADV_BLA) \
+@@ -61,7 +65,7 @@ BUILD_FLAGS := \
+ CONFIG_BATMAN_ADV_NC=$(CONFIG_BATMAN_ADV_NC) \
+ CONFIG_BATMAN_ADV_MCAST=$(CONFIG_BATMAN_ADV_MCAST) \
+ CONFIG_BATMAN_ADV_BATMAN_V=$(CONFIG_BATMAN_ADV_BATMAN_V) \
+- INSTALL_MOD_DIR=updates/net/batman-adv/
++ INSTALL_MOD_DIR=updates/
+
+ all: config
+ $(MAKE) -C $(KERNELPATH) $(BUILD_FLAGS) modules
--- /dev/null
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sat, 28 May 2016 14:38:26 +0200
+Subject: [PATCH] batman-adv: Clean up untagged vlan when destroying via rtnl-link
+
+The untagged vlan object is only destroyed when the interface is removed
+via the legacy sysfs interface. But it also has to be destroyed when the
+standard rtnl-link interface is used.
+
+Fixes: 952cebb57518 ("batman-adv: add per VLAN interface attribute framework")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Cc: Antonio Quartulli <a@unstable.cc>
+
+Origin: https://git.open-mesh.org/batman-adv.git/commit/e721749d57ff57d6df4017d62797626eab9902f1
+---
+ net/batman-adv/soft-interface.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
+index 8a136b6..3710620 100644
+--- a/net/batman-adv/soft-interface.c
++++ b/net/batman-adv/soft-interface.c
+@@ -1017,7 +1017,9 @@ void batadv_softif_destroy_sysfs(struct net_device *soft_iface)
+ static void batadv_softif_destroy_netlink(struct net_device *soft_iface,
+ struct list_head *head)
+ {
++ struct batadv_priv *bat_priv = netdev_priv(soft_iface);
+ struct batadv_hard_iface *hard_iface;
++ struct batadv_softif_vlan *vlan;
+
+ list_for_each_entry(hard_iface, &batadv_hardif_list, list) {
+ if (hard_iface->soft_iface == soft_iface)
+@@ -1025,6 +1027,13 @@ static void batadv_softif_destroy_netlink(struct net_device *soft_iface,
+ BATADV_IF_CLEANUP_KEEP);
+ }
+
++ /* destroy the "untagged" VLAN */
++ vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS);
++ if (vlan) {
++ batadv_softif_destroy_vlan(bat_priv, vlan);
++ batadv_softif_vlan_put(vlan);
++ }
++
+ batadv_sysfs_del_meshif(soft_iface);
+ unregister_netdevice_queue(soft_iface, head);
+ }
--- /dev/null
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sun, 29 May 2016 21:25:52 +0200
+Subject: [PATCH] batman-adv: Fix ICMP RR ethernet access after skb_linearize
+
+The skb_linearize may reallocate the skb. This makes the calculated pointer
+for ethhdr invalid. But it the pointer is used later to fill in the RR
+field of the batadv_icmp_packet_rr packet.
+
+Instead re-evaluate eth_hdr after the skb_linearize+skb_cow to fix the
+pointer and avoid the invalid read.
+
+Fixes: bb69cb678d37 ("batman-adv: generalize batman-adv icmp packet handling")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/f6c80c29ef4e8b45b715976107b7ae06fc0be3a0
+---
+ net/batman-adv/routing.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
+index 0c0c30e..27e07dd 100644
+--- a/net/batman-adv/routing.c
++++ b/net/batman-adv/routing.c
+@@ -374,6 +374,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
+ if (skb_cow(skb, ETH_HLEN) < 0)
+ goto out;
+
++ ethhdr = eth_hdr(skb);
+ icmph = (struct batadv_icmp_header *)skb->data;
+ icmp_packet_rr = (struct batadv_icmp_packet_rr *)icmph;
+ if (icmp_packet_rr->rr_cur >= BATADV_RR_LEN)
--- /dev/null
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 3 Jun 2016 00:00:44 +0100
+Subject: [PATCH] batman-adv: Fix double-put of vlan object
+
+Commit a33d970d0b54 "batman-adv: Fix reference counting of vlan object
+for tt_local_entry") makes each batadv_tt_local_entry hold a single
+reference to a batadv_softif_vlan. In case a new entry cannot be
+added to the hash table, the error path puts the reference, but the
+reference will also now be dropped by batadv_tt_local_entry_release().
+
+Fixes: a33d970d0b54 ("batman-adv: Fix reference counting of vlan object ...")
+Cc: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Acked-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/22bb8b894900064d3fb09032a47577e89fc30d7c
+---
+ net/batman-adv/translation-table.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
+index 48adb91..5ed782b 100644
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -693,7 +693,6 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr,
+ if (unlikely(hash_added != 0)) {
+ /* remove the reference for the hash */
+ batadv_tt_local_entry_put(tt_local);
+- batadv_softif_vlan_put(vlan);
+ goto out;
+ }
+
--- /dev/null
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sat, 4 Jun 2016 08:52:12 +0200
+Subject: [PATCH] batman-adv: Fix use-after-free/double-free of tt_req_node
+
+The tt_req_node is added and removed from a list inside a spinlock. But the
+locking is sometimes removed even when the object is still referenced and
+will be used later via this reference. For example batadv_send_tt_request
+can create a new tt_req_node (including add to a list) and later
+re-acquires the lock to remove it from the list and to free it. But at this
+time another context could have already removed this tt_req_node from the
+list and freed it.
+
+CPU#0
+
+ batadv_batman_skb_recv from net_device 0
+ -> batadv_iv_ogm_receive
+ -> batadv_iv_ogm_process
+ -> batadv_iv_ogm_process_per_outif
+ -> batadv_tvlv_ogm_receive
+ -> batadv_tvlv_ogm_receive
+ -> batadv_tvlv_containers_process
+ -> batadv_tvlv_call_handler
+ -> batadv_tt_tvlv_ogm_handler_v1
+ -> batadv_tt_update_orig
+ -> batadv_send_tt_request
+ -> batadv_tt_req_node_new
+ spin_lock(...)
+ allocates new tt_req_node and adds it to list
+ spin_unlock(...)
+ return tt_req_node
+
+CPU#1
+
+ batadv_batman_skb_recv from net_device 1
+ -> batadv_recv_unicast_tvlv
+ -> batadv_tvlv_containers_process
+ -> batadv_tvlv_call_handler
+ -> batadv_tt_tvlv_unicast_handler_v1
+ -> batadv_handle_tt_response
+ spin_lock(...)
+ tt_req_node gets removed from list and is freed
+ spin_unlock(...)
+
+CPU#0
+
+ <- returned to batadv_send_tt_request
+ spin_lock(...)
+ tt_req_node gets removed from list and is freed
+ MEMORY CORRUPTION/SEGFAULT/...
+ spin_unlock(...)
+
+This can only be solved via reference counting to allow multiple contexts
+to handle the list manipulation while making sure that only the last
+context holding a reference will free the object.
+
+Fixes: cea194d90b11 ("batman-adv: improved client announcement mechanism")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Tested-by: Martin Weinelt <martin@darmstadt.freifunk.net>
+Tested-by: Amadeus Alfa <amadeus@chemnitz.freifunk.net>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/c3fef3d9ec6e8b882f321ec20f6f2cb2ee906503
+---
+ net/batman-adv/translation-table.c | 37 +++++++++++++++++++++++++++++++++----
+ net/batman-adv/types.h | 2 ++
+ 2 files changed, 35 insertions(+), 4 deletions(-)
+
+diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
+index 5ed782b..23fb7ea 100644
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -2271,6 +2271,29 @@ static u32 batadv_tt_local_crc(struct batadv_priv *bat_priv,
+ return crc;
+ }
+
++/**
++ * batadv_tt_req_node_release - free tt_req node entry
++ * @ref: kref pointer of the tt req_node entry
++ */
++static void batadv_tt_req_node_release(struct kref *ref)
++{
++ struct batadv_tt_req_node *tt_req_node;
++
++ tt_req_node = container_of(ref, struct batadv_tt_req_node, refcount);
++
++ kfree(tt_req_node);
++}
++
++/**
++ * batadv_tt_req_node_put - decrement the tt_req_node refcounter and
++ * possibly release it
++ * @tt_req_node: tt_req_node to be free'd
++ */
++static void batadv_tt_req_node_put(struct batadv_tt_req_node *tt_req_node)
++{
++ kref_put(&tt_req_node->refcount, batadv_tt_req_node_release);
++}
++
+ static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
+ {
+ struct batadv_tt_req_node *node;
+@@ -2280,7 +2303,7 @@ static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
+
+ hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
+ hlist_del_init(&node->list);
+- kfree(node);
++ batadv_tt_req_node_put(node);
+ }
+
+ spin_unlock_bh(&bat_priv->tt.req_list_lock);
+@@ -2317,7 +2340,7 @@ static void batadv_tt_req_purge(struct batadv_priv *bat_priv)
+ if (batadv_has_timed_out(node->issued_at,
+ BATADV_TT_REQUEST_TIMEOUT)) {
+ hlist_del_init(&node->list);
+- kfree(node);
++ batadv_tt_req_node_put(node);
+ }
+ }
+ spin_unlock_bh(&bat_priv->tt.req_list_lock);
+@@ -2349,9 +2372,11 @@ batadv_tt_req_node_new(struct batadv_priv *bat_priv,
+ if (!tt_req_node)
+ goto unlock;
+
++ kref_init(&tt_req_node->refcount);
+ ether_addr_copy(tt_req_node->addr, orig_node->orig);
+ tt_req_node->issued_at = jiffies;
+
++ kref_get(&tt_req_node->refcount);
+ hlist_add_head(&tt_req_node->list, &bat_priv->tt.req_list);
+ unlock:
+ spin_unlock_bh(&bat_priv->tt.req_list_lock);
+@@ -2618,9 +2643,13 @@ out:
+ spin_lock_bh(&bat_priv->tt.req_list_lock);
+ /* hlist_del_init() verifies tt_req_node still is in the list */
+ hlist_del_init(&tt_req_node->list);
++ batadv_tt_req_node_put(tt_req_node);
+ spin_unlock_bh(&bat_priv->tt.req_list_lock);
+- kfree(tt_req_node);
+ }
++
++ if (tt_req_node)
++ batadv_tt_req_node_put(tt_req_node);
++
+ kfree(tvlv_tt_data);
+ return ret;
+ }
+@@ -3056,7 +3085,7 @@ static void batadv_handle_tt_response(struct batadv_priv *bat_priv,
+ if (!batadv_compare_eth(node->addr, resp_src))
+ continue;
+ hlist_del_init(&node->list);
+- kfree(node);
++ batadv_tt_req_node_put(node);
+ }
+
+ spin_unlock_bh(&bat_priv->tt.req_list_lock);
+diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
+index 1e47fbe..d75beef 100644
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -1129,11 +1129,13 @@ struct batadv_tt_change_node {
+ * struct batadv_tt_req_node - data to keep track of the tt requests in flight
+ * @addr: mac address address of the originator this request was sent to
+ * @issued_at: timestamp used for purging stale tt requests
++ * @refcount: number of contexts the object is used by
+ * @list: list node for batadv_priv_tt::req_list
+ */
+ struct batadv_tt_req_node {
+ u8 addr[ETH_ALEN];
+ unsigned long issued_at;
++ struct kref refcount;
+ struct hlist_node list;
+ };
+