]> git.neil.brown.name Git - history.git/commitdiff
Import 0.99.14z 0.99.14z
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:21 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:21 +0000 (15:09 -0500)
20 files changed:
Makefile
drivers/char/pty.c
drivers/net/3c501.c
drivers/net/3c507.c
drivers/net/3c509.c
drivers/net/8390.c
drivers/net/at1700.c
drivers/net/atp.c
drivers/net/d_link.c
drivers/net/eexpress.c
drivers/net/lance.c
drivers/net/plip.c
drivers/net/skeleton.c
drivers/net/slip.c
kernel/sched.c
net/inet/arp.c
net/inet/sock.c
net/inet/sock.h
net/inet/tcp.c
net/inet/tcp.h

index 287c8170efa16051ebde90c9b1d5901a6909b8f6..546d9765ef3e5a1c715b89dcedef837fef91bec6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 0.99
 PATCHLEVEL = 14
-ALPHA = y
+ALPHA = z
 
 all:   Version zImage
 
index 4797597d35c50068e60190dc22bd19c75ffa482b..482afe6b2132f1064f07631fbdf42ae1b0008957 100644 (file)
@@ -55,12 +55,14 @@ static inline void pty_copy(struct tty_struct * from, struct tty_struct * to)
 {
        unsigned long count, n;
        struct tty_queue *fq, *tq;
+       int skip_readq;
 
        if (from->stopped || EMPTY(&from->write_q))
                return;
        fq = &from->write_q;
        /* Bypass the read_q if this is a pty master. */
-       tq = IS_A_PTY_MASTER(to->line) ? &to->secondary : &to->read_q;
+       skip_readq = IS_A_PTY_MASTER(to->line) && to->disc == N_TTY;
+       tq = skip_readq ? &to->secondary : &to->read_q;
        count = MIN(CHARS(fq), LEFT(tq));
        while (count) {
                n = MIN(MIN(TTY_BUF_SIZE - fq->tail, TTY_BUF_SIZE - tq->head),
@@ -70,8 +72,8 @@ static inline void pty_copy(struct tty_struct * from, struct tty_struct * to)
                fq->tail = (fq->tail + n) & (TTY_BUF_SIZE - 1);
                tq->head = (tq->head + n) & (TTY_BUF_SIZE - 1);
        }
-       if (IS_A_PTY_MASTER(to->line))
-               wake_up_interruptible(&tq->proc_list);
+       if (skip_readq)
+               wake_up_interruptible(&to->secondary.proc_list);
        else
                TTY_READ_FLUSH(to);
        if (LEFT(fq) > WAKEUP_CHARS)
index 9b9d4dbfc6ffe798329363f46c3b50fd1b13aa4a..d0141b0e5f286dd71e8933fd83f66c1f9af3002c 100644 (file)
@@ -292,7 +292,7 @@ el_start_xmit(struct sk_buff *skb, struct device *dev)
     }
 
     /* Fill in the ethernet header. */
-    if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
+    if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
        skb->dev = dev;
        arp_queue (skb);
        return 0;
@@ -310,7 +310,7 @@ el_start_xmit(struct sk_buff *skb, struct device *dev)
        printk("%s: Transmitter access conflict.\n", dev->name);
     else {
        int gp_start = 0x800 - (ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN);
-       unsigned char *buf = (void *)(skb+1);
+       unsigned char *buf = skb->data;
 
        el_status.tx_pkt_start = gp_start;
        el_status.collisions = 0;
@@ -463,7 +463,7 @@ el_receive(struct device *dev)
        skb->len = pkt_len;
        skb->dev = dev;
 
-       insb(DATAPORT, (void *)(skb+1), pkt_len);
+       insb(DATAPORT, skb->data, pkt_len);
 
 #ifdef HAVE_NETIF_RX
            netif_rx(skb);
index f55131ff75342802056ef19a38fc401336f4f0aa..ba53e06cc47d593d01b30b8295d2b1f9a88fca9c 100644 (file)
@@ -484,7 +484,7 @@ el16_send_packet(struct sk_buff *skb, struct device *dev)
 
        /* For ethernet, fill in the header.  This should really be done by a
           higher level, rather than duplicated for each ethernet adaptor. */
-       if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
+       if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
                skb->dev = dev;
                arp_queue (skb);
                return 0;
@@ -496,7 +496,7 @@ el16_send_packet(struct sk_buff *skb, struct device *dev)
                printk("%s: Transmitter access conflict.\n", dev->name);
        else {
                short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-               unsigned char *buf = (void *)(skb+1);
+               unsigned char *buf = skb->data;
 
                /* Disable the 82586's input to the interrupt line. */
                outb(0x80, ioaddr + MISC_CTRL);
@@ -855,8 +855,8 @@ el16_rx(struct device *dev)
                        skb->len = pkt_len;
                        skb->dev = dev;
 
-                       /* 'skb+1' points to the start of sk_buff data area. */
-                       memcpy((unsigned char *) (skb + 1), data_frame + 5, pkt_len);
+                       /* 'skb->data' points to the start of sk_buff data area. */
+                       memcpy(skb->data, data_frame + 5, pkt_len);
                
 #ifdef HAVE_NETIF_RX
                        netif_rx(skb);
index 0240a1bc562df89323428a0b89ce122ba1998fa5..7e18ce77913a18a188d5a12aa011c1c91f48c9a5 100644 (file)
@@ -366,7 +366,7 @@ el3_start_xmit(struct sk_buff *skb, struct device *dev)
        }
 
        /* Fill in the ethernet header. */
-       if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
+       if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
                skb->dev = dev;
                arp_queue (skb);
                return 0;
@@ -404,7 +404,7 @@ el3_start_xmit(struct sk_buff *skb, struct device *dev)
                outw(skb->len, ioaddr + TX_FIFO);
                outw(0x00, ioaddr + TX_FIFO);
                /* ... and the packet rounded to a doubleword. */
-               outsl(ioaddr + TX_FIFO, (void *)(skb+1), (skb->len + 3) >> 2);
+               outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
        
                dev->trans_start = jiffies;
                if (inw(ioaddr + TX_FREE) > 1536) {
@@ -576,8 +576,8 @@ el3_rx(struct device *dev)
                                skb->len = pkt_len;
                                skb->dev = dev;
 
-                               /* 'skb+1' points to the start of sk_buff data area. */
-                               insl(ioaddr+RX_FIFO, (void *)(skb+1),
+                               /* 'skb->data' points to the start of sk_buff data area. */
+                               insl(ioaddr+RX_FIFO, skb->data,
                                                        (pkt_len + 3) >> 2);
 
 #ifdef HAVE_NETIF_RX
index e6759eafec1dcb79493c835f20b2d9b2b2b55ee7..9c896cc59941b684e6613a9cb4f6cf05957e2583 100644 (file)
@@ -160,7 +160,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev)
                return 0;
     }
     /* Fill in the ethernet header. */
-    if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
+    if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
                skb->dev = dev;
                arp_queue (skb);
                return 0;
@@ -219,7 +219,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev)
                        return 1;
                }
                dev->trans_start = jiffies;
-               ei_block_output(dev, length, (unsigned char *)(skb+1), output_page);
+               ei_block_output(dev, length, skb->data, output_page);
                if (! ei_local->txing) {
                        NS8390_trigger_send(dev, send_length, output_page);
                        if (output_page == ei_local->tx_start_page)
@@ -233,7 +233,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev)
                        tmp_tbusy = 1;
     } else {
                dev->trans_start = jiffies;
-               ei_block_output(dev, length, (unsigned char *)(skb+1),
+               ei_block_output(dev, length, skb->data,
                                                ei_local->tx_start_page);
                NS8390_trigger_send(dev, send_length, ei_local->tx_start_page);
                tmp_tbusy = 1;
@@ -495,8 +495,8 @@ static void ei_receive(struct device *dev)
                                skb->len = pkt_len;
                                skb->dev = dev;
                                
-                               /* 'skb+1' points to the start of sk_buff data area. */
-                               ei_block_input(dev, pkt_len, (char *)(skb+1),
+                               /* 'skb->data' points to the start of sk_buff data area. */
+                               ei_block_input(dev, pkt_len, (char *) skb->data,
                                                           current_offset + sizeof(rx_frame));
 #ifdef HAVE_NETIF_RX
                                netif_rx(skb);
index d31cd66e38683dc81a8b5b78a4c1aec2b28c0362..cfc5922d7d045601fb9face37da560f703498f2e 100644 (file)
@@ -402,7 +402,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev)
 
        /* For ethernet, fill in the header.  This should really be done by a
           higher level, rather than duplicated for each ethernet adaptor. */
-       if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
+       if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
                skb->dev = dev;
                arp_queue (skb);
                return 0;
@@ -415,7 +415,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev)
                printk("%s: Transmitter access conflict.\n", dev->name);
        else {
                short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-               unsigned char *buf = (void *)(skb+1);
+               unsigned char *buf = skb->data;
 
                if (net_debug > 4)
                        printk("%s: Transmitting a packet of length %d.\n", dev->name,
@@ -551,14 +551,14 @@ net_rx(struct device *dev)
                        skb->len = pkt_len;
                        skb->dev = dev;
 
-                       /* 'skb+1' points to the start of sk_buff data area. */
-                       insw(ioaddr + DATAPORT, (void *)(skb+1), (pkt_len + 1) >> 1);
+                       /* 'skb->data' points to the start of sk_buff data area. */
+                       insw(ioaddr + DATAPORT, skb->data, (pkt_len + 1) >> 1);
 
                        if (net_debug > 5) {
                                int i;
                                printk("%s: Rxed packet of length %d: ", dev->name, pkt_len);
                                for (i = 0; i < 14; i++)
-                                       printk(" %02x", ((unsigned char*)(skb + 1))[i]);
+                                       printk(" %02x", skb->data[i]);
                                printk(".\n");
                        }
 
index e99d0249ee815ca4ed5e7763cb0b270358c8785d..d86dc82235af3bc07bb2befc0852d0061e139843 100644 (file)
@@ -477,7 +477,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev)
 
        /* For ethernet, fill in the header.  This should really be done by a
           higher level, rather than duplicated for each ethernet adaptor. */
-       if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
+       if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
                skb->dev = dev;
                arp_queue (skb);
                return 0;
@@ -490,7 +490,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev)
                printk("%s: Transmitter access conflict.\n", dev->name);
        else {
                short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-               unsigned char *buf = (void *)(skb+1);
+               unsigned char *buf = skb->data;
                int flags;
 
                /* Disable interrupts by writing 0x00 to the Interrupt Mask Register.
@@ -686,11 +686,11 @@ static void net_rx(struct device *dev)
                skb->len = pkt_len;
                skb->dev = dev;
                
-               /* 'skb+1' points to the start of sk_buff data area. */
-               read_block(ioaddr, pkt_len, (unsigned char *)(skb + 1), dev->if_port);
+               /* 'skb->data' points to the start of sk_buff data area. */
+               read_block(ioaddr, pkt_len, skb->data, dev->if_port);
 
                if (net_debug > 6) {
-                       unsigned char *data = (unsigned char *)(skb + 1);
+                       unsigned char *data = skb->data;
                        printk(" data %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x..",
                                   data[0], data[1], data[2], data[3], data[4], data[5],
                                   data[6], data[7], data[8], data[9], data[10], data[11],
index a8e79723a581dfcaf382a3b9e66fd919bdb5b969..2ff8a1b1e920b7080eb271c21f67e0819e347500 100644 (file)
@@ -386,7 +386,7 @@ d_link_start_xmit(struct sk_buff *skb, struct device *dev)
        int             transmit_from;
        int             len;
        int             tickssofar;
-       unsigned char   *buffer = (unsigned char *)(skb + 1);
+       unsigned char   *buffer = skb->data;
 
        /*
         * If some higher layer thinks we've missed a
@@ -401,7 +401,7 @@ d_link_start_xmit(struct sk_buff *skb, struct device *dev)
 
        /* For ethernet, fill in the header (hardware addresses) with an arp. */
        if (!skb->arp)
-               if(dev->rebuild_header(skb + 1, dev)) {
+               if(dev->rebuild_header(skb->data, dev)) {
                        skb->dev = dev;
                        arp_queue (skb);
                        return 0;
@@ -590,8 +590,8 @@ d_link_rx_intr(struct device *dev)
        skb->lock = 0;
        skb->mem_len = sksize;
        skb->mem_addr = skb;
-       /* 'skb + 1' points to the start of sk_buff data area. */
-       buffer = (unsigned char *)(skb + 1);
+       /* 'skb->data' points to the start of sk_buff data area. */
+       buffer = skb->data;
 
        /* copy the packet into the buffer */
        d_link_setup_address(read_from, RW_ADDR);
index 7daab328e81300d3e00833024a3796e88edfe3dd..dff42384b141265e0b11eb866841b0ab2799aebc 100644 (file)
@@ -511,7 +511,7 @@ eexp_send_packet(struct sk_buff *skb, struct device *dev)
 
        /* For ethernet, fill in the header.  This should really be done by a
           higher level, rather than duplicated for each ethernet adaptor. */
-       if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
+       if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
                skb->dev = dev;
                arp_queue (skb);
                return 0;
@@ -523,7 +523,7 @@ eexp_send_packet(struct sk_buff *skb, struct device *dev)
                printk("%s: Transmitter access conflict.\n", dev->name);
        else {
                short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-               unsigned char *buf = (void *)(skb+1);
+               unsigned char *buf = skb->data;
 
                /* Disable the 82586's input to the interrupt line. */
                outb(irqrmap[dev->irq], ioaddr + SET_IRQ);
@@ -960,7 +960,7 @@ eexp_rx(struct device *dev)
 
                        outw(data_buffer_addr + 10, ioaddr + READ_PTR);
 
-                       insw(ioaddr, (void *)(skb+1), (pkt_len + 1) >> 1);
+                       insw(ioaddr, skb->data, (pkt_len + 1) >> 1);
                
 #ifdef HAVE_NETIF_RX
                        netif_rx(skb);
index d6c77ed4368bbd02add09cb95654dd7093d33b44..1d610e88a7bba97fae62e614d8ceec4c5526dd6f 100644 (file)
@@ -512,7 +512,7 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev)
     }
 
     /* Fill in the ethernet header. */
-    if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
+    if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
        skb->dev = dev;
        arp_queue (skb);
        return 0;
@@ -553,11 +553,11 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev)
 
     /* If any part of this buffer is >16M we must copy it to a low-memory
        buffer. */
-    if ((int)(skb+1) + skb->len > 0x01000000) {
+    if ((int)(skb->data) + skb->len > 0x01000000) {
        if (lance_debug > 5)
            printk("%s: bouncing a high-memory packet (%#x).\n",
-                  dev->name, (int)(skb+1));
-       memcpy(&lp->tx_bounce_buffs[entry], skb+1, skb->len);
+                  dev->name, (int)skb->data);
+       memcpy(&lp->tx_bounce_buffs[entry], skb->data, skb->len);
        lp->tx_ring[entry].base =
            (int)(lp->tx_bounce_buffs + entry) | 0x83000000;
        if (skb->free)
@@ -567,7 +567,7 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev)
        /* Gimme!!! */
        if(skb->free==0)
                skb_kept_by_device(skb);
-       lp->tx_ring[entry].base = (int)(skb+1) | 0x83000000;
+       lp->tx_ring[entry].base = (int)skb->data | 0x83000000;
     }
     lp->cur_tx++;
 
@@ -726,7 +726,7 @@ lance_rx(struct device *dev)
            skb->mem_addr = skb;
            skb->len = pkt_len;
            skb->dev = dev;
-           memcpy((unsigned char *) (skb + 1),
+           memcpy(skb->data,
                   (unsigned char *)(lp->rx_ring[entry].base & 0x00ffffff),
                   pkt_len);
 #ifdef HAVE_NETIF_RX
index a676cfcc5ceb5d16ab7208285cb617a591e16175..39530dd58c5e70497cc60b939c19c0887ea9c549 100644 (file)
@@ -285,7 +285,7 @@ plip_tx_packet(struct sk_buff *skb, struct device *dev)
 
     /* Pretend we are an ethernet and fill in the header.  This could use
        a simplified routine someday. */
-    if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
+    if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
        skb->dev = dev;
        arp_queue (skb);
        return 0;
@@ -293,7 +293,7 @@ plip_tx_packet(struct sk_buff *skb, struct device *dev)
     skb->arp=1;
 
     dev->trans_start = jiffies;
-    ret_val = plip_send_packet(dev, (unsigned char *)(skb+1), skb->len);
+    ret_val = plip_send_packet(dev, skb->data, skb->len);
     if (skb->free)
        kfree_skb (skb, FREE_WRITE);
     dev->tbusy = 0;
@@ -483,8 +483,8 @@ plip_receive_packet(struct device *dev)
     }
     {
        /* phase of receiving the data */
-       /* 'skb+1' points to the start of sk_buff data area. */
-       unsigned char *buf = (unsigned char *) (skb+1);
+       /* 'skb->data' points to the start of sk_buff data area. */
+       unsigned char *buf = skb->data;
        unsigned char *eth_p = (unsigned char *)&eth;
        int i;
        for ( i = 0; i < sizeof(eth); i++) {
index 760ca94e05eb592c72eca465b5bce4b7991c1191..b6d047bd5e51374e71bc07ccf270cf77030b3ac5 100644 (file)
@@ -316,7 +316,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev)
 
        /* For ethernet, fill in the header.  This should really be done by a
           higher level, rather than duplicated for each ethernet adaptor. */
-       if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
+       if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
                skb->dev = dev;
                arp_queue (skb);
                return 0;
@@ -329,7 +329,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev)
                printk("%s: Transmitter access conflict.\n", dev->name);
        else {
                short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-               unsigned char *buf = (void *)(skb+1);
+               unsigned char *buf = skb->data;
 
                hardware_send_packet(ioaddr, buf, length);
                dev->trans_start = jiffies;
@@ -420,11 +420,11 @@ net_rx(struct device *dev)
                        skb->len = pkt_len;
                        skb->dev = dev;
 
-                       /* 'skb+1' points to the start of sk_buff data area. */
-                       memcpy((unsigned char *) (skb + 1), (void*)dev->rmem_start,
+                       /* 'skb->data' points to the start of sk_buff data area. */
+                       memcpy(skb->data, (void*)dev->rmem_start,
                                   pkt_len);
                        /* or */
-                       insw(ioaddr, (void *)(skb+1), (pkt_len + 1) >> 1);
+                       insw(ioaddr, skb->data, (pkt_len + 1) >> 1);
 
 #ifdef HAVE_NETIF_RX
                        netif_rx(skb);
index f19a2260c8e9c988d959a081473adb6a0e34f2b9..514fa8ceb5eda5b0c5657b425005515b8cffbbb1 100644 (file)
@@ -545,7 +545,7 @@ sl_xmit(struct sk_buff *skb, struct device *dev)
 #ifdef CONFIG_AX25  
        if(sl->mode & SL_MODE_AX25)
        {
-               if(!skb->arp && dev->rebuild_header(skb+1,dev))
+               if(!skb->arp && dev->rebuild_header(skb->data,dev))
                {
                        skb->dev=dev;
                        arp_queue(skb);
@@ -555,8 +555,8 @@ sl_xmit(struct sk_buff *skb, struct device *dev)
        }
 #endif         
        sl_lock(sl);
-/*     sl_hex_dump((unsigned char *)(skb+1),skb->len);*/
-       sl_encaps(sl, (unsigned char *) (skb + 1), skb->len);
+/*     sl_hex_dump(skb->data,skb->len);*/
+       sl_encaps(sl, skb->data, skb->len);
        if (skb->free) kfree_skb(skb, FREE_WRITE);
   }
   return(0);
@@ -599,7 +599,7 @@ sl_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
        struct slip *sl=&sl_ctrl[dev->base_addr];
        
        if(sl->mode&SL_MODE_AX25)
-               arp_add(addr,((char *)(skb+1))+8,dev);
+               arp_add(addr,((char *) skb->data)+8,dev);
 #endif         
 }
 
@@ -686,6 +686,10 @@ sl_open(struct device *dev)
        return(-ENOMEM);
   }
 
+  dev->flags|=IFF_UP;
+  /* Needed because address '0' is special */
+  if(dev->pa_addr==0)
+       dev->pa_addr=ntohl(0xC0000001);
   DPRINTF((DBG_SLIP, "SLIP: channel %d opened.\n", sl->line));
   return(0);
 }
index 6d94afd86f7a99d0f552ff91bc0c4effe931dc71..43c648953ebececae64567da899bcd2fc6b5b3d2 100644 (file)
@@ -642,8 +642,8 @@ static void do_timer(struct pt_regs * regs)
        calc_load();
        if ((VM_MASK & regs->eflags) || (3 & regs->cs)) {
                current->utime++;
-               if(current != task[0]) {
-                       if(current->priority != 15)
+               if (current != task[0]) {
+                       if (current->priority < 15)
                                kstat.cpu_nice++;
                        else
                                kstat.cpu_user++;
index 71384af13e423e810197b3aa00cddb03bef397cc..789b817c616742c2c5f488099eae84ed2e823063 100644 (file)
@@ -251,14 +251,19 @@ arp_send_q(void)
 
 
 /* Create and send our response to an ARP request. */
-static int
-arp_response(struct arphdr *arp1, struct device *dev,  int addrtype)
+
+/*
+ *     We are now a bit smarter. We know the old buffer must be big enough
+ *     so why allocate a new one for the reply ?
+ */
+static int arp_response(struct sk_buff *skb,struct arphdr *arp1, struct device *dev,  int addrtype)
 {
   struct arphdr *arp2;
-  struct sk_buff *skb;
   unsigned long src, dst;
   unsigned char *ptr1, *ptr2;
   int hlen;
+  int len;
   struct arp_table *apt = NULL;/* =NULL otherwise the compiler gives warnings */
 
   /* Decode the source (REQUEST) message. */
@@ -270,24 +275,28 @@ arp_response(struct arphdr *arp1, struct device *dev,  int addrtype)
   {
        apt=arp_lookup_proxy(dst);
        if(apt==NULL)
+       {
+               kfree_skb(skb,FREE_READ);
                return(1);
+       }
   }
 
-  /* Get some mem and initialize it for the return trip. */
-  skb = alloc_skb(sizeof(struct sk_buff) +
-               sizeof(struct arphdr) +
-               (2 * arp1->ar_hln) + (2 * arp1->ar_pln) +
-               dev->hard_header_len, GFP_ATOMIC);
-  if (skb == NULL) {
-       printk("ARP: no memory available for ARP REPLY!\n");
-       return(1);
+  skb->h.raw=skb->data;
+  skb->len+=dev->hard_header_len;      /* Grow the packet back to its original form */
+
+  /* Can't check for exceeding the size - some people pad. */
+  len= sizeof(struct arphdr) + (2 * arp1->ar_hln) + (2 * arp1->ar_pln) + dev->hard_header_len;
+  if(len>skb->len)
+  {
+       printk("Received runt ARP request!\n");
+       kfree_skb(skb,FREE_READ);
+       return 1;
   }
 
-  skb->mem_addr = skb;
-  skb->len      = sizeof(struct arphdr) + (2 * arp1->ar_hln) + 
-                 (2 * arp1->ar_pln) + dev->hard_header_len;
-  skb->mem_len  = sizeof(struct sk_buff) + skb->len;
+  skb->len      = len;
+
   hlen = dev->hard_header(skb->data, dev, ETH_P_ARP, src, dst, skb->len);
+
   if (hlen < 0) {
        printk("ARP: cannot create HW frame header for REPLY !\n");
        kfree_skb(skb, FREE_WRITE);
@@ -578,8 +587,7 @@ arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
    * Yes, it is for us.
    * Allocate, fill in and send an ARP REPLY packet.
    */
-  ret = arp_response(arp, dev, addr_hint);
-  kfree_skb(skb, FREE_READ);
+  ret = arp_response(skb,arp, dev, addr_hint);
   return(ret);
 }
 
@@ -608,14 +616,12 @@ arp_send(unsigned long paddr, struct device *dev, unsigned long saddr)
   
   /* Fill in the request. */
   skb->sk = NULL;
-  skb->mem_addr = skb;
   skb->len = sizeof(struct arphdr) +
             dev->hard_header_len + (2 * dev->addr_len) + 8;
-  skb->mem_len = sizeof(struct sk_buff) + skb->len;
   skb->arp = 1;
   skb->dev = dev;
-  skb->next = NULL;
   skb->free = 1;
+  skb->next = NULL;
   tmp = dev->hard_header(skb->data, dev, ETH_P_ARP, 0, saddr, skb->len);
   if (tmp < 0) {
        kfree_skb(skb,FREE_WRITE);
index 643361dbac08fc6bfc141b9e1a0b225fd373d92e..3de12e38f29064166a2c4c1efc9a440b393a7f58 100644 (file)
@@ -324,10 +324,10 @@ destroy_sock(struct sock *sk)
        delete_timer(sk);
 
 
-       if (sk->send_tmp != NULL) 
+       while ((skb = tcp_dequeue_partial(sk)) != NULL) 
        {
-               IS_SKB(sk->send_tmp);
-               kfree_skb(sk->send_tmp, FREE_WRITE);
+               IS_SKB(skb);
+               kfree_skb(skb, FREE_WRITE);
        }
 
   /* Cleanup up the write buffer. */
@@ -869,7 +869,7 @@ inet_create(struct socket *sock, int protocol)
   sk->state = TCP_CLOSE;
   sk->dead = 0;
   sk->ack_timed = 0;
-  sk->send_tmp = NULL;
+  sk->partial = NULL;
   sk->user_mss = 0;
   sk->debug = 0;
 
index 2133f4db650f04af731bedaedbf435c36c26f735..3fb08a9a00d25443747be297736c7d8df6baa7e4 100644 (file)
@@ -89,7 +89,8 @@ struct sock {
   struct sk_buff               *volatile send_tail;
   struct sk_buff               *volatile send_head;
   struct sk_buff               *volatile back_log;
-  struct sk_buff               *send_tmp;
+  struct sk_buff               *partial;
+  struct timer_list            partial_timer;
   long                         retransmits;
   struct sk_buff               *volatile wback,
                                *volatile wfront,
index b0d60745488f5c6a710d71e8d50f1981d458adba..91f689ae38a89713baea523cc1f6ca12834dbd3a 100644 (file)
@@ -648,43 +648,52 @@ static void tcp_send_skb(struct sock *sk, struct sk_buff *skb)
        }
 }
 
-static struct sk_buff * dequeue_partial(struct sock * sk)
+struct sk_buff * tcp_dequeue_partial(struct sock * sk)
 {
        struct sk_buff * skb;
        unsigned long flags;
 
        save_flags(flags);
        cli();
-       skb = sk->send_tmp;
-       sk->send_tmp = NULL;
+       skb = sk->partial;
+       if (skb) {
+               sk->partial = NULL;
+               del_timer(&sk->partial_timer);
+       }
        restore_flags(flags);
        return skb;
 }
 
-static void enqueue_partial(struct sk_buff * skb, struct sock * sk)
+static void tcp_send_partial(struct sock *sk)
+{
+       struct sk_buff *skb;
+
+       if (sk == NULL)
+               return;
+       while ((skb = tcp_dequeue_partial(sk)) != NULL)
+               tcp_send_skb(sk, skb);
+}
+
+void tcp_enqueue_partial(struct sk_buff * skb, struct sock * sk)
 {
        struct sk_buff * tmp;
        unsigned long flags;
 
        save_flags(flags);
        cli();
-       tmp = sk->send_tmp;
-       sk->send_tmp = skb;
+       tmp = sk->partial;
+       if (tmp)
+               del_timer(&sk->partial_timer);
+       sk->partial = skb;
+       sk->partial_timer.expires = 5*HZ;
+       sk->partial_timer.function = (void (*)(unsigned long)) tcp_send_partial;
+       sk->partial_timer.data = (unsigned long) sk;
+       add_timer(&sk->partial_timer);
        restore_flags(flags);
        if (tmp)
                tcp_send_skb(sk, tmp);
 }
 
-static void tcp_send_partial(struct sock *sk)
-{
-       struct sk_buff *skb;
-
-       if (sk == NULL)
-               return;
-       while ((skb = dequeue_partial(sk)) != NULL)
-               tcp_send_skb(sk, skb);
-}
-
 
 /* This routine sends an ack and also updates the window. */
 static void
@@ -897,7 +906,7 @@ tcp_write(struct sock *sk, unsigned char *from,
  */
 
        /* Now we need to check if we have a half built packet. */
-       if ((skb = dequeue_partial(sk)) != NULL) {
+       if ((skb = tcp_dequeue_partial(sk)) != NULL) {
                int hdrlen;
 
                 /* IP header + TCP header */
@@ -920,10 +929,12 @@ tcp_write(struct sock *sk, unsigned char *from,
                        len -= copy;
                        sk->send_seq += copy;
                      }
-               enqueue_partial(skb, sk);
-               if ((skb->len - hdrlen) >= sk->mss || (flags & MSG_OOB)) {
-                 tcp_send_partial(sk);
-               }
+               if ((skb->len - hdrlen) >= sk->mss ||
+                   (flags & MSG_OOB) ||
+                   !sk->packets_out)
+                       tcp_send_skb(sk, skb);
+               else
+                       tcp_enqueue_partial(skb, sk);
                continue;
        }
 
@@ -949,7 +960,8 @@ tcp_write(struct sock *sk, unsigned char *from,
        copy = min(copy, len);
 
   /* We should really check the window here also. */
-       if (sk->packets_out && copy < sk->mss && !(flags & MSG_OOB)) {
+       send_tmp = NULL;
+       if (copy < sk->mss && !(flags & MSG_OOB)) {
        /* We will release the socket incase we sleep here. */
          release_sock(sk);
          /* NB: following must be mtu, because mss can be increased.
@@ -962,7 +974,6 @@ tcp_write(struct sock *sk, unsigned char *from,
          release_sock(sk);
          skb = prot->wmalloc(sk, copy + prot->max_header + sizeof(*skb), 0, GFP_KERNEL);
          sk->inuse = 1;
-         send_tmp = NULL;
        }
 
        /* If we didn't get any memory, we need to sleep. */
@@ -1041,8 +1052,8 @@ tcp_write(struct sock *sk, unsigned char *from,
        skb->free = 0;
        sk->send_seq += copy;
 
-       if (send_tmp != NULL) {
-               enqueue_partial(send_tmp, sk);
+       if (send_tmp != NULL && sk->packets_out) {
+               tcp_enqueue_partial(send_tmp, sk);
                continue;
        }
        tcp_send_skb(sk, skb);
@@ -1057,7 +1068,7 @@ tcp_write(struct sock *sk, unsigned char *from,
  */
 
   /* Avoid possible race on send_tmp - c/o Johannes Stille */
-  if(sk->send_tmp && 
+  if(sk->partial && 
      ((!sk->packets_out) 
      /* If not nagling we can send on the before case too.. */
       || (sk->nonagle && before(sk->send_seq , sk->window_seq))
@@ -1585,7 +1596,8 @@ tcp_shutdown(struct sock *sk, int how)
   sk->inuse = 1;
 
   /* Clear out any half completed packets. */
-  if (sk->send_tmp) tcp_send_partial(sk);
+  if (sk->partial)
+       tcp_send_partial(sk);
 
   prot =(struct proto *)sk->prot;
   th =(struct tcphdr *)&sk->dummy_th;
@@ -1898,7 +1910,7 @@ tcp_conn_request(struct sock *sk, struct sk_buff *skb,
   newsk->intr = 0;
   newsk->proc = 0;
   newsk->done = 0;
-  newsk->send_tmp = NULL;
+  newsk->partial = NULL;
   newsk->pair = NULL;
   newsk->wmem_alloc = 0;
   newsk->rmem_alloc = 0;
@@ -2081,7 +2093,7 @@ tcp_close(struct sock *sk, int timeout)
   sk->rqueue = NULL;
 
   /* Get rid off any half-completed packets. */
-  if (sk->send_tmp) {
+  if (sk->partial) {
        tcp_send_partial(sk);
   }
 
@@ -2565,7 +2577,7 @@ tcp_ack(struct sock *sk, struct tcphdr *th, unsigned long saddr, int len)
        }
   }
 
-  if (sk->packets_out == 0 && sk->send_tmp != NULL &&
+  if (sk->packets_out == 0 && sk->partial != NULL &&
       sk->wfront == NULL && sk->send_head == NULL) {
        flag |= 1;
        tcp_send_partial(sk);
index bc952568f20c5858c6f5d0cc8c6cb5a3d2497e1a..007f3eee4ca766dc64f887f1acd1fa32ac459513 100644 (file)
@@ -124,5 +124,8 @@ extern int  tcp_rcv(struct sk_buff *skb, struct device *dev,
 
 extern int     tcp_ioctl(struct sock *sk, int cmd, unsigned long arg);
 
+extern void tcp_enqueue_partial(struct sk_buff *, struct sock *);
+extern struct sk_buff * tcp_dequeue_partial(struct sock *);
+
 
 #endif /* _TCP_H */