diff options
Diffstat (limited to 'net/ax25/ax25_route.c')
| -rw-r--r-- | net/ax25/ax25_route.c | 49 |
1 files changed, 8 insertions, 41 deletions
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c index 5ac98250797b..51b7bdaf27eb 100644 --- a/net/ax25/ax25_route.c +++ b/net/ax25/ax25_route.c | |||
| @@ -41,8 +41,6 @@ | |||
| 41 | static ax25_route *ax25_route_list; | 41 | static ax25_route *ax25_route_list; |
| 42 | static DEFINE_RWLOCK(ax25_route_lock); | 42 | static DEFINE_RWLOCK(ax25_route_lock); |
| 43 | 43 | ||
| 44 | static ax25_route *ax25_get_route(ax25_address *, struct net_device *); | ||
| 45 | |||
| 46 | void ax25_rt_device_down(struct net_device *dev) | 44 | void ax25_rt_device_down(struct net_device *dev) |
| 47 | { | 45 | { |
| 48 | ax25_route *s, *t, *ax25_rt; | 46 | ax25_route *s, *t, *ax25_rt; |
| @@ -115,7 +113,7 @@ static int ax25_rt_add(struct ax25_routes_struct *route) | |||
| 115 | return -ENOMEM; | 113 | return -ENOMEM; |
| 116 | } | 114 | } |
| 117 | 115 | ||
| 118 | atomic_set(&ax25_rt->ref, 0); | 116 | atomic_set(&ax25_rt->refcount, 1); |
| 119 | ax25_rt->callsign = route->dest_addr; | 117 | ax25_rt->callsign = route->dest_addr; |
| 120 | ax25_rt->dev = ax25_dev->dev; | 118 | ax25_rt->dev = ax25_dev->dev; |
| 121 | ax25_rt->digipeat = NULL; | 119 | ax25_rt->digipeat = NULL; |
| @@ -140,23 +138,10 @@ static int ax25_rt_add(struct ax25_routes_struct *route) | |||
| 140 | return 0; | 138 | return 0; |
| 141 | } | 139 | } |
| 142 | 140 | ||
| 143 | static void ax25_rt_destroy(ax25_route *ax25_rt) | 141 | void __ax25_put_route(ax25_route *ax25_rt) |
| 144 | { | 142 | { |
| 145 | if (atomic_read(&ax25_rt->ref) == 0) { | 143 | kfree(ax25_rt->digipeat); |
| 146 | kfree(ax25_rt->digipeat); | 144 | kfree(ax25_rt); |
| 147 | kfree(ax25_rt); | ||
| 148 | return; | ||
| 149 | } | ||
| 150 | |||
| 151 | /* | ||
| 152 | * Uh... Route is still in use; we can't yet destroy it. Retry later. | ||
| 153 | */ | ||
| 154 | init_timer(&ax25_rt->timer); | ||
| 155 | ax25_rt->timer.data = (unsigned long) ax25_rt; | ||
| 156 | ax25_rt->timer.function = (void *) ax25_rt_destroy; | ||
| 157 | ax25_rt->timer.expires = jiffies + 5 * HZ; | ||
| 158 | |||
| 159 | add_timer(&ax25_rt->timer); | ||
| 160 | } | 145 | } |
| 161 | 146 | ||
| 162 | static int ax25_rt_del(struct ax25_routes_struct *route) | 147 | static int ax25_rt_del(struct ax25_routes_struct *route) |
| @@ -177,12 +162,12 @@ static int ax25_rt_del(struct ax25_routes_struct *route) | |||
| 177 | ax25cmp(&route->dest_addr, &s->callsign) == 0) { | 162 | ax25cmp(&route->dest_addr, &s->callsign) == 0) { |
| 178 | if (ax25_route_list == s) { | 163 | if (ax25_route_list == s) { |
| 179 | ax25_route_list = s->next; | 164 | ax25_route_list = s->next; |
| 180 | ax25_rt_destroy(s); | 165 | ax25_put_route(s); |
| 181 | } else { | 166 | } else { |
| 182 | for (t = ax25_route_list; t != NULL; t = t->next) { | 167 | for (t = ax25_route_list; t != NULL; t = t->next) { |
| 183 | if (t->next == s) { | 168 | if (t->next == s) { |
| 184 | t->next = s->next; | 169 | t->next = s->next; |
| 185 | ax25_rt_destroy(s); | 170 | ax25_put_route(s); |
| 186 | break; | 171 | break; |
| 187 | } | 172 | } |
| 188 | } | 173 | } |
| @@ -362,7 +347,7 @@ struct file_operations ax25_route_fops = { | |||
| 362 | * | 347 | * |
| 363 | * Only routes with a reference count of zero can be destroyed. | 348 | * Only routes with a reference count of zero can be destroyed. |
| 364 | */ | 349 | */ |
| 365 | static ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev) | 350 | ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev) |
| 366 | { | 351 | { |
| 367 | ax25_route *ax25_spe_rt = NULL; | 352 | ax25_route *ax25_spe_rt = NULL; |
| 368 | ax25_route *ax25_def_rt = NULL; | 353 | ax25_route *ax25_def_rt = NULL; |
| @@ -392,7 +377,7 @@ static ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev) | |||
| 392 | ax25_rt = ax25_spe_rt; | 377 | ax25_rt = ax25_spe_rt; |
| 393 | 378 | ||
| 394 | if (ax25_rt != NULL) | 379 | if (ax25_rt != NULL) |
| 395 | atomic_inc(&ax25_rt->ref); | 380 | ax25_hold_route(ax25_rt); |
| 396 | 381 | ||
| 397 | read_unlock(&ax25_route_lock); | 382 | read_unlock(&ax25_route_lock); |
| 398 | 383 | ||
| @@ -467,24 +452,6 @@ put: | |||
| 467 | return 0; | 452 | return 0; |
| 468 | } | 453 | } |
| 469 | 454 | ||
| 470 | ax25_route *ax25_rt_find_route(ax25_route * route, ax25_address *addr, | ||
| 471 | struct net_device *dev) | ||
| 472 | { | ||
| 473 | ax25_route *ax25_rt; | ||
| 474 | |||
| 475 | if ((ax25_rt = ax25_get_route(addr, dev))) | ||
| 476 | return ax25_rt; | ||
| 477 | |||
| 478 | route->next = NULL; | ||
| 479 | atomic_set(&route->ref, 1); | ||
| 480 | route->callsign = *addr; | ||
| 481 | route->dev = dev; | ||
| 482 | route->digipeat = NULL; | ||
| 483 | route->ip_mode = ' '; | ||
| 484 | |||
| 485 | return route; | ||
| 486 | } | ||
| 487 | |||
| 488 | struct sk_buff *ax25_rt_build_path(struct sk_buff *skb, ax25_address *src, | 455 | struct sk_buff *ax25_rt_build_path(struct sk_buff *skb, ax25_address *src, |
| 489 | ax25_address *dest, ax25_digi *digi) | 456 | ax25_address *dest, ax25_digi *digi) |
| 490 | { | 457 | { |
