remove onlink assumption behavior (consider destination on-link if default

router list is empty) based on recent IETF ipv6 discussion (RFC2461 5.2).

fix "ndp -I delete".
This commit is contained in:
itojun 2004-10-26 06:08:00 +00:00
parent 4d2499feda
commit b5f3688c67

View File

@ -1,4 +1,4 @@
/* $NetBSD: nd6_rtr.c,v 1.47 2003/12/10 11:46:33 itojun Exp $ */
/* $NetBSD: nd6_rtr.c,v 1.48 2004/10/26 06:08:00 itojun Exp $ */
/* $KAME: nd6_rtr.c,v 1.95 2001/02/07 08:09:47 itojun Exp $ */
/*
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.47 2003/12/10 11:46:33 itojun Exp $");
__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.48 2004/10/26 06:08:00 itojun Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -72,7 +72,6 @@ static void pfxrtr_del __P((struct nd_pfxrouter *));
static struct nd_pfxrouter *find_pfxlist_reachable_router
__P((struct nd_prefix *));
static void defrouter_delreq __P((struct nd_defrouter *));
static void defrouter_addifreq __P((struct ifnet *));
static void defrouter_delifreq __P((void));
static void nd6_rtmsg __P((int, struct rtentry *));
@ -477,67 +476,6 @@ defrouter_addreq(new)
return;
}
/* Add a route to a given interface as default */
static void
defrouter_addifreq(ifp)
struct ifnet *ifp;
{
struct sockaddr_in6 def, mask;
struct ifaddr *ifa;
struct rtentry *newrt = NULL;
int error, flags;
struct rt_addrinfo info;
/* remove one if we have already installed one */
if (nd6_defif_installed)
defrouter_delifreq();
bzero(&def, sizeof(def));
bzero(&mask, sizeof(mask));
def.sin6_len = mask.sin6_len = sizeof(struct sockaddr_in6);
def.sin6_family = mask.sin6_family = AF_INET6;
/*
* Search for an ifaddr beloging to the specified interface.
* XXX: An IPv6 address are required to be assigned on the interface.
*/
if ((ifa = ifaof_ifpforaddr((struct sockaddr *)&def, ifp)) == NULL) {
nd6log((LOG_ERR, /* better error? */
"defrouter_addifreq: failed to find an ifaddr "
"to install a route to interface %s\n",
if_name(ifp)));
return;
}
/* RTF_CLONING is necessary to make sure to perform ND */
flags = ifa->ifa_flags | RTF_CLONING;
bzero(&info, sizeof(info));
info.rti_info[RTAX_DST] = (struct sockaddr *)&def;
info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)ifa->ifa_addr;
info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask;
info.rti_info[RTAX_IFA] = (struct sockaddr *)ifa->ifa_addr;
info.rti_flags = flags;
error = rtrequest1(RTM_ADD, &info, &newrt);
if (error != 0) {
nd6log((LOG_ERR,
"defrouter_addifreq: failed to install a route to "
"interface %s (errno = %d)\n",
if_name(ifp), error));
if (newrt) /* maybe unnecessary, but do it for safety */
newrt->rt_refcnt--;
} else {
if (newrt) {
nd6_rtmsg(RTM_ADD, newrt);
newrt->rt_refcnt--;
}
}
nd6_defif_installed = ifa;
IFAREF(ifa);
}
/* Remove a default route points to interface */
static void
defrouter_delifreq()
@ -747,30 +685,18 @@ defrouter_select()
*/
if (!TAILQ_FIRST(&nd_defrouter)) {
/*
* XXX: The specification does not say this mechanism should
* be restricted to hosts, but this would be not useful
* (even harmful) for routers.
* This test is meaningless due to a test at the beginning of
* the function, but we intentionally keep it to make the note
* clear.
*/
if (!ip6_forwarding) {
if (nd6_defifp) {
/*
* Install a route to the default interface
* as default route.
*/
defrouter_addifreq(nd6_defifp);
} else {
/*
* purge the existing route.
* XXX: is this really correct?
*/
defrouter_delifreq();
nd6log((LOG_INFO, "defrouter_select: "
"there's no default router and no default"
" interface\n"));
}
/*
* purge the existing route.
*/
defrouter_delifreq();
nd6log((LOG_INFO, "defrouter_select: "
"there's no default router and no default"
" interface\n"));
}
splx(s);
return;
@ -1983,7 +1909,9 @@ nd6_setdefaultiface(ifindex)
{
int error = 0;
if (ifindex < 0 || if_indexlim <= ifindex || !ifindex2ifnet[ifindex])
if (ifindex < 0 || if_indexlim <= ifindex)
return (EINVAL);
if (ifindex != 0 && !ifindex2ifnet[ifindex])
return (EINVAL);
if (nd6_defifindex != ifindex) {