diff options
author | 2018-11-13 00:03:18 +0000 | |
---|---|---|
committer | 2018-11-13 00:03:18 +0000 | |
commit | b1720f85b75013620daefa13a2afaf79bc5d7c17 (patch) | |
tree | 4e8a035ba1b170e065e236d5ace2697871379a70 | |
parent | add txprio setting support (diff) | |
download | wireguard-openbsd-b1720f85b75013620daefa13a2afaf79bc5d7c17.tar.xz wireguard-openbsd-b1720f85b75013620daefa13a2afaf79bc5d7c17.zip |
add txprio support to gre, mgre, egre, nvgre, and eoip
for l3 interfaces (gre and mgre), allow txprio from the payload,
the mbuf, or a hardcoded value. for l2 interfaces (egre, ngre, and
eoip), get txprio from the mbuf or a hardcoded value.
ok claudio@
-rw-r--r-- | sys/net/if_gre.c | 132 |
1 files changed, 127 insertions, 5 deletions
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index 475d94d7b82..2059ee9b705 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_gre.c,v 1.135 2018/11/12 09:39:52 dlg Exp $ */ +/* $OpenBSD: if_gre.c,v 1.136 2018/11/13 00:03:18 dlg Exp $ */ /* $NetBSD: if_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */ /* @@ -191,6 +191,7 @@ struct gre_tunnel { #define t_dst4 t_dst.in4 #define t_dst6 t_dst.in6 int t_ttl; + int t_txhprio; uint16_t t_df; sa_family_t t_af; }; @@ -230,6 +231,13 @@ static int static int gre_tunnel_ioctl(struct ifnet *, struct gre_tunnel *, u_long, void *); +static int gre_l2_txhprio(struct gre_tunnel *, int); +static int gre_l3_txhprio(struct gre_tunnel *, int); + +static uint8_t gre_l2_tos(const struct gre_tunnel *, const struct mbuf *); +static uint8_t gre_l3_tos(const struct gre_tunnel *, + const struct mbuf *, uint8_t); + /* * layer 3 GRE tunnels */ @@ -576,6 +584,7 @@ gre_clone_create(struct if_clone *ifc, int unit) ifp->if_rtrequest = p2p_rtrequest; sc->sc_tunnel.t_ttl = ip_defttl; + sc->sc_tunnel.t_txhprio = IF_HDRPRIO_PAYLOAD; sc->sc_tunnel.t_df = htons(0); timeout_set(&sc->sc_ka_send, gre_keepalive_send, sc); @@ -641,6 +650,7 @@ mgre_clone_create(struct if_clone *ifc, int unit) ifp->if_ioctl = mgre_ioctl; sc->sc_tunnel.t_ttl = ip_defttl; + sc->sc_tunnel.t_txhprio = IF_HDRPRIO_PAYLOAD; sc->sc_tunnel.t_df = htons(0); if_attach(ifp); @@ -692,6 +702,7 @@ egre_clone_create(struct if_clone *ifc, int unit) ether_fakeaddr(ifp); sc->sc_tunnel.t_ttl = ip_defttl; + sc->sc_tunnel.t_txhprio = 0; sc->sc_tunnel.t_df = htons(0); ifmedia_init(&sc->sc_media, 0, egre_media_change, egre_media_status); @@ -752,6 +763,7 @@ nvgre_clone_create(struct if_clone *ifc, int unit) tunnel = &sc->sc_tunnel; tunnel->t_ttl = IP_DEFAULT_MULTICAST_TTL; + tunnel->t_txhprio = 0; tunnel->t_df = htons(IP_DF); tunnel->t_key_mask = GRE_KEY_ENTROPY; tunnel->t_key = htonl((NVGRE_VSID_RES_MAX + 1) << @@ -818,6 +830,7 @@ eoip_clone_create(struct if_clone *ifc, int unit) ether_fakeaddr(ifp); sc->sc_tunnel.t_ttl = ip_defttl; + sc->sc_tunnel.t_txhprio = 0; sc->sc_tunnel.t_df = htons(0); sc->sc_ka_timeo = 10; @@ -1823,7 +1836,7 @@ mgre_start(struct ifnet *ifp) } #endif - if (m == NULL || gre_ip_output(&sc->sc_tunnel, m) != 0) { + if (gre_ip_output(&sc->sc_tunnel, m) != 0) { ifp->if_oerrors++; continue; } @@ -1864,7 +1877,7 @@ egre_start(struct ifnet *ifp) m->m_len = 0; m = gre_encap(&sc->sc_tunnel, m, htons(ETHERTYPE_TRANSETHER), - sc->sc_tunnel.t_ttl, 0); + sc->sc_tunnel.t_ttl, gre_l2_tos(&sc->sc_tunnel, m)); if (m == NULL || gre_ip_output(&sc->sc_tunnel, m) != 0) { ifp->if_oerrors++; continue; @@ -1943,6 +1956,8 @@ gre_l3_encap_dst(const struct gre_tunnel *tunnel, const void *dst, } else ttl = tttl; + tos = gre_l3_tos(tunnel, m, tos); + return (gre_encap_dst(tunnel, dst, m, proto, ttl, tos)); } @@ -2144,6 +2159,77 @@ gre_tunnel_ioctl(struct ifnet *ifp, struct gre_tunnel *tunnel, } static int +gre_l2_txhprio(struct gre_tunnel *t, int hdrprio) +{ + switch (hdrprio) { + case IF_HDRPRIO_PACKET: + break; + default: + if (hdrprio < IF_HDRPRIO_MIN || hdrprio > IF_HDRPRIO_MAX) + return (EINVAL); + break; + } + + t->t_txhprio = hdrprio; + + return (0); +} + +static int +gre_l3_txhprio(struct gre_tunnel *t, int hdrprio) +{ + switch (hdrprio) { + case IF_HDRPRIO_PACKET: + case IF_HDRPRIO_PAYLOAD: + break; + default: + if (hdrprio < IF_HDRPRIO_MIN || hdrprio > IF_HDRPRIO_MAX) + return (EINVAL); + break; + } + + t->t_txhprio = hdrprio; + + return (0); +} + +static uint8_t +gre_l2_tos(const struct gre_tunnel *t, const struct mbuf *m) +{ + uint8_t prio; + + switch (t->t_txhprio) { + case IF_HDRPRIO_PACKET: + prio = m->m_pkthdr.pf.prio; + break; + default: + prio = t->t_txhprio; + break; + } + + return (IFQ_PRIO2TOS(prio)); +} + +static uint8_t +gre_l3_tos(const struct gre_tunnel *t, const struct mbuf *m, uint8_t ttl) +{ + uint8_t prio; + + switch (t->t_txhprio) { + case IF_HDRPRIO_PAYLOAD: + return (ttl); + case IF_HDRPRIO_PACKET: + prio = m->m_pkthdr.pf.prio; + break; + default: + prio = t->t_txhprio; + break; + } + + return (IFQ_PRIO2TOS(prio)); +} + +static int gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct gre_softc *sc = ifp->if_softc; @@ -2217,6 +2303,13 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ifr->ifr_ttl = sc->sc_tunnel.t_ttl; break; + case SIOCSTXHPRIO: + error = gre_l3_txhprio(&sc->sc_tunnel, ifr->ifr_hdrprio); + break; + case SIOCGTXHPRIO: + ifr->ifr_hdrprio = sc->sc_tunnel.t_txhprio; + break; + default: error = gre_tunnel_ioctl(ifp, &sc->sc_tunnel, cmd, data); break; @@ -2273,6 +2366,13 @@ mgre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) error = mgre_get_tunnel(sc, (struct if_laddrreq *)data); break; + case SIOCSTXHPRIO: + error = gre_l3_txhprio(&sc->sc_tunnel, ifr->ifr_hdrprio); + break; + case SIOCGTXHPRIO: + ifr->ifr_hdrprio = sc->sc_tunnel.t_txhprio; + break; + case SIOCSVNETID: case SIOCDVNETID: case SIOCDIFPHYADDR: @@ -2425,6 +2525,13 @@ egre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ifr->ifr_ttl = (int)sc->sc_tunnel.t_ttl; break; + case SIOCSTXHPRIO: + error = gre_l2_txhprio(&sc->sc_tunnel, ifr->ifr_hdrprio); + break; + case SIOCGTXHPRIO: + ifr->ifr_hdrprio = sc->sc_tunnel.t_txhprio; + break; + case SIOCSVNETID: case SIOCDVNETID: case SIOCSVNETFLOWID: @@ -2581,6 +2688,13 @@ nvgre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ifr->ifr_ttl = tunnel->t_ttl; break; + case SIOCSTXHPRIO: + error = gre_l2_txhprio(&sc->sc_tunnel, ifr->ifr_hdrprio); + break; + case SIOCGTXHPRIO: + ifr->ifr_hdrprio = sc->sc_tunnel.t_txhprio; + break; + case SIOCBRDGSCACHE: if (bparam->ifbrp_csize < 1) { error = EINVAL; @@ -2752,6 +2866,13 @@ eoip_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ifr->ifr_df = sc->sc_tunnel.t_df ? 1 : 0; break; + case SIOCSTXHPRIO: + error = gre_l2_txhprio(&sc->sc_tunnel, ifr->ifr_hdrprio); + break; + case SIOCGTXHPRIO: + ifr->ifr_hdrprio = sc->sc_tunnel.t_txhprio; + break; + default: error = ether_ioctl(ifp, &sc->sc_ac, cmd, data); break; @@ -3557,7 +3678,8 @@ nvgre_start(struct ifnet *ifp) m->m_len = 0; m = gre_encap_dst(tunnel, &gateway, m, - htons(ETHERTYPE_TRANSETHER), tunnel->t_ttl, 0); + htons(ETHERTYPE_TRANSETHER), + tunnel->t_ttl, gre_l2_tos(tunnel, m)); if (m == NULL) continue; @@ -3730,7 +3852,7 @@ eoip_start(struct ifnet *ifp) MH_ALIGN(m, 0); m->m_len = 0; - m = eoip_encap(sc, m, 0); + m = eoip_encap(sc, m, gre_l2_tos(&sc->sc_tunnel, m)); if (m == NULL || gre_ip_output(&sc->sc_tunnel, m) != 0) { ifp->if_oerrors++; continue; |