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 <j...@cs.nott.ac.uk>
@@ -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 {

Reply via email to