From 2fbc2376b01c7f2c1d53932d9f2ce0193543419e Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:09:23 -0500 Subject: [PATCH] Import 0.99.15g --- Configure | 2 +- Makefile | 14 +-- drivers/FPU-emu/errors.c | 14 ++- drivers/FPU-emu/fpu_entry.c | 3 +- drivers/char/tty_io.c | 10 +- drivers/net/slip.c | 15 +++ fs/ext2/super.c | 4 + fs/super.c | 2 +- include/linux/ext2_fs.h | 5 +- net/inet/dev.c | 50 +++++---- net/inet/sock.c | 2 +- net/inet/tcp.c | 206 +++++++++++++++++++----------------- net/inet/tcp.h | 6 +- 13 files changed, 189 insertions(+), 144 deletions(-) diff --git a/Configure b/Configure index b3c4cc8e7307..d936ab76c547 100644 --- a/Configure +++ b/Configure @@ -158,7 +158,7 @@ function int () { eval "$2=$ans" } -CONFIG=.config~ +CONFIG=.tmpconfig CONFIG_H=include/linux/autoconf.h trap "rm -f $CONFIG $CONFIG_H config.new ; exit 1" 1 2 diff --git a/Makefile b/Makefile index 18c648be8c95..9d113f5b7946 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 0.99 PATCHLEVEL = 15 -ALPHA = f +ALPHA = g all: Version zImage @@ -116,10 +116,10 @@ Version: dummy config: $(CONFIG_SHELL) Configure $(OPTS) < config.in - @if grep -s '^CONFIG_SOUND' .config~ ; then \ + @if grep -s '^CONFIG_SOUND' .tmpconfig ; then \ $(MAKE) -C drivers/sound config; \ else : ; fi - mv .config~ .config + mv .tmpconfig .config linuxsubdirs: dummy set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done @@ -229,7 +229,7 @@ clean: rm -f zImage zSystem.map tools/zSystem tools/system rm -f Image System.map boot/bootsect boot/setup rm -f zBoot/zSystem zBoot/xtract zBoot/piggyback - rm -f drivers/sound/configure + rm -f .tmp* drivers/sound/configure rm -f init/*.o tools/build boot/*.o tools/*.o mrproper: clean @@ -246,11 +246,11 @@ backup: mrproper depend dep: touch tools/version.h - for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done > .depend~ - for i in tools/*.c;do echo -n "tools/";$(CPP) -M $$i;done >> .depend~ + for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done > .tmpdepend + for i in tools/*.c;do echo -n "tools/";$(CPP) -M $$i;done >> .tmpdepend set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i dep; done rm -f tools/version.h - mv .depend~ .depend + mv .tmpdepend .depend ifdef CONFIGURATION ..$(CONFIGURATION): diff --git a/drivers/FPU-emu/errors.c b/drivers/FPU-emu/errors.c index d1098ea47bd1..787f4e839fd5 100644 --- a/drivers/FPU-emu/errors.c +++ b/drivers/FPU-emu/errors.c @@ -84,17 +84,21 @@ void emu_printall() RE_ENTRANT_CHECK_OFF; /* No need to verify_area(), we have previously fetched these bytes. */ - printk("At %p: ", (void *) address); + printk("At %p:", (void *) address); #define MAX_PRINTED_BYTES 20 for ( i = 0; i < MAX_PRINTED_BYTES; i++ ) { byte1 = get_fs_byte((unsigned char *) address); - if ( (byte1 & 0xf8) == 0xd8 ) break; - printk("[%02x]", byte1); + if ( (byte1 & 0xf8) == 0xd8 ) + { + printk(" %02x", byte1); + break; + } + printk(" [%02x]", byte1); address++; } - if ( i == MAX_PRINTED_BYTES ) printk("[more..]"); - printk("%02x ", byte1); + if ( i == MAX_PRINTED_BYTES ) printk(" [more..]"); + printk("\n"); FPU_modrm = get_fs_byte(1 + (unsigned char *) address); partial_status = status_word(); diff --git a/drivers/FPU-emu/fpu_entry.c b/drivers/FPU-emu/fpu_entry.c index 001beaf6fab6..a06183c06154 100644 --- a/drivers/FPU-emu/fpu_entry.c +++ b/drivers/FPU-emu/fpu_entry.c @@ -144,6 +144,7 @@ static int valid_prefix(unsigned char *Byte, unsigned char **fpu_eip, asmlinkage void math_emulate(long arg) { unsigned char FPU_modrm, byte1; + unsigned short code; fpu_addr_modes addr_modes; int unmasked; @@ -250,7 +251,7 @@ do_another_FPU_instruction: but a real 80486 uses the following instructions: fninit, fnstenv, fnsave, fnstsw, fnstenv, fnclex. */ - unsigned short code = (FPU_modrm << 8) | byte1; + code = (FPU_modrm << 8) | byte1; if ( ! ( (((code & 0xf803) == 0xe003) || /* fnclex, fninit, fnstsw */ (((code & 0x3003) == 0x3001) && /* fnsave, fnstcw, fnstenv, fnstsw */ diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index c5731f728e6e..dc3553162832 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -259,8 +259,10 @@ void do_tty_hangup(struct tty_struct * tty, struct file_operations *fops) flush_input(tty); flush_output(tty); wake_up_interruptible(&tty->secondary.proc_list); - if (tty->session > 0) + if (tty->session > 0) { kill_sl(tty->session,SIGHUP,1); + kill_sl(tty->session,SIGCONT,1); + } tty->session = 0; tty->pgrp = -1; for_each_task(p) { @@ -297,7 +299,7 @@ int tty_hung_up_p(struct file * filp) * it wants to dissassociate itself from its controlling tty. * * It performs the following functions: - * (1) Sends a SIGHUP to the foreground process group + * (1) Sends a SIGHUP and SIGCONT to the foreground process group * (2) Clears the tty from being controlling the session * (3) Clears the controlling tty for all processes in the * session group. @@ -310,8 +312,10 @@ void disassociate_ctty(int priv) if (current->tty >= 0) { tty = tty_table[current->tty]; if (tty) { - if (tty->pgrp > 0) + if (tty->pgrp > 0) { kill_pg(tty->pgrp, SIGHUP, priv); + kill_pg(tty->pgrp, SIGCONT, priv); + } tty->session = 0; tty->pgrp = -1; } else diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 18c506b14d19..863e3b6ca6f8 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -232,6 +232,13 @@ static void sl_changedmtu(struct slip *sl) sl->mtu=dev->mtu; l=(dev->mtu *2); +/* + * allow for arrival of larger UDP packets, even if we say not to + * also fixes a bug in which SunOS sends 512-byte packets even with + * an MSS of 128 + */ + if (l < (576 * 2)) + l = 576 * 2; DPRINTF((DBG_SLIP,"SLIP: mtu changed!\n")); @@ -655,6 +662,14 @@ sl_open(struct device *dev) * rmem_start Start of RECV frame buffer */ l = (dev->mtu * 2); +/* + * allow for arrival of larger UDP packets, even if we say not to + * also fixes a bug in which SunOS sends 512-byte packets even with + * an MSS of 128 + */ + if (l < (576 * 2)) + l = 576 * 2; + p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL); if (p == NULL) { DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP XMIT buffer!\n")); diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 6c7e7d204c2c..82a9a976f072 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -277,6 +277,10 @@ static void ext2_setup_super (struct super_block * sb, es->s_mnt_count >= (unsigned short) es->s_max_mnt_count) printk ("EXT2-fs warning: maximal mount count reached, " "running e2fsck is recommended\n"); + else if (es->s_checkinterval && + (es->s_lastcheck + es->s_checkinterval <= CURRENT_TIME)) + printk ("EXT2-fs warning: checktime reached, " + "running e2fsck is recommended\n"); if (!(sb->s_flags & MS_RDONLY)) { es->s_state &= ~EXT2_VALID_FS; if (!es->s_max_mnt_count) diff --git a/fs/super.c b/fs/super.c index 5232057084ee..81c1d0817544 100644 --- a/fs/super.c +++ b/fs/super.c @@ -380,7 +380,7 @@ static int do_remount(const char *dir,int flags,char *data) return retval; } -static int copy_mount_options (char * data, unsigned long *where) +static int copy_mount_options (const void * data, unsigned long *where) { int i; unsigned long page; diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h index 7b7bfbb45e86..e6613e9c9e1e 100644 --- a/include/linux/ext2_fs.h +++ b/include/linux/ext2_fs.h @@ -262,6 +262,7 @@ struct ext2_inode { * Maximal mount counts between two filesystem checks */ #define EXT2_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */ +#define EXT2_DFL_CHECKINTERVAL 0 /* Don't use interval check */ /* * Behaviour when detecting errors @@ -294,7 +295,9 @@ struct ext2_super_block { unsigned short s_state; /* File system state */ unsigned short s_errors; /* Behaviour when detecting errors */ unsigned short s_pad; - unsigned long s_reserved[240]; /* Padding to the end of the block */ + unsigned long s_lastcheck; /* time of last check */ + unsigned long s_checkinterval; /* max. time between checks */ + unsigned long s_reserved[238]; /* Padding to the end of the block */ }; /* diff --git a/net/inet/dev.c b/net/inet/dev.c index e5bc51339fb1..a620738ab61b 100644 --- a/net/inet/dev.c +++ b/net/inet/dev.c @@ -969,49 +969,53 @@ dev_ioctl(unsigned int cmd, void *arg) int ret; switch(cmd) { - case IP_SET_DEV: - printk("Your network configuration program needs upgrading.\n"); - return -EINVAL; + case IP_SET_DEV: + printk("Your network configuration program needs upgrading.\n"); + return -EINVAL; + case SIOCGIFCONF: (void) dev_ifconf((char *) arg); - ret = 0; - break; + return 0; + case SIOCGIFFLAGS: - case SIOCSIFFLAGS: case SIOCGIFADDR: - case SIOCSIFADDR: case SIOCGIFDSTADDR: - case SIOCSIFDSTADDR: case SIOCGIFBRDADDR: - case SIOCSIFBRDADDR: case SIOCGIFNETMASK: - case SIOCSIFNETMASK: case SIOCGIFMETRIC: - case SIOCSIFMETRIC: case SIOCGIFMTU: - case SIOCSIFMTU: case SIOCGIFMEM: - case SIOCSIFMEM: case SIOCGIFHWADDR: - if (!suser()) return(-EPERM); - ret = dev_ifsioc(arg, cmd); - break; + return dev_ifsioc(arg, cmd); + + case SIOCSIFFLAGS: + case SIOCSIFADDR: + case SIOCSIFDSTADDR: + case SIOCSIFBRDADDR: + case SIOCSIFNETMASK: + case SIOCSIFMETRIC: + case SIOCSIFMTU: + case SIOCSIFMEM: + if (!suser()) + return -EPERM; + return dev_ifsioc(arg, cmd); + case SIOCSIFLINK: - if (!suser()) return(-EPERM); + if (!suser()) + return -EPERM; memcpy_fromfs(&iflink, arg, sizeof(iflink)); dev = ddi_map(iflink.id); - if (dev == NULL) return(-EINVAL); + if (dev == NULL) + return -EINVAL; /* Now allocate an interface and connect it. */ printk("AF_INET: DDI \"%s\" linked to stream \"%s\"\n", dev->name, iflink.stream); - ret = 0; - break; + return 0; + default: - ret = -EINVAL; + return -EINVAL; } - - return(ret); } diff --git a/net/inet/sock.c b/net/inet/sock.c index 45383b3aadec..c605eacdcd05 100644 --- a/net/inet/sock.c +++ b/net/inet/sock.c @@ -497,7 +497,7 @@ static int inet_setsockopt(struct socket *sock, int level, int optname, static int inet_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen) { - struct sock *sk = sock->data; + struct sock *sk = (struct sock *) sock->data; if (level == SOL_SOCKET) return sock_getsockopt(sk,level,optname,optval,optlen); if(sk->prot->getsockopt==NULL) diff --git a/net/inet/tcp.c b/net/inet/tcp.c index b57e1edee7b6..dc06c7589798 100644 --- a/net/inet/tcp.c +++ b/net/inet/tcp.c @@ -60,6 +60,7 @@ * Charles Hedrick : TCP fixes * Toomas Tamm : TCP window fixes * Alan Cox : Small URG fix to rlogin ^C ack fight + * Linus : Rewrote URG handling completely * * * To Fix: @@ -350,8 +351,8 @@ tcp_readable(struct sock *sk) if (amount && skb->h.th->psh) break; skb =(struct sk_buff *)skb->next; /* Move along */ } while(skb != sk->rqueue); - if (sk->urg_data && - (sk->urg_seq - sk->copied_seq) < (counted - sk->copied_seq)) + if (amount && !sk->urginline && sk->urg_data && + (sk->urg_seq - sk->copied_seq) <= (counted - sk->copied_seq)) amount--; /* don't count urg data */ restore_flags(flags); DPRINTF((DBG_TCP, "tcp readable returning %d bytes\n", amount)); @@ -442,7 +443,7 @@ tcp_select(struct sock *sk, int sel_type, select_table *wait) return(0); case SEL_EX: select_wait(sk->sleep,wait); - if (sk->err) { + if (sk->err || sk->urg_data) { release_sock(sk); return(1); } @@ -486,17 +487,11 @@ tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) } case SIOCATMARK: { - int answ = 0; + int answ = sk->urg_data && sk->urg_seq == sk->copied_seq+1; - /* - * Try to figure out if we need to read - * some urgent data. - */ - if (sk->urg_data && sk->copied_seq+1 == sk->urg_seq) - answ = 1; - err=verify_area(VERIFY_WRITE,(void *) arg, + err = verify_area(VERIFY_WRITE,(void *) arg, sizeof(unsigned long)); - if(err) + if (err) return err; put_fs_long(answ,(int *) arg); return(0); @@ -1250,7 +1245,9 @@ tcp_read_urg(struct sock * sk, int nonblock, struct wait_queue wait = { current, NULL }; while (len > 0) { - if (sk->urg_data && sk->urg_data != URG_READ) { + if (sk->urginline || !sk->urg_data || sk->urg_data == URG_READ) + return -EINVAL; + if (sk->urg_data & URG_VALID) { char c = sk->urg_data; if (!(flags & MSG_PEEK)) sk->urg_data = URG_READ; @@ -1285,8 +1282,8 @@ tcp_read_urg(struct sock * sk, int nonblock, current->state = TASK_INTERRUPTIBLE; add_wait_queue(sk->sleep, &wait); - if ((!sk->urg_data || sk->urg_data == URG_READ) && - sk->err == 0 && !(sk->shutdown & RCV_SHUTDOWN)) + if ((sk->urg_data & URG_NOTYET) && sk->err == 0 && + !(sk->shutdown & RCV_SHUTDOWN)) schedule(); remove_wait_queue(sk->sleep, &wait); current->state = TASK_RUNNING; @@ -1302,7 +1299,9 @@ tcp_read(struct sock *sk, unsigned char *to, { int copied = 0; /* will be used to say how much has been copied. */ struct sk_buff *skb; + unsigned long peek_seq; unsigned long offset; + unsigned long *seq; int err; if (len == 0) @@ -1310,11 +1309,11 @@ tcp_read(struct sock *sk, unsigned char *to, if (len < 0) return -EINVAL; - + err=verify_area(VERIFY_WRITE,to,len); - if(err) + if (err) return err; - + /* This error should be checked. */ if (sk->state == TCP_LISTEN) return -ENOTCONN; @@ -1327,6 +1326,11 @@ tcp_read(struct sock *sk, unsigned char *to, sk->inuse = 1; skb=skb_peek(&sk->rqueue); + peek_seq = sk->copied_seq; + seq = &sk->copied_seq; + if (flags & MSG_PEEK) + seq = &peek_seq; + DPRINTF((DBG_TCP, "tcp_read(sk=%X, to=%X, len=%d, nonblock=%d, flags=%X)\n", sk, to, len, nonblock, flags)); @@ -1334,7 +1338,7 @@ tcp_read(struct sock *sk, unsigned char *to, /* skb->used just checks to see if we've gone all the way around. */ /* While no data, or first data indicates some is missing, or data is used */ - while(skb == NULL || skb->used || before(sk->copied_seq+1, skb->h.th->seq)) { + while(skb == NULL || skb->used || before(1+*seq, skb->h.th->seq)) { DPRINTF((DBG_TCP, "skb = %X:\n", skb)); cleanup_rbuf(sk); if (sk->err) @@ -1413,7 +1417,7 @@ tcp_read(struct sock *sk, unsigned char *to, } skb = skb_peek(&sk->rqueue); - if (skb == NULL || before(sk->copied_seq+1, skb->h.th->seq)) { + if (skb == NULL || before(1+*seq, skb->h.th->seq)) { if(sk->debug) printk("Read wait sleep\n"); interruptible_sleep_on(sk->sleep); @@ -1439,30 +1443,18 @@ tcp_read(struct sock *sk, unsigned char *to, } /* - * are we at urgent data? + * are we at urgent data? Stop if we have read anything. */ - if (sk->urg_data && sk->copied_seq+1 == sk->urg_seq) { - if (sk->urg_data == URG_READ) { - if (copied || (flags & MSG_PEEK)) { - release_sock(sk); - return copied; - } - sk->urg_data = 0; - sk->copied_seq++; - } else { - release_sock(sk); - if (copied) - return copied; - send_sig(SIGURG, current, 0); - return -EINTR; - } + if (copied && sk->urg_data && sk->urg_seq == 1+*seq) { + release_sock(sk); + return copied; } /* * Copy anything from the current block that needs * to go into the user buffer. */ - offset = sk->copied_seq+1 - skb->h.th->seq; + offset = *seq - skb->h.th->seq + 1; if (skb->h.th->syn) offset--; @@ -1473,18 +1465,28 @@ tcp_read(struct sock *sk, unsigned char *to, if (len < used) used = len; /* do we have urgent data here? */ - if (sk->urg_data && sk->urg_seq - (sk->copied_seq+1) < used) - used = sk->urg_seq - (sk->copied_seq+1); + if (sk->urg_data) { + unsigned long urg_offset = sk->urg_seq - (1 + *seq); + if (urg_offset < used) { + if (!urg_offset) { + if (!(flags & MSG_PEEK)) + sk->urg_data = 0; + if (!sk->urginline) { + ++*seq; + offset++; + used--; + } + } else + used = offset; + } + } /* Copy it */ memcpy_tofs(to,((unsigned char *)skb->h.th) + skb->h.th->doff*4 + offset, used); copied += used; len -= used; to += used; - - /* If we were reading the data is 'eaten' */ - if (!(flags & MSG_PEEK)) - sk->copied_seq += used; + *seq += used; /* * Mark this data used if we are really reading it, and we @@ -1495,7 +1497,8 @@ tcp_read(struct sock *sk, unsigned char *to, } else { /* already used this data, must be a retransmit */ - skb->used = 1; + if (!(flags & MSG_PEEK)) + skb->used = 1; } /* Move along a packet */ skb =(struct sk_buff *)skb->next; @@ -2717,8 +2720,16 @@ tcp_data(struct sk_buff *skb, struct sock *sk, /* Now figure out if we can ack anything. */ if ((!dup_dumped && (skb1 == NULL || skb1->acked)) || before(th->seq, sk->acked_seq+1)) { if (before(th->seq, sk->acked_seq+1)) { - if (after(th->ack_seq, sk->acked_seq)) - sk->acked_seq = th->ack_seq; + int newwindow; + + if (after(th->ack_seq, sk->acked_seq)) { + newwindow = sk->window - + (th->ack_seq - sk->acked_seq); + if (newwindow < 0) + newwindow = 0; + sk->window = newwindow; + sk->acked_seq = th->ack_seq; + } skb->acked = 1; /* When we ack the fin, we turn on the RCV_SHUTDOWN flag. */ @@ -2733,16 +2744,12 @@ tcp_data(struct sk_buff *skb, struct sock *sk, if (before(skb2->h.th->seq, sk->acked_seq+1)) { if (after(skb2->h.th->ack_seq, sk->acked_seq)) { - long old_acked_seq = sk->acked_seq; + newwindow = sk->window - + (skb2->h.th->ack_seq - sk->acked_seq); + if (newwindow < 0) + newwindow = 0; + sk->window = newwindow; sk->acked_seq = skb2->h.th->ack_seq; - if((int)(sk->acked_seq - old_acked_seq) >0) - { - int new_window=sk->window-sk->acked_seq+ - old_acked_seq; - if(new_window<0) - new_window=0; - sk->window = new_window; - } } skb2->acked = 1; @@ -2845,54 +2852,56 @@ tcp_data(struct sk_buff *skb, struct sock *sk, } -static int -tcp_urg(struct sock *sk, struct tcphdr *th, unsigned long saddr, unsigned long len) +static void tcp_check_urg(struct sock * sk, struct tcphdr * th) { - unsigned long ptr; - extern int kill_pg(int pg, int sig, int priv); - extern int kill_proc(int pid, int sig, int priv); - - if (!sk->dead) - sk->data_ready(sk,0); - - if (sk->urginline) { - th->urg = 0; - th->psh = 1; - return 0; - } + unsigned long ptr = ntohs(th->urg_ptr); - ptr = ntohs(th->urg_ptr); if (ptr) ptr--; + ptr += th->seq; - /* is the urgent data in this packet at all? */ - if (th->doff*4 + ptr >= len) - return 0; - - /* have we already seen and read this? */ - if (after(sk->copied_seq+1, th->seq+ptr)) - return 0; + /* ignore urgent data that we've already seen and read */ + if (after(sk->copied_seq+1, ptr)) + return; - /* is this a duplicate? */ - if (sk->urg_data && sk->urg_seq == th->seq+ptr) - return 0; + /* do we already have a newer (or duplicate) urgent pointer? */ + if (sk->urg_data && !after(ptr, sk->urg_seq)) + return; - /* - * We signal the user only for the first urgent data: if urgent - * data already exists, no signal is sent - */ - if (!sk->urg_data || sk->urg_data == URG_READ) { - if (sk->proc != 0) { - if (sk->proc > 0) { - kill_proc(sk->proc, SIGURG, 1); - } else { - kill_pg(-sk->proc, SIGURG, 1); - } + /* tell the world about our new urgent pointer */ + if (sk->proc != 0) { + if (sk->proc > 0) { + kill_proc(sk->proc, SIGURG, 1); + } else { + kill_pg(-sk->proc, SIGURG, 1); } } + sk->urg_data = URG_NOTYET; + sk->urg_seq = ptr; +} + +static inline int tcp_urg(struct sock *sk, struct tcphdr *th, + unsigned long saddr, unsigned long len) +{ + unsigned long ptr; + + /* check if we get a new urgent pointer */ + if (th->urg) + tcp_check_urg(sk,th); - sk->urg_data = 0x100 | *(ptr + th->doff*4 + (unsigned char *) th); - sk->urg_seq = th->seq + ptr; + /* do we wait for any urgent data? */ + if (sk->urg_data != URG_NOTYET) + return 0; + + /* is the urgent pointer pointing into this packet? */ + ptr = sk->urg_seq - th->seq + th->doff*4; + if (ptr >= len) + return 0; + + /* ok, got the correct packet, update info */ + sk->urg_data = URG_VALID | *(ptr + (unsigned char *) th); + if (!sk->dead) + wake_up_interruptible(sk->sleep); return 0; } @@ -3389,12 +3398,11 @@ if (inet_debug == DBG_SLIP) printk("\rtcp_rcv: not in seq\n"); return(0); } } - if (th->urg) { - if (tcp_urg(sk, th, saddr, len)) { - kfree_skb(skb, FREE_READ); - release_sock(sk); - return(0); - } + + if (tcp_urg(sk, th, saddr, len)) { + kfree_skb(skb, FREE_READ); + release_sock(sk); + return(0); } if (tcp_data(skb, sk, saddr, len)) { diff --git a/net/inet/tcp.h b/net/inet/tcp.h index 5dcdaf5618db..5cbe0ea0a945 100644 --- a/net/inet/tcp.h +++ b/net/inet/tcp.h @@ -30,8 +30,10 @@ #define MIN_WRITE_SPACE 2048 #define TCP_WINDOW_DIFF 2048 -/* marks the urg_data as read */ -#define URG_READ 0xdeadbeef +/* urg_data states */ +#define URG_VALID 0x0100 +#define URG_NOTYET 0x0200 +#define URG_READ 0x0400 #define TCP_RETR1 7 /* * This is howmany retries it does before it -- 2.39.5