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); > +} >