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)
 {

Reply via email to