I say great. On Sun, Apr 14, 2019, 12:00 AM David Gwynne <da...@gwynne.id.au> wrote:
> the mpls exp bits are now defined as a prio field, but we don't have > support for that currently. > > this lets the mpls tunnelling interfaces configure the use of the exp > fields for prio with the same machinery used for all the other tunnel > interfaces. the interfaces default to using 0 for the value which keeps > it compat. other values can be configured with ifconfig like normal > tunnel interfaces. > > ok? meh? nah? > > Index: if_mpe.c > =================================================================== > RCS file: /cvs/src/sys/net/if_mpe.c,v > retrieving revision 1.90 > diff -u -p -r1.90 if_mpe.c > --- if_mpe.c 2 Apr 2019 10:52:33 -0000 1.90 > +++ if_mpe.c 14 Apr 2019 06:49:56 -0000 > @@ -55,6 +55,7 @@ > > struct mpe_softc { > struct ifnet sc_if; /* the interface */ > + int sc_txhprio; > unsigned int sc_rdomain; > struct ifaddr sc_ifa; > struct sockaddr_mpls sc_smpls; > @@ -121,6 +122,7 @@ mpe_clone_create(struct if_clone *ifc, i > bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t)); > #endif > > + sc->sc_txhprio = 0; > sc->sc_rdomain = 0; > sc->sc_ifa.ifa_ifp = ifp; > sc->sc_ifa.ifa_addr = sdltosa(ifp->if_sadl); > @@ -210,10 +212,13 @@ int > mpe_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, > struct rtentry *rt) > { > + struct mpe_softc *sc; > struct rt_mpls *rtmpls; > struct shim_hdr shim; > int error; > + int txprio; > uint8_t ttl = mpls_defttl; > + uint8_t tos, prio; > size_t ttloff; > socklen_t slen; > > @@ -243,15 +248,22 @@ mpe_output(struct ifnet *ifp, struct mbu > > error = 0; > switch (dst->sa_family) { > - case AF_INET: > + case AF_INET: { > + struct ip *ip = mtod(m, struct ip *); > + tos = ip->ip_tos; > ttloff = offsetof(struct ip, ip_ttl); > slen = sizeof(struct sockaddr_in); > break; > + } > #ifdef INET6 > - case AF_INET6: > + case AF_INET6: { > + struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); > + uint32_t flow = bemtoh32(&ip6->ip6_flow); > + tos = flow >> 20; > ttloff = offsetof(struct ip6_hdr, ip6_hlim); > slen = sizeof(struct sockaddr_in6); > break; > + } > #endif > default: > m_freem(m); > @@ -263,7 +275,23 @@ mpe_output(struct ifnet *ifp, struct mbu > ttl = *(mtod(m, uint8_t *) + ttloff); > } > > - shim.shim_label = rtmpls->mpls_label | MPLS_BOS_MASK | htonl(ttl); > + sc = ifp->if_softc; > + txprio = sc->sc_txhprio; > + > + switch (txprio) { > + case IF_HDRPRIO_PACKET: > + prio = m->m_pkthdr.pf.prio; > + break; > + case IF_HDRPRIO_PAYLOAD: > + prio = IFQ_TOS2PRIO(tos); > + break; > + default: > + prio = txprio; > + break; > + } > + > + shim.shim_label = rtmpls->mpls_label | htonl(prio << > MPLS_EXP_OFFSET) | > + MPLS_BOS_MASK | htonl(ttl); > > m = m_prepend(m, sizeof(shim), M_NOWAIT); > if (m == NULL) { > @@ -278,7 +306,7 @@ mpe_output(struct ifnet *ifp, struct mbu > goto out; > } > memcpy(mtod(m, struct sockaddr *), rt->rt_gateway, slen); > - mtod(m, struct sockaddr *)->sa_len = slen; /* to be sure */ > + mtod(m, struct sockaddr *)->sa_len = slen; /* to be sure */ > > m->m_pkthdr.ph_family = dst->sa_family; > > @@ -387,6 +415,22 @@ mpe_ioctl(struct ifnet *ifp, u_long cmd, > break; > case SIOCGLIFPHYRTABLE: > ifr->ifr_rdomainid = sc->sc_rdomain; > + break; > + > + case SIOCSTXHPRIO: > + if (ifr->ifr_hdrprio == IF_HDRPRIO_PACKET || > + ifr->ifr_hdrprio == IF_HDRPRIO_PAYLOAD) > + ; > + else if (ifr->ifr_hdrprio > IF_HDRPRIO_MAX || > + ifr->ifr_hdrprio < IF_HDRPRIO_MIN) { > + error = EINVAL; > + break; > + } > + > + sc->sc_txhprio = ifr->ifr_hdrprio; > + break; > + case SIOCGTXHPRIO: > + ifr->ifr_hdrprio = sc->sc_txhprio; > break; > > default: > Index: if_mpip.c > =================================================================== > RCS file: /cvs/src/sys/net/if_mpip.c,v > retrieving revision 1.4 > diff -u -p -r1.4 if_mpip.c > --- if_mpip.c 2 Apr 2019 10:50:16 -0000 1.4 > +++ if_mpip.c 14 Apr 2019 06:49:56 -0000 > @@ -55,6 +55,7 @@ struct mpip_softc { > unsigned int sc_dead; > uint32_t sc_flow; /* xor for mbuf flowid */ > > + int sc_txhprio; > struct ifaddr sc_ifa; > struct sockaddr_mpls sc_smpls; /* Local label */ > unsigned int sc_rdomain; > @@ -92,6 +93,7 @@ mpip_clone_create(struct if_clone *ifc, > if (sc == NULL) > return (ENOMEM); > > + sc->sc_txhprio = 0; > sc->sc_neighbor = 0; > sc->sc_cword = 0; /* default to no control word */ > sc->sc_fword = 0; /* both sides have to agree on FAT first */ > @@ -415,6 +417,22 @@ mpip_ioctl(struct ifnet *ifp, u_long cmd > ifr->ifr_ttl = sc->sc_ttl; > break; > > + case SIOCSTXHPRIO: > + if (ifr->ifr_hdrprio == IF_HDRPRIO_PACKET || > + ifr->ifr_hdrprio == IF_HDRPRIO_PAYLOAD) > + ; > + else if (ifr->ifr_hdrprio > IF_HDRPRIO_MAX || > + ifr->ifr_hdrprio < IF_HDRPRIO_MIN) { > + error = EINVAL; > + break; > + } > + > + sc->sc_txhprio = ifr->ifr_hdrprio; > + break; > + case SIOCGTXHPRIO: > + ifr->ifr_hdrprio = sc->sc_txhprio; > + break; > + > case SIOCADDMULTI: > case SIOCDELMULTI: > break; > @@ -611,8 +629,9 @@ mpip_start(struct ifnet *ifp) > .smpls_len = sizeof(smpls), > .smpls_family = AF_MPLS, > }; > - uint32_t bos; > - uint8_t ttl; > + int txprio = sc->sc_txhprio; > + uint32_t exp, bos; > + uint8_t tos, prio, ttl; > > if (!ISSET(ifp->if_flags, IFF_RUNNING) || n == NULL) { > IFQ_PURGE(&ifp->if_snd); > @@ -662,6 +681,40 @@ mpip_start(struct ifnet *ifp) > } else > ttl = mpls_defttl; > > + switch (txprio) { > + case IF_HDRPRIO_PACKET: > + prio = m->m_pkthdr.pf.prio; > + break; > + case IF_HDRPRIO_PAYLOAD: > + switch (m->m_pkthdr.ph_family) { > + case AF_INET: { > + struct ip *ip; > + ip = mtod(m, struct ip *); > + tos = ip->ip_tos; > + break; > + } > +#ifdef INET6 > + case AF_INET6: { > + struct ip6_hdr *ip6; > + uint32_t flow; > + ip6 = mtod(m, struct ip6_hdr *); > + flow = bemtoh32(&ip6->ip6_flow); > + tos = flow >> 20; > + break; > + } > +#endif > + default: > + unhandled_af(m->m_pkthdr.ph_family); > + } > + > + prio = IFQ_TOS2PRIO(tos); > + break; > + default: > + prio = txprio; > + break; > + } > + exp = htonl(prio << MPLS_EXP_OFFSET); > + > if (sc->sc_cword) { > m = m_prepend(m, sizeof(shim), M_NOWAIT); > if (m == NULL) > @@ -686,7 +739,7 @@ mpip_start(struct ifnet *ifp) > shim = htonl(1) & MPLS_TTL_MASK; > shim |= htonl(flow << MPLS_LABEL_OFFSET) & > MPLS_LABEL_MASK; > - shim |= bos; > + shim |= exp | bos; > *mtod(m, uint32_t *) = shim; > > bos = 0; > @@ -698,7 +751,7 @@ mpip_start(struct ifnet *ifp) > > shim = htonl(ttl) & MPLS_TTL_MASK; > shim |= n->n_rshim.shim_label; > - shim |= bos; > + shim |= exp | bos; > *mtod(m, uint32_t *) = shim; > > m->m_pkthdr.ph_rtableid = sc->sc_rdomain; > Index: if_mpw.c > =================================================================== > RCS file: /cvs/src/sys/net/if_mpw.c,v > retrieving revision 1.49 > diff -u -p -r1.49 if_mpw.c > --- if_mpw.c 2 Apr 2019 10:50:16 -0000 1.49 > +++ if_mpw.c 14 Apr 2019 06:49:56 -0000 > @@ -53,6 +53,7 @@ struct mpw_softc { > struct arpcom sc_ac; > #define sc_if sc_ac.ac_if > > + int sc_txhprio; > unsigned int sc_rdomain; > struct ifaddr sc_ifa; > struct sockaddr_mpls sc_smpls; /* Local label */ > @@ -117,6 +118,7 @@ mpw_clone_create(struct if_clone *ifc, i > if_attach(ifp); > ether_ifattach(ifp); > > + sc->sc_txhprio = 0; > sc->sc_rdomain = 0; > sc->sc_ifa.ifa_ifp = ifp; > sc->sc_ifa.ifa_addr = sdltosa(ifp->if_sadl); > @@ -465,6 +467,21 @@ mpw_ioctl(struct ifnet *ifp, u_long cmd, > ifr->ifr_rdomainid = sc->sc_rdomain; > break; > > + case SIOCSTXHPRIO: > + if (ifr->ifr_hdrprio == IF_HDRPRIO_PACKET) > + ; > + else if (ifr->ifr_hdrprio > IF_HDRPRIO_MAX || > + ifr->ifr_hdrprio < IF_HDRPRIO_MIN) { > + error = EINVAL; > + break; > + } > + > + sc->sc_txhprio = ifr->ifr_hdrprio; > + break; > + case SIOCGTXHPRIO: > + ifr->ifr_hdrprio = sc->sc_txhprio; > + break; > + > case SIOCADDMULTI: > case SIOCDELMULTI: > break; > @@ -605,7 +622,9 @@ mpw_start(struct ifnet *ifp) > .smpls_len = sizeof(smpls), > .smpls_family = AF_MPLS, > }; > - uint32_t bos; > + int txprio = sc->sc_txhprio; > + uint8_t prio; > + uint32_t exp, bos; > > n = sc->sc_neighbor; > if (!ISSET(ifp->if_flags, IFF_RUNNING) || > @@ -652,6 +671,16 @@ mpw_start(struct ifnet *ifp) > memset(shim, 0, sizeof(*shim)); > } > > + switch (txprio) { > + case IF_HDRPRIO_PACKET: > + prio = m->m_pkthdr.pf.prio; > + break; > + default: > + prio = txprio; > + break; > + } > + exp = htonl(prio << MPLS_EXP_OFFSET); > + > bos = MPLS_BOS_MASK; > if (sc->sc_fword) { > uint32_t flow = sc->sc_flow; > @@ -665,7 +694,7 @@ mpw_start(struct ifnet *ifp) > > shim = mtod(m0, struct shim_hdr *); > shim->shim_label = htonl(1) & MPLS_TTL_MASK; > - shim->shim_label = MPLS_LABEL2SHIM(flow) | bos; > + shim->shim_label = MPLS_LABEL2SHIM(flow) | exp | > bos; > > bos = 0; > } > @@ -676,7 +705,7 @@ mpw_start(struct ifnet *ifp) > > shim = mtod(m0, struct shim_hdr *); > shim->shim_label = htonl(mpls_defttl) & MPLS_TTL_MASK; > - shim->shim_label |= n->n_rshim.shim_label | bos; > + shim->shim_label |= n->n_rshim.shim_label | exp | bos; > > m0->m_pkthdr.ph_rtableid = sc->sc_rdomain; > CLR(m0->m_flags, M_BCAST|M_MCAST); > >