aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/hard-interface.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-05-08 18:39:11 -0400
committerDavid S. Miller <davem@davemloft.net>2011-05-08 18:39:11 -0400
commit02e73c1edc3746e308d1768a27fdc8121f641ab1 (patch)
treea3db8009e4549e3d85905e11ac2bf8e64df1763f /net/batman-adv/hard-interface.c
parentc5216cc70fa769e5a51837f2cf07c4a0aa734fcf (diff)
parent27aea2128ec09924dfe08e97739b2bf8b15c8619 (diff)
Merge branch 'batman-adv/next' of git://git.open-mesh.org/ecsv/linux-merge
Diffstat (limited to 'net/batman-adv/hard-interface.c')
-rw-r--r--net/batman-adv/hard-interface.c36
1 files changed, 10 insertions, 26 deletions
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 3e888f133d75..dfbfccc9fe40 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -31,9 +31,6 @@
31 31
32#include <linux/if_arp.h> 32#include <linux/if_arp.h>
33 33
34/* protect update critical side of hardif_list - but not the content */
35static DEFINE_SPINLOCK(hardif_list_lock);
36
37 34
38static int batman_skb_recv(struct sk_buff *skb, 35static int batman_skb_recv(struct sk_buff *skb,
39 struct net_device *dev, 36 struct net_device *dev,
@@ -136,7 +133,7 @@ static void primary_if_select(struct bat_priv *bat_priv,
136 struct hard_iface *curr_hard_iface; 133 struct hard_iface *curr_hard_iface;
137 struct batman_packet *batman_packet; 134 struct batman_packet *batman_packet;
138 135
139 spin_lock_bh(&hardif_list_lock); 136 ASSERT_RTNL();
140 137
141 if (new_hard_iface && !atomic_inc_not_zero(&new_hard_iface->refcount)) 138 if (new_hard_iface && !atomic_inc_not_zero(&new_hard_iface->refcount))
142 new_hard_iface = NULL; 139 new_hard_iface = NULL;
@@ -148,7 +145,7 @@ static void primary_if_select(struct bat_priv *bat_priv,
148 hardif_free_ref(curr_hard_iface); 145 hardif_free_ref(curr_hard_iface);
149 146
150 if (!new_hard_iface) 147 if (!new_hard_iface)
151 goto out; 148 return;
152 149
153 batman_packet = (struct batman_packet *)(new_hard_iface->packet_buff); 150 batman_packet = (struct batman_packet *)(new_hard_iface->packet_buff);
154 batman_packet->flags = PRIMARIES_FIRST_HOP; 151 batman_packet->flags = PRIMARIES_FIRST_HOP;
@@ -157,13 +154,10 @@ static void primary_if_select(struct bat_priv *bat_priv,
157 primary_if_update_addr(bat_priv); 154 primary_if_update_addr(bat_priv);
158 155
159 /*** 156 /***
160 * hacky trick to make sure that we send the HNA information via 157 * hacky trick to make sure that we send the TT information via
161 * our new primary interface 158 * our new primary interface
162 */ 159 */
163 atomic_set(&bat_priv->hna_local_changed, 1); 160 atomic_set(&bat_priv->tt_local_changed, 1);
164
165out:
166 spin_unlock_bh(&hardif_list_lock);
167} 161}
168 162
169static bool hardif_is_iface_up(struct hard_iface *hard_iface) 163static bool hardif_is_iface_up(struct hard_iface *hard_iface)
@@ -345,7 +339,7 @@ int hardif_enable_interface(struct hard_iface *hard_iface, char *iface_name)
345 batman_packet->flags = 0; 339 batman_packet->flags = 0;
346 batman_packet->ttl = 2; 340 batman_packet->ttl = 2;
347 batman_packet->tq = TQ_MAX_VALUE; 341 batman_packet->tq = TQ_MAX_VALUE;
348 batman_packet->num_hna = 0; 342 batman_packet->num_tt = 0;
349 343
350 hard_iface->if_num = bat_priv->num_ifaces; 344 hard_iface->if_num = bat_priv->num_ifaces;
351 bat_priv->num_ifaces++; 345 bat_priv->num_ifaces++;
@@ -456,6 +450,8 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
456 struct hard_iface *hard_iface; 450 struct hard_iface *hard_iface;
457 int ret; 451 int ret;
458 452
453 ASSERT_RTNL();
454
459 ret = is_valid_iface(net_dev); 455 ret = is_valid_iface(net_dev);
460 if (ret != 1) 456 if (ret != 1)
461 goto out; 457 goto out;
@@ -482,10 +478,7 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
482 atomic_set(&hard_iface->refcount, 2); 478 atomic_set(&hard_iface->refcount, 2);
483 479
484 check_known_mac_addr(hard_iface->net_dev); 480 check_known_mac_addr(hard_iface->net_dev);
485
486 spin_lock(&hardif_list_lock);
487 list_add_tail_rcu(&hard_iface->list, &hardif_list); 481 list_add_tail_rcu(&hard_iface->list, &hardif_list);
488 spin_unlock(&hardif_list_lock);
489 482
490 return hard_iface; 483 return hard_iface;
491 484
@@ -499,6 +492,8 @@ out:
499 492
500static void hardif_remove_interface(struct hard_iface *hard_iface) 493static void hardif_remove_interface(struct hard_iface *hard_iface)
501{ 494{
495 ASSERT_RTNL();
496
502 /* first deactivate interface */ 497 /* first deactivate interface */
503 if (hard_iface->if_status != IF_NOT_IN_USE) 498 if (hard_iface->if_status != IF_NOT_IN_USE)
504 hardif_disable_interface(hard_iface); 499 hardif_disable_interface(hard_iface);
@@ -514,20 +509,11 @@ static void hardif_remove_interface(struct hard_iface *hard_iface)
514void hardif_remove_interfaces(void) 509void hardif_remove_interfaces(void)
515{ 510{
516 struct hard_iface *hard_iface, *hard_iface_tmp; 511 struct hard_iface *hard_iface, *hard_iface_tmp;
517 struct list_head if_queue;
518
519 INIT_LIST_HEAD(&if_queue);
520 512
521 spin_lock(&hardif_list_lock); 513 rtnl_lock();
522 list_for_each_entry_safe(hard_iface, hard_iface_tmp, 514 list_for_each_entry_safe(hard_iface, hard_iface_tmp,
523 &hardif_list, list) { 515 &hardif_list, list) {
524 list_del_rcu(&hard_iface->list); 516 list_del_rcu(&hard_iface->list);
525 list_add_tail(&hard_iface->list, &if_queue);
526 }
527 spin_unlock(&hardif_list_lock);
528
529 rtnl_lock();
530 list_for_each_entry_safe(hard_iface, hard_iface_tmp, &if_queue, list) {
531 hardif_remove_interface(hard_iface); 517 hardif_remove_interface(hard_iface);
532 } 518 }
533 rtnl_unlock(); 519 rtnl_unlock();
@@ -556,9 +542,7 @@ static int hard_if_event(struct notifier_block *this,
556 hardif_deactivate_interface(hard_iface); 542 hardif_deactivate_interface(hard_iface);
557 break; 543 break;
558 case NETDEV_UNREGISTER: 544 case NETDEV_UNREGISTER:
559 spin_lock(&hardif_list_lock);
560 list_del_rcu(&hard_iface->list); 545 list_del_rcu(&hard_iface->list);
561 spin_unlock(&hardif_list_lock);
562 546
563 hardif_remove_interface(hard_iface); 547 hardif_remove_interface(hard_iface);
564 break; 548 break;