Module Name: src Committed By: ozaki-r Date: Wed Oct 26 06:49:10 UTC 2016
Modified Files: src/sys/net: rtsock.c Log Message: Pull RTM_CHANGE code out of route_output to make further changes easy No functional change. To generate a diff of this commit: cvs rdiff -u -r1.197 -r1.198 src/sys/net/rtsock.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/rtsock.c diff -u src/sys/net/rtsock.c:1.197 src/sys/net/rtsock.c:1.198 --- src/sys/net/rtsock.c:1.197 Mon Oct 3 11:06:06 2016 +++ src/sys/net/rtsock.c Wed Oct 26 06:49:10 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: rtsock.c,v 1.197 2016/10/03 11:06:06 ozaki-r Exp $ */ +/* $NetBSD: rtsock.c,v 1.198 2016/10/26 06:49:10 ozaki-r Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.197 2016/10/03 11:06:06 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.198 2016/10/26 06:49:10 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -593,6 +593,73 @@ out: return ifa; } +static int +route_output_change(struct rtentry *rt, struct rt_addrinfo *info, + struct rt_xmsghdr *rtm) +{ + int error = 0; + struct ifnet *ifp, *new_ifp; + struct ifaddr *ifa, *new_ifa; + struct psref psref_ifa, psref_new_ifa, psref_ifp; + + /* + * new gateway could require new ifaddr, ifp; + * flags may also be different; ifp may be specified + * by ll sockaddr when protocol address is ambiguous + */ + ifp = rt_getifp(info, &psref_ifp); + ifa = rt_getifa(info, &psref_ifa); + if (ifa == NULL) { + error = ENETUNREACH; + goto out; + } + if (info->rti_info[RTAX_GATEWAY]) { + error = rt_setgate(rt, info->rti_info[RTAX_GATEWAY]); + if (error != 0) + goto out; + } + if (info->rti_info[RTAX_TAG]) { + const struct sockaddr *tag; + tag = rt_settag(rt, info->rti_info[RTAX_TAG]); + if (tag == NULL) { + error = ENOBUFS; + goto out; + } + } + /* new gateway could require new ifaddr, ifp; + flags may also be different; ifp may be specified + by ll sockaddr when protocol address is ambiguous */ + new_ifa = route_output_get_ifa(*info, rt, &new_ifp, &psref_new_ifa); + if (new_ifa != NULL) { + ifa_release(ifa, &psref_ifa); + ifa = new_ifa; + } + if (ifa) { + struct ifaddr *oifa = rt->rt_ifa; + if (oifa != ifa) { + if (oifa && oifa->ifa_rtrequest) + oifa->ifa_rtrequest(RTM_DELETE, rt, info); + rt_replace_ifa(rt, ifa); + rt->rt_ifp = new_ifp; + } + if (new_ifa == NULL) + ifa_release(ifa, &psref_ifa); + } + ifa_release(new_ifa, &psref_new_ifa); + if (new_ifp && rt->rt_ifp != new_ifp) + rt->rt_ifp = new_ifp; + rt_setmetrics(rtm->rtm_inits, rtm, rt); + if (rt->rt_flags != info->rti_flags) + rt->rt_flags = (info->rti_flags & ~PRESERVED_RTF) + | (rt->rt_flags & PRESERVED_RTF); + if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest) + rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, info); +out: + if_put(ifp, &psref_ifp); + + return error; +} + /*ARGSUSED*/ int COMPATNAME(route_output)(struct mbuf *m, struct socket *so) @@ -604,11 +671,8 @@ COMPATNAME(route_output)(struct mbuf *m, struct rtentry *saved_nrt = NULL; struct rt_addrinfo info; int len, error = 0; - struct ifnet *ifp = NULL; - struct ifaddr *ifa = NULL; sa_family_t family; struct sockaddr_dl sdl; - struct psref psref; int bound = curlwp_bind(); #define senderr(e) do { error = e; goto flush;} while (/*CONSTCOND*/ 0) @@ -818,70 +882,11 @@ COMPATNAME(route_output)(struct mbuf *m, } break; - case RTM_CHANGE: { - struct ifnet *_ifp; - struct ifaddr *_ifa; - struct psref _psref, psref_ifp; - /* - * new gateway could require new ifaddr, ifp; - * flags may also be different; ifp may be specified - * by ll sockaddr when protocol address is ambiguous - */ - _ifp = rt_getifp(&info, &psref_ifp); - ifa = rt_getifa(&info, &psref); - if (ifa == NULL) { - if_put(_ifp, &psref_ifp); - senderr(ENETUNREACH); - } - if (info.rti_info[RTAX_GATEWAY]) { - error = rt_setgate(rt, - info.rti_info[RTAX_GATEWAY]); - if (error != 0) { - if_put(_ifp, &psref_ifp); - senderr(error); - } - } - if (info.rti_info[RTAX_TAG]) { - const struct sockaddr *tag; - tag = rt_settag(rt, info.rti_info[RTAX_TAG]); - if (tag == NULL) { - if_put(_ifp, &psref_ifp); - senderr(ENOBUFS); - } - } - /* new gateway could require new ifaddr, ifp; - flags may also be different; ifp may be specified - by ll sockaddr when protocol address is ambiguous */ - _ifa = route_output_get_ifa(info, rt, &ifp, &_psref); - if (_ifa != NULL) { - ifa_release(ifa, &psref); - ifa = _ifa; - } - if (ifa) { - struct ifaddr *oifa = rt->rt_ifa; - if (oifa != ifa) { - if (oifa && oifa->ifa_rtrequest) { - oifa->ifa_rtrequest(RTM_DELETE, - rt, &info); - } - rt_replace_ifa(rt, ifa); - rt->rt_ifp = ifp; - } - if (_ifa == NULL) - ifa_release(ifa, &psref); - } - ifa_release(_ifa, &_psref); - if (ifp && rt->rt_ifp != ifp) - rt->rt_ifp = ifp; - rt_setmetrics(rtm->rtm_inits, rtm, rt); - if (rt->rt_flags != info.rti_flags) - rt->rt_flags = (info.rti_flags & ~PRESERVED_RTF) - | (rt->rt_flags & PRESERVED_RTF); - if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest) - rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, &info); - if_put(_ifp, &psref_ifp); + case RTM_CHANGE: + error = route_output_change(rt, &info, rtm); + if (error != 0) + goto flush; /*FALLTHROUGH*/ - } case RTM_LOCK: rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits); rt->rt_rmx.rmx_locks |=