aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@cc.helsinki.fi>1993-12-27 13:22:44 +0000
committerNicolas Pitre <nico@cam.org>2007-08-19 14:19:23 -0400
commit0dde01d03e072edeb56d81e9f027ed4ef5c088eb (patch)
tree46803ed5c2fb9df5169f05766f3f54fed6bd40f9
parent76123c5282eca4effe5fbddf2beb64f30c8a8739 (diff)
downloadarchive-0dde01d03e072edeb56d81e9f027ed4ef5c088eb.tar.gz
ALPHA-pl14h
-rw-r--r--Makefile35
-rw-r--r--drivers/block/floppy.c5
-rw-r--r--drivers/char/mem.c3
-rw-r--r--drivers/char/serial.c13
-rw-r--r--drivers/sound/Makefile14
-rw-r--r--fs/devices.c1
-rw-r--r--fs/ext/fsync.c1
-rw-r--r--fs/ext/truncate.c1
-rw-r--r--fs/minix/fsync.c1
-rw-r--r--fs/minix/truncate.c1
-rw-r--r--fs/proc/kmsg.c1
-rw-r--r--fs/xiafs/fsync.c1
-rw-r--r--fs/xiafs/truncate.c1
-rw-r--r--include/linux/sys.h3
-rw-r--r--include/linux/tty.h1
-rw-r--r--kernel/ptrace.c6
-rw-r--r--net/inet/loopback.c10
-rw-r--r--net/inet/raw.c4
-rw-r--r--net/inet/route.c367
-rw-r--r--net/inet/route.h1
20 files changed, 183 insertions, 287 deletions
diff --git a/Makefile b/Makefile
index 467a14a..9d1f047 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 0.99
PATCHLEVEL = 14
-ALPHA = g
+ALPHA = h
all: Version zImage
@@ -135,14 +135,13 @@ tools/version.h: $(CONFIGURE) Makefile
@echo \#define LINUX_COMPILE_HOST \"`hostname`\" >> tools/version.h
@echo \#define LINUX_COMPILE_DOMAIN \"`domainname`\" >> tools/version.h
-tools/build: $(CONFIGURE) tools/build.c
- $(HOSTCC) $(CFLAGS) \
- -o tools/build tools/build.c
+tools/build: tools/build.c $(CONFIGURE)
+ $(HOSTCC) $(CFLAGS) -o $@ $<
boot/head.o: $(CONFIGURE) boot/head.s
-boot/head.s: $(CONFIGURE) boot/head.S include/linux/tasks.h
- $(CPP) -traditional boot/head.S -o boot/head.s
+boot/head.s: boot/head.S $(CONFIGURE) include/linux/tasks.h
+ $(CPP) -traditional $< -o $@
tools/version.o: tools/version.c tools/version.h
@@ -159,19 +158,23 @@ tools/system: boot/head.o init/main.o tools/version.o linuxsubdirs
nm tools/zSystem | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | \
sort > System.map
-boot/setup: boot/setup.s
- $(AS86) -o boot/setup.o boot/setup.s
- $(LD86) -s -o boot/setup boot/setup.o
+boot/setup: boot/setup.o
+ $(LD86) -s -o $@ $<
-boot/setup.s: $(CONFIGURE) boot/setup.S include/linux/config.h Makefile
- $(CPP) -traditional $(SVGA_MODE) $(RAMDISK) boot/setup.S -o boot/setup.s
+boot/setup.o: boot/setup.s
+ $(AS86) -o $@ $<
-boot/bootsect.s: $(CONFIGURE) boot/bootsect.S include/linux/config.h Makefile
- $(CPP) -traditional $(SVGA_MODE) $(RAMDISK) boot/bootsect.S -o boot/bootsect.s
+boot/setup.s: boot/setup.S $(CONFIGURE) include/linux/config.h Makefile
+ $(CPP) -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
-boot/bootsect: boot/bootsect.s
- $(AS86) -o boot/bootsect.o boot/bootsect.s
- $(LD86) -s -o boot/bootsect boot/bootsect.o
+boot/bootsect: boot/bootsect.o
+ $(LD86) -s -o $@ $<
+
+boot/bootsect.o: boot/bootsect.s
+ $(AS86) -o $@ $<
+
+boot/bootsect.s: boot/bootsect.S $(CONFIGURE) include/linux/config.h Makefile
+ $(CPP) -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
zBoot/zSystem: zBoot/*.c zBoot/*.S tools/zSystem
$(MAKE) -C zBoot
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 37eb05d..ff9b04a 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -419,10 +419,7 @@ int floppy_change(struct buffer_head * bh)
bh->b_uptodate = 0;
ll_rw_block(READ, 1, &bh);
}
- cli();
- while (bh->b_lock)
- sleep_on(&bh->b_wait);
- sti();
+ wait_on_buffer(bh);
if (changed_floppies & mask) {
changed_floppies &= ~mask;
recalibrate = 1;
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index fb46cd4..8a74b8f 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -196,8 +196,7 @@ static int mmap_zero(struct inode * inode, struct file * file,
mpnt->vm_end = addr + len;
mpnt->vm_page_prot = prot;
mpnt->vm_share = NULL;
- mpnt->vm_inode = inode;
- inode->i_count++;
+ mpnt->vm_inode = NULL;
mpnt->vm_offset = off;
mpnt->vm_ops = NULL;
insert_vm_struct(current, mpnt);
diff --git a/drivers/char/serial.c b/drivers/char/serial.c
index 172d8db..cb7a649 100644
--- a/drivers/char/serial.c
+++ b/drivers/char/serial.c
@@ -1573,7 +1573,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
*/
if (info->flags & ASYNC_CLOSING) {
interruptible_sleep_on(&info->close_wait);
- return -ERESTARTNOINTR;
+ return -EAGAIN;
}
/*
@@ -1631,10 +1631,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
current->state = TASK_INTERRUPTIBLE;
if (tty_hung_up_p(filp) ||
!(info->flags & ASYNC_INITIALIZED)) {
- if (info->flags & ASYNC_HUP_NOTIFY)
- retval = -EAGAIN;
- else
- retval = -ERESTARTNOINTR;
+ retval = -EAGAIN;
break;
}
if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
@@ -1696,10 +1693,10 @@ int rs_open(struct tty_struct *tty, struct file * filp)
tty->stop = rs_stop;
tty->start = rs_start;
tty->hangup = rs_hangup;
- if (info->flags & ASYNC_SPLIT_TERMIOS) {
- if (info->flags & ASYNC_NORMAL_ACTIVE)
+ if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
+ if (MAJOR(filp->f_rdev) == 4)
*tty->termios = info->normal_termios;
- if (info->flags & ASYNC_CALLOUT_ACTIVE)
+ else
*tty->termios = info->callout_termios;
}
/*
diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile
index 422ab50..6b58c28 100644
--- a/drivers/sound/Makefile
+++ b/drivers/sound/Makefile
@@ -28,11 +28,6 @@ all: local.h sound.a
@echo "Please make a new /usr/include/sys/soundcard.h containing
@echo "just a line #include <linux/soundcard.h>"
-os.h:
- @$(MAKE) setup-$(TARGET_OS)
- @$(MAKE) config
- @$(MAKE) dep
-
sound.a: $(OBJS)
-rm -f sound.a
$(AR) rcs sound.a $(OBJS)
@@ -40,7 +35,7 @@ sound.a: $(OBJS)
clean:
rm -f core core.* *.o *.a tmp_make *~ x z *%
- rm -f configure Makefile sound_stub.c
+ rm -f configure sound_stub.c
for i in *.c;do rm -f `basename $$i .c`.s;done
indent:
@@ -48,15 +43,10 @@ indent:
local.h:
$(MAKE) clean
- $(MAKE) setup-$(TARGET_OS)
$(MAKE) config
$(MAKE) dep
-soundcard.c: $(TARGET_OS)/soundcard.c
- ln -sf $(TARGET_OS)/soundcard.c soundcard.c
-
config: configure /usr/include/sys/soundcard.h
- @$(MAKE) setup-$(TARGET_OS)
@echo Compiling Sound Driver v $(VERSION) for Linux
@./configure > local.h
@echo \#define SOUND_VERSION_STRING \"$(VERSION)\" >> local.h
@@ -66,7 +56,7 @@ config: configure /usr/include/sys/soundcard.h
@echo \#define SOUND_CONFIG_DOMAIN \"`domainname`\" >> local.h
clrconf:
- rm -f local.h .depend os.h soundcard.c
+ rm -f local.h .depend
configure: configure.c /usr/include/sys/soundcard.h
$(HOSTCC) -o configure configure.c
diff --git a/fs/devices.c b/fs/devices.c
index 02b5cfa..fb6e2c7 100644
--- a/fs/devices.c
+++ b/fs/devices.c
@@ -11,7 +11,6 @@
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/ext_fs.h>
-#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/errno.h>
diff --git a/fs/ext/fsync.c b/fs/ext/fsync.c
index a0c5d01..bb20383 100644
--- a/fs/ext/fsync.c
+++ b/fs/ext/fsync.c
@@ -16,7 +16,6 @@
#include <linux/errno.h>
#include <linux/sched.h>
-#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/locks.h>
diff --git a/fs/ext/truncate.c b/fs/ext/truncate.c
index d7a6506..d14dc6c 100644
--- a/fs/ext/truncate.c
+++ b/fs/ext/truncate.c
@@ -12,7 +12,6 @@
#include <linux/sched.h>
#include <linux/ext_fs.h>
-#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/errno.h>
diff --git a/fs/minix/fsync.c b/fs/minix/fsync.c
index 3f2f831..737a5bf 100644
--- a/fs/minix/fsync.c
+++ b/fs/minix/fsync.c
@@ -13,7 +13,6 @@
#include <linux/errno.h>
#include <linux/sched.h>
-#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/locks.h>
diff --git a/fs/minix/truncate.c b/fs/minix/truncate.c
index 0c0b0c6..bef81a3 100644
--- a/fs/minix/truncate.c
+++ b/fs/minix/truncate.c
@@ -7,7 +7,6 @@
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
-#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index e577d29..812ee3d 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -9,7 +9,6 @@
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
-#include <linux/tty.h>
#include <asm/segment.h>
#include <asm/io.h>
diff --git a/fs/xiafs/fsync.c b/fs/xiafs/fsync.c
index 039272f..67681b2 100644
--- a/fs/xiafs/fsync.c
+++ b/fs/xiafs/fsync.c
@@ -13,7 +13,6 @@
#include <linux/errno.h>
#include <linux/sched.h>
-#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/locks.h>
diff --git a/fs/xiafs/truncate.c b/fs/xiafs/truncate.c
index 6d7cb7f..336dcb0 100644
--- a/fs/xiafs/truncate.c
+++ b/fs/xiafs/truncate.c
@@ -12,7 +12,6 @@
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/xia_fs.h>
-#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
diff --git a/include/linux/sys.h b/include/linux/sys.h
index b0f4ff0..49803fb 100644
--- a/include/linux/sys.h
+++ b/include/linux/sys.h
@@ -1,3 +1,5 @@
+#ifndef _LINUX_SYS_H
+#define _LINUX_SYS_H
/*
* system call entry points
*/
@@ -170,3 +172,4 @@ typedef int (*fn_ptr)();
}
#endif
+#endif
diff --git a/include/linux/tty.h b/include/linux/tty.h
index fc7f9bf..38fb5d1 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -97,7 +97,6 @@ struct serial_struct {
/*
* Definitions for async_struct (and serial_struct) flags field
*/
-#define ASYNC_HUP_NOTIFY 0x0001 /* Notify blocked open on hangups */
#define ASYNC_FOURPORT 0x0002 /* Set OU1, OUT2 per AST Fourport settings */
#define ASYNC_SAK 0x0004 /* Secure Attention Key (Orange book) */
#define ASYNC_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 42d330b..d40dc7d 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -101,6 +101,9 @@ repeat:
do_no_page(0,addr,tsk,0);
goto repeat;
}
+/* this is a hack for non-kernel-mapped video buffers and similar */
+ if (page >= high_memory)
+ return 0;
page &= PAGE_MASK;
page += addr & ~PAGE_MASK;
return *(unsigned long *) page;
@@ -139,6 +142,9 @@ repeat:
do_wp_page(PAGE_RW | PAGE_PRESENT,addr,tsk,0);
goto repeat;
}
+/* this is a hack for non-kernel-mapped video buffers and similar */
+ if (page >= high_memory)
+ return;
/* we're bypassing pagetables, so we have to set the dirty bit ourselves */
*(unsigned long *) pte |= (PAGE_DIRTY|PAGE_COW);
page &= PAGE_MASK;
diff --git a/net/inet/loopback.c b/net/inet/loopback.c
index 7629425..66203eb 100644
--- a/net/inet/loopback.c
+++ b/net/inet/loopback.c
@@ -16,22 +16,22 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-#include <asm/system.h>
-#include <asm/segment.h>
-#include <asm/io.h>
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
-#include <linux/tty.h>
#include <linux/types.h>
-#include <linux/ptrace.h>
#include <linux/string.h>
#include <linux/socket.h>
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/in.h>
#include <linux/if_ether.h> /* For the statistics structure. */
+
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/io.h>
+
#include "inet.h"
#include "dev.h"
#include "eth.h"
diff --git a/net/inet/raw.c b/net/inet/raw.c
index 3fe317c..7533532 100644
--- a/net/inet/raw.c
+++ b/net/inet/raw.c
@@ -19,7 +19,6 @@
* Alan Cox : Checks sk->broadcast.
* Alan Cox : Uses skb_free_datagram/skb_copy_datagram
* Alan Cox : Raw passes ip options too
- * Gerhard Koerting: Pass the right part of the data!
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -113,9 +112,6 @@ raw_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
skb->sk = sk;
skb->len = len;
skb->dev = dev;
- /* Undo IP's work and go get the IP header back [HACK] */
- skb->h.raw = ((char *)(skb+1))+dev->hard_header_len;
- skb->len += skb->h.iph->ihl*sizeof(long);
skb->saddr = daddr;
skb->daddr = saddr;
diff --git a/net/inet/route.c b/net/inet/route.c
index ad0572b..a06c349 100644
--- a/net/inet/route.c
+++ b/net/inet/route.c
@@ -62,222 +62,143 @@ rt_print(struct rtable *rt)
}
-/* Remove a routing table entry. */
-static void
-rt_del(unsigned long dst)
+/*
+ * Remove a routing table entry.
+ */
+static void rt_del(unsigned long dst)
{
- struct rtable *r, *x, *p;
- unsigned long flags;
-
- DPRINTF((DBG_RT, "RT: flushing for dst %s\n", in_ntoa(dst)));
- if ((r = rt_base) == NULL)
- return;
-
- save_flags(flags);
- cli();
- p = NULL;
- while(r != NULL)
- {
- if (r->rt_dst == dst)
- {
- if (p == NULL)
- rt_base = r->rt_next;
- else
- p->rt_next = r->rt_next;
- x = r->rt_next;
+ struct rtable *r, **rp;
+ unsigned long flags;
+
+ DPRINTF((DBG_RT, "RT: flushing for dst %s\n", in_ntoa(dst)));
+ rp = &rt_base;
+ save_flags(flags);
+ cli();
+ while((r = *rp) != NULL) {
+ if (r->rt_dst != dst) {
+ rp = &r->rt_next;
+ continue;
+ }
+ *rp = r->rt_next;
kfree_s(r, sizeof(struct rtable));
- r = x;
}
- else
- {
- p = r;
- r = r->rt_next;
- }
- }
- restore_flags(flags);
+ restore_flags(flags);
}
-/* Remove all routing table entries for a device. */
-void
-rt_flush(struct device *dev)
+/*
+ * Remove all routing table entries for a device.
+ */
+void rt_flush(struct device *dev)
{
- struct rtable *r, *x, *p;
- unsigned long flags;
-
- DPRINTF((DBG_RT, "RT: flushing for dev 0x%08lx (%s)\n", (long)dev, dev->name));
- if ((r = rt_base) == NULL) return;
-
- cli();
- save_flags(flags);
-
- p = NULL;
- while(r != NULL)
- {
- if (r->rt_dev == dev)
- {
- if (p == NULL)
- rt_base = r->rt_next;
- else
- p->rt_next = r->rt_next;
- x = r->rt_next;
+ struct rtable *r;
+ struct rtable **rp;
+ unsigned long flags;
+
+ DPRINTF((DBG_RT, "RT: flushing for dev 0x%08lx (%s)\n", (long)dev, dev->name));
+ rp = &rt_base;
+ cli();
+ save_flags(flags);
+ while ((r = *rp) != NULL) {
+ if (r->rt_dev != dev) {
+ rp = &r->rt_next;
+ continue;
+ }
+ *rp = r->rt_next;
kfree_s(r, sizeof(struct rtable));
- r = x;
}
- else
- {
- p = r;
- r = r->rt_next;
- }
- }
- restore_flags(flags);
+ restore_flags(flags);
}
+/*
+ * Used by 'rt_add()' when we can't get the netmask from the device..
+ */
+static unsigned long guess_mask(unsigned long dst)
+{
+ unsigned long mask = 0xffffffff;
+
+ while (mask & dst)
+ mask <<= 8;
+ return ~mask;
+}
+/*
+ * rewrote rt_add(), as the old one was weird. Linus
+ */
void
rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev)
{
- struct rtable *r, *r1;
- struct rtable *rt;
- int mask=0;
- unsigned long cpuflags;
-
- /* Allocate an entry. */
- rt = (struct rtable *) kmalloc(sizeof(struct rtable), GFP_ATOMIC);
- if (rt == NULL) {
- DPRINTF((DBG_RT, "RT: no memory for new route!\n"));
- return;
- }
-
- /* Fill in the fields. */
- memset(rt, 0, sizeof(struct rtable));
- rt->rt_flags = (flags | RTF_UP);
-
- /*
- * Gateway to our own interface is really direct
- */
- if (gw==dev->pa_addr || gw==dst)
- {
- gw=0;
- rt->rt_flags&=~RTF_GATEWAY;
- }
-
- if (gw != 0)
- rt->rt_flags |= RTF_GATEWAY;
- rt->rt_dev = dev;
- rt->rt_gateway = gw;
-
- /*
- * If this is coming from an ICMP redirect message, truncate
- * the TARGET if we are creating an entry for a NETWORK. Use
- * an Internet class C network mask. Yuck :-(
- */
- if (flags & RTF_DYNAMIC)
- {
- if (flags & RTF_HOST)
+ struct rtable *r, *rt;
+ struct rtable **rp;
+ unsigned long mask;
+ unsigned long cpuflags;
+
+ /* Allocate an entry. */
+ rt = (struct rtable *) kmalloc(sizeof(struct rtable), GFP_ATOMIC);
+ if (rt == NULL) {
+ DPRINTF((DBG_RT, "RT: no memory for new route!\n"));
+ return;
+ }
+ /* Fill in the fields. */
+ memset(rt, 0, sizeof(struct rtable));
+ rt->rt_flags = (flags | RTF_UP);
+ /*
+ * Gateway to our own interface is really direct
+ */
+ if (gw == dev->pa_addr || gw == dst) {
+ gw=0;
+ rt->rt_flags&=~RTF_GATEWAY;
+ }
+ if (gw != 0)
+ rt->rt_flags |= RTF_GATEWAY;
+ rt->rt_dev = dev;
+ rt->rt_gateway = gw;
+ if (flags & RTF_HOST) {
+ mask = 0xffffffff;
+ rt->rt_dst = dst;
+ } else {
+ if (!((dst ^ dev->pa_addr) & dev->pa_mask)) {
+ mask = dev->pa_mask;
+ dst &= mask;
+ if (flags & RTF_DYNAMIC) {
+ kfree_s(rt, sizeof(struct rtable));
+ /*printk("Dynamic route to my own net rejected\n");*/
+ return;
+ }
+ } else
+ mask = guess_mask(dst);
rt->rt_dst = dst;
- else
- {
- /* Cut down to the route at interface mask level */
- rt->rt_dst = (dst & dev->pa_mask);
- mask=dev->pa_mask;
- /* We don't want new routes to our own net*/
- if(rt->rt_dst == (dev->pa_addr & dev->pa_mask))
- {
- kfree_s(rt, sizeof(struct rtable));
- /*printk("Dynamic route to my own net rejected\n");*/
- return;
- }
}
- }
- else
- rt->rt_dst = dst;
-
- rt_print(rt);
-
- if (rt_base == NULL)
- {
- rt->rt_next = NULL;
- rt_base = rt;
- return;
- }
-
- /*
- * What we have to do is loop though this until we have
- * found the first address which has the same generality
- * as the one in rt. Then we can put rt in after it.
- */
-
- if(mask==0) /* Dont figure out masks for DYNAMIC routes. The mask is (our should be!)
- the device mask (obtained above) */
- {
- for (mask = 0xff000000L; mask != 0xffffffffL; mask = (mask >> 8) | mask)
- {
- if (mask & dst)
- {
- mask = mask << 8;
- break;
- }
- }
- DPRINTF((DBG_RT, "RT: mask = %X\n", mask));
- }
-
- save_flags(cpuflags);
- cli();
-
- r1 = rt_base;
-
- /* See if we are getting a duplicate. */
- for (r = rt_base; r != NULL; r = r->rt_next)
- {
- if (r->rt_dst == dst)
- {
- if (r == rt_base)
- {
- rt->rt_next = r->rt_next;
- rt_base = rt;
- }
- else
- {
- rt->rt_next = r->rt_next;
- r1->rt_next = rt;
- }
+ rt->rt_mask = mask;
+ rt_print(rt);
+ /*
+ * What we have to do is loop though this until we have
+ * found the first address which has a higher generality than
+ * the one in rt. Then we can put rt in right before it.
+ */
+ save_flags(cpuflags);
+ cli();
+ /* remove old route if we are getting a duplicate. */
+ rp = &rt_base;
+ while ((r = *rp) != NULL) {
+ if (r->rt_dst != dst) {
+ rp = &r->rt_next;
+ continue;
+ }
+ *rp = r->rt_next;
kfree_s(r, sizeof(struct rtable));
- restore_flags(cpuflags);
- return;
}
- r1 = r;
- }
-
- r1 = rt_base;
- for (r = rt_base; r != NULL; r = r->rt_next)
- {
- /* When we find a route more general than ourselves, and we are not a gateway or it is a gateway then use it
- This puts gateways after direct links in the table and sorts (most) of the bit aligned subnetting out */
- if (! (r->rt_dst & mask) && (gw==0 || r->rt_flags&RTF_GATEWAY))
- {
- DPRINTF((DBG_RT, "RT: adding before r=%X\n", r));
- rt_print(r);
- if (r == rt_base)
- {
- rt->rt_next = rt_base;
- rt_base = rt;
- restore_flags(cpuflags);
- return;
- }
- rt->rt_next = r;
- r1->rt_next = rt;
- restore_flags(cpuflags);
- return;
+ /* add the new route */
+ rp = &rt_base;
+ while ((r = *rp) != NULL) {
+ if ((r->rt_mask & mask) != mask)
+ break;
+ rp = &r->rt_next;
}
- r1 = r;
- }
- DPRINTF((DBG_RT, "RT: adding after r1=%X\n", r1));
- rt_print(r1);
-
- /* Goes at the end. */
- rt->rt_next = NULL;
- r1->rt_next = rt;
+ rt->rt_next = r;
+ *rp = rt;
+ restore_flags(cpuflags);
+ return;
}
@@ -360,16 +281,18 @@ rt_get_info(char *buffer)
}
-struct rtable *
-rt_route(unsigned long daddr, struct options *opt)
+/*
+ * rewrote this too.. Maybe somebody can understand it now. Linus
+ */
+struct rtable * rt_route(unsigned long daddr, struct options *opt)
{
- struct rtable *rt;
- int type;
+ struct rtable *rt;
+ int type;
/*
* This is a hack, I think. -FvK
*/
- if ((type=chk_addr(daddr)) == IS_MYADDR) daddr = my_addr();
+ if ((type=chk_addr(daddr)) == IS_MYADDR) daddr = my_addr();
/*
* Loop over the IP routing table to find a route suitable
@@ -377,33 +300,23 @@ rt_route(unsigned long daddr, struct options *opt)
* at the IP options to see if we have been given a hint as
* to what kind of path we should use... -FvK
*/
- for (rt = rt_base; rt != NULL; rt = rt->rt_next)
- if ((rt->rt_flags & RTF_HOST) && rt->rt_dst == daddr) {
- DPRINTF((DBG_RT, "%s (%s)\n",
- rt->rt_dev->name, in_ntoa(rt->rt_gateway)));
- rt->rt_use++;
- return(rt);
- }
- for (rt = rt_base; rt != NULL; rt = rt->rt_next) {
- DPRINTF((DBG_RT, "RT: %s via ", in_ntoa(daddr)));
- if (!(rt->rt_flags & RTF_HOST) && ip_addr_match(rt->rt_dst, daddr)) {
- DPRINTF((DBG_RT, "%s (%s)\n",
- rt->rt_dev->name, in_ntoa(rt->rt_gateway)));
- rt->rt_use++;
- return(rt);
- }
- if ((rt->rt_dev->flags & IFF_BROADCAST) &&
- rt->rt_dev->pa_brdaddr == daddr) {
- DPRINTF((DBG_RT, "%s (BCAST %s)\n",
- rt->rt_dev->name, in_ntoa(rt->rt_dev->pa_brdaddr)));
- rt->rt_use++;
- return(rt);
+ /*
+ * This depends on 'rt_mask' and the ordering set up in 'rt_add()' - Linus
+ */
+ for (rt = rt_base; rt != NULL; rt = rt->rt_next) {
+ if (!((rt->rt_dst ^ daddr) & rt->rt_mask)) {
+ rt->rt_use++;
+ return rt;
+ }
+ /* broadcast addresses can be special cases.. */
+ if ((rt->rt_dev->flags & IFF_BROADCAST) &&
+ rt->rt_dev->pa_brdaddr == daddr) {
+ rt->rt_use++;
+ return(rt);
+ }
}
- }
-
- DPRINTF((DBG_RT, "NONE\n"));
- return(NULL);
-};
+ return NULL;
+}
int
diff --git a/net/inet/route.h b/net/inet/route.h
index 38536d9..3d9caf6 100644
--- a/net/inet/route.h
+++ b/net/inet/route.h
@@ -26,6 +26,7 @@
struct rtable {
struct rtable *rt_next;
unsigned long rt_dst;
+ unsigned long rt_mask;
unsigned long rt_gateway;
u_char rt_flags;
u_char rt_metric;