I mean rdomain 0 below, not 1.

> On 30 Jan 2019, at 11:48, David Gwynne <da...@gwynne.id.au> wrote:
> 
> mpls uses AF_MPLS routes with RTF_LOCAL set on them to know which tags
> are used as input for the mpe and mpw interfaces. setting this up
> currently goes through rt_ifa_add, but that has a couple of features
> that are undesirable for mpls.
> 
> Firstly, rt_ifa_add unconditionally sets RTF_MPATH on the routes it
> adds, which means multiple mpe and mpw interfaces can "own" the same
> input tag. mpe tries to work around this by maintaining a global list of
> mpe interfaces, and iterates over them when a new label is added. That's
> ok (sort of) for mpe, but it doesnt take the tags used by mpw into
> account.
> 
> Secondly, I'd like to start pulling apart the restriction on the use of
> mpls only in rdomain 1. rt_ifa_add doesn't help this situation because
> it assumes that we're adding a route inside the rdomain the interface is
> in, rather than the one it tunnels in. Changing this assumption means
> forking rt_ifa_add, and oh look, that's what I've started here.
> 
> So, if I have the following:
> 
> mpe2: flags=51<UP,POINTOPOINT,RUNNING> rdomain 2 mtu 1500
>        index 6 priority 0 llprio 3
>        mpls label 1000
>        groups: mpe
>        inet 192.168.0.25 --> 0.0.0.0 netmask 0xffffffff
> mpw0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
>        lladdr fe:e1:ba:d0:93:1a
>        index 7 priority 0 llprio 3
>        encapsulation-type ethernet, control-word
>        mpls label: local 16 remote 16
>        neighbor: 192.168.0.27
>        groups: mpw
>        inet 100.64.100.2 netmask 0xffffff00 broadcast 100.64.100.255
> 
> The following now does what's expected:
> 
> dlg@cpe0 sys$ sudo ifconfig mpe3 create
> dlg@cpe0 sys$ sudo ifconfig mpe3 mplslabel 16  
> ifconfig: SIOCSETLABEL: File exists
> 
> ok?
> 
> Index: net/if_mpe.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_mpe.c,v
> retrieving revision 1.76
> diff -u -p -r1.76 if_mpe.c
> --- net/if_mpe.c      30 Jan 2019 01:09:36 -0000      1.76
> +++ net/if_mpe.c      30 Jan 2019 01:40:47 -0000
> @@ -132,10 +132,8 @@ mpe_clone_destroy(struct ifnet *ifp)
> 
>       LIST_REMOVE(sc, sc_list);
> 
> -     if (sc->sc_smpls.smpls_label) {
> -             rt_ifa_del(&sc->sc_ifa, RTF_MPLS,
> -                 smplstosa(&sc->sc_smpls));
> -     }
> +     if (sc->sc_smpls.smpls_label)
> +             mpls_ifa_del(&sc->sc_ifa, &sc->sc_smpls);
> 
>       if_detach(ifp);
>       free(sc, M_DEVBUF, sizeof *sc);
> @@ -331,13 +329,11 @@ mpe_ioctl(struct ifnet *ifp, u_long cmd,
>               ifm = ifp->if_softc;
>               if (ifm->sc_smpls.smpls_label) {
>                       /* remove old MPLS route */
> -                     rt_ifa_del(&ifm->sc_ifa, RTF_MPLS,
> -                         smplstosa(&ifm->sc_smpls));
> +                     mpls_ifa_del(&ifm->sc_ifa, &ifm->sc_smpls);
>               }
>               /* add new MPLS route */
>               ifm->sc_smpls.smpls_label = shim.shim_label;
> -             error = rt_ifa_add(&ifm->sc_ifa, RTF_MPLS|RTF_LOCAL,
> -                 smplstosa(&ifm->sc_smpls));
> +             error = mpls_ifa_add(&ifm->sc_ifa, &ifm->sc_smpls);
>               if (error) {
>                       ifm->sc_smpls.smpls_label = 0;
>                       break;
> @@ -348,10 +344,8 @@ mpe_ioctl(struct ifnet *ifp, u_long cmd,
>               /* XXX does not make sense, the MPLS route is on rtable 0 */
>               ifm = ifp->if_softc;
>               if (ifr->ifr_rdomainid != ifp->if_rdomain) {
> -                     if (ifm->sc_smpls.smpls_label) {
> -                             rt_ifa_add(&ifm->sc_ifa, RTF_MPLS,
> -                                 smplstosa(&ifm->sc_smpls));
> -                     }
> +                     if (ifm->sc_smpls.smpls_label)
> +                             mpls_ifa_add(&ifm->sc_ifa, &ifm->sc_smpls);
>               }
>               /* return with ENOTTY so that the parent handler finishes */
>               return (ENOTTY);
> Index: net/if_mpw.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_mpw.c,v
> retrieving revision 1.31
> diff -u -p -r1.31 if_mpw.c
> --- net/if_mpw.c      30 Jan 2019 01:09:36 -0000      1.31
> +++ net/if_mpw.c      30 Jan 2019 01:40:47 -0000
> @@ -116,8 +116,7 @@ mpw_clone_destroy(struct ifnet *ifp)
>       ifp->if_flags &= ~IFF_RUNNING;
> 
>       if (sc->sc_smpls.smpls_label) {
> -             rt_ifa_del(&sc->sc_ifa, RTF_MPLS,
> -                 smplstosa(&sc->sc_smpls));
> +             mpls_ifa_del(&sc->sc_ifa, &sc->sc_smpls);
>       }
> 
>       ether_ifdetach(ifp);
> @@ -162,9 +161,8 @@ mpw_ioctl(struct ifnet *ifp, u_long cmd,
>               /* Teardown all configuration if got no nexthop */
>               sin = (struct sockaddr_in *) &imr.imr_nexthop;
>               if (sin->sin_addr.s_addr == 0) {
> -                     if (rt_ifa_del(&sc->sc_ifa, RTF_MPLS,
> -                         smplstosa(&sc->sc_smpls)) == 0)
> -                             sc->sc_smpls.smpls_label = 0;
> +                     mpls_ifa_del(&sc->sc_ifa, &sc->sc_smpls);
> +                     sc->sc_smpls.smpls_label = 0;
> 
>                       memset(&sc->sc_rshim, 0, sizeof(sc->sc_rshim));
>                       memset(&sc->sc_nexthop, 0, sizeof(sc->sc_nexthop));
> @@ -191,12 +189,10 @@ mpw_ioctl(struct ifnet *ifp, u_long cmd,
> 
>               if (sc->sc_smpls.smpls_label != imr.imr_lshim.shim_label) {
>                       if (sc->sc_smpls.smpls_label)
> -                             rt_ifa_del(&sc->sc_ifa, RTF_MPLS,
> -                                 smplstosa(&sc->sc_smpls));
> +                             mpls_ifa_del(&sc->sc_ifa, &sc->sc_smpls);
> 
>                       sc->sc_smpls.smpls_label = imr.imr_lshim.shim_label;
> -                     error = rt_ifa_add(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL,
> -                         smplstosa(&sc->sc_smpls));
> +                     error = mpls_ifa_add(&sc->sc_ifa, &sc->sc_smpls);
>                       if (error != 0) {
>                               sc->sc_smpls.smpls_label = 0;
>                               break;
> Index: netmpls/mpls.h
> ===================================================================
> RCS file: /cvs/src/sys/netmpls/mpls.h,v
> retrieving revision 1.42
> diff -u -p -r1.42 mpls.h
> --- netmpls/mpls.h    30 Jan 2019 01:01:01 -0000      1.42
> +++ netmpls/mpls.h    30 Jan 2019 01:40:47 -0000
> @@ -177,4 +177,7 @@ int                mpls_output(struct ifnet *, struct
>                   struct rtentry *);
> void           mpls_input(struct ifnet *, struct mbuf *);
> 
> +int           mpls_ifa_add(struct ifaddr *, struct sockaddr_mpls *);
> +int           mpls_ifa_del(struct ifaddr *, struct sockaddr_mpls *);
> +
> #endif /* _KERNEL */
> Index: netmpls/mpls_input.c
> ===================================================================
> RCS file: /cvs/src/sys/netmpls/mpls_input.c,v
> retrieving revision 1.74
> diff -u -p -r1.74 mpls_input.c
> --- netmpls/mpls_input.c      29 Jan 2019 23:36:35 -0000      1.74
> +++ netmpls/mpls_input.c      30 Jan 2019 01:40:47 -0000
> @@ -299,6 +299,66 @@ mpls_input_local(struct rtentry *rt, str
>       if_put(ifp);
> }
> 
> +int
> +mpls_ifa_add(struct ifaddr *ifa, struct sockaddr_mpls *dst)
> +{
> +     struct rt_addrinfo info;
> +     struct sockaddr_rtlabel sa_rl;
> +     unsigned int rtableid = 0;
> +     struct ifnet *ifp = ifa->ifa_ifp;
> +     struct rtentry *rt;
> +     int error;
> +
> +     memset(&info, 0, sizeof(info));
> +     info.rti_ifa = ifa;
> +     info.rti_flags = RTF_LOCAL | RTF_MPLS;
> +     info.rti_info[RTAX_DST] = smplstosa(dst);
> +     info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
> +     info.rti_info[RTAX_LABEL] = rtlabel_id2sa(ifp->if_rtlabelid, &sa_rl);
> +     info.rti_mpls = MPLS_OP_POP;
> +
> +     error = rtrequest(RTM_ADD, &info, RTP_LOCAL, &rt, rtableid);
> +     if (error == 0) {
> +             /*
> +              * XXX nothing in userland seems to care about MPLS routes,
> +              * so don't bother sending messages like rt_ifa_add does.
> +              */
> +             rtfree(rt);
> +     }
> +
> +     return (error);
> +}
> +
> +int
> +mpls_ifa_del(struct ifaddr *ifa, struct sockaddr_mpls *dst)
> +{
> +     struct rt_addrinfo info;
> +     struct sockaddr_rtlabel sa_rl;
> +     unsigned int rtableid = 0;
> +     struct ifnet *ifp = ifa->ifa_ifp;
> +     struct rtentry *rt;
> +     int error;
> +
> +     memset(&info, 0, sizeof(info));
> +     info.rti_ifa = ifa;
> +     info.rti_flags = RTF_LOCAL | RTF_MPLS;
> +     info.rti_info[RTAX_DST] = smplstosa(dst);
> +     info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
> +     info.rti_info[RTAX_LABEL] = rtlabel_id2sa(ifp->if_rtlabelid, &sa_rl);
> +     info.rti_mpls = MPLS_OP_POP;
> +
> +     error = rtrequest_delete(&info, RTP_LOCAL, ifp, &rt, rtableid);
> +     if (error == 0) {
> +             /*
> +              * XXX nothing in userland seems to care about MPLS routes,
> +              * so don't bother sending messages like rt_ifa_del does.
> +              */
> +             rtfree(rt);
> +     }
> +
> +     return (error);
> +}
> +
> struct mbuf *
> mpls_ip_adjttl(struct mbuf *m, u_int8_t ttl)
> {

Reply via email to