On Sat, Oct 04, 2014 at 07:39:03PM -0300, Rafael Zalamena wrote: > 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 changed: * Replaced old function that used to create routes in favor of rt_ifa_* * Modified rt_ifa_{add,del} to handle MPLS addresses: when creating an route to a MPLS interface it means we want to remove labels. Also MPLS only works on rdomain 0 Here is the new diff based on mpi@ feedback: Index: sys/net/if_mpe.c =================================================================== RCS file: /cvs/src/sys/net/if_mpe.c,v retrieving revision 1.35 diff -u -p -r1.35 if_mpe.c --- sys/net/if_mpe.c 22 Jul 2014 11:06:09 -0000 1.35 +++ sys/net/if_mpe.c 7 Oct 2014 21:24:47 -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 = @@ -280,6 +279,7 @@ mpeioctl(struct ifnet *ifp, u_long cmd, int error; struct mpe_softc *ifm; struct ifreq *ifr; + struct sockaddr_mpls smpls; struct shim_hdr shim; ifr = (struct ifreq *)data; @@ -331,12 +331,19 @@ mpeioctl(struct ifnet *ifp, u_long cmd, if (error) break; ifm = ifp->if_softc; + memset(&smpls, 0, sizeof(smpls)); + smpls.smpls_family = AF_MPLS; + smpls.smpls_len = sizeof(smpls); if (ifm->sc_shim.shim_label) { /* remove old MPLS route */ - mpe_newlabel(ifp, RTM_DELETE, &ifm->sc_shim); + smpls.smpls_label = ifm->sc_shim.shim_label; + rt_ifa_del(ifp->if_lladdr, RTF_MPLS | RTF_UP, + smplstosa(&smpls)); } /* add new MPLS route */ - error = mpe_newlabel(ifp, RTM_ADD, &shim); + smpls.smpls_label = shim.shim_label; + error = rt_ifa_add(ifp->if_lladdr, RTF_MPLS | RTF_UP, + smplstosa(&smpls)); if (error) break; ifm->sc_shim.shim_label = shim.shim_label; @@ -346,8 +353,12 @@ mpeioctl(struct ifnet *ifp, u_long cmd, ifm = ifp->if_softc; 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); + memset(&smpls, 0, sizeof(smpls)); + smpls.smpls_label = ifm->sc_shim.shim_label; + smpls.smpls_family = AF_MPLS; + smpls.smpls_len = sizeof(smpls); + error = rt_ifa_add(ifp->if_lladdr, + RTF_MPLS | RTF_UP, smplstosa(&smpls)); } } /* return with ENOTTY so that the parent handler finishes */ @@ -442,38 +453,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: sys/net/route.c =================================================================== RCS file: /cvs/src/sys/net/route.c,v retrieving revision 1.185 diff -u -p -r1.185 route.c --- sys/net/route.c 2 Oct 2014 12:21:20 -0000 1.185 +++ sys/net/route.c 7 Oct 2014 21:24:47 -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);