From b905f3f159695ebb928e2b32b54fcc164a9aa40d Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Mon, 31 Mar 2014 21:00:08 +0800 Subject: [PATCH] batman-adv: 2014.1.0 bugfixes & stability updates Signed-off-by: Marek Lindner --- batman-adv/Makefile | 2 +- ...atman-adv-fix-neigh_ifinfo-imbalance.patch | 35 ++++++++ ...an-adv-fix-neigh-reference-imbalance.patch | 47 ++++++++++ ...-adv-always-run-purge_orig_neighbors.patch | 49 +++++++++++ ...batman-adv-fix-removing-neigh_ifinfo.patch | 88 +++++++++++++++++++ ...ocal-TT-check-for-outgoing-arp-reque.patch | 44 ++++++++++ ...e-the-MAC-of-each-VLAN-upon-ndo_set_.patch | 54 ++++++++++++ 7 files changed, 318 insertions(+), 1 deletion(-) create mode 100644 batman-adv/patches/0001-batman-adv-fix-neigh_ifinfo-imbalance.patch create mode 100644 batman-adv/patches/0002-batman-adv-fix-neigh-reference-imbalance.patch create mode 100644 batman-adv/patches/0003-batman-adv-always-run-purge_orig_neighbors.patch create mode 100644 batman-adv/patches/0004-batman-adv-fix-removing-neigh_ifinfo.patch create mode 100644 batman-adv/patches/0005-batman-adv-fix-local-TT-check-for-outgoing-arp-reque.patch create mode 100644 batman-adv/patches/0006-batman-adv-change-the-MAC-of-each-VLAN-upon-ndo_set_.patch diff --git a/batman-adv/Makefile b/batman-adv/Makefile index d613e91..b9c9986 100644 --- a/batman-adv/Makefile +++ b/batman-adv/Makefile @@ -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 index 0000000..eec3497 --- /dev/null +++ b/batman-adv/patches/0001-batman-adv-fix-neigh_ifinfo-imbalance.patch @@ -0,0 +1,35 @@ +From a424cd5a2c956ef1f0353d7e5f2b7fbc4af7d2d8 Mon Sep 17 00:00:00 2001 +From: Simon Wunderlich +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 +Signed-off-by: Simon Wunderlich +Signed-off-by: Marek Lindner +--- + 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 index 0000000..edb90ab --- /dev/null +++ b/batman-adv/patches/0002-batman-adv-fix-neigh-reference-imbalance.patch @@ -0,0 +1,47 @@ +From cdd09f69871ce8c98b8ae9fa0583f73938768943 Mon Sep 17 00:00:00 2001 +From: Simon Wunderlich +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 +Signed-off-by: Simon Wunderlich +Signed-off-by: Marek Lindner +--- + 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 index 0000000..5add063 --- /dev/null +++ b/batman-adv/patches/0003-batman-adv-always-run-purge_orig_neighbors.patch @@ -0,0 +1,49 @@ +From 72125152cc46e55793329984428032769648904e Mon Sep 17 00:00:00 2001 +From: Simon Wunderlich +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 +Signed-off-by: Marek Lindner +--- + 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 index 0000000..70deebb --- /dev/null +++ b/batman-adv/patches/0004-batman-adv-fix-removing-neigh_ifinfo.patch @@ -0,0 +1,88 @@ +From 9b9cdbe28e2b9c8bdf9c761f22ba9655963d13d4 Mon Sep 17 00:00:00 2001 +From: Simon Wunderlich +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 +Signed-off-by: Simon Wunderlich +Signed-off-by: Marek Lindner +--- + 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 index 0000000..dfaffde --- /dev/null +++ b/batman-adv/patches/0005-batman-adv-fix-local-TT-check-for-outgoing-arp-reque.patch @@ -0,0 +1,44 @@ +From 1c2e700fa93e6de3a2ae3725cf437504683b894a Mon Sep 17 00:00:00 2001 +From: Antonio Quartulli +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 +Signed-off-by: Antonio Quartulli +Signed-off-by: Marek Lindner +--- + 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 index 0000000..216f212 --- /dev/null +++ b/batman-adv/patches/0006-batman-adv-change-the-MAC-of-each-VLAN-upon-ndo_set_.patch @@ -0,0 +1,54 @@ +From 31f391475cc08724e96ab060ef4aa6503d11da8e Mon Sep 17 00:00:00 2001 +From: Antonio Quartulli +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 +Signed-off-by: Marek Lindner +--- + 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 +