diff options
author | Simon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de> | 2012-01-22 14:00:18 -0500 |
---|---|---|
committer | Antonio Quartulli <ordex@autistici.org> | 2012-04-11 08:28:58 -0400 |
commit | a7f6ee9493677ba40625d810258de5bd521cc1b0 (patch) | |
tree | 6635b87289ae083a466f14d2c9aed4bb20adae34 | |
parent | 8681a1c4dd258c573e80b4a7af7e7127770b67a8 (diff) |
batman-adv: remove old bridge loop avoidance code
The functionality is to be replaced by an improved implementation,
so first clean up.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
-rw-r--r-- | net/batman-adv/bat_debugfs.c | 8 | ||||
-rw-r--r-- | net/batman-adv/main.c | 5 | ||||
-rw-r--r-- | net/batman-adv/main.h | 2 | ||||
-rw-r--r-- | net/batman-adv/originator.c | 2 | ||||
-rw-r--r-- | net/batman-adv/routing.c | 5 | ||||
-rw-r--r-- | net/batman-adv/routing.h | 1 | ||||
-rw-r--r-- | net/batman-adv/soft-interface.c | 476 | ||||
-rw-r--r-- | net/batman-adv/soft-interface.h | 2 | ||||
-rw-r--r-- | net/batman-adv/types.h | 21 |
9 files changed, 5 insertions, 517 deletions
diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index c3b0548b175d..165ff62a2bed 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c | |||
@@ -238,12 +238,6 @@ static int gateways_open(struct inode *inode, struct file *file) | |||
238 | return single_open(file, gw_client_seq_print_text, net_dev); | 238 | return single_open(file, gw_client_seq_print_text, net_dev); |
239 | } | 239 | } |
240 | 240 | ||
241 | static int softif_neigh_open(struct inode *inode, struct file *file) | ||
242 | { | ||
243 | struct net_device *net_dev = (struct net_device *)inode->i_private; | ||
244 | return single_open(file, softif_neigh_seq_print_text, net_dev); | ||
245 | } | ||
246 | |||
247 | static int transtable_global_open(struct inode *inode, struct file *file) | 241 | static int transtable_global_open(struct inode *inode, struct file *file) |
248 | { | 242 | { |
249 | struct net_device *net_dev = (struct net_device *)inode->i_private; | 243 | struct net_device *net_dev = (struct net_device *)inode->i_private; |
@@ -282,7 +276,6 @@ struct bat_debuginfo bat_debuginfo_##_name = { \ | |||
282 | static BAT_DEBUGINFO(routing_algos, S_IRUGO, bat_algorithms_open); | 276 | static BAT_DEBUGINFO(routing_algos, S_IRUGO, bat_algorithms_open); |
283 | static BAT_DEBUGINFO(originators, S_IRUGO, originators_open); | 277 | static BAT_DEBUGINFO(originators, S_IRUGO, originators_open); |
284 | static BAT_DEBUGINFO(gateways, S_IRUGO, gateways_open); | 278 | static BAT_DEBUGINFO(gateways, S_IRUGO, gateways_open); |
285 | static BAT_DEBUGINFO(softif_neigh, S_IRUGO, softif_neigh_open); | ||
286 | static BAT_DEBUGINFO(transtable_global, S_IRUGO, transtable_global_open); | 279 | static BAT_DEBUGINFO(transtable_global, S_IRUGO, transtable_global_open); |
287 | static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open); | 280 | static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open); |
288 | static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open); | 281 | static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open); |
@@ -290,7 +283,6 @@ static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open); | |||
290 | static struct bat_debuginfo *mesh_debuginfos[] = { | 283 | static struct bat_debuginfo *mesh_debuginfos[] = { |
291 | &bat_debuginfo_originators, | 284 | &bat_debuginfo_originators, |
292 | &bat_debuginfo_gateways, | 285 | &bat_debuginfo_gateways, |
293 | &bat_debuginfo_softif_neigh, | ||
294 | &bat_debuginfo_transtable_global, | 286 | &bat_debuginfo_transtable_global, |
295 | &bat_debuginfo_transtable_local, | 287 | &bat_debuginfo_transtable_local, |
296 | &bat_debuginfo_vis_data, | 288 | &bat_debuginfo_vis_data, |
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 6d51caaf8cec..94d4968a953a 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c | |||
@@ -96,13 +96,10 @@ int mesh_init(struct net_device *soft_iface) | |||
96 | spin_lock_init(&bat_priv->gw_list_lock); | 96 | spin_lock_init(&bat_priv->gw_list_lock); |
97 | spin_lock_init(&bat_priv->vis_hash_lock); | 97 | spin_lock_init(&bat_priv->vis_hash_lock); |
98 | spin_lock_init(&bat_priv->vis_list_lock); | 98 | spin_lock_init(&bat_priv->vis_list_lock); |
99 | spin_lock_init(&bat_priv->softif_neigh_lock); | ||
100 | spin_lock_init(&bat_priv->softif_neigh_vid_lock); | ||
101 | 99 | ||
102 | INIT_HLIST_HEAD(&bat_priv->forw_bat_list); | 100 | INIT_HLIST_HEAD(&bat_priv->forw_bat_list); |
103 | INIT_HLIST_HEAD(&bat_priv->forw_bcast_list); | 101 | INIT_HLIST_HEAD(&bat_priv->forw_bcast_list); |
104 | INIT_HLIST_HEAD(&bat_priv->gw_list); | 102 | INIT_HLIST_HEAD(&bat_priv->gw_list); |
105 | INIT_HLIST_HEAD(&bat_priv->softif_neigh_vids); | ||
106 | INIT_LIST_HEAD(&bat_priv->tt_changes_list); | 103 | INIT_LIST_HEAD(&bat_priv->tt_changes_list); |
107 | INIT_LIST_HEAD(&bat_priv->tt_req_list); | 104 | INIT_LIST_HEAD(&bat_priv->tt_req_list); |
108 | INIT_LIST_HEAD(&bat_priv->tt_roam_list); | 105 | INIT_LIST_HEAD(&bat_priv->tt_roam_list); |
@@ -145,8 +142,6 @@ void mesh_free(struct net_device *soft_iface) | |||
145 | 142 | ||
146 | tt_free(bat_priv); | 143 | tt_free(bat_priv); |
147 | 144 | ||
148 | softif_neigh_purge(bat_priv); | ||
149 | |||
150 | atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); | 145 | atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); |
151 | } | 146 | } |
152 | 147 | ||
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 0a20a19197aa..7a6a25f22fc2 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h | |||
@@ -80,8 +80,6 @@ | |||
80 | #define MAX_AGGREGATION_BYTES 512 | 80 | #define MAX_AGGREGATION_BYTES 512 |
81 | #define MAX_AGGREGATION_MS 100 | 81 | #define MAX_AGGREGATION_MS 100 |
82 | 82 | ||
83 | #define SOFTIF_NEIGH_TIMEOUT 180000 /* 3 minutes */ | ||
84 | |||
85 | /* don't reset again within 30 seconds */ | 83 | /* don't reset again within 30 seconds */ |
86 | #define RESET_PROTECTION_MS 30000 | 84 | #define RESET_PROTECTION_MS 30000 |
87 | #define EXPECTED_SEQNO_RANGE 65536 | 85 | #define EXPECTED_SEQNO_RANGE 65536 |
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 43c0a4f1399e..82390818874b 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c | |||
@@ -375,8 +375,6 @@ static void _purge_orig(struct bat_priv *bat_priv) | |||
375 | 375 | ||
376 | gw_node_purge(bat_priv); | 376 | gw_node_purge(bat_priv); |
377 | gw_election(bat_priv); | 377 | gw_election(bat_priv); |
378 | |||
379 | softif_neigh_purge(bat_priv); | ||
380 | } | 378 | } |
381 | 379 | ||
382 | static void purge_orig(struct work_struct *work) | 380 | static void purge_orig(struct work_struct *work) |
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index b0370e3c59e8..71d4211beb23 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -30,6 +30,9 @@ | |||
30 | #include "vis.h" | 30 | #include "vis.h" |
31 | #include "unicast.h" | 31 | #include "unicast.h" |
32 | 32 | ||
33 | static int route_unicast_packet(struct sk_buff *skb, | ||
34 | struct hard_iface *recv_if); | ||
35 | |||
33 | void slide_own_bcast_window(struct hard_iface *hard_iface) | 36 | void slide_own_bcast_window(struct hard_iface *hard_iface) |
34 | { | 37 | { |
35 | struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); | 38 | struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); |
@@ -798,7 +801,7 @@ static int check_unicast_packet(struct sk_buff *skb, int hdr_size) | |||
798 | return 0; | 801 | return 0; |
799 | } | 802 | } |
800 | 803 | ||
801 | int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) | 804 | static int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) |
802 | { | 805 | { |
803 | struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); | 806 | struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); |
804 | struct orig_node *orig_node = NULL; | 807 | struct orig_node *orig_node = NULL; |
diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h index 92ac100d83da..3d729cb17113 100644 --- a/net/batman-adv/routing.h +++ b/net/batman-adv/routing.h | |||
@@ -25,7 +25,6 @@ | |||
25 | void slide_own_bcast_window(struct hard_iface *hard_iface); | 25 | void slide_own_bcast_window(struct hard_iface *hard_iface); |
26 | void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node, | 26 | void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node, |
27 | struct neigh_node *neigh_node); | 27 | struct neigh_node *neigh_node); |
28 | int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if); | ||
29 | int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if); | 28 | int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if); |
30 | int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if); | 29 | int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if); |
31 | int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if); | 30 | int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if); |
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 82c097d6ec93..e56cb88ef2ba 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
@@ -73,439 +73,6 @@ int my_skb_head_push(struct sk_buff *skb, unsigned int len) | |||
73 | return 0; | 73 | return 0; |
74 | } | 74 | } |
75 | 75 | ||
76 | static void softif_neigh_free_ref(struct softif_neigh *softif_neigh) | ||
77 | { | ||
78 | if (atomic_dec_and_test(&softif_neigh->refcount)) | ||
79 | kfree_rcu(softif_neigh, rcu); | ||
80 | } | ||
81 | |||
82 | static void softif_neigh_vid_free_rcu(struct rcu_head *rcu) | ||
83 | { | ||
84 | struct softif_neigh_vid *softif_neigh_vid; | ||
85 | struct softif_neigh *softif_neigh; | ||
86 | struct hlist_node *node, *node_tmp; | ||
87 | struct bat_priv *bat_priv; | ||
88 | |||
89 | softif_neigh_vid = container_of(rcu, struct softif_neigh_vid, rcu); | ||
90 | bat_priv = softif_neigh_vid->bat_priv; | ||
91 | |||
92 | spin_lock_bh(&bat_priv->softif_neigh_lock); | ||
93 | hlist_for_each_entry_safe(softif_neigh, node, node_tmp, | ||
94 | &softif_neigh_vid->softif_neigh_list, list) { | ||
95 | hlist_del_rcu(&softif_neigh->list); | ||
96 | softif_neigh_free_ref(softif_neigh); | ||
97 | } | ||
98 | spin_unlock_bh(&bat_priv->softif_neigh_lock); | ||
99 | |||
100 | kfree(softif_neigh_vid); | ||
101 | } | ||
102 | |||
103 | static void softif_neigh_vid_free_ref(struct softif_neigh_vid *softif_neigh_vid) | ||
104 | { | ||
105 | if (atomic_dec_and_test(&softif_neigh_vid->refcount)) | ||
106 | call_rcu(&softif_neigh_vid->rcu, softif_neigh_vid_free_rcu); | ||
107 | } | ||
108 | |||
109 | static struct softif_neigh_vid *softif_neigh_vid_get(struct bat_priv *bat_priv, | ||
110 | short vid) | ||
111 | { | ||
112 | struct softif_neigh_vid *softif_neigh_vid; | ||
113 | struct hlist_node *node; | ||
114 | |||
115 | rcu_read_lock(); | ||
116 | hlist_for_each_entry_rcu(softif_neigh_vid, node, | ||
117 | &bat_priv->softif_neigh_vids, list) { | ||
118 | if (softif_neigh_vid->vid != vid) | ||
119 | continue; | ||
120 | |||
121 | if (!atomic_inc_not_zero(&softif_neigh_vid->refcount)) | ||
122 | continue; | ||
123 | |||
124 | goto out; | ||
125 | } | ||
126 | |||
127 | softif_neigh_vid = kzalloc(sizeof(*softif_neigh_vid), GFP_ATOMIC); | ||
128 | if (!softif_neigh_vid) | ||
129 | goto out; | ||
130 | |||
131 | softif_neigh_vid->vid = vid; | ||
132 | softif_neigh_vid->bat_priv = bat_priv; | ||
133 | |||
134 | /* initialize with 2 - caller decrements counter by one */ | ||
135 | atomic_set(&softif_neigh_vid->refcount, 2); | ||
136 | INIT_HLIST_HEAD(&softif_neigh_vid->softif_neigh_list); | ||
137 | INIT_HLIST_NODE(&softif_neigh_vid->list); | ||
138 | spin_lock_bh(&bat_priv->softif_neigh_vid_lock); | ||
139 | hlist_add_head_rcu(&softif_neigh_vid->list, | ||
140 | &bat_priv->softif_neigh_vids); | ||
141 | spin_unlock_bh(&bat_priv->softif_neigh_vid_lock); | ||
142 | |||
143 | out: | ||
144 | rcu_read_unlock(); | ||
145 | return softif_neigh_vid; | ||
146 | } | ||
147 | |||
148 | static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv, | ||
149 | const uint8_t *addr, short vid) | ||
150 | { | ||
151 | struct softif_neigh_vid *softif_neigh_vid; | ||
152 | struct softif_neigh *softif_neigh = NULL; | ||
153 | struct hlist_node *node; | ||
154 | |||
155 | softif_neigh_vid = softif_neigh_vid_get(bat_priv, vid); | ||
156 | if (!softif_neigh_vid) | ||
157 | goto out; | ||
158 | |||
159 | rcu_read_lock(); | ||
160 | hlist_for_each_entry_rcu(softif_neigh, node, | ||
161 | &softif_neigh_vid->softif_neigh_list, | ||
162 | list) { | ||
163 | if (!compare_eth(softif_neigh->addr, addr)) | ||
164 | continue; | ||
165 | |||
166 | if (!atomic_inc_not_zero(&softif_neigh->refcount)) | ||
167 | continue; | ||
168 | |||
169 | softif_neigh->last_seen = jiffies; | ||
170 | goto unlock; | ||
171 | } | ||
172 | |||
173 | softif_neigh = kzalloc(sizeof(*softif_neigh), GFP_ATOMIC); | ||
174 | if (!softif_neigh) | ||
175 | goto unlock; | ||
176 | |||
177 | memcpy(softif_neigh->addr, addr, ETH_ALEN); | ||
178 | softif_neigh->last_seen = jiffies; | ||
179 | /* initialize with 2 - caller decrements counter by one */ | ||
180 | atomic_set(&softif_neigh->refcount, 2); | ||
181 | |||
182 | INIT_HLIST_NODE(&softif_neigh->list); | ||
183 | spin_lock_bh(&bat_priv->softif_neigh_lock); | ||
184 | hlist_add_head_rcu(&softif_neigh->list, | ||
185 | &softif_neigh_vid->softif_neigh_list); | ||
186 | spin_unlock_bh(&bat_priv->softif_neigh_lock); | ||
187 | |||
188 | unlock: | ||
189 | rcu_read_unlock(); | ||
190 | out: | ||
191 | if (softif_neigh_vid) | ||
192 | softif_neigh_vid_free_ref(softif_neigh_vid); | ||
193 | return softif_neigh; | ||
194 | } | ||
195 | |||
196 | static struct softif_neigh *softif_neigh_get_selected( | ||
197 | struct softif_neigh_vid *softif_neigh_vid) | ||
198 | { | ||
199 | struct softif_neigh *softif_neigh; | ||
200 | |||
201 | rcu_read_lock(); | ||
202 | softif_neigh = rcu_dereference(softif_neigh_vid->softif_neigh); | ||
203 | |||
204 | if (softif_neigh && !atomic_inc_not_zero(&softif_neigh->refcount)) | ||
205 | softif_neigh = NULL; | ||
206 | |||
207 | rcu_read_unlock(); | ||
208 | return softif_neigh; | ||
209 | } | ||
210 | |||
211 | static struct softif_neigh *softif_neigh_vid_get_selected( | ||
212 | struct bat_priv *bat_priv, | ||
213 | short vid) | ||
214 | { | ||
215 | struct softif_neigh_vid *softif_neigh_vid; | ||
216 | struct softif_neigh *softif_neigh = NULL; | ||
217 | |||
218 | softif_neigh_vid = softif_neigh_vid_get(bat_priv, vid); | ||
219 | if (!softif_neigh_vid) | ||
220 | goto out; | ||
221 | |||
222 | softif_neigh = softif_neigh_get_selected(softif_neigh_vid); | ||
223 | out: | ||
224 | if (softif_neigh_vid) | ||
225 | softif_neigh_vid_free_ref(softif_neigh_vid); | ||
226 | return softif_neigh; | ||
227 | } | ||
228 | |||
229 | static void softif_neigh_vid_select(struct bat_priv *bat_priv, | ||
230 | struct softif_neigh *new_neigh, | ||
231 | short vid) | ||
232 | { | ||
233 | struct softif_neigh_vid *softif_neigh_vid; | ||
234 | struct softif_neigh *curr_neigh; | ||
235 | |||
236 | softif_neigh_vid = softif_neigh_vid_get(bat_priv, vid); | ||
237 | if (!softif_neigh_vid) | ||
238 | goto out; | ||
239 | |||
240 | spin_lock_bh(&bat_priv->softif_neigh_lock); | ||
241 | |||
242 | if (new_neigh && !atomic_inc_not_zero(&new_neigh->refcount)) | ||
243 | new_neigh = NULL; | ||
244 | |||
245 | curr_neigh = rcu_dereference_protected(softif_neigh_vid->softif_neigh, | ||
246 | 1); | ||
247 | rcu_assign_pointer(softif_neigh_vid->softif_neigh, new_neigh); | ||
248 | |||
249 | if ((curr_neigh) && (!new_neigh)) | ||
250 | bat_dbg(DBG_ROUTES, bat_priv, | ||
251 | "Removing mesh exit point on vid: %d (prev: %pM).\n", | ||
252 | vid, curr_neigh->addr); | ||
253 | else if ((curr_neigh) && (new_neigh)) | ||
254 | bat_dbg(DBG_ROUTES, bat_priv, | ||
255 | "Changing mesh exit point on vid: %d from %pM to %pM.\n", | ||
256 | vid, curr_neigh->addr, new_neigh->addr); | ||
257 | else if ((!curr_neigh) && (new_neigh)) | ||
258 | bat_dbg(DBG_ROUTES, bat_priv, | ||
259 | "Setting mesh exit point on vid: %d to %pM.\n", | ||
260 | vid, new_neigh->addr); | ||
261 | |||
262 | if (curr_neigh) | ||
263 | softif_neigh_free_ref(curr_neigh); | ||
264 | |||
265 | spin_unlock_bh(&bat_priv->softif_neigh_lock); | ||
266 | |||
267 | out: | ||
268 | if (softif_neigh_vid) | ||
269 | softif_neigh_vid_free_ref(softif_neigh_vid); | ||
270 | } | ||
271 | |||
272 | static void softif_neigh_vid_deselect(struct bat_priv *bat_priv, | ||
273 | struct softif_neigh_vid *softif_neigh_vid) | ||
274 | { | ||
275 | struct softif_neigh *curr_neigh; | ||
276 | struct softif_neigh *softif_neigh = NULL, *softif_neigh_tmp; | ||
277 | struct hard_iface *primary_if = NULL; | ||
278 | struct hlist_node *node; | ||
279 | |||
280 | primary_if = primary_if_get_selected(bat_priv); | ||
281 | if (!primary_if) | ||
282 | goto out; | ||
283 | |||
284 | /* find new softif_neigh immediately to avoid temporary loops */ | ||
285 | rcu_read_lock(); | ||
286 | curr_neigh = rcu_dereference(softif_neigh_vid->softif_neigh); | ||
287 | |||
288 | hlist_for_each_entry_rcu(softif_neigh_tmp, node, | ||
289 | &softif_neigh_vid->softif_neigh_list, | ||
290 | list) { | ||
291 | if (softif_neigh_tmp == curr_neigh) | ||
292 | continue; | ||
293 | |||
294 | /* we got a neighbor but its mac is 'bigger' than ours */ | ||
295 | if (memcmp(primary_if->net_dev->dev_addr, | ||
296 | softif_neigh_tmp->addr, ETH_ALEN) < 0) | ||
297 | continue; | ||
298 | |||
299 | if (!atomic_inc_not_zero(&softif_neigh_tmp->refcount)) | ||
300 | continue; | ||
301 | |||
302 | softif_neigh = softif_neigh_tmp; | ||
303 | goto unlock; | ||
304 | } | ||
305 | |||
306 | unlock: | ||
307 | rcu_read_unlock(); | ||
308 | out: | ||
309 | softif_neigh_vid_select(bat_priv, softif_neigh, softif_neigh_vid->vid); | ||
310 | |||
311 | if (primary_if) | ||
312 | hardif_free_ref(primary_if); | ||
313 | if (softif_neigh) | ||
314 | softif_neigh_free_ref(softif_neigh); | ||
315 | } | ||
316 | |||
317 | int softif_neigh_seq_print_text(struct seq_file *seq, void *offset) | ||
318 | { | ||
319 | struct net_device *net_dev = (struct net_device *)seq->private; | ||
320 | struct bat_priv *bat_priv = netdev_priv(net_dev); | ||
321 | struct softif_neigh_vid *softif_neigh_vid; | ||
322 | struct softif_neigh *softif_neigh; | ||
323 | struct hard_iface *primary_if; | ||
324 | struct hlist_node *node, *node_tmp; | ||
325 | struct softif_neigh *curr_softif_neigh; | ||
326 | int ret = 0, last_seen_secs, last_seen_msecs; | ||
327 | |||
328 | primary_if = primary_if_get_selected(bat_priv); | ||
329 | if (!primary_if) { | ||
330 | ret = seq_printf(seq, | ||
331 | "BATMAN mesh %s disabled - please specify interfaces to enable it\n", | ||
332 | net_dev->name); | ||
333 | goto out; | ||
334 | } | ||
335 | |||
336 | if (primary_if->if_status != IF_ACTIVE) { | ||
337 | ret = seq_printf(seq, | ||
338 | "BATMAN mesh %s disabled - primary interface not active\n", | ||
339 | net_dev->name); | ||
340 | goto out; | ||
341 | } | ||
342 | |||
343 | seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name); | ||
344 | |||
345 | rcu_read_lock(); | ||
346 | hlist_for_each_entry_rcu(softif_neigh_vid, node, | ||
347 | &bat_priv->softif_neigh_vids, list) { | ||
348 | seq_printf(seq, " %-15s %s on vid: %d\n", | ||
349 | "Originator", "last-seen", softif_neigh_vid->vid); | ||
350 | |||
351 | curr_softif_neigh = softif_neigh_get_selected(softif_neigh_vid); | ||
352 | |||
353 | hlist_for_each_entry_rcu(softif_neigh, node_tmp, | ||
354 | &softif_neigh_vid->softif_neigh_list, | ||
355 | list) { | ||
356 | last_seen_secs = jiffies_to_msecs(jiffies - | ||
357 | softif_neigh->last_seen) / 1000; | ||
358 | last_seen_msecs = jiffies_to_msecs(jiffies - | ||
359 | softif_neigh->last_seen) % 1000; | ||
360 | seq_printf(seq, "%s %pM %3i.%03is\n", | ||
361 | curr_softif_neigh == softif_neigh | ||
362 | ? "=>" : " ", softif_neigh->addr, | ||
363 | last_seen_secs, last_seen_msecs); | ||
364 | } | ||
365 | |||
366 | if (curr_softif_neigh) | ||
367 | softif_neigh_free_ref(curr_softif_neigh); | ||
368 | |||
369 | seq_printf(seq, "\n"); | ||
370 | } | ||
371 | rcu_read_unlock(); | ||
372 | |||
373 | out: | ||
374 | if (primary_if) | ||
375 | hardif_free_ref(primary_if); | ||
376 | return ret; | ||
377 | } | ||
378 | |||
379 | void softif_neigh_purge(struct bat_priv *bat_priv) | ||
380 | { | ||
381 | struct softif_neigh *softif_neigh, *curr_softif_neigh; | ||
382 | struct softif_neigh_vid *softif_neigh_vid; | ||
383 | struct hlist_node *node, *node_tmp, *node_tmp2; | ||
384 | int do_deselect; | ||
385 | |||
386 | rcu_read_lock(); | ||
387 | hlist_for_each_entry_rcu(softif_neigh_vid, node, | ||
388 | &bat_priv->softif_neigh_vids, list) { | ||
389 | if (!atomic_inc_not_zero(&softif_neigh_vid->refcount)) | ||
390 | continue; | ||
391 | |||
392 | curr_softif_neigh = softif_neigh_get_selected(softif_neigh_vid); | ||
393 | do_deselect = 0; | ||
394 | |||
395 | spin_lock_bh(&bat_priv->softif_neigh_lock); | ||
396 | hlist_for_each_entry_safe(softif_neigh, node_tmp, node_tmp2, | ||
397 | &softif_neigh_vid->softif_neigh_list, | ||
398 | list) { | ||
399 | if ((!has_timed_out(softif_neigh->last_seen, | ||
400 | SOFTIF_NEIGH_TIMEOUT)) && | ||
401 | (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE)) | ||
402 | continue; | ||
403 | |||
404 | if (curr_softif_neigh == softif_neigh) { | ||
405 | bat_dbg(DBG_ROUTES, bat_priv, | ||
406 | "Current mesh exit point on vid: %d '%pM' vanished.\n", | ||
407 | softif_neigh_vid->vid, | ||
408 | softif_neigh->addr); | ||
409 | do_deselect = 1; | ||
410 | } | ||
411 | |||
412 | hlist_del_rcu(&softif_neigh->list); | ||
413 | softif_neigh_free_ref(softif_neigh); | ||
414 | } | ||
415 | spin_unlock_bh(&bat_priv->softif_neigh_lock); | ||
416 | |||
417 | /* soft_neigh_vid_deselect() needs to acquire the | ||
418 | * softif_neigh_lock */ | ||
419 | if (do_deselect) | ||
420 | softif_neigh_vid_deselect(bat_priv, softif_neigh_vid); | ||
421 | |||
422 | if (curr_softif_neigh) | ||
423 | softif_neigh_free_ref(curr_softif_neigh); | ||
424 | |||
425 | softif_neigh_vid_free_ref(softif_neigh_vid); | ||
426 | } | ||
427 | rcu_read_unlock(); | ||
428 | |||
429 | spin_lock_bh(&bat_priv->softif_neigh_vid_lock); | ||
430 | hlist_for_each_entry_safe(softif_neigh_vid, node, node_tmp, | ||
431 | &bat_priv->softif_neigh_vids, list) { | ||
432 | if (!hlist_empty(&softif_neigh_vid->softif_neigh_list)) | ||
433 | continue; | ||
434 | |||
435 | hlist_del_rcu(&softif_neigh_vid->list); | ||
436 | softif_neigh_vid_free_ref(softif_neigh_vid); | ||
437 | } | ||
438 | spin_unlock_bh(&bat_priv->softif_neigh_vid_lock); | ||
439 | |||
440 | } | ||
441 | |||
442 | static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev, | ||
443 | short vid) | ||
444 | { | ||
445 | struct bat_priv *bat_priv = netdev_priv(dev); | ||
446 | struct ethhdr *ethhdr = (struct ethhdr *)skb->data; | ||
447 | struct batman_ogm_packet *batman_ogm_packet; | ||
448 | struct softif_neigh *softif_neigh = NULL; | ||
449 | struct hard_iface *primary_if = NULL; | ||
450 | struct softif_neigh *curr_softif_neigh = NULL; | ||
451 | |||
452 | if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) | ||
453 | batman_ogm_packet = (struct batman_ogm_packet *) | ||
454 | (skb->data + ETH_HLEN + VLAN_HLEN); | ||
455 | else | ||
456 | batman_ogm_packet = (struct batman_ogm_packet *) | ||
457 | (skb->data + ETH_HLEN); | ||
458 | |||
459 | if (batman_ogm_packet->header.version != COMPAT_VERSION) | ||
460 | goto out; | ||
461 | |||
462 | if (batman_ogm_packet->header.packet_type != BAT_OGM) | ||
463 | goto out; | ||
464 | |||
465 | if (!(batman_ogm_packet->flags & PRIMARIES_FIRST_HOP)) | ||
466 | goto out; | ||
467 | |||
468 | if (is_my_mac(batman_ogm_packet->orig)) | ||
469 | goto out; | ||
470 | |||
471 | softif_neigh = softif_neigh_get(bat_priv, batman_ogm_packet->orig, vid); | ||
472 | if (!softif_neigh) | ||
473 | goto out; | ||
474 | |||
475 | curr_softif_neigh = softif_neigh_vid_get_selected(bat_priv, vid); | ||
476 | if (curr_softif_neigh == softif_neigh) | ||
477 | goto out; | ||
478 | |||
479 | primary_if = primary_if_get_selected(bat_priv); | ||
480 | if (!primary_if) | ||
481 | goto out; | ||
482 | |||
483 | /* we got a neighbor but its mac is 'bigger' than ours */ | ||
484 | if (memcmp(primary_if->net_dev->dev_addr, | ||
485 | softif_neigh->addr, ETH_ALEN) < 0) | ||
486 | goto out; | ||
487 | |||
488 | /* close own batX device and use softif_neigh as exit node */ | ||
489 | if (!curr_softif_neigh) { | ||
490 | softif_neigh_vid_select(bat_priv, softif_neigh, vid); | ||
491 | goto out; | ||
492 | } | ||
493 | |||
494 | /* switch to new 'smallest neighbor' */ | ||
495 | if (memcmp(softif_neigh->addr, curr_softif_neigh->addr, ETH_ALEN) < 0) | ||
496 | softif_neigh_vid_select(bat_priv, softif_neigh, vid); | ||
497 | |||
498 | out: | ||
499 | kfree_skb(skb); | ||
500 | if (softif_neigh) | ||
501 | softif_neigh_free_ref(softif_neigh); | ||
502 | if (curr_softif_neigh) | ||
503 | softif_neigh_free_ref(curr_softif_neigh); | ||
504 | if (primary_if) | ||
505 | hardif_free_ref(primary_if); | ||
506 | return; | ||
507 | } | ||
508 | |||
509 | static int interface_open(struct net_device *dev) | 76 | static int interface_open(struct net_device *dev) |
510 | { | 77 | { |
511 | netif_start_queue(dev); | 78 | netif_start_queue(dev); |
@@ -562,7 +129,6 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) | |||
562 | struct hard_iface *primary_if = NULL; | 129 | struct hard_iface *primary_if = NULL; |
563 | struct bcast_packet *bcast_packet; | 130 | struct bcast_packet *bcast_packet; |
564 | struct vlan_ethhdr *vhdr; | 131 | struct vlan_ethhdr *vhdr; |
565 | struct softif_neigh *curr_softif_neigh = NULL; | ||
566 | unsigned int header_len = 0; | 132 | unsigned int header_len = 0; |
567 | int data_len = skb->len, ret; | 133 | int data_len = skb->len, ret; |
568 | short vid = -1; | 134 | short vid = -1; |
@@ -583,17 +149,8 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) | |||
583 | 149 | ||
584 | /* fall through */ | 150 | /* fall through */ |
585 | case ETH_P_BATMAN: | 151 | case ETH_P_BATMAN: |
586 | softif_batman_recv(skb, soft_iface, vid); | ||
587 | goto end; | ||
588 | } | ||
589 | |||
590 | /** | ||
591 | * if we have a another chosen mesh exit node in range | ||
592 | * it will transport the packets to the mesh | ||
593 | */ | ||
594 | curr_softif_neigh = softif_neigh_vid_get_selected(bat_priv, vid); | ||
595 | if (curr_softif_neigh) | ||
596 | goto dropped; | 152 | goto dropped; |
153 | } | ||
597 | 154 | ||
598 | /* Register the client MAC in the transtable */ | 155 | /* Register the client MAC in the transtable */ |
599 | tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif); | 156 | tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif); |
@@ -675,8 +232,6 @@ dropped: | |||
675 | dropped_freed: | 232 | dropped_freed: |
676 | bat_priv->stats.tx_dropped++; | 233 | bat_priv->stats.tx_dropped++; |
677 | end: | 234 | end: |
678 | if (curr_softif_neigh) | ||
679 | softif_neigh_free_ref(curr_softif_neigh); | ||
680 | if (primary_if) | 235 | if (primary_if) |
681 | hardif_free_ref(primary_if); | 236 | hardif_free_ref(primary_if); |
682 | return NETDEV_TX_OK; | 237 | return NETDEV_TX_OK; |
@@ -687,12 +242,9 @@ void interface_rx(struct net_device *soft_iface, | |||
687 | int hdr_size) | 242 | int hdr_size) |
688 | { | 243 | { |
689 | struct bat_priv *bat_priv = netdev_priv(soft_iface); | 244 | struct bat_priv *bat_priv = netdev_priv(soft_iface); |
690 | struct unicast_packet *unicast_packet; | ||
691 | struct ethhdr *ethhdr; | 245 | struct ethhdr *ethhdr; |
692 | struct vlan_ethhdr *vhdr; | 246 | struct vlan_ethhdr *vhdr; |
693 | struct softif_neigh *curr_softif_neigh = NULL; | ||
694 | short vid = -1; | 247 | short vid = -1; |
695 | int ret; | ||
696 | 248 | ||
697 | /* check if enough space is available for pulling, and pull */ | 249 | /* check if enough space is available for pulling, and pull */ |
698 | if (!pskb_may_pull(skb, hdr_size)) | 250 | if (!pskb_may_pull(skb, hdr_size)) |
@@ -716,30 +268,6 @@ void interface_rx(struct net_device *soft_iface, | |||
716 | goto dropped; | 268 | goto dropped; |
717 | } | 269 | } |
718 | 270 | ||
719 | /** | ||
720 | * if we have a another chosen mesh exit node in range | ||
721 | * it will transport the packets to the non-mesh network | ||
722 | */ | ||
723 | curr_softif_neigh = softif_neigh_vid_get_selected(bat_priv, vid); | ||
724 | if (curr_softif_neigh) { | ||
725 | skb_push(skb, hdr_size); | ||
726 | unicast_packet = (struct unicast_packet *)skb->data; | ||
727 | |||
728 | if ((unicast_packet->header.packet_type != BAT_UNICAST) && | ||
729 | (unicast_packet->header.packet_type != BAT_UNICAST_FRAG)) | ||
730 | goto dropped; | ||
731 | |||
732 | skb_reset_mac_header(skb); | ||
733 | |||
734 | memcpy(unicast_packet->dest, | ||
735 | curr_softif_neigh->addr, ETH_ALEN); | ||
736 | ret = route_unicast_packet(skb, recv_if); | ||
737 | if (ret == NET_RX_DROP) | ||
738 | goto dropped; | ||
739 | |||
740 | goto out; | ||
741 | } | ||
742 | |||
743 | /* skb->dev & skb->pkt_type are set here */ | 271 | /* skb->dev & skb->pkt_type are set here */ |
744 | if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) | 272 | if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) |
745 | goto dropped; | 273 | goto dropped; |
@@ -765,8 +293,6 @@ void interface_rx(struct net_device *soft_iface, | |||
765 | dropped: | 293 | dropped: |
766 | kfree_skb(skb); | 294 | kfree_skb(skb); |
767 | out: | 295 | out: |
768 | if (curr_softif_neigh) | ||
769 | softif_neigh_free_ref(curr_softif_neigh); | ||
770 | return; | 296 | return; |
771 | } | 297 | } |
772 | 298 | ||
diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h index 756eab5b8dd4..020300673884 100644 --- a/net/batman-adv/soft-interface.h +++ b/net/batman-adv/soft-interface.h | |||
@@ -23,8 +23,6 @@ | |||
23 | #define _NET_BATMAN_ADV_SOFT_INTERFACE_H_ | 23 | #define _NET_BATMAN_ADV_SOFT_INTERFACE_H_ |
24 | 24 | ||
25 | int my_skb_head_push(struct sk_buff *skb, unsigned int len); | 25 | int my_skb_head_push(struct sk_buff *skb, unsigned int len); |
26 | int softif_neigh_seq_print_text(struct seq_file *seq, void *offset); | ||
27 | void softif_neigh_purge(struct bat_priv *bat_priv); | ||
28 | void interface_rx(struct net_device *soft_iface, | 26 | void interface_rx(struct net_device *soft_iface, |
29 | struct sk_buff *skb, struct hard_iface *recv_if, | 27 | struct sk_buff *skb, struct hard_iface *recv_if, |
30 | int hdr_size); | 28 | int hdr_size); |
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 24c8a31a3d91..feac2f4030c8 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h | |||
@@ -174,7 +174,6 @@ struct bat_priv { | |||
174 | struct hlist_head forw_bat_list; | 174 | struct hlist_head forw_bat_list; |
175 | struct hlist_head forw_bcast_list; | 175 | struct hlist_head forw_bcast_list; |
176 | struct hlist_head gw_list; | 176 | struct hlist_head gw_list; |
177 | struct hlist_head softif_neigh_vids; | ||
178 | struct list_head tt_changes_list; /* tracks changes in a OGM int */ | 177 | struct list_head tt_changes_list; /* tracks changes in a OGM int */ |
179 | struct list_head vis_send_list; | 178 | struct list_head vis_send_list; |
180 | struct hashtable_t *orig_hash; | 179 | struct hashtable_t *orig_hash; |
@@ -191,8 +190,6 @@ struct bat_priv { | |||
191 | spinlock_t gw_list_lock; /* protects gw_list and curr_gw */ | 190 | spinlock_t gw_list_lock; /* protects gw_list and curr_gw */ |
192 | spinlock_t vis_hash_lock; /* protects vis_hash */ | 191 | spinlock_t vis_hash_lock; /* protects vis_hash */ |
193 | spinlock_t vis_list_lock; /* protects vis_info::recv_list */ | 192 | spinlock_t vis_list_lock; /* protects vis_info::recv_list */ |
194 | spinlock_t softif_neigh_lock; /* protects soft-interface neigh list */ | ||
195 | spinlock_t softif_neigh_vid_lock; /* protects soft-interface vid list */ | ||
196 | atomic_t num_local_tt; | 193 | atomic_t num_local_tt; |
197 | /* Checksum of the local table, recomputed before sending a new OGM */ | 194 | /* Checksum of the local table, recomputed before sending a new OGM */ |
198 | atomic_t tt_crc; | 195 | atomic_t tt_crc; |
@@ -327,24 +324,6 @@ struct recvlist_node { | |||
327 | uint8_t mac[ETH_ALEN]; | 324 | uint8_t mac[ETH_ALEN]; |
328 | }; | 325 | }; |
329 | 326 | ||
330 | struct softif_neigh_vid { | ||
331 | struct hlist_node list; | ||
332 | struct bat_priv *bat_priv; | ||
333 | short vid; | ||
334 | atomic_t refcount; | ||
335 | struct softif_neigh __rcu *softif_neigh; | ||
336 | struct rcu_head rcu; | ||
337 | struct hlist_head softif_neigh_list; | ||
338 | }; | ||
339 | |||
340 | struct softif_neigh { | ||
341 | struct hlist_node list; | ||
342 | uint8_t addr[ETH_ALEN]; | ||
343 | unsigned long last_seen; | ||
344 | atomic_t refcount; | ||
345 | struct rcu_head rcu; | ||
346 | }; | ||
347 | |||
348 | struct bat_algo_ops { | 327 | struct bat_algo_ops { |
349 | struct hlist_node list; | 328 | struct hlist_node list; |
350 | char *name; | 329 | char *name; |