commit
a881d5d4a6
11 changed files with 470 additions and 217 deletions
|
@ -11,10 +11,10 @@ include $(TOPDIR)/rules.mk
|
||||||
# The latest alfred git hash in PKG_REV can be obtained from https://git.open-mesh.org/alfred.git
|
# The latest alfred git hash in PKG_REV can be obtained from https://git.open-mesh.org/alfred.git
|
||||||
#
|
#
|
||||||
PKG_NAME:=alfred
|
PKG_NAME:=alfred
|
||||||
PKG_VERSION:=2016.5
|
PKG_VERSION:=2017.0
|
||||||
PKG_RELEASE:=0
|
PKG_RELEASE:=0
|
||||||
PKG_MD5SUM:=e03d422ed3b5a162b90e8af13389523f
|
PKG_MD5SUM:=2e9ae897b1d477f14d06389eb7c1f97b
|
||||||
PKG_HASH:=37b3babf7f37643cf296be11fb82d5730cf441a5a56f72fba96edae9f149c9d2
|
PKG_HASH:=f8d6d83d2ce30b2238354ce12073285387c0f4ca1a28060390ff50b411b50fa8
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
|
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
|
||||||
|
|
|
@ -9,10 +9,10 @@ include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=batctl
|
PKG_NAME:=batctl
|
||||||
|
|
||||||
PKG_VERSION:=2016.5
|
PKG_VERSION:=2017.0
|
||||||
PKG_RELEASE:=0
|
PKG_RELEASE:=0
|
||||||
PKG_MD5SUM:=7b33fb47c7fa5b317e9a152a286999fc
|
PKG_MD5SUM:=17c0ac0746f1994ddacc88ebf48e5aec
|
||||||
PKG_HASH:=07edeb1d87a548285be8c499542790a158fc8d94ef7ebb295f27ebf710024ae9
|
PKG_HASH:=c0bb1127d6070b46abeb8d6a63d1150d71fa85f87f9a846873b649a21934c686
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
|
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
|
||||||
|
|
|
@ -10,10 +10,10 @@ include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=batman-adv
|
PKG_NAME:=batman-adv
|
||||||
|
|
||||||
PKG_VERSION:=2016.5
|
PKG_VERSION:=2017.0
|
||||||
PKG_RELEASE:=4
|
PKG_RELEASE:=0
|
||||||
PKG_MD5SUM:=6717a933a08dd2a01b00df30cb9f16a8
|
PKG_MD5SUM:=1b3121f0baa8771ff6d8ad172c95904f
|
||||||
PKG_HASH:=d0a0fc90c4f410b57d043215e253bb0b855efa5edbe165d87c17bfdcfafd0db7
|
PKG_HASH:=65df01222bc51ec788fb1b6dc63feaf69d393f2d0a96e347d55de83b1602c509
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
|
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
|
||||||
|
|
|
@ -33,6 +33,15 @@
|
||||||
|
|
||||||
#endif /* < KERNEL_VERSION(4, 5, 0) */
|
#endif /* < KERNEL_VERSION(4, 5, 0) */
|
||||||
|
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
|
||||||
|
|
||||||
|
/* wild hack for batadv_getlink_net only */
|
||||||
|
#define get_link_net get_xstats_size || 1 ? fallback_net : (struct net*)netdev->rtnl_link_ops->get_xstats_size
|
||||||
|
|
||||||
|
#endif /* < KERNEL_VERSION(4, 0, 0) */
|
||||||
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
|
||||||
|
|
||||||
struct sk_buff *skb_checksum_trimmed(struct sk_buff *skb,
|
struct sk_buff *skb_checksum_trimmed(struct sk_buff *skb,
|
||||||
|
@ -204,3 +213,78 @@ static inline int batadv_nla_put_u64_64bit(struct sk_buff *skb, int attrtype,
|
||||||
#define __ro_after_init
|
#define __ro_after_init
|
||||||
|
|
||||||
#endif /* < KERNEL_VERSION(4, 10, 0) */
|
#endif /* < KERNEL_VERSION(4, 10, 0) */
|
||||||
|
|
||||||
|
/* <DECLARE_EWMA> */
|
||||||
|
|
||||||
|
#include <linux/version.h>
|
||||||
|
#include_next <linux/average.h>
|
||||||
|
|
||||||
|
#include <linux/bug.h>
|
||||||
|
|
||||||
|
#ifdef DECLARE_EWMA
|
||||||
|
#undef DECLARE_EWMA
|
||||||
|
#endif /* DECLARE_EWMA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exponentially weighted moving average (EWMA)
|
||||||
|
*
|
||||||
|
* This implements a fixed-precision EWMA algorithm, with both the
|
||||||
|
* precision and fall-off coefficient determined at compile-time
|
||||||
|
* and built into the generated helper funtions.
|
||||||
|
*
|
||||||
|
* The first argument to the macro is the name that will be used
|
||||||
|
* for the struct and helper functions.
|
||||||
|
*
|
||||||
|
* The second argument, the precision, expresses how many bits are
|
||||||
|
* used for the fractional part of the fixed-precision values.
|
||||||
|
*
|
||||||
|
* The third argument, the weight reciprocal, determines how the
|
||||||
|
* new values will be weighed vs. the old state, new values will
|
||||||
|
* get weight 1/weight_rcp and old values 1-1/weight_rcp. Note
|
||||||
|
* that this parameter must be a power of two for efficiency.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DECLARE_EWMA(name, _precision, _weight_rcp) \
|
||||||
|
struct ewma_##name { \
|
||||||
|
unsigned long internal; \
|
||||||
|
}; \
|
||||||
|
static inline void ewma_##name##_init(struct ewma_##name *e) \
|
||||||
|
{ \
|
||||||
|
BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
|
||||||
|
BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
|
||||||
|
/* \
|
||||||
|
* Even if you want to feed it just 0/1 you should have \
|
||||||
|
* some bits for the non-fractional part... \
|
||||||
|
*/ \
|
||||||
|
BUILD_BUG_ON((_precision) > 30); \
|
||||||
|
BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
|
||||||
|
e->internal = 0; \
|
||||||
|
} \
|
||||||
|
static inline unsigned long \
|
||||||
|
ewma_##name##_read(struct ewma_##name *e) \
|
||||||
|
{ \
|
||||||
|
BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
|
||||||
|
BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
|
||||||
|
BUILD_BUG_ON((_precision) > 30); \
|
||||||
|
BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
|
||||||
|
return e->internal >> (_precision); \
|
||||||
|
} \
|
||||||
|
static inline void ewma_##name##_add(struct ewma_##name *e, \
|
||||||
|
unsigned long val) \
|
||||||
|
{ \
|
||||||
|
unsigned long internal = ACCESS_ONCE(e->internal); \
|
||||||
|
unsigned long weight_rcp = ilog2(_weight_rcp); \
|
||||||
|
unsigned long precision = _precision; \
|
||||||
|
\
|
||||||
|
BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
|
||||||
|
BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
|
||||||
|
BUILD_BUG_ON((_precision) > 30); \
|
||||||
|
BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
|
||||||
|
\
|
||||||
|
ACCESS_ONCE(e->internal) = internal ? \
|
||||||
|
(((internal << weight_rcp) - internal) + \
|
||||||
|
(val << precision)) >> weight_rcp : \
|
||||||
|
(val << precision); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* </DECLARE_EWMA> */
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
From: Sven Eckelmann <sven@narfation.org>
|
|
||||||
Date: Fri, 23 Sep 2016 14:55:38 +0200
|
|
||||||
Subject: [PATCH] Add compat fallback for batadv_getlink_net
|
|
||||||
---
|
|
||||||
net/batman-adv/hard-interface.c | 4 ++++
|
|
||||||
1 file changed, 4 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
|
|
||||||
index 61a431a9..6969f580 100644
|
|
||||||
--- a/net/batman-adv/hard-interface.c
|
|
||||||
+++ b/net/batman-adv/hard-interface.c
|
|
||||||
@@ -95,6 +95,9 @@ out:
|
|
||||||
static struct net *batadv_getlink_net(const struct net_device *netdev,
|
|
||||||
struct net *fallback_net)
|
|
||||||
{
|
|
||||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
|
|
||||||
+ return fallback_net;
|
|
||||||
+#else
|
|
||||||
if (!netdev->rtnl_link_ops)
|
|
||||||
return fallback_net;
|
|
||||||
|
|
||||||
@@ -102,6 +105,7 @@ static struct net *batadv_getlink_net(const struct net_device *netdev,
|
|
||||||
return fallback_net;
|
|
||||||
|
|
||||||
return netdev->rtnl_link_ops->get_link_net(netdev);
|
|
||||||
+#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
From: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
Date: Wed, 15 Feb 2017 09:49:26 +0100
|
||||||
|
Subject: [PATCH] batman-adv: average: change to declare precision, not factor
|
||||||
|
|
||||||
|
Declaring the factor is counter-intuitive, and people are prone
|
||||||
|
to using small(-ish) values even when that makes no sense.
|
||||||
|
|
||||||
|
Change the DECLARE_EWMA() macro to take the fractional precision,
|
||||||
|
in bits, rather than a factor, and update all users.
|
||||||
|
|
||||||
|
While at it, add some more documentation.
|
||||||
|
|
||||||
|
Acked-by: David S. Miller <davem@davemloft.net>
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
[sven@narfation.org: Added compatibility code]
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
---
|
||||||
|
compat-include/linux/average.h | 67 +++++++++++++++++++++++++++---------------
|
||||||
|
net/batman-adv/types.h | 2 +-
|
||||||
|
2 files changed, 45 insertions(+), 24 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/compat-include/linux/average.h b/compat-include/linux/average.h
|
||||||
|
index ec022cb6..a1e3c254 100644
|
||||||
|
--- a/compat-include/linux/average.h
|
||||||
|
+++ b/compat-include/linux/average.h
|
||||||
|
@@ -26,49 +26,70 @@
|
||||||
|
|
||||||
|
#include <linux/bug.h>
|
||||||
|
|
||||||
|
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
|
||||||
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
|
||||||
|
+#undef DECLARE_EWMA
|
||||||
|
+#endif /* < KERNEL_VERSION(4, 3, 0) */
|
||||||
|
|
||||||
|
-/* Exponentially weighted moving average (EWMA) */
|
||||||
|
+/*
|
||||||
|
+ * Exponentially weighted moving average (EWMA)
|
||||||
|
+ *
|
||||||
|
+ * This implements a fixed-precision EWMA algorithm, with both the
|
||||||
|
+ * precision and fall-off coefficient determined at compile-time
|
||||||
|
+ * and built into the generated helper funtions.
|
||||||
|
+ *
|
||||||
|
+ * The first argument to the macro is the name that will be used
|
||||||
|
+ * for the struct and helper functions.
|
||||||
|
+ *
|
||||||
|
+ * The second argument, the precision, expresses how many bits are
|
||||||
|
+ * used for the fractional part of the fixed-precision values.
|
||||||
|
+ *
|
||||||
|
+ * The third argument, the weight reciprocal, determines how the
|
||||||
|
+ * new values will be weighed vs. the old state, new values will
|
||||||
|
+ * get weight 1/weight_rcp and old values 1-1/weight_rcp. Note
|
||||||
|
+ * that this parameter must be a power of two for efficiency.
|
||||||
|
+ */
|
||||||
|
|
||||||
|
-#define DECLARE_EWMA(name, _factor, _weight) \
|
||||||
|
+#define DECLARE_EWMA(name, _precision, _weight_rcp) \
|
||||||
|
struct ewma_##name { \
|
||||||
|
unsigned long internal; \
|
||||||
|
}; \
|
||||||
|
static inline void ewma_##name##_init(struct ewma_##name *e) \
|
||||||
|
{ \
|
||||||
|
- BUILD_BUG_ON(!__builtin_constant_p(_factor)); \
|
||||||
|
- BUILD_BUG_ON(!__builtin_constant_p(_weight)); \
|
||||||
|
- BUILD_BUG_ON_NOT_POWER_OF_2(_factor); \
|
||||||
|
- BUILD_BUG_ON_NOT_POWER_OF_2(_weight); \
|
||||||
|
+ BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
|
||||||
|
+ BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
|
||||||
|
+ /* \
|
||||||
|
+ * Even if you want to feed it just 0/1 you should have \
|
||||||
|
+ * some bits for the non-fractional part... \
|
||||||
|
+ */ \
|
||||||
|
+ BUILD_BUG_ON((_precision) > 30); \
|
||||||
|
+ BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
|
||||||
|
e->internal = 0; \
|
||||||
|
} \
|
||||||
|
static inline unsigned long \
|
||||||
|
ewma_##name##_read(struct ewma_##name *e) \
|
||||||
|
{ \
|
||||||
|
- BUILD_BUG_ON(!__builtin_constant_p(_factor)); \
|
||||||
|
- BUILD_BUG_ON(!__builtin_constant_p(_weight)); \
|
||||||
|
- BUILD_BUG_ON_NOT_POWER_OF_2(_factor); \
|
||||||
|
- BUILD_BUG_ON_NOT_POWER_OF_2(_weight); \
|
||||||
|
- return e->internal >> ilog2(_factor); \
|
||||||
|
+ BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
|
||||||
|
+ BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
|
||||||
|
+ BUILD_BUG_ON((_precision) > 30); \
|
||||||
|
+ BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
|
||||||
|
+ return e->internal >> (_precision); \
|
||||||
|
} \
|
||||||
|
static inline void ewma_##name##_add(struct ewma_##name *e, \
|
||||||
|
unsigned long val) \
|
||||||
|
{ \
|
||||||
|
unsigned long internal = ACCESS_ONCE(e->internal); \
|
||||||
|
- unsigned long weight = ilog2(_weight); \
|
||||||
|
- unsigned long factor = ilog2(_factor); \
|
||||||
|
+ unsigned long weight_rcp = ilog2(_weight_rcp); \
|
||||||
|
+ unsigned long precision = _precision; \
|
||||||
|
\
|
||||||
|
- BUILD_BUG_ON(!__builtin_constant_p(_factor)); \
|
||||||
|
- BUILD_BUG_ON(!__builtin_constant_p(_weight)); \
|
||||||
|
- BUILD_BUG_ON_NOT_POWER_OF_2(_factor); \
|
||||||
|
- BUILD_BUG_ON_NOT_POWER_OF_2(_weight); \
|
||||||
|
+ BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
|
||||||
|
+ BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
|
||||||
|
+ BUILD_BUG_ON((_precision) > 30); \
|
||||||
|
+ BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
|
||||||
|
\
|
||||||
|
ACCESS_ONCE(e->internal) = internal ? \
|
||||||
|
- (((internal << weight) - internal) + \
|
||||||
|
- (val << factor)) >> weight : \
|
||||||
|
- (val << factor); \
|
||||||
|
+ (((internal << weight_rcp) - internal) + \
|
||||||
|
+ (val << precision)) >> weight_rcp : \
|
||||||
|
+ (val << precision); \
|
||||||
|
}
|
||||||
|
|
||||||
|
-#endif /* < KERNEL_VERSION(4, 3, 0) */
|
||||||
|
-
|
||||||
|
#endif /* _NET_BATMAN_ADV_COMPAT_LINUX_AVERAGE_H */
|
||||||
|
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
|
||||||
|
index 8f64a5c0..66b25e41 100644
|
||||||
|
--- a/net/batman-adv/types.h
|
||||||
|
+++ b/net/batman-adv/types.h
|
||||||
|
@@ -402,7 +402,7 @@ struct batadv_gw_node {
|
||||||
|
struct rcu_head rcu;
|
||||||
|
};
|
||||||
|
|
||||||
|
-DECLARE_EWMA(throughput, 1024, 8)
|
||||||
|
+DECLARE_EWMA(throughput, 10, 8)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct batadv_hardif_neigh_node_bat_v - B.A.T.M.A.N. V private neighbor
|
|
@ -1,63 +0,0 @@
|
||||||
From: Sven Eckelmann <sven@narfation.org>
|
|
||||||
Date: Tue, 27 Dec 2016 08:51:17 +0100
|
|
||||||
Subject: [PATCH] batman-adv: Decrease hardif refcnt on fragmentation send error
|
|
||||||
|
|
||||||
An error before the hardif is found has to free the skb. But every error
|
|
||||||
after that has to free the skb + put the hard interface.
|
|
||||||
|
|
||||||
Fixes: 8b4132b1447a ("batman-adv: Consume skb in batadv_frag_send_packet")
|
|
||||||
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
|
||||||
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
|
|
||||||
---
|
|
||||||
net/batman-adv/fragmentation.c | 10 +++++-----
|
|
||||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
|
|
||||||
index 9c561e6..0854ebd 100644
|
|
||||||
--- a/net/batman-adv/fragmentation.c
|
|
||||||
+++ b/net/batman-adv/fragmentation.c
|
|
||||||
@@ -474,7 +474,7 @@ int batadv_frag_send_packet(struct sk_buff *skb,
|
|
||||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
|
||||||
if (!primary_if) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
- goto put_primary_if;
|
|
||||||
+ goto free_skb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create one header to be copied to all fragments */
|
|
||||||
@@ -502,7 +502,7 @@ int batadv_frag_send_packet(struct sk_buff *skb,
|
|
||||||
skb_fragment = batadv_frag_create(skb, &frag_header, mtu);
|
|
||||||
if (!skb_fragment) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
- goto free_skb;
|
|
||||||
+ goto put_primary_if;
|
|
||||||
}
|
|
||||||
|
|
||||||
batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_TX);
|
|
||||||
@@ -511,7 +511,7 @@ int batadv_frag_send_packet(struct sk_buff *skb,
|
|
||||||
ret = batadv_send_unicast_skb(skb_fragment, neigh_node);
|
|
||||||
if (ret != NET_XMIT_SUCCESS) {
|
|
||||||
ret = NET_XMIT_DROP;
|
|
||||||
- goto free_skb;
|
|
||||||
+ goto put_primary_if;
|
|
||||||
}
|
|
||||||
|
|
||||||
frag_header.no++;
|
|
||||||
@@ -519,7 +519,7 @@ int batadv_frag_send_packet(struct sk_buff *skb,
|
|
||||||
/* The initial check in this function should cover this case */
|
|
||||||
if (frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
- goto free_skb;
|
|
||||||
+ goto put_primary_if;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -527,7 +527,7 @@ int batadv_frag_send_packet(struct sk_buff *skb,
|
|
||||||
if (batadv_skb_head_push(skb, header_size) < 0 ||
|
|
||||||
pskb_expand_head(skb, header_size + ETH_HLEN, 0, GFP_ATOMIC) < 0) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
- goto free_skb;
|
|
||||||
+ goto put_primary_if;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(skb->data, &frag_header, header_size);
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Wed, 22 Feb 2017 17:25:42 +0100
|
||||||
|
Subject: [PATCH] batman-adv: Keep fragments equally sized
|
||||||
|
|
||||||
|
The batman-adv fragmentation packets have the design problem that they
|
||||||
|
cannot be refragmented and cannot handle padding by the underlying link.
|
||||||
|
The latter often leads to problems when networks are incorrectly configured
|
||||||
|
and don't use a common MTU.
|
||||||
|
|
||||||
|
The sender could for example fragment a 1271 byte frame (plus external
|
||||||
|
ethernet header (14) and batadv unicast header (10)) to fit in a 1280 bytes
|
||||||
|
large MTU of the underlying link (max. 1294 byte frames). This would create
|
||||||
|
a 1294 bytes large frame (fragment 2) and a 55 bytes large frame
|
||||||
|
(fragment 1). The extra 54 bytes are the fragment header (20) added to each
|
||||||
|
fragment and the external ethernet header (14) for the second fragment.
|
||||||
|
|
||||||
|
Let us assume that the next hop is then not able to transport 1294 bytes to
|
||||||
|
its next hop. The 1294 byte large frame will be dropped but the 55 bytes
|
||||||
|
large fragment will still be forwarded to its destination.
|
||||||
|
|
||||||
|
Or let us assume that the underlying hardware requires that each frame has
|
||||||
|
a minimum size (e.g. 60 bytes). Then it will pad the 55 bytes frame to 60
|
||||||
|
bytes. The receiver of the 60 bytes frame will no longer be able to
|
||||||
|
correctly assemble the two frames together because it is not aware that 5
|
||||||
|
bytes of the 60 bytes frame are padding and don't belong to the reassembled
|
||||||
|
frame.
|
||||||
|
|
||||||
|
This can partly be avoided by splitting frames more equally. In this
|
||||||
|
example, the 675 and 674 bytes large fragment frames could both potentially
|
||||||
|
reach its destination without being too large or too small.
|
||||||
|
|
||||||
|
Reported-by: Martin Weinelt <martin@darmstadt.freifunk.net>
|
||||||
|
Fixes: db56e4ecf5c2 ("batman-adv: Fragment and send skbs larger than mtu")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Acked-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
---
|
||||||
|
net/batman-adv/fragmentation.c | 20 +++++++++++++-------
|
||||||
|
1 file changed, 13 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
|
||||||
|
index 11a23fd6..8f964bea 100644
|
||||||
|
--- a/net/batman-adv/fragmentation.c
|
||||||
|
+++ b/net/batman-adv/fragmentation.c
|
||||||
|
@@ -404,7 +404,7 @@ bool batadv_frag_skb_fwd(struct sk_buff *skb,
|
||||||
|
* batadv_frag_create - create a fragment from skb
|
||||||
|
* @skb: skb to create fragment from
|
||||||
|
* @frag_head: header to use in new fragment
|
||||||
|
- * @mtu: size of new fragment
|
||||||
|
+ * @fragment_size: size of new fragment
|
||||||
|
*
|
||||||
|
* Split the passed skb into two fragments: A new one with size matching the
|
||||||
|
* passed mtu and the old one with the rest. The new skb contains data from the
|
||||||
|
@@ -414,11 +414,11 @@ bool batadv_frag_skb_fwd(struct sk_buff *skb,
|
||||||
|
*/
|
||||||
|
static struct sk_buff *batadv_frag_create(struct sk_buff *skb,
|
||||||
|
struct batadv_frag_packet *frag_head,
|
||||||
|
- unsigned int mtu)
|
||||||
|
+ unsigned int fragment_size)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb_fragment;
|
||||||
|
unsigned int header_size = sizeof(*frag_head);
|
||||||
|
- unsigned int fragment_size = mtu - header_size;
|
||||||
|
+ unsigned int mtu = fragment_size + header_size;
|
||||||
|
|
||||||
|
skb_fragment = netdev_alloc_skb(NULL, mtu + ETH_HLEN);
|
||||||
|
if (!skb_fragment)
|
||||||
|
@@ -456,7 +456,7 @@ int batadv_frag_send_packet(struct sk_buff *skb,
|
||||||
|
struct sk_buff *skb_fragment;
|
||||||
|
unsigned int mtu = neigh_node->if_incoming->net_dev->mtu;
|
||||||
|
unsigned int header_size = sizeof(frag_header);
|
||||||
|
- unsigned int max_fragment_size, max_packet_size;
|
||||||
|
+ unsigned int max_fragment_size, num_fragments;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* To avoid merge and refragmentation at next-hops we never send
|
||||||
|
@@ -464,10 +464,15 @@ int batadv_frag_send_packet(struct sk_buff *skb,
|
||||||
|
*/
|
||||||
|
mtu = min_t(unsigned int, mtu, BATADV_FRAG_MAX_FRAG_SIZE);
|
||||||
|
max_fragment_size = mtu - header_size;
|
||||||
|
- max_packet_size = max_fragment_size * BATADV_FRAG_MAX_FRAGMENTS;
|
||||||
|
+
|
||||||
|
+ if (skb->len == 0 || max_fragment_size == 0)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ num_fragments = (skb->len - 1) / max_fragment_size + 1;
|
||||||
|
+ max_fragment_size = (skb->len - 1) / num_fragments + 1;
|
||||||
|
|
||||||
|
/* Don't even try to fragment, if we need more than 16 fragments */
|
||||||
|
- if (skb->len > max_packet_size) {
|
||||||
|
+ if (num_fragments > BATADV_FRAG_MAX_FRAGMENTS) {
|
||||||
|
ret = -EAGAIN;
|
||||||
|
goto free_skb;
|
||||||
|
}
|
||||||
|
@@ -507,7 +512,8 @@ int batadv_frag_send_packet(struct sk_buff *skb,
|
||||||
|
goto put_primary_if;
|
||||||
|
}
|
||||||
|
|
||||||
|
- skb_fragment = batadv_frag_create(skb, &frag_header, mtu);
|
||||||
|
+ skb_fragment = batadv_frag_create(skb, &frag_header,
|
||||||
|
+ max_fragment_size);
|
||||||
|
if (!skb_fragment) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto put_primary_if;
|
|
@ -1,61 +0,0 @@
|
||||||
From: Sven Eckelmann <sven@narfation.org>
|
|
||||||
Date: Sun, 12 Feb 2017 11:26:33 +0100
|
|
||||||
Subject: [PATCH] batman-adv: Fix double free during fragment merge error
|
|
||||||
|
|
||||||
The function batadv_frag_skb_buffer was supposed not to consume the skbuff
|
|
||||||
on errors. This was followed in the helper function
|
|
||||||
batadv_frag_insert_packet when the skb would potentially be inserted in the
|
|
||||||
fragment queue. But it could happen that the next helper function
|
|
||||||
batadv_frag_merge_packets would try to merge the fragments and fail. This
|
|
||||||
results in a kfree_skb of all the enqueued fragments (including the just
|
|
||||||
inserted one). batadv_recv_frag_packet would detect the error in
|
|
||||||
batadv_frag_skb_buffer and try to free the skb again.
|
|
||||||
|
|
||||||
The behavior of batadv_frag_skb_buffer (and its helper
|
|
||||||
batadv_frag_insert_packet) must therefore be changed to always consume the
|
|
||||||
skbuff to have a common behavior and avoid the double kfree_skb.
|
|
||||||
|
|
||||||
Fixes: 9b3eab61754d ("batman-adv: Receive fragmented packets and merge")
|
|
||||||
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
|
||||||
|
|
||||||
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/e3bab02816097f860545d9ce9ae0808c69d7c92f
|
|
||||||
---
|
|
||||||
net/batman-adv/fragmentation.c | 8 +++++---
|
|
||||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
|
|
||||||
index 0854ebd8..31e97e9a 100644
|
|
||||||
--- a/net/batman-adv/fragmentation.c
|
|
||||||
+++ b/net/batman-adv/fragmentation.c
|
|
||||||
@@ -239,8 +239,10 @@ err_unlock:
|
|
||||||
spin_unlock_bh(&chain->lock);
|
|
||||||
|
|
||||||
err:
|
|
||||||
- if (!ret)
|
|
||||||
+ if (!ret) {
|
|
||||||
kfree(frag_entry_new);
|
|
||||||
+ kfree_skb(skb);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -313,7 +315,7 @@ free:
|
|
||||||
*
|
|
||||||
* There are three possible outcomes: 1) Packet is merged: Return true and
|
|
||||||
* set *skb to merged packet; 2) Packet is buffered: Return true and set *skb
|
|
||||||
- * to NULL; 3) Error: Return false and leave skb as is.
|
|
||||||
+ * to NULL; 3) Error: Return false and free skb.
|
|
||||||
*
|
|
||||||
* Return: true when packet is merged or buffered, false when skb is not not
|
|
||||||
* used.
|
|
||||||
@@ -338,9 +340,9 @@ bool batadv_frag_skb_buffer(struct sk_buff **skb,
|
|
||||||
goto out_err;
|
|
||||||
|
|
||||||
out:
|
|
||||||
- *skb = skb_out;
|
|
||||||
ret = true;
|
|
||||||
out_err:
|
|
||||||
+ *skb = skb_out;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Sat, 4 Mar 2017 15:48:50 +0100
|
||||||
|
Subject: [PATCH] batman-adv: Initialize gw sel_class via batadv_algo
|
||||||
|
|
||||||
|
The gateway selection class variable is shared between different algorithm
|
||||||
|
versions. But the interpretation of the content is algorithm specific. The
|
||||||
|
initialization is therefore also algorithm specific.
|
||||||
|
|
||||||
|
But this was implemented incorrectly and the initialization for BATMAN_V
|
||||||
|
always overwrote the value previously written for BATMAN_IV. This could
|
||||||
|
only be avoided when BATMAN_V was disabled during compile time.
|
||||||
|
|
||||||
|
Using a special batadv_algo hook for this initialization avoids this
|
||||||
|
problem.
|
||||||
|
|
||||||
|
Fixes: 80b2d47be2c7 ("batman-adv: B.A.T.M.A.N. V - implement GW selection logic")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
---
|
||||||
|
net/batman-adv/bat_iv_ogm.c | 11 +++++++++++
|
||||||
|
net/batman-adv/bat_v.c | 14 +++++++++++---
|
||||||
|
net/batman-adv/gateway_common.c | 5 +++++
|
||||||
|
net/batman-adv/soft-interface.c | 1 -
|
||||||
|
net/batman-adv/types.h | 2 ++
|
||||||
|
5 files changed, 29 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
|
||||||
|
index 7c3d994e..71343d0f 100644
|
||||||
|
--- a/net/batman-adv/bat_iv_ogm.c
|
||||||
|
+++ b/net/batman-adv/bat_iv_ogm.c
|
||||||
|
@@ -2477,6 +2477,16 @@ static void batadv_iv_iface_activate(struct batadv_hard_iface *hard_iface)
|
||||||
|
batadv_iv_ogm_schedule(hard_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * batadv_iv_init_sel_class - initialize GW selection class
|
||||||
|
+ * @bat_priv: the bat priv with all the soft interface information
|
||||||
|
+ */
|
||||||
|
+static void batadv_iv_init_sel_class(struct batadv_priv *bat_priv)
|
||||||
|
+{
|
||||||
|
+ /* set default TQ difference threshold to 20 */
|
||||||
|
+ atomic_set(&bat_priv->gw.sel_class, 20);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static struct batadv_gw_node *
|
||||||
|
batadv_iv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
|
||||||
|
{
|
||||||
|
@@ -2823,6 +2833,7 @@ static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
|
||||||
|
.del_if = batadv_iv_ogm_orig_del_if,
|
||||||
|
},
|
||||||
|
.gw = {
|
||||||
|
+ .init_sel_class = batadv_iv_init_sel_class,
|
||||||
|
.get_best_gw_node = batadv_iv_gw_get_best_gw_node,
|
||||||
|
.is_eligible = batadv_iv_gw_is_eligible,
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_DEBUGFS
|
||||||
|
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
|
||||||
|
index 0acd081d..a36c8e72 100644
|
||||||
|
--- a/net/batman-adv/bat_v.c
|
||||||
|
+++ b/net/batman-adv/bat_v.c
|
||||||
|
@@ -668,6 +668,16 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1,
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * batadv_v_init_sel_class - initialize GW selection class
|
||||||
|
+ * @bat_priv: the bat priv with all the soft interface information
|
||||||
|
+ */
|
||||||
|
+static void batadv_v_init_sel_class(struct batadv_priv *bat_priv)
|
||||||
|
+{
|
||||||
|
+ /* set default throughput difference threshold to 5Mbps */
|
||||||
|
+ atomic_set(&bat_priv->gw.sel_class, 50);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static ssize_t batadv_v_store_sel_class(struct batadv_priv *bat_priv,
|
||||||
|
char *buff, size_t count)
|
||||||
|
{
|
||||||
|
@@ -1052,6 +1062,7 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = {
|
||||||
|
.dump = batadv_v_orig_dump,
|
||||||
|
},
|
||||||
|
.gw = {
|
||||||
|
+ .init_sel_class = batadv_v_init_sel_class,
|
||||||
|
.store_sel_class = batadv_v_store_sel_class,
|
||||||
|
.show_sel_class = batadv_v_show_sel_class,
|
||||||
|
.get_best_gw_node = batadv_v_gw_get_best_gw_node,
|
||||||
|
@@ -1092,9 +1103,6 @@ int batadv_v_mesh_init(struct batadv_priv *bat_priv)
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
- /* set default throughput difference threshold to 5Mbps */
|
||||||
|
- atomic_set(&bat_priv->gw.sel_class, 50);
|
||||||
|
-
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c
|
||||||
|
index 5db2e43e..33940c5c 100644
|
||||||
|
--- a/net/batman-adv/gateway_common.c
|
||||||
|
+++ b/net/batman-adv/gateway_common.c
|
||||||
|
@@ -253,6 +253,11 @@ static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
|
||||||
|
*/
|
||||||
|
void batadv_gw_init(struct batadv_priv *bat_priv)
|
||||||
|
{
|
||||||
|
+ if (bat_priv->algo_ops->gw.init_sel_class)
|
||||||
|
+ bat_priv->algo_ops->gw.init_sel_class(bat_priv);
|
||||||
|
+ else
|
||||||
|
+ atomic_set(&bat_priv->gw.sel_class, 1);
|
||||||
|
+
|
||||||
|
batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1,
|
||||||
|
NULL, BATADV_TVLV_GW, 1,
|
||||||
|
BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
|
||||||
|
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
|
||||||
|
index 5d099b2e..d042c99a 100644
|
||||||
|
--- a/net/batman-adv/soft-interface.c
|
||||||
|
+++ b/net/batman-adv/soft-interface.c
|
||||||
|
@@ -819,7 +819,6 @@ static int batadv_softif_init_late(struct net_device *dev)
|
||||||
|
atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0);
|
||||||
|
#endif
|
||||||
|
atomic_set(&bat_priv->gw.mode, BATADV_GW_MODE_OFF);
|
||||||
|
- atomic_set(&bat_priv->gw.sel_class, 20);
|
||||||
|
atomic_set(&bat_priv->gw.bandwidth_down, 100);
|
||||||
|
atomic_set(&bat_priv->gw.bandwidth_up, 20);
|
||||||
|
atomic_set(&bat_priv->orig_interval, 1000);
|
||||||
|
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
|
||||||
|
index 66b25e41..246f21b4 100644
|
||||||
|
--- a/net/batman-adv/types.h
|
||||||
|
+++ b/net/batman-adv/types.h
|
||||||
|
@@ -1489,6 +1489,7 @@ struct batadv_algo_orig_ops {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct batadv_algo_gw_ops - mesh algorithm callbacks (GW specific)
|
||||||
|
+ * @init_sel_class: initialize GW selection class (optional)
|
||||||
|
* @store_sel_class: parse and stores a new GW selection class (optional)
|
||||||
|
* @show_sel_class: prints the current GW selection class (optional)
|
||||||
|
* @get_best_gw_node: select the best GW from the list of available nodes
|
||||||
|
@@ -1499,6 +1500,7 @@ struct batadv_algo_orig_ops {
|
||||||
|
* @dump: dump gateways to a netlink socket (optional)
|
||||||
|
*/
|
||||||
|
struct batadv_algo_gw_ops {
|
||||||
|
+ void (*init_sel_class)(struct batadv_priv *bat_priv);
|
||||||
|
ssize_t (*store_sel_class)(struct batadv_priv *bat_priv, char *buff,
|
||||||
|
size_t count);
|
||||||
|
ssize_t (*show_sel_class)(struct batadv_priv *bat_priv, char *buff);
|
|
@ -1,54 +0,0 @@
|
||||||
From: Linus Lüssing <linus.luessing@c0d3.blue>
|
|
||||||
Date: Mon, 13 Feb 2017 20:44:31 +0100
|
|
||||||
Subject: [PATCH] batman-adv: Fix transmission of final, 16th fragment
|
|
||||||
|
|
||||||
Trying to split and transmit a unicast packet in 16 parts will fail for
|
|
||||||
the final fragment: After having sent the 15th one with a frag_packet.no
|
|
||||||
index of 14, we will increase the the index to 15 - and return with an
|
|
||||||
error code immediately, even though one more fragment is due for
|
|
||||||
transmission and allowed.
|
|
||||||
|
|
||||||
Fixing this issue by moving the check before incrementing the index.
|
|
||||||
|
|
||||||
While at it, adding an unlikely(), because the check is actually more of
|
|
||||||
an assertion.
|
|
||||||
|
|
||||||
Fixes: db56e4ecf5c2 ("batman-adv: Fragment and send skbs larger than mtu")
|
|
||||||
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
|
||||||
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
|
||||||
|
|
||||||
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/464eff3b1768ff190466a453a57ac140ea5cb756
|
|
||||||
---
|
|
||||||
net/batman-adv/fragmentation.c | 12 ++++++------
|
|
||||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
|
|
||||||
index 31e97e9a..11149e5b 100644
|
|
||||||
--- a/net/batman-adv/fragmentation.c
|
|
||||||
+++ b/net/batman-adv/fragmentation.c
|
|
||||||
@@ -501,6 +501,12 @@ int batadv_frag_send_packet(struct sk_buff *skb,
|
|
||||||
|
|
||||||
/* Eat and send fragments from the tail of skb */
|
|
||||||
while (skb->len > max_fragment_size) {
|
|
||||||
+ /* The initial check in this function should cover this case */
|
|
||||||
+ if (unlikely(frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1)) {
|
|
||||||
+ ret = -EINVAL;
|
|
||||||
+ goto put_primary_if;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
skb_fragment = batadv_frag_create(skb, &frag_header, mtu);
|
|
||||||
if (!skb_fragment) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
@@ -517,12 +523,6 @@ int batadv_frag_send_packet(struct sk_buff *skb,
|
|
||||||
}
|
|
||||||
|
|
||||||
frag_header.no++;
|
|
||||||
-
|
|
||||||
- /* The initial check in this function should cover this case */
|
|
||||||
- if (frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1) {
|
|
||||||
- ret = -EINVAL;
|
|
||||||
- goto put_primary_if;
|
|
||||||
- }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make room for the fragment header. */
|
|
Loading…
Reference in a new issue