> Date: Mon, 10 Oct 2016 13:48:18 +1000
> From: David Gwynne <[email protected]>
>
> if the arch can cope with prepending on an unaligned address in
> vxlan, then let it do it.
>
> this means less work if we can get away with it.
>
> ok?
Let's face it. The vxlan protocol is badly designed. Should we
really create multiple code paths for strict-align and
non-strict-align architectures? Is vxlan really used in
performance-critical setups?
> Index: if_vxlan.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_vxlan.c,v
> retrieving revision 1.49
> diff -u -p -r1.49 if_vxlan.c
> --- if_vxlan.c 7 Oct 2016 06:16:03 -0000 1.49
> +++ if_vxlan.c 10 Oct 2016 03:42:36 -0000
> @@ -766,20 +765,29 @@ vxlan_output(struct ifnet *ifp, struct m
> #endif
> int error, af;
> uint32_t tag;
> - struct mbuf *m0;
>
> /* VXLAN header */
> - MGETHDR(m0, M_DONTWAIT, m->m_type);
> - if (m0 == NULL) {
> - ifp->if_oerrors++;
> - return (ENOBUFS);
> + if (!ALIGNED_POINTER(mtod(m, caddr_t), uint32_t)) {
> + struct mbuf *m0;
> +
> + MGETHDR(m0, M_DONTWAIT, m->m_type);
> + if (m0 == NULL) {
> + ifp->if_oerrors++;
> + return (ENOBUFS);
> + }
> + M_MOVE_PKTHDR(m0, m);
> + m0->m_next = m;
> + m = m0;
> + MH_ALIGN(m, sizeof(*vu));
> + m->m_len = sizeof(*vu);
> + m->m_pkthdr.len += sizeof(*vu);
> + } else {
> + M_PREPEND(m, sizeof(*vu), M_DONTWAIT);
> + if (m == NULL) {
> + ifp->if_oerrors++;
> + return (ENOBUFS);
> + }
> }
> - M_MOVE_PKTHDR(m0, m);
> - m0->m_next = m;
> - m = m0;
> - MH_ALIGN(m, sizeof(*vu));
> - m->m_len = sizeof(*vu);
> - m->m_pkthdr.len += sizeof(*vu);
>
> src = (struct sockaddr *)&sc->sc_src;
> dst = (struct sockaddr *)&sc->sc_dst;
>
>