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