diff options
author | melifaro <melifaro@FreeBSD.org> | 2014-05-08 20:27:06 +0000 |
---|---|---|
committer | melifaro <melifaro@FreeBSD.org> | 2014-05-08 20:27:06 +0000 |
commit | d42ec49fe7376d5d77807fe648fe0af085a8b7ac (patch) | |
tree | 2b9dc36affbd402921b8538bc5e6fb2d6af7fa79 /sys/net/rtsock.c | |
parent | 0576e440912c1dc60e93e505b337ba5ce6f23148 (diff) | |
download | FreeBSD-src-d42ec49fe7376d5d77807fe648fe0af085a8b7ac.zip FreeBSD-src-d42ec49fe7376d5d77807fe648fe0af085a8b7ac.tar.gz |
Merge r259528, r259528, r260295.
r259528:
Simplify contiguous mask checking.
Suggested by: glebius
r260228:
Remove useless register variable modifiers.
Do some more style(9).
r260295:
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>
Diffstat (limited to 'sys/net/rtsock.c')
-rw-r--r-- | sys/net/rtsock.c | 39 |
1 files changed, 17 insertions, 22 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index bacd393..af51ac6 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -725,10 +725,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); } @@ -785,25 +799,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: |