patch-2.1.17 linux/net/rose/rose_route.c
Next file: linux/net/unix/af_unix.c
Previous file: linux/net/rose/rose_out.c
Back to the patch index
Back to the overall index
- Lines: 144
- Date:
Thu Dec 19 10:32:57 1996
- Orig file:
v2.1.16/linux/net/rose/rose_route.c
- Orig date:
Tue Nov 12 15:56:17 1996
diff -u --recursive --new-file v2.1.16/linux/net/rose/rose_route.c linux/net/rose/rose_route.c
@@ -14,6 +14,8 @@
*
* History
* Rose 001 Jonathan(G4KLX) Cloned from nr_route.c.
+ * Terry(VK2KTJ) Added support for variable length
+ * address masks.
*/
#include <linux/config.h>
@@ -60,13 +62,13 @@
*/
static int rose_add_node(struct rose_route_struct *rose_route, struct device *dev)
{
- struct rose_node *rose_node;
+ struct rose_node *rose_node, *rose_tmpn, *rose_tmpp;
struct rose_neigh *rose_neigh;
unsigned long flags;
int i;
for (rose_node = rose_node_list; rose_node != NULL; rose_node = rose_node->next)
- if (rosecmp(&rose_route->address, &rose_node->address) == 0)
+ if ((rose_node->mask == rose_route->mask) && (rosecmpm(&rose_route->address, &rose_node->address, rose_route->mask) == 0))
break;
for (rose_neigh = rose_neigh_list; rose_neigh != NULL; rose_neigh = rose_neigh->next)
@@ -104,19 +106,56 @@
restore_flags(flags);
}
+ /*
+ * This is a new node to be inserted into the list. Find where it needs
+ * to be inserted into the list, and insert it. We want to be sure
+ * to order the list in descending order of mask size to ensure that
+ * later when we are searching this list the first match will be the
+ * best match.
+ */
if (rose_node == NULL) {
+
+ rose_tmpn = rose_node_list;
+ rose_tmpp = NULL;
+ while(rose_tmpn != NULL) {
+ if (rose_tmpn->mask > rose_route->mask) {
+ rose_tmpp = rose_tmpn;
+ rose_tmpn = rose_tmpn->next;
+ } else {
+ break;
+ }
+ }
+
+ /* create new node */
if ((rose_node = (struct rose_node *)kmalloc(sizeof(*rose_node), GFP_ATOMIC)) == NULL)
return -ENOMEM;
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;
-
+
save_flags(flags); cli();
- rose_node->next = rose_node_list;
- rose_node_list = rose_node;
+
+ if (rose_tmpn == NULL) {
+ if (rose_tmpp == NULL) { /* Empty list */
+ rose_node_list = rose_node;
+ rose_node->next = NULL;
+ } else {
+ rose_tmpp->next = rose_node;
+ rose_node->next = NULL;
+ }
+ } else {
+ if (rose_tmpp == NULL) { /* 1st node */
+ rose_node->next = rose_node_list;
+ rose_node_list = rose_node;
+ } else {
+ rose_tmpp->next = rose_node;
+ rose_node->next = rose_tmpn;
+ }
+ }
+
restore_flags(flags);
rose_neigh->count++;
@@ -246,7 +285,7 @@
int i;
for (rose_node = rose_node_list; rose_node != NULL; rose_node = rose_node->next)
- if (rosecmp(&rose_route->address, &rose_node->address) == 0)
+ if ((rose_node->mask == rose_route->mask) && (rosecmpm(&rose_route->address, &rose_node->address, rose_route->mask) == 0))
break;
if (rose_node == NULL) return -EINVAL;
@@ -397,11 +436,11 @@
struct rose_neigh *rose_get_neigh(rose_address *addr)
{
struct rose_node *node;
-
+
for (node = rose_node_list; node != NULL; node = node->next)
- if (rosecmp(&node->address, addr) == 0)
+ if (rosecmpm(addr, &node->address, node->mask) == 0)
break;
-
+
if (node == NULL) return NULL;
if (node->which >= node->count) return NULL;
@@ -428,6 +467,9 @@
return -EINVAL;
if (rose_dev_get(&rose_route.address) != NULL) /* Can't add routes to ourself */
return -EINVAL;
+ if (rose_route.mask > 10) /* Mask can't be more than 10 digits */
+ return -EINVAL;
+
return rose_add_node(&rose_route, dev);
case SIOCDELRT:
@@ -604,7 +646,7 @@
* Create a new route entry, if we can.
*/
for (rose_node = rose_node_list; rose_node != NULL; rose_node = rose_node->next)
- if (rosecmp(&rose_node->address, dest_addr) == 0)
+ if (rosecmpm(dest_addr, &rose_node->address, rose_node->mask) == 0)
break;
/*
* Its an unknown node, or is unreachable.
@@ -651,11 +693,12 @@
cli();
- len += sprintf(buffer, "address w n neigh neigh neigh\n");
+ len += sprintf(buffer, "address mask w n neigh neigh neigh\n");
for (rose_node = rose_node_list; rose_node != NULL; rose_node = rose_node->next) {
- len += sprintf(buffer + len, "%-10s %d %d",
+ len += sprintf(buffer + len, "%-10s %04d %d %d",
rose2asc(&rose_node->address),
+ rose_node->mask,
rose_node->which + 1,
rose_node->count);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov