summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2004-10-28 08:43:04 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2004-10-28 08:43:04 +0000
commit6f8ba6350a628efaa068e196f5517dee45506dad (patch)
treebf4f61c17b9d4657e45b6ea5eaefde8c459e37df /sys
parentd34d77c8e98051e66584451021a2b5f3987ab795 (diff)
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". markus ok
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet6/nd6_rtr.c147
1 files changed, 5 insertions, 142 deletions
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index d6edafcb7e8..2f49ebbe67e 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nd6_rtr.c,v 1.31 2004/06/21 23:50:37 tholo Exp $ */
+/* $OpenBSD: nd6_rtr.c,v 1.32 2004/10/28 08:43:03 itojun Exp $ */
/* $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $ */
/*
@@ -67,8 +67,6 @@ static void pfxrtr_add(struct nd_prefix *, struct nd_defrouter *);
static void pfxrtr_del(struct nd_pfxrouter *);
static struct nd_pfxrouter *find_pfxlist_reachable_router(struct nd_prefix *);
static void defrouter_delreq(struct nd_defrouter *);
-static void defrouter_addifreq(struct ifnet *);
-static void defrouter_delifreq(void);
static void nd6_rtmsg(int, struct rtentry *);
static void in6_init_address_ltimes(struct nd_prefix *,
@@ -80,7 +78,6 @@ extern int nd6_recalc_reachtm_interval;
static struct ifnet *nd6_defifp;
int nd6_defifindex;
-static struct ifaddr *nd6_defif_installed = NULL;
/*
* Receive Router Solicitation Message - just for routers.
@@ -472,102 +469,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",
- ifp->if_xname));
- 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",
- ifp->if_xname, 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;
- ifa->ifa_refcnt++;
-}
-
-/* Remove a default route points to interface */
-static void
-defrouter_delifreq()
-{
- struct sockaddr_in6 def, mask;
- struct rtentry *oldrt = NULL;
-
- if (!nd6_defif_installed)
- return;
-
- 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;
-
- rtrequest(RTM_DELETE, (struct sockaddr *)&def,
- (struct sockaddr *)nd6_defif_installed->ifa_addr,
- (struct sockaddr *)&mask, RTF_GATEWAY, &oldrt);
- if (oldrt) {
- nd6_rtmsg(RTM_DELETE, oldrt);
- if (oldrt->rt_refcnt <= 0) {
- /*
- * XXX: borrowed from the RTM_DELETE case of
- * rtrequest().
- */
- oldrt->rt_refcnt++;
- rtfree(oldrt);
- }
- }
-
- IFAFREE(nd6_defif_installed);
- nd6_defif_installed = NULL;
-}
-
struct nd_defrouter *
defrouter_lookup(addr, ifp)
struct in6_addr *addr;
@@ -684,7 +585,6 @@ defrouter_reset()
for (dr = TAILQ_FIRST(&nd_defrouter); dr;
dr = TAILQ_NEXT(dr, dr_entry))
defrouter_delreq(dr);
- defrouter_delifreq();
/*
* XXX should we also nuke any default routers in the kernel, by
@@ -737,48 +637,14 @@ defrouter_select()
/*
* Let's handle easy case (3) first:
- * If default router list is empty, we should probably install
- * an interface route and assume that all destinations are on-link.
+ * If default router list is empty, there's nothing to be done.
*/
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"));
- }
- }
splx(s);
return;
}
/*
- * If we have a default route for the default interface, delete it.
- * Note that the existence of the route is checked in the delete
- * function.
- */
- defrouter_delifreq();
-
- /*
* Search for a (probably) reachable router from the list.
* We just pick up the first reachable one (if any), assuming that
* the ordering rule of the list described in defrtrlist_update().
@@ -1979,7 +1845,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) {
@@ -1988,11 +1856,6 @@ nd6_setdefaultiface(ifindex)
nd6_defifp = ifindex2ifnet[nd6_defifindex];
} else
nd6_defifp = NULL;
-
- /*
- * Rescan default router list, refresh default route(s).
- */
- defrouter_select();
}
return (error);