On Fri, Mar 26, 2021 at 01:16:32PM +0100, Klemens Nanni wrote: > On Wed, Mar 17, 2021 at 04:47:36PM +0100, Klemens Nanni wrote: > > `ifconfig mp* mplslabel N' validates the label both in ifconfig and each > > driver's ioctl handler, but there is one case where all drivers install > > a route without looking at the label at all. > > > > SIOCSLIFPHYRTABLE in all three drivers just validates the rdomain and > > sets the label to itself (0 after clone) such that the route is > > (re)installed accordingly. > > > > The problem is that respective routines, e.g. mpe_set_label(), do not > > validate the label themselves but instead expect the callee to do so; > > all of them do so except the SIOCSLIFPHYRTABLE ioctl handler case: > > > > case SIOCSLIFPHYRTABLE: > > if (ifr->ifr_rdomainid < 0 || > > ...) { > > error = EINVAL; > > break; > > } > > > > if (sc->sc_rdomain != ifr->ifr_rdomainid) { > > error = mpe_set_label(sc, sc->sc_smpls.smpls_label, > > ifr->ifr_rdomainid); > > } > > break; > > > > Given a pristine setup: > > > > # ifconfig mpw > > mpw: no such interface > > # route -n show -mpls > > Routing tables > > # route -nT2 show -mpls > > Routing tables > > > > that means we can install routes for the explicit NULL label in > > non-default routing tables: > > > > # ifconfig mpw0 tunneldomain 2 > > # ifconfig mpw0 | grep label > > mpls: label (unset) pwe3 remote label (unset) nocw nofat > > # route -nT2 show -mpls > > Routing tables > > > > MPLS: > > In label Out label Op Gateway Flags Refs Use > > Mtu Prio Interface > > 0 - POP fe:e1:ba:db:eb:89 UTl 0 0 > > - 1 mpw0 > > > > and can never clean them up without reboot: > > > > # ifconfig mpw0 -tunneldomain > > # route -nT2 show -mpls > > Routing tables > > > > MPLS: > > In label Out label Op Gateway Flags Refs Use > > Mtu Prio Interface > > 0 - POP fe:e1:ba:db:eb:89 UTl 0 0 > > - 1 (null) > > # ifconfig mpw0 destroy > > # route -nT2 show -mpls > > Routing tables > > > > MPLS: > > In label Out label Op Gateway Flags Refs Use > > Mtu Prio Interface > > 0 - POP fe:e1:ba:db:eb:89 UTl 0 0 > > - 1 (null) > > After that you can create new interfaces but won't be able to use them > with that rdomain since the stale route blocks creating the new one in > that rtable: > > # ifconfig mpw0 create > # ifconfig mpw0 tunneldomain 2 > ifconfig: SIOCSLIFPHYRTABLE: File exists > > > My first approach was removing the label check from mp*_clone_destroy() > > to unconditionally delete the respective route, but my understanding is > > that we must not install such bogus routes to begin with. > > > > So fix this by adding the inverted check to the mp*_set_label() routines > > after updating the rdomain and before route reinstallation to skip those > > nonexistent ones, i.e. to avoid installing bogus ones. > > > > I'd argue this is better factored out into some label validating helper > > function that can then be used from multiple callees, but I don't want > > to touch so much code without a proper setup at hand -- plus, the diff > > is much easier to understand and review this way. > > > > > > Note that I've only tested this with ifconfig(8) and route(8), I have > > no ldpd(8) or proper MPLS link to test with. > > > > Feedback? Objections? OK? > > Ping. > > > Index: if_mpw.c > =================================================================== > RCS file: /cvs/src/sys/net/if_mpw.c,v > retrieving revision 1.61 > diff -u -p -r1.61 if_mpw.c > --- if_mpw.c 17 Mar 2021 18:53:25 -0000 1.61 > +++ if_mpw.c 18 Mar 2021 16:43:10 -0000 > @@ -172,6 +172,10 @@ mpw_set_route(struct mpw_softc *sc, uint > sc->sc_smpls.smpls_label = label; > sc->sc_rdomain = rdomain; > > + /* only install with a label or mpw_clone_destroy() will ignore it */ > + if (sc->sc_smpls.smpls_label == MPLS_LABEL2SHIM(0)) > + return 0; > + > error = rt_ifa_add(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL, > smplstosa(&sc->sc_smpls), sc->sc_rdomain); > if (error != 0) > Index: if_mpe.c > =================================================================== > RCS file: /cvs/src/sys/net/if_mpe.c,v > retrieving revision 1.99 > diff -u -p -r1.99 if_mpe.c > --- if_mpe.c 18 Mar 2021 14:47:17 -0000 1.99 > +++ if_mpe.c 18 Mar 2021 16:43:11 -0000 > @@ -339,6 +339,10 @@ mpe_set_label(struct mpe_softc *sc, uint > sc->sc_smpls.smpls_label = label; > sc->sc_rdomain = rdomain; > > + /* only install with a label or mpe_clone_destroy() will ignore it */ > + if (sc->sc_smpls.smpls_label == MPLS_LABEL2SHIM(0)) > + return 0; > + > error = rt_ifa_add(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL, > smplstosa(&sc->sc_smpls), sc->sc_rdomain); > if (error) > Index: if_mpip.c > =================================================================== > RCS file: /cvs/src/sys/net/if_mpip.c,v > retrieving revision 1.14 > diff -u -p -r1.14 if_mpip.c > --- if_mpip.c 17 Mar 2021 14:30:09 -0000 1.14 > +++ if_mpip.c 18 Mar 2021 16:43:11 -0000 > @@ -170,6 +170,10 @@ mpip_set_route(struct mpip_softc *sc, ui > sc->sc_smpls.smpls_label = shim; > sc->sc_rdomain = rdomain; > > + /* only install with a label or mpip_clone_destroy() will ignore it */ > + if (sc->sc_smpls.smpls_label == MPLS_LABEL2SHIM(0)) > + return 0; > + > error = rt_ifa_add(&sc->sc_ifa, RTF_MPLS | RTF_LOCAL, > smplstosa(&sc->sc_smpls), sc->sc_rdomain); > if (error) { >
OK claudio -- :wq Claudio