batman-adv: upgrade package to latest release 2013.3.0

Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
This commit is contained in:
Marek Lindner 2013-07-24 16:48:40 +08:00
parent a9a174bc33
commit adbb4cb247
11 changed files with 24 additions and 686 deletions

View File

@ -10,11 +10,11 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=batman-adv
PKG_VERSION:=2013.2.0
BATCTL_VERSION:=2013.2.0
PKG_VERSION:=2013.3.0
BATCTL_VERSION:=2013.3.0
PKG_RELEASE:=3
PKG_MD5SUM:=9ec18300b96df22f0ed21c9f51e4ccef
BATCTL_MD5SUM:=712f86cdd0f9076503fc48acf37e109e
PKG_MD5SUM:=d070c0879cd8fe8125315a4566fabd2d
BATCTL_MD5SUM:=747535b0296f0013a6f99373a51d41fc
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
@ -60,16 +60,29 @@ MAKE_BATMAN_ADV_ARGS += \
CONFIG_BATMAN_ADV_NC=$(if $(CONFIG_KMOD_BATMAN_ADV_NC),y,n) \
REVISION="" all
MAKE_BATCTL_ARGS += \
# The linker can identify unused sections of a binary when each symbol is stored
# in a separate section. This mostly removes unused linker sections and reduces
# the size by ~3% on mipsel.
TARGET_CFLAGS += -ffunction-sections -fdata-sections
TARGET_LDFLAGS += -Wl,--gc-sections
# Link-time optimization allows to move parts of the optimization from the single
# source file to the global source view. This is done by emitting the GIMPLE
# representation in each object file and analyzing it again during the link step.
TARGET_CFLAGS += -flto
TARGET_LDFLAGS += -fuse-linker-plugin
MAKE_BATCTL_ENV += \
CPPFLAGS="$(TARGET_CPPFLAGS)" \
CFLAGS="$(TARGET_CFLAGS)" \
CCFLAGS="$(TARGET_CFLAGS)" \
OFLAGS="$(TARGET_CFLAGS)" \
LDFLAGS="$(TARGET_LDFLAGS)"
MAKE_BATCTL_ARGS += \
REVISION="" \
CC="$(TARGET_CC)" \
NODEBUG=1 \
UNAME="Linux" \
DESTDIR="$(PKG_INSTALL_DIR)" \
STRIP="/bin/true" \
batctl install
ifneq ($(DEVELOPER)$(CONFIG_KMOD_BATMAN_ADV_BATCTL),)
@ -82,7 +95,7 @@ $(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_BUILD = $(MAKE_BATCTL_ENV) $(MAKE) -C $(PKG_BATCTL_BUILD_DIR) $(MAKE_BATCTL_ARGS)
BATCTL_INSTALL = $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/local/sbin/batctl $(1)/usr/sbin/
endif

View File

@ -1,74 +0,0 @@
From 9b96ecbae7295269aaa0320667f646870de65661 Mon Sep 17 00:00:00 2001
From: Antonio Quartulli <antonio@open-mesh.com>
Date: Wed, 3 Apr 2013 10:14:20 +0200
Subject: [PATCH 01/10] batman-adv: use the proper header len when checking
the TTVN
Unicast packet might be of type either UNICAST or
UNICAST4ADDR.
In the two cases the header size is different, but the
mechanism checking the TTVN field was assuming it to be
always of the same type (UNICAST), so failing to access the
inner Ethernet header in case of UNICAST4ADDR.
Fix this by passing the real header length as argument.
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
routing.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/routing.c b/routing.c
index 2f1f889..b27a4d7 100644
--- a/routing.c
+++ b/routing.c
@@ -939,7 +939,7 @@ out:
}
static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
- struct sk_buff *skb) {
+ struct sk_buff *skb, int hdr_len) {
uint8_t curr_ttvn, old_ttvn;
struct batadv_orig_node *orig_node;
struct ethhdr *ethhdr;
@@ -948,7 +948,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
int is_old_ttvn;
/* check if there is enough data before accessing it */
- if (pskb_may_pull(skb, sizeof(*unicast_packet) + ETH_HLEN) < 0)
+ if (pskb_may_pull(skb, hdr_len + ETH_HLEN) < 0)
return 0;
/* create a copy of the skb (in case of for re-routing) to modify it. */
@@ -956,7 +956,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
return 0;
unicast_packet = (struct batadv_unicast_packet *)skb->data;
- ethhdr = (struct ethhdr *)(skb->data + sizeof(*unicast_packet));
+ ethhdr = (struct ethhdr *)(skb->data + hdr_len);
/* check if the destination client was served by this node and it is now
* roaming. In this case, it means that the node has got a ROAM_ADV
@@ -1072,8 +1072,7 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
if (check < 0)
return NET_RX_DROP;
-
- if (!batadv_check_unicast_ttvn(bat_priv, skb))
+ if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size))
return NET_RX_DROP;
/* packet for me */
@@ -1117,7 +1116,7 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0)
return NET_RX_DROP;
- if (!batadv_check_unicast_ttvn(bat_priv, skb))
+ if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size))
return NET_RX_DROP;
unicast_packet = (struct batadv_unicast_frag_packet *)skb->data;
--
1.7.10.4

View File

@ -1,69 +0,0 @@
From 82d1a8ebf19a1b9841ee44ce7b2448114be3e772 Mon Sep 17 00:00:00 2001
From: Patrick McHardy <kaber@trash.net>
Date: Wed, 24 Apr 2013 17:42:56 +0200
Subject: [PATCH 02/10] net: vlan: add protocol argument to packet tagging
functions
Add a protocol argument to the VLAN packet tagging functions. In case of HW
tagging, we need that protocol available in the ndo_start_xmit functions,
so it is stored in a new field in the skb. The new field fits into a hole
(on 64 bit) and doesn't increase the sks's size.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
[siwu@hrz.tu-chemnitz.de: added compat code]
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
bridge_loop_avoidance.c | 2 +-
compat.h | 16 +++++++++++++++-
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/bridge_loop_avoidance.c b/bridge_loop_avoidance.c
index 6a4f728..379061c 100644
--- a/bridge_loop_avoidance.c
+++ b/bridge_loop_avoidance.c
@@ -341,7 +341,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
}
if (vid != -1)
- skb = vlan_insert_tag(skb, vid);
+ skb = vlan_insert_tag(skb, htons(ETH_P_8021Q), vid);
skb_reset_mac_header(skb);
skb->protocol = eth_type_trans(skb, soft_iface);
diff --git a/compat.h b/compat.h
index 0663df5..c1dadac 100644
--- a/compat.h
+++ b/compat.h
@@ -170,7 +170,7 @@ static const struct { \
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
#define kfree_rcu(ptr, rcu_head) call_rcu(&ptr->rcu_head, batadv_free_rcu_##ptr)
-#define vlan_insert_tag(skb, vid) __vlan_put_tag(skb, vid)
+#define vlan_insert_tag(skb, proto, vid) __vlan_put_tag(skb, vid)
void batadv_free_rcu_gw_node(struct rcu_head *rcu);
void batadv_free_rcu_neigh_node(struct rcu_head *rcu);
@@ -278,4 +278,18 @@ static int __batadv_interface_set_mac_addr(x, y)
#endif /* < KERNEL_VERSION(3, 9, 0) */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
+
+#ifndef vlan_insert_tag
+
+/* include this header early to let the following define
+ * not mess up the original function prototype.
+ */
+#include <linux/if_vlan.h>
+#define vlan_insert_tag(skb, proto, vid) vlan_insert_tag(skb, vid)
+
+#endif /* vlan_insert_tag */
+
+#endif /* < KERNEL_VERSION(3, 10, 0) */
+
#endif /* _NET_BATMAN_ADV_COMPAT_H_ */
--
1.7.10.4

View File

@ -1,33 +0,0 @@
From aa7d19a5b97fe48657e075e8e4d130bd6916551e Mon Sep 17 00:00:00 2001
From: Marek Lindner <lindner_marek@yahoo.de>
Date: Sat, 27 Apr 2013 16:22:28 +0800
Subject: [PATCH 03/10] batman-adv: check proto length before accessing proto
string buffer
batadv_param_set_ra() strips the trailing '\n' from the supplied
string buffer without checking the length of the buffer first. This
patches avoids random memory access and associated potential
crashes.
Reported-by: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/main.c b/main.c
index 3e30a0f..9c620cd 100644
--- a/main.c
+++ b/main.c
@@ -475,7 +475,7 @@ static int batadv_param_set_ra(const char *val, const struct kernel_param *kp)
char *algo_name = (char *)val;
size_t name_len = strlen(algo_name);
- if (algo_name[name_len - 1] == '\n')
+ if (name_len > 0 && algo_name[name_len - 1] == '\n')
algo_name[name_len - 1] = '\0';
bat_algo_ops = batadv_algo_get(algo_name);
--
1.7.10.4

View File

@ -1,44 +0,0 @@
From d22ebef1431aab13099370b89afa4ba55eb95c35 Mon Sep 17 00:00:00 2001
From: Marek Lindner <lindner_marek@yahoo.de>
Date: Tue, 7 May 2013 19:25:02 +0800
Subject: [PATCH 04/10] batman-adv: check return value of pskb_trim_rcsum()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reported-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Acked-by: Martin Hundebøll <martin@hundeboll.net>
---
network-coding.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/network-coding.c b/network-coding.c
index f7c5430..e84629e 100644
--- a/network-coding.c
+++ b/network-coding.c
@@ -1514,6 +1514,7 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
struct ethhdr *ethhdr, ethhdr_tmp;
uint8_t *orig_dest, ttl, ttvn;
unsigned int coding_len;
+ int err;
/* Save headers temporarily */
memcpy(&coded_packet_tmp, skb->data, sizeof(coded_packet_tmp));
@@ -1568,8 +1569,11 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
coding_len);
/* Resize decoded skb if decoded with larger packet */
- if (nc_packet->skb->len > coding_len + h_size)
- pskb_trim_rcsum(skb, coding_len + h_size);
+ if (nc_packet->skb->len > coding_len + h_size) {
+ err = pskb_trim_rcsum(skb, coding_len + h_size);
+ if (err)
+ return NULL;
+ }
/* Create decoded unicast packet */
unicast_packet = (struct batadv_unicast_packet *)skb->data;
--
1.7.10.4

View File

@ -1,48 +0,0 @@
From d6bd8b36fa1f3d72a6fd5942a6e9bde6ddafcd0d Mon Sep 17 00:00:00 2001
From: Antonio Quartulli <ordex@autistici.org>
Date: Thu, 9 May 2013 09:35:45 +0200
Subject: [PATCH 05/10] batman-adv: make DAT drop ARP requests targeting local
clients
In the outgoing ARP request snooping routine in DAT, ARP
Request sent by local clients which are supposed to be
replied by other local clients can be silently dropped.
The destination host will reply by itself through the LAN
and therefore there is no need to involve DAT.
Reported-by: Carlos Quijano <carlos@crqgestion.es>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Tested-by: Carlos Quijano <carlos@crqgestion.es>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
distributed-arp-table.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/distributed-arp-table.c b/distributed-arp-table.c
index 8e15d96..2399920 100644
--- a/distributed-arp-table.c
+++ b/distributed-arp-table.c
@@ -837,6 +837,19 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
if (dat_entry) {
+ /* If the ARP request is destined for a local client the local
+ * client will answer itself. DAT would only generate a
+ * duplicate packet.
+ *
+ * Moreover, if the soft-interface is enslaved into a bridge, an
+ * additional DAT answer may trigger kernel warnings about
+ * a packet coming from the wrong port.
+ */
+ if (batadv_is_my_client(bat_priv, dat_entry->mac_addr)) {
+ ret = true;
+ goto out;
+ }
+
skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
bat_priv->soft_iface, ip_dst, hw_src,
dat_entry->mac_addr, hw_src);
--
1.7.10.4

View File

@ -1,57 +0,0 @@
From 763f413b9c74ccb25cb066408f49f07e5dd78f9b Mon Sep 17 00:00:00 2001
From: Antonio Quartulli <ordex@autistici.org>
Date: Tue, 7 May 2013 01:06:18 +0200
Subject: [PATCH 06/10] batman-adv: reorder clean up routine in order to avoid
race conditions
nc_worker accesses the originator table during its periodic
work, but since the originator table is freed before
stopping the worker this leads to a global protection fault.
Fix this by killing the worker (in nc_free) before freeing
the originator table.
Moreover tidy up the entire clean up routine by running all
the subcomponents freeing procedures first and then killing
the TT and the originator tables at the end.
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
main.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/main.c b/main.c
index 9c620cd..1240f07 100644
--- a/main.c
+++ b/main.c
@@ -163,14 +163,22 @@ void batadv_mesh_free(struct net_device *soft_iface)
batadv_vis_quit(bat_priv);
batadv_gw_node_purge(bat_priv);
- batadv_originator_free(bat_priv);
batadv_nc_free(bat_priv);
+ batadv_dat_free(bat_priv);
+ batadv_bla_free(bat_priv);
+ /* Free the TT and the originator tables only after having terminated
+ * all the other depending components which may use these structures for
+ * their purposes.
+ */
batadv_tt_free(bat_priv);
- batadv_bla_free(bat_priv);
-
- batadv_dat_free(bat_priv);
+ /* Since the originator table clean up routine is accessing the TT
+ * tables as well, it has to be invoked after the TT tables have been
+ * freed and marked as empty. This ensures that no cleanup RCU callbacks
+ * accessing the TT data are scheduled for later execution.
+ */
+ batadv_originator_free(bat_priv);
free_percpu(bat_priv->bat_counters);
--
1.7.10.4

View File

@ -1,47 +0,0 @@
From a5d79639a76d7a71116abbc369a246bd1fcbf947 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Hundeb=C3=B8ll?= <martin@hundeboll.net>
Date: Wed, 17 Apr 2013 21:13:16 +0200
Subject: [PATCH 07/10] batman-adv: Avoid double freeing of bat_counters
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On errors in batadv_mesh_init(), bat_counters will be freed in both
batadv_mesh_free() and batadv_softif_init_late(). This patch fixes this
by returning earlier from batadv_softif_init_late() in case of errors in
batadv_mesh_init() and by setting bat_counters to NULL after freeing.
Signed-off-by: Martin Hundebøll <martin@hundeboll.net>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
main.c | 1 +
soft-interface.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/main.c b/main.c
index 1240f07..51aafd6 100644
--- a/main.c
+++ b/main.c
@@ -181,6 +181,7 @@ void batadv_mesh_free(struct net_device *soft_iface)
batadv_originator_free(bat_priv);
free_percpu(bat_priv->bat_counters);
+ bat_priv->bat_counters = NULL;
atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
}
diff --git a/soft-interface.c b/soft-interface.c
index 6f20d33..819dfb0 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -505,6 +505,7 @@ unreg_debugfs:
batadv_debugfs_del_meshif(dev);
free_bat_counters:
free_percpu(bat_priv->bat_counters);
+ bat_priv->bat_counters = NULL;
return ret;
}
--
1.7.10.4

View File

@ -1,42 +0,0 @@
From 96cd7725540f4dccdd6fbb4fde59243e1cc1ad80 Mon Sep 17 00:00:00 2001
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Tue, 28 May 2013 17:32:32 +0200
Subject: [PATCH 08/10] batman-adv: wait for rtnl in batadv_store_mesh_iface
instead of failing if it is taken
The rtnl_lock in batadv_store_mesh_iface has been converted to a rtnl_trylock
some time ago to avoid a possible deadlock between rtnl and s_active on removal
of the sysfs nodes.
The behaviour introduced by that was quite confusing as it could lead to the
sysfs store to fail, making batman-adv setup scripts unreliable. As recently the
sysfs removal was postponed to a worker not running with the rtnl taken, the
deadlock can't occur any more and it is safe to change the trylock back to a
lock to make the sysfs store reliable again.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
Reviewed-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
sysfs.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/sysfs.c b/sysfs.c
index 15a22ef..929e304 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -582,10 +582,7 @@ static ssize_t batadv_store_mesh_iface(struct kobject *kobj,
(strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0))
goto out;
- if (!rtnl_trylock()) {
- ret = -ERESTARTSYS;
- goto out;
- }
+ rtnl_lock();
if (status_tmp == BATADV_IF_NOT_IN_USE) {
batadv_hardif_disable_interface(hard_iface,
--
1.7.10.4

View File

@ -1,35 +0,0 @@
From 518fba156ed911c6183cf5cb34955a6fdf1b4637 Mon Sep 17 00:00:00 2001
From: Simon Wunderlich <simon@open-mesh.com>
Date: Fri, 7 Jun 2013 16:52:05 +0200
Subject: [PATCH 09/10] batman-adv: Don't handle address updates when bla is
disabled
The bridge loop avoidance has a hook to handle address updates of the
originator. These should not be handled when bridge loop avoidance is
disabled - it might send some bridge loop avoidance packets which should
not appear if bla is disabled.
Signed-off-by: Simon Wunderlich <simon@open-mesh.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
bridge_loop_avoidance.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/bridge_loop_avoidance.c b/bridge_loop_avoidance.c
index 379061c..de27b31 100644
--- a/bridge_loop_avoidance.c
+++ b/bridge_loop_avoidance.c
@@ -1067,6 +1067,10 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
group = htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN));
bat_priv->bla.claim_dest.group = group;
+ /* purge everything when bridge loop avoidance is turned off */
+ if (!atomic_read(&bat_priv->bridge_loop_avoidance))
+ oldif = NULL;
+
if (!oldif) {
batadv_bla_purge_claims(bat_priv, NULL, 1);
batadv_bla_purge_backbone_gw(bat_priv, 1);
--
1.7.10.4

View File

@ -1,226 +0,0 @@
From 3d999e5116f44b47c742aa16d6382721c360a6d0 Mon Sep 17 00:00:00 2001
From: Simon Wunderlich <simon@open-mesh.com>
Date: Thu, 23 May 2013 13:07:42 +0200
Subject: [PATCH 10/10] batman-adv: forward late OGMs from best next hop
When a packet is received from another node first and later from the
best next hop, this packet is dropped. However the first OGM was sent
with the BATADV_NOT_BEST_NEXT_HOP flag and thus dropped by neighbors.
The late OGM from the best neighbor is then dropped because it is a
duplicate.
If this situation happens constantly, a node might end up not forwarding
the "valid" OGMs anymore, and nodes behind will starve from not getting
valid OGMs.
Fix this by refining the duplicate checking behaviour: The actions
should depend on whether it was a duplicate for a neighbor only or for
the originator. OGMs which are not duplicates for a specific neighbor
will now be considered in batadv_iv_ogm_forward(), but only actually
forwarded for the best next hop. Therefore, late OGMs from the best
next hop are forwarded now and not dropped as duplicates anymore.
Signed-off-by: Simon Wunderlich <simon@open-mesh.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
bat_iv_ogm.c | 86 +++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 55 insertions(+), 31 deletions(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c
index 071f288..f680ee1 100644
--- a/bat_iv_ogm.c
+++ b/bat_iv_ogm.c
@@ -29,6 +29,21 @@
#include "bat_algo.h"
#include "network-coding.h"
+/**
+ * batadv_dup_status - duplicate status
+ * @BATADV_NO_DUP: the packet is a duplicate
+ * @BATADV_ORIG_DUP: OGM is a duplicate in the originator (but not for the
+ * neighbor)
+ * @BATADV_NEIGH_DUP: OGM is a duplicate for the neighbor
+ * @BATADV_PROTECTED: originator is currently protected (after reboot)
+ */
+enum batadv_dup_status {
+ BATADV_NO_DUP = 0,
+ BATADV_ORIG_DUP,
+ BATADV_NEIGH_DUP,
+ BATADV_PROTECTED,
+};
+
static struct batadv_neigh_node *
batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
const uint8_t *neigh_addr,
@@ -650,7 +665,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
const struct batadv_ogm_packet *batadv_ogm_packet,
struct batadv_hard_iface *if_incoming,
const unsigned char *tt_buff,
- int is_duplicate)
+ enum batadv_dup_status dup_status)
{
struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
struct batadv_neigh_node *router = NULL;
@@ -676,7 +691,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
continue;
}
- if (is_duplicate)
+ if (dup_status != BATADV_NO_DUP)
continue;
spin_lock_bh(&tmp_neigh_node->lq_update_lock);
@@ -718,7 +733,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
neigh_node->tq_avg = batadv_ring_buffer_avg(neigh_node->tq_recv);
spin_unlock_bh(&neigh_node->lq_update_lock);
- if (!is_duplicate) {
+ if (dup_status == BATADV_NO_DUP) {
orig_node->last_ttl = batadv_ogm_packet->header.ttl;
neigh_node->last_ttl = batadv_ogm_packet->header.ttl;
}
@@ -902,15 +917,16 @@ out:
return ret;
}
-/* processes a batman packet for all interfaces, adjusts the sequence number and
- * finds out whether it is a duplicate.
- * returns:
- * 1 the packet is a duplicate
- * 0 the packet has not yet been received
- * -1 the packet is old and has been received while the seqno window
- * was protected. Caller should drop it.
+/**
+ * batadv_iv_ogm_update_seqnos - process a batman packet for all interfaces,
+ * adjust the sequence number and find out whether it is a duplicate
+ * @ethhdr: ethernet header of the packet
+ * @batadv_ogm_packet: OGM packet to be considered
+ * @if_incoming: interface on which the OGM packet was received
+ *
+ * Returns duplicate status as enum batadv_dup_status
*/
-static int
+static enum batadv_dup_status
batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
const struct batadv_ogm_packet *batadv_ogm_packet,
const struct batadv_hard_iface *if_incoming)
@@ -918,17 +934,18 @@ 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;
- int is_duplicate = 0;
+ int is_dup;
int32_t seq_diff;
int need_update = 0;
- int set_mark, ret = -1;
+ int set_mark;
+ enum batadv_dup_status ret = BATADV_NO_DUP;
uint32_t seqno = ntohl(batadv_ogm_packet->seqno);
uint8_t *neigh_addr;
uint8_t packet_count;
orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig);
if (!orig_node)
- return 0;
+ return BATADV_NO_DUP;
spin_lock_bh(&orig_node->ogm_cnt_lock);
seq_diff = seqno - orig_node->last_real_seqno;
@@ -936,22 +953,29 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
/* signalize caller that the packet is to be dropped. */
if (!hlist_empty(&orig_node->neigh_list) &&
batadv_window_protected(bat_priv, seq_diff,
- &orig_node->batman_seqno_reset))
+ &orig_node->batman_seqno_reset)) {
+ ret = BATADV_PROTECTED;
goto out;
+ }
rcu_read_lock();
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,
- seqno);
-
neigh_addr = tmp_neigh_node->addr;
+ is_dup = batadv_test_bit(tmp_neigh_node->real_bits,
+ orig_node->last_real_seqno,
+ seqno);
+
if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
- tmp_neigh_node->if_incoming == if_incoming)
+ tmp_neigh_node->if_incoming == if_incoming) {
set_mark = 1;
- else
+ if (is_dup)
+ ret = BATADV_NEIGH_DUP;
+ } else {
set_mark = 0;
+ if (is_dup && (ret != BATADV_NEIGH_DUP))
+ ret = BATADV_ORIG_DUP;
+ }
/* if the window moved, set the update flag. */
need_update |= batadv_bit_get_packet(bat_priv,
@@ -971,8 +995,6 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
orig_node->last_real_seqno = seqno;
}
- ret = is_duplicate;
-
out:
spin_unlock_bh(&orig_node->ogm_cnt_lock);
batadv_orig_node_free_ref(orig_node);
@@ -994,7 +1016,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
int is_broadcast = 0, is_bidirect;
bool is_single_hop_neigh = false;
bool is_from_best_next_hop = false;
- int is_duplicate, sameseq, simlar_ttl;
+ int sameseq, similar_ttl;
+ enum batadv_dup_status dup_status;
uint32_t if_incoming_seqno;
uint8_t *prev_sender;
@@ -1138,10 +1161,10 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
if (!orig_node)
return;
- is_duplicate = batadv_iv_ogm_update_seqnos(ethhdr, batadv_ogm_packet,
- if_incoming);
+ dup_status = batadv_iv_ogm_update_seqnos(ethhdr, batadv_ogm_packet,
+ if_incoming);
- if (is_duplicate == -1) {
+ if (dup_status == BATADV_PROTECTED) {
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Drop packet: packet within seqno protection time (sender: %pM)\n",
ethhdr->h_source);
@@ -1211,11 +1234,12 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
* seqno and similar ttl as the non-duplicate
*/
sameseq = orig_node->last_real_seqno == ntohl(batadv_ogm_packet->seqno);
- simlar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->header.ttl;
- if (is_bidirect && (!is_duplicate || (sameseq && simlar_ttl)))
+ similar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->header.ttl;
+ if (is_bidirect && ((dup_status == BATADV_NO_DUP) ||
+ (sameseq && similar_ttl)))
batadv_iv_ogm_orig_update(bat_priv, orig_node, ethhdr,
batadv_ogm_packet, if_incoming,
- tt_buff, is_duplicate);
+ tt_buff, dup_status);
/* is single hop (direct) neighbor */
if (is_single_hop_neigh) {
@@ -1236,7 +1260,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
goto out_neigh;
}
- if (is_duplicate) {
+ if (dup_status == BATADV_NEIGH_DUP) {
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Drop packet: duplicate packet received\n");
goto out_neigh;
--
1.7.10.4