summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2004-05-12 20:46:01 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2004-05-12 20:46:01 +0000
commitec1f4fc688d987c44082155eb8f93034a01f5f05 (patch)
tree7e8675ba167125090aea880e8f89178f4e52cab4 /sys/net
parent13bc29123d055e43eda691bb0abd981e5ec82904 (diff)
Rework a block readded by the multipath commit that should ensure that
RTM_CHANGE/LOCK only work on perfect matching routes. ppp and bgpd got broken because of this. Most of the code in the "grotty" block is already done by rn_lookup() only host routes need some special treatment. OK cedric@
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/rtsock.c43
1 files changed, 19 insertions, 24 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index d0866800614..7b64447eebe 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.37 2004/05/04 22:50:18 claudio Exp $ */
+/* $OpenBSD: rtsock.c,v 1.38 2004/05/12 20:46:00 claudio Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -240,14 +240,6 @@ route_output(struct mbuf *m, ...)
senderr(EACCES);
switch (rtm->rtm_type) {
- case RTM_DELETE:
- error = rtrequest1(rtm->rtm_type, &info, &saved_nrt);
- if (error == 0) {
- (rt = saved_nrt)->rt_refcnt++;
- goto report;
- }
- break;
-
case RTM_ADD:
if (gate == 0)
senderr(EINVAL);
@@ -258,7 +250,14 @@ route_output(struct mbuf *m, ...)
saved_nrt->rt_refcnt--;
saved_nrt->rt_genmask = genmask;
}
- /* FALLTHROUGH */
+ break;
+ case RTM_DELETE:
+ error = rtrequest1(rtm->rtm_type, &info, &saved_nrt);
+ if (error == 0) {
+ (rt = saved_nrt)->rt_refcnt++;
+ goto report;
+ }
+ break;
case RTM_GET:
case RTM_CHANGE:
case RTM_LOCK:
@@ -288,21 +287,18 @@ route_output(struct mbuf *m, ...)
}
#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)
+ /*
+ * RTM_CHANGE/LOCK need a perfect match, rn_lookup()
+ * returns a perfect match in case a netmask is specified.
+ * For host routes only a longest prefix match is returned
+ * so it is necessary to compare the existence of the netmaks.
+ * If both have a netmask rn_lookup() did a perfect match and
+ * if non of them have a netmask both are host routes which is
+ * also a perfect match.
+ */
+ if (rtm->rtm_type != RTM_GET && !rt_mask(rt) != !netmask) {
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) {
@@ -384,7 +380,6 @@ route_output(struct mbuf *m, ...)
/*
* Fall into
*/
- case RTM_ADD:
case RTM_LOCK:
rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits);
rt->rt_rmx.rmx_locks |=