On Thu, Oct 02, 2014 at 02:36:12PM +0200, Martin Pieuchot wrote: > On 01/10/14(Wed) 21:54, Rafael Zalamena wrote: > > --- old chat snip --- > > > > Code change: > > * Moved label address from softc to lladdr ifa > > I'm afraid this is not what we want. The rest of your diff looks fine > but moving the storage to be represented as a 'destination address' > might make sense, but not attached on the lladdr ifa. >
I tried to use ifp->if_addrlist, but it looks like this KASSERT in rtsock.c doesn't like this. rtsock.c:1322 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { KASSERT(ifa->ifa_addr->sa_family != AF_LINK); See sys/net/rtsock.c: revision 1.144 " Do not put any link-layer address on the per-ifp lists or on the RB- Tree. Since interfaces only support one link-layer address accessible via the if_sadl member, there's no need to have it elsewhere. This improves various address lookups because the first element of the list, the link- layer address, won't necessarily be discarded. Finally remove the empty netmask associated to every link-layer address. This hack was needed to (ab)use the address & netmask comparison code to do a strcmp() on the interface name embedded in the sdl_data field. ok henning@, claudio@ " So I moved the ifa back to softc. > > * Changed rt_ifa_add to default RTF_MPLS routes to do a POP and only > > use rdomain 0 (MPLS only works on domain 0, and it doesn't make sense > > other actions when creating MPLS route to an interface) Also changed rt_ifa_del() to remove routes from rdomain 0 as well. > > * Removed old code that installed mpe MPLS routes > > * Conflicting labels verification is now done by routing (see rt_ifa_add()) I had to put back the old verification for installed routes, since the rt_ifa_add checks failed to find already existing routes when changing domains or having mpe interfaces down. > > This looks ok. > > > This was tested in the setup described in: > > http://2011.eurobsdcon.org/papers/jeker/MPLS.pdf > > > > Here is the diff: > > --- snipped old diff --- Updated diff: Index: net/if_mpe.c =================================================================== RCS file: /home/rzalamena/obsdcvs//src/sys/net/if_mpe.c,v retrieving revision 1.35 diff -u -p -r1.35 if_mpe.c --- net/if_mpe.c 22 Jul 2014 11:06:09 -0000 1.35 +++ net/if_mpe.c 4 Oct 2014 22:21:17 -0000 @@ -61,7 +61,6 @@ int mpeioctl(struct ifnet *, u_long, cad 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 = @@ -84,13 +83,19 @@ mpe_clone_create(struct if_clone *ifc, i { struct ifnet *ifp; struct mpe_softc *mpeif; + struct sockaddr_mpls *smpls; int s; if ((mpeif = malloc(sizeof(*mpeif), M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL) return (ENOMEM); - mpeif->sc_shim.shim_label = 0; + smpls = malloc(sizeof(*smpls), M_IFADDR, M_NOWAIT | M_ZERO); + if (smpls == NULL) { + free(mpeif, M_DEVBUF, 0); + return (ENOMEM); + } + mpeif->sc_unit = unit; ifp = &mpeif->sc_if; snprintf(ifp->if_xname, sizeof ifp->if_xname, "mpe%d", unit); @@ -110,6 +115,12 @@ mpe_clone_create(struct if_clone *ifc, i bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t)); #endif + smpls->smpls_family = AF_MPLS; + smpls->smpls_len = sizeof(*smpls); + mpeif->sc_ifa.ifa_ifp = ifp; + mpeif->sc_ifa.ifa_addr = (struct sockaddr *) ifp->if_sadl; + mpeif->sc_ifa.ifa_dstaddr = smplstosa(smpls); + s = splnet(); LIST_INSERT_HEAD(&mpeif_list, mpeif, sc_list); splx(s); @@ -128,6 +139,7 @@ mpe_clone_destroy(struct ifnet *ifp) splx(s); if_detach(ifp); + free(mpeif->sc_ifa.ifa_dstaddr, M_IFADDR, 0); free(mpeif, M_DEVBUF, 0); return (0); } @@ -278,8 +290,9 @@ int mpeioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { int error; - struct mpe_softc *ifm; + struct mpe_softc *ifm, *ifmn; struct ifreq *ifr; + struct sockaddr_mpls *smpls; struct shim_hdr shim; ifr = (struct ifreq *)data; @@ -304,13 +317,15 @@ mpeioctl(struct ifnet *ifp, u_long cmd, break; case SIOCGETLABEL: ifm = ifp->if_softc; + smpls = satosmpls(ifm->sc_ifa.ifa_dstaddr); shim.shim_label = - ((ntohl(ifm->sc_shim.shim_label & MPLS_LABEL_MASK)) >> + ((ntohl(smpls->smpls_label & MPLS_LABEL_MASK)) >> MPLS_LABEL_OFFSET); error = copyout(&shim, ifr->ifr_data, sizeof(shim)); break; case SIOCSETLABEL: ifm = ifp->if_softc; + smpls = satosmpls(ifm->sc_ifa.ifa_dstaddr); if ((error = copyin(ifr->ifr_data, &shim, sizeof(shim)))) break; if (shim.shim_label > MPLS_LABEL_MAX || @@ -319,36 +334,40 @@ mpeioctl(struct ifnet *ifp, u_long cmd, break; } shim.shim_label = htonl(shim.shim_label << MPLS_LABEL_OFFSET); - if (ifm->sc_shim.shim_label == shim.shim_label) + if (smpls->smpls_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) + LIST_FOREACH(ifmn, &mpeif_list, sc_list) { + if (ifm == ifmn) + continue; + if (satosmpls(ifm->sc_ifa.ifa_dstaddr)->smpls_label != + shim.shim_label) + continue; + + error = EEXIST; 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; + if (smpls->smpls_label) { + rt_ifa_del(&ifm->sc_ifa, RTF_MPLS | RTF_UP, + smplstosa(smpls)); + smpls->smpls_label = 0; + } + + smpls->smpls_label = shim.shim_label; + error = rt_ifa_add(&ifm->sc_ifa, RTF_MPLS | RTF_UP, + smplstosa(smpls)); + if (error != 0) + smpls->smpls_label = 0; break; case SIOCSIFRDOMAIN: /* must readd the MPLS "route" for our label */ ifm = ifp->if_softc; + smpls = satosmpls(ifm->sc_ifa.ifa_dstaddr); 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); - } + if (smpls->smpls_label) + rt_ifa_add(&ifm->sc_ifa, RTF_MPLS | RTF_UP, + smplstosa(smpls)); } /* return with ENOTTY so that the parent handler finishes */ return (ENOTTY); @@ -442,38 +461,3 @@ mpe_input6(struct mbuf *m, struct ifnet splx(s); } #endif /* INET6 */ - -int -mpe_newlabel(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); -} Index: net/route.c =================================================================== RCS file: /home/rzalamena/obsdcvs//src/sys/net/route.c,v retrieving revision 1.185 diff -u -p -r1.185 route.c --- net/route.c 2 Oct 2014 12:21:20 -0000 1.185 +++ net/route.c 4 Oct 2014 22:21:17 -0000 @@ -1100,6 +1100,11 @@ rt_ifa_add(struct ifaddr *ifa, int flags info.rti_info[RTAX_LABEL] = rtlabel_id2sa(ifa->ifa_ifp->if_rtlabelid, &sa_rl); + if ((flags & RTF_MPLS) == RTF_MPLS) { + info.rti_mpls = MPLS_OP_POP; + rtableid = 0; + } + if ((flags & RTF_HOST) == 0) info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; @@ -1144,6 +1149,9 @@ rt_ifa_del(struct ifaddr *ifa, int flags u_short rtableid = ifa->ifa_ifp->if_rdomain; u_int8_t prio = RTP_CONNECTED; int error; + + if ((flags & RTF_MPLS) == RTF_MPLS) + rtableid = 0; if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) { m = m_get(M_DONTWAIT, MT_SONAME); Index: netmpls/mpls.h =================================================================== RCS file: /home/rzalamena/obsdcvs//src/sys/netmpls/mpls.h,v retrieving revision 1.28 diff -u -p -r1.28 mpls.h --- netmpls/mpls.h 24 Apr 2013 10:20:15 -0000 1.28 +++ netmpls/mpls.h 4 Oct 2014 22:21:17 -0000 @@ -148,8 +148,8 @@ extern struct domain mplsdomain; struct mpe_softc { struct ifnet sc_if; /* the interface */ + struct ifaddr sc_ifa; int sc_unit; - struct shim_hdr sc_shim; LIST_ENTRY(mpe_softc) sc_list; };