summaryrefslogtreecommitdiff
path: root/sys/netinet/ip_output.c
diff options
context:
space:
mode:
authorStuart Henderson <sthen@cvs.openbsd.org>2014-03-28 08:33:52 +0000
committerStuart Henderson <sthen@cvs.openbsd.org>2014-03-28 08:33:52 +0000
commit0a90147190d373b5095c738f1ca6b109b7f20e9c (patch)
tree7340b37510a26dad27eb4511e3a67b14033a1771 /sys/netinet/ip_output.c
parente2859ce1d1ec8b4a84b0441c6013497cc514ac6e (diff)
revert "Retire kernel support for SO_DONTROUTE" diff, which does bad things
for localhost connections. discussed with deraadt@
Diffstat (limited to 'sys/netinet/ip_output.c')
-rw-r--r--sys/netinet/ip_output.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 6d490bc5700..03a6a782028 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_output.c,v 1.258 2014/03/27 13:27:28 mpi Exp $ */
+/* $OpenBSD: ip_output.c,v 1.259 2014/03/28 08:33:51 sthen Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@@ -194,7 +194,23 @@ ip_output(struct mbuf *m0, struct mbuf *opt, struct route *ro, int flags,
ro->ro_tableid = m->m_pkthdr.rdomain;
}
- if ((IN_MULTICAST(ip->ip_dst.s_addr) ||
+ /*
+ * If routing to interface only, short-circuit routing lookup.
+ */
+ if (flags & IP_ROUTETOIF) {
+ if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst),
+ m->m_pkthdr.rdomain))) == 0 &&
+ (ia = ifatoia(ifa_ifwithnet(sintosa(dst),
+ m->m_pkthdr.rdomain))) == 0) {
+ ipstat.ips_noroute++;
+ error = ENETUNREACH;
+ goto bad;
+ }
+
+ ifp = ia->ia_ifp;
+ mtu = ifp->if_mtu;
+ ip->ip_ttl = 1;
+ } else if ((IN_MULTICAST(ip->ip_dst.s_addr) ||
(ip->ip_dst.s_addr == INADDR_BROADCAST)) &&
imo != NULL && imo->imo_multicast_ifp != NULL) {
ifp = imo->imo_multicast_ifp;
@@ -344,7 +360,23 @@ reroute:
ro->ro_tableid = m->m_pkthdr.rdomain;
}
- if ((IN_MULTICAST(ip->ip_dst.s_addr) ||
+ /*
+ * If routing to interface only, short-circuit routing lookup.
+ */
+ if (flags & IP_ROUTETOIF) {
+ if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst),
+ m->m_pkthdr.rdomain))) == 0 &&
+ (ia = ifatoia(ifa_ifwithnet(sintosa(dst),
+ m->m_pkthdr.rdomain))) == 0) {
+ ipstat.ips_noroute++;
+ error = ENETUNREACH;
+ goto bad;
+ }
+
+ ifp = ia->ia_ifp;
+ mtu = ifp->if_mtu;
+ ip->ip_ttl = 1;
+ } else if ((IN_MULTICAST(ip->ip_dst.s_addr) ||
(ip->ip_dst.s_addr == INADDR_BROADCAST)) &&
imo != NULL && imo->imo_multicast_ifp != NULL) {
ifp = imo->imo_multicast_ifp;
@@ -720,7 +752,7 @@ sendit:
ipstat.ips_fragmented++;
done:
- if (ro == &iproute && ro->ro_rt)
+ if (ro == &iproute && (flags & IP_ROUTETOIF) == 0 && ro->ro_rt)
RTFREE(ro->ro_rt);
return (error);
bad: