Thu Jun 20 13:56:29 2013 UTC ()
Move the detaching and making tentative addresses out if in6_if_up
and into in6_if_link_up.

This fixes a possible panic where link is up but not the interface.
Note that a better solution would be to listen to the routing socket
in the kernel, but I don't know how to do that.

Reachable Router tests for IFF_UP as well.


(roy)
diff -r1.79 -r1.80 src/sys/dev/mii/mii_physubr.c
diff -r1.263 -r1.264 src/sys/net/if.c
diff -r1.164 -r1.165 src/sys/netinet6/in6.c
diff -r1.72 -r1.73 src/sys/netinet6/in6.h
diff -r1.88 -r1.89 src/sys/netinet6/nd6_rtr.c

cvs diff -r1.79 -r1.80 src/sys/dev/mii/mii_physubr.c (expand / switch to unified diff)

--- src/sys/dev/mii/mii_physubr.c 2013/06/16 06:29:08 1.79
+++ src/sys/dev/mii/mii_physubr.c 2013/06/20 13:56:29 1.80
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: mii_physubr.c,v 1.79 2013/06/16 06:29:08 msaitoh Exp $ */ 1/* $NetBSD: mii_physubr.c,v 1.80 2013/06/20 13:56:29 roy Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center. 9 * NASA Ames Research Center.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -25,27 +25,27 @@ @@ -25,27 +25,27 @@
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * Subroutines common to all PHYs. 34 * Subroutines common to all PHYs.
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: mii_physubr.c,v 1.79 2013/06/16 06:29:08 msaitoh Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: mii_physubr.c,v 1.80 2013/06/20 13:56:29 roy Exp $");
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/device.h> 41#include <sys/device.h>
42#include <sys/systm.h> 42#include <sys/systm.h>
43#include <sys/kernel.h> 43#include <sys/kernel.h>
44#include <sys/socket.h> 44#include <sys/socket.h>
45#include <sys/errno.h> 45#include <sys/errno.h>
46#include <sys/module.h> 46#include <sys/module.h>
47#include <sys/proc.h> 47#include <sys/proc.h>
48 48
49#include <net/if.h> 49#include <net/if.h>
50#include <net/if_media.h> 50#include <net/if_media.h>
51#include <net/route.h> 51#include <net/route.h>
@@ -426,37 +426,34 @@ mii_phy_update(struct mii_softc *sc, int @@ -426,37 +426,34 @@ mii_phy_update(struct mii_softc *sc, int
426 cmd == MII_MEDIACHG) { 426 cmd == MII_MEDIACHG) {
427 mii_phy_statusmsg(sc); 427 mii_phy_statusmsg(sc);
428 (*mii->mii_statchg)(mii->mii_ifp); 428 (*mii->mii_statchg)(mii->mii_ifp);
429 sc->mii_media_active = mii->mii_media_active; 429 sc->mii_media_active = mii->mii_media_active;
430 sc->mii_media_status = mii->mii_media_status; 430 sc->mii_media_status = mii->mii_media_status;
431 } 431 }
432} 432}
433 433
434static void 434static void
435mii_phy_statusmsg(struct mii_softc *sc) 435mii_phy_statusmsg(struct mii_softc *sc)
436{ 436{
437 struct mii_data *mii = sc->mii_pdata; 437 struct mii_data *mii = sc->mii_pdata;
438 struct ifnet *ifp = mii->mii_ifp; 438 struct ifnet *ifp = mii->mii_ifp;
439 int s; 
440 439
441 s = splnet(); 
442 if (mii->mii_media_status & IFM_AVALID) { 440 if (mii->mii_media_status & IFM_AVALID) {
443 if (mii->mii_media_status & IFM_ACTIVE) 441 if (mii->mii_media_status & IFM_ACTIVE)
444 if_link_state_change(ifp, LINK_STATE_UP); 442 if_link_state_change(ifp, LINK_STATE_UP);
445 else 443 else
446 if_link_state_change(ifp, LINK_STATE_DOWN); 444 if_link_state_change(ifp, LINK_STATE_DOWN);
447 } else 445 } else
448 if_link_state_change(ifp, LINK_STATE_UNKNOWN); 446 if_link_state_change(ifp, LINK_STATE_UNKNOWN);
449 splx(s); 
450 447
451 ifp->if_baudrate = ifmedia_baudrate(mii->mii_media_active); 448 ifp->if_baudrate = ifmedia_baudrate(mii->mii_media_active);
452} 449}
453 450
454/* 451/*
455 * Initialize generic PHY media based on BMSR, called when a PHY is 452 * Initialize generic PHY media based on BMSR, called when a PHY is
456 * attached. We expect to be set up to print a comma-separated list 453 * attached. We expect to be set up to print a comma-separated list
457 * of media names. Does not print a newline. 454 * of media names. Does not print a newline.
458 */ 455 */
459void 456void
460mii_phy_add_media(struct mii_softc *sc) 457mii_phy_add_media(struct mii_softc *sc)
461{ 458{
462 struct mii_data *mii = sc->mii_pdata; 459 struct mii_data *mii = sc->mii_pdata;

cvs diff -r1.263 -r1.264 src/sys/net/if.c (expand / switch to unified diff)

--- src/sys/net/if.c 2013/06/11 12:08:29 1.263
+++ src/sys/net/if.c 2013/06/20 13:56:29 1.264
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if.c,v 1.263 2013/06/11 12:08:29 roy Exp $ */ 1/* $NetBSD: if.c,v 1.264 2013/06/20 13:56:29 roy Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by William Studenmund and Jason R. Thorpe. 8 * by William Studenmund and Jason R. Thorpe.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -80,27 +80,27 @@ @@ -80,27 +80,27 @@
80 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 80 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
81 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 81 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
82 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 82 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
83 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 83 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
84 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 84 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
85 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 85 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
86 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 86 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
87 * SUCH DAMAGE. 87 * SUCH DAMAGE.
88 * 88 *
89 * @(#)if.c 8.5 (Berkeley) 1/9/95 89 * @(#)if.c 8.5 (Berkeley) 1/9/95
90 */ 90 */
91 91
92#include <sys/cdefs.h> 92#include <sys/cdefs.h>
93__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.263 2013/06/11 12:08:29 roy Exp $"); 93__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.264 2013/06/20 13:56:29 roy Exp $");
94 94
95#include "opt_inet.h" 95#include "opt_inet.h"
96 96
97#include "opt_atalk.h" 97#include "opt_atalk.h"
98#include "opt_natm.h" 98#include "opt_natm.h"
99#include "opt_pfil_hooks.h" 99#include "opt_pfil_hooks.h"
100 100
101#include <sys/param.h> 101#include <sys/param.h>
102#include <sys/mbuf.h> 102#include <sys/mbuf.h>
103#include <sys/systm.h> 103#include <sys/systm.h>
104#include <sys/callout.h> 104#include <sys/callout.h>
105#include <sys/proc.h> 105#include <sys/proc.h>
106#include <sys/socket.h> 106#include <sys/socket.h>
@@ -1323,76 +1323,83 @@ link_rtrequest(int cmd, struct rtentry * @@ -1323,76 +1323,83 @@ link_rtrequest(int cmd, struct rtentry *
1323 1323
1324 if (cmd != RTM_ADD || (ifa = rt->rt_ifa) == NULL || 1324 if (cmd != RTM_ADD || (ifa = rt->rt_ifa) == NULL ||
1325 (ifp = ifa->ifa_ifp) == NULL || (dst = rt_getkey(rt)) == NULL) 1325 (ifp = ifa->ifa_ifp) == NULL || (dst = rt_getkey(rt)) == NULL)
1326 return; 1326 return;
1327 if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) { 1327 if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) {
1328 rt_replace_ifa(rt, ifa); 1328 rt_replace_ifa(rt, ifa);
1329 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest) 1329 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
1330 ifa->ifa_rtrequest(cmd, rt, info); 1330 ifa->ifa_rtrequest(cmd, rt, info);
1331 } 1331 }
1332} 1332}
1333 1333
1334/* 1334/*
1335 * Handle a change in the interface link state. 1335 * Handle a change in the interface link state.
 1336 * XXX: We should listen to the routing socket in-kernel rather
 1337 * than calling in6_if_link_* functions directly from here.
1336 */ 1338 */
1337void 1339void
1338if_link_state_change(struct ifnet *ifp, int link_state) 1340if_link_state_change(struct ifnet *ifp, int link_state)
1339{ 1341{
1340 int old_link_state; 1342 int old_link_state, s;
1341 1343
1342 if (ifp->if_link_state == link_state) 1344 s = splnet();
 1345 if (ifp->if_link_state == link_state) {
 1346 splx(s);
1343 return; 1347 return;
 1348 }
1344 1349
1345 old_link_state = ifp->if_link_state; 1350 old_link_state = ifp->if_link_state;
1346 ifp->if_link_state = link_state; 1351 ifp->if_link_state = link_state;
1347#ifdef DEBUG 1352#ifdef DEBUG
1348 log(LOG_DEBUG, "%s: link state %s (was %s)\n", ifp->if_xname, 1353 log(LOG_DEBUG, "%s: link state %s (was %s)\n", ifp->if_xname,
1349 link_state == LINK_STATE_UP ? "UP" : 1354 link_state == LINK_STATE_UP ? "UP" :
1350 link_state == LINK_STATE_DOWN ? "DOWN" : 1355 link_state == LINK_STATE_DOWN ? "DOWN" :
1351 "UNKNOWN", 1356 "UNKNOWN",
1352 old_link_state == LINK_STATE_UP ? "UP" : 1357 old_link_state == LINK_STATE_UP ? "UP" :
1353 old_link_state == LINK_STATE_DOWN ? "DOWN" : 1358 old_link_state == LINK_STATE_DOWN ? "DOWN" :
1354 "UNKNOWN"); 1359 "UNKNOWN");
1355#endif 1360#endif
1356 1361
1357#ifdef INET6 1362#ifdef INET6
1358 /* 1363 /*
1359 * When going from UNKNOWN to UP, we need to mark existing 1364 * When going from UNKNOWN to UP, we need to mark existing
1360 * IPv6 addresses as tentative and restart DAD as we may have 1365 * IPv6 addresses as tentative and restart DAD as we may have
1361 * erroneously not found a duplicate. 1366 * erroneously not found a duplicate.
1362 * 1367 *
1363 * This needs to happen before rt_ifmsg to avoid a race where 1368 * This needs to happen before rt_ifmsg to avoid a race where
1364 * listeners would have an address and expect it to work right 1369 * listeners would have an address and expect it to work right
1365 * away. 1370 * away.
1366 */ 1371 */
1367 if (link_state == LINK_STATE_UP && 1372 if (link_state == LINK_STATE_UP &&
1368 old_link_state == LINK_STATE_UNKNOWN) 1373 old_link_state == LINK_STATE_UNKNOWN)
1369 in6_if_down(ifp); 1374 in6_if_link_down(ifp);
1370#endif 1375#endif
1371 1376
1372 /* Notify that the link state has changed. */ 1377 /* Notify that the link state has changed. */
1373 rt_ifmsg(ifp); 1378 rt_ifmsg(ifp);
1374 1379
1375#if NCARP > 0 1380#if NCARP > 0
1376 if (ifp->if_carp) 1381 if (ifp->if_carp)
1377 carp_carpdev_state(ifp); 1382 carp_carpdev_state(ifp);
1378#endif 1383#endif
1379 1384
1380#ifdef INET6 1385#ifdef INET6
1381 if (link_state == LINK_STATE_DOWN) 1386 if (link_state == LINK_STATE_DOWN)
1382 in6_if_down(ifp); 1387 in6_if_link_down(ifp);
1383 else if (link_state == LINK_STATE_UP) 1388 else if (link_state == LINK_STATE_UP)
1384 in6_if_up(ifp); 1389 in6_if_link_up(ifp);
1385#endif 1390#endif
 1391
 1392 splx(s);
1386} 1393}
1387 1394
1388/* 1395/*
1389 * Mark an interface down and notify protocols of 1396 * Mark an interface down and notify protocols of
1390 * the transition. 1397 * the transition.
1391 * NOTE: must be called at splsoftnet or equivalent. 1398 * NOTE: must be called at splsoftnet or equivalent.
1392 */ 1399 */
1393void 1400void
1394if_down(struct ifnet *ifp) 1401if_down(struct ifnet *ifp)
1395{ 1402{
1396 struct ifaddr *ifa; 1403 struct ifaddr *ifa;
1397 1404
1398 ifp->if_flags &= ~IFF_UP; 1405 ifp->if_flags &= ~IFF_UP;

cvs diff -r1.164 -r1.165 src/sys/netinet6/in6.c (expand / switch to unified diff)

--- src/sys/netinet6/in6.c 2013/06/11 12:08:29 1.164
+++ src/sys/netinet6/in6.c 2013/06/20 13:56:29 1.165
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: in6.c,v 1.164 2013/06/11 12:08:29 roy Exp $ */ 1/* $NetBSD: in6.c,v 1.165 2013/06/20 13:56:29 roy Exp $ */
2/* $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $ */ 2/* $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -52,27 +52,27 @@ @@ -52,27 +52,27 @@
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE. 59 * SUCH DAMAGE.
60 * 60 *
61 * @(#)in.c 8.2 (Berkeley) 11/15/93 61 * @(#)in.c 8.2 (Berkeley) 11/15/93
62 */ 62 */
63 63
64#include <sys/cdefs.h> 64#include <sys/cdefs.h>
65__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.164 2013/06/11 12:08:29 roy Exp $"); 65__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.165 2013/06/20 13:56:29 roy Exp $");
66 66
67#include "opt_inet.h" 67#include "opt_inet.h"
68#include "opt_pfil_hooks.h" 68#include "opt_pfil_hooks.h"
69#include "opt_compat_netbsd.h" 69#include "opt_compat_netbsd.h"
70 70
71#include <sys/param.h> 71#include <sys/param.h>
72#include <sys/ioctl.h> 72#include <sys/ioctl.h>
73#include <sys/errno.h> 73#include <sys/errno.h>
74#include <sys/malloc.h> 74#include <sys/malloc.h>
75#include <sys/socket.h> 75#include <sys/socket.h>
76#include <sys/socketvar.h> 76#include <sys/socketvar.h>
77#include <sys/sockio.h> 77#include <sys/sockio.h>
78#include <sys/systm.h> 78#include <sys/systm.h>
@@ -2155,27 +2155,27 @@ in6_ifawithifp(struct ifnet *ifp, struct @@ -2155,27 +2155,27 @@ in6_ifawithifp(struct ifnet *ifp, struct
2155 /* use the last-resort values, that are, deprecated addresses */ 2155 /* use the last-resort values, that are, deprecated addresses */
2156 if (dep[0]) 2156 if (dep[0])
2157 return dep[0]; 2157 return dep[0];
2158 if (dep[1]) 2158 if (dep[1])
2159 return dep[1]; 2159 return dep[1];
2160 2160
2161 return NULL; 2161 return NULL;
2162} 2162}
2163 2163
2164/* 2164/*
2165 * perform DAD when interface becomes IFF_UP. 2165 * perform DAD when interface becomes IFF_UP.
2166 */ 2166 */
2167void 2167void
2168in6_if_up(struct ifnet *ifp) 2168in6_if_link_up(struct ifnet *ifp)
2169{ 2169{
2170 struct ifaddr *ifa; 2170 struct ifaddr *ifa;
2171 struct in6_ifaddr *ia; 2171 struct in6_ifaddr *ia;
2172 2172
2173 /* Ensure it's sane to run DAD */ 2173 /* Ensure it's sane to run DAD */
2174 if (ifp->if_link_state == LINK_STATE_DOWN) 2174 if (ifp->if_link_state == LINK_STATE_DOWN)
2175 return; 2175 return;
2176 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) 2176 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
2177 return; 2177 return;
2178 2178
2179 IFADDR_FOREACH(ifa, ifp) { 2179 IFADDR_FOREACH(ifa, ifp) {
2180 if (ifa->ifa_addr->sa_family != AF_INET6) 2180 if (ifa->ifa_addr->sa_family != AF_INET6)
2181 continue; 2181 continue;
@@ -2196,72 +2196,86 @@ in6_if_up(struct ifnet *ifp) @@ -2196,72 +2196,86 @@ in6_if_up(struct ifnet *ifp)
2196 if (ia->ia6_flags & IN6_IFF_TENTATIVE) { 2196 if (ia->ia6_flags & IN6_IFF_TENTATIVE) {
2197 /* 2197 /*
2198 * The TENTATIVE flag was likely set by hand 2198 * The TENTATIVE flag was likely set by hand
2199 * beforehand, implicitly indicating the need for DAD. 2199 * beforehand, implicitly indicating the need for DAD.
2200 * We may be able to skip the random delay in this 2200 * We may be able to skip the random delay in this
2201 * case, but we impose delays just in case. 2201 * case, but we impose delays just in case.
2202 */ 2202 */
2203 nd6_dad_start(ifa, 2203 nd6_dad_start(ifa,
2204 cprng_fast32() % 2204 cprng_fast32() %
2205 (MAX_RTR_SOLICITATION_DELAY * hz)); 2205 (MAX_RTR_SOLICITATION_DELAY * hz));
2206 } 2206 }
2207 } 2207 }
2208 2208
 2209 /* Restore any detached prefixes */
 2210 pfxlist_onlink_check();
 2211}
 2212
 2213void
 2214in6_if_up(struct ifnet *ifp)
 2215{
 2216
2209 /* 2217 /*
2210 * special cases, like 6to4, are handled in in6_ifattach 2218 * special cases, like 6to4, are handled in in6_ifattach
2211 */ 2219 */
2212 in6_ifattach(ifp, NULL); 2220 in6_ifattach(ifp, NULL);
2213 2221
2214 /* Restore any detached prefixes */ 2222 /* interface may not support link state, so bring it up also */
2215 pfxlist_onlink_check(); 2223 in6_if_link_up(ifp);
2216} 2224}
2217 
2218/* 2225/*
2219 * Mark all addresses as detached. 2226 * Mark all addresses as detached.
2220 */ 2227 */
2221void 2228void
2222in6_if_down(struct ifnet *ifp) 2229in6_if_link_down(struct ifnet *ifp)
2223{ 2230{
2224 struct ifaddr *ifa; 2231 struct ifaddr *ifa;
2225 struct in6_ifaddr *ia; 2232 struct in6_ifaddr *ia;
2226 2233
 2234 /* Any prefixes on this interface should be detached as well */
 2235 pfxlist_onlink_check();
 2236
2227 IFADDR_FOREACH(ifa, ifp) { 2237 IFADDR_FOREACH(ifa, ifp) {
2228 if (ifa->ifa_addr->sa_family != AF_INET6) 2238 if (ifa->ifa_addr->sa_family != AF_INET6)
2229 continue; 2239 continue;
2230 ia = (struct in6_ifaddr *)ifa; 2240 ia = (struct in6_ifaddr *)ifa;
2231 2241
2232 /* Stop DAD processing */ 2242 /* Stop DAD processing */
2233 nd6_dad_stop(ifa); 2243 nd6_dad_stop(ifa);
2234 2244
2235 /* 2245 /*
2236 * Mark the address as detached. 2246 * Mark the address as detached.
2237 * This satisfies RFC4862 Section 5.3, but we should apply 2247 * This satisfies RFC4862 Section 5.3, but we should apply
2238 * this logic to all addresses to be a good citizen and 2248 * this logic to all addresses to be a good citizen and
2239 * avoid potential duplicated addresses. 2249 * avoid potential duplicated addresses.
2240 * When the interface comes up again, detached addresses 2250 * When the interface comes up again, detached addresses
2241 * are marked tentative and DAD commences. 2251 * are marked tentative and DAD commences.
2242 */ 2252 */
2243 if (!(ia->ia6_flags & IN6_IFF_DETACHED)) { 2253 if (!(ia->ia6_flags & IN6_IFF_DETACHED)) {
2244 nd6log((LOG_DEBUG, "in6_if_down: " 2254 nd6log((LOG_DEBUG, "in6_if_down: "
2245 "%s marked detached\n", 2255 "%s marked detached\n",
2246 ip6_sprintf(&ia->ia_addr.sin6_addr))); 2256 ip6_sprintf(&ia->ia_addr.sin6_addr)));
2247 ia->ia6_flags |= IN6_IFF_DETACHED; 2257 ia->ia6_flags |= IN6_IFF_DETACHED;
2248 ia->ia6_flags &= ~IN6_IFF_TENTATIVE; 2258 ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
2249 nd6_newaddrmsg(ifa); 2259 nd6_newaddrmsg(ifa);
2250 } 2260 }
2251 } 2261 }
 2262}
2252 2263
2253 /* Any prefixes on this interface should be detached as well */ 2264void
2254 pfxlist_onlink_check(); 2265in6_if_down(struct ifnet *ifp)
 2266{
 2267
 2268 in6_if_link_down(ifp);
2255} 2269}
2256 2270
2257int 2271int
2258in6if_do_dad(struct ifnet *ifp) 2272in6if_do_dad(struct ifnet *ifp)
2259{ 2273{
2260 if ((ifp->if_flags & IFF_LOOPBACK) != 0) 2274 if ((ifp->if_flags & IFF_LOOPBACK) != 0)
2261 return 0; 2275 return 0;
2262 2276
2263 switch (ifp->if_type) { 2277 switch (ifp->if_type) {
2264 case IFT_FAITH: 2278 case IFT_FAITH:
2265 /* 2279 /*
2266 * These interfaces do not have the IFF_LOOPBACK flag, 2280 * These interfaces do not have the IFF_LOOPBACK flag,
2267 * but loop packets back. We do not have to do DAD on such 2281 * but loop packets back. We do not have to do DAD on such

cvs diff -r1.72 -r1.73 src/sys/netinet6/in6.h (expand / switch to unified diff)

--- src/sys/netinet6/in6.h 2013/06/11 12:08:29 1.72
+++ src/sys/netinet6/in6.h 2013/06/20 13:56:29 1.73
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: in6.h,v 1.72 2013/06/11 12:08:29 roy Exp $ */ 1/* $NetBSD: in6.h,v 1.73 2013/06/20 13:56:29 roy Exp $ */
2/* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */ 2/* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -690,26 +690,28 @@ in6_cksum_phdr(const struct in6_addr *sr @@ -690,26 +690,28 @@ in6_cksum_phdr(const struct in6_addr *sr
690 return (sum); 690 return (sum);
691} 691}
692 692
693struct mbuf; 693struct mbuf;
694struct ifnet; 694struct ifnet;
695int sockaddr_in6_cmp(const struct sockaddr *, const struct sockaddr *); 695int sockaddr_in6_cmp(const struct sockaddr *, const struct sockaddr *);
696struct sockaddr *sockaddr_in6_externalize(struct sockaddr *, socklen_t, 696struct sockaddr *sockaddr_in6_externalize(struct sockaddr *, socklen_t,
697 const struct sockaddr *); 697 const struct sockaddr *);
698int in6_cksum(struct mbuf *, u_int8_t, u_int32_t, u_int32_t); 698int in6_cksum(struct mbuf *, u_int8_t, u_int32_t, u_int32_t);
699void in6_delayed_cksum(struct mbuf *); 699void in6_delayed_cksum(struct mbuf *);
700int in6_localaddr(const struct in6_addr *); 700int in6_localaddr(const struct in6_addr *);
701int in6_addrscope(const struct in6_addr *); 701int in6_addrscope(const struct in6_addr *);
702struct in6_ifaddr *in6_ifawithifp(struct ifnet *, struct in6_addr *); 702struct in6_ifaddr *in6_ifawithifp(struct ifnet *, struct in6_addr *);
 703extern void in6_if_link_up(struct ifnet *);
 704extern void in6_if_link_down(struct ifnet *);
703extern void in6_if_up(struct ifnet *); 705extern void in6_if_up(struct ifnet *);
704extern void in6_if_down(struct ifnet *); 706extern void in6_if_down(struct ifnet *);
705#ifndef __FreeBSD__ 707#ifndef __FreeBSD__
706extern int in6_src_sysctl(void *, size_t *, void *, size_t); 708extern int in6_src_sysctl(void *, size_t *, void *, size_t);
707#endif 709#endif
708extern void addrsel_policy_init(void); 710extern void addrsel_policy_init(void);
709extern u_char ip6_protox[]; 711extern u_char ip6_protox[];
710 712
711#define satosin6(sa) ((struct sockaddr_in6 *)(sa)) 713#define satosin6(sa) ((struct sockaddr_in6 *)(sa))
712#define satocsin6(sa) ((const struct sockaddr_in6 *)(sa)) 714#define satocsin6(sa) ((const struct sockaddr_in6 *)(sa))
713#define sin6tosa(sin6) ((struct sockaddr *)(sin6)) 715#define sin6tosa(sin6) ((struct sockaddr *)(sin6))
714#define sin6tocsa(sin6) ((const struct sockaddr *)(sin6)) 716#define sin6tocsa(sin6) ((const struct sockaddr *)(sin6))
715#define ifatoia6(ifa) ((struct in6_ifaddr *)(ifa)) 717#define ifatoia6(ifa) ((struct in6_ifaddr *)(ifa))

cvs diff -r1.88 -r1.89 src/sys/netinet6/nd6_rtr.c (expand / switch to unified diff)

--- src/sys/netinet6/nd6_rtr.c 2013/06/11 12:08:29 1.88
+++ src/sys/netinet6/nd6_rtr.c 2013/06/20 13:56:29 1.89
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: nd6_rtr.c,v 1.88 2013/06/11 12:08:29 roy Exp $ */ 1/* $NetBSD: nd6_rtr.c,v 1.89 2013/06/20 13:56:29 roy Exp $ */
2/* $KAME: nd6_rtr.c,v 1.95 2001/02/07 08:09:47 itojun Exp $ */ 2/* $KAME: nd6_rtr.c,v 1.95 2001/02/07 08:09:47 itojun Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE. 30 * SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.88 2013/06/11 12:08:29 roy Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.89 2013/06/20 13:56:29 roy Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38#include <sys/malloc.h> 38#include <sys/malloc.h>
39#include <sys/mbuf.h> 39#include <sys/mbuf.h>
40#include <sys/socket.h> 40#include <sys/socket.h>
41#include <sys/sockio.h> 41#include <sys/sockio.h>
42#include <sys/time.h> 42#include <sys/time.h>
43#include <sys/kernel.h> 43#include <sys/kernel.h>
44#include <sys/errno.h> 44#include <sys/errno.h>
45#include <sys/ioctl.h> 45#include <sys/ioctl.h>
46#include <sys/syslog.h> 46#include <sys/syslog.h>
47#include <sys/cprng.h> 47#include <sys/cprng.h>
@@ -1394,31 +1394,32 @@ prelist_update(struct nd_prefixctl *new, @@ -1394,31 +1394,32 @@ prelist_update(struct nd_prefixctl *new,
1394 * A supplement function used in the on-link detection below; 1394 * A supplement function used in the on-link detection below;
1395 * detect if a given prefix has a (probably) reachable advertising router. 1395 * detect if a given prefix has a (probably) reachable advertising router.
1396 * XXX: lengthy function name... 1396 * XXX: lengthy function name...
1397 */ 1397 */
1398static struct nd_pfxrouter * 1398static struct nd_pfxrouter *
1399find_pfxlist_reachable_router(struct nd_prefix *pr) 1399find_pfxlist_reachable_router(struct nd_prefix *pr)
1400{ 1400{
1401 struct nd_pfxrouter *pfxrtr; 1401 struct nd_pfxrouter *pfxrtr;
1402 struct rtentry *rt; 1402 struct rtentry *rt;
1403 struct llinfo_nd6 *ln; 1403 struct llinfo_nd6 *ln;
1404 1404
1405 for (pfxrtr = LIST_FIRST(&pr->ndpr_advrtrs); pfxrtr; 1405 for (pfxrtr = LIST_FIRST(&pr->ndpr_advrtrs); pfxrtr;
1406 pfxrtr = LIST_NEXT(pfxrtr, pfr_entry)) { 1406 pfxrtr = LIST_NEXT(pfxrtr, pfr_entry)) {
1407 if ((rt = nd6_lookup(&pfxrtr->router->rtaddr, 0, 1407 if (pfxrtr->router->ifp->if_flags & IFF_UP &&
 1408 pfxrtr->router->ifp->if_link_state != LINK_STATE_DOWN &&
 1409 (rt = nd6_lookup(&pfxrtr->router->rtaddr, 0,
1408 pfxrtr->router->ifp)) && 1410 pfxrtr->router->ifp)) &&
1409 (ln = (struct llinfo_nd6 *)rt->rt_llinfo) && 1411 (ln = (struct llinfo_nd6 *)rt->rt_llinfo) &&
1410 ND6_IS_LLINFO_PROBREACH(ln) && 1412 ND6_IS_LLINFO_PROBREACH(ln))
1411 pfxrtr->router->ifp->if_link_state != LINK_STATE_DOWN) 
1412 break; /* found */ 1413 break; /* found */
1413 } 1414 }
1414 1415
1415 return (pfxrtr); 1416 return (pfxrtr);
1416} 1417}
1417 1418
1418/* 1419/*
1419 * Check if each prefix in the prefix list has at least one available router 1420 * Check if each prefix in the prefix list has at least one available router
1420 * that advertised the prefix (a router is "available" if its neighbor cache 1421 * that advertised the prefix (a router is "available" if its neighbor cache
1421 * entry is reachable or probably reachable). 1422 * entry is reachable or probably reachable).
1422 * If the check fails, the prefix may be off-link, because, for example, 1423 * If the check fails, the prefix may be off-link, because, for example,
1423 * we have moved from the network but the lifetime of the prefix has not 1424 * we have moved from the network but the lifetime of the prefix has not
1424 * expired yet. So we should not use the prefix if there is another prefix 1425 * expired yet. So we should not use the prefix if there is another prefix