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

Reply via email to