On Sun, Apr 14, 2019 at 05:33:07PM +1000, David Gwynne wrote: > ive been working on RFC 2983 support, with extended functionality. > > rfc 2983 is "Differentiated Services and Tunnels", and discusses where > prio values should go and come from on tunnel ingress and egress. we > currentl support setting the packet on tunnel ingress using the txprio > functionliaty. this diff adds egress or rxprio handling. > > the rfc talks about selecting the outer or inner dscp value on ip > tunnels. this diff adds this support, and allows config to ignore both > the inner and outer prio fields, or hardcode it to a specific value like > we do on tx. it also extends on the rfc by allowing the config to > apply to other encapsulations, eg, vlan, bpe, and the mpls tunnels can > support this too. > > the diff below shows the vlan and gif diffs. i have changes for other > interfaces in a tree somewhere, but i'm happy to commit those on my own > if everyone's ok with the diff below. > > ok?
This is missing a manpage diff for ifconfig.8 apart from that I'm OK with it. > Index: sys/sys/sockio.h > =================================================================== > RCS file: /cvs/src/sys/sys/sockio.h,v > retrieving revision 1.81 > diff -u -p -r1.81 sockio.h > --- sys/sys/sockio.h 10 Apr 2019 09:49:50 -0000 1.81 > +++ sys/sys/sockio.h 14 Apr 2019 07:14:01 -0000 > @@ -207,6 +207,9 @@ > #define SIOCSLIFPHYECN _IOW('i', 199, struct ifreq) /* set ecn > copying */ > #define SIOCGLIFPHYECN _IOWR('i', 200, struct ifreq) /* get ecn > copying */ > > +#define SIOCSRXHPRIO _IOW('i', 219, struct ifreq) /* set rx hdr > prio */ > +#define SIOCGRXHPRIO _IOWR('i', 219, struct ifreq) /* get rx hdr > prio */ > + > #define SIOCSPWE3CTRLWORD _IOW('i', 220, struct ifreq) > #define SIOCGPWE3CTRLWORD _IOWR('i', 220, struct ifreq) > #define SIOCSPWE3FAT _IOW('i', 221, struct ifreq) > Index: sys/net/if.c > =================================================================== > RCS file: /cvs/src/sys/net/if.c,v > retrieving revision 1.575 > diff -u -p -r1.575 if.c > --- sys/net/if.c 14 Apr 2019 06:57:00 -0000 1.575 > +++ sys/net/if.c 14 Apr 2019 07:14:01 -0000 > @@ -2168,6 +2168,7 @@ ifioctl(struct socket *so, u_long cmd, c > case SIOCSVNETID: > case SIOCSVNETFLOWID: > case SIOCSTXHPRIO: > + case SIOCSRXHPRIO: > case SIOCSIFPAIR: > case SIOCSIFPARENT: > case SIOCDIFPARENT: > Index: sys/net/if.h > =================================================================== > RCS file: /cvs/src/sys/net/if.h,v > retrieving revision 1.200 > diff -u -p -r1.200 if.h > --- sys/net/if.h 10 Apr 2019 09:49:22 -0000 1.200 > +++ sys/net/if.h 14 Apr 2019 07:14:02 -0000 > @@ -427,6 +427,7 @@ struct ifreq { > #define IF_HDRPRIO_MAX IFQ_MAXPRIO > #define IF_HDRPRIO_PACKET -1 /* use mbuf prio */ > #define IF_HDRPRIO_PAYLOAD -2 /* copy payload prio */ > +#define IF_HDRPRIO_OUTER -3 /* use outer prio */ > > #define IF_PWE3_ETHERNET 1 /* ethernet or ethernet tagged */ > #define IF_PWE3_IP 2 /* IP layer 2 */ > Index: sys/net/if_vlan.c > =================================================================== > RCS file: /cvs/src/sys/net/if_vlan.c,v > retrieving revision 1.183 > diff -u -p -r1.183 if_vlan.c > --- sys/net/if_vlan.c 15 Feb 2019 13:00:51 -0000 1.183 > +++ sys/net/if_vlan.c 14 Apr 2019 07:14:02 -0000 > @@ -174,6 +174,7 @@ vlan_clone_create(struct if_clone *ifc, > > refcnt_init(&ifv->ifv_refcnt); > ifv->ifv_prio = IF_HDRPRIO_PACKET; > + ifv->ifv_rxprio = IF_HDRPRIO_OUTER; > > ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST; > ifp->if_xflags = IFXF_CLONED|IFXF_MPSAFE; > @@ -373,11 +374,6 @@ vlan_input(struct ifnet *ifp0, struct mb > > /* From now on ether_vtag is fine */ > tag = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag); > - m->m_pkthdr.pf.prio = EVL_PRIOFTAG(m->m_pkthdr.ether_vtag); > - > - /* IEEE 802.1p has prio 0 and 1 swapped */ > - if (m->m_pkthdr.pf.prio <= 1) > - m->m_pkthdr.pf.prio = !m->m_pkthdr.pf.prio; > > list = &tagh[TAG_HASH(tag)]; > SRPL_FOREACH(ifv, &sr, list, ifv_list) { > @@ -408,6 +404,20 @@ vlan_input(struct ifnet *ifp0, struct mb > m_adj(m, EVL_ENCAPLEN); > } > > + switch (ifv->ifv_rxprio) { > + case IF_HDRPRIO_PACKET: > + break; > + case IF_HDRPRIO_OUTER: > + m->m_pkthdr.pf.prio = EVL_PRIOFTAG(m->m_pkthdr.ether_vtag); > + break; > + default: > + m->m_pkthdr.pf.prio = ifv->ifv_rxprio; > + /* IEEE 802.1p has prio 0 and 1 swapped */ > + if (m->m_pkthdr.pf.prio <= 1) > + m->m_pkthdr.pf.prio = !m->m_pkthdr.pf.prio; > + break; > + } > + > ml_enqueue(&ml, m); > if_input(&ifv->ifv_if, &ml); > SRPL_LEAVE(&sr); > @@ -736,6 +746,22 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd > break; > case SIOCGTXHPRIO: > ifr->ifr_hdrprio = ifv->ifv_prio; > + break; > + > + case SIOCSRXHPRIO: > + if (ifr->ifr_hdrprio == IF_HDRPRIO_PACKET || > + ifr->ifr_hdrprio == IF_HDRPRIO_OUTER) > + ; > + else if (ifr->ifr_hdrprio > IF_HDRPRIO_MAX || > + ifr->ifr_hdrprio < IF_HDRPRIO_MIN) { > + error = EINVAL; > + break; > + } > + > + ifv->ifv_rxprio = ifr->ifr_hdrprio; > + break; > + case SIOCGRXHPRIO: > + ifr->ifr_hdrprio = ifv->ifv_rxprio; > break; > > default: > Index: sys/net/if_vlan_var.h > =================================================================== > RCS file: /cvs/src/sys/net/if_vlan_var.h,v > retrieving revision 1.39 > diff -u -p -r1.39 if_vlan_var.h > --- sys/net/if_vlan_var.h 15 Feb 2019 13:00:51 -0000 1.39 > +++ sys/net/if_vlan_var.h 14 Apr 2019 07:14:02 -0000 > @@ -62,6 +62,7 @@ struct vlan_mc_entry { > struct ifvlan { > struct arpcom ifv_ac; /* make this an interface */ > unsigned int ifv_ifidx0; /* parent interface of this vlan */ > + int ifv_rxprio; > struct ifv_linkmib { > int ifvm_prio; /* prio to apply on packet leaving if */ > u_int16_t ifvm_proto; /* encapsulation ethertype */ > Index: sys/net/if_gif.c > =================================================================== > RCS file: /cvs/src/sys/net/if_gif.c,v > retrieving revision 1.125 > diff -u -p -r1.125 if_gif.c > --- sys/net/if_gif.c 29 Nov 2018 00:14:29 -0000 1.125 > +++ sys/net/if_gif.c 14 Apr 2019 07:14:02 -0000 > @@ -107,6 +107,7 @@ struct gif_softc { > uint16_t sc_df; > int sc_ttl; > int sc_txhprio; > + int sc_rxhprio; > int sc_ecn; > }; > > @@ -156,6 +157,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; > + sc->sc_rxhprio = IF_HDRPRIO_PAYLOAD; > sc->sc_ecn = ECN_ALLOWED; > > snprintf(ifp->if_xname, sizeof(ifp->if_xname), > @@ -568,6 +570,23 @@ gif_ioctl(struct ifnet *ifp, u_long cmd, > ifr->ifr_hdrprio = sc->sc_txhprio; > break; > > + case SIOCSRXHPRIO: > + if (ifr->ifr_hdrprio == IF_HDRPRIO_PAYLOAD || > + ifr->ifr_hdrprio == IF_HDRPRIO_PACKET || > + ifr->ifr_hdrprio == IF_HDRPRIO_OUTER) > + ; /* ok, fall through */ > + else if (ifr->ifr_hdrprio < IF_HDRPRIO_MIN || > + ifr->ifr_hdrprio > IF_HDRPRIO_MAX) { > + error = EINVAL; > + break; > + } > + > + sc->sc_rxhprio = ifr->ifr_hdrprio; > + break; > + case SIOCGRXHPRIO: > + ifr->ifr_hdrprio = sc->sc_rxhprio; > + break; > + > default: > error = ENOTTY; > break; > @@ -783,6 +802,7 @@ gif_input(struct gif_tunnel *key, struct > struct ifnet *ifp; > void (*input)(struct ifnet *, struct mbuf *); > uint8_t itos; > + int rxhprio; > > /* IP-in-IP header is caused by tunnel mode, so skip gif lookup */ > if (m->m_flags & M_TUNNEL) { > @@ -803,6 +823,7 @@ gif_input(struct gif_tunnel *key, struct > m_adj(m, *offp); /* this is ours now */ > > ifp = &sc->sc_if; > + rxhprio = sc->sc_rxhprio; > > switch (proto) { > case IPPROTO_IPV4: { > @@ -848,10 +869,19 @@ gif_input(struct gif_tunnel *key, struct > } > #endif /* INET6 */ > #ifdef MPLS > - case IPPROTO_MPLS: > + case IPPROTO_MPLS: { > + uint32_t shim; > + m = *mp = m_pullup(m, sizeof(shim)); > + if (m == NULL) > + return (IPPROTO_DONE); > + > + shim = bemtoh32(mtod(m, uint32_t *)); > + itos = ((shim & MPLS_EXP_MASK) >> MPLS_EXP_OFFSET) << 5; > + > m->m_pkthdr.ph_family = AF_MPLS; > input = mpls_input; > break; > + } > #endif /* MPLS */ > default: > return (-1); > @@ -860,6 +890,21 @@ gif_input(struct gif_tunnel *key, struct > m->m_flags &= ~(M_MCAST|M_BCAST); > m->m_pkthdr.ph_ifidx = ifp->if_index; > m->m_pkthdr.ph_rtableid = ifp->if_rdomain; > + > + switch (rxhprio) { > + case IF_HDRPRIO_PACKET: > + /* nop */ > + break; > + case IF_HDRPRIO_PAYLOAD: > + m->m_pkthdr.pf.prio = IFQ_TOS2PRIO(itos); > + break; > + case IF_HDRPRIO_OUTER: > + m->m_pkthdr.pf.prio = IFQ_TOS2PRIO(otos); > + break; > + default: > + m->m_pkthdr.pf.prio = rxhprio; > + break; > + } > > #if NPF > 0 > pf_pkt_addr_changed(m); > Index: sbin/ifconfig/ifconfig.c > =================================================================== > RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v > retrieving revision 1.399 > diff -u -p -r1.399 ifconfig.c > --- sbin/ifconfig/ifconfig.c 11 Apr 2019 11:32:24 -0000 1.399 > +++ sbin/ifconfig/ifconfig.c 14 Apr 2019 07:14:03 -0000 > @@ -139,6 +139,8 @@ struct ifencap { > > #define IFE_TXHPRIO_SET 0x1000 > int ife_txhprio; > +#define IFE_RXHPRIO_SET 0x2000 > + int ife_rxhprio; > }; > > struct ifreq ifr, ridreq; > @@ -295,6 +297,8 @@ void delvnetflowid(const char *, int); > void getvnetflowid(struct ifencap *); > void gettxprio(struct ifencap *); > void settxprio(const char *, int); > +void getrxprio(struct ifencap *); > +void setrxprio(const char *, int); > void settunneldf(const char *, int); > void settunnelnodf(const char *, int); > void settunnelecn(const char *, int); > @@ -503,6 +507,7 @@ const struct cmd { > { "vnetflowid", 0, 0, setvnetflowid }, > { "-vnetflowid", 0, 0, delvnetflowid }, > { "txprio", NEXTARG, 0, settxprio }, > + { "rxprio", NEXTARG, 0, setrxprio }, > { "pppoedev", NEXTARG, 0, setpppoe_dev }, > { "pppoesvc", NEXTARG, 0, setpppoe_svc }, > { "-pppoesvc", 1, 0, setpppoe_svc }, > @@ -4214,6 +4219,46 @@ settxprio(const char *val, int d) > if (ioctl(s, SIOCSTXHPRIO, (caddr_t)&ifr) < 0) > warn("SIOCSTXHPRIO"); > } > + > +void > +getrxprio(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, SIOCGRXHPRIO, (caddr_t)&ifr) == -1) > + return; > + > + ife->ife_flags |= IFE_RXHPRIO_SET; > + ife->ife_rxhprio = ifr.ifr_hdrprio; > +} > + > +void > +setrxprio(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, "rx 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 if (strcmp(val, "outer") == 0) > + ifr.ifr_hdrprio = IF_HDRPRIO_OUTER; > + else { > + ifr.ifr_hdrprio = strtonum(val, > + IF_HDRPRIO_MIN, IF_HDRPRIO_MAX, &errmsg); > + if (errmsg) > + errx(1, "rx prio %s: %s", val, errmsg); > + } > + > + if (ioctl(s, SIOCSRXHPRIO, (caddr_t)&ifr) < 0) > + warn("SIOCSRXHPRIO"); > +} > #endif > > void > @@ -4226,6 +4271,7 @@ getencap(void) > getifparent(&ife); > #ifndef SMALL > gettxprio(&ife); > + getrxprio(&ife); > #endif > > if (ife.ife_flags == 0) > @@ -4258,15 +4304,34 @@ getencap(void) > > #ifndef SMALL > if (ife.ife_flags & IFE_TXHPRIO_SET) { > + printf(" txprio "); > switch (ife.ife_txhprio) { > case IF_HDRPRIO_PACKET: > - printf(" txprio packet"); > + printf("packet"); > break; > case IF_HDRPRIO_PAYLOAD: > - printf(" txprio payload"); > + printf("payload"); > + break; > + default: > + printf("%d", ife.ife_txhprio); > + break; > + } > + } > + > + if (ife.ife_flags & IFE_RXHPRIO_SET) { > + printf(" rxprio "); > + switch (ife.ife_rxhprio) { > + case IF_HDRPRIO_PACKET: > + printf("packet"); > + break; > + case IF_HDRPRIO_PAYLOAD: > + printf("payload"); > + break; > + case IF_HDRPRIO_OUTER: > + printf("outer"); > break; > default: > - printf(" txprio %d", ife.ife_txhprio); > + printf("%d", ife.ife_rxhprio); > break; > } > } > -- :wq Claudio