From owner-svn-src-projects@FreeBSD.ORG Tue Jun 3 04:38:13 2014 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id CE7D918B; Tue, 3 Jun 2014 04:38:13 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BCA5A2911; Tue, 3 Jun 2014 04:38:13 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s534cDvg031657; Tue, 3 Jun 2014 04:38:13 GMT (envelope-from bryanv@svn.freebsd.org) Received: (from bryanv@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s534cDoc031656; Tue, 3 Jun 2014 04:38:13 GMT (envelope-from bryanv@svn.freebsd.org) Message-Id: <201406030438.s534cDoc031656@svn.freebsd.org> From: Bryan Venteicher Date: Tue, 3 Jun 2014 04:38:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r267000 - projects/vxlan/sys/net X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Jun 2014 04:38:13 -0000 Author: bryanv Date: Tue Jun 3 04:38:13 2014 New Revision: 267000 URL: http://svnweb.freebsd.org/changeset/base/267000 Log: Misc vxlan changes: - Fix assert when the multicast interface is detached: the socket will have already left the multicast group by the time our event handler is called. - Use the UDP tunnel callback context from the previous commit. - Unlock the INP during our receive handling. The locking could be reduced a bit more with some changes to udp_append(). Modified: projects/vxlan/sys/net/if_vxlan.c Modified: projects/vxlan/sys/net/if_vxlan.c ============================================================================== --- projects/vxlan/sys/net/if_vxlan.c Tue Jun 3 04:31:42 2014 (r266999) +++ projects/vxlan/sys/net/if_vxlan.c Tue Jun 3 04:38:13 2014 (r267000) @@ -276,6 +276,7 @@ static int vxlan_setup_multicast_interfa static int vxlan_setup_multicast(struct vxlan_softc *); static int vxlan_setup_socket(struct vxlan_softc *); +static void vxlan_setup_interface(struct vxlan_softc *); static int vxlan_valid_init_config(struct vxlan_softc *); static void vxlan_init_wait(struct vxlan_softc *); static void vxlan_init_complete(struct vxlan_softc *); @@ -320,7 +321,7 @@ static int vxlan_encap6(struct vxlan_sof static int vxlan_transmit(struct ifnet *, struct mbuf *); static void vxlan_qflush(struct ifnet *); static void vxlan_rcv_udp_packet(struct mbuf *, int, struct inpcb *, - const struct sockaddr *); + const struct sockaddr *, void *); static int vxlan_input(struct vxlan_socket *, uint32_t, struct mbuf **, const struct sockaddr *); @@ -834,7 +835,6 @@ static void vxlan_socket_destroy(struct vxlan_socket *vso) { struct socket *so; - struct inpcb *inp; struct vxlan_socket_mc_info *mc; int i; @@ -854,9 +854,6 @@ vxlan_socket_destroy(struct vxlan_socket so = vso->vxlso_sock; if (so != NULL) { vso->vxlso_sock = NULL; - inp = sotoinpcb(so); - MPASS(inp->inp_pspare[0] == vso); - inp->inp_pspare[0] = NULL; soclose(so); } @@ -909,7 +906,6 @@ vxlan_socket_insert(struct vxlan_socket static int vxlan_socket_init(struct vxlan_socket *vso, struct ifnet *ifp) { - struct inpcb *inp; struct thread *td; int error; @@ -922,16 +918,8 @@ vxlan_socket_init(struct vxlan_socket *v return (error); } - inp = sotoinpcb(vso->vxlso_sock); - /* - * XXX: Use a spare field in the inpcb to obtain the vxlan socket - * in the tunneling callback. We instead should be able to pass a - * context to the tunneling callback. - */ - MPASS(inp->inp_pspare[0] == NULL); - inp->inp_pspare[0] = vso; - - error = udp_set_kernel_tunneling(vso->vxlso_sock, vxlan_rcv_udp_packet); + error = udp_set_kernel_tunneling(vso->vxlso_sock, + vxlan_rcv_udp_packet, vso); if (error) { if_printf(ifp, "cannot set tunneling function: %d\n", error); return (error); @@ -1274,7 +1262,7 @@ vxlan_socket_mc_release_group_by_idx(str { union vxlan_sockaddr group, source; struct vxlan_socket_mc_info *mc; - int ifidx, leave, error; + int ifidx, leave; KASSERT(idx >= 0 && idx < VXLAN_SO_MC_MAX_GROUPS, ("%s: vso %p idx %d out of bounds", __func__, vso, idx)); @@ -1294,9 +1282,12 @@ vxlan_socket_mc_release_group_by_idx(str VXLAN_SO_WUNLOCK(vso); if (leave != 0) { - error = vxlan_socket_mc_leave_group(vso, &group, &source, - ifidx); - MPASS(error == 0); + /* + * Our socket's membership in this group may have already + * been removed if we joined through an interface that's + * been detached. + */ + vxlan_socket_mc_leave_group(vso, &group, &source, ifidx); } } @@ -1540,6 +1531,20 @@ out: return (error); } +static void +vxlan_setup_interface(struct vxlan_softc *sc) +{ + struct ifnet *ifp; + + ifp = sc->vxl_ifp; + ifp->if_hdrlen = ETHER_HDR_LEN + sizeof(struct vxlanudphdr); + + if (VXLAN_SOCKADDR_IS_IPV4(&sc->vxl_dst_addr) != 0) + ifp->if_hdrlen += sizeof(struct ip); + else if (VXLAN_SOCKADDR_IS_IPV6(&sc->vxl_dst_addr) != 0) + ifp->if_hdrlen += sizeof(struct ip6_hdr); +} + static int vxlan_valid_init_config(struct vxlan_softc *sc) { @@ -1594,7 +1599,6 @@ vxlan_valid_init_config(struct vxlan_sof fail: if_printf(sc->vxl_ifp, "cannot initialize interface: %s\n", reason); - return (EINVAL); } @@ -1638,9 +1642,12 @@ vxlan_init(void *xsc) if (vxlan_valid_init_config(sc) != 0) goto out; + vxlan_setup_interface(sc); + if (vxlan_setup_socket(sc) != 0) goto out; + /* Initialize the default forwarding entry. */ vxlan_ftable_entry_init(sc, &sc->vxl_default_fe, empty_mac, &sc->vxl_dst_addr.sa, VXLAN_FE_FLAG_STATIC); @@ -1652,7 +1659,6 @@ vxlan_init(void *xsc) out: vxlan_init_complete(sc); - } static void @@ -1853,7 +1859,7 @@ vxlan_ctrl_set_local_addr(struct vxlan_s cmd = arg; vxlsa = &cmd->vxlcmd_sa; - if (!VXLAN_SOCKADDR_IS_IPV4(vxlsa) && !VXLAN_SOCKADDR_IS_IPV6(vxlsa)) + if (!VXLAN_SOCKADDR_IS_IPV46(vxlsa)) return (EINVAL); if (vxlan_sockaddr_in_multicast(vxlsa) != 0) return (EINVAL); @@ -1879,7 +1885,7 @@ vxlan_ctrl_set_remote_addr(struct vxlan_ cmd = arg; vxlsa = &cmd->vxlcmd_sa; - if (!VXLAN_SOCKADDR_IS_IPV4(vxlsa) && !VXLAN_SOCKADDR_IS_IPV6(vxlsa)) + if (!VXLAN_SOCKADDR_IS_IPV46(vxlsa)) return (EINVAL); VXLAN_WLOCK(sc); @@ -2071,7 +2077,7 @@ vxlan_ctrl_ftable_entry_add(struct vxlan cmd = arg; vxlsa = cmd->vxlcmd_sa; - if (!VXLAN_SOCKADDR_IS_IPV4(&vxlsa) && !VXLAN_SOCKADDR_IS_IPV6(&vxlsa)) + if (!VXLAN_SOCKADDR_IS_IPV46(&vxlsa)) return (EINVAL); if (vxlan_sockaddr_in_any(&vxlsa) != 0) return (EINVAL); @@ -2271,6 +2277,7 @@ static int vxlan_encap4(struct vxlan_softc *sc, const union vxlan_sockaddr *fvxlsa, struct mbuf *m) { +#ifdef INET struct ifnet *ifp; struct ip *ip; struct in_addr srcaddr, dstaddr; @@ -2316,12 +2323,17 @@ vxlan_encap4(struct vxlan_softc *sc, con ifp->if_oerrors++; return (error); +#else + m_freem(m); + return (ENOTSUP); +#endif } static int vxlan_encap6(struct vxlan_softc *sc, const union vxlan_sockaddr *fvxlsa, struct mbuf *m) { +#ifdef INET6 struct ifnet *ifp; struct ip6_hdr *ip6; const struct in6_addr *srcaddr, *dstaddr; @@ -2366,6 +2378,10 @@ vxlan_encap6(struct vxlan_softc *sc, con ifp->if_oerrors++; return (error); +#else + m_freem(m); + return (ENOTSUP); +#endif } static int @@ -2424,18 +2440,17 @@ vxlan_qflush(struct ifnet *ifp __unused) static void vxlan_rcv_udp_packet(struct mbuf *m, int offset, struct inpcb *inpcb, - const struct sockaddr *srcsa) + const struct sockaddr *srcsa, void *xvso) { struct vxlan_socket *vso; struct vxlan_header *vxh, vxlanhdr; uint32_t vni; int error; - vso = inpcb->inp_pspare[0]; - if (vso == NULL) - goto out; + INP_RUNLOCK(inpcb); M_ASSERTPKTHDR(m); + vso = xvso; offset += sizeof(struct udphdr); if (m->m_pkthdr.len < offset + sizeof(struct vxlan_header)) @@ -2462,6 +2477,8 @@ vxlan_rcv_udp_packet(struct mbuf *m, int out: if (m != NULL) m_freem(m); + + INP_RLOCK(inpcb); } static int @@ -2655,9 +2672,9 @@ vxlan_clone_create(struct if_clone *ifc, vxlan_fakeaddr(sc); ether_ifattach(ifp, sc->vxl_hwaddr); - /* Now undo some of the damage... */ + ifp->if_baudrate = 0; - ifp->if_hdrlen = sizeof(struct vxlanudphdr); /* + sizeof(struct ip) */ + ifp->if_hdrlen = 0; return (0);