summaryrefslogtreecommitdiff
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 c55bf82fae2..fce8e94dc74 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.35 2004/01/15 10:47:55 markus Exp $ */
+/* $OpenBSD: rtsock.c,v 1.36 2004/04/25 02:48:04 itojun Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -270,7 +270,40 @@ route_output(struct mbuf *m, ...)
senderr(ESRCH);
}
rt = (struct rtentry *)rn;
+#ifndef SMALL_KERNEL
+ /*
+ * for RTM_CHANGE/LOCK, if we got multipath routes,
+ * we require users to specify a matching RTAX_GATEWAY.
+ *
+ * for RTM_GET, gate is optional even with multipath.
+ * if gate == NULL the first match is returned.
+ * (no need to call rt_mpath_matchgate if gate == NULL)
+ */
+ if (rn_mpath_capable(rnh) &&
+ (rtm->rtm_type != RTM_GET || gate)) {
+ rt = rt_mpath_matchgate(rt, gate);
+ rn = (struct radix_node *)rt;
+ if (!rt)
+ senderr(ESRCH);
+ }
+#endif
rt->rt_refcnt++;
+ if (rtm->rtm_type != RTM_GET) {/* XXX: too grotty */
+ struct radix_node *rn;
+ extern struct radix_node_head *mask_rnhead;
+
+ if (Bcmp(dst, rt_key(rt), dst->sa_len) != 0)
+ senderr(ESRCH);
+ if (netmask && (rn = rn_search(netmask,
+ mask_rnhead->rnh_treetop)))
+ netmask = (struct sockaddr *)rn->rn_key;
+ for (rn = rt->rt_nodes; rn; rn = rn->rn_dupedkey)
+ if (netmask == (struct sockaddr *)rn->rn_mask)
+ break;
+ if (rn == 0)
+ senderr(ETOOMANYREFS);
+ rt = (struct rtentry *)rn;
+ }
switch (rtm->rtm_type) {