Index: sbin/ifconfig/ifconfig.c =================================================================== RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v retrieving revision 1.380 diff -u -p -r1.380 ifconfig.c --- sbin/ifconfig/ifconfig.c 15 Oct 2018 11:25:55 -0000 1.380 +++ sbin/ifconfig/ifconfig.c 11 Nov 2018 12:54:58 -0000 @@ -136,6 +136,9 @@ struct ifencap { #define IFE_PARENT_NONE 0x100 #define IFE_PARENT_SET 0x200 char ife_parent[IFNAMSIZ]; + +#define IFE_TXHPRIO_SET 0x1000 + int ife_txhprio; }; struct ifreq ifr, ridreq; @@ -288,6 +291,8 @@ void pfsync_status(void); void setvnetflowid(const char *, int); void delvnetflowid(const char *, int); void getvnetflowid(struct ifencap *); +void gettxprio(struct ifencap *); +void settxprio(const char *, int); void settunneldf(const char *, int); void settunnelnodf(const char *, int); void setpppoe_dev(const char *,int); @@ -486,6 +491,7 @@ const struct cmd { { "-tunneldf", 0, 0, settunnelnodf }, { "vnetflowid", 0, 0, setvnetflowid }, { "-vnetflowid", 0, 0, delvnetflowid }, + { "txprio", NEXTARG, 0, settxprio }, { "pppoedev", NEXTARG, 0, setpppoe_dev }, { "pppoesvc", NEXTARG, 0, setpppoe_svc }, { "-pppoesvc", 1, 0, setpppoe_svc }, @@ -3982,6 +3988,46 @@ getifparent(struct ifencap *ife) } } +#ifndef SMALL +void +gettxprio(struct ifencap *ife) +{ + if (strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)) >= + sizeof(ifr.ifr_name)) + errx(1, "hdr prio: name is too long"); + + if (ioctl(s, SIOCGTXHPRIO, (caddr_t)&ifr) == -1) + return; + + ife->ife_flags |= IFE_TXHPRIO_SET; + ife->ife_txhprio = ifr.ifr_hdrprio; +} + +void +settxprio(const char *val, int d) +{ + const char *errmsg = NULL; + + if (strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)) >= + sizeof(ifr.ifr_name)) + errx(1, "tx prio: name is too long"); + + if (strcmp(val, "packet") == 0) + ifr.ifr_hdrprio = IF_HDRPRIO_PACKET; + else if (strcmp(val, "payload") == 0) + ifr.ifr_hdrprio = IF_HDRPRIO_PAYLOAD; + else { + ifr.ifr_hdrprio = strtonum(val, + IF_HDRPRIO_MIN, IF_HDRPRIO_MAX, &errmsg); + if (errmsg) + errx(1, "tx prio %s: %s", val, errmsg); + } + + if (ioctl(s, SIOCSTXHPRIO, (caddr_t)&ifr) < 0) + warn("SIOCSTXHPRIO"); +} +#endif + void getencap(void) { @@ -3990,6 +4036,9 @@ getencap(void) getvnetid(&ife); getvnetflowid(&ife); getifparent(&ife); +#ifndef SMALL + gettxprio(&ife); +#endif if (ife.ife_flags == 0) return; @@ -4018,6 +4067,22 @@ getencap(void) printf(" parent %s", ife.ife_parent); break; } + +#ifndef SMALL + if (ife.ife_flags & IFE_TXHPRIO_SET) { + switch (ife.ife_txhprio) { + case IF_HDRPRIO_PACKET: + printf(" txprio packet"); + break; + case IF_HDRPRIO_PAYLOAD: + printf(" txprio payload"); + break; + default: + printf(" txprio %d", ife.ife_txhprio); + break; + } + } +#endif printf("\n"); } Index: sys/net/if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.566 diff -u -p -r1.566 if.c --- sys/net/if.c 1 Oct 2018 12:38:32 -0000 1.566 +++ sys/net/if.c 11 Nov 2018 12:54:58 -0000 @@ -2136,6 +2136,7 @@ ifioctl(struct socket *so, u_long cmd, c case SIOCSIFMEDIA: case SIOCSVNETID: case SIOCSVNETFLOWID: + case SIOCSTXHPRIO: case SIOCSIFPAIR: case SIOCSIFPARENT: case SIOCDIFPARENT: Index: sys/net/if.h =================================================================== RCS file: /cvs/src/sys/net/if.h,v retrieving revision 1.196 diff -u -p -r1.196 if.h --- sys/net/if.h 11 Nov 2018 05:55:10 -0000 1.196 +++ sys/net/if.h 11 Nov 2018 12:54:59 -0000 @@ -398,7 +398,13 @@ struct ifreq { #define ifr_data ifr_ifru.ifru_data /* for use by interface */ #define ifr_index ifr_ifru.ifru_index /* interface index */ #define ifr_llprio ifr_ifru.ifru_metric /* link layer priority */ +#define ifr_hdrprio ifr_ifru.ifru_metric /* header prio field config */ }; + +#define IF_HDRPRIO_MIN IFQ_MINPRIO +#define IF_HDRPRIO_MAX IFQ_MAXPRIO +#define IF_HDRPRIO_PACKET -1 /* use mbuf prio */ +#define IF_HDRPRIO_PAYLOAD -2 /* copy payload prio */ struct ifaliasreq { char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */ Index: sys/net/if_etherip.c =================================================================== RCS file: /cvs/src/sys/net/if_etherip.c,v retrieving revision 1.38 diff -u -p -r1.38 if_etherip.c --- sys/net/if_etherip.c 29 Oct 2018 09:51:20 -0000 1.38 +++ sys/net/if_etherip.c 11 Nov 2018 12:54:59 -0000 @@ -85,6 +85,7 @@ struct etherip_softc { struct etherip_tunnel sc_tunnel; /* must be first */ struct arpcom sc_ac; struct ifmedia sc_media; + int sc_txhprio; uint16_t sc_df; uint8_t sc_ttl; }; @@ -137,6 +138,7 @@ etherip_clone_create(struct if_clone *if ifc->ifc_name, unit); sc->sc_ttl = ip_defttl; + sc->sc_txhprio = IFQ_TOS2PRIO(IPTOS_PREC_ROUTINE); /* 0 */ sc->sc_df = htons(0); ifp->if_softc = sc; @@ -282,6 +284,21 @@ etherip_ioctl(struct ifnet *ifp, u_long error = etherip_del_tunnel(sc); break; + case SIOCSTXHPRIO: + if (ifr->ifr_hdrprio == IF_HDRPRIO_PACKET) /* use mbuf prio */ + ; + else if (ifr->ifr_hdrprio < IF_HDRPRIO_MIN || + ifr->ifr_hdrprio > IF_HDRPRIO_MAX) { + error = EINVAL; + break; + } + + sc->sc_txhprio = ifr->ifr_hdrprio; + break; + case SIOCGTXHPRIO: + ifr->ifr_hdrprio = sc->sc_txhprio; + break; + case SIOCSLIFPHYTTL: if (ifr->ifr_ttl < 1 || ifr->ifr_ttl > 0xff) { error = EINVAL; @@ -486,7 +503,8 @@ ip_etherip_output(struct ifnet *ifp, str ip->ip_v = IPVERSION; ip->ip_hl = sizeof(*ip) >> 2; - ip->ip_tos = IPTOS_LOWDELAY; + ip->ip_tos = IFQ_PRIO2TOS(sc->sc_txhprio == IF_HDRPRIO_PACKET ? + m->m_pkthdr.pf.prio : sc->sc_txhprio); ip->ip_len = htons(m->m_pkthdr.len); ip->ip_id = htons(ip_randomid()); ip->ip_off = sc->sc_df; @@ -622,6 +640,7 @@ ip6_etherip_output(struct ifnet *ifp, st struct ip6_hdr *ip6; struct etherip_header *eip; uint16_t len; + uint32_t flow; if (IN6_IS_ADDR_UNSPECIFIED(&sc->sc_tunnel.t_dst6)) { m_freem(m); @@ -636,10 +655,12 @@ ip6_etherip_output(struct ifnet *ifp, st return ENOBUFS; } + flow = IPV6_VERSION << 28; + flow |= IFQ_PRIO2TOS(sc->sc_txhprio == IF_HDRPRIO_PACKET ? + m->m_pkthdr.pf.prio : sc->sc_txhprio) << 20; + ip6 = mtod(m, struct ip6_hdr *); - ip6->ip6_flow = 0; - ip6->ip6_vfc &= ~IPV6_VERSION_MASK; - ip6->ip6_vfc |= IPV6_VERSION; + htobem32(&ip6->ip6_flow, flow); ip6->ip6_nxt = IPPROTO_ETHERIP; ip6->ip6_hlim = sc->sc_ttl; ip6->ip6_plen = htons(len); Index: sys/net/if_gif.c =================================================================== RCS file: /cvs/src/sys/net/if_gif.c,v retrieving revision 1.117 diff -u -p -r1.117 if_gif.c --- sys/net/if_gif.c 11 Nov 2018 12:47:04 -0000 1.117 +++ sys/net/if_gif.c 11 Nov 2018 12:54:59 -0000 @@ -1,4 +1,4 @@ -/* $OpenBSD: if_gif.c,v 1.117 2018/11/11 12:47:04 dlg Exp $ */ +/* $OpenBSD: if_gif.c,v 1.116 2018/04/18 13:24:07 bluhm Exp $ */ /* $KAME: if_gif.c,v 1.43 2001/02/20 08:51:07 itojun Exp $ */ /* @@ -106,6 +106,7 @@ struct gif_softc { struct ifnet sc_if; uint16_t sc_df; int sc_ttl; + int sc_txhprio; }; struct gif_list gif_list = TAILQ_HEAD_INITIALIZER(gif_list); @@ -153,6 +154,7 @@ gif_clone_create(struct if_clone *ifc, i sc->sc_df = htons(0); sc->sc_ttl = ip_defttl; + sc->sc_txhprio = IF_HDRPRIO_PAYLOAD; snprintf(ifp->if_xname, sizeof(ifp->if_xname), "%s%d", ifc->ifc_name, unit); @@ -266,7 +268,6 @@ gif_start(struct ifnet *ifp) tos = (shim >> MPLS_EXP_OFFSET) << 5; ttloff = 3; - proto = IPPROTO_MPLS; break; } @@ -282,6 +283,18 @@ gif_start(struct ifnet *ifp) } else ttl = tttl; + switch (sc->sc_txhprio) { + case IF_HDRPRIO_PAYLOAD: + /* tos is already set */ + break; + case IF_HDRPRIO_PACKET: + tos = IFQ_PRIO2TOS(m->m_pkthdr.pf.prio); + break; + default: + tos = IFQ_PRIO2TOS(sc->sc_txhprio); + break; + } + gif_send(sc, m, proto, ttl, tos); } } @@ -527,6 +540,22 @@ gif_ioctl(struct ifnet *ifp, u_long cmd, break; case SIOCGLIFPHYDF: ifr->ifr_df = sc->sc_df ? 1 : 0; + break; + + case SIOCSTXHPRIO: + if (ifr->ifr_hdrprio == IF_HDRPRIO_PAYLOAD || + ifr->ifr_hdrprio == IF_HDRPRIO_PACKET) + ; /* ok, fall through */ + else if (ifr->ifr_hdrprio < IF_HDRPRIO_MIN || + ifr->ifr_hdrprio > IF_HDRPRIO_MAX) { + error = EINVAL; + break; + } + + sc->sc_txhprio = ifr->ifr_hdrprio; + break; + case SIOCGTXHPRIO: + ifr->ifr_hdrprio = sc->sc_txhprio; break; default: Index: sys/net/if_gre.c =================================================================== RCS file: /cvs/src/sys/net/if_gre.c,v retrieving revision 1.134 diff -u -p -r1.134 if_gre.c --- sys/net/if_gre.c 11 Nov 2018 06:35:41 -0000 1.134 +++ sys/net/if_gre.c 11 Nov 2018 12:54:59 -0000 @@ -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, i 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, 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, 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, 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) << @@ -817,6 +829,7 @@ eoip_clone_create(struct if_clone *ifc, 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; @@ -1822,7 +1835,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; } @@ -1863,7 +1876,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; @@ -1942,6 +1955,8 @@ gre_l3_encap_dst(const struct gre_tunnel } else ttl = tttl; + tos = gre_l3_tos(tunnel, m, tos); + return (gre_encap_dst(tunnel, dst, m, proto, ttl, tos)); } @@ -2143,6 +2158,77 @@ gre_tunnel_ioctl(struct ifnet *ifp, stru } 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; @@ -2216,6 +2302,13 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, 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; @@ -2272,6 +2365,13 @@ mgre_ioctl(struct ifnet *ifp, u_long cmd 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: @@ -2424,6 +2524,13 @@ egre_ioctl(struct ifnet *ifp, u_long cmd 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: @@ -2580,6 +2687,13 @@ nvgre_ioctl(struct ifnet *ifp, u_long cm 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; @@ -2751,6 +2865,13 @@ eoip_ioctl(struct ifnet *ifp, u_long cmd 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; @@ -3556,7 +3677,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; @@ -3729,7 +3851,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; Index: sys/net/if_vlan.c =================================================================== RCS file: /cvs/src/sys/net/if_vlan.c,v retrieving revision 1.178 diff -u -p -r1.178 if_vlan.c --- sys/net/if_vlan.c 11 Jul 2018 14:20:18 -0000 1.178 +++ sys/net/if_vlan.c 11 Nov 2018 12:54:59 -0000 @@ -173,6 +173,7 @@ vlan_clone_create(struct if_clone *ifc, ifv->ifv_type = ETHERTYPE_VLAN; refcnt_init(&ifv->ifv_refcnt); + ifv->ifv_prio = IF_HDRPRIO_PACKET; ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST; ifp->if_xflags = IFXF_CLONED|IFXF_MPSAFE; @@ -261,8 +262,8 @@ vlan_start(struct ifqueue *ifq) bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT); #endif /* NBPFILTER > 0 */ - prio = ISSET(ifp->if_flags, IFF_LINK0) ? - ifp->if_llprio : m->m_pkthdr.pf.prio; + prio = ifv->ifv_prio == IF_HDRPRIO_PACKET ? + m->m_pkthdr.pf.prio : ifv->ifv_prio; /* IEEE 802.1p has prio 0 and 1 swapped */ if (prio <= 1) @@ -712,6 +713,21 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd break; case SIOCGETVLAN: error = vlan_get_compat(ifp, ifr); + 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; + } + + ifv->ifv_prio = ifr->ifr_hdrprio; + break; + case SIOCGTXHPRIO: + ifr->ifr_hdrprio = ifv->ifv_prio; break; default: Index: sys/net/if_vlan_var.h =================================================================== RCS file: /cvs/src/sys/net/if_vlan_var.h,v retrieving revision 1.37 diff -u -p -r1.37 if_vlan_var.h --- sys/net/if_vlan_var.h 24 Jan 2017 10:08:30 -0000 1.37 +++ sys/net/if_vlan_var.h 11 Nov 2018 12:54:59 -0000 @@ -63,9 +63,9 @@ struct ifvlan { struct arpcom ifv_ac; /* make this an interface */ unsigned int ifv_ifp0; /* parent interface of this vlan */ struct ifv_linkmib { + int ifvm_prio; /* prio to apply on packet leaving if */ u_int16_t ifvm_proto; /* encapsulation ethertype */ u_int16_t ifvm_tag; /* tag to apply on packets leaving if */ - u_int16_t ifvm_prio; /* prio to apply on packet leaving if */ u_int16_t ifvm_type; /* non-standard ethertype or 0x8100 */ } ifv_mib; LIST_HEAD(__vlan_mchead, vlan_mc_entry) vlan_mc_listhead; Index: sys/net/if_vxlan.c =================================================================== RCS file: /cvs/src/sys/net/if_vxlan.c,v retrieving revision 1.68 diff -u -p -r1.68 if_vxlan.c --- sys/net/if_vxlan.c 17 Aug 2018 01:53:31 -0000 1.68 +++ sys/net/if_vxlan.c 11 Nov 2018 12:54:59 -0000 @@ -73,6 +73,7 @@ struct vxlan_softc { int64_t sc_vnetid; uint16_t sc_df; u_int8_t sc_ttl; + int sc_txhprio; struct task sc_sendtask; @@ -136,6 +137,7 @@ vxlan_clone_create(struct if_clone *ifc, sc->sc_imo.imo_max_memberships = IP_MIN_MEMBERSHIPS; sc->sc_dstport = htons(VXLAN_PORT); sc->sc_vnetid = VXLAN_VNI_UNSET; + sc->sc_txhprio = IFQ_TOS2PRIO(IPTOS_PREC_ROUTINE); /* 0 */ sc->sc_df = htons(0); task_set(&sc->sc_sendtask, vxlan_send_dispatch, sc); @@ -506,6 +508,21 @@ vxlanioctl(struct ifnet *ifp, u_long cmd ifr->ifr_df = sc->sc_df ? 1 : 0; break; + case SIOCSTXHPRIO: + if (ifr->ifr_hdrprio == IF_HDRPRIO_PACKET) + ; /* fall through */ + else if (ifr->ifr_hdrprio < IF_HDRPRIO_MIN || + ifr->ifr_hdrprio > IF_HDRPRIO_MAX) { + error = EINVAL; + break; + } + + sc->sc_txhprio = ifr->ifr_hdrprio; + break; + case SIOCGTXHPRIO: + ifr->ifr_hdrprio = sc->sc_txhprio; + break; + case SIOCSVNETID: if (sc->sc_vnetid == ifr->ifr_vnetid) break; @@ -756,7 +773,8 @@ vxlan_encap4(struct ifnet *ifp, struct m ip->ip_id = htons(ip_randomid()); ip->ip_off = sc->sc_df; ip->ip_p = IPPROTO_UDP; - ip->ip_tos = IPTOS_LOWDELAY; + ip->ip_tos = IFQ_PRIO2TOS(sc->sc_txhprio == IF_HDRPRIO_PACKET ? + m->m_pkthdr.pf.prio : sc->sc_txhprio); ip->ip_len = htons(m->m_pkthdr.len); ip->ip_src = satosin(src)->sin_addr; @@ -778,6 +796,7 @@ vxlan_encap6(struct ifnet *ifp, struct m struct vxlan_softc *sc = (struct vxlan_softc *)ifp->if_softc; struct ip6_hdr *ip6; struct in6_addr *in6a; + uint32_t flow; /* * Remove multicast and broadcast flags or encapsulated packet @@ -789,8 +808,11 @@ vxlan_encap6(struct ifnet *ifp, struct m if (m == NULL) return (NULL); + flow = (uint32_t)IFQ_PRIO2TOS(sc->sc_txhprio == IF_HDRPRIO_PACKET ? + m->m_pkthdr.pf.prio : sc->sc_txhprio) << 20; + ip6 = mtod(m, struct ip6_hdr *); - ip6->ip6_flow = 0; + ip6->ip6_flow = htonl(flow); ip6->ip6_vfc &= ~IPV6_VERSION_MASK; ip6->ip6_vfc |= IPV6_VERSION; ip6->ip6_nxt = IPPROTO_UDP; Index: sys/sys/sockio.h =================================================================== RCS file: /cvs/src/sys/sys/sockio.h,v retrieving revision 1.76 diff -u -p -r1.76 sockio.h --- sys/sys/sockio.h 30 May 2018 18:15:47 -0000 1.76 +++ sys/sys/sockio.h 11 Nov 2018 12:54:59 -0000 @@ -198,6 +198,9 @@ #define SIOCSVNETFLOWID _IOW('i', 195, struct ifreq) /* set vnet flowid */ #define SIOCGVNETFLOWID _IOWR('i', 196, struct ifreq) /* get vnet flowid */ +#define SIOCSTXHPRIO _IOW('i', 197, struct ifreq) /* set tx hdr prio */ +#define SIOCGTXHPRIO _IOWR('i', 198, struct ifreq) /* get tx hdr prio */ + #define SIOCSVH _IOWR('i', 245, struct ifreq) /* set carp param */ #define SIOCGVH _IOWR('i', 246, struct ifreq) /* get carp param */