diff options
author | qingli <qingli@FreeBSD.org> | 2013-06-25 00:10:49 +0000 |
---|---|---|
committer | qingli <qingli@FreeBSD.org> | 2013-06-25 00:10:49 +0000 |
commit | 2160365ab5c063efe55ccfd0d3879669e3f26170 (patch) | |
tree | 7aa10a9ada51cdb348b341252da27d8c72eb1c13 /sys/net | |
parent | ac847054f7eaa1e775d5102eace816afbbf9daae (diff) | |
download | FreeBSD-src-2160365ab5c063efe55ccfd0d3879669e3f26170.zip FreeBSD-src-2160365ab5c063efe55ccfd0d3879669e3f26170.tar.gz |
Due to the routing related networking kernel redesign work
in FBSD 8.0, interface routes have been returened to the
applications without the RTF_GATEWAY bit. This incompatibility
has caused some issues with Zebra, Qugga and the like.
This patch provides the RTF_GATEWAY flag bit in returned interface
routes so to behave similarly to pre 8.0 systems.
Reviewed by: hrs
Verified by: mackn at opendns dot com
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/route.h | 3 | ||||
-rw-r--r-- | sys/net/rtsock.c | 17 |
2 files changed, 17 insertions, 3 deletions
diff --git a/sys/net/route.h b/sys/net/route.h index 997f3cd..02d0ae9 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -185,6 +185,9 @@ struct ortentry { #define RTF_RNH_LOCKED 0x40000000 /* radix node head is locked */ +#define RTF_GWFLAG_COMPAT 0x80000000 /* a compatibility bit for interacting + with existing routing apps */ + /* Mask of RTF flags that are allowed to be modified by RTM_CHANGE. */ #define RTF_FMASK \ (RTF_PROTO1 | RTF_PROTO2 | RTF_PROTO3 | RTF_BLACKHOLE | \ diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index c3781d5..d665280 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -652,8 +652,10 @@ route_output(struct mbuf *m, struct socket *so) */ if (gw_ro.ro_rt != NULL && gw_ro.ro_rt->rt_gateway->sa_family == AF_LINK && - gw_ro.ro_rt->rt_ifp->if_flags & IFF_LOOPBACK) + gw_ro.ro_rt->rt_ifp->if_flags & IFF_LOOPBACK) { info.rti_flags &= ~RTF_GATEWAY; + info.rti_flags |= RTF_GWFLAG_COMPAT; + } if (gw_ro.ro_rt != NULL) RTFREE(gw_ro.ro_rt); } @@ -853,7 +855,11 @@ route_output(struct mbuf *m, struct socket *so) Free(rtm); rtm = new_rtm; } (void)rt_msg2(rtm->rtm_type, &info, (caddr_t)rtm, NULL); - rtm->rtm_flags = rt->rt_flags; + if (rt->rt_flags & RTF_GWFLAG_COMPAT) + rtm->rtm_flags = RTF_GATEWAY | + (rt->rt_flags & ~RTF_GWFLAG_COMPAT); + else + rtm->rtm_flags = rt->rt_flags; rt_getmetrics(&rt->rt_rmx, &rtm->rtm_rmx); rtm->rtm_addrs = info.rti_addrs; break; @@ -905,6 +911,7 @@ route_output(struct mbuf *m, struct socket *so) RT_UNLOCK(rt); senderr(error); } + rt->rt_flags &= ~RTF_GATEWAY; rt->rt_flags |= (RTF_GATEWAY & info.rti_flags); } if (info.rti_ifa != NULL && @@ -1591,7 +1598,11 @@ sysctl_dumpentry(struct radix_node *rn, void *vw) if (w->w_req && w->w_tmem) { struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem; - rtm->rtm_flags = rt->rt_flags; + if (rt->rt_flags & RTF_GWFLAG_COMPAT) + rtm->rtm_flags = RTF_GATEWAY | + (rt->rt_flags & ~RTF_GWFLAG_COMPAT); + else + rtm->rtm_flags = rt->rt_flags; /* * let's be honest about this being a retarded hack */ |