summaryrefslogtreecommitdiffstats
path: root/sys/net/rtsock.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net/rtsock.c')
-rw-r--r--sys/net/rtsock.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 8fb8899..e48ab90 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -513,6 +513,39 @@ route_output(struct mbuf *m, struct socket *so)
senderr(error);
}
+ /*
+ * The given gateway address may be an interface address.
+ * For example, issuing a "route change" command on a route
+ * entry that was created from a tunnel, and the gateway
+ * address given is the local end point. In this case the
+ * RTF_GATEWAY flag must be cleared or the destination will
+ * not be reachable even though there is no error message.
+ */
+ if (info.rti_info[RTAX_GATEWAY] != NULL &&
+ info.rti_info[RTAX_GATEWAY]->sa_family != AF_LINK) {
+ struct route gw_ro;
+
+ bzero(&gw_ro, sizeof(gw_ro));
+ gw_ro.ro_dst = *info.rti_info[RTAX_GATEWAY];
+ rtalloc_ign(&gw_ro, 0);
+ /*
+ * A host route through the loopback interface is
+ * installed for each interface adddress. In pre 8.0
+ * releases the interface address of a PPP link type
+ * is not reachable locally. This behavior is fixed as
+ * part of the new L2/L3 redesign and rewrite work. The
+ * signature of this interface address route is the
+ * AF_LINK sa_family type of the rt_gateway, and the
+ * rt_ifp has the IFF_LOOPBACK flag set.
+ */
+ 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)
+ info.rti_flags &= ~RTF_GATEWAY;
+ if (gw_ro.ro_rt != NULL)
+ RTFREE(gw_ro.ro_rt);
+ }
+
switch (rtm->rtm_type) {
struct rtentry *saved_nrt;
@@ -714,7 +747,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 &&
info.rti_ifa != rt->rt_ifa) {
OpenPOWER on IntegriCloud