batman-adv: 2014.1.0 bugfixes & stability updates
authorMarek Lindner <mareklindner@neomailbox.ch>
Mon, 31 Mar 2014 13:00:08 +0000 (21:00 +0800)
committerMarek Lindner <mareklindner@neomailbox.ch>
Mon, 31 Mar 2014 13:00:08 +0000 (21:00 +0800)
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
batman-adv/Makefile
batman-adv/patches/0001-batman-adv-fix-neigh_ifinfo-imbalance.patch [new file with mode: 0644]
batman-adv/patches/0002-batman-adv-fix-neigh-reference-imbalance.patch [new file with mode: 0644]
batman-adv/patches/0003-batman-adv-always-run-purge_orig_neighbors.patch [new file with mode: 0644]
batman-adv/patches/0004-batman-adv-fix-removing-neigh_ifinfo.patch [new file with mode: 0644]
batman-adv/patches/0005-batman-adv-fix-local-TT-check-for-outgoing-arp-reque.patch [new file with mode: 0644]
batman-adv/patches/0006-batman-adv-change-the-MAC-of-each-VLAN-upon-ndo_set_.patch [new file with mode: 0644]

index d613e91780ba20996732750fee025debbd87b8d4..b9c998608e73c4b180ddc04b14dc9728e3551c29 100644 (file)
@@ -12,7 +12,7 @@ PKG_NAME:=batman-adv
 
 PKG_VERSION:=2014.1.0
 BATCTL_VERSION:=2014.1.0
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 PKG_MD5SUM:=d55aabb2bc508194407187648c773c1b
 BATCTL_MD5SUM:=92fd4cb60e38ec952fb5fdda4b2e6933
 
diff --git a/batman-adv/patches/0001-batman-adv-fix-neigh_ifinfo-imbalance.patch b/batman-adv/patches/0001-batman-adv-fix-neigh_ifinfo-imbalance.patch
new file mode 100644 (file)
index 0000000..eec3497
--- /dev/null
@@ -0,0 +1,35 @@
+From a424cd5a2c956ef1f0353d7e5f2b7fbc4af7d2d8 Mon Sep 17 00:00:00 2001
+From: Simon Wunderlich <simon@open-mesh.com>
+Date: Wed, 26 Mar 2014 15:46:21 +0100
+Subject: [PATCH 1/6] batman-adv: fix neigh_ifinfo imbalance
+
+The neigh_ifinfo object must be freed if it has been used in
+batadv_iv_ogm_process_per_outif().
+
+This is a regression introduced by
+9bb33b8d88e318c4879d37d06ad28e3e018b9036 ("batman-adv: split tq
+information in neigh_node struct")
+
+Reported-by: Antonio Quartulli <antonio@open-mesh.com>
+Signed-off-by: Simon Wunderlich <simon@open-mesh.com>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+---
+ bat_iv_ogm.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c
+index 8323bce..d074d06 100644
+--- a/bat_iv_ogm.c
++++ b/bat_iv_ogm.c
+@@ -1545,6 +1545,8 @@ out_neigh:
+       if ((orig_neigh_node) && (!is_single_hop_neigh))
+               batadv_orig_node_free_ref(orig_neigh_node);
+ out:
++      if (router_ifinfo)
++              batadv_neigh_ifinfo_free_ref(router_ifinfo);
+       if (router)
+               batadv_neigh_node_free_ref(router);
+       if (router_router)
+-- 
+1.9.0
+
diff --git a/batman-adv/patches/0002-batman-adv-fix-neigh-reference-imbalance.patch b/batman-adv/patches/0002-batman-adv-fix-neigh-reference-imbalance.patch
new file mode 100644 (file)
index 0000000..edb90ab
--- /dev/null
@@ -0,0 +1,47 @@
+From cdd09f69871ce8c98b8ae9fa0583f73938768943 Mon Sep 17 00:00:00 2001
+From: Simon Wunderlich <simon@open-mesh.com>
+Date: Wed, 26 Mar 2014 15:46:22 +0100
+Subject: [PATCH 2/6] batman-adv: fix neigh reference imbalance
+
+When an interface is removed from batman-adv, the orig_ifinfo of a
+orig_node may be removed without releasing the router first.
+This will prevent the reference for the neighbor pointed at by the
+orig_ifinfo->router to be released, and this leak may result in
+reference leaks for the interface used by this neighbor. Fix that.
+
+This is a regression introduced by
+de6bcc76ea84fecb136f8c8f5ba1862e4a13f06b ("batman-adv: split out router
+from orig_node").
+
+Reported-by: Antonio Quartulli <antonio@open-mesh.com>
+Signed-off-by: Simon Wunderlich <simon@open-mesh.com>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+---
+ originator.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/originator.c b/originator.c
+index 8539416..25df60d 100644
+--- a/originator.c
++++ b/originator.c
+@@ -500,12 +500,17 @@ batadv_neigh_node_get(const struct batadv_orig_node *orig_node,
+ static void batadv_orig_ifinfo_free_rcu(struct rcu_head *rcu)
+ {
+       struct batadv_orig_ifinfo *orig_ifinfo;
++      struct batadv_neigh_node *router;
+       orig_ifinfo = container_of(rcu, struct batadv_orig_ifinfo, rcu);
+       if (orig_ifinfo->if_outgoing != BATADV_IF_DEFAULT)
+               batadv_hardif_free_ref_now(orig_ifinfo->if_outgoing);
++      /* this is the last reference to this object */
++      router = rcu_dereference_protected(orig_ifinfo->router, true);
++      if (router)
++              batadv_neigh_node_free_ref_now(router);
+       kfree(orig_ifinfo);
+ }
+-- 
+1.9.0
+
diff --git a/batman-adv/patches/0003-batman-adv-always-run-purge_orig_neighbors.patch b/batman-adv/patches/0003-batman-adv-always-run-purge_orig_neighbors.patch
new file mode 100644 (file)
index 0000000..5add063
--- /dev/null
@@ -0,0 +1,49 @@
+From 72125152cc46e55793329984428032769648904e Mon Sep 17 00:00:00 2001
+From: Simon Wunderlich <simon@open-mesh.com>
+Date: Wed, 26 Mar 2014 15:46:23 +0100
+Subject: [PATCH 3/6] batman-adv: always run purge_orig_neighbors
+
+The current code will not execute batadv_purge_orig_neighbors() when an
+orig_ifinfo has already been purged. However we need to run it in any
+case. Fix that.
+
+This is a regression introduced by
+de6bcc76ea84fecb136f8c8f5ba1862e4a13f06b ("batman-adv: split out router
+from orig_node")
+
+Signed-off-by: Simon Wunderlich <simon@open-mesh.com>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+---
+ originator.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/originator.c b/originator.c
+index 25df60d..47b0886 100644
+--- a/originator.c
++++ b/originator.c
+@@ -857,7 +857,7 @@ static bool batadv_purge_orig_node(struct batadv_priv *bat_priv,
+ {
+       struct batadv_neigh_node *best_neigh_node;
+       struct batadv_hard_iface *hard_iface;
+-      bool changed;
++      bool changed_ifinfo, changed_neigh;
+       if (batadv_has_timed_out(orig_node->last_seen,
+                                2 * BATADV_PURGE_TIMEOUT)) {
+@@ -867,10 +867,10 @@ static bool batadv_purge_orig_node(struct batadv_priv *bat_priv,
+                          jiffies_to_msecs(orig_node->last_seen));
+               return true;
+       }
+-      changed = batadv_purge_orig_ifinfo(bat_priv, orig_node);
+-      changed = changed || batadv_purge_orig_neighbors(bat_priv, orig_node);
++      changed_ifinfo = batadv_purge_orig_ifinfo(bat_priv, orig_node);
++      changed_neigh = batadv_purge_orig_neighbors(bat_priv, orig_node);
+-      if (!changed)
++      if (!changed_ifinfo && !changed_neigh)
+               return false;
+       /* first for NULL ... */
+-- 
+1.9.0
+
diff --git a/batman-adv/patches/0004-batman-adv-fix-removing-neigh_ifinfo.patch b/batman-adv/patches/0004-batman-adv-fix-removing-neigh_ifinfo.patch
new file mode 100644 (file)
index 0000000..70deebb
--- /dev/null
@@ -0,0 +1,88 @@
+From 9b9cdbe28e2b9c8bdf9c761f22ba9655963d13d4 Mon Sep 17 00:00:00 2001
+From: Simon Wunderlich <simon@open-mesh.com>
+Date: Wed, 26 Mar 2014 15:46:24 +0100
+Subject: [PATCH 4/6] batman-adv: fix removing neigh_ifinfo
+
+When an interface is removed separately, all neighbors need to be
+checked if they have a neigh_ifinfo structure for that particular
+interface. If that is the case, remove that ifinfo so any references to
+a hard interface can be freed.
+
+This is a regression introduced by
+9bb33b8d88e318c4879d37d06ad28e3e018b9036 ("batman-adv: split tq
+information in neigh_node struct")
+
+Reported-by: Antonio Quartulli <antonio@open-mesh.com>
+Signed-off-by: Simon Wunderlich <simon@open-mesh.com>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+---
+ originator.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+
+diff --git a/originator.c b/originator.c
+index 47b0886..aa2468b 100644
+--- a/originator.c
++++ b/originator.c
+@@ -702,6 +702,47 @@ free_orig_node:
+ }
+ /**
++ * batadv_purge_neigh_ifinfo - purge obsolete ifinfo entries from neighbor
++ * @bat_priv: the bat priv with all the soft interface information
++ * @neigh_node: orig node which is to be checked
++ */
++static void
++batadv_purge_neigh_ifinfo(struct batadv_priv *bat_priv,
++                        struct batadv_neigh_node *neigh)
++{
++      struct batadv_neigh_ifinfo *neigh_ifinfo;
++      struct batadv_hard_iface *if_outgoing;
++      struct hlist_node *node_tmp;
++
++      spin_lock_bh(&neigh->ifinfo_lock);
++
++      /* for all ifinfo objects for this neighinator */
++      hlist_for_each_entry_safe(neigh_ifinfo, node_tmp,
++                                &neigh->ifinfo_list, list) {
++              if_outgoing = neigh_ifinfo->if_outgoing;
++
++              /* always keep the default interface */
++              if (if_outgoing == BATADV_IF_DEFAULT)
++                      continue;
++
++              /* don't purge if the interface is not (going) down */
++              if ((if_outgoing->if_status != BATADV_IF_INACTIVE) &&
++                  (if_outgoing->if_status != BATADV_IF_NOT_IN_USE) &&
++                  (if_outgoing->if_status != BATADV_IF_TO_BE_REMOVED))
++                      continue;
++
++              batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
++                         "neighbor/ifinfo purge: neighbor %pM, iface: %s\n",
++                         neigh->addr, if_outgoing->net_dev->name);
++
++              hlist_del_rcu(&neigh_ifinfo->list);
++              batadv_neigh_ifinfo_free_ref(neigh_ifinfo);
++      }
++
++      spin_unlock_bh(&neigh->ifinfo_lock);
++}
++
++/**
+  * batadv_purge_orig_ifinfo - purge obsolete ifinfo entries from originator
+  * @bat_priv: the bat priv with all the soft interface information
+  * @orig_node: orig node which is to be checked
+@@ -800,6 +841,11 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
+                       hlist_del_rcu(&neigh_node->list);
+                       batadv_neigh_node_free_ref(neigh_node);
++              } else {
++                      /* only neccesary if not the whole neighbor is to be deleted,
++                       * but some interface has been removed.
++                       */
++                      batadv_purge_neigh_ifinfo(bat_priv, neigh_node);
+               }
+       }
+-- 
+1.9.0
+
diff --git a/batman-adv/patches/0005-batman-adv-fix-local-TT-check-for-outgoing-arp-reque.patch b/batman-adv/patches/0005-batman-adv-fix-local-TT-check-for-outgoing-arp-reque.patch
new file mode 100644 (file)
index 0000000..dfaffde
--- /dev/null
@@ -0,0 +1,44 @@
+From 1c2e700fa93e6de3a2ae3725cf437504683b894a Mon Sep 17 00:00:00 2001
+From: Antonio Quartulli <antonio@open-mesh.com>
+Date: Sat, 29 Mar 2014 17:27:38 +0100
+Subject: [PATCH 5/6] batman-adv: fix local TT check for outgoing arp requests
+ in DAT
+
+Change introduced by d6bd8b36fa1f3d72a6fd5942a6e9bde6ddafcd0d
+("batman-adv: make DAT drop ARP requests targeting local clients")
+implements a check that prevents DAT from using the caching
+mechanism when the client that is supposed to provide a reply
+to an arp request is local.
+
+However change brought by 3e26722bc9f248ec4316749fc1957365c0fa5e4b
+("batman-adv: make the Distributed ARP Table vlan aware")
+has not converted the above check into its vlan aware version
+thus making it useless when the local client is behind a vlan.
+
+Fix the behaviour by properly specifying the vlan when
+checking for a client being local or not.
+
+Reported-by: Simon Wunderlich <simon@open-mesh.com>
+Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+---
+ distributed-arp-table.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/distributed-arp-table.c b/distributed-arp-table.c
+index 5bb37a8..a5d75be 100644
+--- a/distributed-arp-table.c
++++ b/distributed-arp-table.c
+@@ -940,8 +940,7 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
+                * 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,
+-                                      BATADV_NO_FLAGS)) {
++              if (batadv_is_my_client(bat_priv, dat_entry->mac_addr, vid)) {
+                       ret = true;
+                       goto out;
+               }
+-- 
+1.9.0
+
diff --git a/batman-adv/patches/0006-batman-adv-change-the-MAC-of-each-VLAN-upon-ndo_set_.patch b/batman-adv/patches/0006-batman-adv-change-the-MAC-of-each-VLAN-upon-ndo_set_.patch
new file mode 100644 (file)
index 0000000..216f212
--- /dev/null
@@ -0,0 +1,54 @@
+From 31f391475cc08724e96ab060ef4aa6503d11da8e Mon Sep 17 00:00:00 2001
+From: Antonio Quartulli <antonio@open-mesh.com>
+Date: Mon, 31 Mar 2014 13:48:10 +0200
+Subject: [PATCH 6/6] batman-adv: change the MAC of each VLAN upon
+ ndo_set_mac_address
+
+The MAC address of the soft-interface is used to initialise
+the "non-purge" TT entry of each existing VLAN. Therefore
+when the user invokes ndo_set_mac_address() all the
+"non-purge" TT entries have to be updated, not only the one
+belonging to the non-tagged network.
+
+Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+---
+ soft-interface.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/soft-interface.c b/soft-interface.c
+index f82c267..d962363 100644
+--- a/soft-interface.c
++++ b/soft-interface.c
+@@ -105,6 +105,7 @@ static struct net_device_stats *batadv_interface_stats(struct net_device *dev)
+ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
+ {
+       struct batadv_priv *bat_priv = netdev_priv(dev);
++      struct batadv_softif_vlan *vlan;
+       struct sockaddr *addr = p;
+       uint8_t old_addr[ETH_ALEN];
+@@ -115,12 +116,17 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
+       memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+       /* only modify transtable if it has been initialized before */
+-      if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) {
+-              batadv_tt_local_remove(bat_priv, old_addr, BATADV_NO_FLAGS,
++      if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
++              return 0;
++
++      rcu_read_lock();
++      hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
++              batadv_tt_local_remove(bat_priv, old_addr, vlan->vid,
+                                      "mac address changed", false);
+-              batadv_tt_local_add(dev, addr->sa_data, BATADV_NO_FLAGS,
++              batadv_tt_local_add(dev, addr->sa_data, vlan->vid,
+                                   BATADV_NULL_IFINDEX, BATADV_NO_MARK);
+       }
++      rcu_read_unlock();
+       return 0;
+ }
+-- 
+1.9.0
+