diff options
-rw-r--r-- | include/net/rose.h | 2 | ||||
-rw-r--r-- | net/rose/af_rose.c | 4 | ||||
-rw-r--r-- | net/rose/rose_route.c | 29 |
3 files changed, 21 insertions, 14 deletions
diff --git a/include/net/rose.h b/include/net/rose.h index e5bb084d8754..cbd5364b2c8a 100644 --- a/include/net/rose.h +++ b/include/net/rose.h | |||
@@ -201,7 +201,7 @@ extern void rose_link_device_down(struct net_device *); | |||
201 | extern struct net_device *rose_dev_first(void); | 201 | extern struct net_device *rose_dev_first(void); |
202 | extern struct net_device *rose_dev_get(rose_address *); | 202 | extern struct net_device *rose_dev_get(rose_address *); |
203 | extern struct rose_route *rose_route_free_lci(unsigned int, struct rose_neigh *); | 203 | extern struct rose_route *rose_route_free_lci(unsigned int, struct rose_neigh *); |
204 | extern struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *, unsigned char *); | 204 | extern struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *, unsigned char *, int); |
205 | extern int rose_rt_ioctl(unsigned int, void __user *); | 205 | extern int rose_rt_ioctl(unsigned int, void __user *); |
206 | extern void rose_link_failed(ax25_cb *, int); | 206 | extern void rose_link_failed(ax25_cb *, int); |
207 | extern int rose_route_frame(struct sk_buff *, ax25_cb *); | 207 | extern int rose_route_frame(struct sk_buff *, ax25_cb *); |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index af86bcb604e5..46461a69cd0f 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -757,7 +757,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le | |||
757 | sock->state = SS_UNCONNECTED; | 757 | sock->state = SS_UNCONNECTED; |
758 | 758 | ||
759 | rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause, | 759 | rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause, |
760 | &diagnostic); | 760 | &diagnostic, 0); |
761 | if (!rose->neighbour) { | 761 | if (!rose->neighbour) { |
762 | err = -ENETUNREACH; | 762 | err = -ENETUNREACH; |
763 | goto out_release; | 763 | goto out_release; |
@@ -853,7 +853,7 @@ rose_try_next_neigh: | |||
853 | 853 | ||
854 | if (sk->sk_state != TCP_ESTABLISHED) { | 854 | if (sk->sk_state != TCP_ESTABLISHED) { |
855 | /* Try next neighbour */ | 855 | /* Try next neighbour */ |
856 | rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause, &diagnostic); | 856 | rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause, &diagnostic, 0); |
857 | if (rose->neighbour) | 857 | if (rose->neighbour) |
858 | goto rose_try_next_neigh; | 858 | goto rose_try_next_neigh; |
859 | 859 | ||
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index bd593871c81e..a81066a1010a 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c | |||
@@ -662,27 +662,34 @@ struct rose_route *rose_route_free_lci(unsigned int lci, struct rose_neigh *neig | |||
662 | } | 662 | } |
663 | 663 | ||
664 | /* | 664 | /* |
665 | * Find a neighbour given a ROSE address. | 665 | * Find a neighbour or a route given a ROSE address. |
666 | */ | 666 | */ |
667 | struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause, | 667 | struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause, |
668 | unsigned char *diagnostic) | 668 | unsigned char *diagnostic, int new) |
669 | { | 669 | { |
670 | struct rose_neigh *res = NULL; | 670 | struct rose_neigh *res = NULL; |
671 | struct rose_node *node; | 671 | struct rose_node *node; |
672 | int failed = 0; | 672 | int failed = 0; |
673 | int i; | 673 | int i; |
674 | 674 | ||
675 | spin_lock_bh(&rose_node_list_lock); | 675 | if (!new) spin_lock_bh(&rose_node_list_lock); |
676 | for (node = rose_node_list; node != NULL; node = node->next) { | 676 | for (node = rose_node_list; node != NULL; node = node->next) { |
677 | if (rosecmpm(addr, &node->address, node->mask) == 0) { | 677 | if (rosecmpm(addr, &node->address, node->mask) == 0) { |
678 | for (i = 0; i < node->count; i++) { | 678 | for (i = 0; i < node->count; i++) { |
679 | if (!rose_ftimer_running(node->neighbour[i])) { | 679 | if (new) { |
680 | res = node->neighbour[i]; | 680 | if (node->neighbour[i]->restarted) { |
681 | goto out; | 681 | res = node->neighbour[i]; |
682 | } else | 682 | goto out; |
683 | failed = 1; | 683 | } |
684 | } | ||
685 | else { | ||
686 | if (!rose_ftimer_running(node->neighbour[i])) { | ||
687 | res = node->neighbour[i]; | ||
688 | goto out; | ||
689 | } else | ||
690 | failed = 1; | ||
691 | } | ||
684 | } | 692 | } |
685 | break; | ||
686 | } | 693 | } |
687 | } | 694 | } |
688 | 695 | ||
@@ -695,7 +702,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause, | |||
695 | } | 702 | } |
696 | 703 | ||
697 | out: | 704 | out: |
698 | spin_unlock_bh(&rose_node_list_lock); | 705 | if (!new) spin_unlock_bh(&rose_node_list_lock); |
699 | 706 | ||
700 | return res; | 707 | return res; |
701 | } | 708 | } |
@@ -1018,7 +1025,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) | |||
1018 | rose_route = rose_route->next; | 1025 | rose_route = rose_route->next; |
1019 | } | 1026 | } |
1020 | 1027 | ||
1021 | if ((new_neigh = rose_get_neigh(dest_addr, &cause, &diagnostic)) == NULL) { | 1028 | if ((new_neigh = rose_get_neigh(dest_addr, &cause, &diagnostic, 1)) == NULL) { |
1022 | rose_transmit_clear_request(rose_neigh, lci, cause, diagnostic); | 1029 | rose_transmit_clear_request(rose_neigh, lci, cause, diagnostic); |
1023 | goto out; | 1030 | goto out; |
1024 | } | 1031 | } |