Hi,
This patch introduces a test to determine if a neighbor node with a
given ROSE address is already connected and if so returns its address.
The previous test was only performed on timer t0 and not on parameter
restarted that is true when a node is connected.
Also, previously the test was not performed on the whole node list.
A new function __rose_get_neigh() is introduced to cure a spin lock
conflict related to rose_node_list_lock.
signed off by Alexey Dobriyan,[EMAIL PROTECTED]
signed off by Bernard Pidoux, f6bvp @ amsat.org
--- linux-2.6.24-rc5/include/net/rose.h 2007-12-11 04:48:43.000000000 +0100
+++ b/include/net/rose.h 2007-12-14 14:25:02.000000000 +0100
@@ -202,6 +202,7 @@
extern struct net_device *rose_dev_get(rose_address *);
extern struct rose_route *rose_route_free_lci(unsigned int, struct rose_neigh
*);
extern struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *,
unsigned char *);
+extern struct rose_neigh *__rose_get_neigh(rose_address *, unsigned char *,
unsigned char *);
extern int rose_rt_ioctl(unsigned int, void __user *);
extern void rose_link_failed(ax25_cb *, int);
extern int rose_route_frame(struct sk_buff *, ax25_cb *);
--- linux-2.6.24-rc5/net/rose/rose_route.c 2007-12-11 04:48:43.000000000
+0100
+++ b/net/rose/rose_route.c 2007-12-14 14:25:02.000000000 +0100
@@ -664,25 +664,22 @@
/*
* Find a neighbour 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)
{
- struct rose_neigh *res = NULL;
struct rose_node *node;
int failed = 0;
int i;
- spin_lock_bh(&rose_node_list_lock);
for (node = rose_node_list; node != NULL; node = node->next) {
if (rosecmpm(addr, &node->address, node->mask) == 0) {
for (i = 0; i < node->count; i++) {
- if (!rose_ftimer_running(node->neighbour[i])) {
- res = node->neighbour[i];
- goto out;
- } else
- failed = 1;
+ if (node->neighbour[i]->restarted)
+ return node->neighbour[i];
+ if (!rose_ftimer_running(node->neighbour[i]))
+ return node->neighbour[i];
+ failed = 1;
}
- break;
}
}
@@ -694,7 +691,16 @@
*diagnostic = 0;
}
-out:
+ return NULL;
+}
+
+struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+ unsigned char *diagnostic)
+{
+ struct rose_neigh *res;
+
+ spin_lock_bh(&rose_node_list_lock);
+ res = __rose_get_neigh(addr, cause, diagnostic);
spin_unlock_bh(&rose_node_list_lock);
return res;
@@ -1019,7 +1025,7 @@
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)) ==
NULL) {
rose_transmit_clear_request(rose_neigh, lci, cause, diagnostic);
goto out;
}
--- linux-2.6.24-rc5/net/rose/af_rose.c 2007-12-11 04:48:43.000000000 +0100
+++ b/net/rose/af_rose.c 2007-12-14 14:25:02.000000000 +0100
@@ -750,7 +750,7 @@
sk->sk_state = TCP_CLOSE;
sock->state = SS_UNCONNECTED;
- rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause,
+ rose->neighbour = __rose_get_neigh(&addr->srose_addr, &cause,
&diagnostic);
if (!rose->neighbour)
return -ENETUNREACH;