I say great.

On Sun, Apr 14, 2019, 12:00 AM David Gwynne <da...@gwynne.id.au> wrote:

> the mpls exp bits are now defined as a prio field, but we don't have
> support for that currently.
>
> this lets the mpls tunnelling interfaces configure the use of the exp
> fields for prio with the same machinery used for all the other tunnel
> interfaces. the interfaces default to using 0 for the value which keeps
> it compat. other values can be configured with ifconfig like normal
> tunnel interfaces.
>
> ok? meh? nah?
>
> Index: if_mpe.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_mpe.c,v
> retrieving revision 1.90
> diff -u -p -r1.90 if_mpe.c
> --- if_mpe.c    2 Apr 2019 10:52:33 -0000       1.90
> +++ if_mpe.c    14 Apr 2019 06:49:56 -0000
> @@ -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, i
>         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 mbu
>
>         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 mbu
>                 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) {
> @@ -278,7 +306,7 @@ mpe_output(struct ifnet *ifp, struct mbu
>                 goto out;
>         }
>         memcpy(mtod(m, struct sockaddr *), rt->rt_gateway, slen);
> -       mtod(m, struct sockaddr *)->sa_len = slen; /* to be sure */
> +       mtod(m, struct sockaddr *)->sa_len = slen; /* to be sure */
>
>         m->m_pkthdr.ph_family = dst->sa_family;
>
> @@ -387,6 +415,22 @@ mpe_ioctl(struct ifnet *ifp, u_long cmd,
>                 break;
>         case SIOCGLIFPHYRTABLE:
>                 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:
> Index: if_mpip.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_mpip.c,v
> retrieving revision 1.4
> diff -u -p -r1.4 if_mpip.c
> --- if_mpip.c   2 Apr 2019 10:50:16 -0000       1.4
> +++ if_mpip.c   14 Apr 2019 06:49:56 -0000
> @@ -55,6 +55,7 @@ struct mpip_softc {
>         unsigned int            sc_dead;
>         uint32_t                sc_flow; /* xor for mbuf flowid */
>
> +       int                     sc_txhprio;
>         struct ifaddr           sc_ifa;
>         struct sockaddr_mpls    sc_smpls; /* Local label */
>         unsigned int            sc_rdomain;
> @@ -92,6 +93,7 @@ mpip_clone_create(struct if_clone *ifc,
>         if (sc == NULL)
>                 return (ENOMEM);
>
> +       sc->sc_txhprio = 0;
>         sc->sc_neighbor = 0;
>         sc->sc_cword = 0; /* default to no control word */
>         sc->sc_fword = 0; /* both sides have to agree on FAT first */
> @@ -415,6 +417,22 @@ mpip_ioctl(struct ifnet *ifp, u_long cmd
>                 ifr->ifr_ttl = sc->sc_ttl;
>                 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;
> +
>         case SIOCADDMULTI:
>         case SIOCDELMULTI:
>                 break;
> @@ -611,8 +629,9 @@ mpip_start(struct ifnet *ifp)
>                 .smpls_len = sizeof(smpls),
>                 .smpls_family = AF_MPLS,
>         };
> -       uint32_t bos;
> -       uint8_t ttl;
> +       int txprio = sc->sc_txhprio;
> +       uint32_t exp, bos;
> +       uint8_t tos, prio, ttl;
>
>         if (!ISSET(ifp->if_flags, IFF_RUNNING) || n == NULL) {
>                 IFQ_PURGE(&ifp->if_snd);
> @@ -662,6 +681,40 @@ mpip_start(struct ifnet *ifp)
>                 } else
>                         ttl = mpls_defttl;
>
> +               switch (txprio) {
> +               case IF_HDRPRIO_PACKET:
> +                       prio = m->m_pkthdr.pf.prio;
> +                       break;
> +               case IF_HDRPRIO_PAYLOAD:
> +                       switch (m->m_pkthdr.ph_family) {
> +                       case AF_INET: {
> +                               struct ip *ip;
> +                               ip = mtod(m, struct ip *);
> +                               tos = ip->ip_tos;
> +                               break;
> +                       }
> +#ifdef INET6
> +                       case AF_INET6: {
> +                               struct ip6_hdr *ip6;
> +                               uint32_t flow;
> +                               ip6 = mtod(m, struct ip6_hdr *);
> +                               flow = bemtoh32(&ip6->ip6_flow);
> +                               tos = flow >> 20;
> +                               break;
> +                       }
> +#endif
> +                       default:
> +                               unhandled_af(m->m_pkthdr.ph_family);
> +                       }
> +
> +                       prio = IFQ_TOS2PRIO(tos);
> +                       break;
> +               default:
> +                       prio = txprio;
> +                       break;
> +               }
> +               exp = htonl(prio << MPLS_EXP_OFFSET);
> +
>                 if (sc->sc_cword) {
>                         m = m_prepend(m, sizeof(shim), M_NOWAIT);
>                         if (m == NULL)
> @@ -686,7 +739,7 @@ mpip_start(struct ifnet *ifp)
>                         shim = htonl(1) & MPLS_TTL_MASK;
>                         shim |= htonl(flow << MPLS_LABEL_OFFSET) &
>                             MPLS_LABEL_MASK;
> -                       shim |= bos;
> +                       shim |= exp | bos;
>                         *mtod(m, uint32_t *) = shim;
>
>                         bos = 0;
> @@ -698,7 +751,7 @@ mpip_start(struct ifnet *ifp)
>
>                 shim = htonl(ttl) & MPLS_TTL_MASK;
>                 shim |= n->n_rshim.shim_label;
> -               shim |= bos;
> +               shim |= exp | bos;
>                 *mtod(m, uint32_t *) = shim;
>
>                 m->m_pkthdr.ph_rtableid = sc->sc_rdomain;
> Index: if_mpw.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_mpw.c,v
> retrieving revision 1.49
> diff -u -p -r1.49 if_mpw.c
> --- if_mpw.c    2 Apr 2019 10:50:16 -0000       1.49
> +++ if_mpw.c    14 Apr 2019 06:49:56 -0000
> @@ -53,6 +53,7 @@ struct mpw_softc {
>         struct arpcom           sc_ac;
>  #define sc_if                  sc_ac.ac_if
>
> +       int                     sc_txhprio;
>         unsigned int            sc_rdomain;
>         struct ifaddr           sc_ifa;
>         struct sockaddr_mpls    sc_smpls; /* Local label */
> @@ -117,6 +118,7 @@ mpw_clone_create(struct if_clone *ifc, i
>         if_attach(ifp);
>         ether_ifattach(ifp);
>
> +       sc->sc_txhprio = 0;
>         sc->sc_rdomain = 0;
>         sc->sc_ifa.ifa_ifp = ifp;
>         sc->sc_ifa.ifa_addr = sdltosa(ifp->if_sadl);
> @@ -465,6 +467,21 @@ mpw_ioctl(struct ifnet *ifp, u_long cmd,
>                 ifr->ifr_rdomainid = sc->sc_rdomain;
>                 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;
> +               }
> +
> +               sc->sc_txhprio = ifr->ifr_hdrprio;
> +               break;
> +       case SIOCGTXHPRIO:
> +               ifr->ifr_hdrprio = sc->sc_txhprio;
> +               break;
> +
>         case SIOCADDMULTI:
>         case SIOCDELMULTI:
>                 break;
> @@ -605,7 +622,9 @@ mpw_start(struct ifnet *ifp)
>                 .smpls_len = sizeof(smpls),
>                 .smpls_family = AF_MPLS,
>         };
> -       uint32_t bos;
> +       int txprio = sc->sc_txhprio;
> +       uint8_t prio;
> +       uint32_t exp, bos;
>
>         n = sc->sc_neighbor;
>         if (!ISSET(ifp->if_flags, IFF_RUNNING) ||
> @@ -652,6 +671,16 @@ mpw_start(struct ifnet *ifp)
>                         memset(shim, 0, sizeof(*shim));
>                 }
>
> +               switch (txprio) {
> +               case IF_HDRPRIO_PACKET:
> +                       prio = m->m_pkthdr.pf.prio;
> +                       break;
> +               default:
> +                       prio = txprio;
> +                       break;
> +               }
> +               exp = htonl(prio << MPLS_EXP_OFFSET);
> +
>                 bos = MPLS_BOS_MASK;
>                 if (sc->sc_fword) {
>                         uint32_t flow = sc->sc_flow;
> @@ -665,7 +694,7 @@ mpw_start(struct ifnet *ifp)
>
>                         shim = mtod(m0, struct shim_hdr *);
>                         shim->shim_label = htonl(1) & MPLS_TTL_MASK;
> -                       shim->shim_label = MPLS_LABEL2SHIM(flow) | bos;
> +                       shim->shim_label = MPLS_LABEL2SHIM(flow) | exp |
> bos;
>
>                         bos = 0;
>                 }
> @@ -676,7 +705,7 @@ mpw_start(struct ifnet *ifp)
>
>                 shim = mtod(m0, struct shim_hdr *);
>                 shim->shim_label = htonl(mpls_defttl) & MPLS_TTL_MASK;
> -               shim->shim_label |= n->n_rshim.shim_label | bos;
> +               shim->shim_label |= n->n_rshim.shim_label | exp | bos;
>
>                 m0->m_pkthdr.ph_rtableid = sc->sc_rdomain;
>                 CLR(m0->m_flags, M_BCAST|M_MCAST);
>
>

Reply via email to