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) {