67 #ifdef LWIP_HOOK_FILENAME
68 #include LWIP_HOOK_FILENAME
71 #if LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK
72 #error LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK
86 static u8_t nd6_cached_neighbor_index;
87 static u8_t nd6_cached_destination_index;
90 static ip6_addr_t multicast_address;
96 static s8_t nd6_find_neighbor_cache_entry(
const ip6_addr_t *ip6addr);
97 static s8_t nd6_new_neighbor_cache_entry(
void);
98 static void nd6_free_neighbor_cache_entry(
s8_t i);
99 static s8_t nd6_find_destination_cache_entry(
const ip6_addr_t *ip6addr);
100 static s8_t nd6_new_destination_cache_entry(
void);
101 static s8_t nd6_is_prefix_in_netif(
const ip6_addr_t *ip6addr,
struct netif *
netif);
102 static s8_t nd6_select_router(
const ip6_addr_t *ip6addr,
struct netif *
netif);
103 static s8_t nd6_get_router(
const ip6_addr_t *router_addr,
struct netif *
netif);
104 static s8_t nd6_new_router(
const ip6_addr_t *router_addr,
struct netif *
netif);
105 static s8_t nd6_get_onlink_prefix(ip6_addr_t *prefix,
struct netif *
netif);
106 static s8_t nd6_new_onlink_prefix(ip6_addr_t *prefix,
struct netif *
netif);
107 static s8_t nd6_get_next_hop_entry(
const ip6_addr_t *ip6addr,
struct netif *
netif);
108 static err_t nd6_queue_packet(
s8_t neighbor_index,
struct pbuf *q);
110 #define ND6_SEND_FLAG_MULTICAST_DEST 0x01
111 #define ND6_SEND_FLAG_ALLNODES_DEST 0x02
112 static void nd6_send_ns(
struct netif *
netif,
const ip6_addr_t *target_addr,
u8_t flags);
113 static void nd6_send_na(
struct netif *
netif,
const ip6_addr_t *target_addr,
u8_t flags);
114 static void nd6_send_neighbor_cache_probe(
struct nd6_neighbor_cache_entry *entry,
u8_t flags);
115 #if LWIP_IPV6_SEND_ROUTER_SOLICIT
119 #if LWIP_ND6_QUEUEING
120 static void nd6_free_q(
struct nd6_q_entry *q);
122 #define nd6_free_q(q) pbuf_free(q)
124 static void nd6_send_q(
s8_t i);
134 nd6_input(
struct pbuf *p,
struct netif *inp)
160 if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
161 ip6_addr_t target_address;
168 ip6_addr_set(&target_address, &(na_hdr->target_address));
170 #if LWIP_IPV6_DUP_DETECT_ATTEMPTS
173 if (!ip6_addr_isinvalid(netif_ip6_addr_state(inp, i)) &&
174 ip6_addr_cmp(&target_address, netif_ip6_addr(inp, i))) {
176 netif_ip6_addr_set_state(inp, i, IP6_ADDR_INVALID);
178 #if LWIP_IPV6_AUTOCONFIG
180 if (!ip6_addr_islinklocal(&target_address)) {
181 i = nd6_get_onlink_prefix(&target_address, inp);
185 prefix_list[i].flags |= ND6_PREFIX_AUTOCONFIG_ADDRESS_DUPLICATE;
207 if (p->
len < (
sizeof(
struct na_header) + (lladdr_opt->length << 3))) {
216 i = nd6_find_neighbor_cache_entry(&target_address);
223 ip6_addr_t target_address;
230 ip6_addr_set(&target_address, &(na_hdr->target_address));
233 i = nd6_find_neighbor_cache_entry(&target_address);
242 (neighbor_cache[i].state == ND6_INCOMPLETE)) {
254 if (p->
len < (
sizeof(
struct na_header) + (lladdr_opt->length << 3))) {
265 neighbor_cache[i].netif = inp;
266 neighbor_cache[i].
state = ND6_REACHABLE;
267 neighbor_cache[i].counter.reachable_time = reachable_time;
270 if (neighbor_cache[i].q !=
NULL) {
297 if (p->
len < (
sizeof(
struct ns_header) + (lladdr_opt->length << 3))) {
307 if ((ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) ||
308 (ip6_addr_istentative(netif_ip6_addr_state(inp, i)) &&
309 ip6_addr_isany(ip6_current_src_addr()))) &&
310 ip6_addr_cmp(&(ns_hdr->target_address), netif_ip6_addr(inp, i))) {
323 if (ip6_addr_isany(ip6_current_src_addr())) {
326 if (!ip6_addr_isinvalid(netif_ip6_addr_state(inp, i)) &&
327 ip6_addr_cmp(&(ns_hdr->target_address), netif_ip6_addr(inp, i))) {
329 nd6_send_na(inp, netif_ip6_addr(inp, i),
ND6_FLAG_OVERRIDE | ND6_SEND_FLAG_ALLNODES_DEST);
330 if (ip6_addr_istentative(netif_ip6_addr_state(inp, i))) {
332 netif_ip6_addr_set_state(inp, i, IP6_ADDR_INVALID);
337 ip6_addr_t target_address;
341 if (lladdr_opt ==
NULL) {
349 i = nd6_find_neighbor_cache_entry(ip6_current_src_addr());
352 if (neighbor_cache[i].state == ND6_INCOMPLETE) {
353 neighbor_cache[i].netif = inp;
357 neighbor_cache[i].state = ND6_DELAY;
364 i = nd6_new_neighbor_cache_entry();
372 neighbor_cache[i].netif = inp;
374 ip6_addr_set(&(neighbor_cache[i].next_hop_address), ip6_current_src_addr());
378 neighbor_cache[i].state = ND6_DELAY;
383 ip6_addr_set(&target_address, &(ns_hdr->target_address));
396 #if LWIP_ND6_RDNSS_MAX_DNS_SERVERS
398 u8_t rdnss_server_idx = 0;
416 (nd6_send_rs(inp) ==
ERR_OK)) {
422 i = nd6_get_router(ip6_current_src_addr(), inp);
425 i = nd6_new_router(ip6_current_src_addr(), inp);
436 default_router_list[i].invalidation_timer =
lwip_htons(ra_hdr->router_lifetime);
439 #if LWIP_ND6_ALLOW_RA_UPDATES
440 if (ra_hdr->retrans_timer > 0) {
441 retrans_timer =
lwip_htonl(ra_hdr->retrans_timer);
443 if (ra_hdr->reachable_time > 0) {
444 reachable_time =
lwip_htonl(ra_hdr->reachable_time);
452 default_router_list[i].flags = ra_hdr->flags;
458 while ((p->
tot_len - offset) > 0) {
483 if ((default_router_list[i].neighbor_entry !=
NULL) &&
484 (default_router_list[i].neighbor_entry->state == ND6_INCOMPLETE)) {
485 SMEMCPY(default_router_list[i].neighbor_entry->lladdr, lladdr_opt->addr, inp->
hwaddr_len);
486 default_router_list[i].neighbor_entry->state = ND6_REACHABLE;
487 default_router_list[i].neighbor_entry->counter.reachable_time = reachable_time;
496 #if LWIP_ND6_ALLOW_RA_UPDATES
508 (prefix_opt->prefix_length == 64) &&
509 !ip6_addr_islinklocal(&(prefix_opt->prefix))) {
512 ip6_addr_t prefix_addr;
515 ip6_addr_set(&prefix_addr, &(prefix_opt->prefix));
518 prefix = nd6_get_onlink_prefix(&prefix_addr, inp);
521 prefix = nd6_new_onlink_prefix(&prefix_addr, inp);
524 prefix_list[prefix].invalidation_timer =
lwip_htonl(prefix_opt->valid_lifetime);
526 #if LWIP_IPV6_AUTOCONFIG
530 prefix_list[prefix].flags |= ND6_PREFIX_AUTOCONFIG_AUTONOMOUS;
544 #if LWIP_ND6_RDNSS_MAX_DNS_SERVERS
551 num = (rdnss_opt->length - 1) / 2;
558 if (
htonl(rdnss_opt->lifetime) > 0) {
560 dns_setserver(rdnss_server_idx++, &rdnss_address);
565 const ip_addr_t *addr = dns_getserver(s);
567 dns_setserver(s,
NULL);
613 ip6_addr_set(&tmp, &(redir_hdr->destination_address));
616 i = nd6_find_destination_cache_entry(&tmp);
624 ip6_addr_set(&(destination_cache[i].next_hop_addr), &(redir_hdr->target_address));
627 if (lladdr_opt !=
NULL) {
630 ip6_addr_set(&tmp, &(redir_hdr->target_address));
632 i = nd6_find_neighbor_cache_entry(&tmp);
634 i = nd6_new_neighbor_cache_entry();
636 neighbor_cache[i].netif = inp;
638 ip6_addr_set(&(neighbor_cache[i].next_hop_address), &tmp);
642 neighbor_cache[i].state = ND6_DELAY;
647 if (neighbor_cache[i].state == ND6_INCOMPLETE) {
651 neighbor_cache[i].state = ND6_DELAY;
679 ip6_addr_set(&tmp, &(ip6hdr->dest));
682 i = nd6_find_destination_cache_entry(&tmp);
723 switch (neighbor_cache[i].
state) {
726 (!neighbor_cache[i].isrouter)) {
728 nd6_free_neighbor_cache_entry(i);
731 neighbor_cache[i].counter.probes_sent++;
732 nd6_send_neighbor_cache_probe(&neighbor_cache[i], ND6_SEND_FLAG_MULTICAST_DEST);
737 if (neighbor_cache[i].q !=
NULL) {
740 if (neighbor_cache[i].counter.reachable_time <= ND6_TMR_INTERVAL) {
742 neighbor_cache[i].state = ND6_STALE;
743 neighbor_cache[i].counter.stale_time = 0;
745 neighbor_cache[i].counter.reachable_time -= ND6_TMR_INTERVAL;
749 neighbor_cache[i].counter.stale_time++;
752 if (neighbor_cache[i].counter.delay_time <= 1) {
754 neighbor_cache[i].state = ND6_PROBE;
755 neighbor_cache[i].counter.probes_sent = 0;
757 neighbor_cache[i].counter.delay_time--;
762 (!neighbor_cache[i].isrouter)) {
764 nd6_free_neighbor_cache_entry(i);
767 neighbor_cache[i].counter.probes_sent++;
768 nd6_send_neighbor_cache_probe(&neighbor_cache[i], 0);
780 destination_cache[i].age++;
785 if (default_router_list[i].neighbor_entry !=
NULL) {
787 if (default_router_list[i].invalidation_timer > 0) {
788 default_router_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000;
790 if (default_router_list[i].invalidation_timer < ND6_TMR_INTERVAL / 1000) {
792 default_router_list[i].neighbor_entry->isrouter = 0;
793 default_router_list[i].neighbor_entry =
NULL;
794 default_router_list[i].invalidation_timer = 0;
795 default_router_list[i].flags = 0;
803 if (prefix_list[i].invalidation_timer < ND6_TMR_INTERVAL / 1000) {
805 prefix_list[i].invalidation_timer = 0;
807 #if LWIP_IPV6_AUTOCONFIG
809 if (prefix_list[i].
flags & ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED) {
813 if ((netif_ip6_addr_state(prefix_list[i].
netif, j) != IP6_ADDR_INVALID) &&
814 ip6_addr_netcmp(&prefix_list[i].prefix, netif_ip6_addr(prefix_list[i].
netif, j))) {
815 netif_ip6_addr_set_state(prefix_list[i].
netif, j, IP6_ADDR_INVALID);
816 prefix_list[i].flags = 0;
825 prefix_list[i].netif =
NULL;
826 prefix_list[i].flags = 0;
828 prefix_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000;
830 #if LWIP_IPV6_AUTOCONFIG
832 if (prefix_list[i].
netif->ip6_autoconfig_enabled &&
833 (prefix_list[i].flags & ND6_PREFIX_AUTOCONFIG_AUTONOMOUS) &&
834 !(prefix_list[i].flags & ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED)) {
839 if (netif_ip6_addr_state(prefix_list[i].
netif, j) == IP6_ADDR_INVALID) {
841 netif_ip6_addr_set_parts(prefix_list[i].
netif, j,
842 prefix_list[i].prefix.addr[0], prefix_list[i].prefix.addr[1],
843 netif_ip6_addr(prefix_list[i].
netif, 0)->addr[2], netif_ip6_addr(prefix_list[i].
netif, 0)->addr[3]);
846 netif_ip6_addr_set_state(prefix_list[i].
netif, j, IP6_ADDR_TENTATIVE);
849 prefix_list[i].flags |= ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED;
865 u8_t addr_state = netif_ip6_addr_state(
netif, i);
866 if (ip6_addr_istentative(addr_state)) {
869 netif_ip6_addr_set_state(
netif, i, IP6_ADDR_PREFERRED);
873 nd6_send_ns(
netif, netif_ip6_addr(
netif, i), ND6_SEND_FLAG_MULTICAST_DEST);
875 netif_ip6_addr_set_state(
netif, i, addr_state + 1);
883 #if LWIP_IPV6_SEND_ROUTER_SOLICIT
887 (!ip6_addr_isinvalid(netif_ip6_addr_state(
netif, 0)))) {
903 nd6_send_neighbor_cache_probe(
struct nd6_neighbor_cache_entry *entry,
u8_t flags)
905 nd6_send_ns(entry->netif, &entry->next_hop_address,
flags);
920 const ip6_addr_t *src_addr;
921 u16_t lladdr_opt_len;
923 if (ip6_addr_isvalid(netif_ip6_addr_state(
netif,0))) {
925 src_addr = netif_ip6_addr(
netif, 0);
929 src_addr = IP6_ADDR_ANY6;
947 ns_hdr->reserved = 0;
948 ip6_addr_set(&(ns_hdr->target_address), target_addr);
950 if (lladdr_opt_len != 0) {
953 lladdr_opt->length = (
u8_t)lladdr_opt_len;
958 if (flags & ND6_SEND_FLAG_MULTICAST_DEST) {
959 ip6_addr_set_solicitednode(&multicast_address, target_addr->addr[3]);
960 target_addr = &multicast_address;
963 #if CHECKSUM_GEN_ICMP6
972 ip6_output_if(p, (src_addr == IP6_ADDR_ANY6) ?
NULL : src_addr, target_addr,
985 nd6_send_na(
struct netif *
netif,
const ip6_addr_t *target_addr,
u8_t flags)
990 const ip6_addr_t *src_addr;
991 const ip6_addr_t *dest_addr;
992 u16_t lladdr_opt_len;
997 src_addr = target_addr;
1014 na_hdr->flags = flags & 0xf0;
1015 na_hdr->reserved[0] = 0;
1016 na_hdr->reserved[1] = 0;
1017 na_hdr->reserved[2] = 0;
1018 ip6_addr_set(&(na_hdr->target_address), target_addr);
1021 lladdr_opt->length = (
u8_t)lladdr_opt_len;
1025 if (flags & ND6_SEND_FLAG_MULTICAST_DEST) {
1026 ip6_addr_set_solicitednode(&multicast_address, target_addr->addr[3]);
1027 dest_addr = &multicast_address;
1028 }
else if (flags & ND6_SEND_FLAG_ALLNODES_DEST) {
1029 ip6_addr_set_allnodes_linklocal(&multicast_address);
1030 dest_addr = &multicast_address;
1032 dest_addr = ip6_current_src_addr();
1035 #if CHECKSUM_GEN_ICMP6
1044 ip6_output_if(p, src_addr, dest_addr,
1049 #if LWIP_IPV6_SEND_ROUTER_SOLICIT
1061 const ip6_addr_t *src_addr;
1063 u16_t lladdr_opt_len = 0;
1066 if (ip6_addr_isvalid(netif_ip6_addr_state(
netif, 0))) {
1067 src_addr = netif_ip6_addr(
netif, 0);
1069 src_addr = IP6_ADDR_ANY6;
1073 ip6_addr_set_allrouters_linklocal(&multicast_address);
1076 if (src_addr != IP6_ADDR_ANY6) {
1091 rs_hdr->reserved = 0;
1093 if (src_addr != IP6_ADDR_ANY6) {
1097 lladdr_opt->length = (
u8_t)lladdr_opt_len;
1101 #if CHECKSUM_GEN_ICMP6
1104 &multicast_address);
1111 err = ip6_output_if(p, (src_addr == IP6_ADDR_ANY6) ?
NULL : src_addr, &multicast_address,
1127 nd6_find_neighbor_cache_entry(
const ip6_addr_t *ip6addr)
1131 if (ip6_addr_cmp(ip6addr, &(neighbor_cache[i].next_hop_address))) {
1148 nd6_new_neighbor_cache_entry(
void)
1157 if (neighbor_cache[i].state == ND6_NO_ENTRY) {
1166 if ((neighbor_cache[i].state == ND6_STALE) &&
1167 (!neighbor_cache[i].isrouter)) {
1168 nd6_free_neighbor_cache_entry(i);
1175 if ((neighbor_cache[i].state == ND6_PROBE) &&
1176 (!neighbor_cache[i].isrouter)) {
1177 nd6_free_neighbor_cache_entry(i);
1184 if ((neighbor_cache[i].state == ND6_DELAY) &&
1185 (!neighbor_cache[i].isrouter)) {
1186 nd6_free_neighbor_cache_entry(i);
1192 time = 0xfffffffful;
1195 if ((neighbor_cache[i].state == ND6_REACHABLE) &&
1196 (!neighbor_cache[i].isrouter)) {
1197 if (neighbor_cache[i].counter.reachable_time < time) {
1199 time = neighbor_cache[i].counter.reachable_time;
1204 nd6_free_neighbor_cache_entry(j);
1213 (neighbor_cache[i].q ==
NULL) &&
1214 (neighbor_cache[i].state == ND6_INCOMPLETE) &&
1215 (!neighbor_cache[i].isrouter)) {
1216 if (neighbor_cache[i].counter.probes_sent >= time) {
1218 time = neighbor_cache[i].counter.probes_sent;
1223 nd6_free_neighbor_cache_entry(j);
1231 if ((neighbor_cache[i].state == ND6_INCOMPLETE) &&
1232 (!neighbor_cache[i].isrouter)) {
1233 if (neighbor_cache[i].counter.probes_sent >= time) {
1235 time = neighbor_cache[i].counter.probes_sent;
1240 nd6_free_neighbor_cache_entry(j);
1255 nd6_free_neighbor_cache_entry(
s8_t i)
1260 if (neighbor_cache[i].isrouter) {
1266 if (neighbor_cache[i].q !=
NULL) {
1267 nd6_free_q(neighbor_cache[i].q);
1268 neighbor_cache[i].q =
NULL;
1271 neighbor_cache[i].state = ND6_NO_ENTRY;
1272 neighbor_cache[i].isrouter = 0;
1273 neighbor_cache[i].netif =
NULL;
1274 neighbor_cache[i].counter.reachable_time = 0;
1275 ip6_addr_set_zero(&(neighbor_cache[i].next_hop_address));
1286 nd6_find_destination_cache_entry(
const ip6_addr_t *ip6addr)
1290 if (ip6_addr_cmp(ip6addr, &(destination_cache[i].destination_addr))) {
1305 nd6_new_destination_cache_entry(
void)
1312 if (ip6_addr_isany(&(destination_cache[i].destination_addr))) {
1321 if (destination_cache[i].age > age) {
1336 nd6_clear_destination_cache(
void)
1341 ip6_addr_set_any(&destination_cache[i].destination_addr);
1352 nd6_is_prefix_in_netif(
const ip6_addr_t *ip6addr,
struct netif *
netif)
1357 (prefix_list[i].invalidation_timer > 0) &&
1358 ip6_addr_netcmp(ip6addr, &(prefix_list[i].prefix))) {
1364 if (ip6_addr_isvalid(netif_ip6_addr_state(
netif, i)) &&
1365 ip6_addr_netcmp(ip6addr, netif_ip6_addr(
netif, i))) {
1381 nd6_select_router(
const ip6_addr_t *ip6addr,
struct netif *
netif)
1387 static s8_t last_router;
1397 if ((default_router_list[i].neighbor_entry !=
NULL) &&
1398 (
netif !=
NULL ?
netif == default_router_list[i].neighbor_entry->netif : 1) &&
1399 (default_router_list[i].invalidation_timer > 0) &&
1400 (default_router_list[i].neighbor_entry->state == ND6_REACHABLE)) {
1410 if ((default_router_list[i].neighbor_entry !=
NULL) &&
1411 (
netif !=
NULL ?
netif == default_router_list[i].neighbor_entry->netif : 1) &&
1412 (default_router_list[i].invalidation_timer > 0)) {
1422 if (default_router_list[i].neighbor_entry !=
NULL &&
1423 (
netif !=
NULL ?
netif == default_router_list[i].neighbor_entry->netif : 1)) {
1442 nd6_find_route(
const ip6_addr_t *ip6addr)
1446 i = nd6_select_router(ip6addr,
NULL);
1448 if (default_router_list[i].neighbor_entry !=
NULL) {
1449 return default_router_list[i].neighbor_entry->netif;
1464 nd6_get_router(
const ip6_addr_t *router_addr,
struct netif *
netif)
1470 if ((default_router_list[i].neighbor_entry !=
NULL) &&
1471 ((
netif !=
NULL) ?
netif == default_router_list[i].neighbor_entry->netif : 1) &&
1472 ip6_addr_cmp(router_addr, &(default_router_list[i].neighbor_entry->next_hop_address))) {
1489 nd6_new_router(
const ip6_addr_t *router_addr,
struct netif *
netif)
1492 s8_t free_router_index;
1493 s8_t neighbor_index;
1496 neighbor_index = nd6_find_neighbor_cache_entry(router_addr);
1497 if (neighbor_index < 0) {
1499 neighbor_index = nd6_new_neighbor_cache_entry();
1500 if (neighbor_index < 0) {
1504 ip6_addr_set(&(neighbor_cache[neighbor_index].next_hop_address), router_addr);
1505 neighbor_cache[neighbor_index].netif =
netif;
1506 neighbor_cache[neighbor_index].q =
NULL;
1507 neighbor_cache[neighbor_index].state = ND6_INCOMPLETE;
1508 neighbor_cache[neighbor_index].counter.probes_sent = 1;
1509 nd6_send_neighbor_cache_probe(&neighbor_cache[neighbor_index], ND6_SEND_FLAG_MULTICAST_DEST);
1513 neighbor_cache[neighbor_index].isrouter = 1;
1520 if(default_router_list[router_index].neighbor_entry == &(neighbor_cache[neighbor_index])){
1521 return router_index;
1523 if (default_router_list[router_index].neighbor_entry ==
NULL) {
1525 free_router_index = router_index;
1529 default_router_list[free_router_index].neighbor_entry = &(neighbor_cache[neighbor_index]);
1530 return free_router_index;
1536 neighbor_cache[neighbor_index].isrouter = 0;
1550 nd6_get_onlink_prefix(ip6_addr_t *prefix,
struct netif *
netif)
1556 if ((ip6_addr_netcmp(&(prefix_list[i].prefix), prefix)) &&
1574 nd6_new_onlink_prefix(ip6_addr_t *prefix,
struct netif *
netif)
1581 (prefix_list[i].invalidation_timer == 0)) {
1583 prefix_list[i].netif =
netif;
1584 ip6_addr_set(&(prefix_list[i].prefix), prefix);
1585 #if LWIP_IPV6_AUTOCONFIG
1586 prefix_list[i].flags = 0;
1609 nd6_get_next_hop_entry(
const ip6_addr_t *ip6addr,
struct netif *
netif)
1611 #ifdef LWIP_HOOK_ND6_GET_GW
1612 const ip6_addr_t *next_hop_addr;
1616 #if LWIP_NETIF_HWADDRHINT
1621 nd6_cached_destination_index = addr_hint;
1627 if (ip6_addr_cmp(ip6addr, &(destination_cache[nd6_cached_destination_index].destination_addr))) {
1633 i = nd6_find_destination_cache_entry(ip6addr);
1636 nd6_cached_destination_index = i;
1639 i = nd6_new_destination_cache_entry();
1642 nd6_cached_destination_index = i;
1649 ip6_addr_set(&(destination_cache[nd6_cached_destination_index].destination_addr), ip6addr);
1652 if (ip6_addr_islinklocal(ip6addr) ||
1653 nd6_is_prefix_in_netif(ip6addr,
netif)) {
1655 destination_cache[nd6_cached_destination_index].pmtu =
netif->
mtu;
1656 ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, destination_cache[nd6_cached_destination_index].destination_addr);
1657 #ifdef LWIP_HOOK_ND6_GET_GW
1658 }
else if ((next_hop_addr = LWIP_HOOK_ND6_GET_GW(
netif, ip6addr)) !=
NULL) {
1660 destination_cache[nd6_cached_destination_index].pmtu =
netif->
mtu;
1661 ip6_addr_set(&destination_cache[nd6_cached_destination_index].next_hop_addr, next_hop_addr);
1665 i = nd6_select_router(ip6addr,
netif);
1668 ip6_addr_set_any(&(destination_cache[nd6_cached_destination_index].destination_addr));
1671 destination_cache[nd6_cached_destination_index].pmtu =
netif->
mtu;
1672 ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, default_router_list[i].neighbor_entry->next_hop_address);
1677 #if LWIP_NETIF_HWADDRHINT
1680 *(
netif->addr_hint) = nd6_cached_destination_index;
1685 if (ip6_addr_cmp(&(destination_cache[nd6_cached_destination_index].next_hop_addr),
1686 &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) {
1691 i = nd6_find_neighbor_cache_entry(&(destination_cache[nd6_cached_destination_index].next_hop_addr));
1694 nd6_cached_neighbor_index = i;
1697 i = nd6_new_neighbor_cache_entry();
1700 nd6_cached_neighbor_index = i;
1707 ip6_addr_copy(neighbor_cache[i].next_hop_address,
1708 destination_cache[nd6_cached_destination_index].next_hop_addr);
1709 neighbor_cache[i].isrouter = 0;
1710 neighbor_cache[i].netif =
netif;
1711 neighbor_cache[i].
state = ND6_INCOMPLETE;
1712 neighbor_cache[i].counter.probes_sent = 1;
1713 nd6_send_neighbor_cache_probe(&neighbor_cache[i], ND6_SEND_FLAG_MULTICAST_DEST);
1718 destination_cache[nd6_cached_destination_index].age = 0;
1720 return nd6_cached_neighbor_index;
1731 nd6_queue_packet(
s8_t neighbor_index,
struct pbuf *q)
1735 int copy_needed = 0;
1736 #if LWIP_ND6_QUEUEING
1737 struct nd6_q_entry *new_entry, *r;
1758 while ((p ==
NULL) && (neighbor_cache[neighbor_index].q !=
NULL)) {
1760 #if LWIP_ND6_QUEUEING
1761 r = neighbor_cache[neighbor_index].q;
1762 neighbor_cache[neighbor_index].q = r->next;
1766 pbuf_free(neighbor_cache[neighbor_index].q);
1767 neighbor_cache[neighbor_index].q =
NULL;
1785 #if LWIP_ND6_QUEUEING
1787 new_entry = (
struct nd6_q_entry *)
memp_malloc(MEMP_ND6_QUEUE);
1788 if ((new_entry ==
NULL) && (neighbor_cache[neighbor_index].q !=
NULL)) {
1790 r = neighbor_cache[neighbor_index].q;
1791 neighbor_cache[neighbor_index].q = r->next;
1794 new_entry = (
struct nd6_q_entry *)
memp_malloc(MEMP_ND6_QUEUE);
1796 if (new_entry !=
NULL) {
1797 new_entry->next =
NULL;
1799 if (neighbor_cache[neighbor_index].q !=
NULL) {
1801 r = neighbor_cache[neighbor_index].q;
1802 while (r->next !=
NULL) {
1805 r->
next = new_entry;
1808 neighbor_cache[neighbor_index].q = new_entry;
1820 if (neighbor_cache[neighbor_index].q !=
NULL) {
1821 pbuf_free(neighbor_cache[neighbor_index].q);
1823 neighbor_cache[neighbor_index].q = p;
1835 #if LWIP_ND6_QUEUEING
1842 nd6_free_q(
struct nd6_q_entry *q)
1844 struct nd6_q_entry *r;
1867 #if LWIP_ND6_QUEUEING
1868 struct nd6_q_entry *q;
1875 #if LWIP_ND6_QUEUEING
1876 while (neighbor_cache[i].q !=
NULL) {
1878 q = neighbor_cache[i].q;
1880 neighbor_cache[i].q = q->next;
1882 ip6hdr = (
struct ip6_hdr *)(q->p->payload);
1884 ip6_addr_set(&dest, &(ip6hdr->dest));
1886 (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].
netif, q->p, &dest);
1893 if (neighbor_cache[i].q !=
NULL) {
1895 ip6hdr = (
struct ip6_hdr *)(neighbor_cache[i].q->payload);
1897 ip6_addr_set(&dest, &(ip6hdr->dest));
1899 (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].
netif, neighbor_cache[i].q, &dest);
1902 neighbor_cache[i].q =
NULL;
1930 nd6_get_next_hop_addr_or_queue(
struct netif *
netif,
struct pbuf *q,
const ip6_addr_t *ip6addr,
const u8_t **hwaddrp)
1935 i = nd6_get_next_hop_entry(ip6addr,
netif);
1942 if (neighbor_cache[i].state == ND6_STALE) {
1944 neighbor_cache[i].state = ND6_DELAY;
1948 if ((neighbor_cache[i].state == ND6_REACHABLE) ||
1949 (neighbor_cache[i].state == ND6_DELAY) ||
1950 (neighbor_cache[i].state == ND6_PROBE)) {
1953 *hwaddrp = neighbor_cache[i].lladdr;
1959 return nd6_queue_packet(i, q);
1971 nd6_get_destination_mtu(
const ip6_addr_t *ip6addr,
struct netif *
netif)
1975 i = nd6_find_destination_cache_entry(ip6addr);
1977 if (destination_cache[i].pmtu > 0) {
1978 return destination_cache[i].pmtu;
1990 #if LWIP_ND6_TCP_REACHABILITY_HINTS
2001 nd6_reachability_hint(
const ip6_addr_t *ip6addr)
2006 if (ip6_addr_cmp(ip6addr, &(destination_cache[nd6_cached_destination_index].destination_addr))) {
2007 i = nd6_cached_destination_index;
2010 i = nd6_find_destination_cache_entry(ip6addr);
2017 if (ip6_addr_cmp(&(destination_cache[i].next_hop_addr), &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) {
2018 i = nd6_cached_neighbor_index;
2021 i = nd6_find_neighbor_cache_entry(&(destination_cache[i].next_hop_addr));
2028 if (neighbor_cache[i].state == ND6_INCOMPLETE || neighbor_cache[i].state == ND6_NO_ENTRY) {
2033 neighbor_cache[i].state = ND6_REACHABLE;
2034 neighbor_cache[i].counter.reachable_time = reachable_time;
2050 prefix_list[i].netif =
NULL;
2051 prefix_list[i].flags = 0;
2057 if (default_router_list[router_index].neighbor_entry == &neighbor_cache[i]) {
2058 default_router_list[router_index].neighbor_entry =
NULL;
2059 default_router_list[router_index].flags = 0;
2062 neighbor_cache[i].isrouter = 0;
2063 nd6_free_neighbor_cache_entry(i);
2080 u8_t old_state, old_member, new_member;
2082 old_state = netif_ip6_addr_state(
netif, addr_idx);
2087 old_member = (old_state != IP6_ADDR_INVALID && old_state != IP6_ADDR_TENTATIVE);
2088 new_member = (new_state != IP6_ADDR_INVALID && new_state != IP6_ADDR_TENTATIVE);
2090 if (old_member != new_member) {
2091 ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(
netif, addr_idx)->addr[3]);
2094 mld6_joingroup_netif(
netif, &multicast_address);
2096 mld6_leavegroup_netif(
netif, &multicast_address);