proper test for routing frames in rose_get_neigh()
Subsystems (2)
PATCH 1/1 proper test for routing frames in rose_get_neigh()
rose_get_neigh() is called either by rose_connect() or by rose_route_frame(). In the first case it checks f0 timer to find if a connection is in wait state. In that case it returns a NULL otherwise it returns the address of the neighbour.
When called by rose_route_frame() the idea was to route a packet through an adjacent node given a destination rose address.
However in that case t0 timer does not tell if the adjacent node is already connected even if the timer is null.
A second conditional loop is added to check rose_neigh "restarted" structure field for this is the one that is set when a neighbour is connected. When the argument 'new' is null the function knows it is called by rose_route frame. If an adjacent node routing the requested route address is already connected, rose_get_neigh() returns its address, otherwise it returns a NULL. In that case the calling function will initiate a new connection.
--- include/net/rose.h | 2 +- net/rose/af_rose.c | 4 ++-- net/rose/rose_route.c | 29 ++++++++++++++++++----------- 3 files changed, 21 insertions(+), 14 deletions(-)
include/net/rose.h +1 -1
@@ -201,7 +201,7 @@ extern void rose_link_device_down(struct net_device *);extern struct net_device *rose_dev_first (void );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 *,int );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 *);
net/rose/af_rose.c +2 -2
@@ -759,7 +759,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le sock->state =SS_UNCONNECTED ; rose->neighbour =rose_get_neigh (&addr->srose_addr, &cause, - &diagnostic); + &diagnostic,0 );if (!rose->neighbour) { err = -ENETUNREACH ; goto out_release;
@@ -855,7 +855,7 @@ rose_try_next_neigh:if (sk->sk_state !=TCP_ESTABLISHED ) {/* Try next neighbour */ - rose->neighbour =rose_get_neigh (&addr->srose_addr, &cause, &diagnostic); + rose->neighbour =rose_get_neigh (&addr->srose_addr, &cause, &diagnostic,0 );if (rose->neighbour) goto rose_try_next_neigh;
net/rose/rose_route.c +18 -11
@@ -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, -unsigned char *diagnostic) +unsigned char *diagnostic,int new) {struct rose_neigh *res =NULL ;struct rose_node *node;int failed =0 ;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) {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 (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: -spin_unlock_bh (&rose_node_list_lock); +if (!new)spin_unlock_bh (&rose_node_list_lock);return res; }
@@ -1018,7 +1025,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) 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); goto out; }
Signature · 1 line
1.5.5