batman-adv: Merge bugfixes from 2018.0 350/head
authorSven Eckelmann <sven@narfation.org>
Tue, 27 Feb 2018 17:21:45 +0000 (18:21 +0100)
committerSven Eckelmann <sven@narfation.org>
Tue, 27 Feb 2018 17:23:20 +0000 (18:23 +0100)
* fix packet checksum in receive path
* invalidate checksum on fragment reassembly
* Ignore invalid batadv_iv_gw during netlink send
* Ignore invalid batadv_v_gw during netlink send
* Fix netlink dumping of BLA claims
* Fix netlink dumping of BLA backbones
* Fix internal interface indices types

Signed-off-by: Sven Eckelmann <sven@narfation.org>
batman-adv/patches/0024-batman-adv-fix-packet-checksum-in-receive-path.patch [new file with mode: 0644]
batman-adv/patches/0025-batman-adv-invalidate-checksum-on-fragment-reassembl.patch [new file with mode: 0644]
batman-adv/patches/0026-batman-adv-Ignore-invalid-batadv_iv_gw-during-netlin.patch [new file with mode: 0644]
batman-adv/patches/0027-batman-adv-Ignore-invalid-batadv_v_gw-during-netlink.patch [new file with mode: 0644]
batman-adv/patches/0028-batman-adv-Fix-netlink-dumping-of-BLA-claims.patch [new file with mode: 0644]
batman-adv/patches/0029-batman-adv-Fix-netlink-dumping-of-BLA-backbones.patch [new file with mode: 0644]
batman-adv/patches/0030-batman-adv-Fix-internal-interface-indices-types.patch [new file with mode: 0644]

diff --git a/batman-adv/patches/0024-batman-adv-fix-packet-checksum-in-receive-path.patch b/batman-adv/patches/0024-batman-adv-fix-packet-checksum-in-receive-path.patch
new file mode 100644 (file)
index 0000000..08f1219
--- /dev/null
@@ -0,0 +1,43 @@
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Tue, 23 Jan 2018 10:59:49 +0100
+Subject: [PATCH] batman-adv: fix packet checksum in receive path
+
+eth_type_trans() internally calls skb_pull(), which does not adjust the
+skb checksum; skb_postpull_rcsum() is necessary to avoid log spam of the
+form "bat0: hw csum failure" when packets with CHECKSUM_COMPLETE are
+received.
+
+Note that in usual setups, packets don't reach batman-adv with
+CHECKSUM_COMPLETE (I assume NICs bail out of checksumming when they see
+batadv's ethtype?), which is why the log messages do not occur on every
+system using batman-adv. I could reproduce this issue by stacking
+batman-adv on top of a VXLAN interface.
+
+Fixes: fe28a94c01e1 ("batman-adv: receive packets directly using skbs")
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/798174b15153afd88268f2f87811602f68b3f2c6
+---
+ net/batman-adv/soft-interface.c | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
+index 08432b14386a53c771c54b9eb38893d94c6f9b53..5da1a1c0f1efb5d95f31bc852b899f61e462feb1 100644
+--- a/net/batman-adv/soft-interface.c
++++ b/net/batman-adv/soft-interface.c
+@@ -470,13 +470,7 @@ void batadv_interface_rx(struct net_device *soft_iface,
+       /* skb->dev & skb->pkt_type are set here */
+       skb->protocol = eth_type_trans(skb, soft_iface);
+-
+-      /* should not be necessary anymore as we use skb_pull_rcsum()
+-       * TODO: please verify this and remove this TODO
+-       * -- Dec 21st 2009, Simon Wunderlich
+-       */
+-
+-      /* skb->ip_summed = CHECKSUM_UNNECESSARY; */
++      skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
+       batadv_inc_counter(bat_priv, BATADV_CNT_RX);
+       batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
diff --git a/batman-adv/patches/0025-batman-adv-invalidate-checksum-on-fragment-reassembl.patch b/batman-adv/patches/0025-batman-adv-invalidate-checksum-on-fragment-reassembl.patch
new file mode 100644 (file)
index 0000000..098715b
--- /dev/null
@@ -0,0 +1,39 @@
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Tue, 23 Jan 2018 10:59:50 +0100
+Subject: [PATCH] batman-adv: invalidate checksum on fragment reassembly
+
+A more sophisticated implementation could try to combine fragment checksums
+when all fragments have CHECKSUM_COMPLETE and are split at even offsets.
+For now, we just set ip_summed to CHECKSUM_NONE to avoid "hw csum failure"
+warnings in the kernel log when fragmented frames are received. In
+consequence, skb_pull_rcsum() can be replaced with skb_pull().
+
+Note that in usual setups, packets don't reach batman-adv with
+CHECKSUM_COMPLETE (I assume NICs bail out of checksumming when they see
+batadv's ethtype?), which is why the log messages do not occur on every
+system using batman-adv. I could reproduce this issue by stacking
+batman-adv on top of a VXLAN interface.
+
+Fixes: 9b3eab61754d ("batman-adv: Receive fragmented packets and merge")
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/2c1bce065baa688bc1eca4116f83ca3b790432a5
+---
+ net/batman-adv/fragmentation.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
+index 28f54887c975905d03372ab8ba5274fd82117651..5969d3705ec08a96438ecce06577d35291600753 100644
+--- a/net/batman-adv/fragmentation.c
++++ b/net/batman-adv/fragmentation.c
+@@ -287,7 +287,8 @@ batadv_frag_merge_packets(struct hlist_head *chain)
+       /* Move the existing MAC header to just before the payload. (Override
+        * the fragment header.)
+        */
+-      skb_pull_rcsum(skb_out, hdr_size);
++      skb_pull(skb_out, hdr_size);
++      skb_out->ip_summed = CHECKSUM_NONE;
+       memmove(skb_out->data - ETH_HLEN, skb_mac_header(skb_out), ETH_HLEN);
+       skb_set_mac_header(skb_out, -ETH_HLEN);
+       skb_reset_network_header(skb_out);
diff --git a/batman-adv/patches/0026-batman-adv-Ignore-invalid-batadv_iv_gw-during-netlin.patch b/batman-adv/patches/0026-batman-adv-Ignore-invalid-batadv_iv_gw-during-netlin.patch
new file mode 100644 (file)
index 0000000..0c8c31a
--- /dev/null
@@ -0,0 +1,33 @@
+From: Sven Eckelmann <sven.eckelmann@openmesh.com>
+Date: Mon, 19 Feb 2018 14:08:52 +0100
+Subject: [PATCH] batman-adv: Ignore invalid batadv_iv_gw during netlink send
+
+The function batadv_iv_gw_dump stops the processing loop when
+batadv_iv_gw_dump_entry returns a non-0 return code. This should only
+happen when the buffer is full. Otherwise, an empty message may be
+returned by batadv_gw_dump. This empty message will then stop the netlink
+dumping of gateway entries. At worst, not a single entry is returned to
+userspace even when plenty of possible gateways exist.
+
+Fixes: fa3228924152 ("batman-adv: add B.A.T.M.A.N. IV bat_gw_dump implementations")
+Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/c58f37c248bb4926cda82fd0463b6fecb3d3654f
+---
+ net/batman-adv/bat_iv_ogm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
+index 56b4984d738e87098c24213d4aa277a2ef948fec..1847898906d495980a71eb6a0e5a7b510e55d003 100644
+--- a/net/batman-adv/bat_iv_ogm.c
++++ b/net/batman-adv/bat_iv_ogm.c
+@@ -2719,7 +2719,7 @@ static int batadv_iv_gw_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
+       struct batadv_neigh_ifinfo *router_ifinfo = NULL;
+       struct batadv_neigh_node *router;
+       struct batadv_gw_node *curr_gw;
+-      int ret = -EINVAL;
++      int ret = 0;
+       void *hdr;
+       router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
diff --git a/batman-adv/patches/0027-batman-adv-Ignore-invalid-batadv_v_gw-during-netlink.patch b/batman-adv/patches/0027-batman-adv-Ignore-invalid-batadv_v_gw-during-netlink.patch
new file mode 100644 (file)
index 0000000..76428d6
--- /dev/null
@@ -0,0 +1,33 @@
+From: Sven Eckelmann <sven.eckelmann@openmesh.com>
+Date: Mon, 19 Feb 2018 14:08:53 +0100
+Subject: [PATCH] batman-adv: Ignore invalid batadv_v_gw during netlink send
+
+The function batadv_v_gw_dump stops the processing loop when
+batadv_v_gw_dump_entry returns a non-0 return code. This should only
+happen when the buffer is full. Otherwise, an empty message may be
+returned by batadv_gw_dump. This empty message will then stop the netlink
+dumping of gateway entries. At worst, not a single entry is returned to
+userspace even when plenty of possible gateways exist.
+
+Fixes: 15315a94ad98 ("batman-adv: add B.A.T.M.A.N. V bat_gw_dump implementations")
+Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/12f1d3a6bf4d157928fec509aab981e5243ee438
+---
+ net/batman-adv/bat_v.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
+index 2f77e112d4cb4db7b1086715a597ef995054fdc1..0488063ff6ac5985e27c3a0df41ab3566b48abb8 100644
+--- a/net/batman-adv/bat_v.c
++++ b/net/batman-adv/bat_v.c
+@@ -930,7 +930,7 @@ static int batadv_v_gw_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
+       struct batadv_neigh_ifinfo *router_ifinfo = NULL;
+       struct batadv_neigh_node *router;
+       struct batadv_gw_node *curr_gw;
+-      int ret = -EINVAL;
++      int ret = 0;
+       void *hdr;
+       router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
diff --git a/batman-adv/patches/0028-batman-adv-Fix-netlink-dumping-of-BLA-claims.patch b/batman-adv/patches/0028-batman-adv-Fix-netlink-dumping-of-BLA-claims.patch
new file mode 100644 (file)
index 0000000..953316e
--- /dev/null
@@ -0,0 +1,62 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sat, 24 Feb 2018 12:03:36 +0100
+Subject: [PATCH] batman-adv: Fix netlink dumping of BLA claims
+
+The function batadv_bla_claim_dump_bucket must be able to handle
+non-complete dumps of a single bucket. It tries to do that by saving the
+latest dumped index in *idx_skip to inform the caller about the current
+state.
+
+But the caller only assumes that buckets were not completely dumped when
+the return code is non-zero. This function must therefore also return a
+non-zero index when the dumping of an entry failed. Otherwise the caller
+will just skip all remaining buckets.
+
+And the function must also reset *idx_skip back to zero when it finished a
+bucket. Otherwise it will skip the same number of entries in the next
+bucket as the previous one had.
+
+Fixes: 3b7a63606020 ("batman-adv: add B.A.T.M.A.N. Dump BLA claims via netlink")
+Reported-by: Linus Lüssing <linus.luessing@c0d3.blue>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/49197c00f82cfcfeef963ef9367841d38a6ff207
+---
+ net/batman-adv/bridge_loop_avoidance.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
+index 1e6e5d4468ad50c221ea5a0d436678d16c5e154f..4784469cadd4364b6239ce9ff0d1c7cc254de439 100644
+--- a/net/batman-adv/bridge_loop_avoidance.c
++++ b/net/batman-adv/bridge_loop_avoidance.c
+@@ -2149,22 +2149,25 @@ batadv_bla_claim_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
+ {
+       struct batadv_bla_claim *claim;
+       int idx = 0;
++      int ret = 0;
+       rcu_read_lock();
+       hlist_for_each_entry_rcu(claim, head, hash_entry) {
+               if (idx++ < *idx_skip)
+                       continue;
+-              if (batadv_bla_claim_dump_entry(msg, portid, seq,
+-                                              primary_if, claim)) {
++
++              ret = batadv_bla_claim_dump_entry(msg, portid, seq,
++                                                primary_if, claim);
++              if (ret) {
+                       *idx_skip = idx - 1;
+                       goto unlock;
+               }
+       }
+-      *idx_skip = idx;
++      *idx_skip = 0;
+ unlock:
+       rcu_read_unlock();
+-      return 0;
++      return ret;
+ }
+ /**
diff --git a/batman-adv/patches/0029-batman-adv-Fix-netlink-dumping-of-BLA-backbones.patch b/batman-adv/patches/0029-batman-adv-Fix-netlink-dumping-of-BLA-backbones.patch
new file mode 100644 (file)
index 0000000..d41214a
--- /dev/null
@@ -0,0 +1,62 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sat, 24 Feb 2018 12:03:37 +0100
+Subject: [PATCH] batman-adv: Fix netlink dumping of BLA backbones
+
+The function batadv_bla_backbone_dump_bucket must be able to handle
+non-complete dumps of a single bucket. It tries to do that by saving the
+latest dumped index in *idx_skip to inform the caller about the current
+state.
+
+But the caller only assumes that buckets were not completely dumped when
+the return code is non-zero. This function must therefore also return a
+non-zero index when the dumping of an entry failed. Otherwise the caller
+will just skip all remaining buckets.
+
+And the function must also reset *idx_skip back to zero when it finished a
+bucket. Otherwise it will skip the same number of entries in the next
+bucket as the previous one had.
+
+Fixes: 7f609cab5123 ("batman-adv: add backbone table netlink support")
+Reported-by: Linus Lüssing <linus.luessing@c0d3.blue>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/29e4759e49f06014b84791397ebe1b22546edd2d
+---
+ net/batman-adv/bridge_loop_avoidance.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
+index 4784469cadd4364b6239ce9ff0d1c7cc254de439..aecf34503e95d9aa723449ddbf0bb3035336b878 100644
+--- a/net/batman-adv/bridge_loop_avoidance.c
++++ b/net/batman-adv/bridge_loop_avoidance.c
+@@ -2382,22 +2382,25 @@ batadv_bla_backbone_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
+ {
+       struct batadv_bla_backbone_gw *backbone_gw;
+       int idx = 0;
++      int ret = 0;
+       rcu_read_lock();
+       hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
+               if (idx++ < *idx_skip)
+                       continue;
+-              if (batadv_bla_backbone_dump_entry(msg, portid, seq,
+-                                                 primary_if, backbone_gw)) {
++
++              ret = batadv_bla_backbone_dump_entry(msg, portid, seq,
++                                                   primary_if, backbone_gw);
++              if (ret) {
+                       *idx_skip = idx - 1;
+                       goto unlock;
+               }
+       }
+-      *idx_skip = idx;
++      *idx_skip = 0;
+ unlock:
+       rcu_read_unlock();
+-      return 0;
++      return ret;
+ }
+ /**
diff --git a/batman-adv/patches/0030-batman-adv-Fix-internal-interface-indices-types.patch b/batman-adv/patches/0030-batman-adv-Fix-internal-interface-indices-types.patch
new file mode 100644 (file)
index 0000000..2e66586
--- /dev/null
@@ -0,0 +1,241 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Tue, 26 Dec 2017 15:14:01 +0100
+Subject: [PATCH] batman-adv: Fix internal interface indices types
+
+batman-adv uses internal indices for each enabled and active interface.
+It is currently used by the B.A.T.M.A.N. IV algorithm to identifify the
+correct position in the ogm_cnt bitmaps.
+
+The type for the number of enabled interfaces (which defines the next
+interface index) was set to char. This type can be (depending on the
+architecture) either signed (limiting batman-adv to 127 active slave
+interfaces) or unsigned (limiting batman-adv to 255 active slave
+interfaces).
+
+This limit was not correctly checked when an interface was enabled and thus
+an overflow happened. This was only catched on systems with the signed char
+type when the B.A.T.M.A.N. IV code tried to resize its counter arrays with
+a negative size.
+
+The if_num interface index was only a s16 and therefore significantly
+smaller than the ifindex (int) used by the code net code.
+
+Both &batadv_hard_iface->if_num and &batadv_priv->num_ifaces must be
+(unsigned) int to support the same number of slave interfaces as the net
+core code. And the interface activation code must check the number of
+active slave interfaces to avoid integer overflows.
+
+Fixes: d1fbb61d0534 ("raw socket operations added: create / destroy / bind / send broadcast of own OGMs implemented orig interval configurable via /proc/net/batman-adv/orig_interval")
+Fixes: ea6f8d42a595 ("batman-adv: move /proc interface handling to /sys")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+
+Origin: backport, https://git.open-mesh.org/batman-adv.git/commit/d5db560de1352d3ec6933bca25b3aaad7ddd15e1
+---
+ net/batman-adv/bat_iv_ogm.c     | 24 ++++++++++++++----------
+ net/batman-adv/hard-interface.c |  9 +++++++--
+ net/batman-adv/originator.c     |  4 ++--
+ net/batman-adv/originator.h     |  4 ++--
+ net/batman-adv/types.h          | 11 ++++++-----
+ 5 files changed, 31 insertions(+), 21 deletions(-)
+
+diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
+index 1847898906d495980a71eb6a0e5a7b510e55d003..bf389adbb2694746d6397a0a38353cdcd8008899 100644
+--- a/net/batman-adv/bat_iv_ogm.c
++++ b/net/batman-adv/bat_iv_ogm.c
+@@ -149,7 +149,7 @@ static void batadv_iv_ogm_orig_free(struct batadv_orig_node *orig_node)
+  * Return: 0 on success, a negative error code otherwise.
+  */
+ static int batadv_iv_ogm_orig_add_if(struct batadv_orig_node *orig_node,
+-                                   int max_if_num)
++                                   unsigned int max_if_num)
+ {
+       void *data_ptr;
+       size_t old_size;
+@@ -193,7 +193,8 @@ unlock:
+  */
+ static void
+ batadv_iv_ogm_drop_bcast_own_entry(struct batadv_orig_node *orig_node,
+-                                 int max_if_num, int del_if_num)
++                                 unsigned int max_if_num,
++                                 unsigned int del_if_num)
+ {
+       size_t chunk_size;
+       size_t if_offset;
+@@ -231,7 +232,8 @@ batadv_iv_ogm_drop_bcast_own_entry(struct batadv_orig_node *orig_node,
+  */
+ static void
+ batadv_iv_ogm_drop_bcast_own_sum_entry(struct batadv_orig_node *orig_node,
+-                                     int max_if_num, int del_if_num)
++                                     unsigned int max_if_num,
++                                     unsigned int del_if_num)
+ {
+       size_t if_offset;
+       void *data_ptr;
+@@ -268,7 +270,8 @@ batadv_iv_ogm_drop_bcast_own_sum_entry(struct batadv_orig_node *orig_node,
+  * Return: 0 on success, a negative error code otherwise.
+  */
+ static int batadv_iv_ogm_orig_del_if(struct batadv_orig_node *orig_node,
+-                                   int max_if_num, int del_if_num)
++                                   unsigned int max_if_num,
++                                   unsigned int del_if_num)
+ {
+       spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
+@@ -302,7 +305,8 @@ static struct batadv_orig_node *
+ batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const u8 *addr)
+ {
+       struct batadv_orig_node *orig_node;
+-      int size, hash_added;
++      int hash_added;
++      size_t size;
+       orig_node = batadv_orig_hash_find(bat_priv, addr);
+       if (orig_node)
+@@ -885,7 +889,7 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
+       u32 i;
+       size_t word_index;
+       u8 *w;
+-      int if_num;
++      unsigned int if_num;
+       for (i = 0; i < hash->size; i++) {
+               head = &hash->table[i];
+@@ -1015,7 +1019,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
+       struct batadv_neigh_node *tmp_neigh_node = NULL;
+       struct batadv_neigh_node *router = NULL;
+       struct batadv_orig_node *orig_node_tmp;
+-      int if_num;
++      unsigned int if_num;
+       u8 sum_orig, sum_neigh;
+       u8 *neigh_addr;
+       u8 tq_avg;
+@@ -1173,7 +1177,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
+       u8 total_count;
+       u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
+       unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
+-      int if_num;
++      unsigned int if_num;
+       unsigned int tq_asym_penalty, inv_asym_penalty;
+       unsigned int combined_tq;
+       unsigned int tq_iface_penalty;
+@@ -1692,9 +1696,9 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
+       if (is_my_orig) {
+               unsigned long *word;
+-              int offset;
++              size_t offset;
+               s32 bit_pos;
+-              s16 if_num;
++              unsigned int if_num;
+               u8 *weight;
+               orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
+diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
+index 6969f580d0bfd0428f1c6985eaec8bbbf5a0d38b..ebeea5816a06b33c4944b01e40cee157c88bdff7 100644
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -741,6 +741,11 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
+       hard_iface->soft_iface = soft_iface;
+       bat_priv = netdev_priv(hard_iface->soft_iface);
++      if (bat_priv->num_ifaces >= UINT_MAX) {
++              ret = -ENOSPC;
++              goto err_dev;
++      }
++
+       ret = netdev_master_upper_dev_link(hard_iface->net_dev,
+                                          soft_iface, NULL, NULL);
+       if (ret)
+@@ -848,7 +853,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
+       batadv_hardif_recalc_extra_skbroom(hard_iface->soft_iface);
+       /* nobody uses this interface anymore */
+-      if (!bat_priv->num_ifaces) {
++      if (bat_priv->num_ifaces == 0) {
+               batadv_gw_check_client_stop(bat_priv);
+               if (autodel == BATADV_IF_CLEANUP_AUTO)
+@@ -884,7 +889,7 @@ batadv_hardif_add_interface(struct net_device *net_dev)
+       if (ret)
+               goto free_if;
+-      hard_iface->if_num = -1;
++      hard_iface->if_num = 0;
+       hard_iface->net_dev = net_dev;
+       hard_iface->soft_iface = NULL;
+       hard_iface->if_status = BATADV_IF_NOT_IN_USE;
+diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
+index 8f3b2969cc4e3044e714086329166b9a3b7517a4..d9ee84340d93bd03f1de504f7223c7f894818906 100644
+--- a/net/batman-adv/originator.c
++++ b/net/batman-adv/originator.c
+@@ -1500,7 +1500,7 @@ int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb)
+ }
+ int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
+-                          int max_if_num)
++                          unsigned int max_if_num)
+ {
+       struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+       struct batadv_algo_ops *bao = bat_priv->algo_ops;
+@@ -1535,7 +1535,7 @@ err:
+ }
+ int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
+-                          int max_if_num)
++                          unsigned int max_if_num)
+ {
+       struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+       struct batadv_hashtable *hash = bat_priv->orig_hash;
+diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h
+index ebc56183f3581835c899272425a212ff092033b6..fab0b2cc141d9affdbcf68f1d0ce7aad753c3857 100644
+--- a/net/batman-adv/originator.h
++++ b/net/batman-adv/originator.h
+@@ -78,9 +78,9 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset);
+ int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb);
+ int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset);
+ int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
+-                          int max_if_num);
++                          unsigned int max_if_num);
+ int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
+-                          int max_if_num);
++                          unsigned int max_if_num);
+ struct batadv_orig_node_vlan *
+ batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
+                         unsigned short vid);
+diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
+index 7c928938b22dcae681294700252c0ae74378f999..bf1d3f0258ffb2fb8ee483337012798b20462cd6 100644
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -155,7 +155,7 @@ enum batadv_hard_iface_wifi_flags {
+  */
+ struct batadv_hard_iface {
+       struct list_head list;
+-      s16 if_num;
++      unsigned int if_num;
+       char if_status;
+       u8 num_bcasts;
+       u32 wifi_flags;
+@@ -1081,7 +1081,7 @@ struct batadv_priv {
+       atomic_t bcast_seqno;
+       atomic_t bcast_queue_left;
+       atomic_t batman_queue_left;
+-      char num_ifaces;
++      unsigned int num_ifaces;
+       struct kobject *mesh_obj;
+       struct dentry *debug_dir;
+       struct hlist_head forw_bat_list;
+@@ -1477,9 +1477,10 @@ struct batadv_algo_neigh_ops {
+  */
+ struct batadv_algo_orig_ops {
+       void (*free)(struct batadv_orig_node *orig_node);
+-      int (*add_if)(struct batadv_orig_node *orig_node, int max_if_num);
+-      int (*del_if)(struct batadv_orig_node *orig_node, int max_if_num,
+-                    int del_if_num);
++      int (*add_if)(struct batadv_orig_node *orig_node,
++                    unsigned int max_if_num);
++      int (*del_if)(struct batadv_orig_node *orig_node,
++                    unsigned int max_if_num, unsigned int del_if_num);
+ #ifdef CONFIG_BATMAN_ADV_DEBUGFS
+       void (*print)(struct batadv_priv *priv, struct seq_file *seq,
+                     struct batadv_hard_iface *hard_iface);