From 3f3d3923941876d57125ed03e4d95da25cf9799c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:18:15 -0500 Subject: [PATCH] Import 2.2.2 --- Documentation/Configure.help | 4 +-- arch/alpha/kernel/osf_sys.c | 4 +-- arch/alpha/kernel/proto.h | 2 +- arch/alpha/kernel/smc37c669.c | 33 ++++++++++++++++++++---- arch/alpha/kernel/sys_dp264.c | 6 ++--- arch/alpha/kernel/sys_miata.c | 2 +- arch/alpha/kernel/sys_sx164.c | 2 +- drivers/misc/parport_ieee1284.c | 2 +- drivers/net/Space.c | 2 +- drivers/net/hostess_sv11.c | 4 +-- drivers/net/ppp.c | 6 ++++- drivers/net/syncppp.c | 2 +- drivers/scsi/qlogicfas.c | 4 +-- fs/autofs/root.c | 11 +++++++- fs/autofs/waitq.c | 6 ++++- fs/inode.c | 1 + fs/open.c | 13 +++++----- include/linux/videodev.h | 2 ++ kernel/sched.c | 9 +++++++ net/ipv4/af_inet.c | 4 ++- net/ipv4/icmp.c | 4 +++ net/ipv4/tcp.c | 5 +--- net/ipv4/tcp_input.c | 14 ++++++---- net/ipv4/tcp_output.c | 2 +- net/ipv4/timer.c | 2 +- net/ipx/af_ipx.c | 45 ++++++++++++++++++--------------- 26 files changed, 126 insertions(+), 65 deletions(-) diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 587315e6fd71..1c625be2c8dc 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -85,11 +85,11 @@ CONFIG_SMP a system with only one CPU, like most personal computers, say N. If you have a system with more than one CPU, say Y. - If you say Y here, the kernel will run on single and multiprocessor + If you say N here, the kernel will run on single and multiprocessor machines, but will use only one CPU of a multiprocessor machine. If you say Y here, the kernel will run on many, but not all, singleprocessor machines. On a singleprocessor machine, the kernel - will run faster if you say Y here. + will run faster if you say N here. Note that if you say Y here and choose architecture "586" or "Pentium" under "Processor family", the kernel will not work on 486 diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 67c08778d2fa..8a8f153da8a0 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -317,8 +317,8 @@ static int do_osf_statfs(struct dentry * dentry, struct osf_statfs *buffer, unsi struct super_block * sb = inode->i_sb; int error; - error = -ENOSYS; - if (sb->s_op->statfs) { + error = -ENODEV; + if (sb && sb->s_op && sb->s_op->statfs) { set_fs(KERNEL_DS); error = sb->s_op->statfs(sb, &linux_stat, sizeof(linux_stat)); set_fs(USER_DS); diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index 4fa0120179ed..8a0efe52d6af 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h @@ -165,7 +165,7 @@ extern unsigned long est_cycle_freq; extern void SMC93x_Init(void); /* smc37c669.c */ -extern void SMC669_Init(void); +extern void SMC669_Init(int); /* es1888.c */ extern void es1888_init(void); diff --git a/arch/alpha/kernel/smc37c669.c b/arch/alpha/kernel/smc37c669.c index 1202b7b90b0a..caab7accc292 100644 --- a/arch/alpha/kernel/smc37c669.c +++ b/arch/alpha/kernel/smc37c669.c @@ -862,7 +862,7 @@ typedef struct _SMC37c669_DRQ_TRANSLATION_ENTRY { */ SMC37c669_CONFIG_REGS *SMC37c669_detect( - void + int ); unsigned int SMC37c669_enable_device( @@ -1014,6 +1014,29 @@ __initdata = { -1, -1 } /* End of table */ }; +/* +** The following definition is for the MONET (XP1000) IRQ +** translation table. +*/ +static SMC37c669_IRQ_TRANSLATION_ENTRY SMC37c669_monet_irq_table[] +__initdata = + { + { SMC37c669_DEVICE_IRQ_A, -1 }, + { SMC37c669_DEVICE_IRQ_B, -1 }, + { SMC37c669_DEVICE_IRQ_C, 6 }, + { SMC37c669_DEVICE_IRQ_D, 7 }, + { SMC37c669_DEVICE_IRQ_E, 4 }, + { SMC37c669_DEVICE_IRQ_F, 3 }, + { SMC37c669_DEVICE_IRQ_H, -1 }, + { -1, -1 } /* End of table */ + }; + +static SMC37c669_IRQ_TRANSLATION_ENTRY *SMC37c669_irq_tables[] __initdata = + { + SMC37c669_default_irq_table, + SMC37c669_monet_irq_table + }; + /* ** DRQ Translation Table ** @@ -1163,7 +1186,7 @@ struct DDB smc_ddb = { ** **-- */ -SMC37c669_CONFIG_REGS * __init SMC37c669_detect( void ) +SMC37c669_CONFIG_REGS * __init SMC37c669_detect( int index ) { int i; SMC37c669_DEVICE_ID_REGISTER id; @@ -1196,7 +1219,7 @@ SMC37c669_CONFIG_REGS * __init SMC37c669_detect( void ) /* ** Initialize the IRQ and DRQ translation tables. */ - SMC37c669_irq_table = SMC37c669_default_irq_table; + SMC37c669_irq_table = SMC37c669_irq_tables[ index ]; SMC37c669_drq_table = SMC37c669_default_drq_table; /* ** erfix @@ -2516,13 +2539,13 @@ SMC37c669_dump_registers(void) * None * */ -void __init SMC669_Init ( void ) +void __init SMC669_Init ( int index ) { SMC37c669_CONFIG_REGS *SMC_base; unsigned long flags; __save_and_cli(flags); - if ( ( SMC_base = SMC37c669_detect( ) ) != NULL ) { + if ( ( SMC_base = SMC37c669_detect( index ) ) != NULL ) { #if SMC_DEBUG SMC37c669_config_mode( TRUE ); SMC37c669_dump_registers( ); diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c index 656e5d868745..c464c37ec68c 100644 --- a/arch/alpha/kernel/sys_dp264.c +++ b/arch/alpha/kernel/sys_dp264.c @@ -316,7 +316,7 @@ dp264_pci_fixup(void) { layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE); common_pci_fixup(dp264_map_irq, common_swizzle); - SMC669_Init(); + SMC669_Init(0); } static void __init @@ -325,7 +325,7 @@ monet_pci_fixup(void) layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE); common_pci_fixup(monet_map_irq, monet_swizzle); /* es1888_init(); */ /* later? */ - SMC669_Init(); + SMC669_Init(1); } static void __init @@ -333,7 +333,7 @@ webbrick_pci_fixup(void) { layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE); common_pci_fixup(webbrick_map_irq, common_swizzle); - SMC669_Init(); + SMC669_Init(0); } diff --git a/arch/alpha/kernel/sys_miata.c b/arch/alpha/kernel/sys_miata.c index c6f908618277..f9c4b64c5b4e 100644 --- a/arch/alpha/kernel/sys_miata.c +++ b/arch/alpha/kernel/sys_miata.c @@ -267,7 +267,7 @@ miata_pci_fixup(void) { layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE); common_pci_fixup(miata_map_irq, miata_swizzle); - SMC669_Init(); /* it might be a GL (fails harmlessly if not) */ + SMC669_Init(0); /* it might be a GL (fails harmlessly if not) */ es1888_init(); } diff --git a/arch/alpha/kernel/sys_sx164.c b/arch/alpha/kernel/sys_sx164.c index a03f451d07da..a35fdd219800 100644 --- a/arch/alpha/kernel/sys_sx164.c +++ b/arch/alpha/kernel/sys_sx164.c @@ -183,7 +183,7 @@ sx164_pci_fixup(void) { layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE); common_pci_fixup(sx164_map_irq, common_swizzle); - SMC669_Init(); + SMC669_Init(0); } diff --git a/drivers/misc/parport_ieee1284.c b/drivers/misc/parport_ieee1284.c index 76f4c4cb9565..302aa821180d 100644 --- a/drivers/misc/parport_ieee1284.c +++ b/drivers/misc/parport_ieee1284.c @@ -52,7 +52,7 @@ int parport_ieee1284_nibble_mode_ok(struct parport *port, unsigned char mode) & ~1 ) & ~2); udelay(1); parport_write_data(port, mode); - udelay(1); + udelay(400); /* nSelectIn high, nAutoFd low */ parport_write_control(port, (parport_read_control(port) & ~8) | 2); if (parport_wait_peripheral(port, 0x78, 0x38)) { diff --git a/drivers/net/Space.c b/drivers/net/Space.c index 7e8e24848c35..86d2039975b8 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c @@ -518,7 +518,7 @@ __initfunc(static int fddiif_probe(struct device *dev)) && dfx_probe(dev) #endif #ifdef CONFIG_APFDDI - && apfddi_init(dev); + && apfddi_init(dev) #endif && 1 ) { return 1; /* -ENODEV or -EAGAIN would be more accurate. */ diff --git a/drivers/net/hostess_sv11.c b/drivers/net/hostess_sv11.c index 8317d37e046a..fe20840a48fb 100644 --- a/drivers/net/hostess_sv11.c +++ b/drivers/net/hostess_sv11.c @@ -416,10 +416,8 @@ static struct sv11_device *sv11_unit; int init_module(void) { - printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.01.\n"); + printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.02.\n"); printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.\n"); - if(dma) - printk(KERN_WARNING "DMA mode probably wont work right now.\n"); if((sv11_unit=sv11_init(io,irq))==NULL) return -ENODEV; return 0; diff --git a/drivers/net/ppp.c b/drivers/net/ppp.c index b2c07b3faee1..91e94c49b7c7 100644 --- a/drivers/net/ppp.c +++ b/drivers/net/ppp.c @@ -2062,7 +2062,11 @@ rcv_proto_vjc_comp(struct ppp *ppp, struct sk_buff *skb) "ppp: error in VJ decompression\n"); return 0; } - skb_put(skb, new_count + PPP_HDRLEN - skb->len); + new_count += PPP_HDRLEN; + if (new_count > skb->len) + skb_put(skb, new_count - skb->len); + else + skb_trim(skb, new_count); return rcv_proto_ip(ppp, skb); } diff --git a/drivers/net/syncppp.c b/drivers/net/syncppp.c index d2daea0a3020..b405d3d2cb7f 100644 --- a/drivers/net/syncppp.c +++ b/drivers/net/syncppp.c @@ -51,7 +51,7 @@ #include #include "syncppp.h" -#define MAXALIVECNT 3 /* max. alive packets */ +#define MAXALIVECNT 6 /* max. alive packets */ #define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ #define PPP_UI 0x03 /* Unnumbered Information */ diff --git a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c index 4279ee6f380c..cbf6a375cf67 100644 --- a/drivers/scsi/qlogicfas.c +++ b/drivers/scsi/qlogicfas.c @@ -5,8 +5,8 @@ these silly disclaimers. Copyright 1994, Tom Zerucha. - zerucha@shell.portal.com - + tz@execpc.com + Additional Code, and much appreciated help by Michael A. Griffith grif@cs.ucr.edu diff --git a/fs/autofs/root.c b/fs/autofs/root.c index 56190431855f..6d9e9d80dbd2 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c @@ -209,7 +209,7 @@ static struct dentry_operations autofs_dentry_operations = { NULL, /* d_compare */ }; -static int autofs_root_lookup(struct inode *dir, struct dentry * dentry) +static int autofs_root_lookup(struct inode *dir, struct dentry *dentry) { struct autofs_sb_info *sbi; int oz_mode; @@ -220,6 +220,9 @@ static int autofs_root_lookup(struct inode *dir, struct dentry * dentry) if (!S_ISDIR(dir->i_mode)) return -ENOTDIR; + if (dentry->d_name.len > NAME_MAX) + return -ENOENT; /* File name too long to exist */ + sbi = autofs_sbi(dir->i_sb); oz_mode = autofs_oz_mode(sbi); @@ -280,6 +283,9 @@ static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const c if ( !autofs_oz_mode(sbi) ) return -EPERM; + if ( dentry->d_name.len > NAME_MAX ) + return -ENAMETOOLONG; + if ( autofs_hash_lookup(dh, &dentry->d_name) ) return -EEXIST; @@ -401,6 +407,9 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode) if ( !autofs_oz_mode(sbi) ) return -EPERM; + if ( dentry->d_name.len > NAME_MAX ) + return -ENAMETOOLONG; + ent = autofs_hash_lookup(dh, &dentry->d_name); if ( ent ) return -EEXIST; diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c index 81c68af463b3..f9cccbd44074 100644 --- a/fs/autofs/waitq.c +++ b/fs/autofs/waitq.c @@ -99,7 +99,7 @@ static void autofs_notify_daemon(struct autofs_sb_info *sbi, struct autofs_wait_ autofs_catatonic_mode(sbi); } -int autofs_wait(struct autofs_sb_info *sbi, struct qstr * name) +int autofs_wait(struct autofs_sb_info *sbi, struct qstr *name) { struct autofs_wait_queue *wq; int status; @@ -107,6 +107,10 @@ int autofs_wait(struct autofs_sb_info *sbi, struct qstr * name) /* In catatonic mode, we don't wait for nobody */ if ( sbi->catatonic ) return -ENOENT; + + /* We shouldn't be able to get here, but just in case */ + if ( name->len > NAME_MAX ) + return -ENOENT; for ( wq = sbi->queues ; wq ; wq = wq->next ) { if ( wq->hash == name->hash && diff --git a/fs/inode.c b/fs/inode.c index 83554caa9612..0ad4c7992bf4 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -385,6 +385,7 @@ static void try_to_free_inodes(int goal) goal -= inodes_stat.nr_free_inodes; if (goal > 0) { spin_unlock(&inode_lock); + select_dcache(goal, 0); prune_dcache(goal); spin_lock(&inode_lock); sync_all_inodes(); diff --git a/fs/open.c b/fs/open.c index 137eb4d5fe9a..9850309ab242 100644 --- a/fs/open.c +++ b/fs/open.c @@ -22,10 +22,11 @@ asmlinkage int sys_statfs(const char * path, struct statfs * buf) error = PTR_ERR(dentry); if (!IS_ERR(dentry)) { struct inode * inode = dentry->d_inode; + struct super_block * sb = inode->i_sb; - error = -ENOSYS; - if (inode->i_sb->s_op->statfs) - error = inode->i_sb->s_op->statfs(inode->i_sb, buf, sizeof(struct statfs)); + error = -ENODEV; + if (sb && sb->s_op && sb->s_op->statfs) + error = sb->s_op->statfs(sb, buf, sizeof(struct statfs)); dput(dentry); } @@ -52,10 +53,8 @@ asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf) if (!(inode = dentry->d_inode)) goto out_putf; error = -ENODEV; - if (!(sb = inode->i_sb)) - goto out_putf; - error = -ENOSYS; - if (sb->s_op->statfs) + sb = inode->i_sb; + if (sb && sb->s_op && sb->s_op->statfs) error = sb->s_op->statfs(sb, buf, sizeof(struct statfs)); out_putf: fput(file); diff --git a/include/linux/videodev.h b/include/linux/videodev.h index ab04f1fee8ce..48605b233ee6 100644 --- a/include/linux/videodev.h +++ b/include/linux/videodev.h @@ -273,6 +273,8 @@ struct video_unit #define VID_HARDWARE_PLANB 16 /* PowerMac motherboard video-in */ #define VID_HARDWARE_BROADWAY 17 /* Broadway project */ #define VID_HARDWARE_GEMTEK 18 +#define VID_HARDWARE_TYPHOON 19 +#define VID_HARDWARE_VINO 20 /* Reserved for SGI Indy Vino */ /* * Initialiser list diff --git a/kernel/sched.c b/kernel/sched.c index 4510def86b5d..40d5b0729692 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -464,8 +464,17 @@ void add_timer(struct timer_list *timer) unsigned long flags; spin_lock_irqsave(&timerlist_lock, flags); + if (timer->prev) + goto bug; internal_add_timer(timer); +out: spin_unlock_irqrestore(&timerlist_lock, flags); + return; + +bug: + printk("bug: kernel timer added twice at %p.\n", + __builtin_return_address(0)); + goto out; } static inline int detach_timer(struct timer_list *timer) diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 3520b0c52d74..71c547f58193 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -5,7 +5,7 @@ * * PF_INET protocol family socket handler. * - * Version: $Id: af_inet.c,v 1.82 1999/01/04 20:36:44 davem Exp $ + * Version: $Id: af_inet.c,v 1.83 1999/02/22 13:54:18 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -828,6 +828,8 @@ int inet_shutdown(struct socket *sock, int how) sk->shutdown |= how; if (sk->prot->shutdown) sk->prot->shutdown(sk, how); + /* Wake up anyone sleeping in poll. */ + sk->state_change(sk); return(0); } diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 5ac2d9a53cff..544dd8937ce5 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -402,6 +402,10 @@ static inline int icmpv4_xrlim_allow(struct rtable *rt, int type, int code) if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) return 1; + /* No rate limit on loopback */ + if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) + return 1; + return xrlim_allow(dst, *(icmp_pointers[type].timeout)); } diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 67e482e862fe..8378c2b03e90 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp.c,v 1.134 1999/01/09 08:50:09 davem Exp $ + * Version: $Id: tcp.c,v 1.135 1999/02/22 13:54:21 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -1394,9 +1394,6 @@ void tcp_shutdown(struct sock *sk, int how) (TCPF_ESTABLISHED|TCPF_SYN_SENT|TCPF_SYN_RECV|TCPF_CLOSE_WAIT)) { lock_sock(sk); - /* Flag that the sender has shutdown. */ - sk->shutdown |= SEND_SHUTDOWN; - /* Clear out any half completed packets. FIN if needed. */ if (tcp_close_state(sk,0)) tcp_send_fin(sk); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index e6ebfec82d73..c93a874db5f5 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_input.c,v 1.155 1999/01/26 05:33:50 davem Exp $ + * Version: $Id: tcp_input.c,v 1.156 1999/02/22 13:54:13 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -130,11 +130,15 @@ static __inline__ void tcp_remember_ack(struct tcp_opt *tp, struct tcphdr *th, { tp->delayed_acks++; - /* Tiny-grams with PSH set make us ACK quickly. - * Note: This also clears the "quick ack mode" bit. + /* Tiny-grams with PSH set artifically deflate our + * ato measurement, but with a lower bound. */ - if(th->psh && (skb->len < (tp->mss_cache >> 1))) - tp->ato = HZ/50; + if(th->psh && (skb->len < (tp->mss_cache >> 1))) { + /* Preserve the quickack state. */ + if((tp->ato & 0x7fffffff) > HZ/50) + tp->ato = ((tp->ato & 0x80000000) | + (HZ/50)); + } } /* Called to compute a smoothed rtt estimate. The data fed to this diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index eb2185689637..03c96e99c870 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_output.c,v 1.101 1999/01/20 07:20:14 davem Exp $ + * Version: $Id: tcp_output.c,v 1.102 1999/02/22 13:54:26 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, diff --git a/net/ipv4/timer.c b/net/ipv4/timer.c index f6e86d92ddc5..3821a7c4cf21 100644 --- a/net/ipv4/timer.c +++ b/net/ipv4/timer.c @@ -5,7 +5,7 @@ * * TIMER - implementation of software timers for IP. * - * Version: $Id: timer.c,v 1.14 1998/11/07 11:55:43 davem Exp $ + * Version: $Id: timer.c,v 1.15 1999/02/22 13:54:29 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 8ff0fe317db1..929278b68fa4 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -766,11 +766,10 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) i = 0; - /* Dump packet if too many hops or already seen this net */ - if(ipx->ipx_tctrl < 8) - for( ; i < ipx->ipx_tctrl; i++) - if(*l++ == intrfc->if_netnum) - break; + /* Dump packet if already seen this net */ + for( ; i < ipx->ipx_tctrl; i++) + if(*l++ == intrfc->if_netnum) + break; if(i == ipx->ipx_tctrl) { @@ -779,6 +778,10 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) /* xmit on all other interfaces... */ for(ifcs = ipx_interfaces; ifcs != NULL; ifcs = ifcs->if_next) { + /* Except unconfigured interfaces */ + if(ifcs->if_netnum == 0) + continue; + /* That aren't in the list */ l = (__u32 *) c; for(i = 0; i <= ipx->ipx_tctrl; i++) @@ -2074,18 +2077,16 @@ int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) /* Too small? */ if(ntohs(ipx->ipx_pktsize) < sizeof(struct ipxhdr)) - { - kfree_skb(skb); - return (0); - } - + goto drop; + + /* Not ours */ + if (skb->pkt_type == PACKET_OTHERHOST) + goto drop; + if(ipx->ipx_checksum != IPX_NO_CHECKSUM) { if(ipx_set_checksum(ipx, ntohs(ipx->ipx_pktsize)) != ipx->ipx_checksum) - { - kfree_skb(skb); - return (0); - } + goto drop; } /* Determine what local ipx endpoint this is */ @@ -2099,13 +2100,14 @@ int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) } if(intrfc == NULL) /* Not one of ours */ - { - kfree_skb(skb); - return (0); - } + goto drop; } return (ipxitf_rcv(intrfc, skb)); + +drop: + kfree_skb(skb); + return (0); } static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len, @@ -2133,8 +2135,11 @@ static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len, uaddr.sipx_port = 0; uaddr.sipx_network = 0L; #ifdef CONFIG_IPX_INTERN - memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc - ->if_node, IPX_NODE_LEN); + if(sk->protinfo.af_ipx.intrfc) + memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc + ->if_node,IPX_NODE_LEN); + else + return -ENETDOWN; /* Someone zonked the iface */ #endif ret = ipx_bind(sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx)); -- 2.39.5