diff options
Diffstat (limited to 'net/ax25')
| -rw-r--r-- | net/ax25/ax25_ip.c | 23 | ||||
| -rw-r--r-- | net/ax25/ax25_route.c | 49 | 
2 files changed, 23 insertions, 49 deletions
| diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c index 9be5c15e63d3..136c3aefa9de 100644 --- a/net/ax25/ax25_ip.c +++ b/net/ax25/ax25_ip.c @@ -103,11 +103,13 @@ int ax25_rebuild_header(struct sk_buff *skb)  {  	struct sk_buff *ourskb;  	unsigned char *bp  = skb->data; -	struct net_device *dev; +	ax25_route *route; +	struct net_device *dev = NULL;  	ax25_address *src, *dst; +	ax25_digi *digipeat = NULL;  	ax25_dev *ax25_dev; -	ax25_route _route, *route = &_route;  	ax25_cb *ax25; +	char ip_mode = ' ';  	dst = (ax25_address *)(bp + 1);  	src = (ax25_address *)(bp + 8); @@ -115,8 +117,12 @@ int ax25_rebuild_header(struct sk_buff *skb)    	if (arp_find(bp + 1, skb))    		return 1; -	route = ax25_rt_find_route(route, dst, NULL); -	dev      = route->dev; +	route = ax25_get_route(dst, NULL); +	if (route) { +		digipeat = route->digipeat; +		dev = route->dev; +		ip_mode = route->ip_mode; +	};  	if (dev == NULL)  		dev = skb->dev; @@ -126,7 +132,7 @@ int ax25_rebuild_header(struct sk_buff *skb)  	}  	if (bp[16] == AX25_P_IP) { -		if (route->ip_mode == 'V' || (route->ip_mode == ' ' && ax25_dev->values[AX25_VALUES_IPDEFMODE])) { +		if (ip_mode == 'V' || (ip_mode == ' ' && ax25_dev->values[AX25_VALUES_IPDEFMODE])) {  			/*  			 *	We copy the buffer and release the original thereby  			 *	keeping it straight @@ -172,7 +178,7 @@ int ax25_rebuild_header(struct sk_buff *skb)  			    ourskb,   			    ax25_dev->values[AX25_VALUES_PACLEN],   			    &src_c, -			    &dst_c, route->digipeat, dev); +			    &dst_c, digipeat, dev);  			if (ax25) {  				ax25_cb_put(ax25);  			} @@ -190,7 +196,7 @@ int ax25_rebuild_header(struct sk_buff *skb)  	skb_pull(skb, AX25_KISS_HEADER_LEN); -	if (route->digipeat != NULL) { +	if (digipeat != NULL) {  		if ((ourskb = ax25_rt_build_path(skb, src, dst, route->digipeat)) == NULL) {  			kfree_skb(skb);  			goto put; @@ -202,7 +208,8 @@ int ax25_rebuild_header(struct sk_buff *skb)  	ax25_queue_xmit(skb, dev);  put: -	ax25_put_route(route); +	if (route) +		ax25_put_route(route);    	return 1;  } diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c index 5ac98250797b..51b7bdaf27eb 100644 --- a/net/ax25/ax25_route.c +++ b/net/ax25/ax25_route.c @@ -41,8 +41,6 @@  static ax25_route *ax25_route_list;  static DEFINE_RWLOCK(ax25_route_lock); -static ax25_route *ax25_get_route(ax25_address *, struct net_device *); -  void ax25_rt_device_down(struct net_device *dev)  {  	ax25_route *s, *t, *ax25_rt; @@ -115,7 +113,7 @@ static int ax25_rt_add(struct ax25_routes_struct *route)  		return -ENOMEM;  	} -	atomic_set(&ax25_rt->ref, 0); +	atomic_set(&ax25_rt->refcount, 1);  	ax25_rt->callsign     = route->dest_addr;  	ax25_rt->dev          = ax25_dev->dev;  	ax25_rt->digipeat     = NULL; @@ -140,23 +138,10 @@ static int ax25_rt_add(struct ax25_routes_struct *route)  	return 0;  } -static void ax25_rt_destroy(ax25_route *ax25_rt) +void __ax25_put_route(ax25_route *ax25_rt)  { -	if (atomic_read(&ax25_rt->ref) == 0) { -		kfree(ax25_rt->digipeat); -		kfree(ax25_rt); -		return; -	} - -	/* -	 * Uh...  Route is still in use; we can't yet destroy it.  Retry later. -	 */ -	init_timer(&ax25_rt->timer); -	ax25_rt->timer.data	= (unsigned long) ax25_rt; -	ax25_rt->timer.function	= (void *) ax25_rt_destroy; -	ax25_rt->timer.expires	= jiffies + 5 * HZ; - -	add_timer(&ax25_rt->timer); +	kfree(ax25_rt->digipeat); +	kfree(ax25_rt);  }  static int ax25_rt_del(struct ax25_routes_struct *route) @@ -177,12 +162,12 @@ static int ax25_rt_del(struct ax25_routes_struct *route)  		    ax25cmp(&route->dest_addr, &s->callsign) == 0) {  			if (ax25_route_list == s) {  				ax25_route_list = s->next; -				ax25_rt_destroy(s); +				ax25_put_route(s);  			} else {  				for (t = ax25_route_list; t != NULL; t = t->next) {  					if (t->next == s) {  						t->next = s->next; -						ax25_rt_destroy(s); +						ax25_put_route(s);  						break;  					}  				} @@ -362,7 +347,7 @@ struct file_operations ax25_route_fops = {   *   *	Only routes with a reference count of zero can be destroyed.   */ -static ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev) +ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev)  {  	ax25_route *ax25_spe_rt = NULL;  	ax25_route *ax25_def_rt = NULL; @@ -392,7 +377,7 @@ static ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev)  		ax25_rt = ax25_spe_rt;  	if (ax25_rt != NULL) -		atomic_inc(&ax25_rt->ref); +		ax25_hold_route(ax25_rt);  	read_unlock(&ax25_route_lock); @@ -467,24 +452,6 @@ put:  	return 0;  } -ax25_route *ax25_rt_find_route(ax25_route * route, ax25_address *addr, -	struct net_device *dev) -{ -	ax25_route *ax25_rt; - -	if ((ax25_rt = ax25_get_route(addr, dev))) -		return ax25_rt; - -	route->next     = NULL; -	atomic_set(&route->ref, 1); -	route->callsign = *addr; -	route->dev      = dev; -	route->digipeat = NULL; -	route->ip_mode  = ' '; - -	return route; -} -  struct sk_buff *ax25_rt_build_path(struct sk_buff *skb, ax25_address *src,  	ax25_address *dest, ax25_digi *digi)  { | 
