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 /net/batman-adv/soft-interface.c | |
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>
Diffstat (limited to 'net/batman-adv/soft-interface.c')
-rw-r--r-- | net/batman-adv/soft-interface.c | 476 |
1 files changed, 1 insertions, 475 deletions
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 | ||