On Tue, Sep 30, 2014 at 11:00:25AM +0200, Martin Pieuchot wrote: > 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. > >
The diff mpi@ suggested is here: http://marc.info/?l=openbsd-tech&m=141280528700615&w=2 This diff now removes the need of a mpe(4) list and now we use a global list of MPLS label inbound, so wire(4) can share. Here is the new diff to prepare sys/ to receive wire(4): diff --git sys/net/if_mpe.c sys/net/if_mpe.c index fd23b21..522613c 100644 --- sys/net/if_mpe.c +++ sys/net/if_mpe.c @@ -63,7 +63,6 @@ int mpe_clone_create(struct if_clone *, int); int mpe_clone_destroy(struct ifnet *); int mpe_iflabelroute(struct ifnet *, struct shim_hdr *, int); -LIST_HEAD(, mpe_softc) mpeif_list; struct if_clone mpe_cloner = IF_CLONE_INITIALIZER("mpe", mpe_clone_create, mpe_clone_destroy); @@ -75,7 +74,6 @@ extern int mpls_mapttl_ip6; void mpeattach(int nmpe) { - LIST_INIT(&mpeif_list); if_clone_attach(&mpe_cloner); } @@ -109,8 +107,6 @@ mpe_clone_create(struct if_clone *ifc, int unit) bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t)); #endif - LIST_INSERT_HEAD(&mpeif_list, mpeif, sc_list); - return (0); } @@ -119,7 +115,8 @@ mpe_clone_destroy(struct ifnet *ifp) { struct mpe_softc *mpeif = ifp->if_softc; - LIST_REMOVE(mpeif, sc_list); + if (mpeif->sc_shim.shim_label) + mpls_shim_del(&mpeif->sc_shim); if_detach(ifp); free(mpeif, M_DEVBUF, 0); @@ -315,16 +312,10 @@ mpeioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 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) + if (mpls_shim_lookup(&shim) != NULL) { + error = EEXIST; break; - ifm = ifp->if_softc; + } if (ifm->sc_shim.shim_label) { /* remove old MPLS route */ mpe_iflabelroute(ifp, &ifm->sc_shim, 0); @@ -340,6 +331,7 @@ mpeioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ifm = ifp->if_softc; if (ifr->ifr_rdomainid != ifp->if_rdomain) { if (ifm->sc_shim.shim_label) { + mpls_shim_del(&ifm->sc_shim); mpe_iflabelroute(ifp, &ifm->sc_shim, 1); } } @@ -446,6 +438,9 @@ mpe_iflabelroute(struct ifnet *ifp, struct shim_hdr *shim, int add) struct sockaddr_mpls smpls; u_short rdomain = ifp->if_rdomain; + if (add && (error = mpls_shim_add(shim)) != 0) + return (error); + ifp->if_rdomain = 0; memset(&smpls, 0, sizeof(smpls)); @@ -459,6 +454,9 @@ mpe_iflabelroute(struct ifnet *ifp, struct shim_hdr *shim, int add) error = rt_ifa_del(ifp->if_lladdr, RTF_MPLS | RTF_UP, smplstosa(&smpls)); + if (error != 0 || (add == 0 && error == 0)) + mpls_shim_del(shim); + ifp->if_rdomain = rdomain; return (error); } diff --git sys/netmpls/mpls.h sys/netmpls/mpls.h index 2903aa4..0407e99 100644 --- sys/netmpls/mpls.h +++ sys/netmpls/mpls.h @@ -150,7 +150,6 @@ struct mpe_softc { struct ifnet sc_if; /* the interface */ int sc_unit; struct shim_hdr sc_shim; - LIST_ENTRY(mpe_softc) sc_list; }; #define MPE_HDRLEN sizeof(struct shim_hdr) @@ -176,6 +175,15 @@ extern int mpls_inkloop; void mpls_init(void); void mplsintr(void); +struct shim_entry { + TAILQ_ENTRY(shim_entry) se_entry; + + struct shim_hdr se_shim; +}; + +struct shim_entry *mpls_shim_lookup(const struct shim_hdr *); +int mpls_shim_add(const struct shim_hdr *); +void mpls_shim_del(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 *); diff --git sys/netmpls/mpls_shim.c sys/netmpls/mpls_shim.c index 203f220..b4aee25 100644 --- sys/netmpls/mpls_shim.c +++ sys/netmpls/mpls_shim.c @@ -40,6 +40,48 @@ #include <netmpls/mpls.h> +TAILQ_HEAD(, shim_entry) selist; + +struct shim_entry * +mpls_shim_lookup(const struct shim_hdr *shim) +{ + struct shim_entry *se; + + TAILQ_FOREACH(se, &selist, se_entry) + if (se->se_shim.shim_label == shim->shim_label) + break; + + return (se); +} + +int +mpls_shim_add(const struct shim_hdr *shim) +{ + struct shim_entry *se; + + if ((se = mpls_shim_lookup(shim)) != NULL) + return (EEXIST); + + if ((se = malloc(sizeof(*se), M_TEMP, M_NOWAIT | M_ZERO)) == NULL) + return (ENOMEM); + + se->se_shim.shim_label = shim->shim_label; + TAILQ_INSERT_HEAD(&selist, se, se_entry); + return (0); +} + +void +mpls_shim_del(const struct shim_hdr *shim) +{ + struct shim_entry *se; + + if ((se = mpls_shim_lookup(shim)) == NULL) + return; + + TAILQ_REMOVE(&selist, se, se_entry); + free(se, M_DEVBUF, 0); +} + struct mbuf * mpls_shim_pop(struct mbuf *m) {