diff options
Diffstat (limited to 'net/rose/rose_route.c')
-rw-r--r-- | net/rose/rose_route.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index f3e21989b88c..cbc244a128bd 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/string.h> | 16 | #include <linux/string.h> |
17 | #include <linux/sockios.h> | 17 | #include <linux/sockios.h> |
18 | #include <linux/net.h> | 18 | #include <linux/net.h> |
19 | #include <linux/slab.h> | ||
19 | #include <net/ax25.h> | 20 | #include <net/ax25.h> |
20 | #include <linux/inet.h> | 21 | #include <linux/inet.h> |
21 | #include <linux/netdevice.h> | 22 | #include <linux/netdevice.h> |
@@ -77,8 +78,9 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route, | |||
77 | 78 | ||
78 | rose_neigh = rose_neigh_list; | 79 | rose_neigh = rose_neigh_list; |
79 | while (rose_neigh != NULL) { | 80 | while (rose_neigh != NULL) { |
80 | if (ax25cmp(&rose_route->neighbour, &rose_neigh->callsign) == 0 | 81 | if (ax25cmp(&rose_route->neighbour, |
81 | && rose_neigh->dev == dev) | 82 | &rose_neigh->callsign) == 0 && |
83 | rose_neigh->dev == dev) | ||
82 | break; | 84 | break; |
83 | rose_neigh = rose_neigh->next; | 85 | rose_neigh = rose_neigh->next; |
84 | } | 86 | } |
@@ -234,6 +236,8 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh) | |||
234 | 236 | ||
235 | if ((s = rose_neigh_list) == rose_neigh) { | 237 | if ((s = rose_neigh_list) == rose_neigh) { |
236 | rose_neigh_list = rose_neigh->next; | 238 | rose_neigh_list = rose_neigh->next; |
239 | if (rose_neigh->ax25) | ||
240 | ax25_cb_put(rose_neigh->ax25); | ||
237 | kfree(rose_neigh->digipeat); | 241 | kfree(rose_neigh->digipeat); |
238 | kfree(rose_neigh); | 242 | kfree(rose_neigh); |
239 | return; | 243 | return; |
@@ -242,6 +246,8 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh) | |||
242 | while (s != NULL && s->next != NULL) { | 246 | while (s != NULL && s->next != NULL) { |
243 | if (s->next == rose_neigh) { | 247 | if (s->next == rose_neigh) { |
244 | s->next = rose_neigh->next; | 248 | s->next = rose_neigh->next; |
249 | if (rose_neigh->ax25) | ||
250 | ax25_cb_put(rose_neigh->ax25); | ||
245 | kfree(rose_neigh->digipeat); | 251 | kfree(rose_neigh->digipeat); |
246 | kfree(rose_neigh); | 252 | kfree(rose_neigh); |
247 | return; | 253 | return; |
@@ -311,8 +317,9 @@ static int rose_del_node(struct rose_route_struct *rose_route, | |||
311 | 317 | ||
312 | rose_neigh = rose_neigh_list; | 318 | rose_neigh = rose_neigh_list; |
313 | while (rose_neigh != NULL) { | 319 | while (rose_neigh != NULL) { |
314 | if (ax25cmp(&rose_route->neighbour, &rose_neigh->callsign) == 0 | 320 | if (ax25cmp(&rose_route->neighbour, |
315 | && rose_neigh->dev == dev) | 321 | &rose_neigh->callsign) == 0 && |
322 | rose_neigh->dev == dev) | ||
316 | break; | 323 | break; |
317 | rose_neigh = rose_neigh->next; | 324 | rose_neigh = rose_neigh->next; |
318 | } | 325 | } |
@@ -600,13 +607,13 @@ struct net_device *rose_dev_first(void) | |||
600 | { | 607 | { |
601 | struct net_device *dev, *first = NULL; | 608 | struct net_device *dev, *first = NULL; |
602 | 609 | ||
603 | read_lock(&dev_base_lock); | 610 | rcu_read_lock(); |
604 | for_each_netdev(&init_net, dev) { | 611 | for_each_netdev_rcu(&init_net, dev) { |
605 | if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE) | 612 | if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE) |
606 | if (first == NULL || strncmp(dev->name, first->name, 3) < 0) | 613 | if (first == NULL || strncmp(dev->name, first->name, 3) < 0) |
607 | first = dev; | 614 | first = dev; |
608 | } | 615 | } |
609 | read_unlock(&dev_base_lock); | 616 | rcu_read_unlock(); |
610 | 617 | ||
611 | return first; | 618 | return first; |
612 | } | 619 | } |
@@ -618,8 +625,8 @@ struct net_device *rose_dev_get(rose_address *addr) | |||
618 | { | 625 | { |
619 | struct net_device *dev; | 626 | struct net_device *dev; |
620 | 627 | ||
621 | read_lock(&dev_base_lock); | 628 | rcu_read_lock(); |
622 | for_each_netdev(&init_net, dev) { | 629 | for_each_netdev_rcu(&init_net, dev) { |
623 | if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) { | 630 | if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) { |
624 | dev_hold(dev); | 631 | dev_hold(dev); |
625 | goto out; | 632 | goto out; |
@@ -627,7 +634,7 @@ struct net_device *rose_dev_get(rose_address *addr) | |||
627 | } | 634 | } |
628 | dev = NULL; | 635 | dev = NULL; |
629 | out: | 636 | out: |
630 | read_unlock(&dev_base_lock); | 637 | rcu_read_unlock(); |
631 | return dev; | 638 | return dev; |
632 | } | 639 | } |
633 | 640 | ||
@@ -635,14 +642,14 @@ static int rose_dev_exists(rose_address *addr) | |||
635 | { | 642 | { |
636 | struct net_device *dev; | 643 | struct net_device *dev; |
637 | 644 | ||
638 | read_lock(&dev_base_lock); | 645 | rcu_read_lock(); |
639 | for_each_netdev(&init_net, dev) { | 646 | for_each_netdev_rcu(&init_net, dev) { |
640 | if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) | 647 | if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) |
641 | goto out; | 648 | goto out; |
642 | } | 649 | } |
643 | dev = NULL; | 650 | dev = NULL; |
644 | out: | 651 | out: |
645 | read_unlock(&dev_base_lock); | 652 | rcu_read_unlock(); |
646 | return dev != NULL; | 653 | return dev != NULL; |
647 | } | 654 | } |
648 | 655 | ||
@@ -810,6 +817,7 @@ void rose_link_failed(ax25_cb *ax25, int reason) | |||
810 | 817 | ||
811 | if (rose_neigh != NULL) { | 818 | if (rose_neigh != NULL) { |
812 | rose_neigh->ax25 = NULL; | 819 | rose_neigh->ax25 = NULL; |
820 | ax25_cb_put(ax25); | ||
813 | 821 | ||
814 | rose_del_route_by_neigh(rose_neigh); | 822 | rose_del_route_by_neigh(rose_neigh); |
815 | rose_kill_by_neigh(rose_neigh); | 823 | rose_kill_by_neigh(rose_neigh); |