nd6_nbr.c (279564) | nd6_nbr.c (279676) |
---|---|
1/*- 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $KAME: nd6_nbr.c,v 1.86 2002/01/21 02:33:04 jinmei Exp $ 30 */ 31 32#include <sys/cdefs.h> | 1/*- 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $KAME: nd6_nbr.c,v 1.86 2002/01/21 02:33:04 jinmei Exp $ 30 */ 31 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/sys/netinet6/nd6_nbr.c 279564 2015-03-03 10:50:03Z ae $"); | 33__FBSDID("$FreeBSD: head/sys/netinet6/nd6_nbr.c 279676 2015-03-05 21:27:49Z hrs $"); |
34 35#include "opt_inet.h" 36#include "opt_inet6.h" 37#include "opt_ipsec.h" 38#include "opt_mpath.h" 39 40#include <sys/param.h> 41#include <sys/systm.h> --- 1135 unchanged lines hidden (view full) --- 1177 TAILQ_ENTRY(dadq) dad_list; 1178 struct ifaddr *dad_ifa; 1179 int dad_count; /* max NS to send */ 1180 int dad_ns_tcount; /* # of trials to send NS */ 1181 int dad_ns_ocount; /* NS sent so far */ 1182 int dad_ns_icount; 1183 int dad_na_icount; 1184 int dad_ns_lcount; /* looped back NS */ | 34 35#include "opt_inet.h" 36#include "opt_inet6.h" 37#include "opt_ipsec.h" 38#include "opt_mpath.h" 39 40#include <sys/param.h> 41#include <sys/systm.h> --- 1135 unchanged lines hidden (view full) --- 1177 TAILQ_ENTRY(dadq) dad_list; 1178 struct ifaddr *dad_ifa; 1179 int dad_count; /* max NS to send */ 1180 int dad_ns_tcount; /* # of trials to send NS */ 1181 int dad_ns_ocount; /* NS sent so far */ 1182 int dad_ns_icount; 1183 int dad_na_icount; 1184 int dad_ns_lcount; /* looped back NS */ |
1185 int dad_loopbackprobe; /* probing state for loopback detection */ |
|
1185 struct callout dad_timer_ch; 1186 struct vnet *dad_vnet; 1187 u_int dad_refcnt; 1188#define ND_OPT_NONCE_LEN32 \ 1189 ((ND_OPT_NONCE_LEN + sizeof(uint32_t) - 1)/sizeof(uint32_t)) 1190 uint32_t dad_nonce[ND_OPT_NONCE_LEN32]; 1191}; 1192 --- 25 unchanged lines hidden (view full) --- 1218 DADQ_WUNLOCK(); 1219 nd6_dad_rele(dp); 1220} 1221 1222static struct dadq * 1223nd6_dad_find(struct ifaddr *ifa, struct nd_opt_nonce *n) 1224{ 1225 struct dadq *dp; | 1186 struct callout dad_timer_ch; 1187 struct vnet *dad_vnet; 1188 u_int dad_refcnt; 1189#define ND_OPT_NONCE_LEN32 \ 1190 ((ND_OPT_NONCE_LEN + sizeof(uint32_t) - 1)/sizeof(uint32_t)) 1191 uint32_t dad_nonce[ND_OPT_NONCE_LEN32]; 1192}; 1193 --- 25 unchanged lines hidden (view full) --- 1219 DADQ_WUNLOCK(); 1220 nd6_dad_rele(dp); 1221} 1222 1223static struct dadq * 1224nd6_dad_find(struct ifaddr *ifa, struct nd_opt_nonce *n) 1225{ 1226 struct dadq *dp; |
1226 char ip6buf[INET6_ADDRSTRLEN]; | |
1227 1228 DADQ_RLOCK(); 1229 TAILQ_FOREACH(dp, &V_dadq, dad_list) { 1230 if (dp->dad_ifa != ifa) 1231 continue; 1232 /* 1233 * Skip if the nonce matches the received one. 1234 * +2 in the length is required because of type and 1235 * length fields are included in a header. 1236 */ 1237 if (n != NULL && 1238 n->nd_opt_nonce_len == (ND_OPT_NONCE_LEN + 2) / 8 && 1239 memcmp(&n->nd_opt_nonce[0], &dp->dad_nonce[0], 1240 ND_OPT_NONCE_LEN) == 0) { | 1227 1228 DADQ_RLOCK(); 1229 TAILQ_FOREACH(dp, &V_dadq, dad_list) { 1230 if (dp->dad_ifa != ifa) 1231 continue; 1232 /* 1233 * Skip if the nonce matches the received one. 1234 * +2 in the length is required because of type and 1235 * length fields are included in a header. 1236 */ 1237 if (n != NULL && 1238 n->nd_opt_nonce_len == (ND_OPT_NONCE_LEN + 2) / 8 && 1239 memcmp(&n->nd_opt_nonce[0], &dp->dad_nonce[0], 1240 ND_OPT_NONCE_LEN) == 0) { |
1241 log(LOG_ERR, "%s: a looped back NS message is " 1242 "detected during DAD for %s.\n", 1243 if_name(ifa->ifa_ifp), 1244 ip6_sprintf(ip6buf, IFA_IN6(ifa))); | |
1245 dp->dad_ns_lcount++; 1246 continue; 1247 } 1248 refcount_acquire(&dp->dad_refcnt); 1249 break; 1250 } 1251 DADQ_RUNLOCK(); 1252 --- 99 unchanged lines hidden (view full) --- 1352 * first packet to be sent from the interface after interface 1353 * (re)initialization. 1354 */ 1355 dp->dad_ifa = ifa; 1356 ifa_ref(dp->dad_ifa); 1357 dp->dad_count = V_ip6_dad_count; 1358 dp->dad_ns_icount = dp->dad_na_icount = 0; 1359 dp->dad_ns_ocount = dp->dad_ns_tcount = 0; | 1241 dp->dad_ns_lcount++; 1242 continue; 1243 } 1244 refcount_acquire(&dp->dad_refcnt); 1245 break; 1246 } 1247 DADQ_RUNLOCK(); 1248 --- 99 unchanged lines hidden (view full) --- 1348 * first packet to be sent from the interface after interface 1349 * (re)initialization. 1350 */ 1351 dp->dad_ifa = ifa; 1352 ifa_ref(dp->dad_ifa); 1353 dp->dad_count = V_ip6_dad_count; 1354 dp->dad_ns_icount = dp->dad_na_icount = 0; 1355 dp->dad_ns_ocount = dp->dad_ns_tcount = 0; |
1360 dp->dad_ns_lcount = 0; | 1356 dp->dad_ns_lcount = dp->dad_loopbackprobe = 0; |
1361 refcount_init(&dp->dad_refcnt, 1); 1362 nd6_dad_add(dp); 1363 if (delay == 0) { 1364 nd6_dad_ns_output(dp, ifa); 1365 nd6_dad_starttimer(dp, 1366 (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); 1367 } else { 1368 nd6_dad_starttimer(dp, delay); --- 58 unchanged lines hidden (view full) --- 1427 if ((ia->ia6_flags & IN6_IFF_TENTATIVE) == 0) { 1428 log(LOG_ERR, "nd6_dad_timer: called with non-tentative address " 1429 "%s(%s)\n", 1430 ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr), 1431 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1432 goto err; 1433 } 1434 | 1357 refcount_init(&dp->dad_refcnt, 1); 1358 nd6_dad_add(dp); 1359 if (delay == 0) { 1360 nd6_dad_ns_output(dp, ifa); 1361 nd6_dad_starttimer(dp, 1362 (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); 1363 } else { 1364 nd6_dad_starttimer(dp, delay); --- 58 unchanged lines hidden (view full) --- 1423 if ((ia->ia6_flags & IN6_IFF_TENTATIVE) == 0) { 1424 log(LOG_ERR, "nd6_dad_timer: called with non-tentative address " 1425 "%s(%s)\n", 1426 ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr), 1427 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1428 goto err; 1429 } 1430 |
1435 /* timeouted with IFF_{RUNNING,UP} check */ 1436 if (dp->dad_ns_tcount > V_dad_maxtry) { | 1431 /* Stop DAD if the interface is down even after dad_maxtry attempts. */ 1432 if ((dp->dad_ns_tcount > V_dad_maxtry) && 1433 (((ifp->if_flags & IFF_UP) == 0) || 1434 ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0))) { |
1437 nd6log((LOG_INFO, "%s: could not run DAD, driver problem?\n", 1438 if_name(ifa->ifa_ifp))); 1439 goto err; 1440 } 1441 1442 /* Need more checks? */ 1443 if (dp->dad_ns_ocount < dp->dad_count) { 1444 /* --- 6 unchanged lines hidden (view full) --- 1451 } else { 1452 /* 1453 * We have transmitted sufficient number of DAD packets. 1454 * See what we've got. 1455 */ 1456 if (dp->dad_ns_icount > 0 || dp->dad_na_icount > 0) 1457 /* We've seen NS or NA, means DAD has failed. */ 1458 nd6_dad_duplicated(ifa, dp); | 1435 nd6log((LOG_INFO, "%s: could not run DAD, driver problem?\n", 1436 if_name(ifa->ifa_ifp))); 1437 goto err; 1438 } 1439 1440 /* Need more checks? */ 1441 if (dp->dad_ns_ocount < dp->dad_count) { 1442 /* --- 6 unchanged lines hidden (view full) --- 1449 } else { 1450 /* 1451 * We have transmitted sufficient number of DAD packets. 1452 * See what we've got. 1453 */ 1454 if (dp->dad_ns_icount > 0 || dp->dad_na_icount > 0) 1455 /* We've seen NS or NA, means DAD has failed. */ 1456 nd6_dad_duplicated(ifa, dp); |
1459 else { | 1457 else if (V_dad_enhanced != 0 && 1458 dp->dad_ns_lcount > 0 && 1459 dp->dad_ns_lcount > dp->dad_loopbackprobe) { |
1460 /* | 1460 /* |
1461 * A looped back probe is detected, 1462 * Sec. 4.1 in draft-ietf-6man-enhanced-dad-13 1463 * requires transmission of additional probes until 1464 * the loopback condition becomes clear. 1465 */ 1466 log(LOG_ERR, "%s: a looped back NS message is " 1467 "detected during DAD for %s. " 1468 "Another DAD probes are being sent.\n", 1469 if_name(ifa->ifa_ifp), 1470 ip6_sprintf(ip6buf, IFA_IN6(ifa))); 1471 dp->dad_loopbackprobe = dp->dad_ns_lcount; 1472 /* 1473 * An interface with IGNORELOOP is one which a 1474 * loopback is permanently expected while regular 1475 * traffic works. In that case, stop DAD after 1476 * MAX_MULTICAST_SOLICIT number of NS messages 1477 * regardless of the number of received loopback NS 1478 * by increasing dad_loopbackprobe in advance. 1479 */ 1480 if (ND_IFINFO(ifa->ifa_ifp)->flags & ND6_IFF_IGNORELOOP) 1481 dp->dad_loopbackprobe += V_nd6_mmaxtries; 1482 /* 1483 * Send an NS immediately and increase dad_count by 1484 * V_nd6_mmaxtries - 1. 1485 */ 1486 nd6_dad_ns_output(dp, ifa); 1487 dp->dad_count = 1488 dp->dad_ns_ocount + V_nd6_mmaxtries - 1; 1489 nd6_dad_starttimer(dp, 1490 (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); 1491 goto done; 1492 } else { 1493 /* |
|
1461 * We are done with DAD. No NA came, no NS came. 1462 * No duplicate address found. Check IFDISABLED flag 1463 * again in case that it is changed between the 1464 * beginning of this function and here. 1465 */ 1466 if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) == 0) 1467 ia->ia6_flags &= ~IN6_IFF_TENTATIVE; 1468 1469 nd6log((LOG_DEBUG, 1470 "%s: DAD complete for %s - no duplicates found\n", 1471 if_name(ifa->ifa_ifp), 1472 ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr))); | 1494 * We are done with DAD. No NA came, no NS came. 1495 * No duplicate address found. Check IFDISABLED flag 1496 * again in case that it is changed between the 1497 * beginning of this function and here. 1498 */ 1499 if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) == 0) 1500 ia->ia6_flags &= ~IN6_IFF_TENTATIVE; 1501 1502 nd6log((LOG_DEBUG, 1503 "%s: DAD complete for %s - no duplicates found\n", 1504 if_name(ifa->ifa_ifp), 1505 ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr))); |
1506 if (dp->dad_ns_lcount > 0) 1507 log(LOG_ERR, "%s: DAD completed while " 1508 "a looped back NS message is detected " 1509 "during DAD for %s.\n", 1510 if_name(ifa->ifa_ifp), 1511 ip6_sprintf(ip6buf, IFA_IN6(ifa))); |
|
1473 } 1474 } 1475err: 1476 nd6_dad_del(dp); 1477done: 1478 CURVNET_RESTORE(); 1479} 1480 --- 129 unchanged lines hidden --- | 1512 } 1513 } 1514err: 1515 nd6_dad_del(dp); 1516done: 1517 CURVNET_RESTORE(); 1518} 1519 --- 129 unchanged lines hidden --- |