Module Name: src Committed By: ozaki-r Date: Thu Jul 21 03:45:56 UTC 2016
Modified Files: src/sys/net: rtsock.c Log Message: Make complex RTM_CHANGE code understandable Tests for route change added recently would reduce the possibility of regressions. Reviewed by ryo@ To generate a diff of this commit: cvs rdiff -u -r1.191 -r1.192 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.191 src/sys/net/rtsock.c:1.192 --- src/sys/net/rtsock.c:1.191 Thu Jul 7 09:32:02 2016 +++ src/sys/net/rtsock.c Thu Jul 21 03:45:56 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: rtsock.c,v 1.191 2016/07/07 09:32:02 ozaki-r Exp $ */ +/* $NetBSD: rtsock.c,v 1.192 2016/07/21 03:45:56 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.191 2016/07/07 09:32:02 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.192 2016/07/21 03:45:56 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -539,6 +539,53 @@ route_output_report(struct rtentry *rt, return 0; } +static struct ifaddr * +route_output_get_ifa(const struct rt_addrinfo info, const struct rtentry *rt, + struct ifnet **ifp) +{ + struct ifaddr *ifa = NULL; + + *ifp = NULL; + if (info.rti_info[RTAX_IFP] != NULL) { + ifa = ifa_ifwithnet(info.rti_info[RTAX_IFP]); + if (ifa == NULL) + goto next; + *ifp = ifa->ifa_ifp; + if (info.rti_info[RTAX_IFA] == NULL && + info.rti_info[RTAX_GATEWAY] == NULL) + goto next; + if (info.rti_info[RTAX_IFA] == NULL) { + /* route change <dst> <gw> -ifp <if> */ + ifa = ifaof_ifpforaddr(info.rti_info[RTAX_GATEWAY], + *ifp); + } else { + /* route change <dst> -ifp <if> -ifa <addr> */ + ifa = ifa_ifwithaddr(info.rti_info[RTAX_IFA]); + if (ifa != NULL) + goto out; + ifa = ifaof_ifpforaddr(info.rti_info[RTAX_IFA], + *ifp); + } + goto out; + } +next: + if (info.rti_info[RTAX_IFA] != NULL) { + /* route change <dst> <gw> -ifa <addr> */ + ifa = ifa_ifwithaddr(info.rti_info[RTAX_IFA]); + if (ifa != NULL) + goto out; + } + if (info.rti_info[RTAX_GATEWAY] != NULL) { + /* route change <dst> <gw> */ + ifa = ifa_ifwithroute(rt->rt_flags, rt_getkey(rt), + info.rti_info[RTAX_GATEWAY]); + } +out: + if (ifa != NULL && *ifp == NULL) + *ifp = ifa->ifa_ifp; + return ifa; +} + /*ARGSUSED*/ int COMPATNAME(route_output)(struct mbuf *m, struct socket *so) @@ -783,24 +830,7 @@ COMPATNAME(route_output)(struct mbuf *m, /* new gateway could require new ifaddr, ifp; flags may also be different; ifp may be specified by ll sockaddr when protocol address is ambiguous */ - if (info.rti_info[RTAX_IFP] && - (ifa = ifa_ifwithnet(info.rti_info[RTAX_IFP])) && - (ifp = ifa->ifa_ifp) && (info.rti_info[RTAX_IFA] || - info.rti_info[RTAX_GATEWAY])) { - if (info.rti_info[RTAX_IFA] == NULL || - (ifa = ifa_ifwithaddr( - info.rti_info[RTAX_IFA])) == NULL) - ifa = ifaof_ifpforaddr( - info.rti_info[RTAX_IFA] ? - info.rti_info[RTAX_IFA] : - info.rti_info[RTAX_GATEWAY], ifp); - } else if ((info.rti_info[RTAX_IFA] && - (ifa = ifa_ifwithaddr(info.rti_info[RTAX_IFA]))) || - (info.rti_info[RTAX_GATEWAY] && - (ifa = ifa_ifwithroute(rt->rt_flags, - rt_getkey(rt), info.rti_info[RTAX_GATEWAY])))) { - ifp = ifa->ifa_ifp; - } + ifa = route_output_get_ifa(info, rt, &ifp); if (ifa) { struct ifaddr *oifa = rt->rt_ifa; if (oifa != ifa) {