Introduce p2p_rtrequest() so that IFF_POINTOPOINT interfaces can work

with RTF_LOCAL.
Fixes PR kern/49829.
This commit is contained in:
roy 2015-04-20 10:19:54 +00:00
parent 7a329562eb
commit 33e035dca4
8 changed files with 81 additions and 17 deletions

View File

@ -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"
@ -1481,6 +1481,58 @@ if_link_state_change(struct ifnet *ifp, int link_state)
splx(s);
}
/*
* 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.

View File

@ -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, const struct sockaddr *,
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 *);

View File

@ -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, void *data)
{
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:

View File

@ -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_long cmd, void *data)
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)

View File

@ -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, void *data)
error = EAFNOSUPPORT;
break;
}
ifa->ifa_rtrequest = p2p_rtrequest;
break;
case SIOCADDMULTI:

View File

@ -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, void *data)
{
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:

View File

@ -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 <jpo@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, void *data)
{
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:

View File

@ -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_ifaddr *ia,
/* 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 {