|
@@ -662,27 +662,34 @@ struct rose_route *rose_route_free_lci(unsigned int lci, struct rose_neigh *neig
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
- * Find a neighbour given a ROSE address.
|
|
|
|
|
|
+ * Find a neighbour or a route given a ROSE address.
|
|
*/
|
|
*/
|
|
struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
|
|
struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
|
|
- unsigned char *diagnostic)
|
|
|
|
|
|
+ unsigned char *diagnostic, int new)
|
|
{
|
|
{
|
|
struct rose_neigh *res = NULL;
|
|
struct rose_neigh *res = NULL;
|
|
struct rose_node *node;
|
|
struct rose_node *node;
|
|
int failed = 0;
|
|
int failed = 0;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
- spin_lock_bh(&rose_node_list_lock);
|
|
|
|
|
|
+ if (!new) spin_lock_bh(&rose_node_list_lock);
|
|
for (node = rose_node_list; node != NULL; node = node->next) {
|
|
for (node = rose_node_list; node != NULL; node = node->next) {
|
|
if (rosecmpm(addr, &node->address, node->mask) == 0) {
|
|
if (rosecmpm(addr, &node->address, node->mask) == 0) {
|
|
for (i = 0; i < node->count; i++) {
|
|
for (i = 0; i < node->count; i++) {
|
|
- if (!rose_ftimer_running(node->neighbour[i])) {
|
|
|
|
- res = node->neighbour[i];
|
|
|
|
- goto out;
|
|
|
|
- } else
|
|
|
|
- failed = 1;
|
|
|
|
|
|
+ if (new) {
|
|
|
|
+ if (node->neighbour[i]->restarted) {
|
|
|
|
+ res = node->neighbour[i];
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ if (!rose_ftimer_running(node->neighbour[i])) {
|
|
|
|
+ res = node->neighbour[i];
|
|
|
|
+ goto out;
|
|
|
|
+ } else
|
|
|
|
+ failed = 1;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- break;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -695,7 +702,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
|
|
}
|
|
}
|
|
|
|
|
|
out:
|
|
out:
|
|
- spin_unlock_bh(&rose_node_list_lock);
|
|
|
|
|
|
+ if (!new) spin_unlock_bh(&rose_node_list_lock);
|
|
|
|
|
|
return res;
|
|
return res;
|
|
}
|
|
}
|
|
@@ -1018,7 +1025,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
|
|
rose_route = rose_route->next;
|
|
rose_route = rose_route->next;
|
|
}
|
|
}
|
|
|
|
|
|
- if ((new_neigh = rose_get_neigh(dest_addr, &cause, &diagnostic)) == NULL) {
|
|
|
|
|
|
+ if ((new_neigh = rose_get_neigh(dest_addr, &cause, &diagnostic, 1)) == NULL) {
|
|
rose_transmit_clear_request(rose_neigh, lci, cause, diagnostic);
|
|
rose_transmit_clear_request(rose_neigh, lci, cause, diagnostic);
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|