diff options
author | 2019-04-17 00:45:03 +0000 | |
---|---|---|
committer | 2019-04-17 00:45:03 +0000 | |
commit | f1dea89cff4dce489e6e77ee8bc05aa595d781b9 (patch) | |
tree | d99668266cd2e004460cd60e2c9db6a847592750 /sys/net/if_mpe.c | |
parent | document where multiline {} is applicable; (diff) | |
download | wireguard-openbsd-f1dea89cff4dce489e6e77ee8bc05aa595d781b9.tar.xz wireguard-openbsd-f1dea89cff4dce489e6e77ee8bc05aa595d781b9.zip |
use txprio to control the use of exp as a priority field
by default txprio is set to 0, so the exp field will be 0. howerver,
txprio on mpe/mpw/mpip can be configured with other values or
settings like our other tunnel or encapsulation interfaces.
intermediate LSPs can use the exp field to manage their prioritisation
of encapsulated traffic.
Diffstat (limited to 'sys/net/if_mpe.c')
-rw-r--r-- | sys/net/if_mpe.c | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/sys/net/if_mpe.c b/sys/net/if_mpe.c index f6fe6f01087..5fbf1fbf7a4 100644 --- a/sys/net/if_mpe.c +++ b/sys/net/if_mpe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mpe.c,v 1.90 2019/04/02 10:52:33 dlg Exp $ */ +/* $OpenBSD: if_mpe.c,v 1.91 2019/04/17 00:45:03 dlg Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@spootnik.org> @@ -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, int unit) 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 mbuf *m, struct sockaddr *dst, 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 mbuf *m, struct sockaddr *dst, 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) { @@ -389,6 +417,22 @@ mpe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 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: return (ENOTTY); } |