patch-2.0.12 linux/net/ax25/ax25_route.c

Next file: linux/net/ax25/ax25_subr.c
Previous file: linux/net/ax25/ax25_out.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.11/linux/net/ax25/ax25_route.c linux/net/ax25/ax25_route.c
@@ -1,5 +1,5 @@
 /*
- *	AX.25 release 031
+ *	AX.25 release 032
  *
  *	This is ALPHA test software. This code may break your machine, randomly fail to work with new 
  *	releases, misbehave and/or generally screw up. It might even work. 
@@ -37,6 +37,7 @@
  *			Joerg(DL1BKE)	Fixed AX.25 routing of IP datagram and VC, new ioctl()
  *					"SIOCAX25OPTRT" to set IP mode and a 'permanent' flag
  *					on routes.
+ *	AX.25 032	Jonathan(G4KLX)	Remove auto-router.
  */
  
 #include <linux/config.h>
@@ -63,17 +64,12 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 
-#define	AX25_ROUTE_MAX	128
-
 static struct ax25_route {
 	struct ax25_route *next;
 	ax25_address callsign;
 	struct device *dev;
 	ax25_digi *digipeat;
-	struct timeval stamp;
-	int n;
 	char ip_mode;
-	char perm;
 } *ax25_route = NULL;
 
 static struct ax25_dev {
@@ -82,120 +78,22 @@
 	unsigned short values[AX25_MAX_VALUES];
 } *ax25_device = NULL;
 
-static struct ax25_route * ax25_find_route(ax25_address *addr);
+static struct ax25_route *ax25_find_route(ax25_address *, struct device *);
 
 /*
  * small macro to drop non-digipeated digipeaters and reverse path
  */
- 
 static inline void ax25_route_invert(ax25_digi *in, ax25_digi *out)
 {
 	int k;
+
 	for (k = 0; k < in->ndigi; k++)
 		if (!in->repeated[k])
 			break;
-	in->ndigi = k;
-	ax25_digi_invert(in, out);
-
-}
-
-/*
- * dl1bke 960310: new behaviour:
- *
- * * try to find an existing route to 'src', if found:
- *   - if the route was added manually don't adjust the timestamp
- *   - if this route is 'permanent' just do some statistics and return
- *   - overwrite device and digipeater path
- * * no existing route found:
- *   - try to alloc a new entry
- *   - overwrite the oldest, not manually added entry if this fails.
- *
- * * updated on reception of frames directed to us _only_
- *
- */
-
-void ax25_rt_rx_frame(ax25_address *src, struct device *dev, ax25_digi *digi)
-{
-	unsigned long flags;
-	extern struct timeval xtime;
-	struct ax25_route *ax25_rt;
-	struct ax25_route *oldest;
-	int count;
-
-	count  = 0;
-	oldest = NULL;
 
-	for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
-		if (count == 0 || oldest->stamp.tv_sec == 0 || (ax25_rt->stamp.tv_sec != 0 && ax25_rt->stamp.tv_sec < oldest->stamp.tv_sec))
-			oldest = ax25_rt;
-		
-		if (ax25cmp(&ax25_rt->callsign, src) == 0) {
-			if (ax25_rt->stamp.tv_sec != 0)
-				ax25_rt->stamp = xtime;
-
-			if (ax25_rt->perm == AX25_RT_PERMANENT) {
-				ax25_rt->n++;
-				return;
-			}
-			
-			ax25_rt->dev = dev;
-			if (digi == NULL) {
-				/* drop old digipeater list */
-				if (ax25_rt->digipeat != NULL) {
-					kfree_s(ax25_rt->digipeat, sizeof(ax25_digi));
-					ax25_rt->digipeat = NULL;
-				}
-				return;
-			}
-			
-			if (ax25_rt->digipeat == NULL && (ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL)
-					return;
-			
-			ax25_route_invert(digi, ax25_rt->digipeat);
-			return;
-		}
-
-		count++;
-	}
-
-	if (count > AX25_ROUTE_MAX) {
-		if (oldest->stamp.tv_sec == 0)
-			return;
-		if (oldest->digipeat != NULL)
-			kfree_s(oldest->digipeat, sizeof(ax25_digi));
-		ax25_rt = oldest;
-	} else {
-		if ((ax25_rt = (struct ax25_route *)kmalloc(sizeof(struct ax25_route), GFP_ATOMIC)) == NULL)
-			return;		/* No space */
-	}
-	
-	ax25_rt->callsign = *src;
-	ax25_rt->dev      = dev;
-	ax25_rt->digipeat = NULL;
-	ax25_rt->stamp    = xtime;
-	ax25_rt->n        = 1;
-	ax25_rt->ip_mode  = ' ';
-	ax25_rt->perm	  = AX25_RT_DYNAMIC;
-
-	if (digi != NULL) {
-		if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
-			kfree_s(ax25_rt, sizeof(struct ax25_route));
-			return;
-		}
-		
-		ax25_route_invert(digi, ax25_rt->digipeat);
-		/* used to be: *ax25_rt->digipeat = *digi; */
-	}
-
-	if (ax25_rt != oldest) {
-		save_flags(flags);
-		cli();
-
-		ax25_rt->next = ax25_route;
-		ax25_route    = ax25_rt;
+	in->ndigi = k;
 
-		restore_flags(flags);
-	}
+	ax25_digi_invert(in, out);
 }
 
 void ax25_rt_device_down(struct device *dev)
@@ -261,7 +159,6 @@
 							ax25_rt->digipeat->calls[i]    = route.digi_addr[i];
 						}
 					}
-					ax25_rt->stamp.tv_sec = 0;
 					return 0;
 				}
 			}
@@ -270,10 +167,7 @@
 			ax25_rt->callsign     = route.dest_addr;
 			ax25_rt->dev          = dev;
 			ax25_rt->digipeat     = NULL;
-			ax25_rt->stamp.tv_sec = 0;
-			ax25_rt->n            = 0;
 			ax25_rt->ip_mode      = ' ';
-			ax25_rt->perm	      = AX25_RT_DYNAMIC;
 			if (route.digi_count != 0) {
 				if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
 					kfree_s(ax25_rt, sizeof(struct ax25_route));
@@ -323,40 +217,36 @@
 				}
 			}
 			break;
+
 		case SIOCAX25OPTRT:
 			if ((err = verify_area(VERIFY_READ, arg, sizeof(rt_option))) != 0)
 				return err;
 			memcpy_fromfs(&rt_option, arg, sizeof(rt_option));
 			if ((dev = ax25rtr_get_dev(&rt_option.port_addr)) == NULL)
 				return -EINVAL;
-			ax25_rt = ax25_route;
-			while (ax25_rt != NULL) {
+			for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
 				if (ax25_rt->dev == dev && ax25cmp(&rt_option.dest_addr, &ax25_rt->callsign) == 0) {
-					switch(rt_option.cmd) {
-						case AX25_SET_RT_PERMANENT:
-							ax25_rt->perm = (char) rt_option.arg;
-							ax25_rt->stamp.tv_sec = 0;
-							break;
+					switch (rt_option.cmd) {
 						case AX25_SET_RT_IPMODE:
 							switch (rt_option.arg) {
-								case AX25_RT_IPMODE_DEFAULT:
-									ax25_rt->ip_mode = ' ';
-									break;
-								case AX25_RT_IPMODE_DATAGRAM:
-									ax25_rt->ip_mode = 'D';
-									break;
-								case AX25_RT_IPMODE_VC:
-									ax25_rt->ip_mode = 'V';
+								case ' ':
+								case 'D':
+								case 'V':
+									ax25_rt->ip_mode = rt_option.arg;
 									break;
 								default:
 									return -EINVAL;
 							}
 							break;
+						default:
+							return -EINVAL;
 					}
 				}
-				ax25_rt = ax25_rt->next;
 			}
 			break;
+
+		default:
+			return -EINVAL;
 	}
 
 	return 0;
@@ -373,26 +263,22 @@
   
 	cli();
 
-	len += sprintf(buffer, "callsign  dev  count time      mode F digipeaters\n");
+	len += sprintf(buffer, "callsign  dev  mode digipeaters\n");
 
 	for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
 		if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0)
 			callsign = "default";
 		else
 			callsign = ax2asc(&ax25_rt->callsign);
-		len += sprintf(buffer + len, "%-9s %-4s %5d %9d",
+		len += sprintf(buffer + len, "%-9s %-4s",
 			callsign,
-			ax25_rt->dev ? ax25_rt->dev->name : "???",
-			ax25_rt->n,
-			ax25_rt->stamp.tv_sec);
+			ax25_rt->dev ? ax25_rt->dev->name : "???");
 
 		switch (ax25_rt->ip_mode) {
 			case 'V':
-			case 'v':
 				len += sprintf(buffer + len, "   vc");
 				break;
 			case 'D':
-			case 'd':
 				len += sprintf(buffer + len, "   dg");
 				break;
 			default:
@@ -400,20 +286,6 @@
 				break;
 		}
 		
-		switch (ax25_rt->perm) {
-			case AX25_RT_DYNAMIC:
-				if (ax25_rt->stamp.tv_sec == 0)
-					len += sprintf(buffer + len, " M");
-				else
-					len += sprintf(buffer + len, "  ");
-				break;
-			case AX25_RT_PERMANENT:
-				len += sprintf(buffer + len, " P");
-				break;
-			default:
-				len += sprintf(buffer + len, " ?");
-		}
-
 		if (ax25_rt->digipeat != NULL)
 			for (i = 0; i < ax25_rt->digipeat->ndigi; i++)
 				len += sprintf(buffer + len, " %s", ax2asc(&ax25_rt->digipeat->calls[i]));
@@ -479,8 +351,7 @@
 /*
  *	Find AX.25 route
  */
- 
-static struct ax25_route * ax25_find_route(ax25_address *addr)
+static struct ax25_route *ax25_find_route(ax25_address *addr, struct device *dev)
 {
 	struct ax25_route *ax25_spe_rt = NULL;
 	struct ax25_route *ax25_def_rt = NULL;
@@ -491,10 +362,17 @@
 	 *	route if none is found;
 	 */
 	for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
-		if (ax25cmp(&ax25_rt->callsign, addr) == 0 && ax25_rt->dev != NULL)
-			ax25_spe_rt = ax25_rt;
-		if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0 && ax25_rt->dev != NULL)
-			ax25_def_rt = ax25_rt;
+		if (dev == NULL) {
+			if (ax25cmp(&ax25_rt->callsign, addr) == 0 && ax25_rt->dev != NULL)
+				ax25_spe_rt = ax25_rt;
+			if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0 && ax25_rt->dev != NULL)
+				ax25_def_rt = ax25_rt;
+		} else {
+			if (ax25cmp(&ax25_rt->callsign, addr) == 0 && ax25_rt->dev == dev)
+				ax25_spe_rt = ax25_rt;
+			if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0 && ax25_rt->dev == dev)
+				ax25_def_rt = ax25_rt;
+		}
 	}
 
 	if (ax25_spe_rt != NULL)
@@ -508,7 +386,6 @@
  *      a target on the digipeater path but w/o having a special route
  *	set before, the path has to be truncated from your target on.
  */
- 
 static inline void ax25_adjust_path(ax25_address *addr, ax25_digi *digipeat)
 {
 	int k;
@@ -530,14 +407,14 @@
 	struct ax25_route *ax25_rt;
 	ax25_address *call;
 
-	if ((ax25_rt = ax25_find_route(addr)) == NULL)
+	if ((ax25_rt = ax25_find_route(addr, NULL)) == NULL)
 		return -EHOSTUNREACH;
 		
+	ax25->device = ax25_rt->dev;
+
 	if ((call = ax25_findbyuid(current->euid)) == NULL) {
 		if (ax25_uid_policy && !suser())
 			return -EPERM;
-		if (ax25->device == NULL)
-			return -ENODEV;
 		call = (ax25_address *)ax25->device->dev_addr;
 	}
 
@@ -560,19 +437,20 @@
  *	dl1bke 960117: build digipeater path
  *	dl1bke 960301: use the default route if it exists
  */
-void ax25_rt_build_path(ax25_cb *ax25, ax25_address *addr)
+void ax25_rt_build_path(ax25_cb *ax25, ax25_address *addr, struct device *dev)
 {
 	struct ax25_route *ax25_rt;
 	
-	ax25_rt = ax25_find_route(addr);
+	if ((ax25_rt = ax25_find_route(addr, dev)) == NULL)
+		return;
 	
-	if (ax25_rt == NULL || ax25_rt->digipeat == NULL)
+	if (ax25_rt->digipeat == NULL)
 		return;
 
 	if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL)
 		return;
 
-	ax25->device = ax25_rt->dev;
+	ax25->device    = ax25_rt->dev;
 	*ax25->digipeat = *ax25_rt->digipeat;
 	ax25_adjust_path(addr, ax25->digipeat);
 }
@@ -587,8 +465,10 @@
 
 	skb_pull(skb, 1);	/* skip KISS command */
 
-	ax25_rt = ax25_find_route(addr);
-	if (ax25_rt == NULL || ax25_rt->digipeat == NULL)
+	if ((ax25_rt = ax25_find_route(addr, dev)) == NULL)
+		return;
+
+	if (ax25_rt->digipeat == NULL)
 		return;
 		
 	digipeat = *ax25_rt->digipeat;
@@ -611,22 +491,6 @@
 }
 
 /*
- *	Register the mode of an incoming IP frame. It is assumed that an entry
- *	already exists in the routing table.
- */
-void ax25_ip_mode_set(ax25_address *callsign, struct device *dev, char ip_mode)
-{
-	struct ax25_route *ax25_rt;
-
-	for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
-		if (ax25cmp(&ax25_rt->callsign, callsign) == 0 && ax25_rt->dev == dev) {
-			ax25_rt->ip_mode = ip_mode;
-			return;
-		}
-	}
-}
-
-/*
  *	Return the IP mode of a given callsign/device pair.
  */
 char ax25_ip_mode_get(ax25_address *callsign, struct device *dev)
@@ -908,6 +772,9 @@
 			ax25_bpqdev  = bpqdev;
 			restore_flags(flags);
 			break;
+			
+		default:
+			return -EINVAL;
 	}
 
 	return 0;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov