diff options
Diffstat (limited to 'net/ax25/ax25_route.c')
| -rw-r--r-- | net/ax25/ax25_route.c | 19 |
1 files changed, 8 insertions, 11 deletions
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c index a0eff323af12..66f74c85cf6b 100644 --- a/net/ax25/ax25_route.c +++ b/net/ax25/ax25_route.c | |||
| @@ -40,7 +40,7 @@ | |||
| 40 | #include <linux/export.h> | 40 | #include <linux/export.h> |
| 41 | 41 | ||
| 42 | static ax25_route *ax25_route_list; | 42 | static ax25_route *ax25_route_list; |
| 43 | static DEFINE_RWLOCK(ax25_route_lock); | 43 | DEFINE_RWLOCK(ax25_route_lock); |
| 44 | 44 | ||
| 45 | void ax25_rt_device_down(struct net_device *dev) | 45 | void ax25_rt_device_down(struct net_device *dev) |
| 46 | { | 46 | { |
| @@ -335,6 +335,7 @@ const struct seq_operations ax25_rt_seqops = { | |||
| 335 | * Find AX.25 route | 335 | * Find AX.25 route |
| 336 | * | 336 | * |
| 337 | * Only routes with a reference count of zero can be destroyed. | 337 | * Only routes with a reference count of zero can be destroyed. |
| 338 | * Must be called with ax25_route_lock read locked. | ||
| 338 | */ | 339 | */ |
| 339 | ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev) | 340 | ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev) |
| 340 | { | 341 | { |
| @@ -342,7 +343,6 @@ ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev) | |||
| 342 | ax25_route *ax25_def_rt = NULL; | 343 | ax25_route *ax25_def_rt = NULL; |
| 343 | ax25_route *ax25_rt; | 344 | ax25_route *ax25_rt; |
| 344 | 345 | ||
| 345 | read_lock(&ax25_route_lock); | ||
| 346 | /* | 346 | /* |
| 347 | * Bind to the physical interface we heard them on, or the default | 347 | * Bind to the physical interface we heard them on, or the default |
| 348 | * route if none is found; | 348 | * route if none is found; |
| @@ -365,11 +365,6 @@ ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev) | |||
| 365 | if (ax25_spe_rt != NULL) | 365 | if (ax25_spe_rt != NULL) |
| 366 | ax25_rt = ax25_spe_rt; | 366 | ax25_rt = ax25_spe_rt; |
| 367 | 367 | ||
| 368 | if (ax25_rt != NULL) | ||
| 369 | ax25_hold_route(ax25_rt); | ||
| 370 | |||
| 371 | read_unlock(&ax25_route_lock); | ||
| 372 | |||
| 373 | return ax25_rt; | 368 | return ax25_rt; |
| 374 | } | 369 | } |
| 375 | 370 | ||
| @@ -400,9 +395,12 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr) | |||
| 400 | ax25_route *ax25_rt; | 395 | ax25_route *ax25_rt; |
| 401 | int err = 0; | 396 | int err = 0; |
| 402 | 397 | ||
| 403 | if ((ax25_rt = ax25_get_route(addr, NULL)) == NULL) | 398 | ax25_route_lock_use(); |
| 399 | ax25_rt = ax25_get_route(addr, NULL); | ||
| 400 | if (!ax25_rt) { | ||
| 401 | ax25_route_lock_unuse(); | ||
| 404 | return -EHOSTUNREACH; | 402 | return -EHOSTUNREACH; |
| 405 | 403 | } | |
| 406 | if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL) { | 404 | if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL) { |
| 407 | err = -EHOSTUNREACH; | 405 | err = -EHOSTUNREACH; |
| 408 | goto put; | 406 | goto put; |
| @@ -437,8 +435,7 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr) | |||
| 437 | } | 435 | } |
| 438 | 436 | ||
| 439 | put: | 437 | put: |
| 440 | ax25_put_route(ax25_rt); | 438 | ax25_route_lock_unuse(); |
| 441 | |||
| 442 | return err; | 439 | return err; |
| 443 | } | 440 | } |
| 444 | 441 | ||
