Deleted Added
full compact
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 ---