nd6.c (08b68b0e4c6b132127919cfbaf7275c727ca7843) nd6.c (3b0b2840be64ee1ed67bc6939c412b59bfaac2c7)
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

--- 558 unchanged lines hidden (view full) ---

567/*
568 * ND6 timer routine to expire default route list and prefix list
569 */
570void
571nd6_timer(void *arg)
572{
573 CURVNET_SET((struct vnet *) arg);
574 int s;
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

--- 558 unchanged lines hidden (view full) ---

567/*
568 * ND6 timer routine to expire default route list and prefix list
569 */
570void
571nd6_timer(void *arg)
572{
573 CURVNET_SET((struct vnet *) arg);
574 int s;
575 struct nd_defrouter *dr;
576 struct nd_prefix *pr;
575 struct nd_defrouter *dr, *ndr;
576 struct nd_prefix *pr, *npr;
577 struct in6_ifaddr *ia6, *nia6;
578 struct in6_addrlifetime *lt6;
579
580 callout_reset(&V_nd6_timer_ch, V_nd6_prune * hz,
581 nd6_timer, curvnet);
582
583 /* expire default router list */
584 s = splnet();
577 struct in6_ifaddr *ia6, *nia6;
578 struct in6_addrlifetime *lt6;
579
580 callout_reset(&V_nd6_timer_ch, V_nd6_prune * hz,
581 nd6_timer, curvnet);
582
583 /* expire default router list */
584 s = splnet();
585 dr = TAILQ_FIRST(&V_nd_defrouter);
586 while (dr) {
587 if (dr->expire && dr->expire < time_second) {
588 struct nd_defrouter *t;
589 t = TAILQ_NEXT(dr, dr_entry);
585 TAILQ_FOREACH_SAFE(dr, &V_nd_defrouter, dr_entry, ndr) {
586 if (dr->expire && dr->expire < time_second)
590 defrtrlist_del(dr);
587 defrtrlist_del(dr);
591 dr = t;
592 } else {
593 dr = TAILQ_NEXT(dr, dr_entry);
594 }
595 }
596
597 /*
598 * expire interface addresses.
599 * in the past the loop was inside prefix expiry processing.
600 * However, from a stricter speci-confrmance standpoint, we should
601 * rather separate address lifetimes and prefix lifetimes.
602 *

--- 60 unchanged lines hidden (view full) ---

663 * A new RA might have made a deprecated address
664 * preferred.
665 */
666 ia6->ia6_flags &= ~IN6_IFF_DEPRECATED;
667 }
668 }
669
670 /* expire prefix list */
588 }
589
590 /*
591 * expire interface addresses.
592 * in the past the loop was inside prefix expiry processing.
593 * However, from a stricter speci-confrmance standpoint, we should
594 * rather separate address lifetimes and prefix lifetimes.
595 *

--- 60 unchanged lines hidden (view full) ---

656 * A new RA might have made a deprecated address
657 * preferred.
658 */
659 ia6->ia6_flags &= ~IN6_IFF_DEPRECATED;
660 }
661 }
662
663 /* expire prefix list */
671 pr = V_nd_prefix.lh_first;
672 while (pr) {
664 LIST_FOREACH_SAFE(pr, &V_nd_prefix, ndpr_entry, npr) {
673 /*
674 * check prefix lifetime.
675 * since pltime is just for autoconf, pltime processing for
676 * prefix is not necessary.
677 */
678 if (pr->ndpr_vltime != ND6_INFINITE_LIFETIME &&
679 time_second - pr->ndpr_lastupdate > pr->ndpr_vltime) {
665 /*
666 * check prefix lifetime.
667 * since pltime is just for autoconf, pltime processing for
668 * prefix is not necessary.
669 */
670 if (pr->ndpr_vltime != ND6_INFINITE_LIFETIME &&
671 time_second - pr->ndpr_lastupdate > pr->ndpr_vltime) {
680 struct nd_prefix *t;
681 t = pr->ndpr_next;
682
683 /*
684 * address expiration and prefix expiration are
685 * separate. NEVER perform in6_purgeaddr here.
686 */
672
673 /*
674 * address expiration and prefix expiration are
675 * separate. NEVER perform in6_purgeaddr here.
676 */
687
688 prelist_remove(pr);
677 prelist_remove(pr);
689 pr = t;
690 } else
691 pr = pr->ndpr_next;
678 }
692 }
693 splx(s);
694 CURVNET_RESTORE();
695}
696
697/*
698 * ia6 - deprecated/invalidated temporary address
699 */

--- 76 unchanged lines hidden (view full) ---

776 struct nd_prefix *pr, *npr;
777
778 /*
779 * Nuke default router list entries toward ifp.
780 * We defer removal of default router list entries that is installed
781 * in the routing table, in order to keep additional side effects as
782 * small as possible.
783 */
679 }
680 splx(s);
681 CURVNET_RESTORE();
682}
683
684/*
685 * ia6 - deprecated/invalidated temporary address
686 */

--- 76 unchanged lines hidden (view full) ---

763 struct nd_prefix *pr, *npr;
764
765 /*
766 * Nuke default router list entries toward ifp.
767 * We defer removal of default router list entries that is installed
768 * in the routing table, in order to keep additional side effects as
769 * small as possible.
770 */
784 for (dr = TAILQ_FIRST(&V_nd_defrouter); dr; dr = ndr) {
785 ndr = TAILQ_NEXT(dr, dr_entry);
771 TAILQ_FOREACH_SAFE(dr, &V_nd_defrouter, dr_entry, ndr) {
786 if (dr->installed)
787 continue;
788
789 if (dr->ifp == ifp)
790 defrtrlist_del(dr);
791 }
792
772 if (dr->installed)
773 continue;
774
775 if (dr->ifp == ifp)
776 defrtrlist_del(dr);
777 }
778
793 for (dr = TAILQ_FIRST(&V_nd_defrouter); dr; dr = ndr) {
794 ndr = TAILQ_NEXT(dr, dr_entry);
779 TAILQ_FOREACH_SAFE(dr, &V_nd_defrouter, dr_entry, ndr) {
795 if (!dr->installed)
796 continue;
797
798 if (dr->ifp == ifp)
799 defrtrlist_del(dr);
800 }
801
802 /* Nuke prefix list entries toward ifp */
780 if (!dr->installed)
781 continue;
782
783 if (dr->ifp == ifp)
784 defrtrlist_del(dr);
785 }
786
787 /* Nuke prefix list entries toward ifp */
803 for (pr = V_nd_prefix.lh_first; pr; pr = npr) {
804 npr = pr->ndpr_next;
788 LIST_FOREACH_SAFE(pr, &V_nd_prefix, ndpr_entry, npr) {
805 if (pr->ndpr_ifp == ifp) {
806 /*
807 * Because if_detach() does *not* release prefixes
808 * while purging addresses the reference count will
809 * still be above zero. We therefore reset it to
810 * make sure that the prefix really gets purged.
811 */
812 pr->ndpr_refcnt = 0;

--- 94 unchanged lines hidden (view full) ---

907 }
908
909 /*
910 * If the address matches one of our addresses,
911 * it should be a neighbor.
912 * If the address matches one of our on-link prefixes, it should be a
913 * neighbor.
914 */
789 if (pr->ndpr_ifp == ifp) {
790 /*
791 * Because if_detach() does *not* release prefixes
792 * while purging addresses the reference count will
793 * still be above zero. We therefore reset it to
794 * make sure that the prefix really gets purged.
795 */
796 pr->ndpr_refcnt = 0;

--- 94 unchanged lines hidden (view full) ---

891 }
892
893 /*
894 * If the address matches one of our addresses,
895 * it should be a neighbor.
896 * If the address matches one of our on-link prefixes, it should be a
897 * neighbor.
898 */
915 for (pr = V_nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
899 LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) {
916 if (pr->ndpr_ifp != ifp)
917 continue;
918
919 if (!(pr->ndpr_stateflags & NDPRF_ONLINK)) {
920 struct rtentry *rt;
921 rt = rtalloc1((struct sockaddr *)&pr->ndpr_prefix, 0, 0);
922 if (rt == NULL)
923 continue;

--- 33 unchanged lines hidden (view full) ---

957 ifa_free(dstaddr);
958 }
959
960 /*
961 * If the default router list is empty, all addresses are regarded
962 * as on-link, and thus, as a neighbor.
963 */
964 if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV &&
900 if (pr->ndpr_ifp != ifp)
901 continue;
902
903 if (!(pr->ndpr_stateflags & NDPRF_ONLINK)) {
904 struct rtentry *rt;
905 rt = rtalloc1((struct sockaddr *)&pr->ndpr_prefix, 0, 0);
906 if (rt == NULL)
907 continue;

--- 33 unchanged lines hidden (view full) ---

941 ifa_free(dstaddr);
942 }
943
944 /*
945 * If the default router list is empty, all addresses are regarded
946 * as on-link, and thus, as a neighbor.
947 */
948 if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV &&
965 TAILQ_FIRST(&V_nd_defrouter) == NULL &&
949 TAILQ_EMPTY(&V_nd_defrouter) &&
966 V_nd6_defifindex == ifp->if_index) {
967 return (1);
968 }
969
970 return (0);
971}
972
973

--- 255 unchanged lines hidden (view full) ---

1229
1230 switch (cmd) {
1231 case SIOCGDRLST_IN6:
1232 /*
1233 * obsolete API, use sysctl under net.inet6.icmp6
1234 */
1235 bzero(drl, sizeof(*drl));
1236 s = splnet();
950 V_nd6_defifindex == ifp->if_index) {
951 return (1);
952 }
953
954 return (0);
955}
956
957

--- 255 unchanged lines hidden (view full) ---

1213
1214 switch (cmd) {
1215 case SIOCGDRLST_IN6:
1216 /*
1217 * obsolete API, use sysctl under net.inet6.icmp6
1218 */
1219 bzero(drl, sizeof(*drl));
1220 s = splnet();
1237 dr = TAILQ_FIRST(&V_nd_defrouter);
1238 while (dr && i < DRLSTSIZ) {
1221 TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) {
1222 if (i >= DRLSTSIZ)
1223 break;
1239 drl->defrouter[i].rtaddr = dr->rtaddr;
1240 in6_clearscope(&drl->defrouter[i].rtaddr);
1241
1242 drl->defrouter[i].flags = dr->flags;
1243 drl->defrouter[i].rtlifetime = dr->rtlifetime;
1244 drl->defrouter[i].expire = dr->expire;
1245 drl->defrouter[i].if_index = dr->ifp->if_index;
1246 i++;
1224 drl->defrouter[i].rtaddr = dr->rtaddr;
1225 in6_clearscope(&drl->defrouter[i].rtaddr);
1226
1227 drl->defrouter[i].flags = dr->flags;
1228 drl->defrouter[i].rtlifetime = dr->rtlifetime;
1229 drl->defrouter[i].expire = dr->expire;
1230 drl->defrouter[i].if_index = dr->ifp->if_index;
1231 i++;
1247 dr = TAILQ_NEXT(dr, dr_entry);
1248 }
1249 splx(s);
1250 break;
1251 case SIOCGPRLST_IN6:
1252 /*
1253 * obsolete API, use sysctl under net.inet6.icmp6
1254 *
1255 * XXX the structure in6_prlist was changed in backward-
1256 * incompatible manner. in6_oprlist is used for SIOCGPRLST_IN6,
1257 * in6_prlist is used for nd6_sysctl() - fill_prlist().
1258 */
1259 /*
1260 * XXX meaning of fields, especialy "raflags", is very
1261 * differnet between RA prefix list and RR/static prefix list.
1262 * how about separating ioctls into two?
1263 */
1264 bzero(oprl, sizeof(*oprl));
1265 s = splnet();
1232 }
1233 splx(s);
1234 break;
1235 case SIOCGPRLST_IN6:
1236 /*
1237 * obsolete API, use sysctl under net.inet6.icmp6
1238 *
1239 * XXX the structure in6_prlist was changed in backward-
1240 * incompatible manner. in6_oprlist is used for SIOCGPRLST_IN6,
1241 * in6_prlist is used for nd6_sysctl() - fill_prlist().
1242 */
1243 /*
1244 * XXX meaning of fields, especialy "raflags", is very
1245 * differnet between RA prefix list and RR/static prefix list.
1246 * how about separating ioctls into two?
1247 */
1248 bzero(oprl, sizeof(*oprl));
1249 s = splnet();
1266 pr = V_nd_prefix.lh_first;
1267 while (pr && i < PRLSTSIZ) {
1250 LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) {
1268 struct nd_pfxrouter *pfr;
1269 int j;
1270
1251 struct nd_pfxrouter *pfr;
1252 int j;
1253
1254 if (i >= PRLSTSIZ)
1255 break;
1271 oprl->prefix[i].prefix = pr->ndpr_prefix.sin6_addr;
1272 oprl->prefix[i].raflags = pr->ndpr_raf;
1273 oprl->prefix[i].prefixlen = pr->ndpr_plen;
1274 oprl->prefix[i].vltime = pr->ndpr_vltime;
1275 oprl->prefix[i].pltime = pr->ndpr_pltime;
1276 oprl->prefix[i].if_index = pr->ndpr_ifp->if_index;
1277 if (pr->ndpr_vltime == ND6_INFINITE_LIFETIME)
1278 oprl->prefix[i].expire = 0;

--- 8 unchanged lines hidden (view full) ---

1287 maxexpire - pr->ndpr_lastupdate) {
1288 oprl->prefix[i].expire =
1289 pr->ndpr_lastupdate +
1290 pr->ndpr_vltime;
1291 } else
1292 oprl->prefix[i].expire = maxexpire;
1293 }
1294
1256 oprl->prefix[i].prefix = pr->ndpr_prefix.sin6_addr;
1257 oprl->prefix[i].raflags = pr->ndpr_raf;
1258 oprl->prefix[i].prefixlen = pr->ndpr_plen;
1259 oprl->prefix[i].vltime = pr->ndpr_vltime;
1260 oprl->prefix[i].pltime = pr->ndpr_pltime;
1261 oprl->prefix[i].if_index = pr->ndpr_ifp->if_index;
1262 if (pr->ndpr_vltime == ND6_INFINITE_LIFETIME)
1263 oprl->prefix[i].expire = 0;

--- 8 unchanged lines hidden (view full) ---

1272 maxexpire - pr->ndpr_lastupdate) {
1273 oprl->prefix[i].expire =
1274 pr->ndpr_lastupdate +
1275 pr->ndpr_vltime;
1276 } else
1277 oprl->prefix[i].expire = maxexpire;
1278 }
1279
1295 pfr = pr->ndpr_advrtrs.lh_first;
1296 j = 0;
1280 j = 0;
1297 while (pfr) {
1281 LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry) {
1298 if (j < DRLSTSIZ) {
1299#define RTRADDR oprl->prefix[i].advrtr[j]
1300 RTRADDR = pfr->router->rtaddr;
1301 in6_clearscope(&RTRADDR);
1302#undef RTRADDR
1303 }
1304 j++;
1282 if (j < DRLSTSIZ) {
1283#define RTRADDR oprl->prefix[i].advrtr[j]
1284 RTRADDR = pfr->router->rtaddr;
1285 in6_clearscope(&RTRADDR);
1286#undef RTRADDR
1287 }
1288 j++;
1305 pfr = pfr->pfr_next;
1306 }
1307 oprl->prefix[i].advrtrs = j;
1308 oprl->prefix[i].origin = PR_ORIG_RA;
1309
1310 i++;
1289 }
1290 oprl->prefix[i].advrtrs = j;
1291 oprl->prefix[i].origin = PR_ORIG_RA;
1292
1293 i++;
1311 pr = pr->ndpr_next;
1312 }
1313 splx(s);
1314
1315 break;
1316 case OSIOCGIFINFO_IN6:
1317#define ND ndi->ndi
1318 /* XXX: old ndp(8) assumes a positive value for linkmtu. */
1319 bzero(&ND, sizeof(ND));

--- 145 unchanged lines hidden (view full) ---

1465 defrouter_select();
1466 break;
1467 case SIOCSPFXFLUSH_IN6:
1468 {
1469 /* flush all the prefix advertised by routers */
1470 struct nd_prefix *pr, *next;
1471
1472 s = splnet();
1294 }
1295 splx(s);
1296
1297 break;
1298 case OSIOCGIFINFO_IN6:
1299#define ND ndi->ndi
1300 /* XXX: old ndp(8) assumes a positive value for linkmtu. */
1301 bzero(&ND, sizeof(ND));

--- 145 unchanged lines hidden (view full) ---

1447 defrouter_select();
1448 break;
1449 case SIOCSPFXFLUSH_IN6:
1450 {
1451 /* flush all the prefix advertised by routers */
1452 struct nd_prefix *pr, *next;
1453
1454 s = splnet();
1473 for (pr = V_nd_prefix.lh_first; pr; pr = next) {
1455 LIST_FOREACH_SAFE(pr, &V_nd_prefix, ndpr_entry, next) {
1474 struct in6_ifaddr *ia, *ia_next;
1475
1456 struct in6_ifaddr *ia, *ia_next;
1457
1476 next = pr->ndpr_next;
1477
1478 if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr))
1479 continue; /* XXX */
1480
1481 /* do we really have to remove addresses as well? */
1482 /* XXXRW: in6_ifaddrhead locking. */
1483 TAILQ_FOREACH_SAFE(ia, &V_in6_ifaddrhead, ia_link,
1484 ia_next) {
1485 if ((ia->ia6_flags & IN6_IFF_AUTOCONF) == 0)

--- 9 unchanged lines hidden (view full) ---

1495 }
1496 case SIOCSRTRFLUSH_IN6:
1497 {
1498 /* flush all the default routers */
1499 struct nd_defrouter *dr, *next;
1500
1501 s = splnet();
1502 defrouter_reset();
1458 if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr))
1459 continue; /* XXX */
1460
1461 /* do we really have to remove addresses as well? */
1462 /* XXXRW: in6_ifaddrhead locking. */
1463 TAILQ_FOREACH_SAFE(ia, &V_in6_ifaddrhead, ia_link,
1464 ia_next) {
1465 if ((ia->ia6_flags & IN6_IFF_AUTOCONF) == 0)

--- 9 unchanged lines hidden (view full) ---

1475 }
1476 case SIOCSRTRFLUSH_IN6:
1477 {
1478 /* flush all the default routers */
1479 struct nd_defrouter *dr, *next;
1480
1481 s = splnet();
1482 defrouter_reset();
1503 for (dr = TAILQ_FIRST(&V_nd_defrouter); dr; dr = next) {
1504 next = TAILQ_NEXT(dr, dr_entry);
1483 TAILQ_FOREACH_SAFE(dr, &V_nd_defrouter, dr_entry, next) {
1505 defrtrlist_del(dr);
1506 }
1507 defrouter_select();
1508 splx(s);
1509 break;
1510 }
1511 case SIOCGNBRINFO_IN6:
1512 {

--- 306 unchanged lines hidden (view full) ---

1819{
1820 CURVNET_SET((struct vnet *) arg);
1821 struct nd_ifinfo *nd6if;
1822 struct ifnet *ifp;
1823
1824 callout_reset(&V_nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
1825 nd6_slowtimo, curvnet);
1826 IFNET_RLOCK_NOSLEEP();
1484 defrtrlist_del(dr);
1485 }
1486 defrouter_select();
1487 splx(s);
1488 break;
1489 }
1490 case SIOCGNBRINFO_IN6:
1491 {

--- 306 unchanged lines hidden (view full) ---

1798{
1799 CURVNET_SET((struct vnet *) arg);
1800 struct nd_ifinfo *nd6if;
1801 struct ifnet *ifp;
1802
1803 callout_reset(&V_nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
1804 nd6_slowtimo, curvnet);
1805 IFNET_RLOCK_NOSLEEP();
1827 for (ifp = TAILQ_FIRST(&V_ifnet); ifp;
1828 ifp = TAILQ_NEXT(ifp, if_list)) {
1806 TAILQ_FOREACH(ifp, &V_ifnet, if_list) {
1829 nd6if = ND_IFINFO(ifp);
1830 if (nd6if->basereachable && /* already initialized */
1831 (nd6if->recalctm -= ND6_SLOWTIMER_INTERVAL) <= 0) {
1832 /*
1833 * Since reachable time rarely changes by router
1834 * advertisements, we SHOULD insure that a new random
1835 * value gets recomputed at least once every few hours.
1836 * (RFC 2461, 6.3.4)

--- 452 unchanged lines hidden (view full) ---

2289 char buf[1024] __aligned(4);
2290 struct in6_defrouter *d, *de;
2291 struct nd_defrouter *dr;
2292
2293 if (req->newptr)
2294 return EPERM;
2295 error = 0;
2296
1807 nd6if = ND_IFINFO(ifp);
1808 if (nd6if->basereachable && /* already initialized */
1809 (nd6if->recalctm -= ND6_SLOWTIMER_INTERVAL) <= 0) {
1810 /*
1811 * Since reachable time rarely changes by router
1812 * advertisements, we SHOULD insure that a new random
1813 * value gets recomputed at least once every few hours.
1814 * (RFC 2461, 6.3.4)

--- 452 unchanged lines hidden (view full) ---

2267 char buf[1024] __aligned(4);
2268 struct in6_defrouter *d, *de;
2269 struct nd_defrouter *dr;
2270
2271 if (req->newptr)
2272 return EPERM;
2273 error = 0;
2274
2297 for (dr = TAILQ_FIRST(&V_nd_defrouter); dr;
2298 dr = TAILQ_NEXT(dr, dr_entry)) {
2275 TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) {
2299 d = (struct in6_defrouter *)buf;
2300 de = (struct in6_defrouter *)(buf + sizeof(buf));
2301
2302 if (d + 1 <= de) {
2303 bzero(d, sizeof(*d));
2304 d->rtaddr.sin6_family = AF_INET6;
2305 d->rtaddr.sin6_len = sizeof(d->rtaddr);
2306 d->rtaddr.sin6_addr = dr->rtaddr;

--- 23 unchanged lines hidden (view full) ---

2330 struct in6_prefix *p, *pe;
2331 struct nd_prefix *pr;
2332 char ip6buf[INET6_ADDRSTRLEN];
2333
2334 if (req->newptr)
2335 return EPERM;
2336 error = 0;
2337
2276 d = (struct in6_defrouter *)buf;
2277 de = (struct in6_defrouter *)(buf + sizeof(buf));
2278
2279 if (d + 1 <= de) {
2280 bzero(d, sizeof(*d));
2281 d->rtaddr.sin6_family = AF_INET6;
2282 d->rtaddr.sin6_len = sizeof(d->rtaddr);
2283 d->rtaddr.sin6_addr = dr->rtaddr;

--- 23 unchanged lines hidden (view full) ---

2307 struct in6_prefix *p, *pe;
2308 struct nd_prefix *pr;
2309 char ip6buf[INET6_ADDRSTRLEN];
2310
2311 if (req->newptr)
2312 return EPERM;
2313 error = 0;
2314
2338 for (pr = V_nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
2315 LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) {
2339 u_short advrtrs;
2340 size_t advance;
2341 struct sockaddr_in6 *sin6, *s6;
2342 struct nd_pfxrouter *pfr;
2343
2344 p = (struct in6_prefix *)buf;
2345 pe = (struct in6_prefix *)(buf + sizeof(buf));
2346

--- 28 unchanged lines hidden (view full) ---

2375 pr->ndpr_vltime;
2376 } else
2377 p->expire = maxexpire;
2378 }
2379 p->refcnt = pr->ndpr_refcnt;
2380 p->flags = pr->ndpr_stateflags;
2381 p->origin = PR_ORIG_RA;
2382 advrtrs = 0;
2316 u_short advrtrs;
2317 size_t advance;
2318 struct sockaddr_in6 *sin6, *s6;
2319 struct nd_pfxrouter *pfr;
2320
2321 p = (struct in6_prefix *)buf;
2322 pe = (struct in6_prefix *)(buf + sizeof(buf));
2323

--- 28 unchanged lines hidden (view full) ---

2352 pr->ndpr_vltime;
2353 } else
2354 p->expire = maxexpire;
2355 }
2356 p->refcnt = pr->ndpr_refcnt;
2357 p->flags = pr->ndpr_stateflags;
2358 p->origin = PR_ORIG_RA;
2359 advrtrs = 0;
2383 for (pfr = pr->ndpr_advrtrs.lh_first; pfr;
2384 pfr = pfr->pfr_next) {
2360 LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry) {
2385 if ((void *)&sin6[advrtrs + 1] > (void *)pe) {
2386 advrtrs++;
2387 continue;
2388 }
2389 s6 = &sin6[advrtrs];
2390 bzero(s6, sizeof(*s6));
2391 s6->sin6_family = AF_INET6;
2392 s6->sin6_len = sizeof(*sin6);

--- 22 unchanged lines hidden ---
2361 if ((void *)&sin6[advrtrs + 1] > (void *)pe) {
2362 advrtrs++;
2363 continue;
2364 }
2365 s6 = &sin6[advrtrs];
2366 bzero(s6, sizeof(*s6));
2367 s6->sin6_family = AF_INET6;
2368 s6->sin6_len = sizeof(*sin6);

--- 22 unchanged lines hidden ---