diff --git a/kame/sys/netinet/sctp_pcb.c b/kame/sys/netinet/sctp_pcb.c index 22f54d8c3e..2ec83275e3 100644 --- a/kame/sys/netinet/sctp_pcb.c +++ b/kame/sys/netinet/sctp_pcb.c @@ -1,4 +1,4 @@ -/* $KAME: sctp_pcb.c,v 1.19 2003/04/21 06:26:10 itojun Exp $ */ +/* $KAME: sctp_pcb.c,v 1.20 2003/04/22 07:24:05 itojun Exp $ */ /* Header: /home/sctpBsd/netinet/sctp_pcb.c,v 1.207 2002/04/04 16:53:46 randall Exp */ /* @@ -3790,43 +3790,45 @@ sctp_set_primary_addr(struct sctp_tcb *stcb, struct sockaddr *sa) int sctp_is_vtag_good(struct sctp_inpcb *m, u_int32_t tag, struct timeval *now) { - /* - * This function serves two purposes. It will see if a TAG can be - * re-used and return 1 for yes it is ok and 0 for don't use that - * tag. - * A secondary function it will do is purge out old tags that can - * be removed. - */ - struct sctpvtaghead *chain; - struct sctp_tagblock *twait_block; - - int i; + /* + * This function serves two purposes. It will see if a TAG can be + * re-used and return 1 for yes it is ok and 0 for don't use that + * tag. + * A secondary function it will do is purge out old tags that can + * be removed. + */ + struct sctpvtaghead *chain; + struct sctp_tagblock *twait_block; + + int i; #ifdef SCTP_VTAG_TIMEWAIT_PER_STACK - chain = &sctppcbinfo.vtag_timewait[(tag % SCTP_STACK_VTAG_HASH_SIZE)]; + chain = &sctppcbinfo.vtag_timewait[(tag % SCTP_STACK_VTAG_HASH_SIZE)]; #else - chain = &m->vtag_timewait[(tag % SCTP_STACK_VTAG_HASH_SIZE)]; -#endif - if (!LIST_EMPTY(chain)) { - /* Block(s) are present, lets see if we have this tag in the list */ - LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) { - for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) { - if (twait_block->vtag_block[i].v_tag == 0) { - /* not used */ - continue; - } else if (twait_block->vtag_block[i].tv_sec_at_expire > - now->tv_sec) { - /* Audit expires this guy */ - twait_block->vtag_block[i].tv_sec_at_expire = 0; - twait_block->vtag_block[i].v_tag = 0; - } else if (twait_block->vtag_block[i].v_tag == tag) { - /* Bad tag, sorry :< */ - return (0); + chain = &m->vtag_timewait[(tag % SCTP_STACK_VTAG_HASH_SIZE)]; +#endif + if (!LIST_EMPTY(chain)) { + /* + * Block(s) are present, lets see if we have this tag in + * the list + */ + LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) { + for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) { + if (twait_block->vtag_block[i].v_tag == 0) { + /* not used */ + continue; + } else if (twait_block->vtag_block[i].tv_sec_at_expire > now->tv_sec) { + /* Audit expires this guy */ + twait_block->vtag_block[i].tv_sec_at_expire = 0; + twait_block->vtag_block[i].v_tag = 0; + } else if (twait_block->vtag_block[i].v_tag == tag) { + /* Bad tag, sorry :< */ + return (0); + } + } } - } } - } - /* Not found, ok to use the tag */ - return (1); + /* Not found, ok to use the tag */ + return (1); } diff --git a/netbsd/sys/arch/arm/arm32/bcopyinout.S b/netbsd/sys/arch/arm/arm32/bcopyinout.S deleted file mode 100644 index 49aa5a1067..0000000000 --- a/netbsd/sys/arch/arm/arm32/bcopyinout.S +++ /dev/null @@ -1,245 +0,0 @@ -/* $NetBSD: bcopyinout.S,v 1.5 2002/03/23 02:22:57 thorpej Exp $ */ - -/* - * Copyright (c) 1995-1998 Mark Brinicombe. - * Copyright (c) 1995 Brini. - * All rights reserved. - * - * This code is derived from software written for Brini by Mark Brinicombe - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Mark Brinicombe. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * - * bcopyinout.S - * - * optimized and fault protected byte copy functions - * - * Created : 16/05/95 - */ - -#include "assym.h" - -#include -#include - - .text - .align 0 -Lcurpcb: - .word _C_LABEL(curpcb) - -Lvm_min_address: - .word VM_MIN_ADDRESS -Lvm_maxuser_address: - .word VM_MAXUSER_ADDRESS -Lvm_maxkern_address: - .word _C_LABEL(pmap_curmaxkvaddr) - -ENTRY(kcopy) - b do_copyinout - -/* - * r0 = user space address - * r1 = kernel space address - * r2 = length - * - * Copies bytes from user space to kernel space - */ - -ENTRY(copyin) - /* Validate user and kernel addresses */ - ldr r3, Lvm_min_address - cmp r0, r3 - bcc Lbadaddress - ldr r3, Lvm_maxuser_address - cmp r0, r3 - bcs Lbadaddress - cmp r1, r3 - bcc Lbadaddress - ldr r3, Lvm_maxkern_address - ldr ip, [r3] - cmp r1, ip - bcs Lbadaddress - - /* Quick exit if length is zero */ - teq r2, #0 - moveq r0, #0 - moveq pc, lr - - /* Do the actual copy */ - b do_copyinout - -/* - * r0 = kernel space address - * r1 = user space address - * r2 = length - * - * Copies bytes from user space to kernel space - */ - -Lpgbase: - .long PTE_BASE - -ENTRY(copyout) - /* Validate user and kernel addresses */ - ldr r3, Lvm_min_address - cmp r1, r3 - bcc Lbadaddress - ldr r3, Lvm_maxuser_address - cmp r1, r3 - bcs Lbadaddress - cmp r0, r3 - bcc Lbadaddress - ldr r3, Lvm_maxkern_address - ldr ip, [r3] - cmp r0, ip - bcs Lbadaddress - - /* Quick exit if length is zero */ - teq r2, #0 - moveq r0, #0 - moveq pc, lr - - /* Check the page protection for copy-on-write */ - stmfd sp!, {r4-r7} /* stack is 8 byte aligned */ - ldr r4, Lcurpcb - ldr r4, [r4] - - ldr r5, [r4, #PCB_ONFAULT] - add r3, pc, #do_cowfault - . - 8 - str r3, [r4, #PCB_ONFAULT] - - ldr r3, Lpgbase - add r6, r3, r1, lsr #(PGSHIFT-2) - bic r6, r6, #3 /* beginning PTE */ - - mov r7, r1, lsl #(32-PGSHIFT) - add r7, r2, r7, lsr #(32-PGSHIFT) - sub r7, r7, #1 - mov r7, r7, lsr #(PGSHIFT) /* number of pages -1 */ - -do_ptecheck: - ldr r3, [r6] /* grab PTE */ - tst r3, #1 /* check writable bit */ - beq do_cowfault /* if clear, do COW fault */ -do_ptecheck_next: - add r6, r6, #4 - subs r7, r7, #1 - bpl do_ptecheck - str r5, [r4, #PCB_ONFAULT] - ldmfd sp!, {r4-r7} /* stack is 8 byte aligned */ - - /* Do the actual copy */ - b do_copyinout - -do_cowfault: - stmfd sp!, {r0-r2, lr} /* stack is 8 byte aligned */ - ldr r3, Lpgbase - sub r0, r6, r3 - mov r0, r0, lsl #(PGSHIFT-2) /* calculate VA of page */ - bl _C_LABEL(cowfault) - mov r3, r0 - ldmfd sp!, {r0-r2, lr} /* stack is 8 byte aligned */ - teq r3, #0 /* check for error return */ - beq do_ptecheck_next - mov r0, r3 - str r5, [r4, #PCB_ONFAULT] - ldmfd sp!, {r4-r7} /* stack is 8 byte aligned */ - mov pc, lr - -do_copyinout: - stmfd sp!, {r4, r5} /* stack is 8 byte aligned */ - ldr r4, Lcurpcb - ldr r4, [r4] - -#ifdef DIAGNOSTIC - teq r4, #0x00000000 - beq Lcopyinoutpcbfault -#endif /* DIAGNOSTIC */ - - ldr r5, [r4, #PCB_ONFAULT] - add r3, pc, #Lcopyinoutfault - . - 8 - str r3, [r4, #PCB_ONFAULT] - - /* - * If less than 4 bytes or the source or destination address is - * not 32 bit aligned then copy it slowly, byte at a time. - * Otherwise copy it 32 bits at a time. - */ - subs r2, r2, #4 - bmi Lslow_copyinout - tst r0, #3 - tsteq r1, #3 - bne Lslow_copyinout - -Lcopyinout_loop: - ldr r3, [r0], #0x0004 - str r3, [r1], #0x0004 - subs r2, r2, #0x00000004 - bpl Lcopyinout_loop - - tst r2, #3 - beq Lcopyinout_exit - -Lslow_copyinout: - add r2, r2, #4 - -Lslow_copyinout_loop: - ldrb r3, [r0], #0x0001 - strb r3, [r1], #0x0001 - subs r2, r2, #0x00000001 - bne Lslow_copyinout_loop - -Lcopyinout_exit: - mov r0, #0x00000000 - str r5, [r4, #PCB_ONFAULT] - ldmfd sp!, {r4, r5} /* stack is 8 byte aligned */ - mov pc, lr - -/* A fault occurred during the copy */ -Lcopyinoutfault: - str r5, [r4, #PCB_ONFAULT] - ldmfd sp!, {r4, r5} /* stack is 8 byte aligned */ - - /* FALLTHROUGH */ - -/* Source or Destination address was bad so fail */ -Lbadaddress: - /* Don't return EFAULT if legnth was zero */ - teq r2, #0x00000000 - moveq r0, #0x00000000 - movne r0, #EFAULT - mov pc, lr - -#ifdef DIAGNOSTIC -Lcopyinoutpcbfault: - mov r2, r1 - mov r1, r0 - add r0, pc, #Lcopyinouttext - . - 8 - b _C_LABEL(panic) - -Lcopyinouttext: - .asciz "No valid PCB during copyinout() addr1=%08x addr2=%08x\n" - .align 0 -#endif /* DIAGNOSTIC */ diff --git a/netbsd/sys/arch/i386/conf/GENERIC b/netbsd/sys/arch/i386/conf/GENERIC index f69dbf0cc9..65128714e8 100644 --- a/netbsd/sys/arch/i386/conf/GENERIC +++ b/netbsd/sys/arch/i386/conf/GENERIC @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.491.4.2 2002/08/01 04:22:39 lukem Exp $ +# $NetBSD: GENERIC,v 1.491.4.4 2003/01/28 06:28:20 jmc Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ include "arch/i386/conf/std.i386" options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.491.4.2 $" +#ident "GENERIC-$Revision: 1.491.4.4 $" maxusers 32 # estimated number of users @@ -161,6 +161,7 @@ options PPP_DEFLATE # Deflate compression support for PPP options PPP_FILTER # Active filter support for PPP (requires bpf) options PFIL_HOOKS # pfil(9) packet filter hooks options IPFILTER_LOG # ipmon(8) log support +#options IPFILTER_DEFAULT_BLOCK # block all packets by default #options TCP_DEBUG # Record last TCP_NDEBUG packets with SO_DEBUG # These options enable verbose messages for several subsystems. @@ -604,6 +605,7 @@ ed* at edc? # PCI network interfaces an* at pci? dev ? function ? # Aironet PC4500/PC4800 (802.11) +bge* at pci? dev ? function ? # Broadcom 570x gigabit Ethernet en* at pci? dev ? function ? # ENI/Adaptec ATM ep* at pci? dev ? function ? # 3Com 3c59x epic* at pci? dev ? function ? # SMC EPIC/100 Ethernet diff --git a/netbsd/sys/arch/i386/i386/conf.c b/netbsd/sys/arch/i386/i386/conf.c index cf77057864..e5509e6ef8 100644 --- a/netbsd/sys/arch/i386/i386/conf.c +++ b/netbsd/sys/arch/i386/i386/conf.c @@ -1,4 +1,4 @@ -/* $NetBSD: conf.c,v 1.155 2002/04/18 12:54:15 wiz Exp $ */ +/* $NetBSD: conf.c,v 1.155.4.1 2002/12/12 23:48:38 he Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: conf.c,v 1.155 2002/04/18 12:54:15 wiz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: conf.c,v 1.155.4.1 2002/12/12 23:48:38 he Exp $"); #include "opt_compat_svr4.h" @@ -247,6 +247,8 @@ cdev_decl(dpti); cdev_decl(edmca); #include "agp.h" cdev_decl(agp); +#include "dpt.h" +cdev_decl(dpt); #include @@ -358,6 +360,13 @@ struct cdevsw cdevsw[] = cdev_radio_init(NRADIO,radio), /* 87: generic radio I/O */ cdev_netsmb_init(NNETSMB,nsmb_dev_),/* 88: SMB */ cdev_clockctl_init(NCLOCKCTL, clockctl),/* 89: clockctl pseudo device */ + cdev_notdef(), /* 90 */ + cdev_notdef(), /* 91 */ + cdev_notdef(), /* 92 */ + cdev_notdef(), /* 93 */ + cdev_notdef(), /* 94 */ + cdev_notdef(), /* 95 */ + cdev__oci_init(NDPT,dpt), /* 96: DPT/Adaptec RAID management */ }; int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]); @@ -489,6 +498,13 @@ static int chrtoblktbl[] = { /* 87 */ NODEV, /* 88 */ NODEV, /* 89 */ NODEV, + /* 90 */ NODEV, + /* 91 */ NODEV, + /* 92 */ NODEV, + /* 93 */ NODEV, + /* 94 */ NODEV, + /* 95 */ NODEV, + /* 96 */ NODEV, }; /* diff --git a/netbsd/sys/arch/i386/isa/icu.s b/netbsd/sys/arch/i386/isa/icu.s index 3b182d8472..7925ed5a9b 100644 --- a/netbsd/sys/arch/i386/isa/icu.s +++ b/netbsd/sys/arch/i386/isa/icu.s @@ -1,4 +1,4 @@ -/* $NetBSD: icu.s,v 1.65 2001/09/21 14:12:52 fvdl Exp $ */ +/* $NetBSD: icu.s,v 1.65.12.1 2003/02/08 07:17:20 jmc Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -82,13 +82,17 @@ IDTVEC(spllower) movl $1f,%esi # address to resume loop at 1: movl %ebx,%eax notl %eax + cli andl _C_LABEL(ipending),%eax jz 2f + sti bsfl %eax,%eax btrl %eax,_C_LABEL(ipending) jnc 1b jmp *_C_LABEL(Xrecurse)(,%eax,4) -2: popl %edi +2: movl %ebx,_C_LABEL(cpl) + sti + popl %edi popl %esi popl %ebx ret @@ -103,18 +107,19 @@ IDTVEC(spllower) */ IDTVEC(doreti) popl %ebx # get previous priority - movl %ebx,_C_LABEL(cpl) movl $1f,%esi # address to resume loop at 1: movl %ebx,%eax notl %eax + cli andl _C_LABEL(ipending),%eax jz 2f + sti bsfl %eax,%eax # slow, but not worth optimizing btrl %eax,_C_LABEL(ipending) jnc 1b # some intr cleared the in-memory bit jmp *_C_LABEL(Xresume)(,%eax,4) 2: /* Check for ASTs on exit to user mode. */ - cli + movl %ebx,_C_LABEL(cpl) cmpb $0,_C_LABEL(astpending) je 3f testb $SEL_RPL,TF_CS(%esp) @@ -143,7 +148,6 @@ IDTVEC(softserial) call _C_LABEL(softintr_dispatch) addl $4,%esp - movl %ebx,_C_LABEL(cpl) jmp *%esi IDTVEC(softnet) @@ -168,7 +172,6 @@ IDTVEC(softnet) call _C_LABEL(softintr_dispatch) addl $4,%esp - movl %ebx,_C_LABEL(cpl) jmp *%esi IDTVEC(softclock) @@ -179,5 +182,4 @@ IDTVEC(softclock) call _C_LABEL(softintr_dispatch) addl $4,%esp - movl %ebx,_C_LABEL(cpl) jmp *%esi diff --git a/netbsd/sys/arch/macppc/stand/ofwboot/alloc.c b/netbsd/sys/arch/macppc/stand/ofwboot/alloc.c new file mode 100644 index 0000000000..4c26b32374 --- /dev/null +++ b/netbsd/sys/arch/macppc/stand/ofwboot/alloc.c @@ -0,0 +1,249 @@ +/* $NetBSD: alloc.c,v 1.3.2.1 2002/09/30 13:38:33 lukem Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved. + * Copyright (c) 1996 + * Matthias Drochner. All rights reserved. + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Dynamic memory allocator suitable for use with OpenFirmware. + * + * Compile options: + * + * ALLOC_TRACE enable tracing of allocations/deallocations + * + * ALLOC_FIRST_FIT use a first-fit allocation algorithm, rather than + * the default best-fit algorithm. + * + * DEBUG enable debugging sanity checks. + */ + +#include +#include + +#include + +#include "openfirm.h" + +/* + * Each block actually has ALIGN(struct ml) + ALIGN(size) bytes allocated + * to it, as follows: + * + * 0 ... (sizeof(struct ml) - 1) + * allocated or unallocated: holds size of user-data part of block. + * + * sizeof(struct ml) ... (ALIGN(sizeof(struct ml)) - 1) + * allocated: unused + * unallocated: depends on packing of struct fl + * + * ALIGN(sizeof(struct ml)) ... (ALIGN(sizeof(struct ml)) + + * ALIGN(data size) - 1) + * allocated: user data + * unallocated: depends on packing of struct fl + * + * 'next' is only used when the block is unallocated (i.e. on the free list). + * However, note that ALIGN(sizeof(struct ml)) + ALIGN(data size) must + * be at least 'sizeof(struct fl)', so that blocks can be used as structures + * when on the free list. + */ + +/* + * Memory lists. + */ +struct ml { + unsigned size; + LIST_ENTRY(ml) list; +}; + +LIST_HEAD(, ml) freelist = LIST_HEAD_INITIALIZER(freelist); +LIST_HEAD(, ml) allocatedlist = LIST_HEAD_INITIALIZER(allocatedlist); + +#define OVERHEAD ALIGN(sizeof (struct ml)) /* shorthand */ + +void * +alloc(size) + unsigned size; +{ + struct ml *f, *bestf; + unsigned bestsize = 0xffffffff; /* greater than any real size */ + char *help; + int failed; + +#ifdef ALLOC_TRACE + printf("alloc(%u)", size); +#endif + + /* + * Account for overhead now, so that we don't get an + * "exact fit" which doesn't have enough space. + */ + size = ALIGN(size) + OVERHEAD; + +#ifdef ALLOC_FIRST_FIT + /* scan freelist */ + for (f = freelist.lh_first; f != NULL && f->size < size; + f = f->list.le_next) + /* noop */ ; + bestf = f; + failed = (bestf == (struct fl *)0); +#else + /* scan freelist */ + f = freelist.lh_first; + while (f != NULL) { + if (f->size >= size) { + if (f->size == size) /* exact match */ + goto found; + + if (f->size < bestsize) { + /* keep best fit */ + bestf = f; + bestsize = f->size; + } + } + f = f->list.le_next; + } + + /* no match in freelist if bestsize unchanged */ + failed = (bestsize == 0xffffffff); +#endif + + if (failed) { /* nothing found */ + /* + * Allocate memory from the OpenFirmware, rounded + * to page size, and record the chunk size. + */ + size = roundup(size, NBPG); + help = OF_claim(0, size, NBPG); + if (help == (char *)-1) + panic("alloc: out of memory"); + + f = (struct ml *)help; + f->size = size; +#ifdef ALLOC_TRACE + printf("=%lx (new chunk size %u)\n", + (u_long)(help + OVERHEAD), f->f_size); +#endif + goto out; + } + + /* we take the best fit */ + f = bestf; + + found: + /* remove from freelist */ + LIST_REMOVE(f, list); + help = (char *)f; +#ifdef ALLOC_TRACE + printf("=%lx (origsize %u)\n", (u_long)(help + OVERHEAD), f->size); +#endif + out: + /* place on allocated list */ + LIST_INSERT_HEAD(&allocatedlist, f, list); + return (help + OVERHEAD); +} + +void +free(ptr, size) + void *ptr; + unsigned size; /* only for consistenct check */ +{ + register struct ml *a = (struct ml *)((char*)ptr - OVERHEAD); + +#ifdef ALLOC_TRACE + printf("free(%lx, %u) (origsize %u)\n", (u_long)ptr, size, a->size); +#endif +#ifdef DEBUG + if (size > a->size) + printf("free %u bytes @%lx, should be <=%u\n", + size, (u_long)ptr, a->size); +#endif + + /* Remove from allocated list, place on freelist. */ + LIST_REMOVE(a, list); + LIST_INSERT_HEAD(&freelist, a, list); +} + +void +freeall() +{ +#ifdef __notyet__ /* Firmware bug ?! */ + struct ml *m; + + /* Release chunks on freelist... */ + while ((m = freelist.lh_first) != NULL) { + LIST_REMOVE(m, list); + OF_release(m, m->size); + } + + /* ...and allocated list. */ + while ((m = allocatedlist.lh_first) != NULL) { + LIST_REMOVE(m, list); + OF_release(m, m->size); + } +#endif /* __notyet__ */ +} diff --git a/netbsd/sys/conf/files b/netbsd/sys/conf/files index f6c96195c5..114ef72488 100644 --- a/netbsd/sys/conf/files +++ b/netbsd/sys/conf/files @@ -1,4 +1,4 @@ -# $NetBSD: files,v 1.530 2002/05/21 03:05:00 augustss Exp $ +# $NetBSD: files,v 1.530.2.1 2002/12/12 23:48:37 he Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -286,7 +286,7 @@ file dev/ic/aic77xx.c ahc_aic77xx # DPT EATA SCSI controllers # device dpt: scsi -file dev/ic/dpt.c dpt +file dev/ic/dpt.c dpt needs-flag # Compaq Smart ARRAY controllers # @@ -904,7 +904,7 @@ defpseudo faith: ifnet defpseudo stf: ifnet defpseudo irframetty: irframedrv, irdasir defpseudo hif: ifnet -defpseudo vrrp: ifnet, ether +defpseudo vrrp: ifnet, ether defpseudo sequencer defpseudo clockctl @@ -1115,7 +1115,7 @@ file net/if_ieee80211subr.c wlan file net/if_loop.c loop needs-count file net/if_media.c file net/if_ppp.c ppp needs-count -file net/if_stf.c stf needs-count +file net/if_stf.c stf & inet & inet6 needs-count file net/if_sl.c sl needs-count file net/if_spppsubr.c sppp file net/if_strip.c strip needs-count @@ -1123,7 +1123,7 @@ file net/if_tokensubr.c token needs-flag file net/if_tun.c tun needs-flag file net/if_vlan.c vlan needs-flag file net/if_pppoe.c pppoe needs-flag -file net/if_vrrp.c vrrp needs-flag +file net/if_vrrp.c vrrp needs-flag #file net/net_osdep.c file net/pfil.c pfil_hooks | ipfilter file net/ppp-deflate.c ppp & ppp_deflate diff --git a/netbsd/sys/dev/bi/if_ni.c b/netbsd/sys/dev/bi/if_ni.c index 4d9941cbfb..b8f7fab132 100644 --- a/netbsd/sys/dev/bi/if_ni.c +++ b/netbsd/sys/dev/bi/if_ni.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_ni.c,v 1.14 2001/11/13 12:51:34 lukem Exp $ */ +/* $NetBSD: if_ni.c,v 1.14.10.1 2003/01/27 05:37:37 jmc Exp $ */ /* * Copyright (c) 2000 Ludd, University of Lule}, Sweden. All rights reserved. * @@ -36,7 +36,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_ni.c,v 1.14 2001/11/13 12:51:34 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_ni.c,v 1.14.10.1 2003/01/27 05:37:37 jmc Exp $"); #include "opt_inet.h" #include "bpfilter.h" @@ -572,8 +572,6 @@ nistart(ifp) data->nd_ptdbidx = 1; data->nd_len = 10 + i * 8; data->bufs[i - 1]._index &= ~NIDG_CHAIN; - if (mlen < 64) - data->bufs[i - 1]._len = bdp[-1].nb_len += (64 - mlen); data->nd_cmdref = (u_int32_t)m; #ifdef DEBUG if (ifp->if_flags & IFF_DEBUG) diff --git a/netbsd/sys/dev/ic/dp8390.c b/netbsd/sys/dev/ic/dp8390.c index 9c99633d9e..bfc09392b5 100644 --- a/netbsd/sys/dev/ic/dp8390.c +++ b/netbsd/sys/dev/ic/dp8390.c @@ -1,4 +1,4 @@ -/* $NetBSD: dp8390.c,v 1.49 2001/11/13 13:14:36 lukem Exp $ */ +/* $NetBSD: dp8390.c,v 1.49.10.1 2003/01/27 05:26:24 jmc Exp $ */ /* * Device driver for National Semiconductor DS8390/WD83C690 based ethernet @@ -14,7 +14,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: dp8390.c,v 1.49 2001/11/13 13:14:36 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dp8390.c,v 1.49.10.1 2003/01/27 05:26:24 jmc Exp $"); #include "opt_ipkdb.h" #include "opt_inet.h" @@ -509,7 +509,7 @@ dp8390_start(ifp) len = dp8390_write_mbuf(sc, m0, buffer); m_freem(m0); - sc->txb_len[sc->txb_new] = max(len, ETHER_MIN_LEN - ETHER_CRC_LEN); + sc->txb_len[sc->txb_new] = len; /* Point to next buffer slot and wrap if necessary. */ if (++sc->txb_new == sc->txb_cnt) @@ -1259,7 +1259,11 @@ dp8390_write_mbuf(sc, m, buf) buf += len; } } - + if (totlen < ETHER_MIN_LEN - ETHER_CRC_LEN) { + bus_space_set_region_1(buft, bufh, buf, 0, + ETHER_MIN_LEN - ETHER_CRC_LEN - totlen); + totlen = ETHER_MIN_LEN - ETHER_CRC_LEN; + } return (totlen); } diff --git a/netbsd/sys/dev/ic/elinkxl.c b/netbsd/sys/dev/ic/elinkxl.c index fd4347d9da..9d358cb246 100644 --- a/netbsd/sys/dev/ic/elinkxl.c +++ b/netbsd/sys/dev/ic/elinkxl.c @@ -1,4 +1,4 @@ -/* $NetBSD: elinkxl.c,v 1.63 2002/05/12 15:48:38 wiz Exp $ */ +/* $NetBSD: elinkxl.c,v 1.63.4.1 2002/12/12 21:34:39 he Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: elinkxl.c,v 1.63 2002/05/12 15:48:38 wiz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: elinkxl.c,v 1.63.4.1 2002/12/12 21:34:39 he Exp $"); #include "bpfilter.h" #include "rnd.h" @@ -711,7 +711,9 @@ ex_init(ifp) return (error); } -#define ex_mchash(addr) (ether_crc32_be((addr), ETHER_ADDR_LEN) & 0xff) +#define MCHASHSIZE 256 +#define ex_mchash(addr) (ether_crc32_be((addr), ETHER_ADDR_LEN) & \ + (MCHASHSIZE - 1)) /* * Set multicast receive filter. Also take care of promiscuous mode @@ -728,28 +730,44 @@ ex_set_mc(sc) int i; u_int16_t mask = FIL_INDIVIDUAL | FIL_BRDCST; - if (ifp->if_flags & IFF_PROMISC) + if (ifp->if_flags & IFF_PROMISC) { mask |= FIL_PROMISC; + goto allmulti; + } - if (!(ifp->if_flags & IFF_MULTICAST)) - goto out; + ETHER_FIRST_MULTI(estep, ec, enm); + if (enm == NULL) + goto nomulti; + + if ((sc->ex_conf & EX_CONF_90XB) == 0) + /* No multicast hash filtering. */ + goto allmulti; + + for (i = 0; i < MCHASHSIZE; i++) + bus_space_write_2(sc->sc_iot, sc->sc_ioh, + ELINK_COMMAND, ELINK_CLEARHASHFILBIT | i); + + do { + if (memcmp(enm->enm_addrlo, enm->enm_addrhi, + ETHER_ADDR_LEN) != 0) + goto allmulti; + + i = ex_mchash(enm->enm_addrlo); + bus_space_write_2(sc->sc_iot, sc->sc_ioh, + ELINK_COMMAND, ELINK_SETHASHFILBIT | i); + ETHER_NEXT_MULTI(estep, enm); + } while (enm != NULL); + mask |= FIL_MULTIHASH; + +nomulti: + ifp->if_flags &= ~IFF_ALLMULTI; + bus_space_write_2(sc->sc_iot, sc->sc_ioh, ELINK_COMMAND, + SET_RX_FILTER | mask); + return; - if (!(sc->ex_conf & EX_CONF_90XB) || ifp->if_flags & IFF_ALLMULTI) { - mask |= (ifp->if_flags & IFF_MULTICAST) ? FIL_MULTICAST : 0; - } else { - ETHER_FIRST_MULTI(estep, ec, enm); - while (enm != NULL) { - if (memcmp(enm->enm_addrlo, enm->enm_addrhi, - ETHER_ADDR_LEN) != 0) - goto out; - i = ex_mchash(enm->enm_addrlo); - bus_space_write_2(sc->sc_iot, sc->sc_ioh, - ELINK_COMMAND, ELINK_SETHASHFILBIT | i); - ETHER_NEXT_MULTI(estep, enm); - } - mask |= FIL_MULTIHASH; - } - out: +allmulti: + ifp->if_flags |= IFF_ALLMULTI; + mask |= FIL_MULTICAST; bus_space_write_2(sc->sc_iot, sc->sc_ioh, ELINK_COMMAND, SET_RX_FILTER | mask); } diff --git a/netbsd/sys/dev/ic/rtl81x9.c b/netbsd/sys/dev/ic/rtl81x9.c index 37190f3696..f5dbdcc560 100644 --- a/netbsd/sys/dev/ic/rtl81x9.c +++ b/netbsd/sys/dev/ic/rtl81x9.c @@ -1,4 +1,4 @@ -/* $NetBSD: rtl81x9.c,v 1.40 2001/11/13 13:14:43 lukem Exp $ */ +/* $NetBSD: rtl81x9.c,v 1.40.10.1 2003/01/26 16:36:07 he Exp $ */ /* * Copyright (c) 1997, 1998 @@ -86,7 +86,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: rtl81x9.c,v 1.40 2001/11/13 13:14:43 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rtl81x9.c,v 1.40.10.1 2003/01/26 16:36:07 he Exp $"); #include "bpfilter.h" #include "rnd.h" @@ -171,6 +171,8 @@ STATIC int rtk_list_tx_init __P((struct rtk_softc *)); CSR_WRITE_1(sc, RTK_EECMD, \ CSR_READ_1(sc, RTK_EECMD) & ~(x)) +#define ETHER_PAD_LEN (ETHER_MIN_LEN - ETHER_CRC_LEN) + /* * Send a read command and address to the EEPROM, check for ACK. */ @@ -1292,8 +1294,11 @@ STATIC void rtk_start(ifp) * Load the DMA map. If this fails, the packet didn't * fit in one DMA segment, and we need to copy. Note, * the packet must also be aligned. + * if the packet is too small, copy it too, so we're sure + * so have enouth room for the pad buffer. */ if ((mtod(m_head, uintptr_t) & 3) != 0 || + m_head->m_pkthdr.len < ETHER_PAD_LEN || bus_dmamap_load_mbuf(sc->sc_dmat, txd->txd_dmamap, m_head, BUS_DMA_WRITE|BUS_DMA_NOWAIT) != 0) { MGETHDR(m_new, M_DONTWAIT, MT_DATA); @@ -1315,6 +1320,13 @@ STATIC void rtk_start(ifp) mtod(m_new, caddr_t)); m_new->m_pkthdr.len = m_new->m_len = m_head->m_pkthdr.len; + if (m_head->m_pkthdr.len < ETHER_PAD_LEN) { + memset( + mtod(m_new, caddr_t) + m_head->m_pkthdr.len, + 0, ETHER_PAD_LEN - m_head->m_pkthdr.len); + m_new->m_pkthdr.len = m_new->m_len = + ETHER_PAD_LEN; + } error = bus_dmamap_load_mbuf(sc->sc_dmat, txd->txd_dmamap, m_new, BUS_DMA_WRITE|BUS_DMA_NOWAIT); @@ -1325,6 +1337,14 @@ STATIC void rtk_start(ifp) } } IFQ_DEQUEUE(&ifp->if_snd, m_head); +#if NBPFILTER > 0 + /* + * If there's a BPF listener, bounce a copy of this frame + * to him. + */ + if (ifp->if_bpf) + bpf_mtap(ifp->if_bpf, m_head); +#endif if (m_new != NULL) { m_freem(m_head); m_head = m_new; @@ -1334,14 +1354,6 @@ STATIC void rtk_start(ifp) SIMPLEQ_REMOVE_HEAD(&sc->rtk_tx_free, txd, txd_q); SIMPLEQ_INSERT_TAIL(&sc->rtk_tx_dirty, txd, txd_q); -#if NBPFILTER > 0 - /* - * If there's a BPF listener, bounce a copy of this frame - * to him. - */ - if (ifp->if_bpf) - bpf_mtap(ifp->if_bpf, m_head); -#endif /* * Transmit the frame. */ @@ -1350,8 +1362,6 @@ STATIC void rtk_start(ifp) BUS_DMASYNC_PREWRITE); len = txd->txd_dmamap->dm_segs[0].ds_len; - if (len < (ETHER_MIN_LEN - ETHER_CRC_LEN)) - len = (ETHER_MIN_LEN - ETHER_CRC_LEN); CSR_WRITE_4(sc, txd->txd_txaddr, txd->txd_dmamap->dm_segs[0].ds_addr); diff --git a/netbsd/sys/dev/ic/sgec.c b/netbsd/sys/dev/ic/sgec.c index 4f2118c0a4..356b28f216 100644 --- a/netbsd/sys/dev/ic/sgec.c +++ b/netbsd/sys/dev/ic/sgec.c @@ -1,4 +1,4 @@ -/* $NetBSD: sgec.c,v 1.18 2001/11/13 13:14:44 lukem Exp $ */ +/* $NetBSD: sgec.c,v 1.18.10.1 2003/01/27 04:42:31 jmc Exp $ */ /* * Copyright (c) 1999 Ludd, University of Lule}, Sweden. All rights reserved. * @@ -45,7 +45,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sgec.c,v 1.18 2001/11/13 13:14:44 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sgec.c,v 1.18.10.1 2003/01/27 04:42:31 jmc Exp $"); #include "opt_inet.h" #include "bpfilter.h" @@ -370,8 +370,6 @@ zestart(ifp) if (totlen == len) orword = ZE_TDES1_FS; if (totlen == m->m_pkthdr.len) { - if (totlen < ETHER_MIN_LEN) - len += (ETHER_MIN_LEN - totlen); orword |= ZE_TDES1_LS; sc->sc_txmbuf[idx] = m; } diff --git a/netbsd/sys/dev/ic/smc83c170.c b/netbsd/sys/dev/ic/smc83c170.c index fc960e0b85..5518ae48f8 100644 --- a/netbsd/sys/dev/ic/smc83c170.c +++ b/netbsd/sys/dev/ic/smc83c170.c @@ -1,4 +1,4 @@ -/* $NetBSD: smc83c170.c,v 1.49 2001/11/13 13:14:44 lukem Exp $ */ +/* $NetBSD: smc83c170.c,v 1.49.10.1 2003/01/26 16:14:22 he Exp $ */ /*- * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. @@ -43,7 +43,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: smc83c170.c,v 1.49 2001/11/13 13:14:44 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: smc83c170.c,v 1.49.10.1 2003/01/26 16:14:22 he Exp $"); #include "bpfilter.h" @@ -106,6 +106,8 @@ void epic_mediastatus __P((struct ifnet *, struct ifmediareq *)); int epic_copy_small = 0; +#define ETHER_PAD_LEN (ETHER_MIN_LEN - ETHER_CRC_LEN) + /* * Attach an EPIC interface to the system. */ @@ -120,6 +122,7 @@ epic_attach(sc) bus_dma_segment_t seg; u_int8_t enaddr[ETHER_ADDR_LEN], devname[12 + 1]; u_int16_t myea[ETHER_ADDR_LEN / 2], mydevname[6]; + char *nullbuf; callout_init(&sc->sc_mii_callout); @@ -128,20 +131,24 @@ epic_attach(sc) * DMA map for it. */ if ((error = bus_dmamem_alloc(sc->sc_dmat, - sizeof(struct epic_control_data), PAGE_SIZE, 0, &seg, 1, &rseg, - BUS_DMA_NOWAIT)) != 0) { + sizeof(struct epic_control_data) + ETHER_PAD_LEN, PAGE_SIZE, 0, + &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { printf("%s: unable to allocate control data, error = %d\n", sc->sc_dev.dv_xname, error); goto fail_0; } if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, - sizeof(struct epic_control_data), (caddr_t *)&sc->sc_control_data, + sizeof(struct epic_control_data) + ETHER_PAD_LEN, + (caddr_t *)&sc->sc_control_data, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) { printf("%s: unable to map control data, error = %d\n", sc->sc_dev.dv_xname, error); goto fail_1; } + nullbuf = + (char *)sc->sc_control_data + sizeof(struct epic_control_data); + memset(nullbuf, 0, ETHER_PAD_LEN); if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct epic_control_data), 1, @@ -187,6 +194,24 @@ epic_attach(sc) EPIC_DSRX(sc, i)->ds_mbuf = NULL; } + /* + * create and map the pad buffer + */ + if ((error = bus_dmamap_create(sc->sc_dmat, ETHER_PAD_LEN, 1, + ETHER_PAD_LEN, 0, BUS_DMA_NOWAIT,&sc->sc_nulldmamap)) != 0) { + printf("%s: unable to create pad buffer DMA map, " + "error = %d\n", sc->sc_dev.dv_xname, error); + goto fail_5; + } + + if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_nulldmamap, + nullbuf, ETHER_PAD_LEN, NULL, BUS_DMA_NOWAIT)) != 0) { + printf("%s: unable to load pad buffer DMA map, " + "error = %d\n", sc->sc_dev.dv_xname, error); + goto fail_6; + } + bus_dmamap_sync(sc->sc_dmat, sc->sc_nulldmamap, 0, ETHER_PAD_LEN, + BUS_DMASYNC_PREWRITE); /* * Bring the chip out of low-power mode and reset it to a known state. @@ -290,6 +315,8 @@ epic_attach(sc) * Free any resources we've allocated during the failed attach * attempt. Do this in reverse order and fall through. */ + fail_6: + bus_dmamap_destroy(sc->sc_dmat, sc->sc_nulldmamap); fail_5: for (i = 0; i < EPIC_NRXDESC; i++) { if (EPIC_DSRX(sc, i)->ds_dmamap != NULL) @@ -378,8 +405,13 @@ epic_start(ifp) * short on resources. In this case, we'll copy and try * again. */ - if (bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0, - BUS_DMA_WRITE|BUS_DMA_NOWAIT) != 0) { + if ((error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0, + BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 || + (m0->m_pkthdr.len < ETHER_PAD_LEN && + dmamap-> dm_nsegs == EPIC_NFRAGS)) { + if (error == 0) + bus_dmamap_unload(sc->sc_dmat, dmamap); + MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) { printf("%s: unable to allocate Tx mbuf\n", @@ -412,13 +444,19 @@ epic_start(ifp) } /* Initialize the fraglist. */ - fr->ef_nfrags = dmamap->dm_nsegs; for (seg = 0; seg < dmamap->dm_nsegs; seg++) { fr->ef_frags[seg].ef_addr = dmamap->dm_segs[seg].ds_addr; fr->ef_frags[seg].ef_length = dmamap->dm_segs[seg].ds_len; } + if (m0->m_pkthdr.len < ETHER_PAD_LEN) { + fr->ef_frags[seg].ef_addr = sc->sc_nulldma; + fr->ef_frags[seg].ef_length = + ETHER_PAD_LEN - m0->m_pkthdr.len; + seg++; + } + fr->ef_nfrags = seg; EPIC_CDFLSYNC(sc, nexttx, BUS_DMASYNC_PREWRITE); @@ -432,12 +470,10 @@ epic_start(ifp) ds->ds_mbuf = m0; /* - * Fill in the transmit descriptor. The EPIC doesn't - * auto-pad, so we have to do this ourselves. + * Fill in the transmit descriptor. */ txd->et_control = ET_TXCTL_LASTDESC | ET_TXCTL_FRAGLIST; - txd->et_txlength = max(m0->m_pkthdr.len, - ETHER_MIN_LEN - ETHER_CRC_LEN); + txd->et_txlength = max(m0->m_pkthdr.len, ETHER_PAD_LEN); /* * If this is the first descriptor we're enqueueing, diff --git a/netbsd/sys/dev/ic/tulip.c b/netbsd/sys/dev/ic/tulip.c index fb39e54da8..bb5f664de2 100644 --- a/netbsd/sys/dev/ic/tulip.c +++ b/netbsd/sys/dev/ic/tulip.c @@ -1,4 +1,4 @@ -/* $NetBSD: tulip.c,v 1.113.4.2 2002/07/15 16:30:15 thorpej Exp $ */ +/* $NetBSD: tulip.c,v 1.113.4.3 2002/12/07 23:02:09 he Exp $ */ /*- * Copyright (c) 1998, 1999, 2000, 2002 The NetBSD Foundation, Inc. @@ -43,7 +43,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: tulip.c,v 1.113.4.2 2002/07/15 16:30:15 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tulip.c,v 1.113.4.3 2002/12/07 23:02:09 he Exp $"); #include "bpfilter.h" @@ -4962,6 +4962,15 @@ tlp_2114x_isv_tmsw_init(sc) case TULIP_CHIP_21140A: /* XXX should come from SROM */ defmedia = IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, 0); + if (ifmedia_match(&sc->sc_mii.mii_media, defmedia, + sc->sc_mii.mii_media.ifm_mask) == NULL) { + /* + * There is not a 10baseT media. + * Fall back to the first found one. + */ + ife = TAILQ_FIRST(&sc->sc_mii.mii_media.ifm_list); + defmedia = ife->ifm_media; + } break; case TULIP_CHIP_21142: diff --git a/netbsd/sys/dev/isa/if_eg.c b/netbsd/sys/dev/isa/if_eg.c index 33bd8e470b..4bab2a3b07 100644 --- a/netbsd/sys/dev/isa/if_eg.c +++ b/netbsd/sys/dev/isa/if_eg.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_eg.c,v 1.57 2002/01/07 21:47:06 thorpej Exp $ */ +/* $NetBSD: if_eg.c,v 1.57.10.1 2003/01/27 04:45:20 jmc Exp $ */ /* * Copyright (c) 1993 Dean Huxley @@ -40,7 +40,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_eg.c,v 1.57 2002/01/07 21:47:06 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_eg.c,v 1.57.10.1 2003/01/27 04:45:20 jmc Exp $"); #include "opt_inet.h" #include "opt_ns.h" @@ -660,6 +660,8 @@ egstart(ifp) memcpy(buffer, mtod(m, caddr_t), m->m_len); buffer += m->m_len; } + if (len > m0->m_pkthdr.len) + memset(buffer, 0, len - m0->m_pkthdr.len); /* set direction bit: host -> adapter */ bus_space_write_1(iot, ioh, EG_CONTROL, diff --git a/netbsd/sys/dev/isa/if_el.c b/netbsd/sys/dev/isa/if_el.c index 8721cb52d1..fd931d8ec6 100644 --- a/netbsd/sys/dev/isa/if_el.c +++ b/netbsd/sys/dev/isa/if_el.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_el.c,v 1.66 2002/01/07 21:47:07 thorpej Exp $ */ +/* $NetBSD: if_el.c,v 1.66.10.1 2003/01/27 04:54:01 jmc Exp $ */ /* * Copyright (c) 1994, Matthew E. Kimmel. Permission is hereby granted @@ -19,7 +19,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_el.c,v 1.66 2002/01/07 21:47:07 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_el.c,v 1.66.10.1 2003/01/27 04:54:01 jmc Exp $"); #include "opt_inet.h" #include "opt_ns.h" @@ -433,6 +433,9 @@ elstart(ifp) for (m = m0; m != 0; m = m->m_next) bus_space_write_multi_1(iot, ioh, EL_BUF, mtod(m, u_int8_t *), m->m_len); + for (i = 0; + i < ETHER_MIN_LEN - ETHER_CRC_LEN - m0->m_pkthdr.len; i++) + bus_space_write_1(iot, ioh, EL_BUF, 0); m_freem(m0); diff --git a/netbsd/sys/dev/ofw/ofnet.c b/netbsd/sys/dev/ofw/ofnet.c index a6b9aac99c..39e3110b9e 100644 --- a/netbsd/sys/dev/ofw/ofnet.c +++ b/netbsd/sys/dev/ofw/ofnet.c @@ -1,4 +1,4 @@ -/* $NetBSD: ofnet.c,v 1.24 2002/03/05 04:12:58 itojun Exp $ */ +/* $NetBSD: ofnet.c,v 1.24.8.1 2003/01/27 04:57:40 jmc Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -32,7 +32,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ofnet.c,v 1.24 2002/03/05 04:12:58 itojun Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ofnet.c,v 1.24.8.1 2003/01/27 04:57:40 jmc Exp $"); #include "ofnet.h" #include "opt_inet.h" @@ -360,9 +360,10 @@ ofnet_start(struct ifnet *ifp) * minimum size Ethernet packet. */ - if (len < (ETHER_MIN_LEN - ETHER_CRC_LEN)) - len = ETHER_MIN_LEN - ETHER_CRC_LEN; - else + if (len < (ETHER_MIN_LEN - ETHER_CRC_LEN)) { + memset(bufp, 0, ETHER_MIN_LEN - ETHER_CRC_LEN - len); + bufp += ETHER_MIN_LEN - ETHER_CRC_LEN - len; + } else len = bufp - buf; if (OF_write(of->sc_ihandle, buf, len) != len) diff --git a/netbsd/sys/dev/pci/files.pci b/netbsd/sys/dev/pci/files.pci index 970f303979..73a5805a58 100644 --- a/netbsd/sys/dev/pci/files.pci +++ b/netbsd/sys/dev/pci/files.pci @@ -1,4 +1,4 @@ -# $NetBSD: files.pci,v 1.173.2.1 2002/08/07 23:49:20 lukem Exp $ +# $NetBSD: files.pci,v 1.173.2.2 2003/01/28 06:21:23 jmc Exp $ # # Config file and device description for machine-independent PCI code. # Included by ports that need it. Requires that the SCSI files be @@ -469,6 +469,11 @@ device wm: ether, ifnet, arp, mii, mii_bitbang attach wm at pci file dev/pci/if_wm.c wm +# Broadcom 570x Gigabit Ethernet +device bge: ether, ifnet, arp, mii, mii_bitbang +attach bge at pci +file dev/pci/if_bge.c bge + # Realtek 8129/8139 Ethernet controllers attach rtk at pci with rtk_pci file dev/pci/if_rtk_pci.c rtk_pci diff --git a/netbsd/sys/dev/pci/if_bge.c b/netbsd/sys/dev/pci/if_bge.c index a2cfd92d7f..563362637d 100644 --- a/netbsd/sys/dev/pci/if_bge.c +++ b/netbsd/sys/dev/pci/if_bge.c @@ -2380,12 +2380,13 @@ bge_rxeof(sc) * to vlan_input() instead of ether_input(). */ if (have_tag) { - struct mbuf *n; + struct m_tag *mtag; - n = m_aux_add(m, AF_LINK, ETHERTYPE_VLAN); - if (n != NULL) { - *mtod(n, int *) = vlan_tag; - n->m_len = sizeof(int); + mtag = m_tag_get(PACKET_TAG_VLAN, sizeof(u_int), + M_NOWAIT); + if (mtag != NULL) { + *(u_int *)(mtag + 1) = vlan_tag; + m_tag_prepend(m, mtag); have_tag = vlan_tag = 0; } else { printf("%s: no mbuf for tag\n", ifp->if_xname); @@ -2644,9 +2645,9 @@ bge_encap(sc, m_head, txidx) struct txdmamap_pool_entry *dma; bus_dmamap_t dmamap; int i = 0; - struct mbuf *n; - struct mbuf *prev, *m; - int totlen, prevlen; + struct m_tag *mtag; + struct mbuf *prev, *m; + int totlen, prevlen; cur = frag = *txidx; @@ -2722,8 +2723,8 @@ bge_encap(sc, m_head, txidx) BUS_DMA_NOWAIT)) return(ENOBUFS); - n = sc->ethercom.ec_nvlans ? - m_aux_find(m_head, AF_LINK, ETHERTYPE_VLAN) : NULL; + mtag = sc->ethercom.ec_nvlans ? + m_tag_find(m_head, PACKET_TAG_VLAN, NULL) : NULL; for (i = 0; i < dmamap->dm_nsegs; i++) { f = &sc->bge_rdata->bge_tx_ring[frag]; @@ -2733,9 +2734,9 @@ bge_encap(sc, m_head, txidx) f->bge_len = dmamap->dm_segs[i].ds_len; f->bge_flags = csum_flags; - if (n != NULL) { + if (mtag != NULL) { f->bge_flags |= BGE_TXBDFLAG_VLAN_TAG; - f->bge_vlan_tag = *mtod(n, int *); + f->bge_vlan_tag = *(u_int *)(mtag + 1); } else { f->bge_vlan_tag = 0; } diff --git a/netbsd/sys/dev/pci/if_sip.c b/netbsd/sys/dev/pci/if_sip.c index bf7c25f362..665f3f5d78 100644 --- a/netbsd/sys/dev/pci/if_sip.c +++ b/netbsd/sys/dev/pci/if_sip.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_sip.c,v 1.52.4.1 2002/05/28 23:00:39 tv Exp $ */ +/* $NetBSD: if_sip.c,v 1.52.4.7 2002/11/21 18:28:15 he Exp $ */ /*- * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc. @@ -78,11 +78,11 @@ * * - Support the 10-bit interface on the DP83820 (for fiber). * - * - Reduce the interrupt load. + * - Reduce the Rx interrupt load. */ #include -__KERNEL_RCSID(0, "$NetBSD: if_sip.c,v 1.52.4.1 2002/05/28 23:00:39 tv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_sip.c,v 1.52.4.7 2002/11/21 18:28:15 he Exp $"); #include "bpfilter.h" @@ -254,8 +254,11 @@ struct sip_softc { */ struct evcnt sc_ev_txsstall; /* Tx stalled due to no txs */ struct evcnt sc_ev_txdstall; /* Tx stalled due to no txd */ - struct evcnt sc_ev_txintr; /* Tx interrupts */ + struct evcnt sc_ev_txforceintr; /* Tx interrupts forced */ + struct evcnt sc_ev_txdintr; /* Tx descriptor interrupts */ + struct evcnt sc_ev_txiintr; /* Tx idle interrupts */ struct evcnt sc_ev_rxintr; /* Rx interrupts */ + struct evcnt sc_ev_hiberr; /* HIBERR interrupts */ #ifdef DP83820 struct evcnt sc_ev_rxipsum; /* IP checksums checked in-bound */ struct evcnt sc_ev_rxtcpsum; /* TCP checksums checked in-bound */ @@ -286,6 +289,7 @@ struct sip_softc { int sc_txfree; /* number of free Tx descriptors */ int sc_txnext; /* next ready Tx descriptor */ + int sc_txwin; /* Tx descriptors since last intr */ struct sip_txsq sc_txfreeq; /* free Tx descsofts */ struct sip_txsq sc_txdirtyq; /* dirty Tx descsofts */ @@ -548,6 +552,49 @@ SIP_DECL(lookup)(const struct pci_attach_args *pa) return (NULL); } +#ifdef DP83820 +/* + * I really hate stupid hardware vendors. There's a bit in the EEPROM + * which indicates if the card can do 64-bit data transfers. Unfortunately, + * several vendors of 32-bit cards fail to clear this bit in the EEPROM, + * which means we try to use 64-bit data transfers on those cards if we + * happen to be plugged into a 32-bit slot. + * + * What we do is use this table of cards known to be 64-bit cards. If + * you have a 64-bit card who's subsystem ID is not listed in this table, + * send the output of "pcictl dump ..." of the device to me so that your + * card will use the 64-bit data path when plugged into a 64-bit slot. + * + * -- Jason R. Thorpe + * June 30, 2002 + */ +static int +SIP_DECL(check_64bit)(const struct pci_attach_args *pa) +{ + static const struct { + pci_vendor_id_t c64_vendor; + pci_product_id_t c64_product; + } card64[] = { + /* Asante GigaNIX */ + { 0x128a, 0x0002 }, + + { 0, 0} + }; + pcireg_t subsys; + int i; + + subsys = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); + + for (i = 0; card64[i].c64_vendor != 0; i++) { + if (PCI_VENDOR(subsys) == card64[i].c64_vendor && + PCI_PRODUCT(subsys) == card64[i].c64_product) + return (1); + } + + return (0); +} +#endif /* DP83820 */ + int SIP_DECL(match)(struct device *parent, struct cfdata *cf, void *aux) { @@ -787,31 +834,73 @@ SIP_DECL(attach)(struct device *parent, struct device *self, void *aux) * friends -- it affects packet data, not descriptors. */ #ifdef DP83820 + /* + * Cause the chip to load configuration data from the EEPROM. + */ + bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_PTSCR, PTSCR_EELOAD_EN); + for (i = 0; i < 10000; i++) { + delay(10); + if ((bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_PTSCR) & + PTSCR_EELOAD_EN) == 0) + break; + } + if (bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_PTSCR) & + PTSCR_EELOAD_EN) { + printf("%s: timeout loading configuration from EEPROM\n", + sc->sc_dev.dv_xname); + return; + } + reg = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_CFG); if (reg & CFG_PCI64_DET) { - printf("%s: 64-bit PCI slot detected\n", sc->sc_dev.dv_xname); + printf("%s: 64-bit PCI slot detected", sc->sc_dev.dv_xname); /* - * XXX Need some PCI flags indicating support for - * XXX 64-bit addressing (SAC or DAC) and 64-bit - * XXX data path. + * Check to see if this card is 64-bit. If so, enable 64-bit + * data transfers. + * + * We can't use the DATA64_EN bit in the EEPROM, because + * vendors of 32-bit cards fail to clear that bit in many + * cases (yet the card still detects that it's in a 64-bit + * slot; go figure). */ + if (SIP_DECL(check_64bit)(pa)) { + sc->sc_cfg |= CFG_DATA64_EN; + printf(", using 64-bit data transfers"); + } + printf("\n"); } - if (sc->sc_cfg & (CFG_TBI_EN|CFG_EXT_125)) { + + /* + * XXX Need some PCI flags indicating support for + * XXX 64-bit addressing. + */ +#if 0 + if (reg & CFG_M64ADDR) + sc->sc_cfg |= CFG_M64ADDR; + if (reg & CFG_T64ADDR) + sc->sc_cfg |= CFG_T64ADDR; +#endif + + if (reg & (CFG_TBI_EN|CFG_EXT_125)) { const char *sep = ""; printf("%s: using ", sc->sc_dev.dv_xname); - if (sc->sc_cfg & CFG_EXT_125) { + if (reg & CFG_EXT_125) { + sc->sc_cfg |= CFG_EXT_125; printf("%s125MHz clock", sep); sep = ", "; } - if (sc->sc_cfg & CFG_TBI_EN) { + if (reg & CFG_TBI_EN) { + sc->sc_cfg |= CFG_TBI_EN; printf("%sten-bit interface", sep); sep = ", "; } printf("\n"); } - if ((pa->pa_flags & PCI_FLAGS_MRM_OKAY) == 0) + if ((pa->pa_flags & PCI_FLAGS_MRM_OKAY) == 0 || + (reg & CFG_MRM_DIS) != 0) sc->sc_cfg |= CFG_MRM_DIS; - if ((pa->pa_flags & PCI_FLAGS_MWI_OKAY) == 0) + if ((pa->pa_flags & PCI_FLAGS_MWI_OKAY) == 0 || + (reg & CFG_MWI_DIS) != 0) sc->sc_cfg |= CFG_MWI_DIS; /* @@ -930,10 +1019,16 @@ SIP_DECL(attach)(struct device *parent, struct device *self, void *aux) NULL, sc->sc_dev.dv_xname, "txsstall"); evcnt_attach_dynamic(&sc->sc_ev_txdstall, EVCNT_TYPE_MISC, NULL, sc->sc_dev.dv_xname, "txdstall"); - evcnt_attach_dynamic(&sc->sc_ev_txintr, EVCNT_TYPE_INTR, - NULL, sc->sc_dev.dv_xname, "txintr"); + evcnt_attach_dynamic(&sc->sc_ev_txforceintr, EVCNT_TYPE_INTR, + NULL, sc->sc_dev.dv_xname, "txforceintr"); + evcnt_attach_dynamic(&sc->sc_ev_txdintr, EVCNT_TYPE_INTR, + NULL, sc->sc_dev.dv_xname, "txdintr"); + evcnt_attach_dynamic(&sc->sc_ev_txiintr, EVCNT_TYPE_INTR, + NULL, sc->sc_dev.dv_xname, "txiintr"); evcnt_attach_dynamic(&sc->sc_ev_rxintr, EVCNT_TYPE_INTR, NULL, sc->sc_dev.dv_xname, "rxintr"); + evcnt_attach_dynamic(&sc->sc_ev_hiberr, EVCNT_TYPE_INTR, + NULL, sc->sc_dev.dv_xname, "hiberr"); #ifdef DP83820 evcnt_attach_dynamic(&sc->sc_ev_rxipsum, EVCNT_TYPE_MISC, NULL, sc->sc_dev.dv_xname, "rxipsum"); @@ -1188,6 +1283,17 @@ SIP_DECL(start)(struct ifnet *ifp) /* Clear the MORE bit on the last segment. */ sc->sc_txdescs[lasttx].sipd_cmdsts &= htole32(~CMDSTS_MORE); + /* + * If we're in the interrupt delay window, delay the + * interrupt. + */ + if (++sc->sc_txwin >= (SIP_TXQUEUELEN * 2 / 3)) { + SIP_EVCNT_INCR(&sc->sc_ev_txforceintr); + sc->sc_txdescs[lasttx].sipd_cmdsts |= + htole32(CMDSTS_INTR); + sc->sc_txwin = 0; + } + #ifdef DP83820 /* * If VLANs are enabled and the packet has a VLAN tag, set @@ -1266,14 +1372,6 @@ SIP_DECL(start)(struct ifnet *ifp) } if (sc->sc_txfree != ofree) { - /* - * Cause a descriptor interrupt to happen on the - * last packet we enqueued. - */ - sc->sc_txdescs[lasttx].sipd_cmdsts |= htole32(CMDSTS_INTR); - SIP_CDTXSYNC(sc, lasttx, 1, - BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); - /* * The entire packet chain is set up. Give the * first descrptor to the chip now. @@ -1431,8 +1529,13 @@ SIP_DECL(intr)(void *arg) } } - if (isr & (ISR_TXURN|ISR_TXDESC)) { - SIP_EVCNT_INCR(&sc->sc_ev_txintr); + if (isr & (ISR_TXURN|ISR_TXDESC|ISR_TXIDLE)) { +#ifdef SIP_EVENT_COUNTERS + if (isr & ISR_TXDESC) + SIP_EVCNT_INCR(&sc->sc_ev_txdintr); + else if (isr & ISR_TXIDLE) + SIP_EVCNT_INCR(&sc->sc_ev_txiintr); +#endif /* Sweep up transmit descriptors. */ SIP_DECL(txintr)(sc); @@ -1473,15 +1576,31 @@ SIP_DECL(intr)(void *arg) #endif /* ! DP83820 */ if (isr & ISR_HIBERR) { + int want_init = 0; + + SIP_EVCNT_INCR(&sc->sc_ev_hiberr); + #define PRINTERR(bit, str) \ - if (isr & (bit)) \ - printf("%s: %s\n", sc->sc_dev.dv_xname, str) + do { \ + if (isr & (bit)) { \ + printf("%s: %s\n", \ + sc->sc_dev.dv_xname, str); \ + want_init = 1; \ + } \ + } while (/*CONSTCOND*/0) + PRINTERR(ISR_DPERR, "parity error"); PRINTERR(ISR_SSERR, "system error"); PRINTERR(ISR_RMABT, "master abort"); PRINTERR(ISR_RTABT, "target abort"); PRINTERR(ISR_RXSOVR, "receive status FIFO overrun"); - (void) SIP_DECL(init)(ifp); + /* + * Ignore: + * Tx reset complete + * Rx reset complete + */ + if (want_init) + (void) SIP_DECL(init)(ifp); #undef PRINTERR } } @@ -1558,8 +1677,10 @@ SIP_DECL(txintr)(struct sip_softc *sc) * If there are no more pending transmissions, cancel the watchdog * timer. */ - if (txs == NULL) + if (txs == NULL) { ifp->if_timer = 0; + sc->sc_txwin = 0; + } } #if defined(DP83820) @@ -2084,6 +2205,7 @@ SIP_DECL(init)(struct ifnet *ifp) BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); sc->sc_txfree = SIP_NTXDESC; sc->sc_txnext = 0; + sc->sc_txwin = 0; /* * Initialize the transmit job descriptors. @@ -2219,7 +2341,7 @@ SIP_DECL(init)(struct ifnet *ifp) * Initialize the interrupt mask. */ sc->sc_imr = ISR_DPERR|ISR_SSERR|ISR_RMABT|ISR_RTABT|ISR_RXSOVR| - ISR_TXURN|ISR_TXDESC|ISR_RXORN|ISR_RXIDLE|ISR_RXDESC; + ISR_TXURN|ISR_TXDESC|ISR_TXIDLE|ISR_RXORN|ISR_RXIDLE|ISR_RXDESC; bus_space_write_4(st, sh, SIP_IMR, sc->sc_imr); /* Set up the receive filter. */ @@ -3057,12 +3179,6 @@ SIP_DECL(dp83820_read_macaddr)(struct sip_softc *sc, /* Get the GPIOR bits. */ sc->sc_gpior = eeprom_data[0x04]; - - /* Get various CFG related bits. */ - if ((eeprom_data[0x05] >> 0) & 1) - sc->sc_cfg |= CFG_EXT_125; - if ((eeprom_data[0x05] >> 9) & 1) - sc->sc_cfg |= CFG_TBI_EN; } #else /* ! DP83820 */ void diff --git a/netbsd/sys/dev/pci/if_vr.c b/netbsd/sys/dev/pci/if_vr.c index 0b903d2933..942e534627 100644 --- a/netbsd/sys/dev/pci/if_vr.c +++ b/netbsd/sys/dev/pci/if_vr.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_vr.c,v 1.53 2001/11/13 07:48:45 lukem Exp $ */ +/* $NetBSD: if_vr.c,v 1.53.10.1 2003/01/27 05:02:43 jmc Exp $ */ /*- * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. @@ -104,7 +104,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_vr.c,v 1.53 2001/11/13 07:48:45 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_vr.c,v 1.53.10.1 2003/01/27 05:02:43 jmc Exp $"); #include #include @@ -939,8 +939,11 @@ vr_start(ifp) * Load the DMA map. If this fails, the packet didn't * fit in one DMA segment, and we need to copy. Note, * the packet must also be aligned. + * if the packet is too small, copy it too, so we're sure + * so have enouth room for the pad buffer. */ if ((mtod(m0, uintptr_t) & 3) != 0 || + m0->m_pkthdr.len < VR_MIN_FRAMELEN || bus_dmamap_load_mbuf(sc->vr_dmat, ds->ds_dmamap, m0, BUS_DMA_WRITE|BUS_DMA_NOWAIT) != 0) { MGETHDR(m, M_DONTWAIT, MT_DATA); @@ -960,6 +963,15 @@ vr_start(ifp) } m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t)); m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len; + /* + * The Rhine doesn't auto-pad, so we have to do this + * ourselves. + */ + if (m0->m_pkthdr.len < VR_MIN_FRAMELEN) { + memset(mtod(m, caddr_t) + m0->m_pkthdr.len, + 0, VR_MIN_FRAMELEN - m0->m_pkthdr.len); + m->m_pkthdr.len = m->m_len = VR_MIN_FRAMELEN; + } error = bus_dmamap_load_mbuf(sc->vr_dmat, ds->ds_dmamap, m, BUS_DMA_WRITE|BUS_DMA_NOWAIT); if (error) { @@ -994,12 +1006,10 @@ vr_start(ifp) #endif /* - * Fill in the transmit descriptor. The Rhine - * doesn't auto-pad, so we have to do this ourselves. + * Fill in the transmit descriptor. */ d->vr_data = htole32(ds->ds_dmamap->dm_segs[0].ds_addr); - d->vr_ctl = htole32(m0->m_pkthdr.len < VR_MIN_FRAMELEN ? - VR_MIN_FRAMELEN : m0->m_pkthdr.len); + d->vr_ctl = htole32(m0->m_pkthdr.len); d->vr_ctl |= htole32(VR_TXCTL_TLINK|VR_TXCTL_FIRSTFRAG| VR_TXCTL_LASTFRAG); diff --git a/netbsd/sys/dev/pci/if_wm.c b/netbsd/sys/dev/pci/if_wm.c index 0754b478f8..0d7b477208 100644 --- a/netbsd/sys/dev/pci/if_wm.c +++ b/netbsd/sys/dev/pci/if_wm.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_wm.c,v 1.9.4.6 2002/08/17 15:47:44 lukem Exp $ */ +/* $NetBSD: if_wm.c,v 1.9.4.8 2002/11/08 08:50:24 tron Exp $ */ /* * Copyright (c) 2001, 2002 Wasabi Systems, Inc. @@ -36,8 +36,7 @@ */ /* - * Device driver for the Intel i82542 (``Wiseman''), i82543 (``Livengood''), - * and i82544 (``Cordova'') Gigabit Ethernet chips. + * Device driver for the Intel i8254x family of Gigabit Ethernet chips. * * TODO (in order of importance): * @@ -287,13 +286,17 @@ do { \ } while (/*CONSTCOND*/0) /* sc_type */ -#define WM_T_WISEMAN_2_0 0 /* Wiseman (i82542) 2.0 (really old) */ -#define WM_T_WISEMAN_2_1 1 /* Wiseman (i82542) 2.1+ (old) */ -#define WM_T_LIVENGOOD 2 /* Livengood (i82543) */ -#define WM_T_CORDOVA 3 /* Cordova (i82544) */ +#define WM_T_82542_2_0 0 /* i82542 2.0 (really old) */ +#define WM_T_82542_2_1 1 /* i82542 2.1+ (old) */ +#define WM_T_82543 2 /* i82543 */ +#define WM_T_82544 3 /* i82544 */ +#define WM_T_82540 4 /* i82540 */ +#define WM_T_82545 5 /* i82545 */ +#define WM_T_82546 6 /* i82546 */ /* sc_flags */ #define WM_F_HAS_MII 0x01 /* has MII */ +#define WM_F_EEPROM_HANDSHAKE 0x02 /* requires EEPROM handshake */ #ifdef WM_EVENT_COUNTERS #define WM_EVCNT_INCR(ev) (ev)->ev_count++ @@ -404,11 +407,11 @@ void wm_tbi_check_link(struct wm_softc *); void wm_gmii_reset(struct wm_softc *); -int wm_gmii_livengood_readreg(struct device *, int, int); -void wm_gmii_livengood_writereg(struct device *, int, int, int); +int wm_gmii_i82543_readreg(struct device *, int, int); +void wm_gmii_i82543_writereg(struct device *, int, int, int); -int wm_gmii_cordova_readreg(struct device *, int, int); -void wm_gmii_cordova_writereg(struct device *, int, int, int); +int wm_gmii_i82544_readreg(struct device *, int, int); +void wm_gmii_i82544_writereg(struct device *, int, int, int); void wm_gmii_statchg(struct device *); @@ -439,35 +442,55 @@ const struct wm_product { } wm_products[] = { { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82542, "Intel i82542 1000BASE-X Ethernet", - WM_T_WISEMAN_2_1, WMP_F_1000X }, + WM_T_82542_2_1, WMP_F_1000X }, - { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82543_FIBER, - "Intel i82543 1000BASE-X Ethernet", - WM_T_LIVENGOOD, WMP_F_1000X }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82543GC_FIBER, + "Intel i82543GC 1000BASE-X Ethernet", + WM_T_82543, WMP_F_1000X }, - { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82543_SC, - "Intel i82543-SC 1000BASE-X Ethernet", - WM_T_LIVENGOOD, WMP_F_1000X }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82543GC_COPPER, + "Intel i82543GC 1000BASE-T Ethernet", + WM_T_82543, WMP_F_1000T }, - { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82543_COPPER, - "Intel i82543 1000BASE-T Ethernet", - WM_T_LIVENGOOD, WMP_F_1000T }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82544EI_COPPER, + "Intel i82544EI 1000BASE-T Ethernet", + WM_T_82544, WMP_F_1000T }, - { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82544_XT, - "Intel i82544 1000BASE-T Ethernet", - WM_T_CORDOVA, WMP_F_1000T }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82544EI_FIBER, + "Intel i82544EI 1000BASE-X Ethernet", + WM_T_82544, WMP_F_1000X }, - { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82544_XF, - "Intel i82544 1000BASE-X Ethernet", - WM_T_CORDOVA, WMP_F_1000X }, - - { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82544GC, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82544GC_COPPER, "Intel i82544GC 1000BASE-T Ethernet", - WM_T_CORDOVA, WMP_F_1000T }, + WM_T_82544, WMP_F_1000T }, - { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82544GC_64, - "Intel i82544GC 1000BASE-T Ethernet", - WM_T_CORDOVA, WMP_F_1000T }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82544GC_LOM, + "Intel i82544GC (LOM) 1000BASE-T Ethernet", + WM_T_82544, WMP_F_1000T }, + + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82540EM, + "Intel i82540EM 1000BASE-T Ethernet", + WM_T_82540, WMP_F_1000T }, + + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82545EM_COPPER, + "Intel i82545EM 1000BASE-T Ethernet", + WM_T_82545, WMP_F_1000T }, + + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82546EB_COPPER, + "Intel i82546EB 1000BASE-T Ethernet", + WM_T_82546, WMP_F_1000T }, + + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82545EM_FIBER, + "Intel i82545EM 1000BASE-X Ethernet", + WM_T_82545, WMP_F_1000X }, + + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82546EB_FIBER, + "Intel i82546EB 1000BASE-X Ethernet", + WM_T_82546, WMP_F_1000X }, + + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82540EM_LOM, + "Intel i82540EM (LOM) 1000BASE-T Ethernet", + WM_T_82540, WMP_F_1000T }, { 0, 0, NULL, @@ -556,16 +579,22 @@ wm_attach(struct device *parent, struct device *self, void *aux) printf(": %s, rev. %d\n", wmp->wmp_name, preg); sc->sc_type = wmp->wmp_type; - if (sc->sc_type < WM_T_LIVENGOOD) { + if (sc->sc_type < WM_T_82543) { if (preg < 2) { - printf("%s: Wiseman must be at least rev. 2\n", + printf("%s: i82542 must be at least rev. 2\n", sc->sc_dev.dv_xname); return; } if (preg < 3) - sc->sc_type = WM_T_WISEMAN_2_0; + sc->sc_type = WM_T_82542_2_0; } + /* + * Some chips require a handshake to access the EEPROM. + */ + if (sc->sc_type >= WM_T_82540) + sc->sc_flags |= WM_F_EEPROM_HANDSHAKE; + /* * Map the device. */ @@ -589,10 +618,10 @@ wm_attach(struct device *parent, struct device *self, void *aux) return; } - /* Enable bus mastering. Disable MWI on the Wiseman 2.0. */ + /* Enable bus mastering. Disable MWI on the i82542 2.0. */ preg = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); preg |= PCI_COMMAND_MASTER_ENABLE; - if (sc->sc_type < WM_T_WISEMAN_2_1) + if (sc->sc_type < WM_T_82542_2_1) preg &= ~PCI_COMMAND_INVALIDATE_ENABLE; pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, preg); @@ -713,6 +742,15 @@ wm_attach(struct device *parent, struct device *self, void *aux) enaddr[4] = myea[2] & 0xff; enaddr[5] = myea[2] >> 8; + /* + * Toggle the LSB of the MAC address on the second port + * of the i82546. + */ + if (sc->sc_type == WM_T_82546) { + if ((CSR_READ(sc, WMREG_STATUS) >> STATUS_FUNCID_SHIFT) & 1) + enaddr[5] ^= 1; + } + printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname, ether_sprintf(enaddr)); @@ -722,12 +760,12 @@ wm_attach(struct device *parent, struct device *self, void *aux) */ wm_read_eeprom(sc, EEPROM_OFF_CFG1, 1, &cfg1); wm_read_eeprom(sc, EEPROM_OFF_CFG2, 1, &cfg2); - if (sc->sc_type >= WM_T_CORDOVA) + if (sc->sc_type >= WM_T_82544) wm_read_eeprom(sc, EEPROM_OFF_SWDPIN, 1, &swdpin); if (cfg1 & EEPROM_CFG1_ILOS) sc->sc_ctrl |= CTRL_ILOS; - if (sc->sc_type >= WM_T_CORDOVA) { + if (sc->sc_type >= WM_T_82544) { sc->sc_ctrl |= ((swdpin >> EEPROM_SWDPIN_SWDPIO_SHIFT) & 0xf) << CTRL_SWDPIO_SHIFT; @@ -741,7 +779,7 @@ wm_attach(struct device *parent, struct device *self, void *aux) } #if 0 - if (sc->sc_type >= WM_T_CORDOVA) { + if (sc->sc_type >= WM_T_82544) { if (cfg1 & EEPROM_CFG1_IPS0) sc->sc_ctrl_ext |= CTRL_EXT_IPS; if (cfg1 & EEPROM_CFG1_IPS1) @@ -766,9 +804,9 @@ wm_attach(struct device *parent, struct device *self, void *aux) /* * Set up some register offsets that are different between - * the Wiseman and the Livengood and later chips. + * the i82542 and the i82543 and later chips. */ - if (sc->sc_type < WM_T_LIVENGOOD) { + if (sc->sc_type < WM_T_82543) { sc->sc_rdt_reg = WMREG_OLD_RDT0; sc->sc_tdt_reg = WMREG_OLD_TDT; } else { @@ -778,16 +816,16 @@ wm_attach(struct device *parent, struct device *self, void *aux) /* * Determine if we should use flow control. We should - * always use it, unless we're on a Wiseman < 2.1. + * always use it, unless we're on a i82542 < 2.1. */ - if (sc->sc_type >= WM_T_WISEMAN_2_1) + if (sc->sc_type >= WM_T_82542_2_1) sc->sc_ctrl |= CTRL_TFCE | CTRL_RFCE; /* * Determine if we're TBI or GMII mode, and initialize the * media structures accordingly. */ - if (sc->sc_type < WM_T_LIVENGOOD || + if (sc->sc_type < WM_T_82543 || (CSR_READ(sc, WMREG_STATUS) & STATUS_TBIMODE) != 0) { if (wmp->wmp_flags & WMP_F_1000T) printf("%s: WARNING: TBIMODE set on 1000BASE-T " @@ -813,17 +851,17 @@ wm_attach(struct device *parent, struct device *self, void *aux) IFQ_SET_READY(&ifp->if_snd); /* - * If we're a Livengood or greater, we can support VLANs. + * If we're a i82543 or greater, we can support VLANs. */ - if (sc->sc_type >= WM_T_LIVENGOOD) + if (sc->sc_type >= WM_T_82543) sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU /* XXXJRT | ETHERCAP_VLAN_HWTAGGING */; /* * We can perform TCPv4 and UDPv4 checkums in-bound. Only - * on Livengood and later. + * on i82543 and later. */ - if (sc->sc_type >= WM_T_LIVENGOOD) + if (sc->sc_type >= WM_T_82543) ifp->if_capabilities |= IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4; @@ -1480,7 +1518,7 @@ wm_txintr(struct wm_softc *sc) /* * XXX We should probably be using the statistics * XXX registers, but I don't know if they exist - * XXX on chips before the Cordova. + * XXX on chips before the i82544. */ #ifdef WM_EVENT_COUNTERS @@ -1871,7 +1909,7 @@ wm_init(struct ifnet *ifp) sc->sc_txctx_ipcs = 0xffffffff; sc->sc_txctx_tucs = 0xffffffff; - if (sc->sc_type < WM_T_LIVENGOOD) { + if (sc->sc_type < WM_T_82543) { CSR_WRITE(sc, WMREG_OLD_TBDAH, 0); CSR_WRITE(sc, WMREG_OLD_TBDAL, WM_CDTXADDR(sc, 0)); CSR_WRITE(sc, WMREG_OLD_TDLEN, sizeof(sc->sc_txdescs)); @@ -1905,7 +1943,7 @@ wm_init(struct ifnet *ifp) * Initialize the receive descriptor and receive job * descriptor rings. */ - if (sc->sc_type < WM_T_LIVENGOOD) { + if (sc->sc_type < WM_T_82543) { CSR_WRITE(sc, WMREG_OLD_RDBAH0, 0); CSR_WRITE(sc, WMREG_OLD_RDBAL0, WM_CDRXADDR(sc, 0)); CSR_WRITE(sc, WMREG_OLD_RDLEN0, sizeof(sc->sc_rxdescs)); @@ -1965,7 +2003,7 @@ wm_init(struct ifnet *ifp) CSR_WRITE(sc, WMREG_FCAH, FCAH_CONST); CSR_WRITE(sc, WMREG_FCT, ETHERTYPE_FLOWCONTROL); - if (sc->sc_type < WM_T_LIVENGOOD) { + if (sc->sc_type < WM_T_82543) { CSR_WRITE(sc, WMREG_OLD_FCRTH, FCRTH_DFLT); CSR_WRITE(sc, WMREG_OLD_FCRTL, FCRTL_DFLT); } else { @@ -2041,7 +2079,7 @@ wm_init(struct ifnet *ifp) * the register when we set the receive filter. Use multicast * address offset type 0. * - * Only the Cordova has the ability to strip the incoming + * Only the i82544 has the ability to strip the incoming * CRC, so we don't enable that feature. */ sc->sc_mchash_type = 0; @@ -2136,18 +2174,53 @@ void wm_read_eeprom(struct wm_softc *sc, int word, int wordcnt, uint16_t *data) { uint32_t reg; - int i, x; + int i, x, addrbits = 6; for (i = 0; i < wordcnt; i++) { - /* Send CHIP SELECT for one clock tick. */ - CSR_WRITE(sc, WMREG_EECD, EECD_CS); + if (sc->sc_flags & WM_F_EEPROM_HANDSHAKE) { + reg = CSR_READ(sc, WMREG_EECD); + + /* Get number of address bits. */ + if (reg & EECD_EE_SIZE) + addrbits = 8; + + /* Request EEPROM access. */ + reg |= EECD_EE_REQ; + CSR_WRITE(sc, WMREG_EECD, reg); + + /* ..and wait for it to be granted. */ + for (x = 0; x < 100; x++) { + reg = CSR_READ(sc, WMREG_EECD); + if (reg & EECD_EE_GNT) + break; + delay(5); + } + if ((reg & EECD_EE_GNT) == 0) { + printf("%s: could not acquire EEPROM GNT\n", + sc->sc_dev.dv_xname); + *data = 0xffff; + reg &= ~EECD_EE_REQ; + CSR_WRITE(sc, WMREG_EECD, reg); + continue; + } + } else + reg = 0; + + /* Clear SK and DI. */ + reg &= ~(EECD_SK | EECD_DI); + CSR_WRITE(sc, WMREG_EECD, reg); + + /* Set CHIP SELECT. */ + reg |= EECD_CS; + CSR_WRITE(sc, WMREG_EECD, reg); delay(2); /* Shift in the READ command. */ for (x = 3; x > 0; x--) { - reg = EECD_CS; if (UWIRE_OPC_READ & (1 << (x - 1))) reg |= EECD_DI; + else + reg &= ~EECD_DI; CSR_WRITE(sc, WMREG_EECD, reg); delay(2); CSR_WRITE(sc, WMREG_EECD, reg | EECD_SK); @@ -2157,10 +2230,11 @@ wm_read_eeprom(struct wm_softc *sc, int word, int wordcnt, uint16_t *data) } /* Shift in address. */ - for (x = 6; x > 0; x--) { - reg = EECD_CS; + for (x = addrbits; x > 0; x--) { if ((word + i) & (1 << (x - 1))) reg |= EECD_DI; + else + reg &= ~EECD_DI; CSR_WRITE(sc, WMREG_EECD, reg); delay(2); CSR_WRITE(sc, WMREG_EECD, reg | EECD_SK); @@ -2170,7 +2244,7 @@ wm_read_eeprom(struct wm_softc *sc, int word, int wordcnt, uint16_t *data) } /* Shift out the data. */ - reg = EECD_CS; + reg &= ~EECD_DI; data[i] = 0; for (x = 16; x > 0; x--) { CSR_WRITE(sc, WMREG_EECD, reg | EECD_SK); @@ -2182,7 +2256,15 @@ wm_read_eeprom(struct wm_softc *sc, int word, int wordcnt, uint16_t *data) } /* Clear CHIP SELECT. */ - CSR_WRITE(sc, WMREG_EECD, 0); + reg &= ~EECD_CS; + CSR_WRITE(sc, WMREG_EECD, reg); + delay(2); + + if (sc->sc_flags & WM_F_EEPROM_HANDSHAKE) { + /* Release the EEPROM. */ + reg &= ~EECD_EE_REQ; + CSR_WRITE(sc, WMREG_EECD, reg); + } } } @@ -2250,7 +2332,7 @@ wm_set_ral(struct wm_softc *sc, const uint8_t *enaddr, int idx) ral_hi = 0; } - if (sc->sc_type >= WM_T_CORDOVA) { + if (sc->sc_type >= WM_T_82544) { CSR_WRITE(sc, WMREG_RAL_LO(WMREG_CORDOVA_RAL_BASE, idx), ral_lo); CSR_WRITE(sc, WMREG_RAL_HI(WMREG_CORDOVA_RAL_BASE, idx), @@ -2296,7 +2378,7 @@ wm_set_filter(struct wm_softc *sc) uint32_t hash, reg, bit; int i; - if (sc->sc_type >= WM_T_CORDOVA) + if (sc->sc_type >= WM_T_82544) mta_reg = WMREG_CORDOVA_MTA; else mta_reg = WMREG_MTA; @@ -2345,7 +2427,7 @@ wm_set_filter(struct wm_softc *sc) hash |= 1U << bit; /* XXX Hardware bug?? */ - if (sc->sc_type == WM_T_CORDOVA && (reg & 0xe) == 1) { + if (sc->sc_type == WM_T_82544 && (reg & 0xe) == 1) { bit = CSR_READ(sc, mta_reg + ((reg - 1) << 2)); CSR_WRITE(sc, mta_reg + (reg << 2), hash); CSR_WRITE(sc, mta_reg + ((reg - 1) << 2), bit); @@ -2376,7 +2458,7 @@ wm_tbi_mediainit(struct wm_softc *sc) { const char *sep = ""; - if (sc->sc_type < WM_T_LIVENGOOD) + if (sc->sc_type < WM_T_82543) sc->sc_tipg = TIPG_WM_DFLT; else sc->sc_tipg = TIPG_LG_DFLT; @@ -2579,7 +2661,7 @@ wm_gmii_reset(struct wm_softc *sc) { uint32_t reg; - if (sc->sc_type >= WM_T_CORDOVA) { + if (sc->sc_type >= WM_T_82544) { CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl | CTRL_PHY_RESET); delay(20000); @@ -2631,12 +2713,12 @@ wm_gmii_mediainit(struct wm_softc *sc) /* Initialize our media structures and probe the GMII. */ sc->sc_mii.mii_ifp = ifp; - if (sc->sc_type >= WM_T_CORDOVA) { - sc->sc_mii.mii_readreg = wm_gmii_cordova_readreg; - sc->sc_mii.mii_writereg = wm_gmii_cordova_writereg; + if (sc->sc_type >= WM_T_82544) { + sc->sc_mii.mii_readreg = wm_gmii_i82544_readreg; + sc->sc_mii.mii_writereg = wm_gmii_i82544_writereg; } else { - sc->sc_mii.mii_readreg = wm_gmii_livengood_readreg; - sc->sc_mii.mii_writereg = wm_gmii_livengood_writereg; + sc->sc_mii.mii_readreg = wm_gmii_i82543_readreg; + sc->sc_mii.mii_writereg = wm_gmii_i82543_writereg; } sc->sc_mii.mii_statchg = wm_gmii_statchg; @@ -2689,7 +2771,7 @@ wm_gmii_mediachange(struct ifnet *ifp) #define MDI_CLK CTRL_SWDPIN(3) static void -livengood_mii_sendbits(struct wm_softc *sc, uint32_t data, int nbits) +i82543_mii_sendbits(struct wm_softc *sc, uint32_t data, int nbits) { uint32_t i, v; @@ -2712,7 +2794,7 @@ livengood_mii_sendbits(struct wm_softc *sc, uint32_t data, int nbits) } static uint32_t -livengood_mii_recvbits(struct wm_softc *sc) +i82543_mii_recvbits(struct wm_softc *sc) { uint32_t v, i, data = 0; @@ -2750,20 +2832,20 @@ livengood_mii_recvbits(struct wm_softc *sc) #undef MDI_CLK /* - * wm_gmii_livengood_readreg: [mii interface function] + * wm_gmii_i82543_readreg: [mii interface function] * - * Read a PHY register on the GMII (Livengood version). + * Read a PHY register on the GMII (i82543 version). */ int -wm_gmii_livengood_readreg(struct device *self, int phy, int reg) +wm_gmii_i82543_readreg(struct device *self, int phy, int reg) { struct wm_softc *sc = (void *) self; int rv; - livengood_mii_sendbits(sc, 0xffffffffU, 32); - livengood_mii_sendbits(sc, reg | (phy << 5) | + i82543_mii_sendbits(sc, 0xffffffffU, 32); + i82543_mii_sendbits(sc, reg | (phy << 5) | (MII_COMMAND_READ << 10) | (MII_COMMAND_START << 12), 14); - rv = livengood_mii_recvbits(sc) & 0xffff; + rv = i82543_mii_recvbits(sc) & 0xffff; DPRINTF(WM_DEBUG_GMII, ("%s: GMII: read phy %d reg %d -> 0x%04x\n", @@ -2773,28 +2855,28 @@ wm_gmii_livengood_readreg(struct device *self, int phy, int reg) } /* - * wm_gmii_livengood_writereg: [mii interface function] + * wm_gmii_i82543_writereg: [mii interface function] * - * Write a PHY register on the GMII (Livengood version). + * Write a PHY register on the GMII (i82543 version). */ void -wm_gmii_livengood_writereg(struct device *self, int phy, int reg, int val) +wm_gmii_i82543_writereg(struct device *self, int phy, int reg, int val) { struct wm_softc *sc = (void *) self; - livengood_mii_sendbits(sc, 0xffffffffU, 32); - livengood_mii_sendbits(sc, val | (MII_COMMAND_ACK << 16) | + i82543_mii_sendbits(sc, 0xffffffffU, 32); + i82543_mii_sendbits(sc, val | (MII_COMMAND_ACK << 16) | (reg << 18) | (phy << 23) | (MII_COMMAND_WRITE << 28) | (MII_COMMAND_START << 30), 32); } /* - * wm_gmii_cordova_readreg: [mii interface function] + * wm_gmii_i82544_readreg: [mii interface function] * * Read a PHY register on the GMII. */ int -wm_gmii_cordova_readreg(struct device *self, int phy, int reg) +wm_gmii_i82544_readreg(struct device *self, int phy, int reg) { struct wm_softc *sc = (void *) self; uint32_t mdic; @@ -2830,12 +2912,12 @@ wm_gmii_cordova_readreg(struct device *self, int phy, int reg) } /* - * wm_gmii_cordova_writereg: [mii interface function] + * wm_gmii_i82544_writereg: [mii interface function] * * Write a PHY register on the GMII. */ void -wm_gmii_cordova_writereg(struct device *self, int phy, int reg, int val) +wm_gmii_i82544_writereg(struct device *self, int phy, int reg, int val) { struct wm_softc *sc = (void *) self; uint32_t mdic; diff --git a/netbsd/sys/dev/pci/pcidevs b/netbsd/sys/dev/pci/pcidevs index 135f93a61c..0a1acf99ea 100644 --- a/netbsd/sys/dev/pci/pcidevs +++ b/netbsd/sys/dev/pci/pcidevs @@ -1,4 +1,4 @@ -$NetBSD: pcidevs,v 1.428.2.10 2002/08/02 05:40:32 lukem Exp $ +$NetBSD: pcidevs,v 1.428.2.20 2003/01/28 06:22:37 jmc Exp $ /* * Copyright (c) 1995, 1996 Christopher G. Demetriou @@ -555,6 +555,7 @@ vendor SYMPHONY2 0x1c1c Symphony Labs (2nd PCI Vendor ID) vendor TEKRAM2 0x1de1 Tekram Technology (2nd PCI Vendor ID) vendor COREGA 0x15e8 Corega vendor GLOBALSUN 0x16ab Global Sun Tech +vendor ALTIMA 0x173b Altima vendor FZJZEL 0x1796 FZ Juelich / ZEL vendor SANDBURST 0x17ba Sandburst, Inc. vendor HINT 0x3388 HiNT @@ -761,6 +762,11 @@ product ALTEON ACENIC_COPPER 0x0002 ACEnic 1000baseT Gigabit Ethernet product ALTEON BCM5700 0x0003 ACEnic BCM5700 10/100/1000 Ethernet product ALTEON BCM5701 0x0004 ACEnic BCM5701 10/100/1000 Ethernet +/* Altima products */ +product ALTIMA AC1000 0x03e8 AC1000 Gigabit Ethernet +product ALTIMA AC1001 0x03e9 AC1001 Gigabit Ethernet +product ALTIMA AC9100 0x03ea AC9100 Gigabit Ethernet + /* AMD products */ product AMD PCNET_PCI 0x2000 PCnet-PCI Ethernet product AMD PCNET_HOME 0x2001 PCnet-Home HomePNA Ethernet @@ -945,6 +951,15 @@ product BIT3 PCIVME2706 0x0300 PCI-VME Interface Mod. 2706 /* Broadcom Corporation products */ product BROADCOM BCM5700 0x1644 BCM5700 10/100/1000 Ethernet product BROADCOM BCM5701 0x1645 BCM5701 10/100/1000 Ethernet +product BROADCOM BCM5702 0x1646 BCM5702 10/100/1000 Ethernet +product BROADCOM BCM5702X 0x16a6 BCM5702X 10/100/1000 Ethernet +product BROADCOM BCM5702FE 0x164d BCM5702FE 10/100 Ethernet +product BROADCOM BCM5703 0x1647 BCM5703 10/100/1000 Ethernet +product BROADCOM BCM5703X 0x16a7 BCM5703X 10/100/1000 Ethernet +product BROADCOM BCM5704C 0x1648 BCM5704C Gigabit Ethernet (1000BASE-T) +product BROADCOM BCM5704S 0x16a8 BCM5704S Gigabit Ethernet (1000BASE-X) +product BROADCOM BCM5705 0x1653 BCM5705 10/100/1000 Ethernet +product BROADCOM BCM4401 0x4401 BCM4401 10/100 Ethernet /* Brooktree products */ product BROOKTREE BT848 0x0350 Bt848 Video Capture @@ -1127,11 +1142,15 @@ product DELL PERC_3DI 0x0002 PERC 3/Di product DELL PERC_3SI 0x0003 PERC 3/Si product DELL PERC_3SI_2 0x0004 PERC 3/Si product DELL PERC_3DI_2 0x0008 PERC 3/Di +product DELL PERC_3DI_3 0x000a PERC 3/Di product DELL PERC_3SI 0x0003 PERC 3/Si product DELL PERC_3DI_2_SUB 0x00cf PERC 3/Di product DELL PERC_3SI_2_SUB 0x00d0 PERC 3/Si product DELL PERC_3DI_SUB2 0x00d1 PERC 3/Di product DELL PERC_3DI_SUB3 0x00d9 PERC 3/Di +product DELL PERC_3DI_3_SUB 0x0106 PERC 3/Di +product DELL PERC_3DI_3_SUB2 0x011b PERC 3/Di +product DELL PERC_3DI_3_SUB3 0x0121 PERC 3/Di /* Delta products */ product DELTA 8139 0x1360 8139 Ethernet @@ -1148,6 +1167,7 @@ product DLINK DL4000 0x4000 DL-4000 Gigabit Ethernet product DPT SC_RAID 0xa400 SmartCache/SmartRAID (EATA) product DPT I960_PPB 0xa500 PCI-PCI Bridge product DPT RAID_I2O 0xa501 SmartRAID (I2O) +product DPT RAID_2005S 0xa511 Zero Channel SmartRAID (I2O) product DPT MEMCTLR 0x1012 Memory Controller /* Dolphin products */ @@ -1272,6 +1292,7 @@ product IBM MPIC 0x0046 MPIC product IBM TURBOWAYS25 0x0053 Turboways 25 ATM product IBM GXT800P 0x005e GXT-800P product IBM 405GP 0x0156 PPC 405GP PCI Bridge +product IBM 133PCIX 0x01a7 133 PCI-X Bridge product IBM MPIC2 0xffff MPIC-II /* IDT products */ @@ -1300,6 +1321,7 @@ product IMS TT128M 0x9128 TwinTurbo 128M /* Intel products */ product INTEL 80312 0x030d 80312 I/O Companion Chip +product INTEL 80321 0x0319 80321 I/O Processor product INTEL PCEB 0x0482 82375EB/SB PCI-EISA Bridge (PCEB) product INTEL CDC 0x0483 82424ZX Cache and DRAM controller (CDC) product INTEL SIO 0x0484 82378ZB System I/O (SIO) @@ -1309,14 +1331,19 @@ product INTEL GDT_RAID1 0x0600 GDT RAID product INTEL GDT_RAID2 0x061f GDT RAID product INTEL 80960RM 0x0962 i960 RM PCI-PCI product INTEL 80960RN 0x0964 i960 RN PCI-PCI -product INTEL 82542 0x1000 i82452 Gigabit Ethernet -product INTEL 82543_FIBER 0x1001 i82453 Gigabit Ethernet (1000BASE-X) -product INTEL 82543_SC 0x1003 i82453-SC Gigabit Ethernet -product INTEL 82543_COPPER 0x1004 i82543 Gigabit Ethernet (1000BASE-T) -product INTEL 82544_XT 0x1008 i82544 Gigabit Ethernet (1000BASE-T) -product INTEL 82544_XF 0x1009 i82544 Gigabit Ethernet (1000BASE-X) -product INTEL 82544GC 0x100c i82544GC Gigabit Ethernet (1000BASE-T) -product INTEL 82544GC_64 0x100d i82544GC (64-bit) Gigabit Ethernet (1000BASE-T) +product INTEL 82542 0x1000 i82542 Gigabit Ethernet +product INTEL 82543GC_FIBER 0x1001 i82453GC Gigabit Ethernet (1000BASE-X) +product INTEL 82543GC_COPPER 0x1004 i82543GC Gigabit Ethernet (1000BASE-T) +product INTEL 82544EI_COPPER 0x1008 i82544EI Gigabit Ethernet (1000BASE-T) +product INTEL 82544EI_FIBER 0x1009 i82544EI Gigabit Ethernet (1000BASE-X) +product INTEL 82544GC_COPPER 0x100c i82544GC Gigabit Ethernet (1000BASE-T) +product INTEL 82544GC_LOM 0x100d i82544GC (LOM) Gigabit Ethernet +product INTEL 82540EM 0x100e i82540EM Gigabit Ethernet (1000BASE-T) +product INTEL 82545EM_COPPER 0x100f i82545EM Gigabit Ethernet (1000BASE-T) +product INTEL 82546EB_COPPER 0x1010 i82546EB Gigabit Ethernet (1000BASE-T) +product INTEL 82545EM_FIBER 0x1011 i82545EM Gigabit Ethernet (1000BASE-X) +product INTEL 82546EB_FIBER 0x1012 i82546EB Gigabit Ethernet (1000BASE-X) +product INTEL 82540EM_LOM 0x1015 i82540EM (LOM) Gigabit Ethernet product INTEL IN_BUSINESS 0x1030 InBusiness Fast Ethernet LAN Controller product INTEL PRO_100_VE_0 0x1031 PRO/100 VE Network Controller product INTEL PRO_100_VE_1 0x1032 PRO/100 VE Network Controller @@ -1396,6 +1423,9 @@ product INTEL 82801BAM_IDE 0x244a 82801BAM IDE Controller product INTEL 82801BA_IDE 0x244b 82801BA IDE Controller product INTEL 82801BAM_LPC 0x244c 82801BAM LPC Interface Bridge product INTEL 82801BA_HPB 0x244e 82801BA Hub-to-PCI Bridge +product INTEL 82801E_SMB 0x2453 82801E SMBus Controller +product INTEL 82801E_LAN_1 0x2459 82801E LAN Controller +product INTEL 82801E_LAN_2 0x245d 82801E LAN Controller product INTEL 82801CA_LPC 0x2480 82801CA LPC Interface product INTEL 82801CA_USB_1 0x2482 82801CA/CAM USB Controller product INTEL 82801CA_SMB 0x2483 82801CA/CAM SMBus Controller @@ -1748,6 +1778,8 @@ product PROMISE ULTRA100X 0x0d30 Ultra100X/ATA Bus Master IDE Accelerator product PROMISE ULTRA100TX2 0x4d68 Ultra100TX2/ATA Bus Master IDE Accelerator product PROMISE ULTRA100TX2v2 0x6268 Ultra100TX2v2/ATA Bus Master IDE Accelerator product PROMISE ULTRA133 0x4d69 Ultra133/ATA Bus Master IDE Accelerator +product PROMISE ULTRA133TX2 0x5275 Ultra133TX2/ATA Bus Master IDE Accelerator +product PROMISE ULTRA133TX2v2 0x6269 Ultra133TX2v2/ATA Bus Master IDE Accelerator /* QLogic products */ product QLOGIC ISP1020 0x1020 ISP1020 @@ -1841,6 +1873,8 @@ product SERVERWORKS CNB20HE 0x0008 CNB20HE Host product SERVERWORKS CNB20LE 0x0009 CNB20LE Host product SERVERWORKS CIOB30 0x0010 CIOB30 product SERVERWORKS CMIC_HE 0x0011 CMIC_HE Host +product SERVERWORKS CMIC_LE 0x0012 CMIC_LE Host +product SERVERWORKS CMIC_SL 0x0017 CMIC_SL Host product SERVERWORKS OSB4_IDE 0x0211 OSB4 IDE product SERVERWORKS CSB5_IDE 0x0212 CSB5 IDE product SERVERWORKS USB 0x0220 OSB4/CSB5 USB @@ -1937,7 +1971,7 @@ product SYMPHONY 83C553 0x0565 83C553 PCI-ISA Bridge /* Schneider & Koch (really SysKonnect) products */ product SCHNEIDERKOCH SKNET_FDDI 0x4000 SK-NET FDDI-xP product SCHNEIDERKOCH SKNET_GE 0x4300 SK-NET GE -product SCHNEIDERKOCH ALTIMA 0x4400 SK-NET Altima Gigabit Ethernet +product SCHNEIDERKOCH SK_9DX1 0x4400 SK-NET SK-9DX1 Gigabit Ethernet /* These next two are are really subsystem IDs */ product SCHNEIDERKOCH SK_9D21 0x4421 SK-9D21 1000BASE-T product SCHNEIDERKOCH SK_9D41 0x4441 SK-9D41 1000BASE-X @@ -2104,12 +2138,13 @@ product VIATECH VT3043 0x3043 VT3043 (Rhine) 10/100 Ethernet product VIATECH VT6306 0x3044 VT3606 OHCI IEEE 1394 Controller product VIATECH VT82C686A_SMB 0x3057 VT82C686A SMBus Controller product VIATECH VT82C686A_AC97 0x3058 VT82C686A AC-97 Audio Controller -product VIATECH VT8233_AC97 0x3059 VT8233 AC-97 Audio Controller +product VIATECH VT8233_AC97 0x3059 VT8233/VT8235 AC-97 Audio Controller product VIATECH VT6102 0x3065 VT6102 (Rhine II) 10/100 Ethernet product VIATECH VT8233 0x3074 VT8233 PCI-ISA Bridge product VIATECH VT8366 0x3099 VT8366 (Apollo KT266) CPU-PCI Bridge product VIATECH VT82C686A_MC97 0x3068 VT82C686A MC-97 Modem Controller product VIATECH VT8233A 0x3147 VT8233A PCI-ISA Bridge +product VIATECH VT8235 0x3177 VT8235 (Apollo KT400) PCI-ISA Bridge product VIATECH VT86C100A 0x6100 VT86C100A (Rhine-II) 10/100 Ethernet product VIATECH VT8231 0x8231 VT8231 IDE Controller product VIATECH VT8363_PPB 0x8305 VT8363 KT133 PCI to AGP Bridge diff --git a/netbsd/sys/dev/pci/pcidevs.h b/netbsd/sys/dev/pci/pcidevs.h index 50af42f305..d7a4bdf409 100644 --- a/netbsd/sys/dev/pci/pcidevs.h +++ b/netbsd/sys/dev/pci/pcidevs.h @@ -1,10 +1,10 @@ -/* $NetBSD: pcidevs.h,v 1.433.2.9 2002/08/02 05:42:10 lukem Exp $ */ +/* $NetBSD: pcidevs.h,v 1.433.2.18 2003/01/28 06:24:46 jmc Exp $ */ /* * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. * * generated from: - * NetBSD: pcidevs,v 1.428.2.10 2002/08/02 05:40:32 lukem Exp + * NetBSD: pcidevs,v 1.428.2.19 2003/01/27 06:21:36 jmc Exp */ /* @@ -562,6 +562,7 @@ #define PCI_VENDOR_TEKRAM2 0x1de1 /* Tekram Technology (2nd PCI Vendor ID) */ #define PCI_VENDOR_COREGA 0x15e8 /* Corega */ #define PCI_VENDOR_GLOBALSUN 0x16ab /* Global Sun Tech */ +#define PCI_VENDOR_ALTIMA 0x173b /* Altima */ #define PCI_VENDOR_FZJZEL 0x1796 /* FZ Juelich / ZEL */ #define PCI_VENDOR_SANDBURST 0x17ba /* Sandburst, Inc. */ #define PCI_VENDOR_HINT 0x3388 /* HiNT */ @@ -768,6 +769,11 @@ #define PCI_PRODUCT_ALTEON_BCM5700 0x0003 /* ACEnic BCM5700 10/100/1000 Ethernet */ #define PCI_PRODUCT_ALTEON_BCM5701 0x0004 /* ACEnic BCM5701 10/100/1000 Ethernet */ +/* Altima products */ +#define PCI_PRODUCT_ALTIMA_AC1000 0x03e8 /* AC1000 Gigabit Ethernet */ +#define PCI_PRODUCT_ALTIMA_AC1001 0x03e9 /* AC1001 Gigabit Ethernet */ +#define PCI_PRODUCT_ALTIMA_AC9100 0x03ea /* AC9100 Gigabit Ethernet */ + /* AMD products */ #define PCI_PRODUCT_AMD_PCNET_PCI 0x2000 /* PCnet-PCI Ethernet */ #define PCI_PRODUCT_AMD_PCNET_HOME 0x2001 /* PCnet-Home HomePNA Ethernet */ @@ -952,6 +958,15 @@ /* Broadcom Corporation products */ #define PCI_PRODUCT_BROADCOM_BCM5700 0x1644 /* BCM5700 10/100/1000 Ethernet */ #define PCI_PRODUCT_BROADCOM_BCM5701 0x1645 /* BCM5701 10/100/1000 Ethernet */ +#define PCI_PRODUCT_BROADCOM_BCM5702 0x1646 /* BCM5702 10/100/1000 Ethernet */ +#define PCI_PRODUCT_BROADCOM_BCM5702X 0x16a6 /* BCM5702X 10/100/1000 Ethernet */ +#define PCI_PRODUCT_BROADCOM_BCM5702FE 0x164d /* BCM5702FE 10/100 Ethernet */ +#define PCI_PRODUCT_BROADCOM_BCM5703 0x1647 /* BCM5703 10/100/1000 Ethernet */ +#define PCI_PRODUCT_BROADCOM_BCM5703X 0x16a7 /* BCM5703X 10/100/1000 Ethernet */ +#define PCI_PRODUCT_BROADCOM_BCM5704C 0x1648 /* BCM5704C Gigabit Ethernet (1000BASE-T) */ +#define PCI_PRODUCT_BROADCOM_BCM5704S 0x16a8 /* BCM5704S Gigabit Ethernet (1000BASE-X) */ +#define PCI_PRODUCT_BROADCOM_BCM5705 0x1653 /* BCM5705 10/100/1000 Ethernet */ +#define PCI_PRODUCT_BROADCOM_BCM4401 0x4401 /* BCM4401 10/100 Ethernet */ /* Brooktree products */ #define PCI_PRODUCT_BROOKTREE_BT848 0x0350 /* Bt848 Video Capture */ @@ -1134,11 +1149,15 @@ #define PCI_PRODUCT_DELL_PERC_3SI 0x0003 /* PERC 3/Si */ #define PCI_PRODUCT_DELL_PERC_3SI_2 0x0004 /* PERC 3/Si */ #define PCI_PRODUCT_DELL_PERC_3DI_2 0x0008 /* PERC 3/Di */ +#define PCI_PRODUCT_DELL_PERC_3DI_3 0x000a /* PERC 3/Di */ #define PCI_PRODUCT_DELL_PERC_3SI 0x0003 /* PERC 3/Si */ #define PCI_PRODUCT_DELL_PERC_3DI_2_SUB 0x00cf /* PERC 3/Di */ #define PCI_PRODUCT_DELL_PERC_3SI_2_SUB 0x00d0 /* PERC 3/Si */ #define PCI_PRODUCT_DELL_PERC_3DI_SUB2 0x00d1 /* PERC 3/Di */ #define PCI_PRODUCT_DELL_PERC_3DI_SUB3 0x00d9 /* PERC 3/Di */ +#define PCI_PRODUCT_DELL_PERC_3DI_3_SUB 0x0106 /* PERC 3/Di */ +#define PCI_PRODUCT_DELL_PERC_3DI_3_SUB2 0x011b /* PERC 3/Di */ +#define PCI_PRODUCT_DELL_PERC_3DI_3_SUB3 0x0121 /* PERC 3/Di */ /* Delta products */ #define PCI_PRODUCT_DELTA_8139 0x1360 /* 8139 Ethernet */ @@ -1155,6 +1174,7 @@ #define PCI_PRODUCT_DPT_SC_RAID 0xa400 /* SmartCache/SmartRAID (EATA) */ #define PCI_PRODUCT_DPT_I960_PPB 0xa500 /* PCI-PCI Bridge */ #define PCI_PRODUCT_DPT_RAID_I2O 0xa501 /* SmartRAID (I2O) */ +#define PCI_PRODUCT_DPT_RAID_2005S 0xa511 /* Zero Channel SmartRAID (I2O) */ #define PCI_PRODUCT_DPT_MEMCTLR 0x1012 /* Memory Controller */ /* Dolphin products */ @@ -1279,6 +1299,7 @@ #define PCI_PRODUCT_IBM_TURBOWAYS25 0x0053 /* Turboways 25 ATM */ #define PCI_PRODUCT_IBM_GXT800P 0x005e /* GXT-800P */ #define PCI_PRODUCT_IBM_405GP 0x0156 /* PPC 405GP PCI Bridge */ +#define PCI_PRODUCT_IBM_133PCIX 0x01a7 /* 133 PCI-X Bridge */ #define PCI_PRODUCT_IBM_MPIC2 0xffff /* MPIC-II */ /* IDT products */ @@ -1307,6 +1328,7 @@ /* Intel products */ #define PCI_PRODUCT_INTEL_80312 0x030d /* 80312 I/O Companion Chip */ +#define PCI_PRODUCT_INTEL_80321 0x0319 /* 80321 I/O Processor */ #define PCI_PRODUCT_INTEL_PCEB 0x0482 /* 82375EB/SB PCI-EISA Bridge (PCEB) */ #define PCI_PRODUCT_INTEL_CDC 0x0483 /* 82424ZX Cache and DRAM controller (CDC) */ #define PCI_PRODUCT_INTEL_SIO 0x0484 /* 82378ZB System I/O (SIO) */ @@ -1316,14 +1338,19 @@ #define PCI_PRODUCT_INTEL_GDT_RAID2 0x061f /* GDT RAID */ #define PCI_PRODUCT_INTEL_80960RM 0x0962 /* i960 RM PCI-PCI */ #define PCI_PRODUCT_INTEL_80960RN 0x0964 /* i960 RN PCI-PCI */ -#define PCI_PRODUCT_INTEL_82542 0x1000 /* i82452 Gigabit Ethernet */ -#define PCI_PRODUCT_INTEL_82543_FIBER 0x1001 /* i82453 Gigabit Ethernet (1000BASE-X) */ -#define PCI_PRODUCT_INTEL_82543_SC 0x1003 /* i82453-SC Gigabit Ethernet */ -#define PCI_PRODUCT_INTEL_82543_COPPER 0x1004 /* i82543 Gigabit Ethernet (1000BASE-T) */ -#define PCI_PRODUCT_INTEL_82544_XT 0x1008 /* i82544 Gigabit Ethernet (1000BASE-T) */ -#define PCI_PRODUCT_INTEL_82544_XF 0x1009 /* i82544 Gigabit Ethernet (1000BASE-X) */ -#define PCI_PRODUCT_INTEL_82544GC 0x100c /* i82544GC Gigabit Ethernet (1000BASE-T) */ -#define PCI_PRODUCT_INTEL_82544GC_64 0x100d /* i82544GC (64-bit) Gigabit Ethernet (1000BASE-T) */ +#define PCI_PRODUCT_INTEL_82542 0x1000 /* i82542 Gigabit Ethernet */ +#define PCI_PRODUCT_INTEL_82543GC_FIBER 0x1001 /* i82453GC Gigabit Ethernet (1000BASE-X) */ +#define PCI_PRODUCT_INTEL_82543GC_COPPER 0x1004 /* i82543GC Gigabit Ethernet (1000BASE-T) */ +#define PCI_PRODUCT_INTEL_82544EI_COPPER 0x1008 /* i82544EI Gigabit Ethernet (1000BASE-T) */ +#define PCI_PRODUCT_INTEL_82544EI_FIBER 0x1009 /* i82544EI Gigabit Ethernet (1000BASE-X) */ +#define PCI_PRODUCT_INTEL_82544GC_COPPER 0x100c /* i82544GC Gigabit Ethernet (1000BASE-T) */ +#define PCI_PRODUCT_INTEL_82544GC_LOM 0x100d /* i82544GC (LOM) Gigabit Ethernet */ +#define PCI_PRODUCT_INTEL_82540EM 0x100e /* i82540EM Gigabit Ethernet (1000BASE-T) */ +#define PCI_PRODUCT_INTEL_82545EM_COPPER 0x100f /* i82545EM Gigabit Ethernet (1000BASE-T) */ +#define PCI_PRODUCT_INTEL_82546EB_COPPER 0x1010 /* i82546EB Gigabit Ethernet (1000BASE-T) */ +#define PCI_PRODUCT_INTEL_82545EM_FIBER 0x1011 /* i82545EM Gigabit Ethernet (1000BASE-X) */ +#define PCI_PRODUCT_INTEL_82546EB_FIBER 0x1012 /* i82546EB Gigabit Ethernet (1000BASE-X) */ +#define PCI_PRODUCT_INTEL_82540EM_LOM 0x1015 /* i82540EM (LOM) Gigabit Ethernet */ #define PCI_PRODUCT_INTEL_IN_BUSINESS 0x1030 /* InBusiness Fast Ethernet LAN Controller */ #define PCI_PRODUCT_INTEL_PRO_100_VE_0 0x1031 /* PRO/100 VE Network Controller */ #define PCI_PRODUCT_INTEL_PRO_100_VE_1 0x1032 /* PRO/100 VE Network Controller */ @@ -1403,6 +1430,9 @@ #define PCI_PRODUCT_INTEL_82801BA_IDE 0x244b /* 82801BA IDE Controller */ #define PCI_PRODUCT_INTEL_82801BAM_LPC 0x244c /* 82801BAM LPC Interface Bridge */ #define PCI_PRODUCT_INTEL_82801BA_HPB 0x244e /* 82801BA Hub-to-PCI Bridge */ +#define PCI_PRODUCT_INTEL_82801E_SMB 0x2453 /* 82801E SMBus Controller */ +#define PCI_PRODUCT_INTEL_82801E_LAN_1 0x2459 /* 82801E LAN Controller */ +#define PCI_PRODUCT_INTEL_82801E_LAN_2 0x245d /* 82801E LAN Controller */ #define PCI_PRODUCT_INTEL_82801CA_LPC 0x2480 /* 82801CA LPC Interface */ #define PCI_PRODUCT_INTEL_82801CA_USB_1 0x2482 /* 82801CA/CAM USB Controller */ #define PCI_PRODUCT_INTEL_82801CA_SMB 0x2483 /* 82801CA/CAM SMBus Controller */ @@ -1755,6 +1785,8 @@ #define PCI_PRODUCT_PROMISE_ULTRA100TX2 0x4d68 /* Ultra100TX2/ATA Bus Master IDE Accelerator */ #define PCI_PRODUCT_PROMISE_ULTRA100TX2v2 0x6268 /* Ultra100TX2v2/ATA Bus Master IDE Accelerator */ #define PCI_PRODUCT_PROMISE_ULTRA133 0x4d69 /* Ultra133/ATA Bus Master IDE Accelerator */ +#define PCI_PRODUCT_PROMISE_ULTRA133TX2 0x5275 /* Ultra133TX2/ATA Bus Master IDE Accelerator */ +#define PCI_PRODUCT_PROMISE_ULTRA133TX2v2 0x6269 /* Ultra133TX2v2/ATA Bus Master IDE Accelerator */ /* QLogic products */ #define PCI_PRODUCT_QLOGIC_ISP1020 0x1020 /* ISP1020 */ @@ -1848,6 +1880,8 @@ #define PCI_PRODUCT_SERVERWORKS_CNB20LE 0x0009 /* CNB20LE Host */ #define PCI_PRODUCT_SERVERWORKS_CIOB30 0x0010 /* CIOB30 */ #define PCI_PRODUCT_SERVERWORKS_CMIC_HE 0x0011 /* CMIC_HE Host */ +#define PCI_PRODUCT_SERVERWORKS_CMIC_LE 0x0012 /* CMIC_LE Host */ +#define PCI_PRODUCT_SERVERWORKS_CMIC_SL 0x0017 /* CMIC_SL Host */ #define PCI_PRODUCT_SERVERWORKS_OSB4_IDE 0x0211 /* OSB4 IDE */ #define PCI_PRODUCT_SERVERWORKS_CSB5_IDE 0x0212 /* CSB5 IDE */ #define PCI_PRODUCT_SERVERWORKS_USB 0x0220 /* OSB4/CSB5 USB */ @@ -1944,7 +1978,7 @@ /* Schneider & Koch (really SysKonnect) products */ #define PCI_PRODUCT_SCHNEIDERKOCH_SKNET_FDDI 0x4000 /* SK-NET FDDI-xP */ #define PCI_PRODUCT_SCHNEIDERKOCH_SKNET_GE 0x4300 /* SK-NET GE */ -#define PCI_PRODUCT_SCHNEIDERKOCH_ALTIMA 0x4400 /* SK-NET Altima Gigabit Ethernet */ +#define PCI_PRODUCT_SCHNEIDERKOCH_SK_9DX1 0x4400 /* SK-NET SK-9DX1 Gigabit Ethernet */ /* These next two are are really subsystem IDs */ #define PCI_PRODUCT_SCHNEIDERKOCH_SK_9D21 0x4421 /* SK-9D21 1000BASE-T */ #define PCI_PRODUCT_SCHNEIDERKOCH_SK_9D41 0x4441 /* SK-9D41 1000BASE-X */ @@ -2111,12 +2145,13 @@ #define PCI_PRODUCT_VIATECH_VT6306 0x3044 /* VT3606 OHCI IEEE 1394 Controller */ #define PCI_PRODUCT_VIATECH_VT82C686A_SMB 0x3057 /* VT82C686A SMBus Controller */ #define PCI_PRODUCT_VIATECH_VT82C686A_AC97 0x3058 /* VT82C686A AC-97 Audio Controller */ -#define PCI_PRODUCT_VIATECH_VT8233_AC97 0x3059 /* VT8233 AC-97 Audio Controller */ +#define PCI_PRODUCT_VIATECH_VT8233_AC97 0x3059 /* VT8233/VT8235 AC-97 Audio Controller */ #define PCI_PRODUCT_VIATECH_VT6102 0x3065 /* VT6102 (Rhine II) 10/100 Ethernet */ #define PCI_PRODUCT_VIATECH_VT8233 0x3074 /* VT8233 PCI-ISA Bridge */ #define PCI_PRODUCT_VIATECH_VT8366 0x3099 /* VT8366 (Apollo KT266) CPU-PCI Bridge */ #define PCI_PRODUCT_VIATECH_VT82C686A_MC97 0x3068 /* VT82C686A MC-97 Modem Controller */ #define PCI_PRODUCT_VIATECH_VT8233A 0x3147 /* VT8233A PCI-ISA Bridge */ +#define PCI_PRODUCT_VIATECH_VT8235 0x3177 /* VT8235 (Apollo KT400) PCI-ISA Bridge */ #define PCI_PRODUCT_VIATECH_VT86C100A 0x6100 /* VT86C100A (Rhine-II) 10/100 Ethernet */ #define PCI_PRODUCT_VIATECH_VT8231 0x8231 /* VT8231 IDE Controller */ #define PCI_PRODUCT_VIATECH_VT8363_PPB 0x8305 /* VT8363 KT133 PCI to AGP Bridge */ diff --git a/netbsd/sys/dev/pci/pcidevs_data.h b/netbsd/sys/dev/pci/pcidevs_data.h index 732c271e01..07aa1de2ae 100644 --- a/netbsd/sys/dev/pci/pcidevs_data.h +++ b/netbsd/sys/dev/pci/pcidevs_data.h @@ -1,10 +1,10 @@ -/* $NetBSD: pcidevs_data.h,v 1.431.2.9 2002/08/02 05:42:12 lukem Exp $ */ +/* $NetBSD: pcidevs_data.h,v 1.431.2.18 2003/01/28 06:24:48 jmc Exp $ */ /* * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. * * generated from: - * NetBSD: pcidevs,v 1.428.2.10 2002/08/02 05:40:32 lukem Exp + * NetBSD: pcidevs,v 1.428.2.19 2003/01/27 06:21:36 jmc Exp */ /* @@ -867,6 +867,24 @@ const struct pci_knowndev pci_knowndevs[] = { "Alteon", "ACEnic BCM5701 10/100/1000 Ethernet", }, + { + PCI_VENDOR_ALTIMA, PCI_PRODUCT_ALTIMA_AC1000, + 0, + "Altima", + "AC1000 Gigabit Ethernet", + }, + { + PCI_VENDOR_ALTIMA, PCI_PRODUCT_ALTIMA_AC1001, + 0, + "Altima", + "AC1001 Gigabit Ethernet", + }, + { + PCI_VENDOR_ALTIMA, PCI_PRODUCT_ALTIMA_AC9100, + 0, + "Altima", + "AC9100 Gigabit Ethernet", + }, { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PCNET_PCI, 0, @@ -1773,6 +1791,60 @@ const struct pci_knowndev pci_knowndevs[] = { "Broadcom Corporation", "BCM5701 10/100/1000 Ethernet", }, + { + PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5702, + 0, + "Broadcom Corporation", + "BCM5702 10/100/1000 Ethernet", + }, + { + PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5702X, + 0, + "Broadcom Corporation", + "BCM5702X 10/100/1000 Ethernet", + }, + { + PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5702FE, + 0, + "Broadcom Corporation", + "BCM5702FE 10/100 Ethernet", + }, + { + PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5703, + 0, + "Broadcom Corporation", + "BCM5703 10/100/1000 Ethernet", + }, + { + PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5703X, + 0, + "Broadcom Corporation", + "BCM5703X 10/100/1000 Ethernet", + }, + { + PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5704C, + 0, + "Broadcom Corporation", + "BCM5704C Gigabit Ethernet (1000BASE-T)", + }, + { + PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5704S, + 0, + "Broadcom Corporation", + "BCM5704S Gigabit Ethernet (1000BASE-X)", + }, + { + PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5705, + 0, + "Broadcom Corporation", + "BCM5705 10/100/1000 Ethernet", + }, + { + PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4401, + 0, + "Broadcom Corporation", + "BCM4401 10/100 Ethernet", + }, { PCI_VENDOR_BROOKTREE, PCI_PRODUCT_BROOKTREE_BT848, 0, @@ -2535,6 +2607,12 @@ const struct pci_knowndev pci_knowndevs[] = { "Dell Computer", "PERC 3/Di", }, + { + PCI_VENDOR_DELL, PCI_PRODUCT_DELL_PERC_3DI_3, + 0, + "Dell Computer", + "PERC 3/Di", + }, { PCI_VENDOR_DELL, PCI_PRODUCT_DELL_PERC_3SI, 0, @@ -2565,6 +2643,24 @@ const struct pci_knowndev pci_knowndevs[] = { "Dell Computer", "PERC 3/Di", }, + { + PCI_VENDOR_DELL, PCI_PRODUCT_DELL_PERC_3DI_3_SUB, + 0, + "Dell Computer", + "PERC 3/Di", + }, + { + PCI_VENDOR_DELL, PCI_PRODUCT_DELL_PERC_3DI_3_SUB2, + 0, + "Dell Computer", + "PERC 3/Di", + }, + { + PCI_VENDOR_DELL, PCI_PRODUCT_DELL_PERC_3DI_3_SUB3, + 0, + "Dell Computer", + "PERC 3/Di", + }, { PCI_VENDOR_DELTA, PCI_PRODUCT_DELTA_8139, 0, @@ -2613,6 +2709,12 @@ const struct pci_knowndev pci_knowndevs[] = { "Distributed Processing Technology", "SmartRAID (I2O)", }, + { + PCI_VENDOR_DPT, PCI_PRODUCT_DPT_RAID_2005S, + 0, + "Distributed Processing Technology", + "Zero Channel SmartRAID (I2O)", + }, { PCI_VENDOR_DPT, PCI_PRODUCT_DPT_MEMCTLR, 0, @@ -3069,6 +3171,12 @@ const struct pci_knowndev pci_knowndevs[] = { "IBM", "PPC 405GP PCI Bridge", }, + { + PCI_VENDOR_IBM, PCI_PRODUCT_IBM_133PCIX, + 0, + "IBM", + "133 PCI-X Bridge", + }, { PCI_VENDOR_IBM, PCI_PRODUCT_IBM_MPIC2, 0, @@ -3165,6 +3273,12 @@ const struct pci_knowndev pci_knowndevs[] = { "Intel", "80312 I/O Companion Chip", }, + { + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_80321, + 0, + "Intel", + "80321 I/O Processor", + }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PCEB, 0, @@ -3223,49 +3337,79 @@ const struct pci_knowndev pci_knowndevs[] = { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82542, 0, "Intel", - "i82452 Gigabit Ethernet", + "i82542 Gigabit Ethernet", }, { - PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82543_FIBER, + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82543GC_FIBER, 0, "Intel", - "i82453 Gigabit Ethernet (1000BASE-X)", + "i82453GC Gigabit Ethernet (1000BASE-X)", }, { - PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82543_SC, + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82543GC_COPPER, 0, "Intel", - "i82453-SC Gigabit Ethernet", + "i82543GC Gigabit Ethernet (1000BASE-T)", }, { - PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82543_COPPER, + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82544EI_COPPER, 0, "Intel", - "i82543 Gigabit Ethernet (1000BASE-T)", + "i82544EI Gigabit Ethernet (1000BASE-T)", }, { - PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82544_XT, + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82544EI_FIBER, 0, "Intel", - "i82544 Gigabit Ethernet (1000BASE-T)", + "i82544EI Gigabit Ethernet (1000BASE-X)", }, { - PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82544_XF, + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82544GC_COPPER, 0, "Intel", - "i82544 Gigabit Ethernet (1000BASE-X)", + "i82544GC Gigabit Ethernet (1000BASE-T)", }, { - PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82544GC, + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82544GC_LOM, 0, "Intel", - "i82544GC Gigabit Ethernet (1000BASE-T)", + "i82544GC (LOM) Gigabit Ethernet", + }, + { + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82540EM, + 0, + "Intel", + "i82540EM Gigabit Ethernet (1000BASE-T)", + }, + { + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82545EM_COPPER, + 0, + "Intel", + "i82545EM Gigabit Ethernet (1000BASE-T)", }, { - PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82544GC_64, + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82546EB_COPPER, 0, "Intel", - "i82544GC (64-bit) Gigabit Ethernet (1000BASE-T)", + "i82546EB Gigabit Ethernet (1000BASE-T)", + }, + { + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82545EM_FIBER, + 0, + "Intel", + "i82545EM Gigabit Ethernet (1000BASE-X)", + }, + { + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82546EB_FIBER, + 0, + "Intel", + "i82546EB Gigabit Ethernet (1000BASE-X)", + }, + { + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82540EM_LOM, + 0, + "Intel", + "i82540EM (LOM) Gigabit Ethernet", }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_IN_BUSINESS, @@ -3741,6 +3885,24 @@ const struct pci_knowndev pci_knowndevs[] = { "Intel", "82801BA Hub-to-PCI Bridge", }, + { + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801E_SMB, + 0, + "Intel", + "82801E SMBus Controller", + }, + { + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801E_LAN_1, + 0, + "Intel", + "82801E LAN Controller", + }, + { + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801E_LAN_2, + 0, + "Intel", + "82801E LAN Controller", + }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CA_LPC, 0, @@ -5325,6 +5487,18 @@ const struct pci_knowndev pci_knowndevs[] = { "Promise Technology", "Ultra133/ATA Bus Master IDE Accelerator", }, + { + PCI_VENDOR_PROMISE, PCI_PRODUCT_PROMISE_ULTRA133TX2, + 0, + "Promise Technology", + "Ultra133TX2/ATA Bus Master IDE Accelerator", + }, + { + PCI_VENDOR_PROMISE, PCI_PRODUCT_PROMISE_ULTRA133TX2v2, + 0, + "Promise Technology", + "Ultra133TX2v2/ATA Bus Master IDE Accelerator", + }, { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1020, 0, @@ -5739,6 +5913,18 @@ const struct pci_knowndev pci_knowndevs[] = { "ServerWorks", "CMIC_HE Host", }, + { + PCI_VENDOR_SERVERWORKS, PCI_PRODUCT_SERVERWORKS_CMIC_LE, + 0, + "ServerWorks", + "CMIC_LE Host", + }, + { + PCI_VENDOR_SERVERWORKS, PCI_PRODUCT_SERVERWORKS_CMIC_SL, + 0, + "ServerWorks", + "CMIC_SL Host", + }, { PCI_VENDOR_SERVERWORKS, PCI_PRODUCT_SERVERWORKS_OSB4_IDE, 0, @@ -6148,10 +6334,10 @@ const struct pci_knowndev pci_knowndevs[] = { "SK-NET GE", }, { - PCI_VENDOR_SCHNEIDERKOCH, PCI_PRODUCT_SCHNEIDERKOCH_ALTIMA, + PCI_VENDOR_SCHNEIDERKOCH, PCI_PRODUCT_SCHNEIDERKOCH_SK_9DX1, 0, "Schneider & Koch", - "SK-NET Altima Gigabit Ethernet", + "SK-NET SK-9DX1 Gigabit Ethernet", }, { PCI_VENDOR_SCHNEIDERKOCH, PCI_PRODUCT_SCHNEIDERKOCH_SK_9D21, @@ -6937,7 +7123,7 @@ const struct pci_knowndev pci_knowndevs[] = { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8233_AC97, 0, "VIA Technologies", - "VT8233 AC-97 Audio Controller", + "VT8233/VT8235 AC-97 Audio Controller", }, { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT6102, @@ -6969,6 +7155,12 @@ const struct pci_knowndev pci_knowndevs[] = { "VIA Technologies", "VT8233A PCI-ISA Bridge", }, + { + PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8235, + 0, + "VIA Technologies", + "VT8235 (Apollo KT400) PCI-ISA Bridge", + }, { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT86C100A, 0, @@ -10713,6 +10905,12 @@ const struct pci_knowndev pci_knowndevs[] = { "Global Sun Tech", NULL, }, + { + PCI_VENDOR_ALTIMA, 0, + PCI_KNOWNDEV_NOPROD, + "Altima", + NULL, + }, { PCI_VENDOR_FZJZEL, 0, PCI_KNOWNDEV_NOPROD, diff --git a/netbsd/sys/dev/pcmcia/if_xi.c b/netbsd/sys/dev/pcmcia/if_xi.c index ba6efb6894..55ac5180e0 100644 --- a/netbsd/sys/dev/pcmcia/if_xi.c +++ b/netbsd/sys/dev/pcmcia/if_xi.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_xi.c,v 1.21 2002/05/05 03:19:26 takemura Exp $ */ +/* $NetBSD: if_xi.c,v 1.21.4.1 2002/10/02 02:56:55 lukem Exp $ */ /* OpenBSD: if_xe.c,v 1.9 1999/09/16 11:28:42 niklas Exp */ /* @@ -49,7 +49,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_xi.c,v 1.21 2002/05/05 03:19:26 takemura Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_xi.c,v 1.21.4.1 2002/10/02 02:56:55 lukem Exp $"); #include "opt_inet.h" #include "bpfilter.h" @@ -834,13 +834,14 @@ xi_intr(arg) PAGE(sc, 40); rx_status = bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + RXST0); + bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + RXST0, + ~rx_status & 0xff); tx_status = bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + TXST0); - - /* - * XXX Linux writes to RXST0 and TXST* here. My CE2 works just fine - * without it, and I can't see an obvious reason for it. - */ + tx_status |= + bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + TXST1) << 8; + bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + TXST0,0); + bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + TXST1,0); PAGE(sc, 0); while (esr & FULL_PKT_RCV) { @@ -885,6 +886,7 @@ xi_intr(arg) /* Check for rx overrun. */ if (rx_status & RX_OVERRUN) { + ifp->if_ierrors++; bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + CR, CLR_RX_OVERRUN); DPRINTF(XID_INTR, ("xi: overrun cleared\n")); diff --git a/netbsd/sys/dev/pcmcia/pcmciadevs b/netbsd/sys/dev/pcmcia/pcmciadevs index acec08debb..42dcc34f54 100644 --- a/netbsd/sys/dev/pcmcia/pcmciadevs +++ b/netbsd/sys/dev/pcmcia/pcmciadevs @@ -1,4 +1,4 @@ -$NetBSD: pcmciadevs,v 1.167.4.4 2002/06/18 14:30:28 lukem Exp $ +$NetBSD: pcmciadevs,v 1.167.4.6 2002/11/19 21:29:47 tron Exp $ /* $FreeBSD: src/sys/dev/pccard/pccarddevs,v 1.20 2001/11/19 05:02:55 imp Exp $*/ /*- @@ -42,6 +42,7 @@ $NetBSD: pcmciadevs,v 1.167.4.4 2002/06/18 14:30:28 lukem Exp $ */ vendor FUJITSU 0x0004 Fujitsu Corporation +vendor NETGEAR_2 0x000b Netgear vendor PANASONIC 0x0032 Matsushita Electric Industrial Co. vendor SANDISK 0x0045 Sandisk Corporation vendor NEWMEDIA 0x0057 New Media Corporation @@ -277,6 +278,7 @@ product NEWMEDIA2 BUSTOASTER 0x0001 NewMedia BusToaster /* Netgear */ product NETGEAR FA410TXC 0x4530 Netgear FA410TXC product NETGEAR FA411 0x0411 Netgear FA411 +product NETGEAR_2 MA401 0x7300 Netgear MA401 /* National Instruments */ product NI PCMCIA_GPIB 0x4882 National Instruments PCMCIA-GPIB @@ -397,6 +399,7 @@ vendor TEAC -1 TEAC vendor YEDATA -1 Y-E DATA product ACCTON EN2212 { "ACCTON", "EN2212", NULL, NULL } Accton EN2212 +product ACCTON EN2216 { "ACCTON", "EN2216-PCMCIA-ETHERNET", "EN2216R01", NULL } Accton EN2216 product AMBICOM AMB8002T { "AmbiCom&spInc", "AMB8002T", NULL, NULL } AmbiCom AMB8002T product AMD AM79C930 { "AMD", "Am79C930", NULL, NULL } AMD Am79C930 product BILLIONTON LNT10TN { "PCMCIA", "LNT-10TN", NULL, NULL } Billionton Systems Inc. LNT-10TN NE2000 Compatible Card diff --git a/netbsd/sys/dev/pcmcia/pcmciadevs.h b/netbsd/sys/dev/pcmcia/pcmciadevs.h index 320faffd53..e9d1b81084 100644 --- a/netbsd/sys/dev/pcmcia/pcmciadevs.h +++ b/netbsd/sys/dev/pcmcia/pcmciadevs.h @@ -1,4 +1,4 @@ -/* $NetBSD: pcmciadevs.h,v 1.167.4.4 2002/06/18 14:36:56 lukem Exp $ */ +/* $NetBSD: pcmciadevs.h,v 1.167.4.6 2002/11/19 21:30:26 tron Exp $ */ /* * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. @@ -49,6 +49,7 @@ */ #define PCMCIA_VENDOR_FUJITSU 0x0004 /* Fujitsu Corporation */ +#define PCMCIA_VENDOR_NETGEAR_2 0x000b /* Netgear */ #define PCMCIA_VENDOR_PANASONIC 0x0032 /* Matsushita Electric Industrial Co. */ #define PCMCIA_VENDOR_SANDISK 0x0045 /* Sandisk Corporation */ #define PCMCIA_VENDOR_NEWMEDIA 0x0057 /* New Media Corporation */ @@ -472,6 +473,9 @@ #define PCMCIA_CIS_NETGEAR_FA411 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_NETGEAR_FA411 0x0411 #define PCMCIA_STR_NETGEAR_FA411 "Netgear FA411" +#define PCMCIA_CIS_NETGEAR_2_MA401 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_NETGEAR_2_MA401 0x7300 +#define PCMCIA_STR_NETGEAR_2_MA401 "Netgear MA401" /* National Instruments */ #define PCMCIA_CIS_NI_PCMCIA_GPIB { NULL, NULL, NULL, NULL } @@ -688,6 +692,9 @@ #define PCMCIA_CIS_ACCTON_EN2212 { "ACCTON", "EN2212", NULL, NULL } #define PCMCIA_PRODUCT_ACCTON_EN2212 -1 #define PCMCIA_STR_ACCTON_EN2212 "Accton EN2212" +#define PCMCIA_CIS_ACCTON_EN2216 { "ACCTON", "EN2216-PCMCIA-ETHERNET", "EN2216R01", NULL } +#define PCMCIA_PRODUCT_ACCTON_EN2216 -1 +#define PCMCIA_STR_ACCTON_EN2216 "Accton EN2216" #define PCMCIA_CIS_AMBICOM_AMB8002T { "AmbiCom Inc", "AMB8002T", NULL, NULL } #define PCMCIA_PRODUCT_AMBICOM_AMB8002T -1 #define PCMCIA_STR_AMBICOM_AMB8002T "AmbiCom AMB8002T" diff --git a/netbsd/sys/dev/pcmcia/pcmciadevs_data.h b/netbsd/sys/dev/pcmcia/pcmciadevs_data.h index d79280946f..a7c69f4739 100644 --- a/netbsd/sys/dev/pcmcia/pcmciadevs_data.h +++ b/netbsd/sys/dev/pcmcia/pcmciadevs_data.h @@ -1,4 +1,4 @@ -/* $NetBSD: pcmciadevs_data.h,v 1.167.4.4 2002/06/18 14:36:57 lukem Exp $ */ +/* $NetBSD: pcmciadevs_data.h,v 1.167.4.6 2002/11/19 21:30:27 tron Exp $ */ /* * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. @@ -721,6 +721,13 @@ struct pcmcia_knowndev pcmcia_knowndevs[] = { "Netgear", "Netgear FA411", } , + { + PCMCIA_VENDOR_NETGEAR_2, PCMCIA_PRODUCT_NETGEAR_2_MA401, + PCMCIA_CIS_NETGEAR_2_MA401, + 0, + "Netgear", + "Netgear MA401", } + , { PCMCIA_VENDOR_NI, PCMCIA_PRODUCT_NI_PCMCIA_GPIB, PCMCIA_CIS_NI_PCMCIA_GPIB, @@ -1057,6 +1064,13 @@ struct pcmcia_knowndev pcmcia_knowndevs[] = { "ACCTON", "Accton EN2212", } , + { + PCMCIA_VENDOR_UNKNOWN, PCMCIA_PRODUCT_ACCTON_EN2216, + PCMCIA_CIS_ACCTON_EN2216, + 0, + "ACCTON", + "Accton EN2216", } + , { PCMCIA_VENDOR_UNKNOWN, PCMCIA_PRODUCT_AMBICOM_AMB8002T, PCMCIA_CIS_AMBICOM_AMB8002T, @@ -1450,6 +1464,14 @@ struct pcmcia_knowndev pcmcia_knowndevs[] = { "Fujitsu Corporation", NULL, }, + { + PCMCIA_VENDOR_NETGEAR_2, + PCMCIA_KNOWNDEV_NOPROD, + PCMCIA_CIS_INVALID, + 0, + "Netgear", + NULL, + }, { PCMCIA_VENDOR_PANASONIC, PCMCIA_KNOWNDEV_NOPROD, diff --git a/netbsd/sys/dev/usb/if_aue.c b/netbsd/sys/dev/usb/if_aue.c index ec6c37d11a..746aec8012 100644 --- a/netbsd/sys/dev/usb/if_aue.c +++ b/netbsd/sys/dev/usb/if_aue.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_aue.c,v 1.75 2002/03/18 14:01:05 christos Exp $ */ +/* $NetBSD: if_aue.c,v 1.75.6.1 2002/11/06 20:38:31 tron Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 * Bill Paul . All rights reserved. @@ -77,7 +77,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.75 2002/03/18 14:01:05 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.75.6.1 2002/11/06 20:38:31 tron Exp $"); #if defined(__NetBSD__) #include "opt_inet.h" @@ -218,6 +218,7 @@ Static const struct aue_type aue_devs[] = { {{ USB_VENDOR_SIEMENS, USB_PRODUCT_SIEMENS_SPEEDSTREAM}, PII }, {{ USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTNIC},PII }, {{ USB_VENDOR_SMC, USB_PRODUCT_SMC_2202USB}, 0 }, + {{ USB_VENDOR_SMC, USB_PRODUCT_SMC_2206USB}, PII }, {{ USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB100}, 0 }, }; #define aue_lookup(v, p) ((struct aue_type *)usb_lookup(aue_devs, v, p)) diff --git a/netbsd/sys/kern/init_main.c b/netbsd/sys/kern/init_main.c index 04cd22086b..cc4129ed18 100644 --- a/netbsd/sys/kern/init_main.c +++ b/netbsd/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $NetBSD: init_main.c,v 1.199 2002/03/04 02:30:27 simonb Exp $ */ +/* $NetBSD: init_main.c,v 1.199.8.1 2002/12/15 11:21:52 jmc Exp $ */ /* * Copyright (c) 1995 Christopher G. Demetriou. All rights reserved. @@ -42,7 +42,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.199 2002/03/04 02:30:27 simonb Exp $"); +__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.199.8.1 2002/12/15 11:21:52 jmc Exp $"); #include "fs_nfs.h" #include "opt_nfsserver.h" @@ -137,6 +137,8 @@ struct proc *curproc = &proc0; #endif struct proc *initproc; +int nofile = NOFILE; +int maxuprc = MAXUPRC; int cmask = CMASK; extern struct user *proc0paddr; @@ -283,12 +285,12 @@ main(void) limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; limit0.pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles; - limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = - maxfiles < NOFILE ? maxfiles : NOFILE; + limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = + maxfiles < nofile ? maxfiles : nofile; limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc; limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = - maxproc < MAXUPRC ? maxproc : MAXUPRC; + maxproc < maxuprc ? maxproc : maxuprc; lim = ptoa(uvmexp.free); limit0.pl_rlimit[RLIMIT_RSS].rlim_max = lim; diff --git a/netbsd/sys/kern/uipc_socket.c b/netbsd/sys/kern/uipc_socket.c index 3fb3f8c07b..360c52dd28 100644 --- a/netbsd/sys/kern/uipc_socket.c +++ b/netbsd/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_socket.c,v 1.66.4.1 2002/06/11 01:59:49 lukem Exp $ */ +/* $NetBSD: uipc_socket.c,v 1.66.4.2 2002/11/08 09:31:35 tron Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -72,7 +72,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.66.4.1 2002/06/11 01:59:49 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.66.4.2 2002/11/08 09:31:35 tron Exp $"); #include "opt_sock_counters.h" #include "opt_sosend_loan.h" @@ -1115,6 +1115,23 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio, !sosendallatonce(so) && !nextrecord) { if (so->so_error || so->so_state & SS_CANTRCVMORE) break; + /* + * If we are peeking and the socket receive buffer is + * full, stop since we can't get more data to peek at. + */ + if ((flags & MSG_PEEK) && sbspace(&so->so_rcv) <= 0) + break; + /* + * If we've drained the socket buffer, tell the + * protocol in case it needs to do something to + * get it filled again. + */ + if ((pr->pr_flags & PR_WANTRCVD) && so->so_pcb) + (*pr->pr_usrreq)(so, PRU_RCVD, + (struct mbuf *)0, + (struct mbuf *)(long)flags, + (struct mbuf *)0, + (struct proc *)0); error = sbwait(&so->so_rcv); if (error) { sbunlock(&so->so_rcv); diff --git a/netbsd/sys/kern/vfs_cluster.c b/netbsd/sys/kern/vfs_cluster.c deleted file mode 100644 index 4c64d0868c..0000000000 --- a/netbsd/sys/kern/vfs_cluster.c +++ /dev/null @@ -1,785 +0,0 @@ -/* $NetBSD: vfs_cluster.c,v 1.21 1998/11/08 18:18:31 mycroft Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)vfs_cluster.c 8.10 (Berkeley) 3/28/95 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -int doreallocblks = 0; - -#ifdef DEBUG -#include -struct ctldebug debug13 = { "doreallocblks", &doreallocblks }; -#endif - -/* - * Local declarations - */ -struct buf *cluster_rbuild __P((struct vnode *, u_quad_t, struct buf *, - daddr_t, daddr_t, long, int, long)); -void cluster_wbuild __P((struct vnode *, struct buf *, long, - daddr_t, int, daddr_t)); -struct cluster_save *cluster_collectbufs __P((struct vnode *, struct buf *)); - -#ifdef DIAGNOSTIC -/* - * Set to 1 if reads of block zero should cause readahead to be done. - * Set to 0 treats a read of block zero as a non-sequential read. - * - * Setting to one assumes that most reads of block zero of files are due to - * sequential passes over the files (e.g. cat, sum) where additional blocks - * will soon be needed. Setting to zero assumes that the majority are - * surgical strikes to get particular info (e.g. size, file) where readahead - * blocks will not be used and, in fact, push out other potentially useful - * blocks from the cache. The former seems intuitive, but some quick tests - * showed that the latter performed better from a system-wide point of view. - */ -int doclusterraz = 0; -#define ISSEQREAD(vp, blk) \ - (((blk) != 0 || doclusterraz) && \ - ((blk) == (vp)->v_lastr + 1 || (blk) == (vp)->v_lastr)) -#else -#define ISSEQREAD(vp, blk) \ - ((blk) != 0 && ((blk) == (vp)->v_lastr + 1 || (blk) == (vp)->v_lastr)) -#endif - -/* - * This replaces bread. If this is a bread at the beginning of a file and - * lastr is 0, we assume this is the first read and we'll read up to two - * blocks if they are sequential. After that, we'll do regular read ahead - * in clustered chunks. - * - * There are 4 or 5 cases depending on how you count: - * Desired block is in the cache: - * 1 Not sequential access (0 I/Os). - * 2 Access is sequential, do read-ahead (1 ASYNC). - * Desired block is not in cache: - * 3 Not sequential access (1 SYNC). - * 4 Sequential access, next block is contiguous (1 SYNC). - * 5 Sequential access, next block is not contiguous (1 SYNC, 1 ASYNC) - * - * There are potentially two buffers that require I/O. - * bp is the block requested. - * rbp is the read-ahead block. - * If either is NULL, then you don't have to do the I/O. - */ -int -cluster_read(vp, filesize, lblkno, size, cred, bpp) - struct vnode *vp; - u_quad_t filesize; - daddr_t lblkno; - long size; - struct ucred *cred; - struct buf **bpp; -{ - struct buf *bp, *rbp; - daddr_t blkno, ioblkno; - long flags; - int error, num_ra, alreadyincore; - -#ifdef DIAGNOSTIC - if (size == 0) - panic("cluster_read: size = 0"); -#endif - - error = 0; - flags = B_READ; - *bpp = bp = getblk(vp, lblkno, size, 0, 0); - if (bp->b_flags & (B_DONE | B_DELWRI)) { - /* - * Desired block is in cache; do any readahead ASYNC. - * Case 1, 2. - */ - trace(TR_BREADHIT, pack(vp, size), lblkno); - flags |= B_ASYNC; - ioblkno = lblkno + (vp->v_ralen ? vp->v_ralen : 1); - alreadyincore = incore(vp, ioblkno) != NULL; - bp = NULL; - } else { - /* Block wasn't in cache, case 3, 4, 5. */ - trace(TR_BREADMISS, pack(vp, size), lblkno); - bp->b_flags |= B_READ; - ioblkno = lblkno; - alreadyincore = 0; - curproc->p_stats->p_ru.ru_inblock++; /* XXX */ - } - /* - * XXX - * Replace 1 with a window size based on some permutation of - * maxcontig and rot_delay. This will let you figure out how - * many blocks you should read-ahead (case 2, 4, 5). - * - * If the access isn't sequential, reset the window to 1. - * Note that a read to the same block is considered sequential. - * This catches the case where the file is being read sequentially, - * but at smaller than the filesystem block size. - */ - rbp = NULL; - if (!ISSEQREAD(vp, lblkno)) { - vp->v_ralen = 0; - vp->v_maxra = lblkno; - } else if ((u_quad_t)(ioblkno + 1) * (u_quad_t)size <= filesize && - !alreadyincore && - !(error = VOP_BMAP(vp, ioblkno, NULL, &blkno, &num_ra)) && - blkno != -1) { - /* - * Reading sequentially, and the next block is not in the - * cache. We are going to try reading ahead. - */ - if (num_ra) { - /* - * If our desired readahead block had been read - * in a previous readahead but is no longer in - * core, then we may be reading ahead too far - * or are not using our readahead very rapidly. - * In this case we scale back the window. - */ - if (!alreadyincore && ioblkno <= vp->v_maxra) - vp->v_ralen = max(vp->v_ralen >> 1, 1); - /* - * There are more sequential blocks than our current - * window allows, scale up. Ideally we want to get - * in sync with the filesystem maxcontig value. - */ - else if (num_ra > vp->v_ralen && lblkno != vp->v_lastr) - vp->v_ralen = vp->v_ralen ? - min(num_ra, vp->v_ralen << 1) : 1; - - if (num_ra > vp->v_ralen) - num_ra = vp->v_ralen; - } - - if (num_ra) /* case 2, 4 */ - rbp = cluster_rbuild(vp, filesize, - bp, ioblkno, blkno, size, num_ra, flags); - else if (ioblkno == lblkno) { - bp->b_blkno = blkno; - /* Case 5: check how many blocks to read ahead */ - ++ioblkno; - if (((u_quad_t)(ioblkno + 1) * (u_quad_t)size > - filesize) || - incore(vp, ioblkno) || - (error = VOP_BMAP(vp, ioblkno, NULL, - &blkno, &num_ra)) || - blkno == -1) - goto skip_readahead; - /* - * Adjust readahead as above. - * Don't check alreadyincore, we know it is 0 from - * the previous conditional. - */ - if (num_ra) { - if (ioblkno <= vp->v_maxra) - vp->v_ralen = max(vp->v_ralen >> 1, 1); - else if (num_ra > vp->v_ralen && - lblkno != vp->v_lastr) - vp->v_ralen = vp->v_ralen ? - min(num_ra,vp->v_ralen<<1) : 1; - if (num_ra > vp->v_ralen) - num_ra = vp->v_ralen; - } - flags |= B_ASYNC; - if (num_ra) - rbp = cluster_rbuild(vp, filesize, - NULL, ioblkno, blkno, size, num_ra, flags); - else { - rbp = getblk(vp, ioblkno, size, 0, 0); - rbp->b_flags |= flags; - rbp->b_blkno = blkno; - } - } else { - /* case 2; read ahead single block */ - rbp = getblk(vp, ioblkno, size, 0, 0); - rbp->b_flags |= flags; - rbp->b_blkno = blkno; - } - - if (rbp == bp) /* case 4 */ - rbp = NULL; - else if (rbp) { /* case 2, 5 */ - trace(TR_BREADMISSRA, - pack(vp, (num_ra + 1) * size), ioblkno); - curproc->p_stats->p_ru.ru_inblock++; /* XXX */ - } - } - - /* XXX Kirk, do we need to make sure the bp has creds? */ -skip_readahead: - if (bp) { - if (bp->b_flags & (B_DONE | B_DELWRI)) - panic("cluster_read: DONE bp"); - else - error = VOP_STRATEGY(bp); - } - - if (rbp) { - if (error || rbp->b_flags & (B_DONE | B_DELWRI)) { - rbp->b_flags &= ~(B_ASYNC | B_READ); - brelse(rbp); - } else - (void) VOP_STRATEGY(rbp); - } - - /* - * Recalculate our maximum readahead - */ - if (rbp == NULL) - rbp = bp; - if (rbp) - vp->v_maxra = rbp->b_lblkno + (rbp->b_bcount / size) - 1; - - if (bp) - return(biowait(bp)); - return(error); -} - -/* - * If blocks are contiguous on disk, use this to provide clustered - * read ahead. We will read as many blocks as possible sequentially - * and then parcel them up into logical blocks in the buffer hash table. - */ -struct buf * -cluster_rbuild(vp, filesize, bp, lbn, blkno, size, run, flags) - struct vnode *vp; - u_quad_t filesize; - struct buf *bp; - daddr_t lbn; - daddr_t blkno; - long size; - int run; - long flags; -{ - struct cluster_save *b_save = 0; - struct buf *tbp; - daddr_t bn; - int i, inc; - -#ifdef DIAGNOSTIC - if (size != vp->v_mount->mnt_stat.f_iosize) - panic("cluster_rbuild: size %ld != filesize %ld\n", - size, vp->v_mount->mnt_stat.f_iosize); -#endif - if ((u_quad_t)size * (u_quad_t)(lbn + run + 1) > filesize) - --run; - if (run == 0) { - if (!bp) { - bp = getblk(vp, lbn, size, 0, 0); - bp->b_blkno = blkno; - bp->b_flags |= flags; - } - return (bp); - } - - if (!bp) - bp = getblk(vp, lbn, size, 0, 0); - bp->b_blkno = blkno; - - /* - * If initial component of the cluster is already - * in core, terminate the cluster early. - */ - if (bp->b_flags & (B_DONE | B_DELWRI)) - return (bp); - - bp->b_flags |= flags; - - /* - * If block size is not a multiple of page size there - * is no way of doing the necessary page moving, so - * terminate early. - */ - if (size != roundup(size, CLBYTES)) - return (bp); - - inc = btodb(size); - for (bn = blkno + inc, i = 1; i <= run; ++i, bn += inc) { - /* - * If a component of the cluster is already in core, - * terminate the cluster early. - */ - if (incore(vp, lbn + i)) - break; - tbp = getblk(vp, lbn + i, size, 0, 0); - if (tbp->b_flags & (B_DONE | B_DELWRI)) { - brelse(tbp); - break; - } - - /* - * If there are excess pages in the cluster buffer and - * this buffer can take some of them, then shift some - * of the excess to here. - */ - if (bp->b_bufsize > (i * size)) { - int freespace = MAXBSIZE - tbp->b_bufsize; - - if (freespace > 0) { - int nbytes = bp->b_bufsize - (i * size); - if (nbytes > freespace) - nbytes = freespace; - - /* move pages and update sizes */ - pagemove(bp->b_data + bp->b_bufsize - nbytes, - tbp->b_data + tbp->b_bufsize, - nbytes); - bp->b_bufsize -= nbytes; - tbp->b_bufsize += nbytes; - } - } - - /* - * If there there is no space for forming a composite - * cluster buffer with this one, terminate. - */ - if (bp->b_bufsize + size > MAXBSIZE) { - brelse(tbp); - break; - } - - /* - * Have good candidate for cluster; make sure cluster - * save area is allocated etc. - */ - if (b_save == 0) { - bp->b_iodone = cluster_callback; - bp->b_flags |= B_CALL; - - b_save = malloc(sizeof(struct buf *) * run + - sizeof(struct cluster_save), - M_SEGMENT, M_WAITOK); - b_save->bs_bufsize = b_save->bs_bcount = size; - b_save->bs_nchildren = 0; - b_save->bs_children = (struct buf **)(b_save + 1); - b_save->bs_saveaddr = bp->b_saveaddr; - - bp->b_saveaddr = (caddr_t) b_save; - } - - /* - * Move pages to the cluster buffer and update - * its size appropriately. - */ - pagemove(tbp->b_data, bp->b_data + bp->b_bufsize, size); - bp->b_bcount += size; - bp->b_bufsize += size; - - tbp->b_bufsize -= size; - tbp->b_blkno = bn; - tbp->b_flags |= flags | B_READ | B_ASYNC; - - b_save->bs_children[b_save->bs_nchildren++] = tbp; - } - - return(bp); -} - -/* - * Cleanup after a clustered read or write. - * This is complicated by the fact that any of the buffers might have - * extra memory (if there were no empty buffer headers at allocbuf time) - * that we will need to shift around. - */ -void -cluster_callback(bp) - struct buf *bp; -{ - struct cluster_save *b_save; - struct buf *tbp; - long bsize; - caddr_t cp; - int error = 0; - - /* - * Must propogate errors to all the components. - */ - if (bp->b_flags & B_ERROR) - error = bp->b_error; - - b_save = (struct cluster_save *)(bp->b_saveaddr); - bp->b_saveaddr = b_save->bs_saveaddr; - - bsize = b_save->bs_bufsize; - cp = (char *)bp->b_data + bsize * b_save->bs_nchildren; - /* - * Move memory from the large cluster buffer into the component - * buffers in reverse order and mark IO as done on these. - */ - while (b_save->bs_nchildren--) { - tbp = b_save->bs_children[b_save->bs_nchildren]; - pagemove(cp, tbp->b_data, bsize); - tbp->b_bufsize += bsize; - tbp->b_bcount = bsize; - if (error) { - tbp->b_flags |= B_ERROR; - tbp->b_error = error; - } - biodone(tbp); - bp->b_bufsize -= bsize; - cp -= bsize; - } - /* - * If there was excess memory in the cluster buffer, - * slide it up adjacent to the remaining valid data. - */ - if (bp->b_bufsize != bsize) { - if (bp->b_bufsize < bsize) - panic("cluster_callback: too little memory"); - pagemove((char *)bp->b_data + bp->b_bcount, - (char *)bp->b_data + bsize, - bp->b_bufsize - bsize); - } - bp->b_bcount = bsize; - - bp->b_iodone = NULL; - free(b_save, M_SEGMENT); - - if (bp->b_flags & B_ASYNC) - brelse(bp); - else { - bp->b_flags &= ~B_WANTED; - wakeup((caddr_t)bp); - } -} - -/* - * Do clustered write for FFS. - * - * Three cases: - * 1. Write is not sequential (write asynchronously) - * Write is sequential: - * 2. beginning of cluster - begin cluster - * 3. middle of a cluster - add to cluster - * 4. end of a cluster - asynchronously write cluster - */ -void -cluster_write(bp, filesize) - struct buf *bp; - u_quad_t filesize; -{ - struct vnode *vp; - daddr_t lbn; - int maxclen, cursize; - - vp = bp->b_vp; - lbn = bp->b_lblkno; - - /* Initialize vnode to beginning of file. */ - if (lbn == 0) - vp->v_lasta = vp->v_clen = vp->v_cstart = vp->v_lastw = 0; - - if (vp->v_clen == 0 || lbn != vp->v_lastw + 1 || - (bp->b_blkno != vp->v_lasta + btodb(bp->b_bcount))) { - maxclen = MAXBSIZE / vp->v_mount->mnt_stat.f_iosize - 1; - if (vp->v_clen != 0) { - /* - * Next block is not sequential. - * - * If we are not writing at end of file, the process - * seeked to another point in the file since its - * last write, or we have reached our maximum - * cluster size, then push the previous cluster. - * Otherwise try reallocating to make it sequential. - */ - cursize = vp->v_lastw - vp->v_cstart + 1; - if (!doreallocblks || - (u_quad_t)(lbn + 1) * bp->b_bcount != filesize || - lbn != vp->v_lastw + 1 || vp->v_clen <= cursize) { - cluster_wbuild(vp, NULL, bp->b_bcount, - vp->v_cstart, cursize, lbn); - } else { - struct buf **bpp, **endbp; - struct cluster_save *buflist; - - buflist = cluster_collectbufs(vp, bp); - endbp = &buflist->bs_children - [buflist->bs_nchildren - 1]; - if (VOP_REALLOCBLKS(vp, buflist)) { - /* - * Failed, push the previous cluster. - */ - for (bpp = buflist->bs_children; - bpp < endbp; bpp++) - brelse(*bpp); - free(buflist, M_SEGMENT); - cluster_wbuild(vp, NULL, bp->b_bcount, - vp->v_cstart, cursize, lbn); - } else { - /* - * Succeeded, keep building cluster. - */ - for (bpp = buflist->bs_children; - bpp <= endbp; bpp++) - bdwrite(*bpp); - free(buflist, M_SEGMENT); - vp->v_lastw = lbn; - vp->v_lasta = bp->b_blkno; - return; - } - } - } - /* - * Consider beginning a cluster. - * If at end of file, make cluster as large as possible, - * otherwise find size of existing cluster. - */ - if ((u_quad_t)(lbn + 1) * (u_quad_t)bp->b_bcount != filesize && - (VOP_BMAP(vp, lbn, NULL, &bp->b_blkno, &maxclen) || - bp->b_blkno == -1)) { - bawrite(bp); - vp->v_clen = 0; - vp->v_lasta = bp->b_blkno; - vp->v_cstart = lbn + 1; - vp->v_lastw = lbn; - return; - } - vp->v_clen = maxclen; - if (maxclen == 0) { /* I/O not contiguous */ - vp->v_cstart = lbn + 1; - bawrite(bp); - } else { /* Wait for rest of cluster */ - vp->v_cstart = lbn; - bdwrite(bp); - } - } else if (lbn == vp->v_cstart + vp->v_clen) { - /* - * At end of cluster, write it out. - */ - cluster_wbuild(vp, bp, bp->b_bcount, vp->v_cstart, - vp->v_clen + 1, lbn); - vp->v_clen = 0; - vp->v_cstart = lbn + 1; - } else - /* - * In the middle of a cluster, so just delay the - * I/O for now. - */ - bdwrite(bp); - vp->v_lastw = lbn; - vp->v_lasta = bp->b_blkno; -} - - -/* - * This is an awful lot like cluster_rbuild...wish they could be combined. - * The last lbn argument is the current block on which I/O is being - * performed. Check to see that it doesn't fall in the middle of - * the current block (if last_bp == NULL). - */ -void -cluster_wbuild(vp, last_bp, size, start_lbn, len, lbn) - struct vnode *vp; - struct buf *last_bp; - long size; - daddr_t start_lbn; - int len; - daddr_t lbn; -{ - struct cluster_save *b_save; - struct buf *bp, *tbp; - caddr_t cp; - int i, s; - -#ifdef DIAGNOSTIC - if (size != vp->v_mount->mnt_stat.f_iosize) - panic("cluster_wbuild: size %ld != filesize %ld\n", - size, vp->v_mount->mnt_stat.f_iosize); -#endif -redo: - while ((!incore(vp, start_lbn) || start_lbn == lbn) && len) { - ++start_lbn; - --len; - } - - /* Get more memory for current buffer */ - if (len <= 1) { - if (last_bp) { - bawrite(last_bp); - } else if (len) { - bp = getblk(vp, start_lbn, size, 0, 0); - /* - * The buffer may have been in the process of being - * reclaimed, and is no longer valid. If so, we'll - * get a new buffer here, which won't have B_DELWRI - * set. Detect this and just drop the buffer on the - * floor rather than writing it out. - */ - if (!(bp->b_flags & B_DELWRI)) - brelse(bp); - else - bawrite(bp); - } - return; - } - - bp = getblk(vp, start_lbn, size, 0, 0); - if (!(bp->b_flags & B_DELWRI)) { - ++start_lbn; - --len; - brelse(bp); - goto redo; - } - - /* - * Extra memory in the buffer, punt on this buffer. - * XXX we could handle this in most cases, but we would have to - * push the extra memory down to after our max possible cluster - * size and then potentially pull it back up if the cluster was - * terminated prematurely--too much hassle. - */ - if (bp->b_bcount != bp->b_bufsize) { - ++start_lbn; - --len; - bawrite(bp); - goto redo; - } - - --len; - b_save = malloc(sizeof(struct buf *) * len + sizeof(struct cluster_save), - M_SEGMENT, M_WAITOK); - b_save->bs_bcount = bp->b_bcount; - b_save->bs_bufsize = bp->b_bufsize; - b_save->bs_nchildren = 0; - b_save->bs_children = (struct buf **)(b_save + 1); - b_save->bs_saveaddr = bp->b_saveaddr; - bp->b_saveaddr = (caddr_t) b_save; - - bp->b_flags |= B_CALL; - bp->b_iodone = cluster_callback; - cp = (char *)bp->b_data + size; - for (++start_lbn, i = 0; i < len; ++i, ++start_lbn) { - /* - * Block is not in core or the non-sequential block - * ending our cluster was part of the cluster (in which - * case we don't want to write it twice). - */ - if (!incore(vp, start_lbn) || - (last_bp == NULL && start_lbn == lbn)) - break; - - /* - * Get the desired block buffer (unless it is the final - * sequential block whose buffer was passed in explictly - * as last_bp). - */ - if (last_bp == NULL || start_lbn != lbn) { - tbp = getblk(vp, start_lbn, size, 0, 0); - if (!(tbp->b_flags & B_DELWRI)) { - brelse(tbp); - break; - } - } else - tbp = last_bp; - - ++b_save->bs_nchildren; - - /* Move memory from children to parent */ - if (tbp->b_blkno != (bp->b_blkno + btodb(bp->b_bufsize))) { - printf("Clustered Block: %d addr %x bufsize: %ld\n", - bp->b_lblkno, bp->b_blkno, bp->b_bufsize); - printf("Child Block: %d addr: %x\n", tbp->b_lblkno, - tbp->b_blkno); - panic("Clustered write to wrong blocks"); - } - - pagemove(tbp->b_data, cp, size); - bp->b_bcount += size; - bp->b_bufsize += size; - - tbp->b_bufsize -= size; - tbp->b_flags &= ~(B_READ | B_DONE | B_ERROR | B_DELWRI); - /* - * We might as well AGE the buffer here; it's either empty, or - * contains data that we couldn't get rid of (but wanted to). - */ - tbp->b_flags |= (B_ASYNC | B_AGE); - s = splbio(); - reassignbuf(tbp, tbp->b_vp); /* put on clean list */ - ++tbp->b_vp->v_numoutput; - splx(s); - b_save->bs_children[i] = tbp; - - cp += size; - } - - if (i == 0) { - /* None to cluster */ - bp->b_saveaddr = b_save->bs_saveaddr; - bp->b_flags &= ~B_CALL; - bp->b_iodone = NULL; - free(b_save, M_SEGMENT); - } - bawrite(bp); - if (i < len) { - len -= i + 1; - start_lbn += 1; - goto redo; - } -} - -/* - * Collect together all the buffers in a cluster. - * Plus add one additional buffer. - */ -struct cluster_save * -cluster_collectbufs(vp, last_bp) - struct vnode *vp; - struct buf *last_bp; -{ - struct cluster_save *buflist; - daddr_t lbn; - int i, len; - - len = vp->v_lastw - vp->v_cstart + 1; - buflist = malloc(sizeof(struct buf *) * (len + 1) + sizeof(*buflist), - M_SEGMENT, M_WAITOK); - buflist->bs_nchildren = 0; - buflist->bs_children = (struct buf **)(buflist + 1); - for (lbn = vp->v_cstart, i = 0; i < len; lbn++, i++) - (void)bread(vp, lbn, last_bp->b_bcount, NOCRED, - &buflist->bs_children[i]); - buflist->bs_children[i] = last_bp; - buflist->bs_nchildren = i + 1; - return (buflist); -} diff --git a/netbsd/sys/lib/libkern/libkern.h b/netbsd/sys/lib/libkern/libkern.h index 2d9a30add1..6fa18e0726 100644 --- a/netbsd/sys/lib/libkern/libkern.h +++ b/netbsd/sys/lib/libkern/libkern.h @@ -1,4 +1,4 @@ -/* $NetBSD: libkern.h,v 1.39 2001/12/28 07:37:06 thorpej Exp $ */ +/* $NetBSD: libkern.h,v 1.39.10.2 2002/12/03 22:11:07 he Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -286,8 +286,13 @@ int strncmp __P((const char *, const char *, size_t)); char *strchr __P((const char *, int)); char *strrchr __P((const char *, int)); -/* This exists in GCC 3.x, but we don't bother (yet). */ +/* + * ffs is an instruction on vax. + */ int ffs __P((int)); +#if __GNUC_PREREQ__(2, 95) && !defined(__vax__) +#define ffs(x) __builtin_ffs(x) +#endif void __assert __P((const char *, const char *, int, const char *)) __attribute__((__noreturn__)); diff --git a/netbsd/sys/net/Makefile b/netbsd/sys/net/Makefile index faba3bfdba..f10d778dba 100644 --- a/netbsd/sys/net/Makefile +++ b/netbsd/sys/net/Makefile @@ -12,6 +12,6 @@ INCS= bpf.h bpfdesc.h dlt.h ethertypes.h if.h if_arc.h if_arp.h \ raw_cb.h route.h slcompress.h slip.h zlib.h INCS+= radix_art.h radix_mpath.h INCS+= if_hif.h -INCS+= if_vrrp_var.h +INCS+= if_vrrp_var.h .include diff --git a/netbsd/sys/net/if.c b/netbsd/sys/net/if.c index 910f232a86..6a4b060256 100644 --- a/netbsd/sys/net/if.c +++ b/netbsd/sys/net/if.c @@ -1,4 +1,4 @@ -/* $NetBSD: if.c,v 1.104 2002/05/12 20:40:11 matt Exp $ */ +/* $NetBSD: if.c,v 1.104.4.1 2002/11/01 10:56:17 tron Exp $ */ /*- * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc. @@ -101,7 +101,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.104 2002/05/12 20:40:11 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.104.4.1 2002/11/01 10:56:17 tron Exp $"); #include "opt_inet.h" @@ -1274,6 +1274,28 @@ ifunit(name) const char *name; { struct ifnet *ifp; + const char *cp = name; + u_int unit = 0; + u_int i; + + /* + * If the entire name is a number, treat it as an ifindex. + */ + for (i = 0; i < IFNAMSIZ && *cp >= '0' && *cp <= '9'; i++, cp++) { + unit = unit * 10 + (*cp - '0'); + } + + /* + * If the number took all of the name, then it's a valid ifindex. + */ + if (i == IFNAMSIZ || (cp != name && *cp == '\0')) { + if (unit >= if_index) + return (NULL); + ifp = ifindex2ifnet[unit]; + if (ifp == NULL || ifp->if_output == if_nulloutput) + return (NULL); + return (ifp); + } for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; ifp = TAILQ_NEXT(ifp, if_list)) { @@ -1298,6 +1320,7 @@ ifioctl(so, cmd, data, p) struct ifnet *ifp; struct ifreq *ifr; struct ifcapreq *ifcr; + struct ifdatareq *ifdr; int s, error = 0; short oif_flags; @@ -1309,6 +1332,7 @@ ifioctl(so, cmd, data, p) } ifr = (struct ifreq *)data; ifcr = (struct ifcapreq *)data; + ifdr = (struct ifdatareq *)data; switch (cmd) { case SIOCIFCREATE: @@ -1433,6 +1457,22 @@ ifioctl(so, cmd, data, p) ifp->if_metric = ifr->ifr_metric; break; + case SIOCGIFDATA: + ifdr->ifdr_data = ifp->if_data; + break; + + case SIOCZIFDATA: + if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) + return (error); + ifdr->ifdr_data = ifp->if_data; + /* + * Assumes that the volatile counters that can be + * zero'ed are at the end of if_data. + */ + memset(&ifp->if_data.ifi_ipackets, 0, sizeof(ifp->if_data) - + offsetof(struct if_data, ifi_ipackets)); + break; + case SIOCSIFMTU: { u_long oldmtu = ifp->if_mtu; diff --git a/netbsd/sys/net/if.h b/netbsd/sys/net/if.h index b8c338bb0a..3be555d181 100644 --- a/netbsd/sys/net/if.h +++ b/netbsd/sys/net/if.h @@ -1,4 +1,4 @@ -/* $NetBSD: if.h,v 1.75 2002/03/17 10:21:42 simonb Exp $ */ +/* $NetBSD: if.h,v 1.75.6.1 2002/11/01 10:56:03 tron Exp $ */ /*- * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc. @@ -533,6 +533,11 @@ struct ifaliasreq { struct sockaddr ifra_mask; }; +struct ifdatareq { + char ifdr_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + struct if_data ifdr_data; +}; + struct ifmediareq { char ifm_name[IFNAMSIZ]; /* if name, e.g. "en0" */ int ifm_current; /* current media options */ diff --git a/netbsd/sys/net/if_atmsubr.c b/netbsd/sys/net/if_atmsubr.c index ec3a320148..6d8027ac1c 100644 --- a/netbsd/sys/net/if_atmsubr.c +++ b/netbsd/sys/net/if_atmsubr.c @@ -200,10 +200,10 @@ atm_output(ifp, m0, dst, rt0) default: #if defined(__NetBSD__) || defined(__OpenBSD__) printf("%s: can't handle af%d\n", ifp->if_xname, - dst->sa_family); + dst->sa_family); #elif defined(__FreeBSD__) || defined(__bsdi__) printf("%s%d: can't handle af%d\n", ifp->if_name, - ifp->if_unit, dst->sa_family); + ifp->if_unit, dst->sa_family); #endif senderr(EAFNOSUPPORT); } diff --git a/netbsd/sys/net/if_ethersubr.c b/netbsd/sys/net/if_ethersubr.c index b6972419b8..f75cef08b3 100644 --- a/netbsd/sys/net/if_ethersubr.c +++ b/netbsd/sys/net/if_ethersubr.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_ethersubr.c,v 1.95 2002/05/18 22:52:44 itojun Exp $ */ +/* $NetBSD: if_ethersubr.c,v 1.95.2.2 2003/01/26 10:32:57 jmc Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -65,7 +65,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.95 2002/05/18 22:52:44 itojun Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.95.2.2 2003/01/26 10:32:57 jmc Exp $"); #include "opt_inet.h" #include "opt_atalk.h" @@ -105,9 +105,9 @@ __KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.95 2002/05/18 22:52:44 itojun Exp #if NARP == 0 /* - * XXX there should realy be a way to issue this warning from within config(8) + * XXX there should really be a way to issue this warning from within config(8) */ -#error You have included a pseudo-device in your configuration that depends on the presence of ethernet interfaces, but have no such interfaces configured. Check if you realy need pseudo-device bridge, ppppoe or vlan. +#error You have included a pseudo-device in your configuration that depends on the presence of ethernet interfaces, but have no such interfaces configured. Check if you really need pseudo-device bridge, ppppoe or vlan. #endif #if NBPFILTER > 0 @@ -484,8 +484,21 @@ ether_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst, if (m == 0) senderr(ENOBUFS); eh = mtod(m, struct ether_header *); - bcopy((caddr_t)&etype,(caddr_t)&eh->ether_type, - sizeof(eh->ether_type)); + /* Note: etype is already in network byte order. */ +#ifdef __NO_STRICT_ALIGNMENT + eh->ether_type = etype; +#else + { + uint8_t *dstp = (uint8_t *) &eh->ether_type; +#if BYTE_ORDER == BIG_ENDIAN + dstp[0] = etype >> 8; + dstp[1] = etype; +#else + dstp[0] = etype; + dstp[1] = etype >> 8; +#endif /* BYTE_ORDER == BIG_ENDIAN */ + } +#endif /* __NO_STRICT_ALIGNMENT */ bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst)); if (hdrcmplt) bcopy((caddr_t)esrc, (caddr_t)eh->ether_shost, diff --git a/netbsd/sys/net/if_spppsubr.c b/netbsd/sys/net/if_spppsubr.c index 2445f8a0a7..a88814f7df 100644 --- a/netbsd/sys/net/if_spppsubr.c +++ b/netbsd/sys/net/if_spppsubr.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_spppsubr.c,v 1.46.4.4 2002/08/17 05:49:31 lukem Exp $ */ +/* $NetBSD: if_spppsubr.c,v 1.46.4.17 2003/02/07 18:40:19 tron Exp $ */ /* * Synchronous PPP/Cisco link level subroutines. @@ -13,12 +13,25 @@ * RFC2472 IPv6CP support. * Copyright (C) 2000, Jun-ichiro itojun Hagino . * - * This software is distributed with NO WARRANTIES, not even the implied - * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. * - * Authors grant any other persons or organisations permission to use - * or modify this software as long as this message is kept with the software, - * all derivative works or modified versions. + * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * * From: Version 2.4, Thu Apr 30 17:17:21 MSD 1997 * @@ -28,7 +41,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.46.4.4 2002/08/17 05:49:31 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.46.4.17 2003/02/07 18:40:19 tron Exp $"); #include "opt_inet.h" #include "opt_ipx.h" @@ -46,6 +59,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.46.4.4 2002/08/17 05:49:31 lukem E #include #include #include +#include #include #include @@ -84,7 +98,8 @@ __KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.46.4.4 2002/08/17 05:49:31 lukem E #include #include -#define MAXALIVECNT 3 /* max. alive packets */ +#define LCP_KEEPALIVE_INTERVAL 10 /* seconds */ +#define MAXALIVECNT 3 /* max. missed alive packets */ #define DEFAULT_MAX_AUTH_FAILURES 5 /* max. auth. failures */ /* @@ -251,7 +266,7 @@ static u_short interactive_ports[8] = { 0, 513, 0, 0, 0, 21, 0, 23, }; -#define INTERACTIVE(p) (interactive_ports[(p) & 7] == (p)) +#define INTERACTIVE(p) (interactive_ports[(p) & 7] == (p)) #endif /* almost every function needs these */ @@ -472,7 +487,7 @@ sppp_input(struct ifnet *ifp, struct mbuf *m) drop: ++ifp->if_ierrors; ++ifp->if_iqdrops; - m_freem (m); + m_freem(m); return; } @@ -483,8 +498,8 @@ sppp_input(struct ifnet *ifp, struct mbuf *m) } else { /* Get PPP header. */ - h = mtod (m, struct ppp_header*); - m_adj (m, PPP_HEADER_LEN); + h = mtod(m, struct ppp_header *); + m_adj(m, PPP_HEADER_LEN); switch (h->address) { case PPP_ALLSTATIONS: @@ -512,35 +527,35 @@ sppp_input(struct ifnet *ifp, struct mbuf *m) h->address, h->control, ntohs(h->protocol)); goto drop; } - switch (ntohs (h->protocol)) { + switch (ntohs(h->protocol)) { default: ++ifp->if_noproto; goto invalid; case CISCO_KEEPALIVE: - sppp_cisco_input ((struct sppp*) ifp, m); - m_freem (m); + sppp_cisco_input((struct sppp *) ifp, m); + m_freem(m); return; #ifdef INET case ETHERTYPE_IP: - schednetisr (NETISR_IP); + schednetisr(NETISR_IP); inq = &ipintrq; break; #endif #ifdef INET6 case ETHERTYPE_IPV6: - schednetisr (NETISR_IPV6); + schednetisr(NETISR_IPV6); inq = &ip6intrq; break; #endif #ifdef IPX case ETHERTYPE_IPX: - schednetisr (NETISR_IPX); + schednetisr(NETISR_IPX); inq = &ipxintrq; break; #endif #ifdef NS case ETHERTYPE_NS: - schednetisr (NETISR_NS); + schednetisr(NETISR_NS); inq = &nsintrq; break; #endif @@ -556,14 +571,14 @@ sppp_input(struct ifnet *ifp, struct mbuf *m) h->address, h->control, ntohs(h->protocol)); goto drop; } - protocol = ntohs (h->protocol); + protocol = ntohs(h->protocol); } switch (protocol) { default: if (sp->state[IDX_LCP] == STATE_OPENED) { u_int16_t prot = htons(protocol); - sppp_cp_send (sp, PPP_LCP, PROTO_REJ, + sppp_cp_send(sp, PPP_LCP, PROTO_REJ, ++sp->pp_seq[IDX_LCP], m->m_pkthdr.len + 2, &prot); } @@ -575,29 +590,29 @@ sppp_input(struct ifnet *ifp, struct mbuf *m) goto drop; case PPP_LCP: sppp_cp_input(&lcp, sp, m); - m_freem (m); + m_freem(m); return; case PPP_PAP: if (sp->pp_phase >= SPPP_PHASE_AUTHENTICATE) sppp_pap_input(sp, m); - m_freem (m); + m_freem(m); return; case PPP_CHAP: if (sp->pp_phase >= SPPP_PHASE_AUTHENTICATE) sppp_chap_input(sp, m); - m_freem (m); + m_freem(m); return; #ifdef INET case PPP_IPCP: if (sp->pp_phase == SPPP_PHASE_NETWORK) sppp_cp_input(&ipcp, sp, m); - m_freem (m); + m_freem(m); return; case PPP_IP: if (sp->state[IDX_IPCP] == STATE_OPENED) { - schednetisr (NETISR_IP); + schednetisr(NETISR_IP); inq = &ipintrq; - sp->pp_last_activity = time.tv_sec; + sp->pp_last_activity = mono_time.tv_sec; } break; #endif @@ -605,14 +620,14 @@ sppp_input(struct ifnet *ifp, struct mbuf *m) case PPP_IPV6CP: if (sp->pp_phase == SPPP_PHASE_NETWORK) sppp_cp_input(&ipv6cp, sp, m); - m_freem (m); + m_freem(m); return; case PPP_IPV6: if (sp->state[IDX_IPV6CP] == STATE_OPENED) { - schednetisr (NETISR_IPV6); + schednetisr(NETISR_IPV6); inq = &ip6intrq; - sp->pp_last_activity = time.tv_sec; + sp->pp_last_activity = mono_time.tv_sec; } break; #endif @@ -620,7 +635,7 @@ sppp_input(struct ifnet *ifp, struct mbuf *m) case PPP_IPX: /* IPX IPXCP not implemented yet */ if (sp->pp_phase == SPPP_PHASE_NETWORK) { - schednetisr (NETISR_IPX); + schednetisr(NETISR_IPX); inq = &ipxintrq; } break; @@ -629,7 +644,7 @@ sppp_input(struct ifnet *ifp, struct mbuf *m) case PPP_XNS: /* XNS IDPCP not implemented yet */ if (sp->pp_phase == SPPP_PHASE_NETWORK) { - schednetisr (NETISR_NS); + schednetisr(NETISR_NS); inq = &nsintrq; } break; @@ -638,7 +653,7 @@ sppp_input(struct ifnet *ifp, struct mbuf *m) case PPP_ISO: /* OSI NLCP not implemented yet */ if (sp->pp_phase == SPPP_PHASE_NETWORK) { - schednetisr (NETISR_ISO); + schednetisr(NETISR_ISO); inq = &clnlintrq; } break; @@ -651,7 +666,7 @@ sppp_input(struct ifnet *ifp, struct mbuf *m) /* Check queue. */ s = splnet(); - if (IF_QFULL (inq)) { + if (IF_QFULL(inq)) { /* Queue overflow. */ IF_DROP(inq); splx(s); @@ -671,7 +686,7 @@ static int sppp_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct rtentry *rt) { - struct sppp *sp = (struct sppp*) ifp; + struct sppp *sp = (struct sppp *) ifp; struct ppp_header *h = NULL; struct ifqueue *ifq = NULL; /* XXX */ int s, len, rv = 0; @@ -680,12 +695,12 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, s = splnet(); - sp->pp_last_activity = time.tv_sec; + sp->pp_last_activity = mono_time.tv_sec; if ((ifp->if_flags & IFF_UP) == 0 || (ifp->if_flags & (IFF_RUNNING | IFF_AUTO)) == 0) { - m_freem (m); - splx (s); + m_freem(m); + splx(s); return (ENETDOWN); } @@ -707,11 +722,20 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr); #ifdef INET - if (dst->sa_family == AF_INET) - { - /* Check mbuf length here??? */ - struct ip *ip = mtod (m, struct ip*); - struct tcphdr *tcp = (struct tcphdr*) ((int32_t*)ip + ip->ip_hl); + if (dst->sa_family == AF_INET) { + struct ip *ip = NULL; + struct tcphdr *th = NULL; + + if (m->m_len >= sizeof(struct ip)) { + ip = mtod(m, struct ip *); + if (ip->ip_p == IPPROTO_TCP && + m->m_len >= sizeof(struct ip) + (ip->ip_hl << 2) + + sizeof(struct tcphdr)) { + th = (struct tcphdr *) + ((caddr_t)ip + (ip->ip_hl << 2)); + } + } else + ip = NULL; /* * When using dynamic local IP address assignment by using @@ -723,15 +747,15 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, * - don't let packets with src ip addr 0 thru * - we flag TCP packets with src ip 0 as an error */ + if (ip && ip->ip_src.s_addr == INADDR_ANY) { + u_int8_t proto = ip->ip_p; - if(ip->ip_src.s_addr == INADDR_ANY) /* -hm */ - { m_freem(m); splx(s); - if(ip->ip_p == IPPROTO_TCP) - return(EADDRNOTAVAIL); + if (proto == IPPROTO_TCP) + return (EADDRNOTAVAIL); else - return(0); + return (0); } /* @@ -739,12 +763,10 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, * in front of the queue. */ - if (! IF_QFULL (&sp->pp_fastq) && - ((ip->ip_tos & IPTOS_LOWDELAY) || - ((ip->ip_p == IPPROTO_TCP && - m->m_len >= sizeof (struct ip) + sizeof (struct tcphdr) && - (INTERACTIVE (ntohs (tcp->th_sport)))) || - INTERACTIVE (ntohs (tcp->th_dport))))) + if (!IF_QFULL(&sp->pp_fastq) && + ((ip && (ip->ip_tos & IPTOS_LOWDELAY)) || + (th && (INTERACTIVE(ntohs(th->th_sport)) || + INTERACTIVE(ntohs(th->th_dport)))))) ifq = &sp->pp_fastq; } #endif @@ -759,20 +781,20 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, /* * Prepend general data packet PPP header. For now, IP only. */ - M_PREPEND (m, PPP_HEADER_LEN, M_DONTWAIT); + M_PREPEND(m, PPP_HEADER_LEN, M_DONTWAIT); if (! m) { if (ifp->if_flags & IFF_DEBUG) log(LOG_DEBUG, SPP_FMT "no memory for transmit header\n", SPP_ARGS(ifp)); ++ifp->if_oerrors; - splx (s); + splx(s); return (ENOBUFS); } /* * May want to check size of packet * (albeit due to the implementation it's always enough) */ - h = mtod (m, struct ppp_header*); + h = mtod(m, struct ppp_header *); if (sp->pp_flags & PP_CISCO) { h->address = CISCO_UNICAST; /* unicast address */ h->control = 0; @@ -786,7 +808,7 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, #ifdef INET case AF_INET: /* Internet Protocol */ if (sp->pp_flags & PP_CISCO) - protocol = htons (ETHERTYPE_IP); + protocol = htons(ETHERTYPE_IP); else { /* * Don't choke with an ENETDOWN early. It's @@ -806,7 +828,7 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, #ifdef INET6 case AF_INET6: /* Internet Protocol version 6 */ if (sp->pp_flags & PP_CISCO) - protocol = htons (ETHERTYPE_IPV6); + protocol = htons(ETHERTYPE_IPV6); else { /* * Don't choke with an ENETDOWN early. It's @@ -825,13 +847,13 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, #endif #ifdef NS case AF_NS: /* Xerox NS Protocol */ - protocol = htons ((sp->pp_flags & PP_CISCO) ? + protocol = htons((sp->pp_flags & PP_CISCO) ? ETHERTYPE_NS : PPP_XNS); break; #endif #ifdef IPX case AF_IPX: /* Novell IPX Protocol */ - protocol = htons ((sp->pp_flags & PP_CISCO) ? + protocol = htons((sp->pp_flags & PP_CISCO) ? ETHERTYPE_IPX : PPP_IPX); break; #endif @@ -839,28 +861,28 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, case AF_ISO: /* ISO OSI Protocol */ if (sp->pp_flags & PP_CISCO) goto nosupport; - protocol = htons (PPP_ISO); + protocol = htons(PPP_ISO); break; nosupport: #endif default: - m_freem (m); + m_freem(m); ++ifp->if_oerrors; - splx (s); + splx(s); return (EAFNOSUPPORT); } if (sp->pp_flags & PP_NOFRAMING) { - M_PREPEND (m, 2, M_DONTWAIT); + M_PREPEND(m, 2, M_DONTWAIT); if (m == NULL) { if (ifp->if_flags & IFF_DEBUG) log(LOG_DEBUG, SPP_FMT "no memory for transmit header\n", SPP_ARGS(ifp)); ++ifp->if_oerrors; - splx (s); + splx(s); return (ENOBUFS); } - *mtod(m, u_int16_t*) = protocol; + *mtod(m, u_int16_t *) = protocol; } else { h->protocol = protocol; } @@ -875,13 +897,14 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, && ALTQ_IS_ENABLED(&ifp->if_snd) == 0 #endif ) { - if (IF_QFULL (ifq)) { - IF_DROP (&ifp->if_snd); - m_freem (m); + if (IF_QFULL(ifq)) { + IF_DROP(&ifp->if_snd); + m_freem(m); if (rv == 0) rv = ENOBUFS; } - IF_ENQUEUE(ifq, m); + else + IF_ENQUEUE(ifq, m); } else IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, rv); if (rv != 0) { @@ -891,7 +914,7 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, } if (! (ifp->if_flags & IFF_OACTIVE)) - (*ifp->if_start) (ifp); + (*ifp->if_start)(ifp); /* * Count output packets and bytes. @@ -899,19 +922,19 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, * according to RFC 1333. */ ifp->if_obytes += len + sp->pp_framebytes; - splx (s); + splx(s); return (0); } void sppp_attach(struct ifnet *ifp) { - struct sppp *sp = (struct sppp*) ifp; + struct sppp *sp = (struct sppp *) ifp; /* Initialize keepalive handler. */ if (! spppq) { callout_init(&keepalive_ch); - callout_reset(&keepalive_ch, hz * 10, sppp_keepalive, NULL); + callout_reset(&keepalive_ch, hz * LCP_KEEPALIVE_INTERVAL, sppp_keepalive, NULL); } /* Insert new entry into the keepalive list. */ @@ -948,7 +971,7 @@ sppp_attach(struct ifnet *ifp) void sppp_detach(struct ifnet *ifp) { - struct sppp **q, *p, *sp = (struct sppp*) ifp; + struct sppp **q, *p, *sp = (struct sppp *) ifp; int i; /* Remove the entry from the keepalive list. */ @@ -983,11 +1006,11 @@ sppp_detach(struct ifnet *ifp) void sppp_flush(struct ifnet *ifp) { - struct sppp *sp = (struct sppp*) ifp; + struct sppp *sp = (struct sppp *) ifp; - IFQ_PURGE (&sp->pp_if.if_snd); - IF_PURGE (&sp->pp_fastq); - IF_PURGE (&sp->pp_cpq); + IFQ_PURGE(&sp->pp_if.if_snd); + IF_PURGE(&sp->pp_fastq); + IF_PURGE(&sp->pp_cpq); } /* @@ -996,7 +1019,7 @@ sppp_flush(struct ifnet *ifp) int sppp_isempty(struct ifnet *ifp) { - struct sppp *sp = (struct sppp*) ifp; + struct sppp *sp = (struct sppp *) ifp; int empty, s; s = splnet(); @@ -1012,7 +1035,7 @@ sppp_isempty(struct ifnet *ifp) struct mbuf * sppp_dequeue(struct ifnet *ifp) { - struct sppp *sp = (struct sppp*) ifp; + struct sppp *sp = (struct sppp *) ifp; struct mbuf *m; int s; @@ -1028,7 +1051,7 @@ sppp_dequeue(struct ifnet *ifp) (sppp_ncp_check(sp) || (sp->pp_flags & PP_CISCO) != 0)) { IF_DEQUEUE(&sp->pp_fastq, m); if (m == NULL) - IFQ_DEQUEUE (&sp->pp_if.if_snd, m); + IFQ_DEQUEUE(&sp->pp_if.if_snd, m); } splx(s); return m; @@ -1040,11 +1063,11 @@ sppp_dequeue(struct ifnet *ifp) struct mbuf * sppp_pick(struct ifnet *ifp) { - struct sppp *sp = (struct sppp*)ifp; + struct sppp *sp = (struct sppp *)ifp; struct mbuf *m; int s; - s= splnet (); + s= splnet(); m = sp->pp_cpq.ifq_head; if (m == NULL && @@ -1062,8 +1085,8 @@ sppp_pick(struct ifnet *ifp) int sppp_ioctl(struct ifnet *ifp, u_long cmd, void *data) { - struct ifreq *ifr = (struct ifreq*) data; - struct sppp *sp = (struct sppp*) ifp; + struct ifreq *ifr = (struct ifreq *) data; + struct sppp *sp = (struct sppp *) ifp; int s, error=0, going_up, going_down, newmode; s = splnet(); @@ -1107,16 +1130,23 @@ sppp_ioctl(struct ifnet *ifp, u_long cmd, void *data) #define ifr_mtu ifr_metric #endif case SIOCSIFMTU: - if (ifr->ifr_mtu < 128 || ifr->ifr_mtu > sp->lcp.their_mru) - return (EINVAL); + if (ifr->ifr_mtu < 128 || ifr->ifr_mtu > sp->lcp.their_mru) { + error = EINVAL; + break; + } + ifp->if_mtu = ifr->ifr_mtu; break; #endif #ifdef SLIOCSETMTU case SLIOCSETMTU: - if (*(short*)data < 128 || *(short*)data > sp->lcp.their_mru) - return (EINVAL); - ifp->if_mtu = *(short*)data; + if (*(short *)data < 128 || *(short *)data > sp->lcp.their_mru) + { + error = EINVAL; + break; + } + + ifp->if_mtu = *(short *)data; break; #endif #ifdef SIOCGIFMTU @@ -1126,7 +1156,7 @@ sppp_ioctl(struct ifnet *ifp, u_long cmd, void *data) #endif #ifdef SLIOCGETMTU case SLIOCGETMTU: - *(short*)data = ifp->if_mtu; + *(short *)data = ifp->if_mtu; break; #endif case SIOCADDMULTI: @@ -1184,7 +1214,7 @@ sppp_cisco_input(struct sppp *sp, struct mbuf *m) SPP_ARGS(ifp), m->m_pkthdr.len); return; } - h = mtod (m, struct cisco_packet*); + h = mtod(m, struct cisco_packet *); if (debug) log(LOG_DEBUG, SPP_FMT "cisco input: %d bytes " @@ -1212,8 +1242,8 @@ sppp_cisco_input(struct sppp *sp, struct mbuf *m) SPP_ARGS(ifp)); sp->pp_loopcnt = 0; if (ifp->if_flags & IFF_UP) { - if_down (ifp); - IF_PURGE (&sp->pp_cpq); + if_down(ifp); + IF_PURGE(&sp->pp_cpq); } } ++sp->pp_loopcnt; @@ -1248,25 +1278,25 @@ sppp_cisco_send(struct sppp *sp, int type, int32_t par1, int32_t par2) struct mbuf *m; u_int32_t t = (time.tv_sec - boottime.tv_sec) * 1000; - MGETHDR (m, M_DONTWAIT, MT_DATA); + MGETHDR(m, M_DONTWAIT, MT_DATA); if (! m) return; m->m_pkthdr.len = m->m_len = PPP_HEADER_LEN + CISCO_PACKET_LEN; m->m_pkthdr.rcvif = 0; - h = mtod (m, struct ppp_header*); + h = mtod(m, struct ppp_header *); h->address = CISCO_MULTICAST; h->control = 0; - h->protocol = htons (CISCO_KEEPALIVE); + h->protocol = htons(CISCO_KEEPALIVE); - ch = (struct cisco_packet*) (h + 1); - ch->type = htonl (type); - ch->par1 = htonl (par1); - ch->par2 = htonl (par2); + ch = (struct cisco_packet *)(h + 1); + ch->type = htonl(type); + ch->par1 = htonl(par1); + ch->par2 = htonl(par2); ch->rel = -1; - ch->time0 = htons ((u_short) (t >> 16)); - ch->time1 = htons ((u_short) t); + ch->time0 = htons((u_short)(t >> 16)); + ch->time1 = htons((u_short) t); if (debug) log(LOG_DEBUG, @@ -1275,14 +1305,16 @@ sppp_cisco_send(struct sppp *sp, int type, int32_t par1, int32_t par2) ch->par2, (u_int)ch->rel, (u_int)ch->time0, (u_int)ch->time1); - if (IF_QFULL (&sp->pp_cpq)) { - IF_DROP (&sp->pp_fastq); - IF_DROP (&ifp->if_snd); - m_freem (m); + if (IF_QFULL(&sp->pp_cpq)) { + IF_DROP(&sp->pp_fastq); + IF_DROP(&ifp->if_snd); + m_freem(m); + ++ifp->if_oerrors; + return; } else - IF_ENQUEUE (&sp->pp_cpq, m); + IF_ENQUEUE(&sp->pp_cpq, m); if (! (ifp->if_flags & IFF_OACTIVE)) - (*ifp->if_start) (ifp); + (*ifp->if_start)(ifp); ifp->if_obytes += m->m_pkthdr.len + sp->pp_framebytes; } @@ -1306,48 +1338,48 @@ sppp_cp_send(struct sppp *sp, u_short proto, u_char type, if (len > MHLEN - pkthdrlen - LCP_HEADER_LEN) len = MHLEN - pkthdrlen - LCP_HEADER_LEN; - MGETHDR (m, M_DONTWAIT, MT_DATA); + MGETHDR(m, M_DONTWAIT, MT_DATA); if (! m) return; m->m_pkthdr.len = m->m_len = pkthdrlen + LCP_HEADER_LEN + len; m->m_pkthdr.rcvif = 0; if (sp->pp_flags & PP_NOFRAMING) { - *mtod(m, u_int16_t*) = htons(proto); - lh = (struct lcp_header*)(mtod(m, u_int8_t*) + 2); + *mtod(m, u_int16_t *) = htons(proto); + lh = (struct lcp_header *)(mtod(m, u_int8_t *) + 2); } else { struct ppp_header *h; - h = mtod (m, struct ppp_header*); + h = mtod(m, struct ppp_header *); h->address = PPP_ALLSTATIONS; /* broadcast address */ h->control = PPP_UI; /* Unnumbered Info */ - h->protocol = htons (proto); /* Link Control Protocol */ - lh = (struct lcp_header*) (h + 1); + h->protocol = htons(proto); /* Link Control Protocol */ + lh = (struct lcp_header *)(h + 1); } lh->type = type; lh->ident = ident; - lh->len = htons (LCP_HEADER_LEN + len); + lh->len = htons(LCP_HEADER_LEN + len); if (len) - bcopy (data, lh+1, len); + bcopy (data, lh + 1, len); if (debug) { log(LOG_DEBUG, SPP_FMT "%s output <%s id=0x%x len=%d", SPP_ARGS(ifp), sppp_proto_name(proto), - sppp_cp_type_name (lh->type), lh->ident, - ntohs (lh->len)); + sppp_cp_type_name(lh->type), lh->ident, ntohs(lh->len)); if (len) - sppp_print_bytes ((u_char*) (lh+1), len); + sppp_print_bytes((u_char *)(lh + 1), len); addlog(">\n"); } - if (IF_QFULL (&sp->pp_cpq)) { - IF_DROP (&sp->pp_fastq); - IF_DROP (&ifp->if_snd); - m_freem (m); + if (IF_QFULL(&sp->pp_cpq)) { + IF_DROP(&sp->pp_fastq); + IF_DROP(&ifp->if_snd); + m_freem(m); ++ifp->if_oerrors; + return; } else - IF_ENQUEUE (&sp->pp_cpq, m); + IF_ENQUEUE(&sp->pp_cpq, m); if (! (ifp->if_flags & IFF_OACTIVE)) - (*ifp->if_start) (ifp); + (*ifp->if_start)(ifp); ifp->if_obytes += m->m_pkthdr.len + sp->pp_framebytes; } @@ -1371,19 +1403,19 @@ sppp_cp_input(const struct cp *cp, struct sppp *sp, struct mbuf *m) SPP_ARGS(ifp), cp->name, len); return; } - h = mtod (m, struct lcp_header*); + h = mtod(m, struct lcp_header *); if (debug) { log(LOG_DEBUG, SPP_FMT "%s input(%s): <%s id=0x%x len=%d", SPP_ARGS(ifp), cp->name, sppp_state_name(sp->state[cp->protoidx]), - sppp_cp_type_name (h->type), h->ident, ntohs (h->len)); + sppp_cp_type_name(h->type), h->ident, ntohs(h->len)); if (len > 4) - sppp_print_bytes ((u_char*) (h+1), len-4); + sppp_print_bytes((u_char *)(h + 1), len - 4); addlog(">\n"); } - if (len > ntohs (h->len)) - len = ntohs (h->len); + if (len > ntohs(h->len)) + len = ntohs(h->len); p = (u_char *)(h + 1); switch (h->type) { case CONF_REQ: @@ -1552,7 +1584,6 @@ sppp_cp_input(const struct cp *cp, struct sppp *sp, struct mbuf *m) sp->rst_counter[cp->protoidx] = 0; sppp_cp_change_state(cp, sp, STATE_STOPPING); goto sta; - break; default: printf(SPP_FMT "%s illegal %s in state %s\n", SPP_ARGS(ifp), cp->name, @@ -1707,8 +1738,8 @@ sppp_cp_input(const struct cp *cp, struct sppp *sp, struct mbuf *m) if (ntohl(u32) == sp->lcp.magic) { /* Line loopback mode detected. */ printf(SPP_FMT "loopback\n", SPP_ARGS(ifp)); - if_down (ifp); - IF_PURGE (&sp->pp_cpq); + if_down(ifp); + IF_PURGE(&sp->pp_cpq); /* Shut down the PPP link. */ /* XXX */ @@ -1721,7 +1752,8 @@ sppp_cp_input(const struct cp *cp, struct sppp *sp, struct mbuf *m) if (debug) addlog(SPP_FMT "got lcp echo req, sending echo rep\n", SPP_ARGS(ifp)); - sppp_cp_send (sp, PPP_LCP, ECHO_REPLY, h->ident, len-4, h+1); + sppp_cp_send(sp, PPP_LCP, ECHO_REPLY, h->ident, len - 4, + h + 1); break; case ECHO_REPLY: if (cp->proto != PPP_LCP) @@ -2024,7 +2056,7 @@ sppp_lcp_up(struct sppp *sp) STDDCL; /* Initialize activity timestamp: opening a connection is an activity */ - sp->pp_last_activity = time.tv_sec; + sp->pp_last_activity = mono_time.tv_sec; /* * If this interface is passive or dial-on-demand, and we are @@ -2136,7 +2168,7 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len) SPP_ARGS(ifp)); /* pass 1: check for things that need to be rejected */ - p = (void*) (h+1); + p = (void *)(h + 1); for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) { if (debug) addlog(" %s", sppp_lcp_opt_name(*p)); @@ -2197,7 +2229,7 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len) if (rlen) { if (debug) addlog(" send conf-rej\n"); - sppp_cp_send (sp, PPP_LCP, CONF_REJ, h->ident, rlen, buf); + sppp_cp_send(sp, PPP_LCP, CONF_REJ, h->ident, rlen, buf); goto end; } else if (debug) addlog("\n"); @@ -2210,7 +2242,7 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len) log(LOG_DEBUG, SPP_FMT "lcp parse opt values: ", SPP_ARGS(ifp)); - p = (void*) (h+1); + p = (void *)(h + 1); len = origlen; for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) { if (debug) @@ -2256,21 +2288,21 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len) break; case LCP_OPT_ASYNC_MAP: - /* Async control character map -- check to be zero. */ - if (! p[2] && ! p[3] && ! p[4] && ! p[5]) { - if (debug) - addlog(" [empty]"); - continue; - } - if (debug) - addlog(" [non-empty]"); - /* suggest a zero one */ -#ifndef BROKEN_98 /* XXX - broken Win98 drivers INSIST on having an ASYNC_MAP */ - p[2] = p[3] = p[4] = p[5] = 0; - break; -#else + /* + * Async control character map -- just ignore it. + * + * Quote from RFC 1662, chapter 6: + * To enable this functionality, synchronous PPP + * implementations MUST always respond to the + * Async-Control-Character-Map Configuration + * Option with the LCP Configure-Ack. However, + * acceptance of the Configuration Option does + * not imply that the synchronous implementation + * will do any ACCM mapping. Instead, all such + * octet mapping will be performed by the + * asynchronous-to-synchronous converter. + */ continue; -#endif case LCP_OPT_MRU: /* @@ -2317,7 +2349,7 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len) } else { if (debug) addlog(" send conf-nak\n"); - sppp_cp_send (sp, PPP_LCP, CONF_NAK, h->ident, rlen, buf); + sppp_cp_send(sp, PPP_LCP, CONF_NAK, h->ident, rlen, buf); } goto end; } else { @@ -2325,12 +2357,11 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len) addlog(" send conf-ack\n"); sp->fail_counter[IDX_LCP] = 0; sp->pp_loopcnt = 0; - sppp_cp_send (sp, PPP_LCP, CONF_ACK, - h->ident, origlen, h+1); + sppp_cp_send(sp, PPP_LCP, CONF_ACK, h->ident, origlen, h + 1); } end: - free (buf, M_TEMP); + free(buf, M_TEMP); return (rlen == 0); } @@ -2353,7 +2384,7 @@ sppp_lcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len) log(LOG_DEBUG, SPP_FMT "lcp rej opts:", SPP_ARGS(ifp)); - p = (void*) (h+1); + p = (void *)(h + 1); for (; len > 1 && p[1]; len -= p[1], p += p[1]) { if (debug) addlog(" %s", sppp_lcp_opt_name(*p)); @@ -2393,7 +2424,7 @@ sppp_lcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len) } if (debug) addlog("\n"); - free (buf, M_TEMP); + free(buf, M_TEMP); return; } @@ -2417,7 +2448,7 @@ sppp_lcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len) log(LOG_DEBUG, SPP_FMT "lcp nak opts:", SPP_ARGS(ifp)); - p = (void*) (h+1); + p = (void *)(h + 1); for (; len > 1 && p[1]; len -= p[1], p += p[1]) { if (debug) addlog(" %s", sppp_lcp_opt_name(*p)); @@ -2473,7 +2504,7 @@ sppp_lcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len) } if (debug) addlog("\n"); - free (buf, M_TEMP); + free(buf, M_TEMP); return; } @@ -2646,7 +2677,7 @@ sppp_lcp_scr(struct sppp *sp) } sp->confid[IDX_LCP] = ++sp->pp_seq[IDX_LCP]; - sppp_cp_send (sp, PPP_LCP, CONF_REQ, sp->confid[IDX_LCP], i, &opt); + sppp_cp_send(sp, PPP_LCP, CONF_REQ, sp->confid[IDX_LCP], i, &opt); } /* @@ -2761,12 +2792,23 @@ sppp_ipcp_open(struct sppp *sp) static void sppp_ipcp_close(struct sppp *sp) { + STDDCL; + sppp_close_event(&ipcp, sp); if (sp->ipcp.flags & (IPCP_MYADDR_DYN|IPCP_HISADDR_DYN)) /* * Some address was dynamic, clear it again. */ sppp_clear_ip_addrs(sp); + + if (sp->pp_saved_mtu > 0) { + ifp->if_mtu = sp->pp_saved_mtu; + sp->pp_saved_mtu = 0; + if (debug) + log(LOG_DEBUG, + SPP_FMT "resetting MTU to %" PRIu64 " bytes\n", + SPP_ARGS(ifp), ifp->if_mtu); + } } static void @@ -2803,7 +2845,7 @@ sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len) if (debug) log(LOG_DEBUG, SPP_FMT "ipcp parse opts:", SPP_ARGS(ifp)); - p = (void*) (h+1); + p = (void *)(h + 1); for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) { if (debug) addlog(" %s", sppp_ipcp_opt_name(*p)); @@ -2840,7 +2882,7 @@ sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len) if (rlen) { if (debug) addlog(" send conf-rej\n"); - sppp_cp_send (sp, PPP_IPCP, CONF_REJ, h->ident, rlen, buf); + sppp_cp_send(sp, PPP_IPCP, CONF_REJ, h->ident, rlen, buf); goto end; } else if (debug) addlog("\n"); @@ -2853,7 +2895,7 @@ sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len) if (debug) log(LOG_DEBUG, SPP_FMT "ipcp parse opt values: ", SPP_ARGS(ifp)); - p = (void*) (h+1); + p = (void *)(h + 1); len = origlen; for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) { if (debug) @@ -2934,16 +2976,15 @@ sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len) if (rlen) { if (debug) addlog(" send conf-nak\n"); - sppp_cp_send (sp, PPP_IPCP, CONF_NAK, h->ident, rlen, buf); + sppp_cp_send(sp, PPP_IPCP, CONF_NAK, h->ident, rlen, buf); } else { if (debug) addlog(" send conf-ack\n"); - sppp_cp_send (sp, PPP_IPCP, CONF_ACK, - h->ident, origlen, h+1); + sppp_cp_send(sp, PPP_IPCP, CONF_ACK, h->ident, origlen, h + 1); } end: - free (buf, M_TEMP); + free(buf, M_TEMP); return (rlen == 0); } @@ -2967,7 +3008,7 @@ sppp_ipcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len) log(LOG_DEBUG, SPP_FMT "ipcp rej opts:", SPP_ARGS(ifp)); - p = (void*) (h+1); + p = (void *)(h + 1); for (; len > 1 && p[1]; len -= p[1], p += p[1]) { if (debug) addlog(" %s", sppp_ipcp_opt_name(*p)); @@ -2988,7 +3029,7 @@ sppp_ipcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len) } if (debug) addlog("\n"); - free (buf, M_TEMP); + free(buf, M_TEMP); return; } @@ -3010,7 +3051,7 @@ sppp_ipcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len) log(LOG_DEBUG, SPP_FMT "ipcp nak opts:", SPP_ARGS(ifp)); - p = (void*) (h+1); + p = (void *)(h + 1); for (; len > 1 && p[1]; len -= p[1], p += p[1]) { if (debug) addlog(" %s", sppp_ipcp_opt_name(*p)); @@ -3074,13 +3115,25 @@ static void sppp_ipcp_tlu(struct sppp *sp) { /* we are up. Set addresses and notify anyone interested */ + STDDCL; u_int32_t myaddr, hisaddr; + sppp_get_ip_addrs(sp, &myaddr, &hisaddr, 0); if ((sp->ipcp.flags & IPCP_MYADDR_DYN) && (sp->ipcp.flags & IPCP_MYADDR_SEEN)) myaddr = sp->ipcp.req_myaddr; if ((sp->ipcp.flags & IPCP_HISADDR_DYN) && (sp->ipcp.flags & IPCP_HISADDR_SEEN)) hisaddr = sp->ipcp.req_hisaddr; sppp_set_ip_addrs(sp, myaddr, hisaddr); + + if (ifp->if_mtu > sp->lcp.their_mru) { + sp->pp_saved_mtu = ifp->if_mtu; + ifp->if_mtu = sp->lcp.their_mru; + if (debug) + log(LOG_DEBUG, + SPP_FMT "setting MTU to %" PRIu64 " bytes\n", + SPP_ARGS(ifp), ifp->if_mtu); + } + if (sp->pp_con) sp->pp_con(sp); } @@ -3265,7 +3318,7 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len) if (debug) log(LOG_DEBUG, SPP_FMT "ipv6cp parse opts:", SPP_ARGS(ifp)); - p = (void*) (h+1); + p = (void *)(h + 1); ifidcount = 0; for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) { if (debug) @@ -3304,7 +3357,7 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len) if (rlen) { if (debug) addlog(" send conf-rej\n"); - sppp_cp_send (sp, PPP_IPV6CP, CONF_REJ, h->ident, rlen, buf); + sppp_cp_send(sp, PPP_IPV6CP, CONF_REJ, h->ident, rlen, buf); goto end; } else if (debug) addlog("\n"); @@ -3314,7 +3367,7 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len) if (debug) log(LOG_DEBUG, SPP_FMT "ipv6cp parse opt values: ", SPP_ARGS(ifp)); - p = (void*) (h+1); + p = (void *)(h + 1); len = origlen; type = CONF_ACK; for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) { @@ -3376,9 +3429,9 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len) if (rlen == 0 && type == CONF_ACK) { if (debug) addlog(" send %s\n", sppp_cp_type_name(type)); - sppp_cp_send (sp, PPP_IPV6CP, type, h->ident, origlen, h+1); + sppp_cp_send(sp, PPP_IPV6CP, type, h->ident, origlen, h + 1); } else { -#ifdef DIAGNOSTIC +#ifdef notdef if (type == CONF_ACK) panic("IPv6CP RCR: CONF_ACK with non-zero rlen"); #endif @@ -3387,11 +3440,11 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len) addlog(" send %s suggest %s\n", sppp_cp_type_name(type), ip6_sprintf(&suggestaddr)); } - sppp_cp_send (sp, PPP_IPV6CP, type, h->ident, rlen, buf); + sppp_cp_send(sp, PPP_IPV6CP, type, h->ident, rlen, buf); } end: - free (buf, M_TEMP); + free(buf, M_TEMP); return (rlen == 0); } @@ -3415,7 +3468,7 @@ sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len) log(LOG_DEBUG, SPP_FMT "ipv6cp rej opts:", SPP_ARGS(ifp)); - p = (void*) (h+1); + p = (void *)(h + 1); for (; len > 1 && p[1]; len -= p[1], p += p[1]) { if (debug) addlog(" %s", sppp_ipv6cp_opt_name(*p)); @@ -3436,7 +3489,7 @@ sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len) } if (debug) addlog("\n"); - free (buf, M_TEMP); + free(buf, M_TEMP); return; } @@ -3461,7 +3514,7 @@ sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len) log(LOG_DEBUG, SPP_FMT "ipv6cp nak opts:", SPP_ARGS(ifp)); - p = (void*) (h+1); + p = (void *)(h + 1); for (; len > 1 && p[1]; len -= p[1], p += p[1]) { if (debug) addlog(" %s", sppp_ipv6cp_opt_name(*p)); @@ -3533,7 +3586,7 @@ sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len) } if (debug) addlog("\n"); - free (buf, M_TEMP); + free(buf, M_TEMP); return; } @@ -3759,9 +3812,9 @@ sppp_chap_input(struct sppp *sp, struct mbuf *m) SPP_ARGS(ifp), len); return; } - h = mtod (m, struct lcp_header*); - if (len > ntohs (h->len)) - len = ntohs (h->len); + h = mtod(m, struct lcp_header *); + if (len > ntohs(h->len)) + len = ntohs(h->len); switch (h->type) { /* challenge, failure and success are his authproto */ @@ -3773,7 +3826,7 @@ sppp_chap_input(struct sppp *sp, struct mbuf *m) SPP_ARGS(ifp)); break; } - value = 1 + (u_char*)(h+1); + value = 1 + (u_char *)(h + 1); value_len = value[-1]; name = value + value_len; name_len = len - value_len - 5; @@ -3786,7 +3839,8 @@ sppp_chap_input(struct sppp *sp, struct mbuf *m) sppp_auth_type_name(PPP_CHAP, h->type), h->ident, ntohs(h->len)); if (len > 4) - sppp_print_bytes((u_char*) (h+1), len-4); + sppp_print_bytes((u_char *)(h + 1), + len - 4); addlog(">\n"); } break; @@ -3798,7 +3852,7 @@ sppp_chap_input(struct sppp *sp, struct mbuf *m) SPP_ARGS(ifp), sppp_auth_type_name(PPP_CHAP, h->type), h->ident, ntohs(h->len)); - sppp_print_string((char*) name, name_len); + sppp_print_string((char *) name, name_len); addlog(" value-size=%d value=", value_len); sppp_print_bytes(value, value_len); addlog(">\n"); @@ -3826,7 +3880,7 @@ sppp_chap_input(struct sppp *sp, struct mbuf *m) SPP_ARGS(ifp)); if (len > 4) { addlog(": "); - sppp_print_string((char*)(h + 1), len - 4); + sppp_print_string((char *)(h + 1), len - 4); } addlog("\n"); } @@ -3857,7 +3911,7 @@ sppp_chap_input(struct sppp *sp, struct mbuf *m) SPP_ARGS(ifp)); if (len > 4) { addlog(": "); - sppp_print_string((char*)(h + 1), len - 4); + sppp_print_string((char *)(h + 1), len - 4); } addlog("\n"); } else @@ -3874,7 +3928,7 @@ sppp_chap_input(struct sppp *sp, struct mbuf *m) SPP_ARGS(ifp)); break; } - value = 1 + (u_char*)(h+1); + value = 1 + (u_char *)(h + 1); value_len = value[-1]; name = value + value_len; name_len = len - value_len - 5; @@ -3887,7 +3941,8 @@ sppp_chap_input(struct sppp *sp, struct mbuf *m) sppp_auth_type_name(PPP_CHAP, h->type), h->ident, ntohs(h->len)); if (len > 4) - sppp_print_bytes((u_char*)(h+1), len-4); + sppp_print_bytes((u_char *)(h + 1), + len - 4); addlog(">\n"); } break; @@ -3919,8 +3974,8 @@ sppp_chap_input(struct sppp *sp, struct mbuf *m) SPP_ARGS(ifp), sppp_state_name(sp->state[IDX_CHAP]), sppp_auth_type_name(PPP_CHAP, h->type), - h->ident, ntohs (h->len)); - sppp_print_string((char*)name, name_len); + h->ident, ntohs(h->len)); + sppp_print_string((char *)name, name_len); addlog(" value-size=%d value=", value_len); sppp_print_bytes(value, value_len); addlog(">\n"); @@ -3979,7 +4034,7 @@ sppp_chap_input(struct sppp *sp, struct mbuf *m) sppp_state_name(sp->state[IDX_CHAP]), h->type, h->ident, ntohs(h->len)); if (len > 4) - sppp_print_bytes((u_char*)(h+1), len-4); + sppp_print_bytes((u_char *)(h + 1), len - 4); addlog(">\n"); } break; @@ -4198,9 +4253,9 @@ sppp_pap_input(struct sppp *sp, struct mbuf *m) SPP_ARGS(ifp), len); return; } - h = mtod (m, struct lcp_header*); - if (len > ntohs (h->len)) - len = ntohs (h->len); + h = mtod(m, struct lcp_header *); + if (len > ntohs(h->len)) + len = ntohs(h->len); switch (h->type) { /* PAP request is my authproto */ case PAP_REQ: @@ -4210,7 +4265,7 @@ sppp_pap_input(struct sppp *sp, struct mbuf *m) SPP_ARGS(ifp)); break; } - name = 1 + (u_char*)(h+1); + name = 1 + (u_char *)(h + 1); name_len = name[-1]; secret = name + name_len + 1; if (name_len > len - 6 || @@ -4222,7 +4277,8 @@ sppp_pap_input(struct sppp *sp, struct mbuf *m) sppp_auth_type_name(PPP_PAP, h->type), h->ident, ntohs(h->len)); if (len > 4) - sppp_print_bytes((u_char*)(h+1), len-4); + sppp_print_bytes((u_char *)(h + 1), + len - 4); addlog(">\n"); } break; @@ -4234,9 +4290,9 @@ sppp_pap_input(struct sppp *sp, struct mbuf *m) sppp_state_name(sp->state[IDX_PAP]), sppp_auth_type_name(PPP_PAP, h->type), h->ident, ntohs(h->len)); - sppp_print_string((char*)name, name_len); + sppp_print_string((char *)name, name_len); addlog(" secret="); - sppp_print_string((char*)secret, secret_len); + sppp_print_string((char *)secret, secret_len); addlog(">\n"); } if (name_len != sp->hisauth.name_len || @@ -4277,7 +4333,7 @@ sppp_pap_input(struct sppp *sp, struct mbuf *m) name_len = *(char *)h; if (len > 5 && name_len) { addlog(": "); - sppp_print_string((char*)(h+1), name_len); + sppp_print_string((char *)(h + 1), name_len); } addlog("\n"); } @@ -4308,7 +4364,7 @@ sppp_pap_input(struct sppp *sp, struct mbuf *m) name_len = *(char *)h; if (len > 5 && name_len) { addlog(": "); - sppp_print_string((char*)(h+1), name_len); + sppp_print_string((char *)(h + 1), name_len); } addlog("\n"); } else @@ -4325,7 +4381,7 @@ sppp_pap_input(struct sppp *sp, struct mbuf *m) SPP_ARGS(ifp), h->type, h->ident, ntohs(h->len)); if (len > 4) - sppp_print_bytes((u_char*)(h+1), len-4); + sppp_print_bytes((u_char *)(h + 1), len - 4); addlog(">\n"); } break; @@ -4523,29 +4579,29 @@ sppp_auth_send(const struct cp *cp, struct sppp *sp, const char *msg; va_list ap; - MGETHDR (m, M_DONTWAIT, MT_DATA); + MGETHDR(m, M_DONTWAIT, MT_DATA); if (! m) return; m->m_pkthdr.rcvif = 0; if (sp->pp_flags & PP_NOFRAMING) { - *mtod(m, u_int16_t*) = htons(cp->proto); + *mtod(m, u_int16_t *) = htons(cp->proto); pkthdrlen = 2; - lh = (struct lcp_header*)(mtod(m, u_int8_t*)+2); + lh = (struct lcp_header *)(mtod(m, u_int8_t *)+2); } else { struct ppp_header *h; - h = mtod (m, struct ppp_header*); + h = mtod(m, struct ppp_header *); h->address = PPP_ALLSTATIONS; /* broadcast address */ h->control = PPP_UI; /* Unnumbered Info */ h->protocol = htons(cp->proto); pkthdrlen = PPP_HEADER_LEN; - lh = (struct lcp_header*)(h + 1); + lh = (struct lcp_header *)(h + 1); } lh->type = type; lh->ident = id; - p = (u_char*) (lh+1); + p = (u_char *)(lh + 1); va_start(ap, id); len = 0; @@ -4565,7 +4621,7 @@ sppp_auth_send(const struct cp *cp, struct sppp *sp, va_end(ap); m->m_pkthdr.len = m->m_len = pkthdrlen + LCP_HEADER_LEN + len; - lh->len = htons (LCP_HEADER_LEN + len); + lh->len = htons(LCP_HEADER_LEN + len); if (debug) { log(LOG_DEBUG, SPP_FMT "%s output <%s id=0x%x len=%d", @@ -4573,18 +4629,19 @@ sppp_auth_send(const struct cp *cp, struct sppp *sp, sppp_auth_type_name(cp->proto, lh->type), lh->ident, ntohs(lh->len)); if (len) - sppp_print_bytes((u_char*) (lh+1), len); + sppp_print_bytes((u_char *)(lh + 1), len); addlog(">\n"); } - if (IF_QFULL (&sp->pp_cpq)) { - IF_DROP (&sp->pp_fastq); - IF_DROP (&ifp->if_snd); - m_freem (m); + if (IF_QFULL(&sp->pp_cpq)) { + IF_DROP(&sp->pp_fastq); + IF_DROP(&ifp->if_snd); + m_freem(m); ++ifp->if_oerrors; + return; } else - IF_ENQUEUE (&sp->pp_cpq, m); + IF_ENQUEUE(&sp->pp_cpq, m); if (! (ifp->if_flags & IFF_OACTIVE)) - (*ifp->if_start) (ifp); + (*ifp->if_start)(ifp); ifp->if_obytes += m->m_pkthdr.len + 3; } @@ -4599,7 +4656,7 @@ sppp_keepalive(void *dummy) time_t now; s = splnet(); - now = time.tv_sec; + now = mono_time.tv_sec; for (sp=spppq; sp; sp=sp->pp_next) { struct ifnet *ifp = &sp->pp_if; @@ -4627,10 +4684,16 @@ sppp_keepalive(void *dummy) sp->pp_phase < SPPP_PHASE_AUTHENTICATE) continue; + /* No echo reply, but maybe user data passed through? */ + if ((now - sp->pp_last_activity) < LCP_KEEPALIVE_INTERVAL) { + sp->pp_alivecnt = 0; + continue; + } + if (sp->pp_alivecnt == MAXALIVECNT) { /* No keepalive packets got. Stop the interface. */ if_down (ifp); - IF_PURGE (&sp->pp_cpq); + IF_PURGE(&sp->pp_cpq); if (! (sp->pp_flags & PP_CISCO)) { printf("%s: LCP keepalive timed out, going to restart the connection\n", ifp->if_xname); @@ -4651,17 +4714,17 @@ sppp_keepalive(void *dummy) if (sp->pp_alivecnt <= MAXALIVECNT) ++sp->pp_alivecnt; if (sp->pp_flags & PP_CISCO) - sppp_cisco_send (sp, CISCO_KEEPALIVE_REQ, + sppp_cisco_send(sp, CISCO_KEEPALIVE_REQ, ++sp->pp_seq[IDX_LCP], sp->pp_rseq[IDX_LCP]); else if (sp->pp_phase >= SPPP_PHASE_AUTHENTICATE) { - int32_t nmagic = htonl (sp->lcp.magic); + int32_t nmagic = htonl(sp->lcp.magic); sp->lcp.echoid = ++sp->pp_seq[IDX_LCP]; - sppp_cp_send (sp, PPP_LCP, ECHO_REQ, + sppp_cp_send(sp, PPP_LCP, ECHO_REQ, sp->lcp.echoid, 4, &nmagic); } } splx(s); - callout_reset(&keepalive_ch, hz * 10, sppp_keepalive, NULL); + callout_reset(&keepalive_ch, hz * LCP_KEEPALIVE_INTERVAL, sppp_keepalive, NULL); } /* @@ -4994,7 +5057,7 @@ sppp_params(struct sppp *sp, int cmd, void *data) break; case SPPPSETAUTHCFG: { - struct spppauthcfg *cfg = (struct spppauthcfg*)data; + struct spppauthcfg *cfg = (struct spppauthcfg *)data; int error; if (sp->myauth.name) { @@ -5125,19 +5188,19 @@ sppp_params(struct sppp *sp, int cmd, void *data) break; case SPPPSETDNSOPTS: { - struct spppdnssettings *req = (struct spppdnssettings*)data; + struct spppdnssettings *req = (struct spppdnssettings *)data; sp->query_dns = req->query_dns & 3; } break; case SPPPGETDNSOPTS: { - struct spppdnssettings *req = (struct spppdnssettings*)data; + struct spppdnssettings *req = (struct spppdnssettings *)data; req->query_dns = sp->query_dns; } break; case SPPPGETDNSADDRS: { - struct spppdnsaddrs *addrs = (struct spppdnsaddrs*)data; + struct spppdnsaddrs *addrs = (struct spppdnsaddrs *)data; memcpy(&addrs->dns, &sp->dns_addrs, sizeof addrs->dns); } break; diff --git a/netbsd/sys/net/route.c b/netbsd/sys/net/route.c index 3056986cb1..03a969b148 100644 --- a/netbsd/sys/net/route.c +++ b/netbsd/sys/net/route.c @@ -1,4 +1,4 @@ -/* $NetBSD: route.c,v 1.52 2002/05/12 20:40:12 matt Exp $ */ +/* $NetBSD: route.c,v 1.52.4.1 2002/12/11 18:14:47 he Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -102,7 +102,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.52 2002/05/12 20:40:12 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.52.4.1 2002/12/11 18:14:47 he Exp $"); #include "opt_ns.h" @@ -275,7 +275,7 @@ rtfree(rt) printf("rtfree: %p not freed (neg refs)\n", rt); return; } - rt_timer_remove_all(rt); + rt_timer_remove_all(rt, 0); ifa = rt->rt_ifa; IFAFREE(ifa); Free(rt_key(rt)); @@ -1042,14 +1042,17 @@ rt_timer_count(rtq) } void -rt_timer_remove_all(rt) +rt_timer_remove_all(rt, destroy) struct rtentry *rt; + int destroy; { struct rttimer *r; while ((r = LIST_FIRST(&rt->rt_timer)) != NULL) { LIST_REMOVE(r, rtt_link); TAILQ_REMOVE(&r->rtt_queue->rtq_head, r, rtt_next); + if (destroy) + RTTIMER_CALLOUT(r); if (r->rtt_queue->rtq_count > 0) r->rtt_queue->rtq_count--; else diff --git a/netbsd/sys/net/route.h b/netbsd/sys/net/route.h index 0704f94e7c..f40edc81db 100644 --- a/netbsd/sys/net/route.h +++ b/netbsd/sys/net/route.h @@ -1,4 +1,4 @@ -/* $NetBSD: route.h,v 1.29 2002/05/12 20:40:12 matt Exp $ */ +/* $NetBSD: route.h,v 1.29.4.1 2002/12/11 18:14:29 he Exp $ */ /* * Copyright (c) 1980, 1986, 1993 @@ -363,7 +363,7 @@ struct rttimer_queue * rt_timer_queue_create __P((u_int)); void rt_timer_queue_change __P((struct rttimer_queue *, long)); void rt_timer_queue_destroy __P((struct rttimer_queue *, int)); -void rt_timer_remove_all __P((struct rtentry *)); +void rt_timer_remove_all __P((struct rtentry *, int)); unsigned long rt_timer_count __P((struct rttimer_queue *)); void rt_timer_timer __P((void *)); void rt_add_cache __P((struct rtentry *, diff --git a/netbsd/sys/netinet/Makefile b/netbsd/sys/netinet/Makefile index d03b2ffcd7..956678e202 100644 --- a/netbsd/sys/netinet/Makefile +++ b/netbsd/sys/netinet/Makefile @@ -4,12 +4,13 @@ KDIR= /sys/netinet INCSDIR= /usr/include/netinet INCS= icmp6.h icmp_var.h if_atm.h if_ether.h if_inarp.h \ - igmp.h igmp_var.h in.h in_gif.h in_msf.h in_pcb.h in_systm.h \ + igmp.h igmp_var.h in.h in_gif.h in_pcb.h in_systm.h \ in_var.h ip.h ip6.h ip_auth.h ip_compat.h ip_ecn.h \ ip_encap.h ip_fil.h ip_frag.h ip_icmp.h ip_mroute.h \ ip_nat.h ip_proxy.h ip_state.h ip_var.h tcp.h \ tcp_debug.h tcp_fsm.h tcp_seq.h tcp_timer.h tcp_var.h \ tcpip.h udp.h udp_var.h +INCS+= in_msf.h INCS+= sctp.h sctp_uio.h sctp_var.h .include diff --git a/netbsd/sys/netinet/fil.c b/netbsd/sys/netinet/fil.c index f6d624fdca..4490e2d0a9 100644 --- a/netbsd/sys/netinet/fil.c +++ b/netbsd/sys/netinet/fil.c @@ -1,4 +1,4 @@ -/* $NetBSD: fil.c,v 1.55 2002/05/02 17:13:27 martti Exp $ */ +/* $NetBSD: fil.c,v 1.55.4.1 2002/10/24 09:33:49 lukem Exp $ */ /* * Copyright (C) 1993-2001 by Darren Reed. @@ -100,10 +100,10 @@ #if !defined(lint) #if defined(__NetBSD__) #include -__KERNEL_RCSID(0, "$NetBSD: fil.c,v 1.55 2002/05/02 17:13:27 martti Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fil.c,v 1.55.4.1 2002/10/24 09:33:49 lukem Exp $"); #else static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)Id: fil.c,v 2.35.2.60 2002/04/26 10:20:34 darrenr Exp"; +static const char rcsid[] = "@(#)Id: fil.c,v 2.35.2.63 2002/08/28 12:40:08 darrenr Exp"; #endif #endif @@ -152,9 +152,6 @@ static int frflushlist __P((int, minor_t, int *, frentry_t **)); #ifdef _KERNEL static void frsynclist __P((frentry_t *)); #endif -#ifndef _KERNEL -int mbuflen(mb_t *); -#endif /* @@ -1086,7 +1083,7 @@ int out; fin->fin_fr = fr; if ((pass & (FR_KEEPFRAG|FR_KEEPSTATE)) == FR_KEEPFRAG) { if (fin->fin_fl & FI_FRAG) { - if (ipfr_newfrag(ip, fin, pass) == -1) { + if (ipfr_newfrag(ip, fin) == -1) { ATOMIC_INCL(frstats[out].fr_bnfr); } else { ATOMIC_INCL(frstats[out].fr_nfr); @@ -1201,7 +1198,16 @@ int out; * some operating systems. */ if (!out) { - if (pass & FR_RETICMP) { + if (changed == -1) + /* + * If a packet results in a NAT error, do not + * send a reset or ICMP error as it may disrupt + * an existing flow. This is the proxy saying + * the content is bad so just drop the packet + * silently. + */ + ; + else if (pass & FR_RETICMP) { int dst; if ((pass & FR_RETMASK) == FR_FAKEICMP) @@ -1511,7 +1517,7 @@ tcphdr_t *tcp; * SUCH DAMAGE. * * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 - * Id: fil.c,v 2.35.2.60 2002/04/26 10:20:34 darrenr Exp + * Id: fil.c,v 2.35.2.63 2002/08/28 12:40:08 darrenr Exp */ /* * Copy data from an mbuf chain starting "off" bytes from the beginning, @@ -1626,7 +1632,6 @@ frgroup_t ***fgpp; fgp = &ipfgroups[0][set]; else return NULL; - num &= 0xffff; while ((fg = *fgp)) if (fg->fg_num == num) diff --git a/netbsd/sys/netinet/ip_auth.c b/netbsd/sys/netinet/ip_auth.c index 3c68b16e6d..215a6100b4 100644 --- a/netbsd/sys/netinet/ip_auth.c +++ b/netbsd/sys/netinet/ip_auth.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_auth.c,v 1.27 2002/05/02 17:13:28 martti Exp $ */ +/* $NetBSD: ip_auth.c,v 1.27.4.1 2002/10/24 09:33:51 lukem Exp $ */ /* * Copyright (C) 1998-2001 by Darren Reed & Guido van Rooij. @@ -108,9 +108,9 @@ extern struct ifqueue ipintrq; /* ip packet input queue */ #if !defined(lint) #if defined(__NetBSD__) #include -__KERNEL_RCSID(0, "$NetBSD: ip_auth.c,v 1.27 2002/05/02 17:13:28 martti Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_auth.c,v 1.27.4.1 2002/10/24 09:33:51 lukem Exp $"); #else -static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.11.2.19 2002/04/23 14:57:27 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.11.2.20 2002/06/04 14:40:42 darrenr Exp"; #endif #endif @@ -622,7 +622,10 @@ void fr_authexpire() } else faep = &fae->fae_next; } - ipauth = &fae_list->fae_fr; + if (fae_list != NULL) + ipauth = &fae_list->fae_fr; + else + ipauth = NULL; for (frp = &fr_authlist; (fr = *frp); ) { if (fr->fr_ref == 1) { diff --git a/netbsd/sys/netinet/ip_fil.c b/netbsd/sys/netinet/ip_fil.c index 533e7dd928..fadf14515d 100644 --- a/netbsd/sys/netinet/ip_fil.c +++ b/netbsd/sys/netinet/ip_fil.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_fil.c,v 1.79 2002/05/02 17:13:28 martti Exp $ */ +/* $NetBSD: ip_fil.c,v 1.79.4.1 2002/10/24 09:33:45 lukem Exp $ */ /* * Copyright (C) 1993-2001 by Darren Reed. @@ -123,10 +123,10 @@ extern int ip_optcopy __P((struct ip *, struct ip *)); #if !defined(lint) #if defined(__NetBSD__) #include -__KERNEL_RCSID(0, "$NetBSD: ip_fil.c,v 1.79 2002/05/02 17:13:28 martti Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_fil.c,v 1.79.4.1 2002/10/24 09:33:45 lukem Exp $"); #else static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)Id: ip_fil.c,v 2.42.2.55 2002/03/26 15:54:39 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ip_fil.c,v 2.42.2.60 2002/08/28 12:40:39 darrenr Exp"; #endif #endif @@ -164,6 +164,7 @@ static int ipfr_fastroute6 __P((struct mbuf *, struct mbuf **, fr_info_t *, frdest_t *)); # endif # ifdef __sgi +extern int tcp_mtudisc; extern kmutex_t ipf_rw; extern KRWLOCK_T ipf_mutex; # endif @@ -198,6 +199,15 @@ struct timeout ipfr_slowtimer_ch; toid_t ipfr_slowtimer_ch; #endif +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000) && \ + defined(_KERNEL) +#include +const struct cdevsw ipl_cdevsw = { + iplopen, iplclose, iplread, nowrite, iplioctl, + nostop, notty, nopoll, nommap, +}; +#endif + #if (_BSDI_VERSION >= 199510) && defined(_KERNEL) # include # include @@ -492,7 +502,7 @@ int ipl_disable() int ipldetach() # endif { - int s, i = FR_INQUE|FR_OUTQUE; + int s, i; #if defined(NETBSD_PF) && (__NetBSD_Version__ >= 104200000) int error = 0; # if __NetBSD_Version__ >= 105150000 @@ -533,7 +543,8 @@ int ipldetach() printf("%s unloaded\n", ipfilter_version); fr_checkp = fr_savep; - i = frflush(IPL_LOGIPF, i); + i = frflush(IPL_LOGIPF, FR_INQUE|FR_OUTQUE|FR_INACTIVE); + i += frflush(IPL_LOGIPF, FR_INQUE|FR_OUTQUE); fr_running = 0; # ifdef NETBSD_PF @@ -653,6 +664,9 @@ int mode; unit = dev; #endif + if (fr_running == 0 && (cmd != SIOCFRENB || unit != IPL_LOGIPF)) + return ENODEV; + SPL_NET(s); if (unit == IPL_LOGNAT) { @@ -913,7 +927,8 @@ caddr_t data; * Check that the group number does exist and that if a head group * has been specified, doesn't exist. */ - if ((req != SIOCZRLST) && fp->fr_grhead && + if ((req != SIOCZRLST) && ((req == SIOCINAFR) || (req == SIOCINIFR) || + (req == SIOCADAFR) || (req == SIOCADIFR)) && fp->fr_grhead && fr_findgroup((u_int)fp->fr_grhead, fp->fr_flags, unit, set, NULL)) return EEXIST; if ((req != SIOCZRLST) && fp->fr_group && @@ -1247,13 +1262,18 @@ fr_info_t *fin; struct mbuf **mp; { struct mbuf *m = *mp; - char *dpsave; - int error; + int error, hlen; + fr_info_t frn; ip_t *ip; - dpsave = fin->fin_dp; + bzero((char *)&frn, sizeof(frn)); + frn.fin_ifp = fin->fin_ifp; + frn.fin_v = fin->fin_v; + frn.fin_out = fin->fin_out; + frn.fin_mp = fin->fin_mp; ip = mtod(m, ip_t *); + hlen = sizeof(*ip); ip->ip_v = fin->fin_v; if (ip->ip_v == 4) { @@ -1261,28 +1281,41 @@ struct mbuf **mp; ip->ip_v = IPVERSION; ip->ip_tos = oip->ip_tos; ip->ip_id = oip->ip_id; - ip->ip_off = 0; + +# if defined(__NetBSD__) || defined(__OpenBSD__) + if (ip_mtudisc != 0) + ip->ip_off = IP_DF; +# else +# if defined(__sgi) + if (ip->ip_p == IPPROTO_TCP && tcp_mtudisc != 0) + ip->ip_off = IP_DF; +# endif +# endif + # if (BSD < 199306) || defined(__sgi) ip->ip_ttl = tcp_ttl; # else ip->ip_ttl = ip_defttl; # endif ip->ip_sum = 0; - fin->fin_dp = (char *)(ip + 1); + frn.fin_dp = (char *)(ip + 1); } # ifdef USE_INET6 else if (ip->ip_v == 6) { ip6_t *ip6 = (ip6_t *)ip; + hlen = sizeof(*ip6); ip6->ip6_hlim = 127; - fin->fin_dp = (char *)(ip6 + 1); + frn.fin_dp = (char *)(ip6 + 1); } # endif # ifdef IPSEC m->m_pkthdr.rcvif = NULL; # endif - error = ipfr_fastroute(m, mp, fin, NULL); - fin->fin_dp = dpsave; + + fr_makefrip(hlen, ip, &frn); + + error = ipfr_fastroute(m, mp, &frn, NULL); return error; } @@ -1589,6 +1622,9 @@ frdest_t *fdp; /* * Route packet. */ +#ifdef __sgi + ROUTE_RDLOCK(); +#endif bzero((caddr_t)ro, sizeof (*ro)); dst = (struct sockaddr_in *)&ro->ro_dst; dst->sin_family = AF_INET; @@ -1625,6 +1661,11 @@ frdest_t *fdp; # else rtalloc(ro); # endif + +#ifdef __sgi + ROUTE_UNLOCK(); +#endif + if (!ifp) { if (!fr || !(fr->fr_flags & FR_FASTROUTE)) { error = -2; @@ -1677,7 +1718,8 @@ frdest_t *fdp; */ if (ip->ip_len <= ifp->if_mtu) { # ifndef sparc -# if (!defined(__FreeBSD__) && !(_BSDI_VERSION >= 199510)) +# if (!defined(__FreeBSD__) && !(_BSDI_VERSION >= 199510)) && \ + !(__NetBSD_Version__ >= 105110000) ip->ip_id = htons(ip->ip_id); # endif ip->ip_len = htons(ip->ip_len); @@ -2132,7 +2174,7 @@ int code; fr_info_t *fin; int dst; { - verbose("- ICMP UNREACHABLE RST sent\n"); + verbose("- ICMP UNREACHABLE sent\n"); return 0; } diff --git a/netbsd/sys/netinet/ip_frag.c b/netbsd/sys/netinet/ip_frag.c index b53ad2cc95..8647c3a6dc 100644 --- a/netbsd/sys/netinet/ip_frag.c +++ b/netbsd/sys/netinet/ip_frag.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_frag.c,v 1.30 2002/05/02 17:13:29 martti Exp $ */ +/* $NetBSD: ip_frag.c,v 1.30.4.1 2002/10/24 09:33:56 lukem Exp $ */ /* * Copyright (C) 1993-2001 by Darren Reed. @@ -93,10 +93,10 @@ extern struct timeout ipfr_slowtimer_ch; #if !defined(lint) #if defined(__NetBSD__) #include -__KERNEL_RCSID(0, "$NetBSD: ip_frag.c,v 1.30 2002/05/02 17:13:29 martti Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_frag.c,v 1.30.4.1 2002/10/24 09:33:56 lukem Exp $"); #else static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)Id: ip_frag.c,v 2.10.2.21 2002/04/10 04:56:10 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ip_frag.c,v 2.10.2.24 2002/08/28 12:41:04 darrenr Exp"; #endif #endif @@ -127,7 +127,7 @@ extern kmutex_t ipf_rw; #endif -static ipfr_t *ipfr_new __P((ip_t *, fr_info_t *, u_int, ipfr_t **)); +static ipfr_t *ipfr_new __P((ip_t *, fr_info_t *, ipfr_t **)); static ipfr_t *ipfr_lookup __P((ip_t *, fr_info_t *, ipfr_t **)); static void ipfr_delete __P((ipfr_t *)); @@ -145,10 +145,9 @@ ipfrstat_t *ipfr_fragstats() * add a new entry to the fragment cache, registering it as having come * through this box, with the result of the filter operation. */ -static ipfr_t *ipfr_new(ip, fin, pass, table) +static ipfr_t *ipfr_new(ip, fin, table) ip_t *ip; fr_info_t *fin; -u_int pass; ipfr_t *table[]; { ipfr_t **fp, *fra, frag; @@ -205,7 +204,7 @@ ipfr_t *table[]; /* * Instert the fragment into the fragment table, copy the struct used * in the search using bcopy rather than reassign each field. - * Set the ttl to the default and mask out logging from "pass" + * Set the ttl to the default. */ if ((fra->ipfr_next = table[idx])) table[idx]->ipfr_prev = fra; @@ -227,17 +226,16 @@ ipfr_t *table[]; } -int ipfr_newfrag(ip, fin, pass) +int ipfr_newfrag(ip, fin) ip_t *ip; fr_info_t *fin; -u_int pass; { ipfr_t *ipf; if ((ip->ip_v != 4) || (fr_frag_lock)) return -1; WRITE_ENTER(&ipf_frag); - ipf = ipfr_new(ip, fin, pass, ipfr_heads); + ipf = ipfr_new(ip, fin, ipfr_heads); RWLOCK_EXIT(&ipf_frag); if (ipf == NULL) { ATOMIC_INCL(frstats[fin->fin_out].fr_bnfr); @@ -248,10 +246,9 @@ u_int pass; } -int ipfr_nat_newfrag(ip, fin, pass, nat) +int ipfr_nat_newfrag(ip, fin, nat) ip_t *ip; fr_info_t *fin; -u_int pass; nat_t *nat; { ipfr_t *ipf; @@ -263,10 +260,10 @@ nat_t *nat; off = fin->fin_off; off <<= 3; if ((off + fin->fin_dlen) > 0xffff || (fin->fin_dlen == 0)) - return NULL; + return -1; WRITE_ENTER(&ipf_natfrag); - ipf = ipfr_new(ip, fin, pass, ipfr_nattab); + ipf = ipfr_new(ip, fin, ipfr_nattab); if (ipf != NULL) { ipf->ipfr_data = nat; nat->nat_data = ipf; diff --git a/netbsd/sys/netinet/ip_input.c b/netbsd/sys/netinet/ip_input.c index 13ee1ac32c..98ac3e4908 100644 --- a/netbsd/sys/netinet/ip_input.c +++ b/netbsd/sys/netinet/ip_input.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.150.4.1 2002/06/07 19:39:21 thorpej Exp $ */ +/* $NetBSD: ip_input.c,v 1.150.4.2 2002/11/12 14:44:11 tron Exp $ */ /* * Copyright (c) 2002 INRIA. All rights reserved. @@ -139,7 +139,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.150.4.1 2002/06/07 19:39:21 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.150.4.2 2002/11/12 14:44:11 tron Exp $"); #include "opt_gateway.h" #include "opt_pfil_hooks.h" @@ -386,9 +386,7 @@ ip_init() TAILQ_INIT(&in_ifaddr); in_ifaddrhashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, M_IFADDR, M_WAITOK, &in_ifaddrhash); - if (ip_mtudisc != 0) - ip_mtudisc_timeout_q = - rt_timer_queue_create(ip_mtudisc_timeout); + ip_mtudisc_timeout_q = rt_timer_queue_create(ip_mtudisc_timeout); #ifdef GATEWAY ipflow_init(); #endif diff --git a/netbsd/sys/netinet/ip_output.c b/netbsd/sys/netinet/ip_output.c index 34dd7dd512..83f66028f2 100644 --- a/netbsd/sys/netinet/ip_output.c +++ b/netbsd/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_output.c,v 1.95 2002/02/07 21:47:45 thorpej Exp $ */ +/* $NetBSD: ip_output.c,v 1.95.10.2 2002/11/01 12:14:28 tron Exp $ */ /* * Copyright (c) 2002 INRIA. All rights reserved. @@ -139,7 +139,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.95 2002/02/07 21:47:45 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.95.10.2 2002/11/01 12:14:28 tron Exp $"); #include "opt_pfil_hooks.h" #include "opt_ipsec.h" @@ -238,6 +238,7 @@ ip_output(m0, va_alist) #endif /*IPSEC*/ u_int16_t ip_len; + len = 0; va_start(ap, m0); opt = va_arg(ap, struct mbuf *); ro = va_arg(ap, struct route *); @@ -260,7 +261,8 @@ ip_output(m0, va_alist) #endif if (opt) { m = ip_insertoptions(m, opt, &len); - hlen = len; + if (len >= sizeof(struct ip)) + hlen = len; } ip = mtod(m, struct ip *); /* @@ -316,7 +318,7 @@ ip_output(m0, va_alist) mtu = ifp->if_mtu; ip->ip_ttl = 1; } else if ((IN_MULTICAST(ip->ip_dst.s_addr) || - (ip->ip_dst.s_addr == INADDR_BROADCAST)) && + ip->ip_dst.s_addr == INADDR_BROADCAST) && imo != NULL && imo->imo_multicast_ifp != NULL) { ifp = imo->imo_multicast_ifp; mtu = ifp->if_mtu; @@ -369,7 +371,7 @@ ip_output(m0, va_alist) */ if (!ifp) { ipstat.ips_noroute++; - error = EHOSTUNREACH; + error = ENETUNREACH; goto bad; } diff --git a/netbsd/sys/netinet/tcp_input.c b/netbsd/sys/netinet/tcp_input.c index 0788e1af81..dea61eaf9a 100644 --- a/netbsd/sys/netinet/tcp_input.c +++ b/netbsd/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $NetBSD: tcp_input.c,v 1.141.4.3 2002/09/06 06:21:17 lukem Exp $ */ +/* $NetBSD: tcp_input.c,v 1.141.4.5 2002/10/23 12:21:24 lukem Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -152,7 +152,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.141.4.3 2002/09/06 06:21:17 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.141.4.5 2002/10/23 12:21:24 lukem Exp $"); #include "opt_inet.h" #include "opt_ipsec.h" @@ -1030,7 +1030,8 @@ tcp_input(m, va_alist) #endif { ++tcpstat.tcps_noport; - if (tcp_log_refused && (tiflags & TH_SYN)) { + if (tcp_log_refused && + (tiflags & (TH_RST|TH_ACK|TH_SYN)) == TH_SYN) { char src[4*sizeof "123"]; char dst[4*sizeof "123"]; @@ -1083,7 +1084,8 @@ tcp_input(m, va_alist) } if (in6p == NULL) { ++tcpstat.tcps_noport; - if (tcp_log_refused && (tiflags & TH_SYN)) { + if (tcp_log_refused && + (tiflags & (TH_RST|TH_ACK|TH_SYN)) == TH_SYN) { char src[INET6_ADDRSTRLEN]; char dst[INET6_ADDRSTRLEN]; @@ -1731,7 +1733,7 @@ tcp_input(m, va_alist) tcp_established(tp); /* Do window scaling on this connection? */ if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == - (TF_RCVD_SCALE|TF_REQ_SCALE)) { + (TF_RCVD_SCALE|TF_REQ_SCALE)) { tp->snd_scale = tp->requested_s_scale; tp->rcv_scale = tp->request_r_scale; } @@ -2008,7 +2010,7 @@ tcp_input(m, va_alist) tcp_established(tp); /* Do window scaling? */ if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == - (TF_RCVD_SCALE|TF_REQ_SCALE)) { + (TF_RCVD_SCALE|TF_REQ_SCALE)) { tp->snd_scale = tp->requested_s_scale; tp->rcv_scale = tp->request_r_scale; } @@ -3443,10 +3445,10 @@ syn_cache_get(src, dst, th, hlen, tlen, so, m) tp->request_r_scale = sc->sc_request_r_scale; tp->snd_scale = sc->sc_requested_s_scale; tp->rcv_scale = sc->sc_request_r_scale; - tp->t_flags |= TF_RCVD_SCALE; + tp->t_flags |= TF_REQ_SCALE|TF_RCVD_SCALE; } if (sc->sc_flags & SCF_TIMESTAMP) - tp->t_flags |= TF_RCVD_TSTMP; + tp->t_flags |= TF_REQ_TSTMP|TF_RCVD_TSTMP; #ifdef TCP_ECN if (sc->sc_flags & SCF_ECN) { tp->t_flags |= TF_ECN_PERMIT; @@ -3728,7 +3730,8 @@ syn_cache_add(src, dst, th, hlen, so, m, optp, optlen, oi) sc->sc_win = win; sc->sc_timebase = tcp_now; /* see tcp_newtcpcb() */ sc->sc_timestamp = tb.ts_recent; - if (tcp_do_rfc1323 && (tb.t_flags & TF_RCVD_TSTMP)) + if ((tb.t_flags & (TF_REQ_TSTMP|TF_RCVD_TSTMP)) == + (TF_REQ_TSTMP|TF_RCVD_TSTMP)) sc->sc_flags |= SCF_TIMESTAMP; if ((tb.t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == (TF_RCVD_SCALE|TF_REQ_SCALE)) { diff --git a/netbsd/sys/netinet/tcp_output.c b/netbsd/sys/netinet/tcp_output.c index 122989264c..07164b9cb1 100644 --- a/netbsd/sys/netinet/tcp_output.c +++ b/netbsd/sys/netinet/tcp_output.c @@ -1,4 +1,4 @@ -/* $NetBSD: tcp_output.c,v 1.79.4.1 2002/06/14 17:32:59 lukem Exp $ */ +/* $NetBSD: tcp_output.c,v 1.79.4.3 2002/11/30 14:31:59 he Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -142,7 +142,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.79.4.1 2002/06/14 17:32:59 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.79.4.3 2002/11/30 14:31:59 he Exp $"); #include "opt_inet.h" #include "opt_ipsec.h" @@ -234,6 +234,7 @@ tcp_segsize(struct tcpcb *tp, int *txsegsizep, int *rxsegsizep) #ifdef INET6 struct in6pcb *in6p = tp->t_in6pcb; #endif + struct socket *so; struct rtentry *rt; struct ifnet *ifp; int size; @@ -262,12 +263,16 @@ tcp_segsize(struct tcpcb *tp, int *txsegsizep, int *rxsegsizep) rt = NULL; #ifdef INET - if (inp) + if (inp) { rt = in_pcbrtentry(inp); + so = inp->inp_socket; + } #endif #ifdef INET6 - if (in6p) + if (in6p) { rt = in6_pcbrtentry(in6p); + so = in6p->in6p_socket; + } #endif if (rt == NULL) { size = tcp_mssdflt; @@ -361,6 +366,14 @@ tcp_segsize(struct tcpcb *tp, int *txsegsizep, int *rxsegsizep) * I'm not quite sure about this (could someone comment). */ *txsegsizep = min(tp->t_peermss - optlen, size); + /* + * Never send more than half a buffer full. This insures that we can + * always keep 2 packets on the wire, no matter what SO_SNDBUF is, and + * therefore acks will never be delayed unless we run out of data to + * transmit. + */ + if (so) + *txsegsizep = min(so->so_snd.sb_hiwat >> 1, *txsegsizep); *rxsegsizep = min(tp->t_ourmss - optlen, size); if (*txsegsizep != tp->t_segsz) { diff --git a/netbsd/sys/netinet6/IMPLEMENTATION b/netbsd/sys/netinet6/IMPLEMENTATION deleted file mode 100644 index 46ae01fb30..0000000000 --- a/netbsd/sys/netinet6/IMPLEMENTATION +++ /dev/null @@ -1,1544 +0,0 @@ -$NetBSD: IMPLEMENTATION,v 1.14 2000/06/12 10:47:17 itojun Exp $ - -# NOTE: this is from original KAME distribution. -# Some portion of this document is not applicable to the code merged into -# NetBSD-current (for example, section 5). Check sys/netinet6/TODO as well. - - Implementation Note - - KAME Project - http://www.kame.net/ - KAME Date: 2000/06/12 09:29:16 - -1. IPv6 - -1.1 Conformance - -The KAME kit conforms, or tries to conform, to the latest set of IPv6 -specifications. For future reference we list some of the relevant documents -below (NOTE: this is not a complete list - this is too hard to maintain...). -For details please refer to specific chapter in the document, RFCs, manpages -come with KAME, or comments in the source code. - -Conformance tests have been performed on past and latest KAME STABLE kit, -at TAHI project. Results can be viewed at http://www.tahi.org/report/KAME/. -We also attended Univ. of New Hampshire IOL tests (http://www.iol.unh.edu/) -in the past, with our past snapshots. - -RFC1639: FTP Operation Over Big Address Records (FOOBAR) - * RFC2428 is preferred over RFC1639. ftp clients will first try RFC2428, - then RFC1639 if failed. -RFC1886: DNS Extensions to support IPv6 -RFC1933: Transition Mechanisms for IPv6 Hosts and Routers - * IPv4 compatible address is not supported. - * automatic tunneling (4.3) is not supported. - * "gif" interface implements IPv[46]-over-IPv[46] tunnel in a generic way, - and it covers "configured tunnel" described in the spec. - See 1.5 in this document for details. -RFC1981: Path MTU Discovery for IPv6 -RFC2080: RIPng for IPv6 - * KAME-supplied route6d, bgpd and hroute6d support this. -RFC2283: Multiprotocol Extensions for BGP-4 - * so-called "BGP4+". - * KAME-supplied bgpd supports this. -RFC2292: Advanced Sockets API for IPv6 - * For supported library functions/kernel APIs, see sys/netinet6/ADVAPI. -RFC2362: Protocol Independent Multicast-Sparse Mode (PIM-SM) - * RFC2362 defines packet formats for PIM-SM. draft-ietf-pim-ipv6-01.txt - is written based on this. -RFC2373: IPv6 Addressing Architecture - * KAME supports node required addresses, and conforms to the scope - requirement. -RFC2374: An IPv6 Aggregatable Global Unicast Address Format - * KAME supports 64-bit length of Interface ID. -RFC2375: IPv6 Multicast Address Assignments - * Userland applications use the well-known addresses assigned in the RFC. -RFC2428: FTP Extensions for IPv6 and NATs - * RFC2428 is preferred over RFC1639. ftp clients will first try RFC2428, - then RFC1639 if failed. -RFC2460: IPv6 specification -RFC2461: Neighbor discovery for IPv6 - * See 1.2 in this document for details. -RFC2462: IPv6 Stateless Address Autoconfiguration - * See 1.4 in this document for details. -RFC2463: ICMPv6 for IPv6 specification - * See 1.8 in this document for details. -RFC2464: Transmission of IPv6 Packets over Ethernet Networks -RFC2465: MIB for IPv6: Textual Conventions and General Group - * Necessary statistics are gathered by the kernel. Actual IPv6 MIB - support is provided as patchkit for ucd-snmp. -RFC2466: MIB for IPv6: ICMPv6 group - * Necessary statistics are gathered by the kernel. Actual IPv6 MIB - support is provided as patchkit for ucd-snmp. -RFC2467: Transmission of IPv6 Packets over FDDI Networks -RFC2472: IPv6 over PPP -RFC2492: IPv6 over ATM Networks - * only PVC is supported. -RFC2497: Transmission of IPv6 packet over ARCnet Networks -RFC2545: Use of BGP-4 Multiprotocol Extensions for IPv6 Inter-Domain Routing -RFC2553: Basic Socket Interface Extensions for IPv6 - * IPv4 mapped address (3.7) and special behavior of IPv6 wildcard bind - socket (3.8) are, - - supported on KAME/FreeBSD3x, - - supported on KAME/NetBSD, - - supported on KAME/BSDI4, - - not supported on KAME/FreeBSD228, KAME/OpenBSD and KAME/BSDI3. - see 1.12 in this document for details. -RFC2675: IPv6 Jumbograms - * See 1.7 in this document for details. -RFC2710: Multicast Listener Discovery for IPv6 -RFC2711: IPv6 router alert option -RFC2732: Format for Literal IPv6 Addresses in URL's - * The spec is implemented in programs that handle URLs - (like freebsd ftpio(3) and fetch(1), or netbsd ftp(1)) -draft-ietf-ipngwg-router-renum-10: Router renumbering for IPv6 -draft-ietf-ipngwg-icmp-name-lookups-05: IPv6 Name Lookups Through ICMP -draft-ietf-pim-ipv6-03.txt: PIM for IPv6 - * pim6dd implements dense mode. pim6sd implements sparse mode. -draft-ietf-dhc-dhcpv6-15.txt: DHCPv6 -draft-ietf-dhc-dhcpv6exts-12.txt: Extensions for DHCPv6 - * kame/dhcp6 has test implementation, which will not be compiled in - default compilation. -draft-itojun-ipv6-tcp-to-anycast-00.txt: - Disconnecting TCP connection toward IPv6 anycast address -draft-ietf-ipngwg-scopedaddr-format-01.txt: - An Extension of Format for IPv6 Scoped Addresses -draft-ietf-ngtrans-tcpudp-relay-01.txt: - An IPv6-to-IPv4 transport relay translator - * FAITH tcp relay translator (faithd) implements this. See 3.1 for more - details. -draft-ietf-ngtrans-6to4-06.txt: - Connection of IPv6 Domains via IPv4 Clouds without Explicit Tunnels - * "stf" interface implements it. Be sure to read the next item before - configuring it, there are security issues. -http://playground.iijlab.net/i-d/draft-itojun-ipv6-transition-abuse-00.txt: - Possible abuse against IPv6 transition technologies - * KAME does not implement RFC1933 automatic tunnel. - * "stf" interface implements some address filters. Refer to stf(4) - for details. Since there's no way to make 6to4 interface 100% secure, - we do not include "stf" interface into GENERIC.v6 compilation. - * kame/openbsd completely disables IPv4 mapped address support. - * kame/netbsd makes IPv4 mapped address support off by default. - * See section 12.6 and 14 for more details. - -1.2 Neighbor Discovery - -Neighbor Discovery is fairly stable. Currently Address Resolution, -Duplicated Address Detection, and Neighbor Unreachability Detection -are supported. In the near future we will be adding Unsolicited Neighbor -Advertisement transmission command as admin tool. - -Duplicated Address Detection (DAD) will be performed when an IPv6 address -is assigned to a network interface, or the network interface is enabled -(ifconfig up). It is documented in RFC2462 5.4. -If DAD fails, the address will be marked "duplicated" and message will be -generated to syslog (and usually to console). The "duplicated" mark -can be checked with ifconfig. It is administrators' responsibility to check -for and recover from DAD failures. We may try to improve failure recovery -in future KAME code. -DAD procedure may not be effective on certain network interfaces/drivers. -If a network driver needs long initialization time (with wireless network -interfaces this situation is popular), and the driver mistakingly raises -IFF_RUNNING before the driver becomes ready, DAD code will try to transmit -DAD probes to not-really-ready network driver and the packet will not go out -from the interface. In such cases, network drivers should be corrected. - -Some of network drivers loop multicast packets back to themselves, -even if instructed not to do so (especially in promiscuous mode). -In such cases DAD may fail, because DAD engine sees inbound NS packet -(actually from the node itself) and considers it as a sign of duplicate. -You may want to look at #if condition marked "heuristics" in -sys/netinet6/nd6_nbr.c:nd6_dad_timer() as workaround (note that the code -fragment in "heuristics" section is not spec conformant). - -Neighbor Discovery specification (RFC2461) does not talk about neighbor -cache handling in the following cases: -(1) when there was no neighbor cache entry, node received unsolicited - RS/NS/NA/redirect packet without link-layer address -(2) neighbor cache handling on medium without link-layer address - (we need a neighbor cache entry for IsRouter bit) -For (1), we implemented workaround based on discussions on IETF ipngwg mailing -list. For more details, see the comments in the source code and email -thread started from (IPng 7155), dated Feb 6 1999. - -IPv6 on-link determination rule (RFC2461) is quite different from assumptions -in BSD IPv4 network code. To implement behavior in RFC2461 section 5.2 -(when default router list is empty), the kernel needs to know the default -outgoing interface. To configure the default outgoing interface, use -commands like "ndp -I de0" as root. Note that the spec misuse the word -"host" and "node" in several places in the section. - -To avoid possible DoS attacks and infinite loops, KAME stack will accept -only 10 options on ND packet. Therefore, if you have 20 prefix options -attached to RA, only the first 10 prefixes will be recognized. -If this troubles you, please contact KAME team and/or modify -nd6_maxndopt in sys/netinet6/nd6.c. If there are high demands we may -provide sysctl knob for the variable. - -Proxy Neighbor Advertisement support is implemented in the kernel. -You can configure it by using the following command: - # ndp -s fe80:1::1234 0:1:2:3:4:5 proxy -You need to fill in scope index into the address - see 1.3.3. -There are certain limitations, though: -- It does not send unsolicited multicast NA on configuration. This is MAY - behavior in RFC2461. -- It does not add random delay before transmission of solicited NA. This is - SHOULD behavior in RFC2461. -- We cannot configure proxy NDP for off-link address. The target address for - proxying must be link-local address, or must be in prefixes configured to - node which does proxy NDP. -- RFC2461 is unclear about if it is legal for a host to perform proxy ND. - We do not prohibit hosts from doing proxy ND, but there will be very limited - use in it. - -Starting mid March 2000, we support Neighbor Unreachability Detection (NUD) -on p2p interfaces, including tunnel interfaces (gif). NUD is turned on by -default. Before March 2000 KAME stack did not perform NUD on p2p interfaces. -If the change raises any interoperability issues, you can turn off/on NUD -by per-interface basis. Use "ndp -i interface -nud" to turn it off. -Consult ndp(8) for details. - -1.3 Scope Index - -IPv6 uses scoped addresses. It is therefore very important to -specify scope index (interface index for link-local address, or -site index for site-local address) with an IPv6 address. Without -scope index, a scoped IPv6 address is ambiguous to the kernel, and -the kernel will not be able to determine the outbound interface for a -packet. KAME code tries to address the issue in several ways. - -Site-local address is very vaguely defined in the specs, and both specification -and KAME code need tons of improvements to enable its actual use. -For example, it is still very unclear how we define a site, or how we resolve -hostnames in a site. There are work underway to define behavior of routers -at site border, however, we have almost no code for site boundary node support -(both forwarding nor routing) and we bet almost noone has. -We recommend, at this moment, you to use global addresses for experiments - -there are way too many pitfalls if you use site-local addresses. - -1.3.1 Kernel internal - -In the kernel, the interface index for a link-local scope address is -embedded into the 2nd 16bit-word (the 3rd and 4th bytes) in the IPv6 -address. -For example, you may see something like: - fe80:1::200:f8ff:fe01:6317 -in the routing table and interface address structure (struct -in6_ifaddr). The address above is a link-local unicast address -which belongs to a network interface whose interface identifier is 1. -The embedded index enables us to identify IPv6 link local -addresses over multiple interfaces effectively and with only a -little code change. - -1.3.2 Interaction with API - -Ordinary userland applications should use the advanced API (RFC2292) -to specify scope index, or interface index. For the similar purpose, -the sin6_scope_id member in the sockaddr_in6 structure is defined in -RFC2553. However, the semantics for sin6_scope_id is rather vague. -If you care about portability of your application, we suggest you to -use the advanced API rather than sin6_scope_id. - -Routing daemons and configuration programs, like route6d and -ifconfig, will need to manipulate the "embedded" scope index. -These programs use routing sockets and ioctls (like SIOCGIFADDR_IN6) -and the kernel API will return IPv6 addresses with 2nd 16bit-word -filled in. The APIs are for manipulating kernel internal structure. -Programs that use these APIs have to be prepared about differences -in kernels anyway. - -getaddrinfo(3) and getnameinfo(3) are modified to support extended numeric -IPv6 syntax, as documented in draft-ietf-ipngwg-scopedaddr-format-01.txt. -You can specify outgoing link, by using name of the outgoing interface -like "fe80::1%ne0". This way you will be able to specify link-local scoped -address without much trouble. -To use this extension in your program, you'll need to use getaddrinfo(3), -and getnameinfo(3) with NI_WITHSCOPEID. -The implementation currently assumes 1-to-1 relationship between a link and an -interface, which is stronger than what IPv6 specs say. -Other APIs like inet_pton(3) or getipnodebyname(3) are inherently unfriendly -with scoped addresses, since they are unable to annotate addresses with -scope identifier. - -1.3.3 Interaction with users (command line) - -Some of the userland tools support extended numeric IPv6 syntax, as -documented in draft-ietf-ipngwg-scopedaddr-format-01.txt. In this case, -you can specify outgoing link, by using name of the outgoing interface like -"fe80::1%ne0". - -When you specify scoped address to the command line, NEVER write the -embedded form (such as ff02:1::1 or fe80:2::fedc). This is not supposed -to work. Always use standard form, like ff02::1 or fe80::fedc, with -command line option for specifying interface (like "ping6 -I ne0 ff02::1). -In general, if a command does not have command line option to specify -outgoing interface, that command is not ready to accept scoped address. -This may seem to be opposite from IPv6's premise to support "dentist office" -situation. We believe that specifications need some improvements for this. - -The only exception to the above rule would be when you configure routing table -manually by route(8), or ndp(8). Gateway portion of IPv6 routing entry must -be an link-local address (otherwise ICMPv6 redirect will not work), and in this -case you'll need to configure it by putting interface index into the address: - # route add -inet6 default fe80:2::9876:5432:1234:5678 - (when interface index for outgoing interface = 2) -To avoid configuration mistakes, we suggest you to run dynamic routing instead -(like route6d(8)). - -1.4 Plug and Play - -The KAME kit implements most of the IPv6 stateless address -autoconfiguration in the kernel. -Neighbor Discovery functions are implemented in the kernel as a whole. -Router Advertisement (RA) input for hosts is implemented in the -kernel. Router Solicitation (RS) output for endhosts, RS input -for routers, and RA output for routers are implemented in the -userland. - -1.4.1 Assignment of link-local, and special addresses - -IPv6 link-local address is generated from IEEE802 address (ethernet MAC -address). Each of interface is assigned an IPv6 link-local address -automatically, when the interface becomes up (IFF_UP). Also, direct route -for the link-local address is added to routing table. - -Here is an output of netstat command: - -Internet6: -Destination Gateway Flags Netif Expire -fe80::%ed0/64 link#1 UC ed0 -fe80::%ep0/64 link#2 UC ep0 - -Interfaces that has no IEEE802 address (pseudo interfaces like tunnel -interfaces, or ppp interfaces) will borrow IEEE802 address from other -interfaces, such as ethernet interfaces, whenever possible. -If there is no IEEE802 hardware attached, last-resort pseudorandom value, -which is from MD5(hostname), will be used as source of link-local address. -If it is not suitable for your usage, you will need to configure the -link-local address manually. - -If an interface is not capable of handling IPv6 (such as lack of multicast -support), link-local address will not be assigned to that interface. -See section 2 for details. - -Each interface joins the solicited multicast address and the -link-local all-nodes multicast addresses (e.g. fe80::1:ff01:6317 -and ff02::1, respectively, on the link the interface is attached). -In addition to a link-local address, the loopback address (::1) will be -assigned to the loopback interface. Also, ::1/128 and ff01::/32 are -automatically added to routing table, and loopback interface joins -node-local multicast group ff01::1. - -1.4.2 Stateless address autoconfiguration on hosts - -In IPv6 specification, nodes are separated into two categories: -routers and hosts. Routers forward packets addressed to others, hosts does -not forward the packets. net.inet6.ip6.forwarding defines whether this -node is router or host (router if it is 1, host if it is 0). - -It is NOT recommended to change net.inet6.ip6.forwarding while the node -is in operation. IPv6 specification defines behavior for "host" and "router" -quite differently, and switching from one to another can cause serious -troubles. It is recommended to configure the variable at bootstrap time only. - -The first step in stateless address configuration is Duplicated Address -Detection (DAD). See 1.2 for more detail on DAD. - -When a host hears Router Advertisement from the router, a host may -autoconfigure itself by stateless address autoconfiguration. -This behavior can be controlled by net.inet6.ip6.accept_rtadv -(host autoconfigures itself if it is set to 1). -By autoconfiguration, network address prefix for the receiving interface -(usually global address prefix) is added. Default route is also configured. -Routers periodically generate Router Advertisement packets. To request -an adjacent router to generate RA packet, a host can transmit Router -Solicitation. To generate a RS packet at any time, use the "rtsol" command. -"rtsold" daemon is also available. "rtsold" generates Router Solicitation -whenever necessary, and it works great for nomadic usage (notebooks/laptops). -If one wishes to ignore Router Advertisements, use sysctl to set -net.inet6.ip6.accept_rtadv to 0. - -To generate Router Advertisement from a router, use the "rtadvd" daemon. - -Note that, IPv6 specification assumes the following items, and nonconforming -cases are left unspecified: -- Only hosts will listen to router advertisements -- Hosts have single network interface (except loopback) -Therefore, this is unwise to enable net.inet6.ip6.accept_rtadv on routers, -or multi-interface host. A misconfigured node can behave strange -(KAME code allows nonconforming configuration, for those who would like -to do some experiments). - -To summarize the sysctl knob: - accept_rtadv forwarding role of the node - --- --- --- - 0 0 host (to be manually configured) - 0 1 router - 1 0 autoconfigured host - (spec assumes that host has single - interface only, autoconfigred host with - multiple interface is out-of-scope) - 1 1 invalid, or experimental - (out-of-scope of spec) - -RFC2462 has validation rule against incoming RA prefix information option, -in 5.5.3 (e). This is to protect hosts from malicious (or misconfigured) -routers that advertise very short prefix lifetime. -There was an update from Jim Bound to ipngwg mailing list (look -for "(ipng 6712)" in the archive) and KAME implements Jim's update. - -See 1.2 in the document for relationship between DAD and autoconfiguration. - -1.4.3 DHCPv6 - -We supply a tiny DHCPv6 server/client in kame/dhcp6. However, the -implementation is very premature (for example, this does NOT -implement address lease/release), and it is not in default compilation -tree. If you want to do some experiment, compile it on your own. - -DHCPv6 and autoconfiguration also needs more work. "Managed" and "Other" -bits in RA have no special effect to stateful autoconfiguration procedure -in DHCPv6 client program ("Managed" bit actually prevents stateless -autoconfiguration, but no special action will be taken for DHCPv6 client). - -1.5 Generic tunnel interface - -GIF (Generic InterFace) is a pseudo interface for configured tunnel. -Details are described in gif(4) manpage. -Currently - v6 in v6 - v6 in v4 - v4 in v6 - v4 in v4 -are available. Use "gifconfig" to assign physical (outer) source -and destination address to gif interfaces. -Configuration that uses same address family for inner and outer IP -header (v4 in v4, or v6 in v6) is dangerous. It is very easy to -configure interfaces and routing tables to perform infinite level -of tunneling. Please be warned. - -gif can be configured to be ECN-friendly. See 4.5 for ECN-friendliness -of tunnels, and gif(4) manpage for how to configure. - -If you would like to configure an IPv4-in-IPv6 tunnel with gif interface, -read gif(4) carefully. You may need to remove IPv6 link-local address -automatically assigned to the gif interface. - -1.6 Source Address Selection - -KAME's source address selection takes care of the following -conditions: -- address scope -- prefix matching against the destination -- outgoing interface -- whether an address is deprecated - -Roughly speaking, the selection policy is as follows: -- always use an address that belongs to the same scope zone as the - destination. -- addresses that have equal or larger scope than the scope of the - destination are preferred. -- if multiple addresses have the equal scope, one which is longest - prefix matching against the destination is preferred. -- a deprecated address is not used in new communications if an - alternate (non-deprecated) address is available and has sufficient - scope. -- if none of above conditions tie-breaks, addresses assigned on the - outgoing interface are preferred. - -For instance, ::1 is selected for ff01::1, -fe80::200:f8ff:fe01:6317%ne0 for fe80::2a0:24ff:feab:839b%ne0. -To see how longest-matching works, suppose that -3ffe:501:808:1:200:f8ff:fe01:6317 and 3ffe:2001:9:124:200:f8ff:fe01:6317 -are given on the outgoing interface. Then the former is chosen as the -source for the destination 3ffe:501:800::1. Note that even if all -available addresses have smaller scope than the scope of the -destination, we choose one anyway. For example, if we have link-local -and site-local addresses only, we choose a site-local addresses for a -global destination. If the packet is going to break a site boundary, -the boundary router will return an ICMPv6 destination unreachable -error with code 2 - beyond scope of source address. - -The precise desripction of the algorithm is quite complicated. To -describe the algorithm, we introduce the following notation: - -For a given destination D, - samescope(D): A set of addresses that have the same scope as D. - largerscope(D): A set of addresses that have a larger scope than D. - smallerscope(D): A set of addresses that have a smaller scope than D. - -For a given set of addresses A, - DEP(A): a set of deprecated addresses in A. - nonDEP(A): A - DEP(A). - -Also, the algorithm assumes that the outgoing interface for the -destination D is determined. We call the interface "I". - -The algorithm is as follows. Selection proceeds step by step as -described; For example, if an address is selected by item 1, item 2 or -later are not considered at all. - - 0. If there is no address in the same scope zone as D, just give up; - the packet will not be sent. - 1. If nonDEP(samescope(D)) is not empty, - choose a longest matching address against D. If more than one - address is longest matching, choose arbitrary one provided that - an address on I is always preferred. - 2. If nonDEP(largerscope(D)) is not empty, - choose an address that has the smallest scope. If more than one - address has the smallest scope, choose arbitrary one provided - that an address on I is always preferred. - 3. If DEP(samescope(D)) is not empty, - choose a longest matching address against D. If more than one - address is longest matching, choose arbitrary one provided that - an address on I is always preferred. - 4. If DEP(largerscope(D)) is not empty, - choose an address that has the smallest scope. If more than one - address has the smallest scope, choose arbitrary one provided - that an address on I is always preferred. - 5. if nonDEP(smallerscope(D)) is not empty, - choose an address that has the largest scope. If more than one - address has the largest scope, choose arbitrary one provided - that an address on I is always preferred. - 6. if DEP(smallerscope(D)) is not empty, - choose an address that has the largest scope. If more than one - address has the largest scope, choose arbitrary one provided - that an address on I is always preferred. - -There exists a document about source address selection -(draft-ietf-ipngwg-default-addr-select-xx.txt). KAME's algorithm -described above takes a similar approach to the document, but there -are some differences. See the document for more details. - -There are some cases where we do not use the above rule. One -example is connected TCP session, and we use the address kept in TCP -protocol control block (tcb) as the source. -Another example is source address for Neighbor Advertisement. -Under the spec (RFC2461 7.2.2) NA's source should be the target -address of the corresponding NS's target. In this case we follow -the spec rather than the above longest-match rule. - -If you would like to prohibit the use of deprecated address for some -reason, configure net.inet6.ip6.use_deprecated to 0. The issue -related to deprecated address is described in RFC2462 5.5.4 (NOTE: -there is some debate underway in IETF ipngwg on how to use -"deprecated" address). - -1.7 Jumbo Payload - -KAME supports the Jumbo Payload hop-by-hop option used to send IPv6 -packets with payloads longer than 65,535 octets. But since currently -KAME does not support any physical interface whose MTU is more than -65,535, such payloads can be seen only on the loopback interface(i.e. -lo0). - -If you want to try jumbo payloads, you first have to reconfigure the -kernel so that the MTU of the loopback interface is more than 65,535 -bytes; add the following to the kernel configuration file: - options "LARGE_LOMTU" #To test jumbo payload -and recompile the new kernel. - -Then you can test jumbo payloads by the ping6 command with -b and -s -options. The -b option must be specified to enlarge the size of the -socket buffer and the -s option specifies the length of the packet, -which should be more than 65,535. For example, type as follows; - % ping6 -b 70000 -s 68000 ::1 - -The IPv6 specification requires that the Jumbo Payload option must not -be used in a packet that carries a fragment header. If this condition -is broken, an ICMPv6 Parameter Problem message must be sent to the -sender. KAME kernel follows the specification, but you cannot usually -see an ICMPv6 error caused by this requirement. - -If KAME kernel receives an IPv6 packet, it checks the frame length of -the packet and compares it to the length specified in the payload -length field of the IPv6 header or in the value of the Jumbo Payload -option, if any. If the former is shorter than the latter, KAME kernel -discards the packet and increments the statistics. You can see the -statistics as output of netstat command with `-s -p ip6' option: - % netstat -s -p ip6 - ip6: - (snip) - 1 with data size < data length - -So, KAME kernel does not send an ICMPv6 error unless the erroneous -packet is an actual Jumbo Payload, that is, its packet size is more -than 65,535 bytes. As described above, KAME kernel currently does not -support physical interface with such a huge MTU, so it rarely returns an -ICMPv6 error. - -TCP/UDP over jumbogram is not supported at this moment. This is because -we have no medium (other than loopback) to test this. Contact us if you -need this. - -IPsec does not work on jumbograms. This is due to some specification twists -in supporting AH with jumbograms (AH header size influences payload length, -and this makes it real hard to authenticate inbound packet with jumbo payload -option as well as AH). - -There are fundamental issues in *BSD support for jumbograms. We would like to -address those, but we need more time to finalize the task. To name a few: -- mbuf pkthdr.len field is typed as "int" in 4.4BSD, so it cannot hold - jumbogram with len > 2G on 32bit architecture CPUs. If we would like to - support jumbogram properly, the field must be expanded to hold 4G + - IPv6 header + link-layer header. Therefore, it must be expanded to at least - int64_t (u_int32_t is NOT enough). -- We mistakingly use "int" to hold packet length in many places. We need - to convert them into larger numeric type. It needs a great care, as we may - experience overflow during packet length computation. -- We mistakingly check for ip6_plen field of IPv6 header for packet payload - length in various places. We should be checking mbuf pkthdr.len instead. - ip6_input() will perform sanity check on jumbo payload option on input, - and we can safely use mbuf pkthdr.len afterwards. -- TCP code needs careful updates in bunch of places, of course. - -1.8 Loop prevention in header processing - -IPv6 specification allows arbitrary number of extension headers to -be placed onto packets. If we implement IPv6 packet processing -code in the way BSD IPv4 code is implemented, kernel stack may -overflow due to long function call chain. KAME sys/netinet6 code -is carefully designed to avoid kernel stack overflow. Because of -this, KAME sys/netinet6 code defines its own protocol switch -structure, as "struct ip6protosw" (see netinet6/ip6protosw.h). -IPv4 part (sys/netinet) remains untouched for compatibility. -Because of this, if you receive IPsec-over-IPv4 packet with massive -number of IPsec headers, kernel stack may blow up. IPsec-over-IPv6 is okay. - -1.9 ICMPv6 - -After RFC2463 was published, IETF ipngwg has decided to disallow ICMPv6 error -packet against ICMPv6 redirect, to prevent ICMPv6 storm on a network medium. -KAME already implements this into the kernel. - -1.10 Applications - -For userland programming, we support IPv6 socket API as specified in -RFC2553, RFC2292 and upcoming internet drafts. - -TCP/UDP over IPv6 is available and quite stable. You can enjoy "telnet", -"ftp", "rlogin", "rsh", "ssh", etc. These applications are protocol -independent. That is, they automatically chooses IPv4 or IPv6 -according to DNS. - -1.11 Kernel Internals - - (*) TCP/UDP part is handled differently between operating system platforms. - See 1.12 for details. - -The current KAME has escaped from the IPv4 netinet logic. While -ip_forward() calls ip_output(), ip6_forward() directly calls -if_output() since routers must not divide IPv6 packets into fragments. - -ICMPv6 should contain the original packet as long as possible up to -1280. UDP6/IP6 port unreach, for instance, should contain all -extension headers and the *unchanged* UDP6 and IP6 headers. -So, all IP6 functions except TCP6 never convert network byte -order into host byte order, to save the original packet. - -tcp6_input(), udp6_input() and icmp6_input() can't assume that IP6 -header is preceding the transport headers due to extension -headers. So, in6_cksum() was implemented to handle packets whose IP6 -header and transport header is not continuous. TCP/IP6 nor UDP/IP6 -header structure don't exist for checksum calculation. - -To process IP6 header, extension headers and transport headers easily, -KAME requires network drivers to store packets in one internal mbuf or -one or more external mbufs. A typical old driver prepares two -internal mbufs for 100 - 208 bytes data, however, KAME's reference -implementation stores it in one external mbuf. - -"netstat -s -p ip6" tells you whether or not your driver conforms -KAME's requirement. In the following example, "cce0" violates the -requirement. (For more information, refer to Section 2.) - - Mbuf statistics: - 317 one mbuf - two or more mbuf:: - lo0 = 8 - cce0 = 10 - 3282 one ext mbuf - 0 two or more ext mbuf - -Each input function calls IP6_EXTHDR_CHECK in the beginning to check -if the region between IP6 and its header is -continuous. IP6_EXTHDR_CHECK calls m_pullup() only if the mbuf has -M_LOOP flag, that is, the packet comes from the loopback -interface. m_pullup() is never called for packets coming from physical -network interfaces. - -TCP6 reassembly makes use of IP6 header to store reassemble -information. IP6 is not supposed to be just before TCP6, so -ip6tcpreass structure has a pointer to TCP6 header. Of course, it has -also a pointer back to mbuf to avoid m_pullup(). - -Like TCP6, both IP and IP6 reassemble functions never call m_pullup(). - -xxx_ctlinput() calls in_mrejoin() on PRC_IFNEWADDR. We think this is -one of 4.4BSD implementation flaws. Since 4.4BSD keeps ia_multiaddrs -in in_ifaddr{}, it can't use multicast feature if the interface has no -unicast address. So, if an application joins to an interface and then -all unicast addresses are removed from the interface, the application -can't send/receive any multicast packets. Moreover, if a new unicast -address is assigned to the interface, in_mrejoin() must be called. -KAME's interfaces, however, have ALWAYS one link-local unicast -address. These extensions have thus not been implemented in KAME. - -1.12 IPv4 mapped address and IPv6 wildcard socket - -RFC2553 describes IPv4 mapped address (3.7) and special behavior -of IPv6 wildcard bind socket (3.8). The spec allows you to: -- Accept IPv4 connections by AF_INET6 wildcard bind socket. -- Transmit IPv4 packet over AF_INET6 socket by using special form of - the address like ::ffff:10.1.1.1. -but the spec itself is very complicated and does not specify how the -socket layer should behave. -Here we call the former one "listening side" and the latter one "initiating -side", for reference purposes. - -Almost all KAME implementations treat tcp/udp port number space separately -between IPv4 and IPv6. You can perform wildcard bind on both of the address -families, on the same port. - -There are some OS-platform differences in KAME code, as we use tcp/udp -code from different origin. The following table summarizes the behavior. - - listening side initiating side - (AF_INET6 wildcard (connection to ::ffff:10.1.1.1) - socket gets IPv4 conn.) - --- --- -KAME/BSDI3 not supported not supported -KAME/FreeBSD228 not supported not supported -KAME/FreeBSD3x configurable supported - default: enabled -KAME/NetBSD configurable supported - default: disabled -KAME/BSDI4 enabled supported -KAME/OpenBSD not supported not supported - -The following sections will give you more details, and how you can -configure the behavior. - -Comments on listening side: - -It looks that RFC2553 talks too little on wildcard bind issue, -specifically on (1) port space issue, (2) failure mode, (3) relationship -between AF_INET/INET6 wildcard bind like ordering constraint, and (4) behavior -when conflicting socket is opened/closed. There can be several separate -interpretation for this RFC which conform to it but behaves differently. -So, to implement portable application you should assume nothing -about the behavior in the kernel. Using getaddrinfo() is the safest way. -Port number space and wildcard bind issues were discussed in detail -on ipv6imp mailing list, in mid March 1999 and it looks that there's -no concrete consensus (means, up to implementers). You may want to -check the mailing list archives. -We supply a tool called "bindtest" that explores the behavior of -kernel bind(2). The tool will not be compiled by default. - -If a server application would like to accept IPv4 and IPv6 connections, -it should use AF_INET and AF_INET6 socket (you'll need two sockets). -Use getaddrinfo() with AI_PASSIVE into ai_flags, and socket(2) and bind(2) -to all the addresses returned. -By opening multiple sockets, you can accept connections onto the socket with -proper address family. IPv4 connections will be accepted by AF_INET socket, -and IPv6 connections will be accepted by AF_INET6 socket (NOTE: KAME/BSDI4 -kernel sometimes violate this - we will fix it). - -If you try to support IPv6 traffic only and would like to reject IPv4 -traffic, always check the peer address when a connection is made toward -AF_INET6 listening socket. If the address is IPv4 mapped address, you may -want to reject the connection. You can check the condition by using -IN6_IS_ADDR_V4MAPPED() macro. This is one of the reasons the author of -the section (itojun) dislikes special behavior of AF_INET6 wildcard bind. - -Comments on initiating side: - -Advise to application implementers: to implement a portable IPv6 application -(which works on multiple IPv6 kernels), we believe that the following -is the key to the success: -- NEVER hardcode AF_INET nor AF_INET6. -- Use getaddrinfo() and getnameinfo() throughout the system. - Never use gethostby*(), getaddrby*(), inet_*() or getipnodeby*(). -- If you would like to connect to destination, use getaddrinfo() and try - all the destination returned, like telnet does. -- Some of the IPv6 stack is shipped with buggy getaddrinfo(). Ship a minimal - working version with your application and use that as last resort. - -If you would like to use AF_INET6 socket for both IPv4 and IPv6 outgoing -connection, you will need tweaked implementation in DNS support libraries, -as documented in RFC2553 6.1. KAME libinet6 includes the tweak in -getipnodebyname(). Note that getipnodebyname() itself is not recommended as -it does not handle scoped IPv6 addresses at all. For IPv6 name resolution -getaddrinfo() is the preferred API. getaddrinfo() does not implement the -tweak. - -When writing applications that make outgoing connections, story goes much -simpler if you treat AF_INET and AF_INET6 as totally separate address family. -{set,get}sockopt issue goes simpler, DNS issue will be made simpler. We do -not recommend you to rely upon IPv4 mapped address. - -1.12.1 KAME/BSDI3 and KAME/FreeBSD228 - -The platforms do not support IPv4 mapped address at all (both listening side -and initiating side). AF_INET6 and AF_INET sockets are totally separated. - -Port number space is totally separate between AF_INET and AF_INET6 sockets. - -1.12.2 KAME/FreeBSD3x - -KAME/FreeBSD3x uses shared tcp4/6 code (from sys/netinet/tcp*) and shared -udp4/6 code (from sys/netinet/udp*). It uses unified inpcb/in6pcb structure. - -1.12.2.1 KAME/FreeBSD3x, listening side - -The platform can be configured to support IPv4 mapped address/special -AF_INET6 wildcard bind (enabled by default). There is no kernel compilation -option to disable it. You can enable/disable the behavior with sysctl -(per-node), or setsockopt (per-socket). - -Wildcard AF_INET6 socket grabs IPv4 connection if and only if the following -conditions are satisfied: -- there's no AF_INET socket that matches the IPv4 connection -- the AF_INET6 socket is configured to accept IPv4 traffic, i.e. - getsockopt(IPV6_BINDV6ONLY) returns 0. - -(XXX need checking) - -1.12.2.2 KAME/FreeBSD3x, initiating side - -KAME/FreeBSD3x supports outgoing connection to IPv4 mapped address -(::ffff:10.1.1.1), if the node is configured to accept IPv4 connections -by AF_INET6 socket. - -(XXX need checking) - -1.12.3 KAME/NetBSD - -KAME/NetBSD uses shared tcp4/6 code (from sys/netinet/tcp*) and shared -udp4/6 code (from sys/netinet/udp*). The implementation is made differently -from KAME/FreeBSD3x. KAME/NetBSD uses separate inpcb/in6pcb structures, -while KAME/FreeBSD3x uses merged inpcb structure. - -1.12.3.1 KAME/NetBSD, listening side - -The platform can be configured to support IPv4 mapped address/special AF_INET6 -wildcard bind (disabled by default). Kernel behavior can be summarized as -follows: -- default: special support code will be compiled in, but is disabled by - default. It can be controlled by sysctl (net.inet6.ip6.bindv6only), - or setsockopt(IPV6_BINDV6ONLY). -- add "INET6_BINDV6ONLY": No special support code for AF_INET6 wildcard socket - will be compiled in. AF_INET6 sockets and AF_INET sockets are totally - separate. The behavior is similar to what described in 1.12.1. - -sysctl setting will affect per-socket configuration at in6pcb creation time -only. In other words, per-socket configuration will be copied from sysctl -configuration at in6pcb creation time. To change per-socket behavior, you -must perform setsockopt or reopen the socket. Change in sysctl configuration -will not change the behavior or sockets that are already opened. - -Wildcard AF_INET6 socket grabs IPv4 connection if and only if the following -conditions are satisfied: -- there's no AF_INET socket that matches the IPv4 connection -- the AF_INET6 socket is configured to accept IPv4 traffic, i.e. - getsockopt(IPV6_BINDV6ONLY) returns 0. - -You cannot bind(2) with IPv4 mapped address. This is a workaround for port -number duplicate and other twists. - -1.12.3.2 KAME/NetBSD, initiating side - -When you initiate a connection, you can always connect to IPv4 destination -over AF_INET6 socket, usin IPv4 mapped address destination (::ffff:10.1.1.1). -This is enabled independently from the configuration for listening side, and -always enabled. - -1.12.4 KAME/BSDI4 - -KAME/BSDI4 uses NRL-based TCP/UDP stack and inpcb source code, -which was derived from NRL IPv6/IPsec stack. I guess it supports IPv4 mapped -address and speical AF_INET6 wildcard bind. The implementation is, again, -different from other KAME/*BSDs. - -1.12.4.1 KAME/BSDI4, listening side - -NRL inpcb layer supports special behavior of AF_INET6 wildcard socket. -There is no way to disable the behavior. - -Wildcard AF_INET6 socket grabs IPv4 connection if and only if the following -condition is satisfied: -- there's no AF_INET socket that matches the IPv4 connection - -1.12.4.2 KAME/BSDI4, initiating side - -KAME/BSDi4 supports connection initiation to IPv4 mapped address -(like ::ffff:10.1.1.1). - -1.12.5 KAME/OpenBSD - -KAME/OpenBSD uses NRL-based TCP/UDP stack and inpcb source code, -which was derived from NRL IPv6/IPsec stack. - -1.12.5.1 KAME/OpenBSD, listening side - -KAME/OpenBSD disables special behavior on AF_INET6 wildcard bind for -security reasons (if IPv4 traffic toward AF_INET6 wildcard bind is allowed, -access control will become much harder). KAME/BSDI4 uses NRL-based TCP/UDP -stack as well, however, the behavior is different due to OpenBSD's security -policy. - -As a result the behavior of KAME/OpenBSD is similar to KAME/BSDI3 and -KAME/FreeBSD228 (see 1.12.1 for more detail). - -1.12.5.2 KAME/OpenBSD, initiating side - -KAME/OpenBSD does not support connection initiation to IPv4 mapped address -(like ::ffff:10.1.1.1). - -1.12.6 More issues - -IPv4 mapped address support adds a big requirement to EVERY userland codebase. -Every userland code should check if an AF_INET6 sockaddr contains IPv4 -mapped address or not. This adds many twists: - -- Access controls code becomes harder to write. - For example, if you would like to reject packets from 10.0.0.0/8, - you need to reject packets to AF_INET socket from 10.0.0.0/8, - and to AF_INET6 socket from ::ffff:10.0.0.0/104. -- If a protocol on top of IPv4 is defined differently with IPv6, we need to be - really careful when we determine which protocol to use. - For example, with FTP protocol, we can not simply use sa_family to determine - FTP command sets. The following example is incorrect: - if (sa_family == AF_INET) - use EPSV/EPRT or PASV/PORT; /*IPv4*/ - else if (sa_family == AF_INET6) - use EPSV/EPRT or LPSV/LPRT; /*IPv6*/ - else - error; - Under SIIT environment, the correct code would be: - if (sa_family == AF_INET) - use EPSV/EPRT or PASV/PORT; /*IPv4*/ - else if (sa_family == AF_INET6 && IPv4 mapped address) - use EPSV/EPRT or PASV/PORT; /*IPv4 command set on AF_INET6*/ - else if (sa_family == AF_INET6 && !IPv4 mapped address) - use EPSV/EPRT or LPSV/LPRT; /*IPv6*/ - else - error; - It is too much to ask for every body to be careful like this. - The problem is, we are not sure if the above code fragment is perfect for - all situations. -- By enabling kernel support for IPv4 mapped address (outgoing direction), - servers on the kernel can be hosed by IPv6 native packet that has IPv4 - mapped address in IPv6 header source, and can generate unwanted IPv4 packets. - http://playground.iijlab.net/i-d/draft-itojun-ipv6-transition-abuse-00.txt - talks more about this scenario. - -Due to the above twists, some of KAME userland programs has restrictions on -the use of IPv4 mapped addresses: -- rshd/rlogind do not accept connections from IPv4 mapped address. - This is to avoid malicious use of IPv4 mapped address in IPv6 native - packet, to bypass source-address based authentication. -- ftp/ftpd does not support SIIT environment. IPv4 mapped address will be - decoded in userland, and will be passed to AF_INET sockets - (SIIT client should pass IPv4 mapped address as is, to AF_INET6 sockets). - -1.13 sockaddr_storage - -When RFC2553 was about to be finalized, there was discussion on how struct -sockaddr_storage members are named. One proposal is to prepend "__" to the -members (like "__ss_len") as they should not be touched. The other proposal -was that don't prepend it (like "ss_len") as we need to touch those members -directly. There was no clear consensus on it. - -As a result, RFC2553 defines struct sockaddr_storage as follows: - struct sockaddr_storage { - u_char __ss_len; /* address length */ - u_char __ss_family; /* address family */ - /* and bunch of padding */ - }; -On the contrary, XNET draft defines as follows: - struct sockaddr_storage { - u_char ss_len; /* address length */ - u_char ss_family; /* address family */ - /* and bunch of padding */ - }; - -In December 1999, it was agreed that RFC2553bis should pick the latter (XNET) -definition. - -KAME kit prior to December 1999 used RFC2553 definition. KAME kit after -December 1999 (including December) will conform to XNET definition, -based on RFC2553bis discussion. - -If you look at multiple IPv6 implementations, you will be able to see -both definitions. As an userland programmer, the most portable way of -dealing with it is to: -(1) ensure ss_family and/or ss_len are available on the platform, by using - GNU autoconf, -(2) have -Dss_family=__ss_family to unify all occurences (including header - file) into __ss_family, or -(3) never touch __ss_family. cast to sockaddr * and use sa_family like: - struct sockaddr_storage ss; - family = ((struct sockaddr *)&ss)->sa_family - -1.14 Invalid addresses on the wire - -Some of IPv6 transition technologies embed IPv4 address into IPv6 address. -These specifications themselves are fine, however, there can be certain -set of attacks enabled by these specifications. Recent speicifcation -documents covers up those issues, however, there are already-published RFCs -that does not have protection against those (like using source address of -::ffff:127.0.0.1 to bypass "reject packet from remote" filter). - -To name a few, these address ranges can be used to hose an IPv6 implementation, -or bypass security controls: -- IPv4 mapped address that embeds unspecified/multicast/loopback/broadcast - IPv4 address (if they are in IPv6 native packet header, they are malicious) - ::ffff:0.0.0.0/104 ::ffff:127.0.0.0/104 - ::ffff:224.0.0.0/100 ::ffff:255.0.0.0/104 -- 6to4 prefix generated from unspecified/multicast/loopback/broadcast/private - IPv4 address - 2002:0000::/24 2002:7f00::/24 2002:e000::/24 - 2002:ff00::/24 2002:0a00::/24 2002:ac10::/28 - 2002:c0a8::/32 - -Also, since KAME does not support RFC1933 auto tunnels, seeing IPv4 compatible -is very rare. You should take caution if you see those on the wire. - -KAME code is carefully written to avoid such incidents. More specifically, -KAME kernel will reject packets with certain source/dstination address in IPv6 -base header, or IPv6 routing header. Also, KAME default configuration file -is written carefully, to avoid those attacks. - -http://playground.iijlab.net/i-d/draft-itojun-ipv6-transition-abuse-00.txt -talks about more about this. - -1.15 Node's required addresses - -RFC2373 section 2.8 talks about required addresses for an IPv6 -node. The section talks about how KAME stack manages those required -addresses. - -1.15.1 Host case - -The following items are automatically assigned to the node (or the node will -automatically joins the group), at bootstrap time: -- Loopback address -- All-nodes multicast addresses (ff01::1) - -The following items will be automatically handled when the interface becomes -IFF_UP: -- Its link-local address for each interface -- Solicited-node multicast address for link-local addresses -- Link-local allnodes multicast address (ff02::1) - -The following items need to be configured manually by ifconfig(8) or prefix(8). -Alternatively, these can be autoconfigured by using stateless address -autoconfiguration. -- Assigned unicast/anycast addresses -- Solicited-Node multicast address for assigned unicast address - -Users can join groups by using appropriate system calls like setsockopt(2). - -1.15.2 Router case - -In addition to the above, routers needs to handle the following items. - -The following items need to be configured manually by using ifconfig(8). -o The subnet-router anycast addresses for the interfaces it is configured - to act as a router on (prefix::/64) -o All other anycast addresses with which the router has been configured - -The router will join the following multicast group when rtadvd(8) is available -for the interface. -o All-Routers Multicast Addresses (ff02::2) - -Routing daemons will join appropriate multicast groups, as necessary, -like ff02::9 for RIPng. - -Users can join groups by using appropriate system calls like setsockopt(2). - -2. Network Drivers - -KAME requires three items to be added into the standard drivers: - -(1) mbuf clustering requirement. In this stable release, we changed - MINCLSIZE into MHLEN+1 for all the operating systems in order to make - all the drivers behave as we expect. - -(2) multicast. If "ifmcstat" yields no multicast group for a - interface, that interface has to be patched. - -To avoid troubles, we suggest you to comment out the device drivers -for unsupported/unnecessary cards, from the kernel configuration file. -If you accidentally enable unsupported drivers, some of the userland -tools may not work correctly (routing daemons are typical example). - -In the following sections, "official support" means that KAME developers -are using that ethernet card/driver frequently. - -(NOTE: In the past we required all pcmcia drivers to have a call to -in6_ifattach(). We have no such requirement any more) - -2.1 FreeBSD 2.2.x-RELEASE - -Here is a list of FreeBSD 2.2.x-RELEASE drivers and its conditions: - - driver mbuf(1) multicast(2) official support? - --- --- --- --- - (Ethernet) - ar looks ok - - - cnw ok ok yes (*) - ed ok ok yes - ep ok ok yes - fe ok ok yes - sn looks ok - - (*) - vx looks ok - - - wlp ok ok - (*) - xl ok ok yes - zp ok ok - - (FDDI) - fpa looks ok ? - - (ATM) - en ok ok yes - (Serial) - lp ? - not work - sl ? - not work - sr looks ok ok - (**) - -You may want to add an invocation of "rtsol" in "/etc/pccard_ether", -if you are using notebook computers and PCMCIA ethernet card. - -(*) These drivers are distributed with PAO (http://www.jp.freebsd.org/PAO/). - -(**) There was some report says that, if you make sr driver up and down and -then up, the kernel may hang up. We have disabled frame-relay support from -sr driver and after that this looks to be working fine. If you need -frame-relay support to come back, please contact KAME developers. - -2.2 BSD/OS 3.x - -The following lists BSD/OS 3.x device drivers and its conditions: - - driver mbuf(1) multicast(2) official support? - --- --- --- --- - (Ethernet) - cnw ok ok yes - de ok ok - - df ok ok - - eb ok ok - - ef ok ok yes - exp ok ok - - mz ok ok yes - ne ok ok yes - we ok ok - - (FDDI) - fpa ok ok - - (ATM) - en maybe ok - - (Serial) - ntwo ok ok yes - sl ? - not work - appp ? - not work - -You may want to use "@insert" directive in /etc/pccard.conf to invoke -"rtsol" command right after dynamic insertion of PCMCIA ethernet cards. - -2.3 NetBSD - -The following table lists the network drivers we have tried so far. - - driver mbuf(1) multicast(2) official support? - --- --- --- --- - (Ethernet) - awi pcmcia/i386 ok ok - - bah zbus/amiga NG(*) - cnw pcmcia/i386 ok ok yes - ep pcmcia/i386 ok ok - - le sbus/sparc ok ok yes - ne pci/i386 ok ok yes - ne pcmcia/i386 ok ok yes - wi pcmcia/i386 ok ok yes - (ATM) - en pci/i386 ok ok - - -(*) This may need some fix, but I'm not sure what arcnet interfaces assume... - -2.4 FreeBSD 3.x-RELEASE - -Here is a list of FreeBSD 3.x-RELEASE drivers and its conditions: - - driver mbuf(1) multicast(2) official support? - --- --- --- --- - (Ethernet) - cnw ok ok -(*) - ed ? ok - - ep ok ok - - fe ok ok yes - fxp ?(**) - lnc ? ok - - sn ? ? -(*) - wi ok ok yes - xl ? ok - - -(*) These drivers are distributed with PAO as PAO3 - (http://www.jp.freebsd.org/PAO/). -(**) there are trouble reports with multicast filter initialization. - -More drivers will just simply work on KAME FreeBSD 3.x-RELEASE but have not -been checked yet. - -2.5 OpenBSD 2.x - -Here is a list of OpenBSD 2.x drivers and its conditions: - - driver mbuf(1) multicast(2) official support? - --- --- --- --- - (Ethernet) - de pci/i386 ok ok yes - fxp pci/i386 ?(*) - le sbus/sparc ok ok yes - ne pci/i386 ok ok yes - ne pcmcia/i386 ok ok yes - -(*) There seem to be some problem in driver, with multicast filter -configuration. This happens with certain revision of chipset on the card. -Should be fixed by now by workaround in sys/net/if.c, but still not sure. - -2.6 BSD/OS 4.x - -The following lists BSD/OS 4.x device drivers and its conditions: - - driver mbuf(1) multicast(2) official support? - --- --- --- --- - (Ethernet) - de ok ok yes - exp (*) - -You may want to use "@insert" directive in /etc/pccard.conf to invoke -"rtsol" command right after dynamic insertion of PCMCIA ethernet cards. - -(*) exp driver has serious conflict with KAME initialization sequence. -A workaround is committed into sys/i386/pci/if_exp.c, and should be okay by now. - -3. Translator - -We categorize IPv4/IPv6 translator into 4 types. - -Translator A --- It is used in the early stage of transition to make -it possible to establish a connection from an IPv6 host in an IPv6 -island to an IPv4 host in the IPv4 ocean. - -Translator B --- It is used in the early stage of transition to make -it possible to establish a connection from an IPv4 host in the IPv4 -ocean to an IPv6 host in an IPv6 island. - -Translator C --- It is used in the late stage of transition to make it -possible to establish a connection from an IPv4 host in an IPv4 island -to an IPv6 host in the IPv6 ocean. - -Translator D --- It is used in the late stage of transition to make it -possible to establish a connection from an IPv6 host in the IPv6 ocean -to an IPv4 host in an IPv4 island. - -KAME provides an TCP relay translator for category A. This is called -"FAITH". We also provide IP header translator for category A. - -3.1 FAITH TCP relay translator - -FAITH system uses TCP relay daemon called "faithd" helped by the KAME kernel. -FAITH will reserve an IPv6 address prefix, and relay TCP connection -toward that prefix to IPv4 destination. - -For example, if the reserved IPv6 prefix is 3ffe:0501:0200:ffff::, and -the IPv6 destination for TCP connection is 3ffe:0501:0200:ffff::163.221.202.12, -the connection will be relayed toward IPv4 destination 163.221.202.12. - - destination IPv4 node (163.221.202.12) - ^ - | IPv4 tcp toward 163.221.202.12 - FAITH-relay dual stack node - ^ - | IPv6 TCP toward 3ffe:0501:0200:ffff::163.221.202.12 - source IPv6 node - -faithd must be invoked on FAITH-relay dual stack node. - -For more details, consult kame/kame/faithd/README and -draft-ietf-ngtrans-tcpudp-relay-01.txt. - -3.2 IPv6-to-IPv4 header translator - -# removed since it is not imported to NetBSD-current - -4. IPsec - -IPsec is implemented as the following three components. - -(1) Policy Management -(2) Key Management -(3) AH, ESP and IPComp handling in kernel - -Note that KAME/OpenBSD does NOT include support for KAME IPsec code, -as OpenBSD team has their home-brew IPsec stack and they have no plan -to replace it. IPv6 support for IPsec is, therefore, lacking on KAME/OpenBSD. - -4.1 Policy Management - -The kernel implements experimental policy management code. There are two way -to manage security policy. One is to configure per-socket policy using -setsockopt(3). In this cases, policy configuration is described in -ipsec_set_policy(3). The other is to configure kernel packet filter-based -policy using PF_KEY interface, via setkey(8). - -The policy entry will be matched in order. The order of entries makes -difference in behavior. - -4.2 Key Management - -The key management code implemented in this kit (sys/netkey) is a -home-brew PFKEY v2 implementation. This conforms to RFC2367. - -The home-brew IKE daemon, "racoon" is included in the kit (kame/kame/racoon, -or usr.sbin/racoon). -Basically you'll need to run racoon as daemon, then setup a policy -to require keys (like ping -P 'out ipsec esp/transport//use'). -The kernel will contact racoon daemon as necessary to exchange keys. - -In IKE spec, there's ambiguity about interpretation of "tunnel" proposal. -For example, if we would like to propose the use of following packet: - IP AH ESP IP payload -some implementation proposes it as "AH transport and ESP tunnel", since -this is more logical from packet construction point of view. Some -implementation proposes it as "AH tunnel and ESP tunnel". -Racoon follows the former route. -This raises real interoperability issue. We hope this to be resolved quickly. - -4.3 AH and ESP handling - -IPsec module is implemented as "hooks" to the standard IPv4/IPv6 -processing. When sending a packet, ip{,6}_output() checks if ESP/AH -processing is required by checking if a matching SPD (Security -Policy Database) is found. If ESP/AH is needed, -{esp,ah}{4,6}_output() will be called and mbuf will be updated -accordingly. When a packet is received, {esp,ah}4_input() will be -called based on protocol number, i.e. (*inetsw[proto])(). -{esp,ah}4_input() will decrypt/check authenticity of the packet, -and strips off daisy-chained header and padding for ESP/AH. It is -safe to strip off the ESP/AH header on packet reception, since we -will never use the received packet in "as is" form. - -By using ESP/AH, TCP4/6 effective data segment size will be affected by -extra daisy-chained headers inserted by ESP/AH. Our code takes care of -the case. - -Basic crypto functions can be found in directory "sys/crypto". ESP/AH -transform are listed in {esp,ah}_core.c with wrapper functions. If you -wish to add some algorithm, add wrapper function in {esp,ah}_core.c, and -add your crypto algorithm code into sys/crypto. - -Tunnel mode works basically fine, but comes with the following restrictions: -- You cannot run routing daemon across IPsec tunnel, since we do not model - IPsec tunnel as pseudo interfaces. -- Authentication model for AH tunnel must be revisited. We'll need to - improve the policy management engine, eventually. -- Tunnelling for IPv6 IPsec is still incomplete. This is disabled by default. - If you need to perform experiments, add "options IPSEC_IPV6FWD" into - the kernel configuration file. Note that path MTU discovery does not work - across IPv6 IPsec tunnel gateway due to insufficient code. - -AH specificaton does not talk much about "multiple AH on a packet" case. -We incrementally compute AH checksum, from inside to outside. Also, we -treat inner AH to be immutable. -For example, if we are to create the following packet: - IP AH1 AH2 AH3 payload -we do it incrementally. As a result, we get crypto checksums like below: - AH3 has checksum against "IP AH3' payload". - where AH3' = AH3 with checksum field filled with 0. - AH2 has checksum against "IP AH2' AH3 payload". - AH1 has checksum against "IP AH1' AH2 AH3 payload", -Also note that AH3 has the smallest sequence number, and AH1 has the largest -sequence number. - -4.4 IPComp handling - -IPComp stands for IP payload compression protocol. This is aimed for -payload compression, not the header compression like PPP VJ compression. -This may be useful when you are using slow serial link (say, cell phone) -with powerful CPU (well, recent notebook PCs are really powerful...). -The protocol design of IPComp is very similar to IPsec, though it was -defined separately from IPsec itself. - -Here are some points to be noted: -- IPComp is treated as part of IPsec protocol suite, and SPI and - CPI space is unified. Spec says that there's no relationship - between two so they are assumed to be separate in specs. -- IPComp association (IPCA) is kept in SAD. -- It is possible to use well-known CPI (CPI=2 for DEFLATE for example), - for outbound/inbound packet, but for indexing purposes one element from - SPI/CPI space will be occupied anyway. -- pfkey is modified to support IPComp. However, there's no official - SA type number assignment yet. Portability with other IPComp - stack is questionable (anyway, who else implement IPComp on UN*X?). -- Spec says that IPComp output processing must be performed before AH/ESP - output processing, to achieve better compression ratio and "stir" data - stream before encryption. The most meaningful processing order is: - (1) compress payload by IPComp, (2) encrypt payload by ESP, then (3) attach - authentication data by AH. - However, with manual SPD setting, you are able to violate the ordering - (KAME code is too generic, maybe). Also, it is just okay to use IPComp - alone, without AH/ESP. -- Though the packet size can be significantly decreased by using IPComp, no - special consideration is made about path MTU (spec talks nothing about MTU - consideration). IPComp is designed for serial links, not ethernet-like - medium, it seems. -- You can change compression ratio on outbound packet, by changing - deflate_policy in sys/netinet6/ipcomp_core.c. You can also change outbound - history buffer size by changing deflate_window_out in the same source code. - (should it be sysctl accessible, or per-SAD configurable?) -- Tunnel mode IPComp is not working right. KAME box can generate tunnelled - IPComp packet, however, cannot accept tunneled IPComp packet. -- You can negotiate IPComp association with racoon IKE daemon. -- KAME code does not attach Adler32 checksum to compressed data. - see ipsec wg mailing list discussion in Jan 2000 for details. - -4.5 Conformance to RFCs and IDs - -The IPsec code in the kernel conforms (or, tries to conform) to the -following standards: - "old IPsec" specification documented in rfc182[5-9].txt - "new IPsec" specification documented in rfc240[1-6].txt, rfc241[01].txt, - rfc2451.txt and draft-mcdonald-simple-ipsec-api-01.txt (draft expired, - but you can take from ftp://ftp.kame.net/pub/internet-drafts/). - (NOTE: IKE specifications, rfc240[7-9].txt are implemented in userland, - as "racoon" IKE daemon) - IPComp: - RFC2393: IP Payload Compression Protocol (IPComp) - -Currently supported algorithms are: - old IPsec AH - null crypto checksum (no document, just for debugging) - keyed MD5 with 128bit crypto checksum (rfc1828.txt) - keyed SHA1 with 128bit crypto checksum (no document) - HMAC MD5 with 128bit crypto checksum (rfc2085.txt) - HMAC SHA1 with 128bit crypto checksum (no document) - old IPsec ESP - null encryption (no document, similar to rfc2410.txt) - DES-CBC mode (rfc1829.txt) - new IPsec AH - null crypto checksum (no document, just for debugging) - keyed MD5 with 96bit crypto checksum (no document) - keyed SHA1 with 96bit crypto checksum (no document) - HMAC MD5 with 96bit crypto checksum (rfc2403.txt - HMAC SHA1 with 96bit crypto checksum (rfc2404.txt) - new IPsec ESP - null encryption (rfc2410.txt) - DES-CBC with derived IV - (draft-ietf-ipsec-ciph-des-derived-01.txt, draft expired) - DES-CBC with explicit IV (rfc2405.txt) - 3DES-CBC with explicit IV (rfc2451.txt) - BLOWFISH CBC (rfc2451.txt) - CAST128 CBC (rfc2451.txt) - RC5 CBC (rfc2451.txt) - each of the above can be combined with: - ESP authentication with HMAC-MD5(96bit) - ESP authentication with HMAC-SHA1(96bit) - IPComp - RFC2394: IP Payload Compression Using DEFLATE - -The following algorithms are NOT supported: - old IPsec AH - HMAC MD5 with 128bit crypto checksum + 64bit replay prevention - (rfc2085.txt) - keyed SHA1 with 160bit crypto checksum + 32bit padding (rfc1852.txt) - -The key/policy management API is based on the following document, with fair -amount of extensions: - RFC2367: PF_KEY key management API - -4.6 ECN consideration on IPsec tunnels - -KAME IPsec implements ECN-friendly IPsec tunnel, described in -draft-ietf-ipsec-ecn-02.txt. -Normal IPsec tunnel is described in RFC2401. On encapsulation, -IPv4 TOS field (or, IPv6 traffic class field) will be copied from inner -IP header to outer IP header. On decapsulation outer IP header -will be simply dropped. The decapsulation rule is not compatible -with ECN, since ECN bit on the outer IP TOS/traffic class field will be -lost. -To make IPsec tunnel ECN-friendly, we should modify encapsulation -and decapsulation procedure. This is described in -draft-ietf-ipsec-ecn-02.txt, chapter 3.3. - -KAME IPsec tunnel implementation can give you three behaviors, by setting -net.inet.ipsec.ecn (or net.inet6.ipsec6.ecn) to some value: -- RFC2401: no consideration for ECN (sysctl value -1) -- ECN forbidden (sysctl value 0) -- ECN allowed (sysctl value 1) -Note that the behavior is configurable in per-node manner, not per-SA manner -(draft-ietf-ipsec-ecn-02 wants per-SA configuration, but it looks too much -for me). - -The behavior is summarized as follows (see source code for more detail): - - encapsulate decapsulate - --- --- -RFC2401 copy all TOS bits drop TOS bits on outer - from inner to outer. (use inner TOS bits as is) - -ECN forbidden copy TOS bits except for ECN drop TOS bits on outer - (masked with 0xfc) from inner (use inner TOS bits as is) - to outer. set ECN bits to 0. - -ECN allowed copy TOS bits except for ECN use inner TOS bits with some - CE (masked with 0xfe) from change. if outer ECN CE bit - inner to outer. is 1, enable ECN CE bit on - set ECN CE bit to 0. the inner. - -General strategy for configuration is as follows: -- if both IPsec tunnel endpoint are capable of ECN-friendly behavior, - you'd better configure both end to "ECN allowed" (sysctl value 1). -- if the other end is very strict about TOS bit, use "RFC2401" - (sysctl value -1). -- in other cases, use "ECN forbidden" (sysctl value 0). -The default behavior is "ECN forbidden" (sysctl value 0). - -For more information, please refer to: - draft-ietf-ipsec-ecn-02.txt - RFC2481 (Explicit Congestion Notification) - KAME sys/netinet6/{ah,esp}_input.c - -(Thanks goes to Kenjiro Cho for detailed analysis) - -4.7 Interoperability - -IPsec, IPComp (in kernel) and IKE (in userland as "racoon") has been tested -at several interoperability test events, and it is known to interoperate -with many other implementations well. Also, KAME IPsec has quite wide -coverage for IPsec crypto algorithms documented in RFC (we do not cover -algorithms with intellectual property issues, though). - -Here are (some of) platforms we have tested IPsec/IKE interoperability -in the past, in no particular order. Note that both ends (KAME and -others) may have modified their implementation, so use the following -list just for reference purposes. - Altiga, Ashley-laurent (vpcom.com), Data Fellows (F-Secure), - BlueSteel, CISCO, Ericsson, ACC, Fitel, FreeS/WAN, HITACHI, IBM - AIX, IIJ, Intel, Microsoft WinNT, NAI PGPnet, - NIST (linux IPsec + plutoplus), Netscreen, OpenBSD isakmpd, Radguard, - RedCreek, Routerware, SSH, Secure Computing, Soliton, Toshiba, - TIS/NAI Gauntret, VPNet, Yamaha RT100i - -Here are (some of) platforms we have tested IPComp/IKE interoperability -in the past, in no particular order. - IRE - -5. ALTQ - -# removed since it is not imported to NetBSD-current - -6. mobile-ip6 - -# removed since it is not imported to NetBSD-current - - diff --git a/netbsd/sys/netinet6/Makefile b/netbsd/sys/netinet6/Makefile index 527d8db785..43b26c9cdc 100644 --- a/netbsd/sys/netinet6/Makefile +++ b/netbsd/sys/netinet6/Makefile @@ -1,12 +1,12 @@ -# $NetBSD: Makefile,v 1.4 2000/06/04 11:52:10 itojun Exp $ +# $NetBSD: Makefile,v 1.5 2001/10/18 09:12:14 itojun Exp $ KDIR= /sys/netinet6 INCSDIR= /usr/include/netinet6 INCS= ah.h esp.h in6.h in6_gif.h in6_ifattach.h in6_pcb.h \ in6_var.h ip6_mroute.h ip6_var.h ip6protosw.h \ - ipcomp.h ipsec.h mld6_var.h nd6.h pim6.h pim6_var.h udp6.h udp6_var.h -INCS+= raw_ip6.h + ipcomp.h ipsec.h mld6_var.h nd6.h pim6.h pim6_var.h \ + raw_ip6.h udp6.h udp6_var.h INCS+= mip6.h mip6_var.h INCS+= in6_msf.h diff --git a/netbsd/sys/netinet6/TODO b/netbsd/sys/netinet6/TODO deleted file mode 100644 index 3ddf57fb4c..0000000000 --- a/netbsd/sys/netinet6/TODO +++ /dev/null @@ -1,120 +0,0 @@ -KAME/NetBSD integration TODOs -$NetBSD: TODO,v 1.12 2000/02/05 18:11:41 itojun Exp $ -Jun-ichiro itojun Hagino - - -This file talks about issues/TODOs in KAME/NetBSD integration. -For details about original KAME distribution, please refer to -sys/netinet6/IMPLEMENTATION, or documents in KAME distribution. - - -KERNEL -====== -* net/if_types.h - -IFT_GIF and IFT_FAITH are not defined in IANA assignment, but we need to -define these two (they are essential). If it is prohibited to define these, -where should we check to get interface type? if_xname? - -* ATM PVC support in Adaptec/ENI ATM driver - -Is it MI enough? If not, would you like it to be removed from the tree? -Actually this is quite useful (we use it in Japanese ATM PVC leased line -service and is quite stable). - -* mbuf pullup consideration - -KAME IPv6 onion-peeling routine assumes that headers are contiguous on -mbufs. For this we impose little restriction on drivers (namely, -MINCLSIZE has been modified for this). From stats we gathered it has no -impact on performance (maybe better due to less m_pullup), but some of -you may not like this (you may hate deep-copy code in net/if_loop.c). -We may need to implement safer way, something similar to m_pullup(). -I have an idea but I still need some time for this. I'll test this in -KAME tree and then will bring it to NetBSD. -(NOTE: m_pullup is not very useful for IPv6 as the chained header length -can easily exceed MHLEN. Remember, IPv6 header itself already occupies 40 -bytes) - -KAME team is doing experiments with m_pulldown(). will migrate to m_pulldown() -after stabilization. working nicely but need more tests and code reviews. - -* ipsec socket pointer - -We currently reuse m_pkthdr.rcvif for ipsec socket pointer, and ipf and -other code does not like this. - -It is planned to add m->m_pkthdr.aux (pointer to mbuf chain) to carry around -extra information for IPsec and other cases. - -* gre/ipip compatibility - -Hope I did not break any of these... Could someone check? - -* mbuf flags - -KAME code introduces 5 mbuf flags, which should be decreased. M_ANYCAST6 -is local to IPv6 code so it should be M_PROTO0 or something like that. -Others (IPsec items) are used across IPv4 and IPv6 so they cannot be in -M_PROTO0 kind of thing. - -When we switch to full m->m_pkthdr.aux support, we don't need IPsec related -flags in m->m_flags. - -* use of xx_control() from kernel - -xx_control() are designed to be called from userland process, not -from within the kernel. Calling xx_control() from interrupt context would -cause various problems, like M_WAIT/NOWAIT issue, spl issue and others. -we need to clean it up. The right thing to happen is to split those -necessary functions into (1) called-from-userland function, (2) called-from- -interrupt function, and (3) common backend which shares as much code as -possible. in6_prefix.c is the offending portion. - -* more LP64 friendliness checking - -* scoped address printing - -KAME implements extended format for link-local address printing, like -"fe80::1@lo0". After long debate, IETF ipngwg will pick "lo0%fe80::1" as -standard one (picked "%" for avoiding conflict with "user@host" notation). -We'll need to update the support before the release. - -* PRC_IF{UP,CHANGE} - -We have some hook in sys/net/if.c for IPv6, for detecting (1) when interface -bringed up, and (2) when interface MTU changes. These hooks should be -removed by introducing PRC_IF{UP,CHANGE}. - - -USERLAND -======== -* pim6dd/pim6sd licensing - -pim6dd/pim6sd license issue should be clarified, just like we need -clarification for mroute6d. - -* IPv6-support in resolvers and libraries - -Dual stack resolver code is from KAME. The change may not be compatible with -future bind8 code, so we may have to merge future bind8 carefully. -(or we should volunteer for bind8 improvements) - -At this moment IPv6 support in lib/libc/net/* is implemented in very -conservative way so that it will not break existing codebase. - -* -DINET6, -DIPSEC - -Where should we define -DINET6? Should it be global option like -EXPORTABLE_SYSTEM=1 (in /etc/mk.conf), or local option defined somewhere? -(some people may need a binary tree with no IPv6 support at all, for -smaller footprint) - -At this moment -DINET6 is placed in each of leaf directory Makefiles, -and there's no global option for enabling/disabling userland IPv6/IPsec -support. Since we ship single binary tree we want to ship them enabled -by default. - -* more IPv6 support - -X11, NFS, RPC, whatever. diff --git a/netbsd/sys/sys/malloc.h b/netbsd/sys/sys/malloc.h index 30a562b2d3..e0895f34bd 100644 --- a/netbsd/sys/sys/malloc.h +++ b/netbsd/sys/sys/malloc.h @@ -1,4 +1,4 @@ -/* $NetBSD: malloc.h,v 1.77.10.1 2002/07/21 03:35:56 lukem Exp $ */ +/* $NetBSD: malloc.h,v 1.77.10.2 2002/12/16 04:56:46 jmc Exp $ */ /* * Copyright (c) 1987, 1993 @@ -433,11 +433,14 @@ do { \ long s = splvm(); \ if (kbp->kb_next == NULL) { \ (space) = (cast)malloc((u_long)(size), (type), (flags)); \ + splx(s); \ } else { \ (space) = (cast)kbp->kb_next; \ kbp->kb_next = *(caddr_t *)(space); \ + splx(s); \ + if ((flags) & M_ZERO) \ + memset((space), 0, (size)); \ } \ - splx(s); \ } while (/* CONSTCOND */ 0) #define FREE(addr, type) \ diff --git a/netbsd/sys/sys/mbuf.h b/netbsd/sys/sys/mbuf.h index bdbc9a5210..57c4ad68d5 100644 --- a/netbsd/sys/sys/mbuf.h +++ b/netbsd/sys/sys/mbuf.h @@ -216,10 +216,8 @@ struct mbuf { #define M_LOOP 0x0040 /* for Mbuf statistics */ #define M_AUTHIPDGM 0x0080 /* data origin authentication */ -#define M_AUX 0x8000 /* mbufs pointed to by m->m_pkthdr.aux */ - /* flags copied when copying m_pkthdr */ -#define M_COPYFLAGS (M_PKTHDR|M_EOR|M_BCAST|M_MCAST|M_CANFASTFWD|M_LINK0|M_LINK1|M_LINK2|M_AUTHIPHDR|M_DECRYPTED|M_LOOP|M_AUTHIPDGM|M_AUX|M_NOTIFICATION) +#define M_COPYFLAGS (M_PKTHDR|M_EOR|M_BCAST|M_MCAST|M_CANFASTFWD|M_LINK0|M_LINK1|M_LINK2|M_AUTHIPHDR|M_DECRYPTED|M_LOOP|M_AUTHIPDGM|M_NOTIFICATION) /* mbuf types */ #define MT_FREE 0 /* should be on free list */ diff --git a/netbsd/sys/sys/sockio.h b/netbsd/sys/sys/sockio.h index e47549fdaf..4a730d0764 100644 --- a/netbsd/sys/sys/sockio.h +++ b/netbsd/sys/sys/sockio.h @@ -1,4 +1,4 @@ -/* $NetBSD: sockio.h,v 1.18 2001/06/02 16:17:11 thorpej Exp $ */ +/* $NetBSD: sockio.h,v 1.18.16.1 2002/11/01 10:55:45 tron Exp $ */ /* * Copyright (c) 2002 INRIA. All rights reserved. @@ -112,11 +112,11 @@ #define SIOCDIFADDR _IOW('i', 25, struct ifreq) /* delete IF addr */ #define SIOCAIFADDR _IOW('i', 26, struct ifaliasreq)/* add/chg IF alias */ -#define SIOCGIFALIAS _IOWR('i', 27, struct ifaliasreq)/* get IF alias */ +#define SIOCGIFALIAS _IOWR('i', 27, struct ifaliasreq)/* get IF alias */ -#define SIOCALIFADDR _IOW('i', 28, struct if_laddrreq) /* add IF addr */ -#define SIOCGLIFADDR _IOWR('i', 29, struct if_laddrreq) /* get IF addr */ -#define SIOCDLIFADDR _IOW('i', 30, struct if_laddrreq) /* delete IF addr */ +#define SIOCALIFADDR _IOW('i', 28, struct if_laddrreq) /* add IF addr */ +#define SIOCGLIFADDR _IOWR('i', 29, struct if_laddrreq) /* get IF addr */ +#define SIOCDLIFADDR _IOW('i', 30, struct if_laddrreq) /* delete IF addr */ #define SIOCADDMULTI _IOW('i', 49, struct ifreq) /* add m'cast addr */ #define SIOCDELMULTI _IOW('i', 50, struct ifreq) /* del m'cast addr */ @@ -131,24 +131,28 @@ #define SIOCGIFGENERIC _IOWR('i', 58, struct ifreq) /* generic IF get op */ #define SIOCDIFGENERIC _IOWR('i', 59, struct ifreq) /* generic IF del op */ -#define SIOCSIFPHYADDR _IOW('i', 70, struct ifaliasreq) /* set gif addres */ +#define SIOCSIFPHYADDR _IOW('i', 70, struct ifaliasreq) /* set gif addres */ #define SIOCGIFPSRCADDR _IOWR('i', 71, struct ifreq) /* get gif psrc addr */ #define SIOCGIFPDSTADDR _IOWR('i', 72, struct ifreq) /* get gif pdst addr */ -#define SIOCDIFPHYADDR _IOW('i', 73, struct ifreq) /* delete gif addrs */ +#define SIOCDIFPHYADDR _IOW('i', 73, struct ifreq) /* delete gif addrs */ #define SIOCSLIFPHYADDR _IOW('i', 74, struct if_laddrreq) /* set gif addrs */ #define SIOCGLIFPHYADDR _IOWR('i', 75, struct if_laddrreq) /* get gif addrs */ #define SIOCGSTFMODE _IOWR('i', 76, struct ifreq) /* get stf mode */ #define SIOCSSTFMODE _IOW('i', 77, struct ifreq) /* set stf mode */ +#define SIOCZIFDATA _IOWR('i', 129, struct ifdatareq) /* get if_data then + zero ctrs*/ +#define SIOCGIFDATA _IOWR('i', 128, struct ifdatareq) /* get if_data */ + #define SIOCSIFMTU _IOW('i', 127, struct ifreq) /* set ifnet mtu */ #define SIOCGIFMTU _IOWR('i', 126, struct ifreq) /* get ifnet mtu */ #define SIOCSIFASYNCMAP _IOW('i', 125, struct ifreq) /* set ppp asyncmap */ #define SIOCGIFASYNCMAP _IOWR('i', 124, struct ifreq) /* get ppp asyncmap */ -#define SIOCSDRVSPEC _IOW('i', 123, struct ifdrv) /* set driver-specific +#define SIOCSDRVSPEC _IOW('i', 123, struct ifdrv) /* set driver-specific parameters */ -#define SIOCGDRVSPEC _IOWR('i', 123, struct ifdrv) /* get driver-specific +#define SIOCGDRVSPEC _IOWR('i', 123, struct ifdrv) /* get driver-specific parameters */ #define SIOCIFCREATE _IOW('i', 122, struct ifreq) /* create clone if */ diff --git a/netbsd/sys/sys/systm.h b/netbsd/sys/sys/systm.h index 24c6019df7..5e06ab5b8b 100644 --- a/netbsd/sys/sys/systm.h +++ b/netbsd/sys/sys/systm.h @@ -1,4 +1,4 @@ -/* $NetBSD: systm.h,v 1.144 2002/05/21 01:38:26 thorpej Exp $ */ +/* $NetBSD: systm.h,v 1.144.2.1 2002/11/09 10:21:27 tron Exp $ */ /*- * Copyright (c) 1982, 1988, 1991, 1993 @@ -224,6 +224,9 @@ int copyoutstr __P((const void *, void *, size_t, size_t *)); int copyin __P((const void *, void *, size_t)); int copyout __P((const void *, void *, size_t)); +int copyin_proc __P((struct proc *, const void *, void *, size_t)); +int copyout_proc __P((struct proc *, const void *, void *, size_t)); + int subyte __P((void *, int)); int suibyte __P((void *, int)); int susword __P((void *, short));