Date: Tue, 4 Feb 2014 09:30:42 +0000 (UTC) From: "Andrey V. Elsukov" <ae@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r261480 - in user/ae/inet6: gnu/lib/libgcc sys/amd64/vmm/intel sys/ia64/conf sys/net sys/netinet sys/netinet6 sys/ofed/drivers/infiniband/ulp/ipoib sys/powerpc/powermac usr.sbin/bsdinst... Message-ID: <201402040930.s149Ugwr078172@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ae Date: Tue Feb 4 09:30:42 2014 New Revision: 261480 URL: http://svnweb.freebsd.org/changeset/base/261480 Log: Merge from head/ up to r260882. Modified: user/ae/inet6/gnu/lib/libgcc/Makefile user/ae/inet6/sys/amd64/vmm/intel/vmx.c user/ae/inet6/sys/ia64/conf/GENERIC user/ae/inet6/sys/net/ieee8023ad_lacp.c user/ae/inet6/sys/net/if.c user/ae/inet6/sys/net/if_arcsubr.c user/ae/inet6/sys/net/if_dl.h user/ae/inet6/sys/net/if_ethersubr.c user/ae/inet6/sys/net/if_fddisubr.c user/ae/inet6/sys/net/if_iso88025subr.c user/ae/inet6/sys/net/if_lagg.c user/ae/inet6/sys/netinet/ip_carp.c user/ae/inet6/sys/netinet/tcp_syncache.c user/ae/inet6/sys/netinet6/in6.c user/ae/inet6/sys/netinet6/in6_var.h user/ae/inet6/sys/netinet6/nd6.c user/ae/inet6/sys/netinet6/nd6.h user/ae/inet6/sys/netinet6/nd6_rtr.c user/ae/inet6/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c user/ae/inet6/sys/powerpc/powermac/pmu.c user/ae/inet6/usr.sbin/bsdinstall/scripts/services Directory Properties: user/ae/inet6/ (props changed) user/ae/inet6/gnu/lib/ (props changed) user/ae/inet6/sys/ (props changed) user/ae/inet6/sys/amd64/vmm/ (props changed) Modified: user/ae/inet6/gnu/lib/libgcc/Makefile ============================================================================== --- user/ae/inet6/gnu/lib/libgcc/Makefile Tue Feb 4 09:11:50 2014 (r261479) +++ user/ae/inet6/gnu/lib/libgcc/Makefile Tue Feb 4 09:30:42 2014 (r261480) @@ -34,9 +34,9 @@ OBJS= # added to below in various ways #--------------------------------------------------------------------------- # -# When upgrading GCC, get the following defintions straight from Makefile.in -# # Library members defined in libgcc2.c. +# When upgrading GCC, obtain the following list from mklibgcc.in +# LIB2FUNCS= _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 \ _cmpdi2 _ucmpdi2 \ _enable_execute_stack _trampoline __main _absvsi2 _absvdi2 _addvsi3 \ @@ -44,7 +44,7 @@ LIB2FUNCS= _muldi3 _negdi2 _lshrdi3 _ash _ffssi2 _ffsdi2 _clz _clzsi2 _clzdi2 _ctzsi2 _ctzdi2 _popcount_tab \ _popcountsi2 _popcountdi2 _paritysi2 _paritydi2 _powisf2 _powidf2 \ _powixf2 _powitf2 _mulsc3 _muldc3 _mulxc3 _multc3 _divsc3 _divdc3 \ - _divxc3 _divtc3 + _divxc3 _divtc3 _bswapsi2 _bswapdi2 .if ${COMPILER_TYPE} != "clang" || ${TARGET_CPUARCH} != "arm" LIB2FUNCS+= _clear_cache .endif @@ -145,7 +145,6 @@ LIB1ASMFUNCS = __divxf3 __divdf3 __divsf __divsi3 __modsi3 __udivsi3 __umodsi3 __save_stack_nonlocal \ __nonlocal_goto __restore_stack_nonlocal __trampoline \ _fixtfdi _fixunstfdi _floatditf -LIB2FUNCS += _bswapsi2 _bswapdi2 LIB2ADDEH = unwind-ia64.c unwind-sjlj.c unwind-c.c .endif Modified: user/ae/inet6/sys/amd64/vmm/intel/vmx.c ============================================================================== --- user/ae/inet6/sys/amd64/vmm/intel/vmx.c Tue Feb 4 09:11:50 2014 (r261479) +++ user/ae/inet6/sys/amd64/vmm/intel/vmx.c Tue Feb 4 09:30:42 2014 (r261480) @@ -147,21 +147,6 @@ SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, initia &vmx_initialized, 0, "Intel VMX initialized"); /* - * Virtual NMI blocking conditions. - * - * Some processor implementations also require NMI to be blocked if - * the STI_BLOCKING bit is set. It is possible to detect this at runtime - * based on the (exit_reason,exit_qual) tuple being set to - * (EXIT_REASON_INVAL_VMCS, EXIT_QUAL_NMI_WHILE_STI_BLOCKING). - * - * We take the easy way out and also include STI_BLOCKING as one of the - * gating items for vNMI injection. - */ -static uint64_t nmi_blocking_bits = VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING | - VMCS_INTERRUPTIBILITY_NMI_BLOCKING | - VMCS_INTERRUPTIBILITY_STI_BLOCKING; - -/* * Optional capabilities */ static int cap_halt_exit; @@ -1020,117 +1005,145 @@ static void __inline vmx_set_int_window_exiting(struct vmx *vmx, int vcpu) { - vmx->cap[vcpu].proc_ctls |= PROCBASED_INT_WINDOW_EXITING; - vmcs_write(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls); + if ((vmx->cap[vcpu].proc_ctls & PROCBASED_INT_WINDOW_EXITING) == 0) { + vmx->cap[vcpu].proc_ctls |= PROCBASED_INT_WINDOW_EXITING; + vmcs_write(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls); + VCPU_CTR0(vmx->vm, vcpu, "Enabling interrupt window exiting"); + } } static void __inline vmx_clear_int_window_exiting(struct vmx *vmx, int vcpu) { + KASSERT((vmx->cap[vcpu].proc_ctls & PROCBASED_INT_WINDOW_EXITING) != 0, + ("intr_window_exiting not set: %#x", vmx->cap[vcpu].proc_ctls)); vmx->cap[vcpu].proc_ctls &= ~PROCBASED_INT_WINDOW_EXITING; vmcs_write(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls); + VCPU_CTR0(vmx->vm, vcpu, "Disabling interrupt window exiting"); } static void __inline vmx_set_nmi_window_exiting(struct vmx *vmx, int vcpu) { - vmx->cap[vcpu].proc_ctls |= PROCBASED_NMI_WINDOW_EXITING; - vmcs_write(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls); + if ((vmx->cap[vcpu].proc_ctls & PROCBASED_NMI_WINDOW_EXITING) == 0) { + vmx->cap[vcpu].proc_ctls |= PROCBASED_NMI_WINDOW_EXITING; + vmcs_write(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls); + VCPU_CTR0(vmx->vm, vcpu, "Enabling NMI window exiting"); + } } static void __inline vmx_clear_nmi_window_exiting(struct vmx *vmx, int vcpu) { + KASSERT((vmx->cap[vcpu].proc_ctls & PROCBASED_NMI_WINDOW_EXITING) != 0, + ("nmi_window_exiting not set %#x", vmx->cap[vcpu].proc_ctls)); vmx->cap[vcpu].proc_ctls &= ~PROCBASED_NMI_WINDOW_EXITING; vmcs_write(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls); + VCPU_CTR0(vmx->vm, vcpu, "Disabling NMI window exiting"); } -static int +#define NMI_BLOCKING (VMCS_INTERRUPTIBILITY_NMI_BLOCKING | \ + VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING) +#define HWINTR_BLOCKING (VMCS_INTERRUPTIBILITY_STI_BLOCKING | \ + VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING) + +static void vmx_inject_nmi(struct vmx *vmx, int vcpu) { - uint64_t info, interruptibility; + uint32_t gi, info; - /* Bail out if no NMI requested */ - if (!vm_nmi_pending(vmx->vm, vcpu)) - return (0); + gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY); + KASSERT((gi & NMI_BLOCKING) == 0, ("vmx_inject_nmi: invalid guest " + "interruptibility-state %#x", gi)); - interruptibility = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY); - if (interruptibility & nmi_blocking_bits) - goto nmiblocked; + info = vmcs_read(VMCS_ENTRY_INTR_INFO); + KASSERT((info & VMCS_INTR_VALID) == 0, ("vmx_inject_nmi: invalid " + "VM-entry interruption information %#x", info)); /* * Inject the virtual NMI. The vector must be the NMI IDT entry * or the VMCS entry check will fail. */ - info = VMCS_INTR_T_NMI | VMCS_INTR_VALID; - info |= IDT_NMI; + info = IDT_NMI | VMCS_INTR_T_NMI | VMCS_INTR_VALID; vmcs_write(VMCS_ENTRY_INTR_INFO, info); VCPU_CTR0(vmx->vm, vcpu, "Injecting vNMI"); /* Clear the request */ vm_nmi_clear(vmx->vm, vcpu); - return (1); - -nmiblocked: - /* - * Set the NMI Window Exiting execution control so we can inject - * the virtual NMI as soon as blocking condition goes away. - */ - vmx_set_nmi_window_exiting(vmx, vcpu); - - VCPU_CTR0(vmx->vm, vcpu, "Enabling NMI window exiting"); - return (1); } static void vmx_inject_interrupts(struct vmx *vmx, int vcpu, struct vlapic *vlapic) { - int vector; - uint64_t info, rflags, interruptibility; - - const int HWINTR_BLOCKED = VMCS_INTERRUPTIBILITY_STI_BLOCKING | - VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING; + int vector, need_nmi_exiting; + uint64_t rflags; + uint32_t gi, info; - /* - * If there is already an interrupt pending then just return. - * - * This could happen if an interrupt was injected on a prior - * VM entry but the actual entry into guest mode was aborted - * because of a pending AST. - */ - info = vmcs_read(VMCS_ENTRY_INTR_INFO); - if (info & VMCS_INTR_VALID) - return; + if (vm_nmi_pending(vmx->vm, vcpu)) { + /* + * If there are no conditions blocking NMI injection then + * inject it directly here otherwise enable "NMI window + * exiting" to inject it as soon as we can. + * + * We also check for STI_BLOCKING because some implementations + * don't allow NMI injection in this case. If we are running + * on a processor that doesn't have this restriction it will + * immediately exit and the NMI will be injected in the + * "NMI window exiting" handler. + */ + need_nmi_exiting = 1; + gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY); + if ((gi & (HWINTR_BLOCKING | NMI_BLOCKING)) == 0) { + info = vmcs_read(VMCS_ENTRY_INTR_INFO); + if ((info & VMCS_INTR_VALID) == 0) { + vmx_inject_nmi(vmx, vcpu); + need_nmi_exiting = 0; + } else { + VCPU_CTR1(vmx->vm, vcpu, "Cannot inject NMI " + "due to VM-entry intr info %#x", info); + } + } else { + VCPU_CTR1(vmx->vm, vcpu, "Cannot inject NMI due to " + "Guest Interruptibility-state %#x", gi); + } - /* - * NMI injection has priority so deal with those first - */ - if (vmx_inject_nmi(vmx, vcpu)) - return; + if (need_nmi_exiting) + vmx_set_nmi_window_exiting(vmx, vcpu); + } if (virtual_interrupt_delivery) { vmx_inject_pir(vlapic); return; } + /* + * If there is already an interrupt pending then just return. This + * could happen for multiple reasons: + * - A vectoring VM-entry was aborted due to astpending or rendezvous. + * - A VM-exit happened during event injection. + * - A NMI was injected above or after "NMI window exiting" VM-exit. + */ + info = vmcs_read(VMCS_ENTRY_INTR_INFO); + if (info & VMCS_INTR_VALID) + return; + /* Ask the local apic for a vector to inject */ if (!vlapic_pending_intr(vlapic, &vector)) return; - if (vector < 32 || vector > 255) - panic("vmx_inject_interrupts: invalid vector %d\n", vector); + KASSERT(vector >= 32 && vector <= 255, ("invalid vector %d", vector)); /* Check RFLAGS.IF and the interruptibility state of the guest */ rflags = vmcs_read(VMCS_GUEST_RFLAGS); if ((rflags & PSL_I) == 0) goto cantinject; - interruptibility = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY); - if (interruptibility & HWINTR_BLOCKED) + gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY); + if (gi & HWINTR_BLOCKING) goto cantinject; /* Inject the interrupt */ @@ -1151,8 +1164,6 @@ cantinject: * the interrupt as soon as blocking condition goes away. */ vmx_set_int_window_exiting(vmx, vcpu); - - VCPU_CTR0(vmx->vm, vcpu, "Enabling interrupt window exiting"); } /* @@ -1587,7 +1598,6 @@ vmx_exit_process(struct vmx *vmx, int vc case EXIT_REASON_INTR_WINDOW: vmm_stat_incr(vmx->vm, vcpu, VMEXIT_INTR_WINDOW, 1); vmx_clear_int_window_exiting(vmx, vcpu); - VCPU_CTR0(vmx->vm, vcpu, "Disabling interrupt window exiting"); return (1); case EXIT_REASON_EXT_INTR: /* @@ -1613,9 +1623,10 @@ vmx_exit_process(struct vmx *vmx, int vc return (1); case EXIT_REASON_NMI_WINDOW: /* Exit to allow the pending virtual NMI to be injected */ - vmm_stat_incr(vmx->vm, vcpu, VMEXIT_NMI_WINDOW, 1); + if (vm_nmi_pending(vmx->vm, vcpu)) + vmx_inject_nmi(vmx, vcpu); vmx_clear_nmi_window_exiting(vmx, vcpu); - VCPU_CTR0(vmx->vm, vcpu, "Disabling NMI window exiting"); + vmm_stat_incr(vmx->vm, vcpu, VMEXIT_NMI_WINDOW, 1); return (1); case EXIT_REASON_INOUT: vmm_stat_incr(vmx->vm, vcpu, VMEXIT_INOUT, 1); Modified: user/ae/inet6/sys/ia64/conf/GENERIC ============================================================================== --- user/ae/inet6/sys/ia64/conf/GENERIC Tue Feb 4 09:11:50 2014 (r261479) +++ user/ae/inet6/sys/ia64/conf/GENERIC Tue Feb 4 09:30:42 2014 (r261480) @@ -192,7 +192,9 @@ options AH_SUPPORT_AR5416 # Various (pseudo) devices device ether # Ethernet support device faith # IPv6-to-IPv4 relaying (translation) +device firmware # firmware assist module device gif # IPv6 and IPv4 tunneling +device kbdmux # keyboard multiplexer device loop # Network loopback device md # Memory "disks" device puc # Multi I/O cards and multi-channel UARTs @@ -200,7 +202,8 @@ device random # Entropy device device tun # Packet tunnel. device uart # Serial port (UART) device vlan # 802.1Q VLAN support -device firmware # firmware assist module +device vt # Virtual terminals +device vt_vga # VGA terminal device # The `bpf' device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! Modified: user/ae/inet6/sys/net/ieee8023ad_lacp.c ============================================================================== --- user/ae/inet6/sys/net/ieee8023ad_lacp.c Tue Feb 4 09:11:50 2014 (r261479) +++ user/ae/inet6/sys/net/ieee8023ad_lacp.c Tue Feb 4 09:30:42 2014 (r261480) @@ -522,11 +522,7 @@ lacp_port_create(struct lagg_port *lgp) boolean_t active = TRUE; /* XXX should be configurable */ boolean_t fast = FALSE; /* XXX should be configurable */ - bzero((char *)&sdl, sizeof(sdl)); - sdl.sdl_len = sizeof(sdl); - sdl.sdl_family = AF_LINK; - sdl.sdl_index = ifp->if_index; - sdl.sdl_type = IFT_ETHER; + link_init_sdl(ifp, (struct sockaddr *)&sdl, IFT_ETHER); sdl.sdl_alen = ETHER_ADDR_LEN; bcopy(ðermulticastaddr_slowprotocols, Modified: user/ae/inet6/sys/net/if.c ============================================================================== --- user/ae/inet6/sys/net/if.c Tue Feb 4 09:11:50 2014 (r261479) +++ user/ae/inet6/sys/net/if.c Tue Feb 4 09:30:42 2014 (r261480) @@ -1902,6 +1902,38 @@ link_rtrequest(int cmd, struct rtentry * } } +struct sockaddr_dl * +link_alloc_sdl(size_t size, int flags) +{ + + return (malloc(size, M_TEMP, flags)); +} + +void +link_free_sdl(struct sockaddr *sa) +{ + free(sa, M_TEMP); +} + +/* + * Fills in given sdl with interface basic info. + * Returns pointer to filled sdl. + */ +struct sockaddr_dl * +link_init_sdl(struct ifnet *ifp, struct sockaddr *paddr, u_char iftype) +{ + struct sockaddr_dl *sdl; + + sdl = (struct sockaddr_dl *)paddr; + memset(sdl, 0, sizeof(struct sockaddr_dl)); + sdl->sdl_len = sizeof(struct sockaddr_dl); + sdl->sdl_family = AF_LINK; + sdl->sdl_index = ifp->if_index; + sdl->sdl_type = iftype; + + return (sdl); +} + /* * Mark an interface down and notify protocols of * the transition. @@ -2952,6 +2984,7 @@ if_addmulti(struct ifnet *ifp, struct so { struct ifmultiaddr *ifma, *ll_ifma; struct sockaddr *llsa; + struct sockaddr_dl sdl; int error; /* @@ -2971,12 +3004,18 @@ if_addmulti(struct ifnet *ifp, struct so /* * The address isn't already present; resolve the protocol address * into a link layer address, and then look that up, bump its - * refcount or allocate an ifma for that also. If 'llsa' was - * returned, we will need to free it later. + * refcount or allocate an ifma for that also. + * Most link layer resolving functions returns address data which + * fits inside default sockaddr_dl structure. However callback + * can allocate another sockaddr structure, in that case we need to + * free it later. */ llsa = NULL; ll_ifma = NULL; if (ifp->if_resolvemulti != NULL) { + /* Provide called function with buffer size information */ + sdl.sdl_len = sizeof(sdl); + llsa = (struct sockaddr *)&sdl; error = ifp->if_resolvemulti(ifp, &llsa, sa); if (error) goto unlock_out; @@ -3040,14 +3079,14 @@ if_addmulti(struct ifnet *ifp, struct so (void) (*ifp->if_ioctl)(ifp, SIOCADDMULTI, 0); } - if (llsa != NULL) - free(llsa, M_IFMADDR); + if ((llsa != NULL) && (llsa != (struct sockaddr *)&sdl)) + link_free_sdl(llsa); return (0); free_llsa_out: - if (llsa != NULL) - free(llsa, M_IFMADDR); + if ((llsa != NULL) && (llsa != (struct sockaddr *)&sdl)) + link_free_sdl(llsa); unlock_out: IF_ADDR_WUNLOCK(ifp); Modified: user/ae/inet6/sys/net/if_arcsubr.c ============================================================================== --- user/ae/inet6/sys/net/if_arcsubr.c Tue Feb 4 09:11:50 2014 (r261479) +++ user/ae/inet6/sys/net/if_arcsubr.c Tue Feb 4 09:30:42 2014 (r261480) @@ -786,14 +786,7 @@ arc_resolvemulti(struct ifnet *ifp, stru sin = (struct sockaddr_in *)sa; if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) return EADDRNOTAVAIL; - sdl = malloc(sizeof *sdl, M_IFMADDR, - M_NOWAIT | M_ZERO); - if (sdl == NULL) - return ENOMEM; - sdl->sdl_len = sizeof *sdl; - sdl->sdl_family = AF_LINK; - sdl->sdl_index = ifp->if_index; - sdl->sdl_type = IFT_ARCNET; + sdl = link_init_sdl(ifp, *llsa, IFT_ETHER); sdl->sdl_alen = ARC_ADDR_LEN; *LLADDR(sdl) = 0; *llsa = (struct sockaddr *)sdl; @@ -814,14 +807,7 @@ arc_resolvemulti(struct ifnet *ifp, stru } if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) return EADDRNOTAVAIL; - sdl = malloc(sizeof *sdl, M_IFMADDR, - M_NOWAIT | M_ZERO); - if (sdl == NULL) - return ENOMEM; - sdl->sdl_len = sizeof *sdl; - sdl->sdl_family = AF_LINK; - sdl->sdl_index = ifp->if_index; - sdl->sdl_type = IFT_ARCNET; + sdl = link_init_sdl(ifp, *llsa, IFT_ETHER); sdl->sdl_alen = ARC_ADDR_LEN; *LLADDR(sdl) = 0; *llsa = (struct sockaddr *)sdl; Modified: user/ae/inet6/sys/net/if_dl.h ============================================================================== --- user/ae/inet6/sys/net/if_dl.h Tue Feb 4 09:11:50 2014 (r261479) +++ user/ae/inet6/sys/net/if_dl.h Tue Feb 4 09:30:42 2014 (r261480) @@ -69,6 +69,12 @@ struct sockaddr_dl { #define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen)) #define LLINDEX(s) ((s)->sdl_index) + +struct ifnet; +struct sockaddr_dl *link_alloc_sdl(size_t, int); +void link_free_sdl(struct sockaddr *sa); +struct sockaddr_dl *link_init_sdl(struct ifnet *, struct sockaddr *, u_char); + #ifndef _KERNEL #include <sys/cdefs.h> Modified: user/ae/inet6/sys/net/if_ethersubr.c ============================================================================== --- user/ae/inet6/sys/net/if_ethersubr.c Tue Feb 4 09:11:50 2014 (r261479) +++ user/ae/inet6/sys/net/if_ethersubr.c Tue Feb 4 09:30:42 2014 (r261480) @@ -1171,14 +1171,7 @@ ether_resolvemulti(struct ifnet *ifp, st sin = (struct sockaddr_in *)sa; if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) return EADDRNOTAVAIL; - sdl = malloc(sizeof *sdl, M_IFMADDR, - M_NOWAIT|M_ZERO); - if (sdl == NULL) - return ENOMEM; - sdl->sdl_len = sizeof *sdl; - sdl->sdl_family = AF_LINK; - sdl->sdl_index = ifp->if_index; - sdl->sdl_type = IFT_ETHER; + sdl = link_init_sdl(ifp, *llsa, IFT_ETHER); sdl->sdl_alen = ETHER_ADDR_LEN; e_addr = LLADDR(sdl); ETHER_MAP_IP_MULTICAST(&sin->sin_addr, e_addr); @@ -1200,14 +1193,7 @@ ether_resolvemulti(struct ifnet *ifp, st } if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) return EADDRNOTAVAIL; - sdl = malloc(sizeof *sdl, M_IFMADDR, - M_NOWAIT|M_ZERO); - if (sdl == NULL) - return (ENOMEM); - sdl->sdl_len = sizeof *sdl; - sdl->sdl_family = AF_LINK; - sdl->sdl_index = ifp->if_index; - sdl->sdl_type = IFT_ETHER; + sdl = link_init_sdl(ifp, *llsa, IFT_ETHER); sdl->sdl_alen = ETHER_ADDR_LEN; e_addr = LLADDR(sdl); ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, e_addr); Modified: user/ae/inet6/sys/net/if_fddisubr.c ============================================================================== --- user/ae/inet6/sys/net/if_fddisubr.c Tue Feb 4 09:11:50 2014 (r261479) +++ user/ae/inet6/sys/net/if_fddisubr.c Tue Feb 4 09:30:42 2014 (r261480) @@ -729,14 +729,7 @@ fddi_resolvemulti(ifp, llsa, sa) sin = (struct sockaddr_in *)sa; if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) return (EADDRNOTAVAIL); - sdl = malloc(sizeof *sdl, M_IFMADDR, - M_NOWAIT | M_ZERO); - if (sdl == NULL) - return (ENOMEM); - sdl->sdl_len = sizeof *sdl; - sdl->sdl_family = AF_LINK; - sdl->sdl_index = ifp->if_index; - sdl->sdl_type = IFT_FDDI; + sdl = link_init_sdl(ifp, *llsa, IFT_FDDI); sdl->sdl_nlen = 0; sdl->sdl_alen = FDDI_ADDR_LEN; sdl->sdl_slen = 0; @@ -760,14 +753,7 @@ fddi_resolvemulti(ifp, llsa, sa) } if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) return (EADDRNOTAVAIL); - sdl = malloc(sizeof *sdl, M_IFMADDR, - M_NOWAIT | M_ZERO); - if (sdl == NULL) - return (ENOMEM); - sdl->sdl_len = sizeof *sdl; - sdl->sdl_family = AF_LINK; - sdl->sdl_index = ifp->if_index; - sdl->sdl_type = IFT_FDDI; + sdl = link_init_sdl(ifp, *llsa, IFT_FDDI); sdl->sdl_nlen = 0; sdl->sdl_alen = FDDI_ADDR_LEN; sdl->sdl_slen = 0; Modified: user/ae/inet6/sys/net/if_iso88025subr.c ============================================================================== --- user/ae/inet6/sys/net/if_iso88025subr.c Tue Feb 4 09:11:50 2014 (r261479) +++ user/ae/inet6/sys/net/if_iso88025subr.c Tue Feb 4 09:30:42 2014 (r261480) @@ -721,14 +721,7 @@ iso88025_resolvemulti (ifp, llsa, sa) if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { return (EADDRNOTAVAIL); } - sdl = malloc(sizeof *sdl, M_IFMADDR, - M_NOWAIT|M_ZERO); - if (sdl == NULL) - return (ENOMEM); - sdl->sdl_len = sizeof *sdl; - sdl->sdl_family = AF_LINK; - sdl->sdl_index = ifp->if_index; - sdl->sdl_type = IFT_ISO88025; + sdl = link_init_sdl(ifp, *llsa, IFT_ISO88025); sdl->sdl_alen = ISO88025_ADDR_LEN; e_addr = LLADDR(sdl); ETHER_MAP_IP_MULTICAST(&sin->sin_addr, e_addr); @@ -751,14 +744,7 @@ iso88025_resolvemulti (ifp, llsa, sa) if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) { return (EADDRNOTAVAIL); } - sdl = malloc(sizeof *sdl, M_IFMADDR, - M_NOWAIT|M_ZERO); - if (sdl == NULL) - return (ENOMEM); - sdl->sdl_len = sizeof *sdl; - sdl->sdl_family = AF_LINK; - sdl->sdl_index = ifp->if_index; - sdl->sdl_type = IFT_ISO88025; + sdl = link_init_sdl(ifp, *llsa, IFT_ISO88025); sdl->sdl_alen = ISO88025_ADDR_LEN; e_addr = LLADDR(sdl); ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, e_addr); Modified: user/ae/inet6/sys/net/if_lagg.c ============================================================================== --- user/ae/inet6/sys/net/if_lagg.c Tue Feb 4 09:11:50 2014 (r261479) +++ user/ae/inet6/sys/net/if_lagg.c Tue Feb 4 09:30:42 2014 (r261480) @@ -1214,12 +1214,8 @@ lagg_ether_cmdmulti(struct lagg_port *lp LAGG_WLOCK_ASSERT(sc); - bzero((char *)&sdl, sizeof(sdl)); - sdl.sdl_len = sizeof(sdl); - sdl.sdl_family = AF_LINK; - sdl.sdl_type = IFT_ETHER; + link_init_sdl(ifp, (struct sockaddr *)&sdl, IFT_ETHER); sdl.sdl_alen = ETHER_ADDR_LEN; - sdl.sdl_index = ifp->if_index; if (set) { TAILQ_FOREACH(ifma, &scifp->if_multiaddrs, ifma_link) { Modified: user/ae/inet6/sys/netinet/ip_carp.c ============================================================================== --- user/ae/inet6/sys/netinet/ip_carp.c Tue Feb 4 09:11:50 2014 (r261479) +++ user/ae/inet6/sys/netinet/ip_carp.c Tue Feb 4 09:30:42 2014 (r261480) @@ -956,7 +956,7 @@ carp_ifa_addroute(struct ifaddr *ifa) case AF_INET6: ifa_add_loopback_route(ifa, (struct sockaddr *)&ifatoia6(ifa)->ia_addr); - in6_ifaddloop(ifa); + nd6_add_ifa_lle(ifatoia6(ifa)); break; #endif } @@ -987,7 +987,7 @@ carp_ifa_delroute(struct ifaddr *ifa) case AF_INET6: ifa_del_loopback_route(ifa, (struct sockaddr *)&ifatoia6(ifa)->ia_addr); - in6_ifremloop(ifa); + nd6_rem_ifa_lle(ifatoia6(ifa)); break; #endif } Modified: user/ae/inet6/sys/netinet/tcp_syncache.c ============================================================================== --- user/ae/inet6/sys/netinet/tcp_syncache.c Tue Feb 4 09:11:50 2014 (r261479) +++ user/ae/inet6/sys/netinet/tcp_syncache.c Tue Feb 4 09:30:42 2014 (r261480) @@ -724,6 +724,16 @@ syncache_socket(struct syncache *sc, str #endif /* + * If there's an mbuf and it has a flowid, then let's initialise the + * inp with that particular flowid. + */ + if (m != NULL && m->m_flags & M_FLOWID) { + inp->inp_flags |= INP_HW_FLOWID; + inp->inp_flags &= ~INP_SW_FLOWID; + inp->inp_flowid = m->m_pkthdr.flowid; + } + + /* * Install in the reservation hash table for now, but don't yet * install a connection group since the full 4-tuple isn't yet * configured. Modified: user/ae/inet6/sys/netinet6/in6.c ============================================================================== --- user/ae/inet6/sys/netinet6/in6.c Tue Feb 4 09:11:50 2014 (r261479) +++ user/ae/inet6/sys/netinet6/in6.c Tue Feb 4 09:30:42 2014 (r261480) @@ -133,8 +133,8 @@ const struct in6_addr in6mask128 = IN6MA const struct sockaddr_in6 sa6_any = { sizeof(sa6_any), AF_INET6, 0, 0, IN6ADDR_ANY_INIT, 0 }; -static int in6_ifinit(struct ifnet *, struct in6_ifaddr *, - struct sockaddr_in6 *, int); +static int in6_notify_ifa(struct ifnet *, struct in6_ifaddr *, + struct in6_aliasreq *, int); static void in6_unlink_ifa(struct in6_ifaddr *, struct ifnet *); int (*faithprefix_p)(struct in6_addr *); @@ -145,44 +145,26 @@ static struct in6_ifaddr *in6_alloc_ifa( struct in6_aliasreq *, int flags); static int in6_update_ifa_internal(struct ifnet *, struct in6_aliasreq *, struct in6_ifaddr *, int, int); -static int in6_setup_ifa(struct ifnet *, struct in6_aliasreq *, +static int in6_broadcast_ifa(struct ifnet *, struct in6_aliasreq *, struct in6_ifaddr *, int); #define ifa2ia6(ifa) ((struct in6_ifaddr *)(ifa)) #define ia62ifa(ia6) (&((ia6)->ia_ifa)) + void -in6_ifaddloop(struct ifaddr *ifa) +in6_newaddrmsg(struct in6_ifaddr *ia, int cmd) { struct sockaddr_dl gateway; struct sockaddr_in6 mask, addr; struct rtentry rt; - struct in6_ifaddr *ia; - struct ifnet *ifp; - struct llentry *ln; - ia = ifa2ia6(ifa); - ifp = ifa->ifa_ifp; - IF_AFDATA_LOCK(ifp); - ifa->ifa_rtrequest = nd6_rtrequest; - ln = lla_lookup(LLTABLE6(ifp), (LLE_CREATE | LLE_IFADDR | - LLE_EXCLUSIVE), (struct sockaddr *)&ia->ia_addr); - IF_AFDATA_UNLOCK(ifp); - if (ln != NULL) { - ln->la_expire = 0; /* for IPv6 this means permanent */ - ln->ln_state = ND6_LLINFO_REACHABLE; - /* - * initialize for rtmsg generation - */ - bzero(&gateway, sizeof(gateway)); - gateway.sdl_len = sizeof(gateway); - gateway.sdl_family = AF_LINK; - gateway.sdl_nlen = 0; - gateway.sdl_alen = 6; - memcpy(gateway.sdl_data, &ln->ll_addr.mac_aligned, - sizeof(ln->ll_addr)); - LLE_WUNLOCK(ln); - } + /* + * initialize for rtmsg generation + */ + bzero(&gateway, sizeof(gateway)); + gateway.sdl_len = sizeof(gateway); + gateway.sdl_family = AF_LINK; bzero(&rt, sizeof(rt)); rt.rt_gateway = (struct sockaddr *)&gateway; @@ -190,42 +172,11 @@ in6_ifaddloop(struct ifaddr *ifa) memcpy(&addr, &ia->ia_addr, sizeof(ia->ia_addr)); rt_mask(&rt) = (struct sockaddr *)&mask; rt_key(&rt) = (struct sockaddr *)&addr; - rt.rt_flags = RTF_UP | RTF_HOST | RTF_STATIC; + rt.rt_flags = RTF_HOST | RTF_STATIC; + if (cmd == RTM_ADD) + rt.rt_flags |= RTF_UP; /* Announce arrival of local address to all FIBs. */ - rt_newaddrmsg(RTM_ADD, ifa, 0, &rt); -} - -void -in6_ifremloop(struct ifaddr *ifa) -{ - struct sockaddr_dl gateway; - struct sockaddr_in6 mask, addr; - struct rtentry rt0; - struct in6_ifaddr *ia; - struct ifnet *ifp; - - ia = ifa2ia6(ifa); - ifp = ifa->ifa_ifp; - memcpy(&addr, &ia->ia_addr, sizeof(ia->ia_addr)); - memcpy(&mask, &ia->ia_prefixmask, sizeof(ia->ia_prefixmask)); - lltable_prefix_free(AF_INET6, (struct sockaddr *)&addr, - (struct sockaddr *)&mask, LLE_STATIC); - - /* - * initialize for rtmsg generation - */ - bzero(&gateway, sizeof(gateway)); - gateway.sdl_len = sizeof(gateway); - gateway.sdl_family = AF_LINK; - gateway.sdl_nlen = 0; - gateway.sdl_alen = ifp->if_addrlen; - bzero(&rt0, sizeof(rt0)); - rt0.rt_gateway = (struct sockaddr *)&gateway; - rt_mask(&rt0) = (struct sockaddr *)&mask; - rt_key(&rt0) = (struct sockaddr *)&addr; - rt0.rt_flags = RTF_HOST | RTF_STATIC; - /* Announce removal of local address to all FIBs. */ - rt_newaddrmsg(RTM_DELETE, ifa, 0, &rt0); + rt_newaddrmsg(cmd, &ia->ia_ifa, 0, &rt); } int @@ -962,13 +913,13 @@ in6_update_ifa(struct ifnet *ifp, struct } if (hostIsNew) - error = in6_setup_ifa(ifp, ifra, ia, flags); + error = in6_broadcast_ifa(ifp, ifra, ia, flags); return (error); } /* - * Fill in basic IPv6 address request info + * Fill in basic IPv6 address request info. */ void in6_prepare_ifra(struct in6_aliasreq *ifra, const struct in6_addr *addr, @@ -992,9 +943,9 @@ static int in6_validate_ifra(struct ifnet *ifp, struct in6_aliasreq *ifra, struct in6_ifaddr *ia, int flags) { - int plen = -1; struct sockaddr_in6 dst6; struct in6_addrlifetime *lt; + int plen; char ip6buf[INET6_ADDRSTRLEN]; /* Validate parameters */ @@ -1009,6 +960,19 @@ in6_validate_ifra(struct ifnet *ifp, str ifra->ifra_dstaddr.sin6_family != AF_INET6 && ifra->ifra_dstaddr.sin6_family != AF_UNSPEC) return (EAFNOSUPPORT); + + /* + * Validate address + */ + if (ifra->ifra_addr.sin6_len != sizeof(struct sockaddr_in6) || + ifra->ifra_addr.sin6_family != AF_INET6) + return (EINVAL); + /* + * Check and automatically fill scope zone index. + */ + plen = sa6_checkzone_ifp(ifp, &ifra->ifra_addr); + if (plen != 0) + return (plen); /* * validate ifra_prefixmask. don't check sin6_family, netmask * does not carry fields other than sin6_len. @@ -1126,12 +1090,11 @@ in6_alloc_ifa(struct ifnet *ifp, struct LIST_INIT(&ia->ia6_memberships); /* Initialize the address and masks, and put time stamp */ ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; - ia->ia_addr.sin6_family = AF_INET6; - ia->ia_addr.sin6_len = sizeof(ia->ia_addr); + ia->ia_addr = ifra->ifra_addr; ia->ia6_createtime = time_uptime; if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) { /* - * XXX: some functions expect that ifa_dstaddr is not + * Some functions expect that ifa_dstaddr is not * NULL for p2p interfaces. */ ia->ia_ifa.ifa_dstaddr = @@ -1139,7 +1102,15 @@ in6_alloc_ifa(struct ifnet *ifp, struct } else { ia->ia_ifa.ifa_dstaddr = NULL; } + + /* set prefix mask if any */ ia->ia_ifa.ifa_netmask = (struct sockaddr *)&ia->ia_prefixmask; + if (ifra->ifra_prefixmask.sin6_len != 0) { + ia->ia_prefixmask.sin6_family = AF_INET6; + ia->ia_prefixmask.sin6_len = ifra->ifra_prefixmask.sin6_len; + ia->ia_prefixmask.sin6_addr = ifra->ifra_prefixmask.sin6_addr; + } + ia->ia_ifp = ifp; ifa_ref(&ia->ia_ifa); /* if_addrhead */ IF_ADDR_WLOCK(ifp); @@ -1149,30 +1120,28 @@ in6_alloc_ifa(struct ifnet *ifp, struct ifa_ref(&ia->ia_ifa); /* in6_ifaddrhead */ IN6_IFADDR_WLOCK(); TAILQ_INSERT_TAIL(&V_in6_ifaddrhead, ia, ia_link); - LIST_INSERT_HEAD(IN6ADDR_HASH(&ifra->ifra_addr.sin6_addr), - ia, ia6_hash); + LIST_INSERT_HEAD(IN6ADDR_HASH(&ia->ia_addr.sin6_addr), ia, ia6_hash); IN6_IFADDR_WUNLOCK(); return (ia); } +/* + * Update/configure interface address parameters: + * + * 1) Update lifetime + * 2) Update interface metric ad flags + * 3) Notify other subsystems + */ static int in6_update_ifa_internal(struct ifnet *ifp, struct in6_aliasreq *ifra, struct in6_ifaddr *ia, int hostIsNew, int flags) { - struct sockaddr_in6 *pdst; int error; - char ip6buf[INET6_ADDRSTRLEN]; /* update timestamp */ ia->ia6_updatetime = time_uptime; - /* set prefix mask */ - if (ifra->ifra_prefixmask.sin6_len != 0) { - ia->ia_prefixmask = ifra->ifra_prefixmask; - ia->ia_prefixmask.sin6_family = AF_INET6; - } - /* * Set lifetimes. We do not refer to ia6t_expire and ia6t_preferred * to see if the address is deprecated or invalidated, but initialize @@ -1199,6 +1168,9 @@ in6_update_ifa_internal(struct ifnet *if ia->ia6_lifetime.ia6t_preferred = time_uptime; } + /* Update metric */ + ia->ia_ifa.ifa_metric = ifp->if_metric; + /* * configure address flags. */ @@ -1217,53 +1189,40 @@ in6_update_ifa_internal(struct ifnet *if if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) ia->ia6_flags |= IN6_IFF_TENTATIVE; - /* - * If a new destination address is specified, scrub the old one and - * install the new destination. Note that the interface must be - * p2p or loopback (see the check above.) - */ - pdst = &ifra->ifra_dstaddr; - if (pdst->sin6_family == AF_INET6 && - !IN6_ARE_ADDR_EQUAL(&pdst->sin6_addr, &ia->ia_dstaddr.sin6_addr)) { - if ((ia->ia_flags & IFA_ROUTE) != 0 && - (rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST) != 0)) { - nd6log((LOG_ERR, "in6_update_ifa_internal: failed to " - "remove a route to the old destination: %s\n", - ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr))); - /* proceed anyway... */ - } else - ia->ia_flags &= ~IFA_ROUTE; - ia->ia_dstaddr = *pdst; - } - - /* reset the interface and routing table appropriately. */ - if ((error = in6_ifinit(ifp, ia, &ifra->ifra_addr, hostIsNew)) != 0) { - /* - * XXX: if a change of an existing address failed, keep the entry - * anyway. - */ - } + /* notify other subsystems */ + error = in6_notify_ifa(ifp, ia, ifra, hostIsNew); return (error); } +/* + * Do link-level ifa job: + * 1) Add lle entry for added address + * 2) Notifies routing socket users about new address + * 3) join appropriate multicast group + * 4) start DAD if enabled + */ static int -in6_setup_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, +in6_broadcast_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, struct in6_ifaddr *ia, int flags) { struct in6_multi *in6m_sol; int error = 0; /* Add local address to lltable, if necessary (ex. on p2p link). */ - in6_ifaddloop(&(ia->ia_ifa)); + if ((error = nd6_add_ifa_lle(ia)) != 0) { + in6_purgeaddr(&ia->ia_ifa); + ifa_free(&ia->ia_ifa); + return (error); + } /* Join necessary multicast groups. */ in6m_sol = NULL; if ((ifp->if_flags & IFF_MULTICAST) != 0) { error = in6_update_ifa_join_mc(ifp, ifra, ia, flags, &in6m_sol); if (error != 0) { - ifa_free(&ia->ia_ifa); in6_purgeaddr(&ia->ia_ifa); + ifa_free(&ia->ia_ifa); return (error); } } @@ -1370,7 +1329,7 @@ in6_purgeaddr(struct ifaddr *ifa) nd6_dad_stop(ifa); /* Remove local address entry from lltable. */ - in6_ifremloop(ifa); + nd6_rem_ifa_lle(ia); /* Leave multicast groups. */ error = in6_purgeaddr_mc(ifp, ia, ifa0); @@ -1435,46 +1394,60 @@ in6_unlink_ifa(struct in6_ifaddr *ia, st } /* - * Initialize an interface's IPv6 address and routing table entry. + * Notifies other other subsystems about address change/arrival: + * 1) Notifies device handler on first IPv6 address assignment + * 2) Handle routing table changes for P2P links and route + * 3) Handle routing table changes for address host route */ static int -in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia, - struct sockaddr_in6 *sin6, int newhost) +in6_notify_ifa(struct ifnet *ifp, struct in6_ifaddr *ia, + struct in6_aliasreq *ifra, int hostIsNew) { int error = 0, plen, ifacount = 0; struct ifaddr *ifa; + struct sockaddr_in6 *pdst; + char ip6buf[INET6_ADDRSTRLEN]; /* * Give the interface a chance to initialize * if this is its first address, - * and to validate the address if necessary. */ - IF_ADDR_RLOCK(ifp); - TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - if (ifa->ifa_addr->sa_family != AF_INET6) - continue; - ifacount++; + if (hostIsNew != 0) { + IF_ADDR_RLOCK(ifp); + TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { + if (ifa->ifa_addr->sa_family != AF_INET6) + continue; + ifacount++; + } + IF_ADDR_RUNLOCK(ifp); } - IF_ADDR_RUNLOCK(ifp); - ia->ia_addr = *sin6; - /* - * Initialize sin6_scope_id using specified ifnet. - */ - ia->ia_addr.sin6_scope_id = in6_getscopezone(ifp, - in6_addrscope(&sin6->sin6_addr)); if (ifacount <= 1 && ifp->if_ioctl) { error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia); if (error) return (error); } - ia->ia_ifa.ifa_metric = ifp->if_metric; - - /* we could do in(6)_socktrim here, but just omit it at this moment. */ + /* + * If a new destination address is specified, scrub the old one and + * install the new destination. Note that the interface must be + * p2p or loopback. + */ + pdst = &ifra->ifra_dstaddr; + if (pdst->sin6_family == AF_INET6 && + !IN6_ARE_ADDR_EQUAL(&pdst->sin6_addr, &ia->ia_dstaddr.sin6_addr)) { + if ((ia->ia_flags & IFA_ROUTE) != 0 && + (rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST) != 0)) { + nd6log((LOG_ERR, "in6_update_ifa_internal: failed to " *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201402040930.s149Ugwr078172>