Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys avoid calling in6_control(SIOCDIFADDR_IN6) from interrup...
details: https://anonhg.NetBSD.org/src/rev/f88a15039902
branches: trunk
changeset: 481737:f88a15039902
user: itojun <itojun%NetBSD.org@localhost>
date: Fri Feb 04 14:34:22 2000 +0000
description:
avoid calling in6_control(SIOCDIFADDR_IN6) from interrupt context.
it is not supposed to work.
logging fix: add "\n" to some of log() in in6_prefix.c.
improve in6_ifdetach(). now almost all structure depend on ifnet
will be cleared up.
possible loose ends:
- cached route_in6 in static varaiables needs to be cleared as well
- there are ifaddr manipulation without reference counting,
which should be fixed
we still see panics after card removal, though... not sure what is left.
(sync with kame)
diffstat:
sys/netinet/tcp_usrreq.c | 3 +-
sys/netinet6/in6_ifattach.c | 10 +++-
sys/netinet6/in6_prefix.c | 76 +++++++++++++++++-------------------
sys/netinet6/in6_prefix.h | 5 +-
sys/netinet6/in6_var.h | 3 +-
sys/netinet6/nd6.c | 94 ++++++++++++++++++++++++++++++++++++++++++++-
sys/netinet6/nd6.h | 3 +-
7 files changed, 145 insertions(+), 49 deletions(-)
diffs (truncated from 431 to 300 lines):
diff -r 6ae0cfafa23f -r f88a15039902 sys/netinet/tcp_usrreq.c
--- a/sys/netinet/tcp_usrreq.c Fri Feb 04 14:21:33 2000 +0000
+++ b/sys/netinet/tcp_usrreq.c Fri Feb 04 14:34:22 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tcp_usrreq.c,v 1.46 2000/02/02 23:28:09 thorpej Exp $ */
+/* $NetBSD: tcp_usrreq.c,v 1.47 2000/02/04 14:34:22 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -204,6 +204,7 @@
in_purgeif((struct ifnet *)control);
in_pcbpurgeif(&tcbtable, (struct ifnet *)control);
#ifdef INET6
+ in6_purgeif((struct ifnet *)control);
in6_pcbpurgeif(&tcb6, (struct ifnet *)control);
#endif
return (0);
diff -r 6ae0cfafa23f -r f88a15039902 sys/netinet6/in6_ifattach.c
--- a/sys/netinet6/in6_ifattach.c Fri Feb 04 14:21:33 2000 +0000
+++ b/sys/netinet6/in6_ifattach.c Fri Feb 04 14:34:22 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: in6_ifattach.c,v 1.17 2000/02/02 16:58:11 itojun Exp $ */
+/* $NetBSD: in6_ifattach.c,v 1.18 2000/02/04 14:34:25 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -628,6 +628,12 @@
short rtflags;
struct sockaddr_in6 sin6;
+ /* nuke prefix list. this may try to remove some of ifaddrs as well */
+ in6_purgeprefix(ifp);
+
+ /* remove neighbor management table */
+ nd6_purge(ifp);
+
for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
{
if (ifa->ifa_addr->sa_family != AF_INET6
@@ -673,7 +679,7 @@
/* cleanup multicast address kludge table, if there is any */
in6_purgemkludge(ifp);
-
+
/* remove route to link-local allnodes multicast (ff02::1) */
bzero(&sin6, sizeof(sin6));
sin6.sin6_len = sizeof(struct sockaddr_in6);
diff -r 6ae0cfafa23f -r f88a15039902 sys/netinet6/in6_prefix.c
--- a/sys/netinet6/in6_prefix.c Fri Feb 04 14:21:33 2000 +0000
+++ b/sys/netinet6/in6_prefix.c Fri Feb 04 14:34:22 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: in6_prefix.c,v 1.6 2000/02/03 12:13:50 itojun Exp $ */
+/* $NetBSD: in6_prefix.c,v 1.7 2000/02/04 14:34:25 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -205,7 +205,7 @@
}
if (ifpr != NULL)
log(LOG_ERR, "in6_prefix.c: search_matched_prefix: addr %s"
- "has no pointer to prefix %s", ip6_sprintf(IFA_IN6(ifa)),
+ "has no pointer to prefix %s\n", ip6_sprintf(IFA_IN6(ifa)),
ip6_sprintf(IFPR_IN6(ifpr)));
return ifpr2rp(ifpr);
}
@@ -263,7 +263,7 @@
} else
log(LOG_WARNING, "in6_prefix.c: mark_matched_prefixes:"
"no back pointer to ifprefix for %s. "
- "ND autoconfigured addr?",
+ "ND autoconfigured addr?\n",
ip6_sprintf(IFA_IN6(ifa)));
}
return matched;
@@ -457,7 +457,7 @@
else if (rap->ra_addr != ia) {
/* There may be some inconsistencies between addrs. */
log(LOG_ERR, "ip6_prefix.c: addr %s/%d matched prefix"
- "has already another ia %p(%s) on its ifid list",
+ "has already another ia %p(%s) on its ifid list\n",
ip6_sprintf(IA6_IN6(ia)), plen,
rap->ra_addr,
ip6_sprintf(IA6_IN6(rap->ra_addr)));
@@ -488,6 +488,22 @@
}
}
+void
+in6_purgeprefix(ifp)
+ struct ifnet *ifp;
+{
+ struct ifprefix *ifpr, *nextifpr;
+
+ /* delete prefixes before ifnet goes away */
+ for (ifpr = ifp->if_prefixlist; ifpr; ifpr = nextifpr) {
+ nextifpr = ifpr->ifpr_next;
+ if (ifpr->ifpr_prefix->sa_family != AF_INET6 ||
+ ifpr->ifpr_type != IN6_PREFIX_RR)
+ continue;
+ (void)delete_each_prefix(ifpr2rp(ifpr), PR_ORIG_KERNEL);
+ }
+}
+
static void
add_each_addr(struct socket *so, struct rr_prefix *rpp, struct rp_addr *rap)
{
@@ -538,7 +554,7 @@
* log it and return.
*/
log(LOG_ERR, "in6_prefix.c: add_each_addr: addition of an addr"
- "%s/%d failed because there is already another addr %s/%d",
+ "%s/%d failed because there is already another addr %s/%d\n",
ip6_sprintf(&ifra.ifra_addr.sin6_addr), rpp->rp_plen,
ip6_sprintf(IA6_IN6(ia6)),
in6_mask2len(&ia6->ia_prefixmask.sin6_addr));
@@ -551,7 +567,7 @@
, curproc);
if (error != 0)
log(LOG_ERR, "in6_prefix.c: add_each_addr: addition of an addr"
- "%s/%d failed because in6_control failed for error %d",
+ "%s/%d failed because in6_control failed for error %d\n",
ip6_sprintf(&ifra.ifra_addr.sin6_addr), rpp->rp_plen,
error);
return;
@@ -628,15 +644,14 @@
M_NOWAIT);
if (rpp == NULL) {
log(LOG_ERR, "in6_prefix.c: rrpr_update:%d"
- ": ENOBUFS for rr_prefix", __LINE__);
+ ": ENOBUFS for rr_prefix\n", __LINE__);
return(ENOBUFS);
}
/* initilization */
*rpp = *new;
LIST_INIT(&rpp->rp_addrhead);
/* move rp_addr entries of new to rpp */
- while (new->rp_addrhead.lh_first != NULL)
- {
+ while (new->rp_addrhead.lh_first != NULL) {
rap = LIST_FIRST(&new->rp_addrhead);
LIST_REMOVE(rap, ra_entry);
LIST_INSERT_HEAD(&rpp->rp_addrhead, rap, ra_entry);
@@ -728,7 +743,7 @@
M_NOWAIT);
if (*rapp == NULL) {
log(LOG_ERR, "in6_prefix.c: init_newprefix:%d: ENOBUFS"
- "for rp_addr", __LINE__);
+ "for rp_addr\n", __LINE__);
return ENOBUFS;
}
bzero(*rapp, sizeof(*(*rapp)));
@@ -845,9 +860,8 @@
}
int
-delete_each_prefix(struct socket *so, struct rr_prefix *rpp, u_char origin)
+delete_each_prefix(struct rr_prefix *rpp, u_char origin)
{
- struct in6_aliasreq ifra;
int error = 0;
if (rpp->rp_origin > origin)
@@ -869,22 +883,7 @@
}
rap->ra_addr->ia6_ifpr = NULL;
- bzero(&ifra, sizeof(ifra));
- strncpy(ifra.ifra_name, if_name(rpp->rp_ifp),
- sizeof(ifra.ifra_name));
- ifra.ifra_addr = rap->ra_addr->ia_addr;
- ifra.ifra_dstaddr = rap->ra_addr->ia_dstaddr;
- ifra.ifra_prefixmask = rap->ra_addr->ia_prefixmask;
-
- error = in6_control(so, SIOCDIFADDR_IN6, (caddr_t)&ifra,
- rpp->rp_ifp, curproc);
- if (error != 0)
- log(LOG_ERR, "in6_prefix.c: delete_each_prefix:"
- "deletion of an addr %s/%d failed because"
- "in6_control failed for error %d",
- ip6_sprintf(&ifra.ifra_addr.sin6_addr),
- rpp->rp_plen, error);
-
+ in6_purgeaddr(&rap->ra_addr->ia_ifa, rpp->rp_ifp);
free(rap, M_RR_ADDR);
}
rp_remove(rpp);
@@ -893,7 +892,7 @@
}
static void
-delete_prefixes(struct socket *so, struct ifnet *ifp, u_char origin)
+delete_prefixes(struct ifnet *ifp, u_char origin)
{
struct ifprefix *ifpr, *nextifpr;
@@ -904,7 +903,7 @@
ifpr->ifpr_type != IN6_PREFIX_RR)
continue;
if (ifpr2rp(ifpr)->rp_statef_delmark)
- (void)delete_each_prefix(so, ifpr2rp(ifpr), origin);
+ (void)delete_each_prefix(ifpr2rp(ifpr), origin);
}
}
@@ -931,7 +930,7 @@
rpp->rp_plen))
log(LOG_ERR, "in6_prefix.c: link_stray_ia6s:"
"addr %s/%d already linked to a prefix"
- "and it matches also %s/%d",
+ "and it matches also %s/%d\n",
ip6_sprintf(IFA_IN6(ifa)), orpp->rp_plen,
ip6_sprintf(RP_IN6(rpp)),
rpp->rp_plen);
@@ -946,6 +945,7 @@
return 0;
}
+/* XXX assumes that permission is already checked by the caller */
int
in6_prefix_ioctl(struct socket *so, u_long cmd, caddr_t data,
struct ifnet *ifp)
@@ -974,7 +974,7 @@
if (irr->irr_pltime > irr->irr_vltime) {
log(LOG_NOTICE,
"in6_prefix_ioctl: preferred lifetime"
- "(%ld) is greater than valid lifetime(%ld)",
+ "(%ld) is greater than valid lifetime(%ld)\n",
(u_long)irr->irr_pltime, (u_long)irr->irr_vltime);
error = EINVAL;
break;
@@ -985,7 +985,7 @@
!= 0)
goto failed;
if (cmd != SIOCAIFPREFIX_IN6)
- delete_prefixes(so, ifp, irr->irr_origin);
+ delete_prefixes(ifp, irr->irr_origin);
} else
return (EADDRNOTAVAIL);
failed:
@@ -1009,7 +1009,7 @@
if (ipr->ipr_pltime > ipr->ipr_vltime) {
log(LOG_NOTICE,
"in6_prefix_ioctl: preferred lifetime"
- "(%ld) is greater than valid lifetime(%ld)",
+ "(%ld) is greater than valid lifetime(%ld)\n",
(u_long)ipr->ipr_pltime, (u_long)ipr->ipr_vltime);
error = EINVAL;
break;
@@ -1058,7 +1058,7 @@
if (rpp == NULL || ifp != rpp->rp_ifp)
return (EADDRNOTAVAIL);
- error = delete_each_prefix(so, rpp, ipr->ipr_origin);
+ error = delete_each_prefix(rpp, ipr->ipr_origin);
break;
}
return error;
@@ -1079,13 +1079,9 @@
while (rpp) {
if (rpp->rp_expire && rpp->rp_expire < time_second) {
struct rr_prefix *next_rpp;
- struct socket so;
-
- /* XXX: init dummy so */
- bzero(&so, sizeof(so));
next_rpp = LIST_NEXT(rpp, rp_entry);
- delete_each_prefix(&so, rpp, PR_ORIG_KERNEL);
+ delete_each_prefix(rpp, PR_ORIG_KERNEL);
rpp = next_rpp;
continue;
}
diff -r 6ae0cfafa23f -r f88a15039902 sys/netinet6/in6_prefix.h
--- a/sys/netinet6/in6_prefix.h Fri Feb 04 14:21:33 2000 +0000
+++ b/sys/netinet6/in6_prefix.h Fri Feb 04 14:34:22 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: in6_prefix.h,v 1.2 1999/12/13 15:17:22 itojun Exp $ */
+/* $NetBSD: in6_prefix.h,v 1.3 2000/02/04 14:34:26 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998 and 1999 WIDE Project.
@@ -84,5 +84,4 @@
extern struct rr_prhead rr_prefix;
void in6_rr_timer __P((void *));
-int delete_each_prefix __P((struct socket *so, struct rr_prefix *rpp,
- u_char origin));
+int delete_each_prefix __P((struct rr_prefix *rpp, u_char origin));
diff -r 6ae0cfafa23f -r f88a15039902 sys/netinet6/in6_var.h
--- a/sys/netinet6/in6_var.h Fri Feb 04 14:21:33 2000 +0000
+++ b/sys/netinet6/in6_var.h Fri Feb 04 14:34:22 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: in6_var.h,v 1.9 2000/02/02 23:28:10 thorpej Exp $ */
+/* $NetBSD: in6_var.h,v 1.10 2000/02/04 14:34:26 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -568,6 +568,7 @@
struct ifnet *ifp));
Home |
Main Index |
Thread Index |
Old Index