summaryrefslogtreecommitdiffstats
path: root/sys/net/if_mpe.c
diff options
context:
space:
mode:
authordlg <dlg@openbsd.org>2019-04-17 00:45:03 +0000
committerdlg <dlg@openbsd.org>2019-04-17 00:45:03 +0000
commitf1dea89cff4dce489e6e77ee8bc05aa595d781b9 (patch)
treed99668266cd2e004460cd60e2c9db6a847592750 /sys/net/if_mpe.c
parentdocument where multiline {} is applicable; (diff)
downloadwireguard-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.c52
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);
}