diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2014-05-31 15:36:45 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2014-05-31 15:36:45 +0000 |
commit | 1aaf3db45a67e7a69d7549ded06c8433dfae0995 (patch) | |
tree | 7e3ed9461464ed863b2ff21fc2ab83454fe509e9 /sys/net/rtsock.c | |
parent | 5f8f3ee1b99e66325a7cf50d9fab9ea7d4c44fbf (diff) |
Unbreak RTM_CHANGE. Unlike RTM_LOCK or RTM_GET it is OK to pass in a
new gateway for RTM_CHANGE if the route is not a multipath route.
Fixes issues found by benno@, OK benno@
Diffstat (limited to 'sys/net/rtsock.c')
-rw-r--r-- | sys/net/rtsock.c | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 017ac635149..88e3904016a 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtsock.c,v 1.146 2014/05/27 19:38:15 claudio Exp $ */ +/* $OpenBSD: rtsock.c,v 1.147 2014/05/31 15:36:44 claudio Exp $ */ /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ /* @@ -619,31 +619,40 @@ route_output(struct mbuf *m, ...) goto flush; } #ifndef SMALL_KERNEL - /* - * for RTM_CHANGE/LOCK, if we got multipath routes, - * we require users to specify a matching RTAX_GATEWAY. - * - * for RTM_GET, info.rti_info[RTAX_GATEWAY] is optional - * even with multipath. - */ if (rn_mpath_capable(rnh)) { - rt = rt_mpath_matchgate(rt, - info.rti_info[RTAX_GATEWAY], prio); + /* first find the right priority */ + rt = rt_mpath_matchgate(rt, NULL, prio); if (!rt) { error = ESRCH; goto flush; } - /* - * only RTM_GET may use an empty gateway - * on multipath routes + * For RTM_CHANGE/LOCK, if we got multipath routes, + * a matching RTAX_GATEWAY is required. + * OR + * If a gateway is specified then RTM_GET and + * RTM_LOCK must match the gateway no matter + * what even in the non multipath case. */ - if (!info.rti_info[RTAX_GATEWAY] && - rt->rt_flags & RTF_MPATH && - rtm->rtm_type != RTM_GET) { - rt = NULL; - error = ESRCH; - goto flush; + if ((rt->rt_flags & RTF_MPATH) || + (info.rti_info[RTAX_GATEWAY] && rtm->rtm_type != + RTM_CHANGE)) { + rt = rt_mpath_matchgate(rt, + info.rti_info[RTAX_GATEWAY], prio); + if (!rt) { + error = ESRCH; + goto flush; + } + /* + * only RTM_GET may use an empty gateway + * on multipath routes + */ + if (!info.rti_info[RTAX_GATEWAY] && + rtm->rtm_type != RTM_GET) { + rt = NULL; + error = ESRCH; + goto flush; + } } rn = (struct radix_node *)rt; } |