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 {