diff --git a/[refs] b/[refs] index 3673ad743c7b..8b79e8707937 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e6b0edef3453677b13e175a104a83eb36d062dd3 +refs/heads/master: 3843fc2575e3389f4f0ad0420a720240a5746a5d diff --git a/trunk/arch/sparc64/kernel/process.c b/trunk/arch/sparc64/kernel/process.c index 2084f81a76e1..0a0c05fc3a33 100644 --- a/trunk/arch/sparc64/kernel/process.c +++ b/trunk/arch/sparc64/kernel/process.c @@ -657,39 +657,20 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, struct task_struct *p, struct pt_regs *regs) { struct thread_info *t = task_thread_info(p); - struct sparc_stackf *parent_sf; - unsigned long child_stack_sz; char *child_trap_frame; - int kernel_thread; - - kernel_thread = (regs->tstate & TSTATE_PRIV) ? 1 : 0; - parent_sf = ((struct sparc_stackf *) regs) - 1; /* Calculate offset to stack_frame & pt_regs */ - child_stack_sz = ((STACKFRAME_SZ + TRACEREG_SZ) + - (kernel_thread ? STACKFRAME_SZ : 0)); - child_trap_frame = (task_stack_page(p) + - (THREAD_SIZE - child_stack_sz)); - memcpy(child_trap_frame, parent_sf, child_stack_sz); - - t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | - (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) | + child_trap_frame = task_stack_page(p) + (THREAD_SIZE - (TRACEREG_SZ+STACKFRAME_SZ)); + memcpy(child_trap_frame, (((struct sparc_stackf *)regs)-1), (TRACEREG_SZ+STACKFRAME_SZ)); + + t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) | (((regs->tstate + 1) & TSTATE_CWP) << TI_FLAG_CWP_SHIFT); t->new_child = 1; t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS; - t->kregs = (struct pt_regs *) (child_trap_frame + - sizeof(struct sparc_stackf)); + t->kregs = (struct pt_regs *)(child_trap_frame+sizeof(struct sparc_stackf)); t->fpsaved[0] = 0; - if (kernel_thread) { - struct sparc_stackf *child_sf = (struct sparc_stackf *) - (child_trap_frame + (STACKFRAME_SZ + TRACEREG_SZ)); - - /* Zero terminate the stack backtrace. */ - child_sf->fp = NULL; - t->kregs->u_regs[UREG_FP] = - ((unsigned long) child_sf) - STACK_BIAS; - + if (regs->tstate & TSTATE_PRIV) { /* Special case, if we are spawning a kernel thread from * a userspace task (via KMOD, NFS, or similar) we must * disable performance counters in the child because the @@ -700,7 +681,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, t->pcr_reg = 0; t->flags &= ~_TIF_PERFCTR; } + t->kregs->u_regs[UREG_FP] = t->ksp; t->flags |= ((long)ASI_P << TI_FLAG_CURRENT_DS_SHIFT); + flush_register_windows(); + memcpy((void *)(t->ksp + STACK_BIAS), + (void *)(regs->u_regs[UREG_FP] + STACK_BIAS), + sizeof(struct sparc_stackf)); t->kregs->u_regs[UREG_G6] = (unsigned long) t; t->kregs->u_regs[UREG_G4] = (unsigned long) t->task; } else { diff --git a/trunk/arch/sparc64/kernel/rtrap.S b/trunk/arch/sparc64/kernel/rtrap.S index c6fc695fe1fe..3afacbb5781d 100644 --- a/trunk/arch/sparc64/kernel/rtrap.S +++ b/trunk/arch/sparc64/kernel/rtrap.S @@ -363,7 +363,6 @@ kern_rtt: rdpr %canrestore, %g1 brz,pn %g1, kern_rtt_fill nop kern_rtt_restore: - stw %g0, [%sp + PTREGS_OFF + PT_V9_MAGIC] restore retry diff --git a/trunk/arch/sparc64/kernel/stacktrace.c b/trunk/arch/sparc64/kernel/stacktrace.c index c73ce3f4197e..01b52f561af4 100644 --- a/trunk/arch/sparc64/kernel/stacktrace.c +++ b/trunk/arch/sparc64/kernel/stacktrace.c @@ -19,7 +19,7 @@ void save_stack_trace(struct stack_trace *trace) fp = ksp + STACK_BIAS; thread_base = (unsigned long) tp; do { - struct sparc_stackf *sf; + struct reg_window *rw; struct pt_regs *regs; unsigned long pc; @@ -28,17 +28,15 @@ void save_stack_trace(struct stack_trace *trace) fp >= (thread_base + THREAD_SIZE)) break; - sf = (struct sparc_stackf *) fp; - regs = (struct pt_regs *) (sf + 1); + rw = (struct reg_window *) fp; + regs = (struct pt_regs *) (rw + 1); if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) { - if (!(regs->tstate & TSTATE_PRIV)) - break; pc = regs->tpc; fp = regs->u_regs[UREG_I6] + STACK_BIAS; } else { - pc = sf->callers_pc; - fp = (unsigned long)sf->fp + STACK_BIAS; + pc = rw->ins[7]; + fp = rw->ins[6] + STACK_BIAS; } if (trace->skip > 0) diff --git a/trunk/arch/sparc64/kernel/traps.c b/trunk/arch/sparc64/kernel/traps.c index 369749262653..d9b8d46707d1 100644 --- a/trunk/arch/sparc64/kernel/traps.c +++ b/trunk/arch/sparc64/kernel/traps.c @@ -2116,7 +2116,7 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp) printk("\n"); #endif do { - struct sparc_stackf *sf; + struct reg_window *rw; struct pt_regs *regs; unsigned long pc; @@ -2124,17 +2124,15 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp) if (fp < (thread_base + sizeof(struct thread_info)) || fp >= (thread_base + THREAD_SIZE)) break; - sf = (struct sparc_stackf *) fp; - regs = (struct pt_regs *) (sf + 1); + rw = (struct reg_window *)fp; + regs = (struct pt_regs *) (rw + 1); if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) { - if (!(regs->tstate & TSTATE_PRIV)) - break; pc = regs->tpc; fp = regs->u_regs[UREG_I6] + STACK_BIAS; } else { - pc = sf->callers_pc; - fp = (unsigned long)sf->fp + STACK_BIAS; + pc = rw->ins[7]; + fp = rw->ins[6] + STACK_BIAS; } printk(" [%016lx] ", pc); diff --git a/trunk/arch/x86/vdso/vma.c b/trunk/arch/x86/vdso/vma.c index 19a6cfaf5db9..3fdd51497a83 100644 --- a/trunk/arch/x86/vdso/vma.c +++ b/trunk/arch/x86/vdso/vma.c @@ -16,7 +16,7 @@ #include "vextern.h" /* Just for VMAGIC. */ #undef VEXTERN -unsigned int __read_mostly vdso_enabled = 1; +int vdso_enabled = 1; extern char vdso_start[], vdso_end[]; extern unsigned short vdso_sync_cpuid; diff --git a/trunk/arch/x86/xen/Kconfig b/trunk/arch/x86/xen/Kconfig index 2e641be2737e..525b108411bd 100644 --- a/trunk/arch/x86/xen/Kconfig +++ b/trunk/arch/x86/xen/Kconfig @@ -6,7 +6,7 @@ config XEN bool "Xen guest support" select PARAVIRT depends on X86_32 - depends on X86_CMPXCHG && X86_TSC && !(X86_VISWS || X86_VOYAGER) + depends on X86_CMPXCHG && X86_TSC && X86_PAE && !(X86_VISWS || X86_VOYAGER) help This is the Linux Xen port. Enabling this will allow the kernel to boot in a paravirtualized environment under the diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c index c8a56e457d61..a05b7721bc81 100644 --- a/trunk/arch/x86/xen/enlighten.c +++ b/trunk/arch/x86/xen/enlighten.c @@ -785,38 +785,35 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte) static __init void xen_pagetable_setup_start(pgd_t *base) { pgd_t *xen_pgd = (pgd_t *)xen_start_info->pt_base; + int i; /* special set_pte for pagetable initialization */ pv_mmu_ops.set_pte = xen_set_pte_init; init_mm.pgd = base; /* - * copy top-level of Xen-supplied pagetable into place. For - * !PAE we can use this as-is, but for PAE it is a stand-in - * while we copy the pmd pages. + * copy top-level of Xen-supplied pagetable into place. This + * is a stand-in while we copy the pmd pages. */ memcpy(base, xen_pgd, PTRS_PER_PGD * sizeof(pgd_t)); - if (PTRS_PER_PMD > 1) { - int i; - /* - * For PAE, need to allocate new pmds, rather than - * share Xen's, since Xen doesn't like pmd's being - * shared between address spaces. - */ - for (i = 0; i < PTRS_PER_PGD; i++) { - if (pgd_val_ma(xen_pgd[i]) & _PAGE_PRESENT) { - pmd_t *pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE); + /* + * For PAE, need to allocate new pmds, rather than + * share Xen's, since Xen doesn't like pmd's being + * shared between address spaces. + */ + for (i = 0; i < PTRS_PER_PGD; i++) { + if (pgd_val_ma(xen_pgd[i]) & _PAGE_PRESENT) { + pmd_t *pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE); - memcpy(pmd, (void *)pgd_page_vaddr(xen_pgd[i]), - PAGE_SIZE); + memcpy(pmd, (void *)pgd_page_vaddr(xen_pgd[i]), + PAGE_SIZE); - make_lowmem_page_readonly(pmd); + make_lowmem_page_readonly(pmd); - set_pgd(&base[i], __pgd(1 + __pa(pmd))); - } else - pgd_clear(&base[i]); - } + set_pgd(&base[i], __pgd(1 + __pa(pmd))); + } else + pgd_clear(&base[i]); } /* make sure zero_page is mapped RO so we can use it in pagetables */ @@ -873,17 +870,7 @@ static __init void xen_pagetable_setup_done(pgd_t *base) /* Actually pin the pagetable down, but we can't set PG_pinned yet because the page structures don't exist yet. */ - { - unsigned level; - -#ifdef CONFIG_X86_PAE - level = MMUEXT_PIN_L3_TABLE; -#else - level = MMUEXT_PIN_L2_TABLE; -#endif - - pin_pagetable_pfn(level, PFN_DOWN(__pa(base))); - } + pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(base))); } /* This is called once we have the cpu_possible_map */ @@ -1093,7 +1080,6 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = { .make_pte = xen_make_pte, .make_pgd = xen_make_pgd, -#ifdef CONFIG_X86_PAE .set_pte_atomic = xen_set_pte_atomic, .set_pte_present = xen_set_pte_at, .set_pud = xen_set_pud, @@ -1102,7 +1088,6 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = { .make_pmd = xen_make_pmd, .pmd_val = xen_pmd_val, -#endif /* PAE */ .activate_mm = xen_activate_mm, .dup_mmap = xen_dup_mmap, diff --git a/trunk/arch/x86/xen/mmu.c b/trunk/arch/x86/xen/mmu.c index 126766d43aea..07c2653ec335 100644 --- a/trunk/arch/x86/xen/mmu.c +++ b/trunk/arch/x86/xen/mmu.c @@ -222,7 +222,7 @@ pmdval_t xen_pmd_val(pmd_t pmd) ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT; return ret; } -#ifdef CONFIG_X86_PAE + void xen_set_pud(pud_t *ptr, pud_t val) { struct multicall_space mcs; @@ -272,12 +272,6 @@ pmd_t xen_make_pmd(pmdval_t pmd) return native_make_pmd(pmd); } -#else /* !PAE */ -void xen_set_pte(pte_t *ptep, pte_t pte) -{ - *ptep = pte; -} -#endif /* CONFIG_X86_PAE */ /* (Yet another) pagetable walker. This one is intended for pinning a @@ -430,8 +424,6 @@ static int pin_page(struct page *page, enum pt_level level) read-only, and can be pinned. */ void xen_pgd_pin(pgd_t *pgd) { - unsigned level; - xen_mc_batch(); if (pgd_walk(pgd, pin_page, TASK_SIZE)) { @@ -441,14 +433,7 @@ void xen_pgd_pin(pgd_t *pgd) xen_mc_batch(); } -#ifdef CONFIG_X86_PAE - level = MMUEXT_PIN_L3_TABLE; -#else - level = MMUEXT_PIN_L2_TABLE; -#endif - - xen_do_pin(level, PFN_DOWN(__pa(pgd))); - + xen_do_pin(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(pgd))); xen_mc_issue(0); } diff --git a/trunk/arch/x86/xen/mmu.h b/trunk/arch/x86/xen/mmu.h index b5e189b1519d..5fe961caffd4 100644 --- a/trunk/arch/x86/xen/mmu.h +++ b/trunk/arch/x86/xen/mmu.h @@ -37,14 +37,13 @@ void xen_exit_mmap(struct mm_struct *mm); void xen_pgd_pin(pgd_t *pgd); //void xen_pgd_unpin(pgd_t *pgd); -#ifdef CONFIG_X86_PAE -unsigned long long xen_pte_val(pte_t); -unsigned long long xen_pmd_val(pmd_t); -unsigned long long xen_pgd_val(pgd_t); +pteval_t xen_pte_val(pte_t); +pmdval_t xen_pmd_val(pmd_t); +pgdval_t xen_pgd_val(pgd_t); -pte_t xen_make_pte(unsigned long long); -pmd_t xen_make_pmd(unsigned long long); -pgd_t xen_make_pgd(unsigned long long); +pte_t xen_make_pte(pteval_t); +pmd_t xen_make_pmd(pmdval_t); +pgd_t xen_make_pgd(pgdval_t); void xen_set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval); @@ -53,15 +52,4 @@ void xen_set_pud(pud_t *ptr, pud_t val); void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); void xen_pmd_clear(pmd_t *pmdp); - -#else -unsigned long xen_pte_val(pte_t); -unsigned long xen_pmd_val(pmd_t); -unsigned long xen_pgd_val(pgd_t); - -pte_t xen_make_pte(unsigned long); -pmd_t xen_make_pmd(unsigned long); -pgd_t xen_make_pgd(unsigned long); -#endif - #endif /* _XEN_MMU_H */ diff --git a/trunk/arch/x86/xen/xen-head.S b/trunk/arch/x86/xen/xen-head.S index 288d587ce73c..2ab5f42f34d8 100644 --- a/trunk/arch/x86/xen/xen-head.S +++ b/trunk/arch/x86/xen/xen-head.S @@ -30,11 +30,7 @@ ENTRY(hypercall_page) ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long startup_xen) ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long hypercall_page) ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz "!writable_page_tables|pae_pgdir_above_4gb") -#ifdef CONFIG_X86_PAE ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "yes") -#else - ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "no") -#endif ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic") #endif /*CONFIG_XEN */ diff --git a/trunk/drivers/net/cassini.c b/trunk/drivers/net/cassini.c index 83768df27806..93e13636f8dd 100644 --- a/trunk/drivers/net/cassini.c +++ b/trunk/drivers/net/cassini.c @@ -142,8 +142,8 @@ #define DRV_MODULE_NAME "cassini" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.6" -#define DRV_MODULE_RELDATE "21 May 2008" +#define DRV_MODULE_VERSION "1.5" +#define DRV_MODULE_RELDATE "4 Jan 2008" #define CAS_DEF_MSG_ENABLE \ (NETIF_MSG_DRV | \ @@ -2136,12 +2136,9 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc, if (addr) cas_page_unmap(addr); } + skb->csum = csum_unfold(~csum); + skb->ip_summed = CHECKSUM_COMPLETE; skb->protocol = eth_type_trans(skb, cp->dev); - if (skb->protocol == htons(ETH_P_IP)) { - skb->csum = csum_unfold(~csum); - skb->ip_summed = CHECKSUM_COMPLETE; - } else - skb->ip_summed = CHECKSUM_NONE; return len; } diff --git a/trunk/drivers/net/wireless/ath5k/base.c b/trunk/drivers/net/wireless/ath5k/base.c index 635b9ac9aaa1..4e5c8fc35200 100644 --- a/trunk/drivers/net/wireless/ath5k/base.c +++ b/trunk/drivers/net/wireless/ath5k/base.c @@ -1787,8 +1787,6 @@ ath5k_tasklet_rx(unsigned long data) spin_lock(&sc->rxbuflock); do { - rxs.flag = 0; - if (unlikely(list_empty(&sc->rxbuf))) { ATH5K_WARN(sc, "empty rx buf pool\n"); break; diff --git a/trunk/drivers/net/wireless/ath5k/hw.c b/trunk/drivers/net/wireless/ath5k/hw.c index 77990b56860b..5fb1ae6ad3e2 100644 --- a/trunk/drivers/net/wireless/ath5k/hw.c +++ b/trunk/drivers/net/wireless/ath5k/hw.c @@ -4119,7 +4119,6 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); rs->rs_status = 0; - rs->rs_phyerr = 0; /* * Key table status @@ -4146,7 +4145,7 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { rs->rs_status |= AR5K_RXERR_PHY; - rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1, + rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); } @@ -4194,7 +4193,6 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); rs->rs_status = 0; - rs->rs_phyerr = 0; /* * Key table status @@ -4217,7 +4215,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { rs->rs_status |= AR5K_RXERR_PHY; - rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1, + rs->rs_phyerr = AR5K_REG_MS(rx_err->rx_error_1, AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); } diff --git a/trunk/drivers/net/wireless/hostap/hostap_cs.c b/trunk/drivers/net/wireless/hostap/hostap_cs.c index ed4317a17cbb..437a9bcc9bd3 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_cs.c +++ b/trunk/drivers/net/wireless/hostap/hostap_cs.c @@ -833,7 +833,6 @@ static struct pcmcia_device_id hostap_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x0001), PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* PCMCIA_DEVICE_MANF_CARD(0xc00f, 0x0000), conflict with pcnet_cs */ - PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010), diff --git a/trunk/drivers/net/wireless/libertas/ethtool.c b/trunk/drivers/net/wireless/libertas/ethtool.c index 688d60de55cb..dcfdb404678b 100644 --- a/trunk/drivers/net/wireless/libertas/ethtool.c +++ b/trunk/drivers/net/wireless/libertas/ethtool.c @@ -73,8 +73,8 @@ static int lbs_ethtool_get_eeprom(struct net_device *dev, return ret; } -static void lbs_ethtool_get_stats(struct net_device *dev, - struct ethtool_stats *stats, uint64_t *data) +static void lbs_ethtool_get_stats(struct net_device * dev, + struct ethtool_stats * stats, u64 * data) { struct lbs_private *priv = dev->priv; struct cmd_ds_mesh_access mesh_access; @@ -83,12 +83,12 @@ static void lbs_ethtool_get_stats(struct net_device *dev, lbs_deb_enter(LBS_DEB_ETHTOOL); /* Get Mesh Statistics */ - ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_STATS, &mesh_access); + ret = lbs_prepare_and_send_command(priv, + CMD_MESH_ACCESS, CMD_ACT_MESH_GET_STATS, + CMD_OPTION_WAITFORRSP, 0, &mesh_access); - if (ret) { - memset(data, 0, MESH_STATS_NUM*(sizeof(uint64_t))); + if (ret) return; - } priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]); priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]); @@ -111,18 +111,19 @@ static void lbs_ethtool_get_stats(struct net_device *dev, lbs_deb_enter(LBS_DEB_ETHTOOL); } -static int lbs_ethtool_get_sset_count(struct net_device *dev, int sset) +static int lbs_ethtool_get_sset_count(struct net_device * dev, int sset) { - struct lbs_private *priv = dev->priv; - - if (sset == ETH_SS_STATS && dev == priv->mesh_dev) + switch (sset) { + case ETH_SS_STATS: return MESH_STATS_NUM; - - return -EOPNOTSUPP; + default: + return -EOPNOTSUPP; + } } static void lbs_ethtool_get_strings(struct net_device *dev, - uint32_t stringset, uint8_t *s) + u32 stringset, + u8 * s) { int i; diff --git a/trunk/drivers/net/wireless/orinoco_cs.c b/trunk/drivers/net/wireless/orinoco_cs.c index 1c216e015f64..8b7f5768a103 100644 --- a/trunk/drivers/net/wireless/orinoco_cs.c +++ b/trunk/drivers/net/wireless/orinoco_cs.c @@ -461,7 +461,6 @@ static struct pcmcia_device_id orinoco_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */ PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */ - PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x3021), /* SpeedStream Wireless Adapter */ PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */ PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */ diff --git a/trunk/drivers/net/wireless/rtl8187_dev.c b/trunk/drivers/net/wireless/rtl8187_dev.c index 9223ada5f00e..d5787b37e1fb 100644 --- a/trunk/drivers/net/wireless/rtl8187_dev.c +++ b/trunk/drivers/net/wireless/rtl8187_dev.c @@ -92,7 +92,6 @@ static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr, u8 data[4]; struct usb_ctrlrequest dr; } *buf; - int rc; buf = kmalloc(sizeof(*buf), GFP_ATOMIC); if (!buf) @@ -117,11 +116,7 @@ static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr, usb_fill_control_urb(urb, priv->udev, usb_sndctrlpipe(priv->udev, 0), (unsigned char *)dr, buf, len, rtl8187_iowrite_async_cb, buf); - rc = usb_submit_urb(urb, GFP_ATOMIC); - if (rc < 0) { - kfree(buf); - usb_free_urb(urb); - } + usb_submit_urb(urb, GFP_ATOMIC); } static inline void rtl818x_iowrite32_async(struct rtl8187_priv *priv, @@ -174,7 +169,6 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb, struct urb *urb; __le16 rts_dur = 0; u32 flags; - int rc; urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { @@ -214,11 +208,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb, info->dev = dev; usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, 2), hdr, skb->len, rtl8187_tx_cb, skb); - rc = usb_submit_urb(urb, GFP_ATOMIC); - if (rc < 0) { - usb_free_urb(urb); - kfree_skb(skb); - } + usb_submit_urb(urb, GFP_ATOMIC); return 0; } diff --git a/trunk/drivers/serial/sunhv.c b/trunk/drivers/serial/sunhv.c index 2847336742d7..145c0281495d 100644 --- a/trunk/drivers/serial/sunhv.c +++ b/trunk/drivers/serial/sunhv.c @@ -499,6 +499,7 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig } else spin_lock(&port->lock); + spin_lock_irqsave(&port->lock, flags); for (i = 0; i < n; i++) { if (*s == '\n') sunhv_console_putchar(port, '\r'); diff --git a/trunk/fs/cifs/cifs_spnego.c b/trunk/fs/cifs/cifs_spnego.c index 7013aaff6aed..6653e29637a7 100644 --- a/trunk/fs/cifs/cifs_spnego.c +++ b/trunk/fs/cifs/cifs_spnego.c @@ -119,9 +119,6 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo) dp = description + strlen(description); sprintf(dp, ";uid=0x%x", sesInfo->linux_uid); - dp = description + strlen(description); - sprintf(dp, ";user=%s", sesInfo->userName); - cFYI(1, ("key description = %s", description)); spnego_key = request_key(&cifs_spnego_key_type, description, ""); diff --git a/trunk/fs/cifs/cifssmb.c b/trunk/fs/cifs/cifssmb.c index 9b8b4cfdf993..7b9938445b07 100644 --- a/trunk/fs/cifs/cifssmb.c +++ b/trunk/fs/cifs/cifssmb.c @@ -2159,7 +2159,8 @@ CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char *fromName, cFYI(1, ("Send error in copy = %d with %d files copied", rc, le16_to_cpu(pSMBr->CopyCount))); } - cifs_buf_release(pSMB); + if (pSMB) + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto copyRetry; @@ -2248,7 +2249,8 @@ CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon, if (rc) cFYI(1, ("Send error in SetPathInfo create symlink = %d", rc)); - cifs_buf_release(pSMB); + if (pSMB) + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto createSymLinkRetry; @@ -4093,7 +4095,8 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, target_nodes, nls_codepage); GetDFSRefExit: - cifs_buf_release(pSMB); + if (pSMB) + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto getDFSRetry; @@ -5114,7 +5117,8 @@ CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, if (rc) cFYI(1, ("SetPathInfo (perms) returned %d", rc)); - cifs_buf_release(pSMB); + if (pSMB) + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto setPermsRetry; return rc; @@ -5336,7 +5340,8 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, } } } - cifs_buf_release(pSMB); + if (pSMB) + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto QAllEAsRetry; @@ -5485,7 +5490,8 @@ ssize_t CIFSSMBQueryEA(const int xid, struct cifsTconInfo *tcon, } } } - cifs_buf_release(pSMB); + if (pSMB) + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto QEARetry; diff --git a/trunk/fs/cifs/inode.c b/trunk/fs/cifs/inode.c index 129dbfe4dca7..00ced97bd53a 100644 --- a/trunk/fs/cifs/inode.c +++ b/trunk/fs/cifs/inode.c @@ -172,7 +172,7 @@ static void fill_fake_finddataunix(FILE_UNIX_BASIC_INFO *pfnd_dat, { struct inode *pinode = NULL; - memset(pfnd_dat, 0, sizeof(FILE_UNIX_BASIC_INFO)); + memset(pfnd_dat, sizeof(FILE_UNIX_BASIC_INFO), 0); /* __le64 pfnd_dat->EndOfFile = cpu_to_le64(0); __le64 pfnd_dat->NumOfBytes = cpu_to_le64(0); @@ -384,7 +384,7 @@ static int get_sfu_mode(struct inode *inode, static void fill_fake_finddata(FILE_ALL_INFO *pfnd_dat, struct super_block *sb) { - memset(pfnd_dat, 0, sizeof(FILE_ALL_INFO)); + memset(pfnd_dat, sizeof(FILE_ALL_INFO), 0); /* __le64 pfnd_dat->AllocationSize = cpu_to_le64(0); __le64 pfnd_dat->EndOfFile = cpu_to_le64(0); diff --git a/trunk/include/asm-x86/xen/page.h b/trunk/include/asm-x86/xen/page.h index baf3a4dce28c..e11f24038b1d 100644 --- a/trunk/include/asm-x86/xen/page.h +++ b/trunk/include/asm-x86/xen/page.h @@ -150,13 +150,9 @@ static inline pte_t __pte_ma(pteval_t x) return (pte_t) { .pte = x }; } -#ifdef CONFIG_X86_PAE #define pmd_val_ma(v) ((v).pmd) #define pud_val_ma(v) ((v).pgd.pgd) #define __pmd_ma(x) ((pmd_t) { (x) } ) -#else /* !X86_PAE */ -#define pmd_val_ma(v) ((v).pud.pgd.pgd) -#endif /* CONFIG_X86_PAE */ #define pgd_val_ma(x) ((x).pgd) diff --git a/trunk/include/linux/netfilter.h b/trunk/include/linux/netfilter.h index 0c5eb7ed8b3f..e4c66593b5c6 100644 --- a/trunk/include/linux/netfilter.h +++ b/trunk/include/linux/netfilter.h @@ -3,6 +3,7 @@ #ifdef __KERNEL__ #include +#include #include #include #include @@ -13,7 +14,6 @@ #include #include #endif -#include #include /* Responses from hook functions. */ diff --git a/trunk/include/linux/netfilter_arp/arp_tables.h b/trunk/include/linux/netfilter_arp/arp_tables.h index 590ac3d6d5d6..dd9c97f2d436 100644 --- a/trunk/include/linux/netfilter_arp/arp_tables.h +++ b/trunk/include/linux/netfilter_arp/arp_tables.h @@ -11,11 +11,11 @@ #ifdef __KERNEL__ #include +#include #include #include #include #endif -#include #include #include diff --git a/trunk/include/linux/netfilter_ipv4/ip_tables.h b/trunk/include/linux/netfilter_ipv4/ip_tables.h index 092bd50581a9..bfc889f90276 100644 --- a/trunk/include/linux/netfilter_ipv4/ip_tables.h +++ b/trunk/include/linux/netfilter_ipv4/ip_tables.h @@ -17,11 +17,11 @@ #ifdef __KERNEL__ #include +#include #include #include #include #endif -#include #include #include diff --git a/trunk/include/linux/netfilter_ipv6/ip6_tables.h b/trunk/include/linux/netfilter_ipv6/ip6_tables.h index 1089e33cf633..f2507dcc5750 100644 --- a/trunk/include/linux/netfilter_ipv6/ip6_tables.h +++ b/trunk/include/linux/netfilter_ipv6/ip6_tables.h @@ -17,11 +17,11 @@ #ifdef __KERNEL__ #include +#include #include #include #include #endif -#include #include #include diff --git a/trunk/include/linux/tcp.h b/trunk/include/linux/tcp.h index 18e62e3d406f..d96d9b122304 100644 --- a/trunk/include/linux/tcp.h +++ b/trunk/include/linux/tcp.h @@ -355,7 +355,7 @@ struct tcp_sock { u32 lost_retrans_low; /* Sent seq after any rxmit (lowest) */ u16 advmss; /* Advertised MSS */ - u32 prior_ssthresh; /* ssthresh saved at recovery start */ + u16 prior_ssthresh; /* ssthresh saved at recovery start */ u32 lost_out; /* Lost packets */ u32 sacked_out; /* SACK'd packets */ u32 fackets_out; /* FACK'd packets */ diff --git a/trunk/net/ipv4/arp.c b/trunk/net/ipv4/arp.c index 9b539fa9fe18..418862f1bf22 100644 --- a/trunk/net/ipv4/arp.c +++ b/trunk/net/ipv4/arp.c @@ -1288,6 +1288,7 @@ static void arp_format_neigh_entry(struct seq_file *seq, struct neighbour *n) { char hbuffer[HBUFFERLEN]; + const char hexbuf[] = "0123456789ABCDEF"; int k, j; char tbuf[16]; struct net_device *dev = n->dev; @@ -1301,8 +1302,8 @@ static void arp_format_neigh_entry(struct seq_file *seq, else { #endif for (k = 0, j = 0; k < HBUFFERLEN - 3 && j < dev->addr_len; j++) { - hbuffer[k++] = hex_asc_hi(n->ha[j]); - hbuffer[k++] = hex_asc_lo(n->ha[j]); + hbuffer[k++] = hexbuf[(n->ha[j] >> 4) & 15]; + hbuffer[k++] = hexbuf[n->ha[j] & 15]; hbuffer[k++] = ':'; } hbuffer[--k] = 0; diff --git a/trunk/net/ipv4/ip_gre.c b/trunk/net/ipv4/ip_gre.c index 4342cba4ff82..2ada033406de 100644 --- a/trunk/net/ipv4/ip_gre.c +++ b/trunk/net/ipv4/ip_gre.c @@ -313,8 +313,9 @@ static void ipgre_tunnel_uninit(struct net_device *dev) static void ipgre_err(struct sk_buff *skb, u32 info) { +#ifndef I_WISH_WORLD_WERE_PERFECT -/* All the routers (except for Linux) return only +/* It is not :-( All the routers (except for Linux) return only 8 bytes of packet payload. It means, that precise relaying of ICMP in the real Internet is absolutely infeasible. @@ -397,6 +398,149 @@ static void ipgre_err(struct sk_buff *skb, u32 info) out: read_unlock(&ipgre_lock); return; +#else + struct iphdr *iph = (struct iphdr*)dp; + struct iphdr *eiph; + __be16 *p = (__be16*)(dp+(iph->ihl<<2)); + const int type = icmp_hdr(skb)->type; + const int code = icmp_hdr(skb)->code; + int rel_type = 0; + int rel_code = 0; + __be32 rel_info = 0; + __u32 n = 0; + __be16 flags; + int grehlen = (iph->ihl<<2) + 4; + struct sk_buff *skb2; + struct flowi fl; + struct rtable *rt; + + if (p[1] != htons(ETH_P_IP)) + return; + + flags = p[0]; + if (flags&(GRE_CSUM|GRE_KEY|GRE_SEQ|GRE_ROUTING|GRE_VERSION)) { + if (flags&(GRE_VERSION|GRE_ROUTING)) + return; + if (flags&GRE_CSUM) + grehlen += 4; + if (flags&GRE_KEY) + grehlen += 4; + if (flags&GRE_SEQ) + grehlen += 4; + } + if (len < grehlen + sizeof(struct iphdr)) + return; + eiph = (struct iphdr*)(dp + grehlen); + + switch (type) { + default: + return; + case ICMP_PARAMETERPROB: + n = ntohl(icmp_hdr(skb)->un.gateway) >> 24; + if (n < (iph->ihl<<2)) + return; + + /* So... This guy found something strange INSIDE encapsulated + packet. Well, he is fool, but what can we do ? + */ + rel_type = ICMP_PARAMETERPROB; + n -= grehlen; + rel_info = htonl(n << 24); + break; + + case ICMP_DEST_UNREACH: + switch (code) { + case ICMP_SR_FAILED: + case ICMP_PORT_UNREACH: + /* Impossible event. */ + return; + case ICMP_FRAG_NEEDED: + /* And it is the only really necessary thing :-) */ + n = ntohs(icmp_hdr(skb)->un.frag.mtu); + if (n < grehlen+68) + return; + n -= grehlen; + /* BSD 4.2 MORE DOES NOT EXIST IN NATURE. */ + if (n > ntohs(eiph->tot_len)) + return; + rel_info = htonl(n); + break; + default: + /* All others are translated to HOST_UNREACH. + rfc2003 contains "deep thoughts" about NET_UNREACH, + I believe, it is just ether pollution. --ANK + */ + rel_type = ICMP_DEST_UNREACH; + rel_code = ICMP_HOST_UNREACH; + break; + } + break; + case ICMP_TIME_EXCEEDED: + if (code != ICMP_EXC_TTL) + return; + break; + } + + /* Prepare fake skb to feed it to icmp_send */ + skb2 = skb_clone(skb, GFP_ATOMIC); + if (skb2 == NULL) + return; + dst_release(skb2->dst); + skb2->dst = NULL; + skb_pull(skb2, skb->data - (u8*)eiph); + skb_reset_network_header(skb2); + + /* Try to guess incoming interface */ + memset(&fl, 0, sizeof(fl)); + fl.fl4_dst = eiph->saddr; + fl.fl4_tos = RT_TOS(eiph->tos); + fl.proto = IPPROTO_GRE; + if (ip_route_output_key(dev_net(skb->dev), &rt, &fl)) { + kfree_skb(skb2); + return; + } + skb2->dev = rt->u.dst.dev; + + /* route "incoming" packet */ + if (rt->rt_flags&RTCF_LOCAL) { + ip_rt_put(rt); + rt = NULL; + fl.fl4_dst = eiph->daddr; + fl.fl4_src = eiph->saddr; + fl.fl4_tos = eiph->tos; + if (ip_route_output_key(dev_net(skb->dev), &rt, &fl) || + rt->u.dst.dev->type != ARPHRD_IPGRE) { + ip_rt_put(rt); + kfree_skb(skb2); + return; + } + } else { + ip_rt_put(rt); + if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, skb2->dev) || + skb2->dst->dev->type != ARPHRD_IPGRE) { + kfree_skb(skb2); + return; + } + } + + /* change mtu on this route */ + if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { + if (n > dst_mtu(skb2->dst)) { + kfree_skb(skb2); + return; + } + skb2->dst->ops->update_pmtu(skb2->dst, n); + } else if (type == ICMP_TIME_EXCEEDED) { + struct ip_tunnel *t = netdev_priv(skb2->dev); + if (t->parms.iph.ttl) { + rel_type = ICMP_DEST_UNREACH; + rel_code = ICMP_HOST_UNREACH; + } + } + + icmp_send(skb2, rel_type, rel_code, rel_info); + kfree_skb(skb2); +#endif } static inline void ipgre_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb) diff --git a/trunk/net/ipv4/ipip.c b/trunk/net/ipv4/ipip.c index af5cb53da5cc..149111f08e8d 100644 --- a/trunk/net/ipv4/ipip.c +++ b/trunk/net/ipv4/ipip.c @@ -278,8 +278,9 @@ static void ipip_tunnel_uninit(struct net_device *dev) static int ipip_err(struct sk_buff *skb, u32 info) { +#ifndef I_WISH_WORLD_WERE_PERFECT -/* All the routers (except for Linux) return only +/* It is not :-( All the routers (except for Linux) return only 8 bytes of packet payload. It means, that precise relaying of ICMP in the real Internet is absolutely infeasible. */ @@ -336,6 +337,133 @@ static int ipip_err(struct sk_buff *skb, u32 info) out: read_unlock(&ipip_lock); return err; +#else + struct iphdr *iph = (struct iphdr*)dp; + int hlen = iph->ihl<<2; + struct iphdr *eiph; + const int type = icmp_hdr(skb)->type; + const int code = icmp_hdr(skb)->code; + int rel_type = 0; + int rel_code = 0; + __be32 rel_info = 0; + __u32 n = 0; + struct sk_buff *skb2; + struct flowi fl; + struct rtable *rt; + + if (len < hlen + sizeof(struct iphdr)) + return 0; + eiph = (struct iphdr*)(dp + hlen); + + switch (type) { + default: + return 0; + case ICMP_PARAMETERPROB: + n = ntohl(icmp_hdr(skb)->un.gateway) >> 24; + if (n < hlen) + return 0; + + /* So... This guy found something strange INSIDE encapsulated + packet. Well, he is fool, but what can we do ? + */ + rel_type = ICMP_PARAMETERPROB; + rel_info = htonl((n - hlen) << 24); + break; + + case ICMP_DEST_UNREACH: + switch (code) { + case ICMP_SR_FAILED: + case ICMP_PORT_UNREACH: + /* Impossible event. */ + return 0; + case ICMP_FRAG_NEEDED: + /* And it is the only really necessary thing :-) */ + n = ntohs(icmp_hdr(skb)->un.frag.mtu); + if (n < hlen+68) + return 0; + n -= hlen; + /* BSD 4.2 MORE DOES NOT EXIST IN NATURE. */ + if (n > ntohs(eiph->tot_len)) + return 0; + rel_info = htonl(n); + break; + default: + /* All others are translated to HOST_UNREACH. + rfc2003 contains "deep thoughts" about NET_UNREACH, + I believe, it is just ether pollution. --ANK + */ + rel_type = ICMP_DEST_UNREACH; + rel_code = ICMP_HOST_UNREACH; + break; + } + break; + case ICMP_TIME_EXCEEDED: + if (code != ICMP_EXC_TTL) + return 0; + break; + } + + /* Prepare fake skb to feed it to icmp_send */ + skb2 = skb_clone(skb, GFP_ATOMIC); + if (skb2 == NULL) + return 0; + dst_release(skb2->dst); + skb2->dst = NULL; + skb_pull(skb2, skb->data - (u8*)eiph); + skb_reset_network_header(skb2); + + /* Try to guess incoming interface */ + memset(&fl, 0, sizeof(fl)); + fl.fl4_daddr = eiph->saddr; + fl.fl4_tos = RT_TOS(eiph->tos); + fl.proto = IPPROTO_IPIP; + if (ip_route_output_key(dev_net(skb->dev), &rt, &key)) { + kfree_skb(skb2); + return 0; + } + skb2->dev = rt->u.dst.dev; + + /* route "incoming" packet */ + if (rt->rt_flags&RTCF_LOCAL) { + ip_rt_put(rt); + rt = NULL; + fl.fl4_daddr = eiph->daddr; + fl.fl4_src = eiph->saddr; + fl.fl4_tos = eiph->tos; + if (ip_route_output_key(dev_net(skb->dev), &rt, &fl) || + rt->u.dst.dev->type != ARPHRD_TUNNEL) { + ip_rt_put(rt); + kfree_skb(skb2); + return 0; + } + } else { + ip_rt_put(rt); + if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, skb2->dev) || + skb2->dst->dev->type != ARPHRD_TUNNEL) { + kfree_skb(skb2); + return 0; + } + } + + /* change mtu on this route */ + if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { + if (n > dst_mtu(skb2->dst)) { + kfree_skb(skb2); + return 0; + } + skb2->dst->ops->update_pmtu(skb2->dst, n); + } else if (type == ICMP_TIME_EXCEEDED) { + struct ip_tunnel *t = netdev_priv(skb2->dev); + if (t->parms.iph.ttl) { + rel_type = ICMP_DEST_UNREACH; + rel_code = ICMP_HOST_UNREACH; + } + } + + icmp_send(skb2, rel_type, rel_code, rel_info); + kfree_skb(skb2); + return 0; +#endif } static inline void ipip_ecn_decapsulate(const struct iphdr *outer_iph, diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index e399bde7813a..debf23581606 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -1836,7 +1836,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) { struct tcp_sock *tp = tcp_sk(sk); struct inet_connection_sock *icsk = inet_csk(sk); - unsigned int cur_mss; + unsigned int cur_mss = tcp_current_mss(sk, 0); int err; /* Inconslusive MTU probe */ @@ -1858,11 +1858,6 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) return -ENOMEM; } - if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk)) - return -EHOSTUNREACH; /* Routing failure or similar. */ - - cur_mss = tcp_current_mss(sk, 0); - /* If receiver has shrunk his window, and skb is out of * new window, do not retransmit it. The exception is the * case, when window is shrunk to zero. In this case @@ -1889,6 +1884,9 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) (sysctl_tcp_retrans_collapse != 0)) tcp_retrans_try_collapse(sk, skb, cur_mss); + if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk)) + return -EHOSTUNREACH; /* Routing failure or similar. */ + /* Some Solaris stacks overoptimize and ignore the FIN on a * retransmit when old data is attached. So strip it off * since it is cheap to do so and saves bytes on the network. diff --git a/trunk/net/ipv6/sit.c b/trunk/net/ipv6/sit.c index 3de6ffdaedf2..5a6fab95569f 100644 --- a/trunk/net/ipv6/sit.c +++ b/trunk/net/ipv6/sit.c @@ -403,8 +403,9 @@ static void ipip6_tunnel_uninit(struct net_device *dev) static int ipip6_err(struct sk_buff *skb, u32 info) { +#ifndef I_WISH_WORLD_WERE_PERFECT -/* All the routers (except for Linux) return only +/* It is not :-( All the routers (except for Linux) return only 8 bytes of packet payload. It means, that precise relaying of ICMP in the real Internet is absolutely infeasible. */ @@ -461,6 +462,92 @@ static int ipip6_err(struct sk_buff *skb, u32 info) out: read_unlock(&ipip6_lock); return err; +#else + struct iphdr *iph = (struct iphdr*)dp; + int hlen = iph->ihl<<2; + struct ipv6hdr *iph6; + const int type = icmp_hdr(skb)->type; + const int code = icmp_hdr(skb)->code; + int rel_type = 0; + int rel_code = 0; + int rel_info = 0; + struct sk_buff *skb2; + struct rt6_info *rt6i; + + if (len < hlen + sizeof(struct ipv6hdr)) + return; + iph6 = (struct ipv6hdr*)(dp + hlen); + + switch (type) { + default: + return; + case ICMP_PARAMETERPROB: + if (icmp_hdr(skb)->un.gateway < hlen) + return; + + /* So... This guy found something strange INSIDE encapsulated + packet. Well, he is fool, but what can we do ? + */ + rel_type = ICMPV6_PARAMPROB; + rel_info = icmp_hdr(skb)->un.gateway - hlen; + break; + + case ICMP_DEST_UNREACH: + switch (code) { + case ICMP_SR_FAILED: + case ICMP_PORT_UNREACH: + /* Impossible event. */ + return; + case ICMP_FRAG_NEEDED: + /* Too complicated case ... */ + return; + default: + /* All others are translated to HOST_UNREACH. + rfc2003 contains "deep thoughts" about NET_UNREACH, + I believe, it is just ether pollution. --ANK + */ + rel_type = ICMPV6_DEST_UNREACH; + rel_code = ICMPV6_ADDR_UNREACH; + break; + } + break; + case ICMP_TIME_EXCEEDED: + if (code != ICMP_EXC_TTL) + return; + rel_type = ICMPV6_TIME_EXCEED; + rel_code = ICMPV6_EXC_HOPLIMIT; + break; + } + + /* Prepare fake skb to feed it to icmpv6_send */ + skb2 = skb_clone(skb, GFP_ATOMIC); + if (skb2 == NULL) + return 0; + dst_release(skb2->dst); + skb2->dst = NULL; + skb_pull(skb2, skb->data - (u8*)iph6); + skb_reset_network_header(skb2); + + /* Try to guess incoming interface */ + rt6i = rt6_lookup(dev_net(skb->dev), &iph6->saddr, NULL, NULL, 0); + if (rt6i && rt6i->rt6i_dev) { + skb2->dev = rt6i->rt6i_dev; + + rt6i = rt6_lookup(dev_net(skb->dev), + &iph6->daddr, &iph6->saddr, NULL, 0); + + if (rt6i && rt6i->rt6i_dev && rt6i->rt6i_dev->type == ARPHRD_SIT) { + struct ip_tunnel *t = netdev_priv(rt6i->rt6i_dev); + if (rel_type == ICMPV6_TIME_EXCEED && t->parms.iph.ttl) { + rel_type = ICMPV6_DEST_UNREACH; + rel_code = ICMPV6_ADDR_UNREACH; + } + icmpv6_send(skb2, rel_type, rel_code, rel_info, skb2->dev); + } + } + kfree_skb(skb2); + return 0; +#endif } static inline void ipip6_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb) diff --git a/trunk/net/key/af_key.c b/trunk/net/key/af_key.c index 9bba7ac5fee0..9e7236ff6bcc 100644 --- a/trunk/net/key/af_key.c +++ b/trunk/net/key/af_key.c @@ -1251,7 +1251,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, x->sel.prefixlen_s = addr->sadb_address_prefixlen; } - if (!x->sel.family) + if (x->props.mode == XFRM_MODE_TRANSPORT) x->sel.family = x->props.family; if (ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1]) { diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index 7cfd12e0d1e2..e470bf12b765 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -730,17 +730,7 @@ static void ieee80211_send_assoc(struct net_device *dev, if (bss->wmm_ie) { wmm = 1; } - - /* get all rates supported by the device and the AP as - * some APs don't like getting a superset of their rates - * in the association request (e.g. D-Link DAP 1353 in - * b-only mode) */ - rates_len = ieee80211_compatible_rates(bss, sband, &rates); - ieee80211_rx_bss_put(dev, bss); - } else { - rates = ~0; - rates_len = sband->n_bitrates; } mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); @@ -771,7 +761,10 @@ static void ieee80211_send_assoc(struct net_device *dev, *pos++ = ifsta->ssid_len; memcpy(pos, ifsta->ssid, ifsta->ssid_len); - /* add all rates which were marked to be used above */ + /* all supported rates should be added here but some APs + * (e.g. D-Link DAP 1353 in b-only mode) don't like that + * Therefore only add rates the AP supports */ + rates_len = ieee80211_compatible_rates(bss, sband, &rates); supp_rates_len = rates_len; if (supp_rates_len > 8) supp_rates_len = 8; diff --git a/trunk/net/mac80211/wext.c b/trunk/net/mac80211/wext.c index 457ebf9e85ae..76e1de1dc735 100644 --- a/trunk/net/mac80211/wext.c +++ b/trunk/net/mac80211/wext.c @@ -209,6 +209,7 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev, range->num_frequency = c; IW_EVENT_CAPA_SET_KERNEL(range->event_capa); + IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY); IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN); diff --git a/trunk/net/xfrm/xfrm_user.c b/trunk/net/xfrm/xfrm_user.c index b976d9ed10e4..a1b0fbe3ea35 100644 --- a/trunk/net/xfrm/xfrm_user.c +++ b/trunk/net/xfrm/xfrm_user.c @@ -50,8 +50,19 @@ static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type) switch (type) { case XFRMA_ALG_AUTH: + if (!algp->alg_key_len && + strcmp(algp->alg_name, "digest_null") != 0) + return -EINVAL; + break; + case XFRMA_ALG_CRYPT: + if (!algp->alg_key_len && + strcmp(algp->alg_name, "cipher_null") != 0) + return -EINVAL; + break; + case XFRMA_ALG_COMP: + /* Zero length keys are legal. */ break; default: