aboutsummaryrefslogtreecommitdiffstats
path: root/net/rose/rose_route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/rose/rose_route.c')
-rw-r--r--net/rose/rose_route.c34
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;
629out: 636out:
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;
644out: 651out:
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);