patch-2.1.25 linux/net/rose/rose_route.c

Next file: linux/net/rose/rose_timer.c
Previous file: linux/net/rose/rose_out.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.24/linux/net/rose/rose_route.c linux/net/rose/rose_route.c
@@ -86,8 +86,8 @@
 		rose_neigh->number    = rose_neigh_no++;
 		rose_neigh->restarted = 0;
 		skb_queue_head_init(&rose_neigh->queue);
-		rose_neigh->t0        = sysctl_rose_restart_request_timeout;
 		rose_neigh->t0timer   = 0;
+		rose_neigh->ftimer    = 0;
 		init_timer(&rose_neigh->timer);
 
 		if (rose_route->ndigis != 0) {
@@ -114,10 +114,10 @@
 	 * best match.
 	 */
 	if (rose_node == NULL) {
-
 		rose_tmpn = rose_node_list;
 		rose_tmpp = NULL;
-		while(rose_tmpn != NULL) {
+
+		while (rose_tmpn != NULL) {
 			if (rose_tmpn->mask > rose_route->mask) {
 				rose_tmpp = rose_tmpn;
 				rose_tmpn = rose_tmpn->next;
@@ -132,7 +132,6 @@
 
 		rose_node->address = rose_route->address;
 		rose_node->mask    = rose_route->mask;
-		rose_node->which   = 0;
 		rose_node->count   = 1;
 		rose_node->neighbour[0] = rose_neigh;
 
@@ -163,13 +162,9 @@
 		return 0;
 	}
 
-	/* We have space at the bottom, slot it in */
+	/* We have space, slot it in */
 	if (rose_node->count < 3) {
-		rose_node->neighbour[2] = rose_node->neighbour[1];
-		rose_node->neighbour[1] = rose_node->neighbour[0];
-
-		rose_node->neighbour[0] = rose_neigh;
-
+		rose_node->neighbour[rose_node->count] = rose_neigh;
 		rose_node->count++;
 		rose_neigh->count++;
 	}
@@ -302,7 +297,7 @@
 
 			if (rose_neigh->count == 0)
 				rose_remove_neigh(rose_neigh);
-				
+
 			rose_node->count--;
 
 			if (rose_node->count == 0) {
@@ -436,6 +431,7 @@
 struct rose_neigh *rose_get_neigh(rose_address *addr)
 {
 	struct rose_node *node;
+	int i;
 
 	for (node = rose_node_list; node != NULL; node = node->next)
 		if (rosecmpm(addr, &node->address, node->mask) == 0)
@@ -443,9 +439,11 @@
 
 	if (node == NULL) return NULL;
 
-	if (node->which >= node->count) return NULL;
+	for (i = 0; i < node->count; i++)
+		if (node->neighbour[i]->ftimer == 0)
+			return node->neighbour[i];
 
-	return node->neighbour[node->which];
+	return NULL;
 }
 
 /*
@@ -494,25 +492,22 @@
 void rose_link_failed(ax25_address *callsign, struct device *dev)
 {
 	struct rose_neigh *rose_neigh;
-	struct rose_node  *rose_node;
 	struct sk_buff    *skb;
 
 	for (rose_neigh = rose_neigh_list; rose_neigh != NULL; rose_neigh = rose_neigh->next)
 		if (ax25cmp(&rose_neigh->callsign, callsign) == 0 && rose_neigh->dev == dev)
 			break;
-			
+
 	if (rose_neigh == NULL) return;
 
 	rose_neigh->restarted = 0;
 	rose_neigh->t0timer   = 0;
-	del_timer(&rose_neigh->timer);
+	rose_neigh->ftimer    = sysctl_rose_link_fail_timeout;
+
+	rose_link_set_timer(rose_neigh);
 
 	while ((skb = skb_dequeue(&rose_neigh->queue)) != NULL)
 		kfree_skb(skb, FREE_WRITE);
-
-	for (rose_node = rose_node_list; rose_node != NULL; rose_node = rose_node->next)
-		if (rose_node->which < rose_node->count && rose_node->neighbour[rose_node->which] == rose_neigh)
-			rose_node->which++;
 }
 
 /*
@@ -521,35 +516,29 @@
 void rose_link_device_down(struct device *dev)
 {
 	struct rose_neigh *rose_neigh;
-	struct rose_node  *rose_node;
 	struct sk_buff    *skb;
 
 	for (rose_neigh = rose_neigh_list; rose_neigh != NULL; rose_neigh = rose_neigh->next) {
 		if (rose_neigh->dev == dev) {
 			rose_neigh->restarted = 0;
 			rose_neigh->t0timer   = 0;
+			rose_neigh->ftimer    = 0;
 			del_timer(&rose_neigh->timer);
 
 			while ((skb = skb_dequeue(&rose_neigh->queue)) != NULL)
 				kfree_skb(skb, FREE_WRITE);
-	
-			for (rose_node = rose_node_list; rose_node != NULL; rose_node = rose_node->next)
-				if (rose_node->which < rose_node->count && rose_node->neighbour[rose_node->which] == rose_neigh)
-					rose_node->which++;
 		}
 	}
 }
 
 /*
- *	Route a frame to an appropriate AX.25 connection. A NULL ax25_cb
- *	indicates an internally generated frame.
+ *	Route a frame to an appropriate AX.25 connection.
  */
 int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
 {
 	struct rose_neigh *rose_neigh, *new_neigh;
-	struct rose_node  *rose_node;
 	struct rose_route *rose_route;
-	rose_address *dest_addr;
+	rose_address *src_addr, *dest_addr;
 	struct sock *sk;
 	unsigned short frametype;
 	unsigned int lci;
@@ -563,6 +552,8 @@
 
 	frametype = skb->data[2];
 	lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
+	src_addr  = (rose_address *)(skb->data + 9);
+	dest_addr = (rose_address *)(skb->data + 4);
 
 	for (rose_neigh = rose_neigh_list; rose_neigh != NULL; rose_neigh = rose_neigh->next)
 		if (ax25cmp(&ax25->dest_addr, &rose_neigh->callsign) == 0 && ax25->device == rose_neigh->dev)
@@ -572,6 +563,11 @@
 		return 0;
 
 	/*
+	 *	Obviously the link is working, halt the ftimer.
+	 */
+	rose_neigh->ftimer = 0;
+
+	/*
 	 *	LCI of zero is always for us, and its always a restart
 	 * 	frame.
 	 */
@@ -591,12 +587,9 @@
 	/*
 	 *	Is is a Call Request and is it for us ?
 	 */
-	if (frametype == ROSE_CALL_REQUEST) {
-		dest_addr = (rose_address *)(skb->data + 4);
-
+	if (frametype == ROSE_CALL_REQUEST)
 		if ((dev = rose_dev_get(dest_addr)) != NULL)
 			return rose_rx_call_request(skb, dev, rose_neigh, lci);
-	}
 
 	if (!sysctl_rose_routing_control) {
 		rose_transmit_clear_request(rose_neigh, lci, 0x0D);
@@ -640,18 +633,7 @@
 	if (frametype != ROSE_CALL_REQUEST)	/* XXX */
 		return 0;
 
-	dest_addr = (rose_address *)(skb->data + 4);
-
-	/*
-	 *	Create a new route entry, if we can.
-	 */
-	for (rose_node = rose_node_list; rose_node != NULL; rose_node = rose_node->next)
-		if (rosecmpm(dest_addr, &rose_node->address, rose_node->mask) == 0)
-			break;
-	/*
-	 *	Its an unknown node, or is unreachable.
-	 */
-	if (rose_node == NULL || rose_node->which >= rose_node->count) {
+	if ((new_neigh = rose_get_neigh(dest_addr)) == NULL) {
 		rose_transmit_clear_request(rose_neigh, lci, 0x0D);
 		return 0;
 	}
@@ -661,8 +643,6 @@
 		return 0;
 	}
 
-	new_neigh = rose_node->neighbour[rose_node->which];
-
 	rose_route->lci1   = lci;
 	rose_route->neigh1 = rose_neigh;
 	rose_route->lci2   = rose_new_lci(new_neigh->dev);
@@ -693,13 +673,12 @@
 
 	cli();
 
-	len += sprintf(buffer, "address    mask w n neigh neigh neigh\n");
+	len += sprintf(buffer, "address    mask n neigh neigh neigh\n");
 
 	for (rose_node = rose_node_list; rose_node != NULL; rose_node = rose_node->next) {
-		len += sprintf(buffer + len, "%-10s %04d %d %d",
+		len += sprintf(buffer + len, "%-10s %04d %d",
 			rose2asc(&rose_node->address),
 			rose_node->mask,
-			rose_node->which + 1,
 			rose_node->count);			
 
 		for (i = 0; i < rose_node->count; i++)
@@ -739,17 +718,17 @@
 
 	cli();
 
-	len += sprintf(buffer, "addr  callsign  dev  count  restart     t0\n");
+	len += sprintf(buffer, "addr  callsign  dev  count  restart   t0   tf\n");
 
 	for (rose_neigh = rose_neigh_list; rose_neigh != NULL; rose_neigh = rose_neigh->next) {
-		len += sprintf(buffer + len, "%05d %-9s %-4s   %3d      %3s  %3d/%03d\n",
+		len += sprintf(buffer + len, "%05d %-9s %-4s   %3d      %3s  %3d  %3d\n",
 			rose_neigh->number,
 			ax2asc(&rose_neigh->callsign),
 			rose_neigh->dev ? rose_neigh->dev->name : "???",
 			rose_neigh->count,
 			(rose_neigh->restarted) ? "yes" : "no",
 			rose_neigh->t0timer / ROSE_SLOWHZ,
-			rose_neigh->t0      / ROSE_SLOWHZ);
+			rose_neigh->ftimer  / ROSE_SLOWHZ);
 
 		pos = begin + len;
 

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