From: Simon Wunderlich Date: Sun, 5 Mar 2017 16:49:46 +0000 (+0100) Subject: Merge pull request #282 from ecsv/batadv-2017.0 X-Git-Url: http://git.openwrt.org/?p=feed%2Frouting.git;a=commitdiff_plain;h=a881d5d4a6c4d0a5d9c515525eb83774516d038c;hp=c1b0d8e36f581e227ea5b021224659b2cfa9c689 Merge pull request #282 from ecsv/batadv-2017.0 batman-adv 2017.0 --- diff --git a/alfred/Makefile b/alfred/Makefile index 379c0fe..8b2d9e3 100644 --- a/alfred/Makefile +++ b/alfred/Makefile @@ -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 # PKG_NAME:=alfred -PKG_VERSION:=2016.5 +PKG_VERSION:=2017.0 PKG_RELEASE:=0 -PKG_MD5SUM:=e03d422ed3b5a162b90e8af13389523f -PKG_HASH:=37b3babf7f37643cf296be11fb82d5730cf441a5a56f72fba96edae9f149c9d2 +PKG_MD5SUM:=2e9ae897b1d477f14d06389eb7c1f97b +PKG_HASH:=f8d6d83d2ce30b2238354ce12073285387c0f4ca1a28060390ff50b411b50fa8 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION) diff --git a/batctl/Makefile b/batctl/Makefile index 24bd16b..819d42b 100644 --- a/batctl/Makefile +++ b/batctl/Makefile @@ -9,10 +9,10 @@ include $(TOPDIR)/rules.mk PKG_NAME:=batctl -PKG_VERSION:=2016.5 +PKG_VERSION:=2017.0 PKG_RELEASE:=0 -PKG_MD5SUM:=7b33fb47c7fa5b317e9a152a286999fc -PKG_HASH:=07edeb1d87a548285be8c499542790a158fc8d94ef7ebb295f27ebf710024ae9 +PKG_MD5SUM:=17c0ac0746f1994ddacc88ebf48e5aec +PKG_HASH:=c0bb1127d6070b46abeb8d6a63d1150d71fa85f87f9a846873b649a21934c686 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION) diff --git a/batman-adv/Makefile b/batman-adv/Makefile index d3e916e..0ba7310 100644 --- a/batman-adv/Makefile +++ b/batman-adv/Makefile @@ -10,10 +10,10 @@ include $(TOPDIR)/rules.mk PKG_NAME:=batman-adv -PKG_VERSION:=2016.5 -PKG_RELEASE:=4 -PKG_MD5SUM:=6717a933a08dd2a01b00df30cb9f16a8 -PKG_HASH:=d0a0fc90c4f410b57d043215e253bb0b855efa5edbe165d87c17bfdcfafd0db7 +PKG_VERSION:=2017.0 +PKG_RELEASE:=0 +PKG_MD5SUM:=1b3121f0baa8771ff6d8ad172c95904f +PKG_HASH:=65df01222bc51ec788fb1b6dc63feaf69d393f2d0a96e347d55de83b1602c509 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION) diff --git a/batman-adv/files/compat-hacks.h b/batman-adv/files/compat-hacks.h index af91f41..8c8a889 100644 --- a/batman-adv/files/compat-hacks.h +++ b/batman-adv/files/compat-hacks.h @@ -33,6 +33,15 @@ #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) 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 #endif /* < KERNEL_VERSION(4, 10, 0) */ + +/* */ + +#include +#include_next + +#include + +#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); \ + } + +/* */ diff --git a/batman-adv/patches/0001-Add-compat-fallback-for-batadv_getlink_net.patch b/batman-adv/patches/0001-Add-compat-fallback-for-batadv_getlink_net.patch deleted file mode 100644 index c641828..0000000 --- a/batman-adv/patches/0001-Add-compat-fallback-for-batadv_getlink_net.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Sven Eckelmann -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 - } - - /** diff --git a/batman-adv/patches/0001-batman-adv-average-change-to-declare-precision-not-f.patch b/batman-adv/patches/0001-batman-adv-average-change-to-declare-precision-not-f.patch new file mode 100644 index 0000000..c2f9467 --- /dev/null +++ b/batman-adv/patches/0001-batman-adv-average-change-to-declare-precision-not-f.patch @@ -0,0 +1,132 @@ +From: Johannes Berg +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 +Signed-off-by: Johannes Berg +[sven@narfation.org: Added compatibility code] +Signed-off-by: Sven Eckelmann +--- + 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 + +-#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 diff --git a/batman-adv/patches/0002-batman-adv-Decrease-hardif-refcnt-on-fragmentation-s.patch b/batman-adv/patches/0002-batman-adv-Decrease-hardif-refcnt-on-fragmentation-s.patch deleted file mode 100644 index 92da394..0000000 --- a/batman-adv/patches/0002-batman-adv-Decrease-hardif-refcnt-on-fragmentation-s.patch +++ /dev/null @@ -1,63 +0,0 @@ -From: Sven Eckelmann -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 -Signed-off-by: Simon Wunderlich ---- - 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); diff --git a/batman-adv/patches/0002-batman-adv-Keep-fragments-equally-sized.patch b/batman-adv/patches/0002-batman-adv-Keep-fragments-equally-sized.patch new file mode 100644 index 0000000..3286cf3 --- /dev/null +++ b/batman-adv/patches/0002-batman-adv-Keep-fragments-equally-sized.patch @@ -0,0 +1,103 @@ +From: Sven Eckelmann +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 +Fixes: db56e4ecf5c2 ("batman-adv: Fragment and send skbs larger than mtu") +Signed-off-by: Sven Eckelmann +Acked-by: Linus Lüssing +--- + 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; diff --git a/batman-adv/patches/0003-batman-adv-Fix-double-free-during-fragment-merge-err.patch b/batman-adv/patches/0003-batman-adv-Fix-double-free-during-fragment-merge-err.patch deleted file mode 100644 index f4baf46..0000000 --- a/batman-adv/patches/0003-batman-adv-Fix-double-free-during-fragment-merge-err.patch +++ /dev/null @@ -1,61 +0,0 @@ -From: Sven Eckelmann -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 - -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; - } - diff --git a/batman-adv/patches/0003-batman-adv-Initialize-gw-sel_class-via-batadv_algo.patch b/batman-adv/patches/0003-batman-adv-Initialize-gw-sel_class-via-batadv_algo.patch new file mode 100644 index 0000000..f65ac45 --- /dev/null +++ b/batman-adv/patches/0003-batman-adv-Initialize-gw-sel_class-via-batadv_algo.patch @@ -0,0 +1,141 @@ +From: Sven Eckelmann +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 +--- + 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); diff --git a/batman-adv/patches/0004-batman-adv-Fix-transmission-of-final-16th-fragment.patch b/batman-adv/patches/0004-batman-adv-Fix-transmission-of-final-16th-fragment.patch deleted file mode 100644 index 6dec0f6..0000000 --- a/batman-adv/patches/0004-batman-adv-Fix-transmission-of-final-16th-fragment.patch +++ /dev/null @@ -1,54 +0,0 @@ -From: Linus Lüssing -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 -Signed-off-by: Sven Eckelmann - -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. */