do not differentiate manually configured address from autoconfigured ones

wrt prefix management;
- always earn a reference to the prefix when an address is configured
 (by ioctl).
- always delete the prefix when an address that has the last referene
  is manually removed.

The change should solve the problem raised in KAME-snap 6989.

sync w/kame
This commit is contained in:
itojun 2002-10-17 00:07:44 +00:00
parent 69ea8215e0
commit 5fc1c3b058
1 changed files with 11 additions and 18 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6.c,v 1.70 2002/09/23 13:16:52 itojun Exp $ */
/* $NetBSD: in6.c,v 1.71 2002/10/17 00:07:44 itojun Exp $ */
/* $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $ */
/*
@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.70 2002/09/23 13:16:52 itojun Exp $");
__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.71 2002/10/17 00:07:44 itojun Exp $");
#include "opt_inet.h"
@ -713,7 +713,7 @@ in6_control(so, cmd, data, ifp, p)
pr0.ndpr_vltime = ifra->ifra_lifetime.ia6t_vltime;
pr0.ndpr_pltime = ifra->ifra_lifetime.ia6t_pltime;
/* add the prefix if there's one. */
/* add the prefix if not yet. */
if ((pr = nd6_prefix_lookup(&pr0)) == NULL) {
/*
* nd6_prelist_add will install the corresponding
@ -727,8 +727,9 @@ in6_control(so, cmd, data, ifp, p)
return (EINVAL); /* XXX panic here? */
}
}
if ((ia->ia6_flags & IN6_IFF_AUTOCONF) &&
ia->ia6_ndpr == NULL) { /* new autoconfed addr */
/* relate the address to the prefix */
if (ia->ia6_ndpr == NULL) {
ia->ia6_ndpr = pr;
pr->ndpr_refcnt++;
}
@ -768,20 +769,12 @@ in6_control(so, cmd, data, ifp, p)
pr0.ndpr_prefix.sin6_addr.s6_addr32[i] &=
ia->ia_prefixmask.sin6_addr.s6_addr32[i];
}
/*
* The logic of the following condition is a bit complicated.
* We expire the prefix when
* 1. the address obeys autoconfiguration and it is the
* only owner of the associated prefix, or
* 2. the address does not obey autoconf and there is no
* other owner of the prefix.
*/
if ((pr = nd6_prefix_lookup(&pr0)) != NULL &&
(((ia->ia6_flags & IN6_IFF_AUTOCONF) != 0 &&
pr->ndpr_refcnt == 1) ||
((ia->ia6_flags & IN6_IFF_AUTOCONF) == 0 &&
pr->ndpr_refcnt == 0)))
purgeprefix = 1;
pr == ia->ia6_ndpr) {
pr->ndpr_refcnt--;
if (pr->ndpr_refcnt == 0)
purgeprefix = 1;
}
purgeaddr:
in6_purgeaddr(&ia->ia_ifa);