diff options
Diffstat (limited to 'sys/net/rtsock.c')
-rw-r--r-- | sys/net/rtsock.c | 35 |
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) { |