summaryrefslogtreecommitdiffstats
path: root/sys/net/rtsock.c
diff options
context:
space:
mode:
authormelifaro <melifaro@FreeBSD.org>2014-01-04 22:25:26 +0000
committermelifaro <melifaro@FreeBSD.org>2014-01-04 22:25:26 +0000
commitf85abe95558065229851d77464b1b080e8b7388a (patch)
tree30ad6ec1053ace25e1f08c9626c9844194354f00 /sys/net/rtsock.c
parentb03757c0c6594aac65b51957fe1b1c9f55f84fe5 (diff)
downloadFreeBSD-src-f85abe95558065229851d77464b1b080e8b7388a.zip
FreeBSD-src-f85abe95558065229851d77464b1b080e8b7388a.tar.gz
Change semantics for rnh_lookup() function: now
it performs exact match search, regardless of netmask existance. This simplifies most of rnh_lookup() consumers. Fix panic triggered by deleting non-existent host route. PR: kern/185092 Submitted by: Nikolay Denev <ndenev at gmail.com> MFC after: 1 month
Diffstat (limited to 'sys/net/rtsock.c')
-rw-r--r--sys/net/rtsock.c39
1 files changed, 17 insertions, 22 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index e7d1d99..50b7f0d 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -727,10 +727,24 @@ route_output(struct mbuf *m, struct socket *so)
info.rti_info[RTAX_DST]->sa_family);
if (rnh == NULL)
senderr(EAFNOSUPPORT);
+
RADIX_NODE_HEAD_RLOCK(rnh);
- rt = (struct rtentry *) rnh->rnh_lookup(info.rti_info[RTAX_DST],
- info.rti_info[RTAX_NETMASK], rnh);
- if (rt == NULL) { /* XXX looks bogus */
+
+ if (info.rti_info[RTAX_NETMASK] == NULL &&
+ rtm->rtm_type == RTM_GET) {
+ /*
+ * Provide logest prefix match for
+ * address lookup (no mask).
+ * 'route -n get addr'
+ */
+ rt = (struct rtentry *) rnh->rnh_matchaddr(
+ info.rti_info[RTAX_DST], rnh);
+ } else
+ rt = (struct rtentry *) rnh->rnh_lookup(
+ info.rti_info[RTAX_DST],
+ info.rti_info[RTAX_NETMASK], rnh);
+
+ if (rt == NULL) {
RADIX_NODE_HEAD_RUNLOCK(rnh);
senderr(ESRCH);
}
@@ -787,25 +801,6 @@ route_output(struct mbuf *m, struct socket *so)
RT_ADDREF(rt);
RADIX_NODE_HEAD_RUNLOCK(rnh);
- /*
- * Fix for PR: 82974
- *
- * 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 netmask. If both have a netmask
- * rnh_lookup() did a perfect match and if none of them
- * have a netmask both are host routes which is also a
- * perfect match.
- */
-
- if (rtm->rtm_type != RTM_GET &&
- (!rt_mask(rt) != !info.rti_info[RTAX_NETMASK])) {
- RT_UNLOCK(rt);
- senderr(ESRCH);
- }
-
switch(rtm->rtm_type) {
case RTM_GET:
OpenPOWER on IntegriCloud