summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2014-11-10 10:46:11 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2014-11-10 10:46:11 +0000
commit95577037eb3a020972f17cacb20a5bfa587987bc (patch)
treed2d09acfbe162797861040938670296e17894f57
parentf25486282bcfc3dc683f128d667b93b6155b664c (diff)
Do not pass an ifa pointer when we already have a DAD descriptor.
Tweaks and ok florian@
-rw-r--r--sys/netinet6/nd6.h3
-rw-r--r--sys/netinet6/nd6_nbr.c90
2 files changed, 35 insertions, 58 deletions
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
index e5ca468ed28..30e4b32e942 100644
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: nd6.h,v 1.39 2014/08/25 14:00:34 florian Exp $ */
+/* $OpenBSD: nd6.h,v 1.40 2014/11/10 10:46:10 mpi Exp $ */
/* $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $ */
/*
@@ -299,7 +299,6 @@ void nd6_ns_output(struct ifnet *, struct in6_addr *,
caddr_t nd6_ifptomac(struct ifnet *);
void nd6_dad_start(struct ifaddr *, int *);
void nd6_dad_stop(struct ifaddr *);
-void nd6_dad_duplicated(struct ifaddr *);
void nd6_rs_input(struct mbuf *, int, int);
void nd6_ra_input(struct mbuf *, int, int);
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index 68fe2ce3943..ab23d49e3cc 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nd6_nbr.c,v 1.82 2014/11/01 21:40:39 mpi Exp $ */
+/* $OpenBSD: nd6_nbr.c,v 1.83 2014/11/10 10:46:10 mpi Exp $ */
/* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */
/*
@@ -65,14 +65,25 @@
#define SDL(s) ((struct sockaddr_dl *)s)
-struct dadq;
+TAILQ_HEAD(dadq_head, dadq);
+struct dadq {
+ TAILQ_ENTRY(dadq) dad_list;
+ struct ifaddr *dad_ifa;
+ int dad_count; /* max NS to send */
+ int dad_ns_tcount; /* # of trials to send NS */
+ int dad_ns_ocount; /* NS sent so far */
+ int dad_ns_icount;
+ int dad_na_icount;
+ struct timeout dad_timer_ch;
+};
+
struct dadq *nd6_dad_find(struct ifaddr *);
void nd6_dad_starttimer(struct dadq *, int);
void nd6_dad_stoptimer(struct dadq *);
void nd6_dad_timer(struct ifaddr *);
void nd6_dad_ns_output(struct dadq *, struct ifaddr *);
void nd6_dad_ns_input(struct ifaddr *);
-void nd6_dad_na_input(struct ifaddr *);
+void nd6_dad_duplicated(struct dadq *);
static int dad_ignore_ns = 0; /* ignore NS in DAD - specwise incorrect*/
static int dad_maxtry = 15; /* max # of *tries* to transmit DAD packet */
@@ -640,7 +651,15 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
* Otherwise, process as defined in RFC 2461.
*/
if (ifa && (ifatoia6(ifa)->ia6_flags & IN6_IFF_TENTATIVE)) {
- nd6_dad_na_input(ifa);
+ struct dadq *dp;
+
+ dp = nd6_dad_find(ifa);
+ if (dp) {
+ dp->dad_na_icount++;
+
+ /* remove the address. */
+ nd6_dad_duplicated(dp);
+ }
goto freeit;
}
@@ -1071,18 +1090,6 @@ nd6_ifptomac(struct ifnet *ifp)
}
}
-TAILQ_HEAD(dadq_head, dadq);
-struct dadq {
- TAILQ_ENTRY(dadq) dad_list;
- struct ifaddr *dad_ifa;
- int dad_count; /* max NS to send */
- int dad_ns_tcount; /* # of trials to send NS */
- int dad_ns_ocount; /* NS sent so far */
- int dad_ns_icount;
- int dad_na_icount;
- struct timeout dad_timer_ch;
-};
-
static struct dadq_head dadq;
static int dad_init = 0;
@@ -1300,10 +1307,6 @@ nd6_dad_timer(struct ifaddr *ifa)
duplicate = 0;
if (dp->dad_na_icount) {
- /*
- * the check is in nd6_dad_na_input(),
- * but just in case
- */
duplicate++;
}
@@ -1313,9 +1316,8 @@ nd6_dad_timer(struct ifaddr *ifa)
}
if (duplicate) {
- /* (*dp) will be freed in nd6_dad_duplicated() */
- dp = NULL;
- nd6_dad_duplicated(ifa);
+ /* dp will be freed in nd6_dad_duplicated() */
+ nd6_dad_duplicated(dp);
} else {
/*
* We are done with DAD. No NA came, no NS came.
@@ -1342,21 +1344,14 @@ done:
}
void
-nd6_dad_duplicated(struct ifaddr *ifa)
+nd6_dad_duplicated(struct dadq *dp)
{
- struct in6_ifaddr *ia6 = ifatoia6(ifa);
- struct dadq *dp;
+ struct in6_ifaddr *ia6 = ifatoia6(dp->dad_ifa);
char addr[INET6_ADDRSTRLEN];
- dp = nd6_dad_find(ifa);
- if (dp == NULL) {
- log(LOG_ERR, "nd6_dad_duplicated: DAD structure not found\n");
- return;
- }
-
log(LOG_ERR, "%s: DAD detected duplicate IPv6 address %s: "
"NS in/out=%d/%d, NA in=%d\n",
- ifa->ifa_ifp->if_xname,
+ ia6->ia_ifp->if_xname,
inet_ntop(AF_INET6, &ia6->ia_addr.sin6_addr, addr, sizeof(addr)),
dp->dad_ns_icount, dp->dad_ns_ocount, dp->dad_na_icount);
@@ -1367,15 +1362,14 @@ nd6_dad_duplicated(struct ifaddr *ifa)
nd6_dad_stoptimer(dp);
log(LOG_ERR, "%s: DAD complete for %s - duplicate found\n",
- ifa->ifa_ifp->if_xname,
+ ia6->ia_ifp->if_xname,
inet_ntop(AF_INET6, &ia6->ia_addr.sin6_addr, addr, sizeof(addr)));
log(LOG_ERR, "%s: manual intervention required\n",
- ifa->ifa_ifp->if_xname);
+ ia6->ia_ifp->if_xname);
- TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
+ TAILQ_REMOVE(&dadq, dp, dad_list);
+ ifafree(dp->dad_ifa);
free(dp, M_IP6NDP, 0);
- dp = NULL;
- ifafree(ifa);
ip6_dad_pending--;
}
@@ -1441,8 +1435,8 @@ nd6_dad_ns_input(struct ifaddr *ifa)
/* XXX more checks for loopback situation - see nd6_dad_timer too */
if (duplicate) {
- dp = NULL; /* will be freed in nd6_dad_duplicated() */
- nd6_dad_duplicated(ifa);
+ /* dp will be freed in nd6_dad_duplicated() */
+ nd6_dad_duplicated(dp);
} else {
/*
* not sure if I got a duplicate.
@@ -1452,19 +1446,3 @@ nd6_dad_ns_input(struct ifaddr *ifa)
dp->dad_ns_icount++;
}
}
-
-void
-nd6_dad_na_input(struct ifaddr *ifa)
-{
- struct dadq *dp;
-
- if (!ifa)
- panic("ifa == NULL in nd6_dad_na_input");
-
- dp = nd6_dad_find(ifa);
- if (dp)
- dp->dad_na_icount++;
-
- /* remove the address. */
- nd6_dad_duplicated(ifa);
-}