Module Name: src
Committed By: roy
Date: Mon Apr 20 10:19:54 UTC 2015
Modified Files:
src/sys/net: if.c if.h if_gif.c if_gre.c if_ppp.c if_spppsubr.c
if_tun.c
src/sys/netinet6: in6.c
Log Message:
Introduce p2p_rtrequest() so that IFF_POINTOPOINT interfaces can work
with RTF_LOCAL.
Fixes PR kern/49829.
To generate a diff of this commit:
cvs rdiff -u -r1.309 -r1.310 src/sys/net/if.c
cvs rdiff -u -r1.187 -r1.188 src/sys/net/if.h
cvs rdiff -u -r1.83 -r1.84 src/sys/net/if_gif.c
cvs rdiff -u -r1.162 -r1.163 src/sys/net/if_gre.c
cvs rdiff -u -r1.146 -r1.147 src/sys/net/if_ppp.c
cvs rdiff -u -r1.131 -r1.132 src/sys/net/if_spppsubr.c
cvs rdiff -u -r1.120 -r1.121 src/sys/net/if_tun.c
cvs rdiff -u -r1.186 -r1.187 src/sys/netinet6/in6.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/if.c
diff -u src/sys/net/if.c:1.309 src/sys/net/if.c:1.310
--- src/sys/net/if.c:1.309 Tue Apr 7 23:30:36 2015
+++ src/sys/net/if.c Mon Apr 20 10:19:54 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: if.c,v 1.309 2015/04/07 23:30:36 roy Exp $ */
+/* $NetBSD: if.c,v 1.310 2015/04/20 10:19:54 roy Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.309 2015/04/07 23:30:36 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.310 2015/04/20 10:19:54 roy Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@@ -1482,6 +1482,58 @@ if_link_state_change(struct ifnet *ifp,
}
/*
+ * Default action when installing a local route on a point-to-point
+ * interface.
+ */
+void
+p2p_rtrequest(int req, struct rtentry *rt,
+ __unused const struct rt_addrinfo *info)
+{
+ struct ifnet *ifp = rt->rt_ifp;
+ struct ifaddr *ifa, *lo0ifa;
+
+ switch (req) {
+ case RTM_ADD:
+ if ((rt->rt_flags & RTF_LOCAL) == 0)
+ break;
+
+ IFADDR_FOREACH(ifa, ifp) {
+ if (equal(rt_getkey(rt), ifa->ifa_addr))
+ break;
+ }
+ if (ifa == NULL)
+ break;
+
+ /*
+ * Ensure lo0 has an address of the same family.
+ */
+ IFADDR_FOREACH(lo0ifa, lo0ifp) {
+ if (lo0ifa->ifa_addr->sa_family ==
+ ifa->ifa_addr->sa_family)
+ break;
+ }
+ if (lo0ifa == NULL)
+ break;
+
+ rt->rt_ifp = lo0ifp;
+ rt->rt_flags &= ~RTF_LLINFO;
+
+ /*
+ * Make sure to set rt->rt_ifa to the interface
+ * address we are using, otherwise we will have trouble
+ * with source address selection.
+ */
+ if (ifa != rt->rt_ifa)
+ rt_replace_ifa(rt, ifa);
+ break;
+ case RTM_DELETE:
+ case RTM_RESOLVE:
+ default:
+ break;
+ }
+}
+
+/*
* Mark an interface down and notify protocols of
* the transition.
* NOTE: must be called at splsoftnet or equivalent.
Index: src/sys/net/if.h
diff -u src/sys/net/if.h:1.187 src/sys/net/if.h:1.188
--- src/sys/net/if.h:1.187 Tue Apr 7 23:30:36 2015
+++ src/sys/net/if.h Mon Apr 20 10:19:54 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: if.h,v 1.187 2015/04/07 23:30:36 roy Exp $ */
+/* $NetBSD: if.h,v 1.188 2015/04/20 10:19:54 roy Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -899,6 +899,7 @@ struct ifaddr *ifa_ifwithroute(int, cons
struct ifaddr *ifaof_ifpforaddr(const struct sockaddr *, struct ifnet *);
void ifafree(struct ifaddr *);
void link_rtrequest(int, struct rtentry *, const struct rt_addrinfo *);
+void p2p_rtrequest(int, struct rtentry *, const struct rt_addrinfo *);
void if_clone_attach(struct if_clone *);
void if_clone_detach(struct if_clone *);
Index: src/sys/net/if_gif.c
diff -u src/sys/net/if_gif.c:1.83 src/sys/net/if_gif.c:1.84
--- src/sys/net/if_gif.c:1.83 Thu Jun 5 23:48:16 2014
+++ src/sys/net/if_gif.c Mon Apr 20 10:19:54 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: if_gif.c,v 1.83 2014/06/05 23:48:16 rmind Exp $ */
+/* $NetBSD: if_gif.c,v 1.84 2015/04/20 10:19:54 roy Exp $ */
/* $KAME: if_gif.c,v 1.76 2001/08/20 02:01:02 kjc Exp $ */
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.83 2014/06/05 23:48:16 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.84 2015/04/20 10:19:54 roy Exp $");
#include "opt_inet.h"
@@ -423,12 +423,14 @@ gif_ioctl(struct ifnet *ifp, u_long cmd,
{
struct gif_softc *sc = ifp->if_softc;
struct ifreq *ifr = (struct ifreq*)data;
+ struct ifaddr *ifa = (struct ifaddr*)data;
int error = 0, size;
struct sockaddr *dst, *src;
switch (cmd) {
case SIOCINITIFADDR:
ifp->if_flags |= IFF_UP;
+ ifa->ifa_rtrequest = p2p_rtrequest;
break;
case SIOCADDMULTI:
Index: src/sys/net/if_gre.c
diff -u src/sys/net/if_gre.c:1.162 src/sys/net/if_gre.c:1.163
--- src/sys/net/if_gre.c:1.162 Fri Apr 3 20:01:07 2015
+++ src/sys/net/if_gre.c Mon Apr 20 10:19:54 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: if_gre.c,v 1.162 2015/04/03 20:01:07 rtr Exp $ */
+/* $NetBSD: if_gre.c,v 1.163 2015/04/20 10:19:54 roy Exp $ */
/*
* Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
@@ -45,7 +45,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1.162 2015/04/03 20:01:07 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1.163 2015/04/20 10:19:54 roy Exp $");
#include "opt_atalk.h"
#include "opt_gre.h"
@@ -1180,6 +1180,7 @@ static int
gre_ioctl(struct ifnet *ifp, const u_long cmd, void *data)
{
struct ifreq *ifr;
+ struct ifaddr *ifa = (struct ifaddr *)data;
struct if_laddrreq *lifr = (struct if_laddrreq *)data;
struct gre_softc *sc = ifp->if_softc;
struct gre_soparm *sp;
@@ -1221,6 +1222,7 @@ gre_ioctl(struct ifnet *ifp, const u_lon
break;
gre_clearconf(sp, false);
ifp->if_flags |= IFF_UP;
+ ifa->ifa_rtrequest = p2p_rtrequest;
goto mksocket;
case SIOCSIFFLAGS:
if ((error = ifioctl_common(ifp, cmd, data)) != 0)
Index: src/sys/net/if_ppp.c
diff -u src/sys/net/if_ppp.c:1.146 src/sys/net/if_ppp.c:1.147
--- src/sys/net/if_ppp.c:1.146 Tue Jul 1 15:03:58 2014
+++ src/sys/net/if_ppp.c Mon Apr 20 10:19:54 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ppp.c,v 1.146 2014/07/01 15:03:58 msaitoh Exp $ */
+/* $NetBSD: if_ppp.c,v 1.147 2015/04/20 10:19:54 roy Exp $ */
/* Id: if_ppp.c,v 1.6 1997/03/04 03:33:00 paulus Exp */
/*
@@ -102,7 +102,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ppp.c,v 1.146 2014/07/01 15:03:58 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ppp.c,v 1.147 2015/04/20 10:19:54 roy Exp $");
#include "ppp.h"
@@ -767,6 +767,7 @@ pppsioctl(struct ifnet *ifp, u_long cmd,
error = EAFNOSUPPORT;
break;
}
+ ifa->ifa_rtrequest = p2p_rtrequest;
break;
case SIOCADDMULTI:
Index: src/sys/net/if_spppsubr.c
diff -u src/sys/net/if_spppsubr.c:1.131 src/sys/net/if_spppsubr.c:1.132
--- src/sys/net/if_spppsubr.c:1.131 Fri Nov 28 08:29:00 2014
+++ src/sys/net/if_spppsubr.c Mon Apr 20 10:19:54 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: if_spppsubr.c,v 1.131 2014/11/28 08:29:00 ozaki-r Exp $ */
+/* $NetBSD: if_spppsubr.c,v 1.132 2015/04/20 10:19:54 roy Exp $ */
/*
* Synchronous PPP/Cisco link level subroutines.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.131 2014/11/28 08:29:00 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.132 2015/04/20 10:19:54 roy Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@@ -1017,12 +1017,14 @@ sppp_ioctl(struct ifnet *ifp, u_long cmd
{
struct lwp *l = curlwp; /* XXX */
struct ifreq *ifr = (struct ifreq *) data;
+ struct ifaddr *ifa = (struct ifaddr *) data;
struct sppp *sp = (struct sppp *) ifp;
int s, error=0, going_up, going_down, newmode;
s = splnet();
switch (cmd) {
case SIOCINITIFADDR:
+ ifa->ifa_rtrequest = p2p_rtrequest;
break;
case SIOCSIFFLAGS:
Index: src/sys/net/if_tun.c
diff -u src/sys/net/if_tun.c:1.120 src/sys/net/if_tun.c:1.121
--- src/sys/net/if_tun.c:1.120 Fri Jul 25 08:10:40 2014
+++ src/sys/net/if_tun.c Mon Apr 20 10:19:54 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: if_tun.c,v 1.120 2014/07/25 08:10:40 dholland Exp $ */
+/* $NetBSD: if_tun.c,v 1.121 2015/04/20 10:19:54 roy Exp $ */
/*
* Copyright (c) 1988, Julian Onions <[email protected]>
@@ -15,7 +15,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_tun.c,v 1.120 2014/07/25 08:10:40 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_tun.c,v 1.121 2015/04/20 10:19:54 roy Exp $");
#include "opt_inet.h"
@@ -435,13 +435,15 @@ tun_ioctl(struct ifnet *ifp, u_long cmd,
{
int error = 0, s;
struct tun_softc *tp = (struct tun_softc *)(ifp->if_softc);
- struct ifreq *ifr = data;
+ struct ifreq *ifr = (struct ifreq *)data;
+ struct ifaddr *ifa = (struct ifaddr *)data;
s = splnet();
switch (cmd) {
case SIOCINITIFADDR:
tuninit(tp);
+ ifa->ifa_rtrequest = p2p_rtrequest;
TUNDEBUG("%s: address set\n", ifp->if_xname);
break;
case SIOCSIFBRDADDR:
Index: src/sys/netinet6/in6.c
diff -u src/sys/netinet6/in6.c:1.186 src/sys/netinet6/in6.c:1.187
--- src/sys/netinet6/in6.c:1.186 Tue Apr 7 23:30:36 2015
+++ src/sys/netinet6/in6.c Mon Apr 20 10:19:54 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: in6.c,v 1.186 2015/04/07 23:30:36 roy Exp $ */
+/* $NetBSD: in6.c,v 1.187 2015/04/20 10:19:54 roy Exp $ */
/* $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $ */
/*
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.186 2015/04/07 23:30:36 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.187 2015/04/20 10:19:54 roy Exp $");
#include "opt_inet.h"
#include "opt_compat_netbsd.h"
@@ -1695,7 +1695,9 @@ in6_ifinit(struct ifnet *ifp, struct in6
/* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */
if (newhost) {
/* set the rtrequest function to create llinfo */
- if ((ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) == 0)
+ if (ifp->if_flags & IFF_POINTOPOINT)
+ ia->ia_ifa.ifa_rtrequest = p2p_rtrequest;
+ else if ((ifp->if_flags & IFF_LOOPBACK) == 0)
ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;
in6_ifaddlocal(&ia->ia_ifa);
} else {