]> git.neil.brown.name Git - history.git/commitdiff
Import 0.99.14h 0.99.14h
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:17 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:17 +0000 (15:09 -0500)
20 files changed:
Makefile
drivers/block/floppy.c
drivers/char/mem.c
drivers/char/serial.c
drivers/sound/Makefile
fs/devices.c
fs/ext/fsync.c
fs/ext/truncate.c
fs/minix/fsync.c
fs/minix/truncate.c
fs/proc/kmsg.c
fs/xiafs/fsync.c
fs/xiafs/truncate.c
include/linux/sys.h
include/linux/tty.h
kernel/ptrace.c
net/inet/loopback.c
net/inet/raw.c
net/inet/route.c
net/inet/route.h

index 467a14aff93fb607ffe39aee024f9f90841bb19f..dbbe935b028dcbe3b1d8ea56c693c79be014c672 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 0.99
 PATCHLEVEL = 14
-ALPHA = g
+ALPHA = i
 
 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
index 37eb05dd4c1a7270b8d268ccbfc9f310ad9e1a4c..ff9b04a3f751bd6c5207016ae0a8d71e98c0b011 100644 (file)
@@ -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;
index fb46cd428b5bc7048972c5009bfd4a90194fabfd..8a74b8fb86a35cd590e9a7b7d4d71cce883488df 100644 (file)
@@ -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);
index 172d8db708f780204593192ac93f1ab9c7347f5b..cb7a649903df5a22345360dc2fbd23ab58bf1440 100644 (file)
@@ -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;
        }
        /*
index 422ab501a011bcd740ad403eb61d418d7e2a1fe9..6b58c28422770211f01b11d210f734c376a23ff1 100644 (file)
@@ -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
index 02b5cfa4e1fb111c97d901eb22bd4376376a2a97..fb6e2c7b49c3683860819619cd8f167d00c43b28 100644 (file)
@@ -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>
index a0c5d01c16b2c765401875cb52501d29e19ddc8c..bb20383ccb68e8abf6f06db04aa9caa4e95c7d42 100644 (file)
@@ -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>
index d7a65063a0f20c736ede037a67f9edfccfc3e8b9..d14dc6cb340c8e089a6231f734794fc5f5e8bdc6 100644 (file)
@@ -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>
index 3f2f831b4bbb488d913349b511b6a6c5252c1865..737a5bfcd18459bd1149c3e66e3e3d043ea18e15 100644 (file)
@@ -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>
index 0c0b0c611c358bfb89cda9e2a94bfd5ca18562e5..bef81a302eab34ee14a79f6cc68b931d250cf2c0 100644 (file)
@@ -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>
 
index e577d296cd9f265c7fe16faf7c4f2c81b428ee39..812ee3dd5a34260eee4c2b335ac2d1c335f999d4 100644 (file)
@@ -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>
index 039272f375999de6b5d01df91bcc62739477be11..67681b2c6175c7e0ce1e598785dc7f951a297c5b 100644 (file)
@@ -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>
index 6d7cb7f3713a164a95321295803779f9e67d7537..336dcb0ab3265ba2b1b3473f675d253d917aa4f7 100644 (file)
@@ -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>
 
index b0f4ff0a9bb935781433130bbc383639189bf2ef..49803fb1b73584e7558c600cf44813c4e93caac0 100644 (file)
@@ -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
index fc7f9bfd70d5db048a31aaf525ac1ae4627c802f..38fb5d1451367e4ea598327668aa506c8b3bac56 100644 (file)
@@ -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 */
index 42d330b2a66b7ec31dc1861691ac1f1aa1148550..d40dc7d574d35d2d8969edc3e53abfd34d0080ab 100644 (file)
@@ -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;
index 76294254e04fe782dbe15a0c89e9d3ab2457a18d..66203eb540f9edbdf474f47bd38ec30dc77863d1 100644 (file)
  *             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"
index 3fe317c681e7d7ab979e77c625078d58ea0d6790..75335322310074649b7b68ad4f9abf7877ab298a 100644 (file)
@@ -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;
 
index ad0572b14466ef535f3ffe3319f22d3648f9fef6..a06c349d411d4f332d3e15dc483463c773c081d3 100644 (file)
@@ -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
index 38536d9db4d372b2bff6cb38da32653441869e80..3d9caf6c6f8b1b8dfb9089c1f1cefef9f783efc5 100644 (file)
@@ -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;