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