Hello Rafael,

On 14/09/14(Sun) 23:49, Rafael Zalamena wrote:
> The following patch is just a preparation for the code that is coming to
> implement the wire network interface (the VPLS datapath) to work on OpenBSD.
> 
> This code turns the mpe code that handles route and labels into some general
> use functions that will be called by mpe and wire.

Would it be possible to use  the new rt_ifa_add() and rt_ifa_del() instead of
keeping what is basically a copy of the old rtinit()?

In your case you want to use the lladdr's ifa and you can check for
RTF_MPLS in the flags to add the corresponding MPLS_OP_POP value.


> diff --git sys/net/if_mpe.c sys/net/if_mpe.c
> index 74039dc..98d69f4 100644
> --- sys/net/if_mpe.c
> +++ sys/net/if_mpe.c
> @@ -61,7 +61,6 @@ int mpeioctl(struct ifnet *, u_long, caddr_t);
>  void mpestart(struct ifnet *);
>  int  mpe_clone_create(struct if_clone *, int);
>  int  mpe_clone_destroy(struct ifnet *);
> -int  mpe_newlabel(struct ifnet *, int, struct shim_hdr *);
>  
>  LIST_HEAD(, mpe_softc)       mpeif_list;
>  struct if_clone      mpe_cloner =
> @@ -319,36 +318,17 @@ mpeioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
>                       break;
>               }
>               shim.shim_label = htonl(shim.shim_label << MPLS_LABEL_OFFSET);
> -             if (ifm->sc_shim.shim_label == shim.shim_label)
> -                     break;
> -             LIST_FOREACH(ifm, &mpeif_list, sc_list) {
> -                     if (ifm != ifp->if_softc &&
> -                         ifm->sc_shim.shim_label == shim.shim_label) {
> -                             error = EEXIST;
> -                             break;
> -                     }
> -             }
> -             if (error)
> -                     break;
> -             ifm = ifp->if_softc;
> -             if (ifm->sc_shim.shim_label) {
> -                     /* remove old MPLS route */
> -                     mpe_newlabel(ifp, RTM_DELETE, &ifm->sc_shim);
> -             }
> -             /* add new MPLS route */
> -             error = mpe_newlabel(ifp, RTM_ADD, &shim);
> -             if (error)
> -                     break;
> -             ifm->sc_shim.shim_label = shim.shim_label;
> +             error = mpls_shim_set(ifp, &shim, &ifm->sc_shim);
>               break;
>       case SIOCSIFRDOMAIN:
>               /* must readd the MPLS "route" for our label */
>               ifm = ifp->if_softc;
>               if (ifr->ifr_rdomainid != ifp->if_rdomain) {
> -                     if (ifm->sc_shim.shim_label) {
> -                             shim.shim_label = ifm->sc_shim.shim_label;
> -                             error = mpe_newlabel(ifp, RTM_ADD, &shim);
> -                     }
> +                     shim.shim_label = ifm->sc_shim.shim_label;
> +
> +                     /* XXX trick mpls_shim_set() to reinstall the route */
> +                     bzero(&ifm->sc_shim, sizeof(ifm->sc_shim));
> +                     error = mpls_shim_set(ifp, &shim, &ifm->sc_shim);
>               }
>               /* return with ENOTTY so that the parent handler finishes */
>               return (ENOTTY);
> @@ -444,36 +424,13 @@ mpe_input6(struct mbuf *m, struct ifnet *ifp, struct 
> sockaddr_mpls *smpls,
>  #endif       /* INET6 */
>  
>  int
> -mpe_newlabel(struct ifnet *ifp, int cmd, struct shim_hdr *shim)
> +mpe_label_exists(const struct shim_hdr *shim)
>  {
> -     struct rtentry *nrt;
> -     struct sockaddr_mpls dst;
> -     struct rt_addrinfo info;
> -     int error;
> -
> -     bzero(&dst, sizeof(dst));
> -     dst.smpls_len = sizeof(dst);
> -     dst.smpls_family = AF_MPLS;
> -     dst.smpls_label = shim->shim_label;
> -
> -     bzero(&info, sizeof(info));
> -     info.rti_flags = RTF_UP | RTF_MPLS;
> -     info.rti_mpls = MPLS_OP_POP;
> -     info.rti_info[RTAX_DST] = smplstosa(&dst);
> -     info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)ifp->if_sadl;
> -
> -     error = rtrequest1(cmd, &info, RTP_CONNECTED, &nrt, 0);
> -     rt_missmsg(cmd, &info, error ? 0 : nrt->rt_flags, ifp, error, 0);
> -     if (cmd == RTM_DELETE) {
> -             if (error == 0 && nrt != NULL) {
> -                     if (nrt->rt_refcnt <= 0) {
> -                             nrt->rt_refcnt++;
> -                             rtfree(nrt);
> -                     }
> -             }
> -     }
> -     if (cmd == RTM_ADD && error == 0 && nrt != NULL) {
> -             nrt->rt_refcnt--;
> -     }
> -     return (error);
> +     struct  mpe_softc *mpe_sc;
> +
> +     LIST_FOREACH(mpe_sc, &mpeif_list, sc_list)
> +             if (shim->shim_label == mpe_sc->sc_shim.shim_label)
> +                     return (1);
> +
> +     return (0);
>  }
> diff --git sys/netmpls/mpls.h sys/netmpls/mpls.h
> index 2903aa4..0363d86 100644
> --- sys/netmpls/mpls.h
> +++ sys/netmpls/mpls.h
> @@ -176,9 +176,13 @@ extern int               mpls_inkloop;
>  void mpls_init(void);
>  void mplsintr(void);
>  
> +int           mpe_label_exists(const struct shim_hdr *);
> +
>  struct mbuf  *mpls_shim_pop(struct mbuf *);
>  struct mbuf  *mpls_shim_swap(struct mbuf *, struct rt_mpls *);
>  struct mbuf  *mpls_shim_push(struct mbuf *, struct rt_mpls *);
> +int           mpls_shim_set(struct ifnet *, struct shim_hdr *,
> +                 struct shim_hdr *);
>  
>  int           mpls_sysctl(int *, u_int, void *, size_t *, void *, size_t);
>  void          mpls_input(struct mbuf *);
> diff --git sys/netmpls/mpls_shim.c sys/netmpls/mpls_shim.c
> index 203f220..3275dfb 100644
> --- sys/netmpls/mpls_shim.c
> +++ sys/netmpls/mpls_shim.c
> @@ -30,6 +30,8 @@
>   * SUCH DAMAGE.
>   */
>  
> +#include "mpe.h"
> +
>  #include <sys/param.h>
>  #include <sys/mbuf.h>
>  #include <sys/errno.h>
> @@ -37,9 +39,13 @@
>  #include <sys/systm.h>
>  
>  #include <net/if.h>
> +#include <net/route.h>
>  
>  #include <netmpls/mpls.h>
>  
> +int  mpls_shim_label_exists(const struct shim_hdr *);
> +int  mpls_shim_route(struct ifnet *, int, struct shim_hdr *);
> +
>  struct mbuf *
>  mpls_shim_pop(struct mbuf *m)
>  {
> @@ -96,3 +102,78 @@ mpls_shim_push(struct mbuf *m, struct rt_mpls *rt_mpls)
>  
>       return (mpls_shim_swap(m, rt_mpls));
>  }
> +
> +int
> +mpls_shim_label_exists(const struct shim_hdr *shim)
> +{
> +#if NMPE > 0
> +     if (mpe_label_exists(shim))
> +             return (1);
> +#endif /* NMPE */
> +
> +     return (0);
> +}
> +
> +int
> +mpls_shim_route(struct ifnet *ifp, int cmd, struct shim_hdr *shim)
> +{
> +     struct rtentry *nrt;
> +     struct sockaddr_mpls dst;
> +     struct rt_addrinfo info;
> +     int error;
> +
> +     bzero(&dst, sizeof(dst));
> +     dst.smpls_len = sizeof(dst);
> +     dst.smpls_family = AF_MPLS;
> +     dst.smpls_label = shim->shim_label;
> +
> +     bzero(&info, sizeof(info));
> +     info.rti_flags = RTF_UP | RTF_MPLS;
> +     info.rti_mpls = MPLS_OP_POP;
> +     info.rti_info[RTAX_DST] = smplstosa(&dst);
> +     info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)ifp->if_sadl;
> +
> +     error = rtrequest1(cmd, &info, RTP_CONNECTED, &nrt, 0);
> +     rt_missmsg(cmd, &info, error ? 0 : nrt->rt_flags, ifp, error, 0);
> +     if (cmd == RTM_DELETE) {
> +             if (error == 0 && nrt != NULL) {
> +                     if (nrt->rt_refcnt <= 0) {
> +                             nrt->rt_refcnt++;
> +                             rtfree(nrt);
> +                     }
> +             }
> +     }
> +     if (cmd == RTM_ADD && error == 0 && nrt != NULL)
> +             nrt->rt_refcnt--;
> +
> +     return (error);
> +}
> +
> +int
> +mpls_shim_set(struct ifnet *ifp, struct shim_hdr *sshim, struct shim_hdr 
> *dshim)
> +{
> +     int     error;
> +
> +     if (sshim->shim_label == dshim->shim_label)
> +             return (0);
> +
> +     /* There must be only one route to this path */
> +     if (mpls_shim_label_exists(sshim))
> +             return (EEXIST);
> +
> +     /* Remove old MPLS route */
> +     if (dshim->shim_label != 0) {
> +             mpls_shim_route(ifp, RTM_DELETE, dshim);
> +             bzero(dshim, sizeof(*dshim));
> +     }
> +
> +     if (sshim->shim_label == 0)
> +             return (0);
> +
> +     /* Add new MPLS route */
> +     error = mpls_shim_route(ifp, RTM_ADD, sshim);
> +     if (error == 0)
> +             dshim->shim_label = sshim->shim_label;
> +
> +     return (error);
> +}
> 

Reply via email to