aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/rose.h2
-rw-r--r--net/rose/af_rose.c4
-rw-r--r--net/rose/rose_route.c29
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 *);
201extern struct net_device *rose_dev_first(void); 201extern struct net_device *rose_dev_first(void);
202extern struct net_device *rose_dev_get(rose_address *); 202extern struct net_device *rose_dev_get(rose_address *);
203extern struct rose_route *rose_route_free_lci(unsigned int, struct rose_neigh *); 203extern struct rose_route *rose_route_free_lci(unsigned int, struct rose_neigh *);
204extern struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *, unsigned char *); 204extern struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *, unsigned char *, int);
205extern int rose_rt_ioctl(unsigned int, void __user *); 205extern int rose_rt_ioctl(unsigned int, void __user *);
206extern void rose_link_failed(ax25_cb *, int); 206extern void rose_link_failed(ax25_cb *, int);
207extern int rose_route_frame(struct sk_buff *, ax25_cb *); 207extern 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 */
667struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause, 667struct 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
697out: 704out:
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 }