495dae532a9842fac189f713226bc06a333eb413
[feed/routing.git] / batman-adv / patches / 0004-batman-adv-fix-removing-neigh_ifinfo.patch
1 From 9b9cdbe28e2b9c8bdf9c761f22ba9655963d13d4 Mon Sep 17 00:00:00 2001
2 From: Simon Wunderlich <simon@open-mesh.com>
3 Date: Wed, 26 Mar 2014 15:46:24 +0100
4 Subject: [PATCH 4/9] batman-adv: fix removing neigh_ifinfo
5
6 When an interface is removed separately, all neighbors need to be
7 checked if they have a neigh_ifinfo structure for that particular
8 interface. If that is the case, remove that ifinfo so any references to
9 a hard interface can be freed.
10
11 This is a regression introduced by
12 9bb33b8d88e318c4879d37d06ad28e3e018b9036 ("batman-adv: split tq
13 information in neigh_node struct")
14
15 Reported-by: Antonio Quartulli <antonio@open-mesh.com>
16 Signed-off-by: Simon Wunderlich <simon@open-mesh.com>
17 Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
18 ---
19 originator.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
20 1 file changed, 46 insertions(+)
21
22 diff --git a/originator.c b/originator.c
23 index 47b0886..aa2468b 100644
24 --- a/originator.c
25 +++ b/originator.c
26 @@ -702,6 +702,47 @@ free_orig_node:
27 }
28
29 /**
30 + * batadv_purge_neigh_ifinfo - purge obsolete ifinfo entries from neighbor
31 + * @bat_priv: the bat priv with all the soft interface information
32 + * @neigh_node: orig node which is to be checked
33 + */
34 +static void
35 +batadv_purge_neigh_ifinfo(struct batadv_priv *bat_priv,
36 + struct batadv_neigh_node *neigh)
37 +{
38 + struct batadv_neigh_ifinfo *neigh_ifinfo;
39 + struct batadv_hard_iface *if_outgoing;
40 + struct hlist_node *node_tmp;
41 +
42 + spin_lock_bh(&neigh->ifinfo_lock);
43 +
44 + /* for all ifinfo objects for this neighinator */
45 + hlist_for_each_entry_safe(neigh_ifinfo, node_tmp,
46 + &neigh->ifinfo_list, list) {
47 + if_outgoing = neigh_ifinfo->if_outgoing;
48 +
49 + /* always keep the default interface */
50 + if (if_outgoing == BATADV_IF_DEFAULT)
51 + continue;
52 +
53 + /* don't purge if the interface is not (going) down */
54 + if ((if_outgoing->if_status != BATADV_IF_INACTIVE) &&
55 + (if_outgoing->if_status != BATADV_IF_NOT_IN_USE) &&
56 + (if_outgoing->if_status != BATADV_IF_TO_BE_REMOVED))
57 + continue;
58 +
59 + batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
60 + "neighbor/ifinfo purge: neighbor %pM, iface: %s\n",
61 + neigh->addr, if_outgoing->net_dev->name);
62 +
63 + hlist_del_rcu(&neigh_ifinfo->list);
64 + batadv_neigh_ifinfo_free_ref(neigh_ifinfo);
65 + }
66 +
67 + spin_unlock_bh(&neigh->ifinfo_lock);
68 +}
69 +
70 +/**
71 * batadv_purge_orig_ifinfo - purge obsolete ifinfo entries from originator
72 * @bat_priv: the bat priv with all the soft interface information
73 * @orig_node: orig node which is to be checked
74 @@ -800,6 +841,11 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
75
76 hlist_del_rcu(&neigh_node->list);
77 batadv_neigh_node_free_ref(neigh_node);
78 + } else {
79 + /* only neccesary if not the whole neighbor is to be deleted,
80 + * but some interface has been removed.
81 + */
82 + batadv_purge_neigh_ifinfo(bat_priv, neigh_node);
83 }
84 }
85
86 --
87 2.0.0.rc2
88