86#ifdef LWIP_HOOK_FILENAME
87#include LWIP_HOOK_FILENAME
90#if LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK
91#error LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK
105static u8_t nd6_cached_neighbor_index;
106static u8_t nd6_cached_destination_index;
109static ip6_addr_t multicast_address;
115static s8_t nd6_find_neighbor_cache_entry(
const ip6_addr_t *ip6addr);
116static s8_t nd6_new_neighbor_cache_entry(
void);
117static void nd6_free_neighbor_cache_entry(s8_t i);
118static s8_t nd6_find_destination_cache_entry(
const ip6_addr_t *ip6addr);
119static s8_t nd6_new_destination_cache_entry(
void);
120static s8_t nd6_is_prefix_in_netif(
const ip6_addr_t *ip6addr,
struct netif *
netif);
121static s8_t nd6_select_router(
const ip6_addr_t *ip6addr,
struct netif *
netif);
122static s8_t nd6_get_router(
const ip6_addr_t *router_addr,
struct netif *
netif);
123static s8_t nd6_new_router(
const ip6_addr_t *router_addr,
struct netif *
netif);
124static s8_t nd6_get_onlink_prefix(ip6_addr_t *prefix,
struct netif *
netif);
125static s8_t nd6_new_onlink_prefix(ip6_addr_t *prefix,
struct netif *
netif);
126static s8_t nd6_get_next_hop_entry(
const ip6_addr_t *ip6addr,
struct netif *
netif);
127static err_t nd6_queue_packet(s8_t neighbor_index,
struct pbuf *q);
129#define ND6_SEND_FLAG_MULTICAST_DEST 0x01
130#define ND6_SEND_FLAG_ALLNODES_DEST 0x02
131static void nd6_send_ns(
struct netif *
netif,
const ip6_addr_t *target_addr, u8_t flags);
132static void nd6_send_na(
struct netif *
netif,
const ip6_addr_t *target_addr, u8_t flags);
133static void nd6_send_neighbor_cache_probe(
struct nd6_neighbor_cache_entry *entry, u8_t flags);
134#if LWIP_IPV6_SEND_ROUTER_SOLICIT
139static void nd6_free_q(
struct nd6_q_entry *q);
141#define nd6_free_q(q) pbuf_free(q)
143static void nd6_send_q(s8_t i);
153nd6_input(
struct pbuf *p,
struct netif *inp)
158 ND6_STATS_INC(nd6.recv);
160 msg_type = *((u8_t *)p->
payload);
171 ND6_STATS_INC(nd6.lenerr);
172 ND6_STATS_INC(nd6.drop);
179 if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
180 ip6_addr_t target_address;
187 ip6_addr_set(&target_address, &(na_hdr->target_address));
189#if LWIP_IPV6_DUP_DETECT_ATTEMPTS
192 if (!ip6_addr_isinvalid(netif_ip6_addr_state(inp, i)) &&
193 ip6_addr_cmp(&target_address, netif_ip6_addr(inp, i))) {
195 netif_ip6_addr_set_state(inp, i, IP6_ADDR_INVALID);
197#if LWIP_IPV6_AUTOCONFIG
199 if (!ip6_addr_islinklocal(&target_address)) {
200 i = nd6_get_onlink_prefix(&target_address, inp);
204 prefix_list[i].flags |= ND6_PREFIX_AUTOCONFIG_ADDRESS_DUPLICATE;
219 ND6_STATS_INC(nd6.lenerr);
220 ND6_STATS_INC(nd6.drop);
226 if (p->
len < (
sizeof(
struct na_header) + (lladdr_opt->length << 3))) {
229 ND6_STATS_INC(nd6.lenerr);
230 ND6_STATS_INC(nd6.drop);
235 i = nd6_find_neighbor_cache_entry(&target_address);
237 if (na_hdr->flags & ND6_FLAG_OVERRIDE) {
238 MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->
hwaddr_len);
242 ip6_addr_t target_address;
249 ip6_addr_set(&target_address, &(na_hdr->target_address));
252 i = nd6_find_neighbor_cache_entry(&target_address);
260 if ((na_hdr->flags & ND6_FLAG_OVERRIDE) ||
261 (neighbor_cache[i].state == ND6_INCOMPLETE)) {
266 ND6_STATS_INC(nd6.lenerr);
267 ND6_STATS_INC(nd6.drop);
273 if (p->
len < (
sizeof(
struct na_header) + (lladdr_opt->length << 3))) {
276 ND6_STATS_INC(nd6.lenerr);
277 ND6_STATS_INC(nd6.drop);
281 MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->
hwaddr_len);
284 neighbor_cache[i].netif = inp;
285 neighbor_cache[i].
state = ND6_REACHABLE;
286 neighbor_cache[i].counter.reachable_time = reachable_time;
289 if (neighbor_cache[i].q != NULL) {
306 ND6_STATS_INC(nd6.lenerr);
307 ND6_STATS_INC(nd6.drop);
316 if (p->
len < (
sizeof(
struct ns_header) + (lladdr_opt->length << 3))) {
326 if ((ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) ||
327 (ip6_addr_istentative(netif_ip6_addr_state(inp, i)) &&
328 ip6_addr_isany(ip6_current_src_addr()))) &&
329 ip6_addr_cmp(&(ns_hdr->target_address), netif_ip6_addr(inp, i))) {
342 if (ip6_addr_isany(ip6_current_src_addr())) {
345 if (!ip6_addr_isinvalid(netif_ip6_addr_state(inp, i)) &&
346 ip6_addr_cmp(&(ns_hdr->target_address), netif_ip6_addr(inp, i))) {
348 nd6_send_na(inp, netif_ip6_addr(inp, i), ND6_FLAG_OVERRIDE | ND6_SEND_FLAG_ALLNODES_DEST);
349 if (ip6_addr_istentative(netif_ip6_addr_state(inp, i))) {
351 netif_ip6_addr_set_state(inp, i, IP6_ADDR_INVALID);
356 ip6_addr_t target_address;
360 if (lladdr_opt == NULL) {
363 ND6_STATS_INC(nd6.proterr);
364 ND6_STATS_INC(nd6.drop);
368 i = nd6_find_neighbor_cache_entry(ip6_current_src_addr());
371 if (neighbor_cache[i].state == ND6_INCOMPLETE) {
372 neighbor_cache[i].netif = inp;
373 MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->
hwaddr_len);
376 neighbor_cache[i].state = ND6_DELAY;
383 i = nd6_new_neighbor_cache_entry();
388 ND6_STATS_INC(nd6.memerr);
391 neighbor_cache[i].netif = inp;
392 MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->
hwaddr_len);
393 ip6_addr_set(&(neighbor_cache[i].next_hop_address), ip6_current_src_addr());
397 neighbor_cache[i].state = ND6_DELAY;
402 ip6_addr_set(&target_address, &(ns_hdr->target_address));
405 nd6_send_na(inp, &target_address, ND6_FLAG_SOLICITED | ND6_FLAG_OVERRIDE);
415#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS
417 u8_t rdnss_server_idx = 0;
424 ND6_STATS_INC(nd6.lenerr);
425 ND6_STATS_INC(nd6.drop);
432#if LWIP_IPV6_SEND_ROUTER_SOLICIT
435 (nd6_send_rs(inp) ==
ERR_OK)) {
441 i = nd6_get_router(ip6_current_src_addr(), inp);
444 i = nd6_new_router(ip6_current_src_addr(), inp);
450 ND6_STATS_INC(nd6.memerr);
455 default_router_list[i].invalidation_timer = lwip_htons(ra_hdr->router_lifetime);
458#if LWIP_ND6_ALLOW_RA_UPDATES
459 if (ra_hdr->retrans_timer > 0) {
460 retrans_timer = lwip_htonl(ra_hdr->retrans_timer);
462 if (ra_hdr->reachable_time > 0) {
463 reachable_time = lwip_htonl(ra_hdr->reachable_time);
471 default_router_list[i].flags = ra_hdr->flags;
477 while ((p->
tot_len - offset) > 0) {
480 buffer = &((u8_t*)p->
payload)[offset];
482 buffer = nd6_ra_buffer;
485 ND6_STATS_INC(nd6.lenerr);
486 ND6_STATS_INC(nd6.drop);
490 if (buffer[1] == 0) {
493 ND6_STATS_INC(nd6.lenerr);
494 ND6_STATS_INC(nd6.drop);
502 if ((default_router_list[i].neighbor_entry != NULL) &&
503 (default_router_list[i].neighbor_entry->state == ND6_INCOMPLETE)) {
504 SMEMCPY(default_router_list[i].neighbor_entry->lladdr, lladdr_opt->addr, inp->
hwaddr_len);
505 default_router_list[i].neighbor_entry->state = ND6_REACHABLE;
506 default_router_list[i].neighbor_entry->counter.reachable_time = reachable_time;
514 if (lwip_htonl(mtu_opt->mtu) >= 1280) {
515#if LWIP_ND6_ALLOW_RA_UPDATES
516 inp->
mtu = (u16_t)lwip_htonl(mtu_opt->mtu);
526 if ((prefix_opt->flags & ND6_PREFIX_FLAG_ON_LINK) &&
527 (prefix_opt->prefix_length == 64) &&
528 !ip6_addr_islinklocal(&(prefix_opt->prefix))) {
531 ip6_addr_t prefix_addr;
534 ip6_addr_set(&prefix_addr, &(prefix_opt->prefix));
537 prefix = nd6_get_onlink_prefix(&prefix_addr, inp);
540 prefix = nd6_new_onlink_prefix(&prefix_addr, inp);
543 prefix_list[prefix].invalidation_timer = lwip_htonl(prefix_opt->valid_lifetime);
545#if LWIP_IPV6_AUTOCONFIG
546 if (prefix_opt->flags & ND6_PREFIX_FLAG_AUTONOMOUS) {
549 prefix_list[prefix].flags |= ND6_PREFIX_AUTOCONFIG_AUTONOMOUS;
563#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS
564 case ND6_OPTION_TYPE_RDNSS:
570 num = (rdnss_opt->length - 1) / 2;
572 ip_addr_t rdnss_address;
575 ip_addr_copy_from_ip6(rdnss_address, rdnss_opt->rdnss_address[n]);
577 if (htonl(rdnss_opt->lifetime) > 0) {
579 dns_setserver(rdnss_server_idx++, &rdnss_address);
584 const ip_addr_t *addr = dns_getserver(s);
585 if(ip_addr_cmp(addr, &rdnss_address)) {
586 dns_setserver(s, NULL);
596 ND6_STATS_INC(nd6.proterr);
600 offset += 8 * ((u16_t)buffer[1]);
615 ND6_STATS_INC(nd6.lenerr);
616 ND6_STATS_INC(nd6.drop);
632 ip6_addr_set(&tmp, &(redir_hdr->destination_address));
635 i = nd6_find_destination_cache_entry(&tmp);
643 ip6_addr_set(&(destination_cache[i].next_hop_addr), &(redir_hdr->target_address));
646 if (lladdr_opt != NULL) {
647 if (lladdr_opt->type == ND6_OPTION_TYPE_TARGET_LLADDR) {
649 ip6_addr_set(&tmp, &(redir_hdr->target_address));
651 i = nd6_find_neighbor_cache_entry(&tmp);
653 i = nd6_new_neighbor_cache_entry();
655 neighbor_cache[i].netif = inp;
656 MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->
hwaddr_len);
657 ip6_addr_set(&(neighbor_cache[i].next_hop_address), &tmp);
661 neighbor_cache[i].state = ND6_DELAY;
666 if (neighbor_cache[i].state == ND6_INCOMPLETE) {
667 MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->
hwaddr_len);
670 neighbor_cache[i].state = ND6_DELAY;
689 ND6_STATS_INC(nd6.lenerr);
690 ND6_STATS_INC(nd6.drop);
698 ip6_addr_set(&tmp, &(ip6hdr->dest));
701 i = nd6_find_destination_cache_entry(&tmp);
709 pmtu = lwip_htonl(icmp6hdr->data);
710 destination_cache[i].pmtu = (u16_t)LWIP_MIN(pmtu, 0xFFFF);
716 ND6_STATS_INC(nd6.proterr);
717 ND6_STATS_INC(nd6.drop);
742 switch (neighbor_cache[i].
state) {
745 (!neighbor_cache[i].isrouter)) {
747 nd6_free_neighbor_cache_entry(i);
750 neighbor_cache[i].counter.probes_sent++;
751 nd6_send_neighbor_cache_probe(&neighbor_cache[i], ND6_SEND_FLAG_MULTICAST_DEST);
756 if (neighbor_cache[i].q != NULL) {
759 if (neighbor_cache[i].counter.reachable_time <= ND6_TMR_INTERVAL) {
761 neighbor_cache[i].state = ND6_STALE;
762 neighbor_cache[i].counter.stale_time = 0;
764 neighbor_cache[i].counter.reachable_time -= ND6_TMR_INTERVAL;
768 neighbor_cache[i].counter.stale_time++;
771 if (neighbor_cache[i].counter.delay_time <= 1) {
773 neighbor_cache[i].state = ND6_PROBE;
774 neighbor_cache[i].counter.probes_sent = 0;
776 neighbor_cache[i].counter.delay_time--;
781 (!neighbor_cache[i].isrouter)) {
783 nd6_free_neighbor_cache_entry(i);
786 neighbor_cache[i].counter.probes_sent++;
787 nd6_send_neighbor_cache_probe(&neighbor_cache[i], 0);
799 destination_cache[i].age++;
804 if (default_router_list[i].neighbor_entry != NULL) {
806 if (default_router_list[i].invalidation_timer > 0) {
807 default_router_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000;
809 if (default_router_list[i].invalidation_timer < ND6_TMR_INTERVAL / 1000) {
811 default_router_list[i].neighbor_entry->isrouter = 0;
812 default_router_list[i].neighbor_entry = NULL;
813 default_router_list[i].invalidation_timer = 0;
814 default_router_list[i].flags = 0;
821 if (prefix_list[i].
netif != NULL) {
822 if (prefix_list[i].invalidation_timer < ND6_TMR_INTERVAL / 1000) {
824 prefix_list[i].invalidation_timer = 0;
826#if LWIP_IPV6_AUTOCONFIG
828 if (prefix_list[i].
flags & ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED) {
832 if ((netif_ip6_addr_state(prefix_list[i].
netif, j) != IP6_ADDR_INVALID) &&
833 ip6_addr_netcmp(&prefix_list[i].prefix, netif_ip6_addr(prefix_list[i].
netif, j))) {
834 netif_ip6_addr_set_state(prefix_list[i].
netif, j, IP6_ADDR_INVALID);
835 prefix_list[i].flags = 0;
844 prefix_list[i].netif = NULL;
845 prefix_list[i].flags = 0;
847 prefix_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000;
849#if LWIP_IPV6_AUTOCONFIG
851 if (prefix_list[i].
netif->ip6_autoconfig_enabled &&
852 (prefix_list[i].flags & ND6_PREFIX_AUTOCONFIG_AUTONOMOUS) &&
853 !(prefix_list[i].flags & ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED)) {
858 if (netif_ip6_addr_state(prefix_list[i].
netif, j) == IP6_ADDR_INVALID) {
860 netif_ip6_addr_set_parts(prefix_list[i].
netif, j,
861 prefix_list[i].prefix.addr[0], prefix_list[i].prefix.addr[1],
862 netif_ip6_addr(prefix_list[i].
netif, 0)->addr[2], netif_ip6_addr(prefix_list[i].
netif, 0)->addr[3]);
865 netif_ip6_addr_set_state(prefix_list[i].
netif, j, IP6_ADDR_TENTATIVE);
868 prefix_list[i].flags |= ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED;
884 u8_t addr_state = netif_ip6_addr_state(
netif, i);
885 if (ip6_addr_istentative(addr_state)) {
888 netif_ip6_addr_set_state(
netif, i, IP6_ADDR_PREFERRED);
892 nd6_send_ns(
netif, netif_ip6_addr(
netif, i), ND6_SEND_FLAG_MULTICAST_DEST);
894 netif_ip6_addr_set_state(
netif, i, addr_state + 1);
902#if LWIP_IPV6_SEND_ROUTER_SOLICIT
906 (!ip6_addr_isinvalid(netif_ip6_addr_state(
netif, 0)))) {
922nd6_send_neighbor_cache_probe(
struct nd6_neighbor_cache_entry *entry, u8_t
flags)
924 nd6_send_ns(entry->netif, &entry->next_hop_address,
flags);
935nd6_send_ns(
struct netif *
netif,
const ip6_addr_t *target_addr, u8_t
flags)
939 const ip6_addr_t *src_addr;
940 u16_t lladdr_opt_len;
942 if (ip6_addr_isvalid(netif_ip6_addr_state(
netif,0))) {
944 src_addr = netif_ip6_addr(
netif, 0);
948 src_addr = IP6_ADDR_ANY6;
956 ND6_STATS_INC(nd6.memerr);
966 ns_hdr->reserved = 0;
967 ip6_addr_set(&(ns_hdr->target_address), target_addr);
969 if (lladdr_opt_len != 0) {
972 lladdr_opt->length = (u8_t)lladdr_opt_len;
977 if (flags & ND6_SEND_FLAG_MULTICAST_DEST) {
978 ip6_addr_set_solicitednode(&multicast_address, target_addr->addr[3]);
979 target_addr = &multicast_address;
982#if CHECKSUM_GEN_ICMP6
983 IF__NETIF_CHECKSUM_ENABLED(
netif, NETIF_CHECKSUM_GEN_ICMP6) {
984 ns_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->
len, src_addr,
990 ND6_STATS_INC(nd6.xmit);
991 ip6_output_if(p, (src_addr == IP6_ADDR_ANY6) ? NULL : src_addr, target_addr,
1004nd6_send_na(
struct netif *
netif,
const ip6_addr_t *target_addr, u8_t flags)
1009 const ip6_addr_t *src_addr;
1010 const ip6_addr_t *dest_addr;
1011 u16_t lladdr_opt_len;
1016 src_addr = target_addr;
1022 ND6_STATS_INC(nd6.memerr);
1033 na_hdr->flags = flags & 0xf0;
1034 na_hdr->reserved[0] = 0;
1035 na_hdr->reserved[1] = 0;
1036 na_hdr->reserved[2] = 0;
1037 ip6_addr_set(&(na_hdr->target_address), target_addr);
1039 lladdr_opt->type = ND6_OPTION_TYPE_TARGET_LLADDR;
1040 lladdr_opt->length = (u8_t)lladdr_opt_len;
1044 if (flags & ND6_SEND_FLAG_MULTICAST_DEST) {
1045 ip6_addr_set_solicitednode(&multicast_address, target_addr->addr[3]);
1046 dest_addr = &multicast_address;
1047 }
else if (flags & ND6_SEND_FLAG_ALLNODES_DEST) {
1048 ip6_addr_set_allnodes_linklocal(&multicast_address);
1049 dest_addr = &multicast_address;
1051 dest_addr = ip6_current_src_addr();
1054#if CHECKSUM_GEN_ICMP6
1055 IF__NETIF_CHECKSUM_ENABLED(
netif, NETIF_CHECKSUM_GEN_ICMP6) {
1056 na_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->
len, src_addr,
1062 ND6_STATS_INC(nd6.xmit);
1063 ip6_output_if(p, src_addr, dest_addr,
1068#if LWIP_IPV6_SEND_ROUTER_SOLICIT
1080 const ip6_addr_t *src_addr;
1082 u16_t lladdr_opt_len = 0;
1085 if (ip6_addr_isvalid(netif_ip6_addr_state(
netif, 0))) {
1086 src_addr = netif_ip6_addr(
netif, 0);
1088 src_addr = IP6_ADDR_ANY6;
1092 ip6_addr_set_allrouters_linklocal(&multicast_address);
1095 if (src_addr != IP6_ADDR_ANY6) {
1100 ND6_STATS_INC(nd6.memerr);
1110 rs_hdr->reserved = 0;
1112 if (src_addr != IP6_ADDR_ANY6) {
1116 lladdr_opt->length = (u8_t)lladdr_opt_len;
1120#if CHECKSUM_GEN_ICMP6
1121 IF__NETIF_CHECKSUM_ENABLED(
netif, NETIF_CHECKSUM_GEN_ICMP6) {
1122 rs_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->
len, src_addr,
1123 &multicast_address);
1128 ND6_STATS_INC(nd6.xmit);
1130 err = ip6_output_if(p, (src_addr == IP6_ADDR_ANY6) ? NULL : src_addr, &multicast_address,
1146nd6_find_neighbor_cache_entry(
const ip6_addr_t *ip6addr)
1150 if (ip6_addr_cmp(ip6addr, &(neighbor_cache[i].next_hop_address))) {
1167nd6_new_neighbor_cache_entry(
void)
1176 if (neighbor_cache[i].state == ND6_NO_ENTRY) {
1185 if ((neighbor_cache[i].state == ND6_STALE) &&
1186 (!neighbor_cache[i].isrouter)) {
1187 nd6_free_neighbor_cache_entry(i);
1194 if ((neighbor_cache[i].state == ND6_PROBE) &&
1195 (!neighbor_cache[i].isrouter)) {
1196 nd6_free_neighbor_cache_entry(i);
1203 if ((neighbor_cache[i].state == ND6_DELAY) &&
1204 (!neighbor_cache[i].isrouter)) {
1205 nd6_free_neighbor_cache_entry(i);
1211 time = 0xfffffffful;
1214 if ((neighbor_cache[i].state == ND6_REACHABLE) &&
1215 (!neighbor_cache[i].isrouter)) {
1216 if (neighbor_cache[i].counter.reachable_time < time) {
1218 time = neighbor_cache[i].counter.reachable_time;
1223 nd6_free_neighbor_cache_entry(j);
1232 (neighbor_cache[i].q == NULL) &&
1233 (neighbor_cache[i].state == ND6_INCOMPLETE) &&
1234 (!neighbor_cache[i].isrouter)) {
1235 if (neighbor_cache[i].counter.probes_sent >= time) {
1237 time = neighbor_cache[i].counter.probes_sent;
1242 nd6_free_neighbor_cache_entry(j);
1250 if ((neighbor_cache[i].state == ND6_INCOMPLETE) &&
1251 (!neighbor_cache[i].isrouter)) {
1252 if (neighbor_cache[i].counter.probes_sent >= time) {
1254 time = neighbor_cache[i].counter.probes_sent;
1259 nd6_free_neighbor_cache_entry(j);
1274nd6_free_neighbor_cache_entry(s8_t i)
1279 if (neighbor_cache[i].isrouter) {
1285 if (neighbor_cache[i].q != NULL) {
1286 nd6_free_q(neighbor_cache[i].q);
1287 neighbor_cache[i].q = NULL;
1290 neighbor_cache[i].state = ND6_NO_ENTRY;
1291 neighbor_cache[i].isrouter = 0;
1292 neighbor_cache[i].netif = NULL;
1293 neighbor_cache[i].counter.reachable_time = 0;
1294 ip6_addr_set_zero(&(neighbor_cache[i].next_hop_address));
1305nd6_find_destination_cache_entry(
const ip6_addr_t *ip6addr)
1309 if (ip6_addr_cmp(ip6addr, &(destination_cache[i].destination_addr))) {
1324nd6_new_destination_cache_entry(
void)
1331 if (ip6_addr_isany(&(destination_cache[i].destination_addr))) {
1340 if (destination_cache[i].age > age) {
1355nd6_clear_destination_cache(
void)
1360 ip6_addr_set_any(&destination_cache[i].destination_addr);
1371nd6_is_prefix_in_netif(
const ip6_addr_t *ip6addr,
struct netif *
netif)
1376 (prefix_list[i].invalidation_timer > 0) &&
1377 ip6_addr_netcmp(ip6addr, &(prefix_list[i].prefix))) {
1383 if (ip6_addr_isvalid(netif_ip6_addr_state(
netif, i)) &&
1384 ip6_addr_netcmp(ip6addr, netif_ip6_addr(
netif, i))) {
1400nd6_select_router(
const ip6_addr_t *ip6addr,
struct netif *
netif)
1406 static s8_t last_router;
1416 if ((default_router_list[i].neighbor_entry != NULL) &&
1417 (
netif != NULL ?
netif == default_router_list[i].neighbor_entry->netif : 1) &&
1418 (default_router_list[i].invalidation_timer > 0) &&
1419 (default_router_list[i].neighbor_entry->state == ND6_REACHABLE)) {
1429 if ((default_router_list[i].neighbor_entry != NULL) &&
1430 (
netif != NULL ?
netif == default_router_list[i].neighbor_entry->netif : 1) &&
1431 (default_router_list[i].invalidation_timer > 0)) {
1441 if (default_router_list[i].neighbor_entry != NULL &&
1442 (
netif != NULL ?
netif == default_router_list[i].neighbor_entry->netif : 1)) {
1461nd6_find_route(
const ip6_addr_t *ip6addr)
1465 i = nd6_select_router(ip6addr, NULL);
1467 if (default_router_list[i].neighbor_entry != NULL) {
1468 return default_router_list[i].neighbor_entry->netif;
1483nd6_get_router(
const ip6_addr_t *router_addr,
struct netif *
netif)
1489 if ((default_router_list[i].neighbor_entry != NULL) &&
1490 ((
netif != NULL) ?
netif == default_router_list[i].neighbor_entry->netif : 1) &&
1491 ip6_addr_cmp(router_addr, &(default_router_list[i].neighbor_entry->next_hop_address))) {
1508nd6_new_router(
const ip6_addr_t *router_addr,
struct netif *
netif)
1511 s8_t free_router_index;
1512 s8_t neighbor_index;
1515 neighbor_index = nd6_find_neighbor_cache_entry(router_addr);
1516 if (neighbor_index < 0) {
1518 neighbor_index = nd6_new_neighbor_cache_entry();
1519 if (neighbor_index < 0) {
1523 ip6_addr_set(&(neighbor_cache[neighbor_index].next_hop_address), router_addr);
1524 neighbor_cache[neighbor_index].netif =
netif;
1525 neighbor_cache[neighbor_index].q = NULL;
1526 neighbor_cache[neighbor_index].state = ND6_INCOMPLETE;
1527 neighbor_cache[neighbor_index].counter.probes_sent = 1;
1528 nd6_send_neighbor_cache_probe(&neighbor_cache[neighbor_index], ND6_SEND_FLAG_MULTICAST_DEST);
1532 neighbor_cache[neighbor_index].isrouter = 1;
1539 if(default_router_list[router_index].neighbor_entry == &(neighbor_cache[neighbor_index])){
1540 return router_index;
1542 if (default_router_list[router_index].neighbor_entry == NULL) {
1544 free_router_index = router_index;
1548 default_router_list[free_router_index].neighbor_entry = &(neighbor_cache[neighbor_index]);
1549 return free_router_index;
1555 neighbor_cache[neighbor_index].isrouter = 0;
1569nd6_get_onlink_prefix(ip6_addr_t *prefix,
struct netif *
netif)
1575 if ((ip6_addr_netcmp(&(prefix_list[i].prefix), prefix)) &&
1593nd6_new_onlink_prefix(ip6_addr_t *prefix,
struct netif *
netif)
1599 if ((prefix_list[i].
netif == NULL) ||
1600 (prefix_list[i].invalidation_timer == 0)) {
1602 prefix_list[i].netif =
netif;
1603 ip6_addr_set(&(prefix_list[i].prefix), prefix);
1604#if LWIP_IPV6_AUTOCONFIG
1605 prefix_list[i].flags = 0;
1628nd6_get_next_hop_entry(
const ip6_addr_t *ip6addr,
struct netif *
netif)
1630#ifdef LWIP_HOOK_ND6_GET_GW
1631 const ip6_addr_t *next_hop_addr;
1635#if LWIP_NETIF_HWADDRHINT
1636 if (
netif->addr_hint != NULL) {
1638 u8_t addr_hint = *(
netif->addr_hint);
1640 nd6_cached_destination_index = addr_hint;
1646 if (ip6_addr_cmp(ip6addr, &(destination_cache[nd6_cached_destination_index].destination_addr))) {
1649 ND6_STATS_INC(nd6.cachehit);
1652 i = nd6_find_destination_cache_entry(ip6addr);
1655 nd6_cached_destination_index = i;
1658 i = nd6_new_destination_cache_entry();
1661 nd6_cached_destination_index = i;
1668 ip6_addr_set(&(destination_cache[nd6_cached_destination_index].destination_addr), ip6addr);
1671 if (ip6_addr_islinklocal(ip6addr) ||
1672 nd6_is_prefix_in_netif(ip6addr,
netif)) {
1674 destination_cache[nd6_cached_destination_index].pmtu =
netif->
mtu;
1675 ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, destination_cache[nd6_cached_destination_index].destination_addr);
1676#ifdef LWIP_HOOK_ND6_GET_GW
1677 }
else if ((next_hop_addr = LWIP_HOOK_ND6_GET_GW(
netif, ip6addr)) != NULL) {
1679 destination_cache[nd6_cached_destination_index].pmtu =
netif->
mtu;
1680 ip6_addr_set(&destination_cache[nd6_cached_destination_index].next_hop_addr, next_hop_addr);
1684 i = nd6_select_router(ip6addr,
netif);
1687 ip6_addr_set_any(&(destination_cache[nd6_cached_destination_index].destination_addr));
1690 destination_cache[nd6_cached_destination_index].pmtu =
netif->
mtu;
1691 ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, default_router_list[i].neighbor_entry->next_hop_address);
1696#if LWIP_NETIF_HWADDRHINT
1697 if (
netif->addr_hint != NULL) {
1699 *(
netif->addr_hint) = nd6_cached_destination_index;
1704 if (ip6_addr_cmp(&(destination_cache[nd6_cached_destination_index].next_hop_addr),
1705 &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) {
1708 ND6_STATS_INC(nd6.cachehit);
1710 i = nd6_find_neighbor_cache_entry(&(destination_cache[nd6_cached_destination_index].next_hop_addr));
1713 nd6_cached_neighbor_index = i;
1716 i = nd6_new_neighbor_cache_entry();
1719 nd6_cached_neighbor_index = i;
1726 ip6_addr_copy(neighbor_cache[i].next_hop_address,
1727 destination_cache[nd6_cached_destination_index].next_hop_addr);
1728 neighbor_cache[i].isrouter = 0;
1729 neighbor_cache[i].netif =
netif;
1730 neighbor_cache[i].
state = ND6_INCOMPLETE;
1731 neighbor_cache[i].counter.probes_sent = 1;
1732 nd6_send_neighbor_cache_probe(&neighbor_cache[i], ND6_SEND_FLAG_MULTICAST_DEST);
1737 destination_cache[nd6_cached_destination_index].age = 0;
1739 return nd6_cached_neighbor_index;
1750nd6_queue_packet(s8_t neighbor_index,
struct pbuf *q)
1754 int copy_needed = 0;
1755#if LWIP_ND6_QUEUEING
1756 struct nd6_q_entry *new_entry, *r;
1777 while ((p == NULL) && (neighbor_cache[neighbor_index].q != NULL)) {
1779#if LWIP_ND6_QUEUEING
1780 r = neighbor_cache[neighbor_index].q;
1781 neighbor_cache[neighbor_index].q = r->next;
1785 pbuf_free(neighbor_cache[neighbor_index].q);
1786 neighbor_cache[neighbor_index].q = NULL;
1804#if LWIP_ND6_QUEUEING
1806 new_entry = (
struct nd6_q_entry *)
memp_malloc(MEMP_ND6_QUEUE);
1807 if ((new_entry == NULL) && (neighbor_cache[neighbor_index].q != NULL)) {
1809 r = neighbor_cache[neighbor_index].q;
1810 neighbor_cache[neighbor_index].q = r->next;
1813 new_entry = (
struct nd6_q_entry *)
memp_malloc(MEMP_ND6_QUEUE);
1815 if (new_entry != NULL) {
1816 new_entry->next = NULL;
1818 if (neighbor_cache[neighbor_index].q != NULL) {
1820 r = neighbor_cache[neighbor_index].q;
1821 while (r->next != NULL) {
1824 r->
next = new_entry;
1827 neighbor_cache[neighbor_index].q = new_entry;
1839 if (neighbor_cache[neighbor_index].q != NULL) {
1840 pbuf_free(neighbor_cache[neighbor_index].q);
1842 neighbor_cache[neighbor_index].q = p;
1854#if LWIP_ND6_QUEUEING
1861nd6_free_q(
struct nd6_q_entry *q)
1863 struct nd6_q_entry *r;
1864 LWIP_ASSERT(
"q != NULL", q != NULL);
1865 LWIP_ASSERT(
"q->p != NULL", q->p != NULL);
1869 LWIP_ASSERT(
"r->p != NULL", (r->p != NULL));
1886#if LWIP_ND6_QUEUEING
1887 struct nd6_q_entry *q;
1894#if LWIP_ND6_QUEUEING
1895 while (neighbor_cache[i].q != NULL) {
1897 q = neighbor_cache[i].q;
1899 neighbor_cache[i].q = q->next;
1901 ip6hdr = (
struct ip6_hdr *)(q->p->payload);
1903 ip6_addr_set(&dest, &(ip6hdr->dest));
1905 (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].
netif, q->p, &dest);
1912 if (neighbor_cache[i].q != NULL) {
1914 ip6hdr = (
struct ip6_hdr *)(neighbor_cache[i].q->payload);
1916 ip6_addr_set(&dest, &(ip6hdr->dest));
1918 (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].
netif, neighbor_cache[i].q, &dest);
1921 neighbor_cache[i].q = NULL;
1949nd6_get_next_hop_addr_or_queue(
struct netif *
netif,
struct pbuf *q,
const ip6_addr_t *ip6addr,
const u8_t **hwaddrp)
1954 i = nd6_get_next_hop_entry(ip6addr,
netif);
1961 if (neighbor_cache[i].state == ND6_STALE) {
1963 neighbor_cache[i].state = ND6_DELAY;
1967 if ((neighbor_cache[i].state == ND6_REACHABLE) ||
1968 (neighbor_cache[i].state == ND6_DELAY) ||
1969 (neighbor_cache[i].state == ND6_PROBE)) {
1972 *hwaddrp = neighbor_cache[i].lladdr;
1978 return nd6_queue_packet(i, q);
1990nd6_get_destination_mtu(
const ip6_addr_t *ip6addr,
struct netif *
netif)
1994 i = nd6_find_destination_cache_entry(ip6addr);
1996 if (destination_cache[i].pmtu > 0) {
1997 return destination_cache[i].pmtu;
2001 if (
netif != NULL) {
2009#if LWIP_ND6_TCP_REACHABILITY_HINTS
2020nd6_reachability_hint(
const ip6_addr_t *ip6addr)
2025 if (ip6_addr_cmp(ip6addr, &(destination_cache[nd6_cached_destination_index].destination_addr))) {
2026 i = nd6_cached_destination_index;
2027 ND6_STATS_INC(nd6.cachehit);
2029 i = nd6_find_destination_cache_entry(ip6addr);
2036 if (ip6_addr_cmp(&(destination_cache[i].next_hop_addr), &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) {
2037 i = nd6_cached_neighbor_index;
2038 ND6_STATS_INC(nd6.cachehit);
2040 i = nd6_find_neighbor_cache_entry(&(destination_cache[i].next_hop_addr));
2047 if (neighbor_cache[i].state == ND6_INCOMPLETE || neighbor_cache[i].state == ND6_NO_ENTRY) {
2052 neighbor_cache[i].state = ND6_REACHABLE;
2053 neighbor_cache[i].counter.reachable_time = reachable_time;
2069 prefix_list[i].netif = NULL;
2070 prefix_list[i].flags = 0;
2076 if (default_router_list[router_index].neighbor_entry == &neighbor_cache[i]) {
2077 default_router_list[router_index].neighbor_entry = NULL;
2078 default_router_list[router_index].flags = 0;
2081 neighbor_cache[i].isrouter = 0;
2082 nd6_free_neighbor_cache_entry(i);
2097nd6_adjust_mld_membership(
struct netif *
netif, s8_t addr_idx, u8_t new_state)
2099 u8_t old_state, old_member, new_member;
2101 old_state = netif_ip6_addr_state(
netif, addr_idx);
2106 old_member = (old_state != IP6_ADDR_INVALID && old_state != IP6_ADDR_TENTATIVE);
2107 new_member = (new_state != IP6_ADDR_INVALID && new_state != IP6_ADDR_TENTATIVE);
2109 if (old_member != new_member) {
2110 ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(
netif, addr_idx)->addr[3]);
2113 mld6_joingroup_netif(
netif, &multicast_address);
2115 mld6_leavegroup_netif(
netif, &multicast_address);
#define LWIP_DEBUGF(debug, message)
#define LWIP_IPV6_NUM_ADDRESSES
#define LWIP_IPV6_DUP_DETECT_ATTEMPTS
#define LWIP_ND6_REACHABLE_TIME
#define LWIP_ND6_DELAY_FIRST_PROBE_TIME
#define LWIP_ND6_RETRANS_TIMER
#define LWIP_ND6_NUM_ROUTERS
#define LWIP_ND6_MAX_MULTICAST_SOLICIT
#define LWIP_ND6_NUM_NEIGHBORS
#define LWIP_ND6_NUM_DESTINATIONS
#define LWIP_ND6_NUM_PREFIXES
void pbuf_ref(struct pbuf *p)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u8_t pbuf_free(struct pbuf *p)
err_t pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from)
u16_t pbuf_copy_partial(const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
void * memp_malloc(memp_t type)
void memp_free(memp_t type, void *mem)
struct netif * netif_list
#define ND6_OPTION_TYPE_PREFIX_INFO
#define ND6_OPTION_TYPE_SOURCE_LLADDR
#define ND6_OPTION_TYPE_MTU
#define ND6_OPTION_TYPE_ROUTE_INFO
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]