diff options
Diffstat (limited to 'net/batman-adv/hard-interface.c')
-rw-r--r-- | net/batman-adv/hard-interface.c | 36 |
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 */ | ||
35 | static DEFINE_SPINLOCK(hardif_list_lock); | ||
36 | |||
37 | 34 | ||
38 | static int batman_skb_recv(struct sk_buff *skb, | 35 | static 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 | |||
165 | out: | ||
166 | spin_unlock_bh(&hardif_list_lock); | ||
167 | } | 161 | } |
168 | 162 | ||
169 | static bool hardif_is_iface_up(struct hard_iface *hard_iface) | 163 | static 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 | ||
500 | static void hardif_remove_interface(struct hard_iface *hard_iface) | 493 | static 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) | |||
514 | void hardif_remove_interfaces(void) | 509 | void 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; |