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 105 static u8_t nd6_cached_neighbor_index;
106 static u8_t nd6_cached_destination_index;
109 static ip6_addr_t multicast_address;
115 static s8_t nd6_find_neighbor_cache_entry(
const ip6_addr_t *ip6addr);
116 static s8_t nd6_new_neighbor_cache_entry(
void);
117 static void nd6_free_neighbor_cache_entry(s8_t i);
118 static s8_t nd6_find_destination_cache_entry(
const ip6_addr_t *ip6addr);
119 static s8_t nd6_new_destination_cache_entry(
void);
120 static s8_t nd6_is_prefix_in_netif(
const ip6_addr_t *ip6addr,
struct netif *
netif);
121 static s8_t nd6_select_router(
const ip6_addr_t *ip6addr,
struct netif *
netif);
122 static s8_t nd6_get_router(
const ip6_addr_t *router_addr,
struct netif *
netif);
123 static s8_t nd6_new_router(
const ip6_addr_t *router_addr,
struct netif *
netif);
124 static s8_t nd6_get_onlink_prefix(ip6_addr_t *prefix,
struct netif *
netif);
125 static s8_t nd6_new_onlink_prefix(ip6_addr_t *prefix,
struct netif *
netif);
126 static s8_t nd6_get_next_hop_entry(
const ip6_addr_t *ip6addr,
struct netif *
netif);
127 static 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 131 static void nd6_send_ns(
struct netif *
netif,
const ip6_addr_t *target_addr, u8_t flags);
132 static void nd6_send_na(
struct netif *
netif,
const ip6_addr_t *target_addr, u8_t flags);
133 static void nd6_send_neighbor_cache_probe(
struct nd6_neighbor_cache_entry *entry, u8_t flags);
134 #if LWIP_IPV6_SEND_ROUTER_SOLICIT 138 #if LWIP_ND6_QUEUEING 139 static void nd6_free_q(
struct nd6_q_entry *q);
141 #define nd6_free_q(q) pbuf_free(q) 143 static void nd6_send_q(s8_t i);
153 nd6_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);
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)))) {
907 if (nd6_send_rs(netif) ==
ERR_OK) {
922 nd6_send_neighbor_cache_probe(
struct nd6_neighbor_cache_entry *entry, u8_t
flags)
924 nd6_send_ns(entry->netif, &entry->next_hop_address, flags);
935 nd6_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);
946 lladdr_opt_len = ((netif->
hwaddr_len + 2) + 7) >> 3;
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,
1004 nd6_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 1075 nd6_send_rs(
struct netif *netif)
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,
1146 nd6_find_neighbor_cache_entry(
const ip6_addr_t *ip6addr)
1150 if (ip6_addr_cmp(ip6addr, &(neighbor_cache[i].next_hop_address))) {
1167 nd6_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);
1274 nd6_free_neighbor_cache_entry(s8_t i)
1276 if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) {
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));
1305 nd6_find_destination_cache_entry(
const ip6_addr_t *ip6addr)
1309 if (ip6_addr_cmp(ip6addr, &(destination_cache[i].destination_addr))) {
1324 nd6_new_destination_cache_entry(
void)
1331 if (ip6_addr_isany(&(destination_cache[i].destination_addr))) {
1338 j = LWIP_ND6_NUM_DESTINATIONS - 1;
1340 if (destination_cache[i].age > age) {
1355 nd6_clear_destination_cache(
void)
1360 ip6_addr_set_any(&destination_cache[i].destination_addr);
1371 nd6_is_prefix_in_netif(
const ip6_addr_t *ip6addr,
struct netif *netif)
1375 if ((prefix_list[i].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))) {
1400 nd6_select_router(
const ip6_addr_t *ip6addr,
struct netif *netif)
1406 static s8_t last_router;
1413 if (++last_router >= LWIP_ND6_NUM_ROUTERS) {
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)) {
1426 if (++last_router >= LWIP_ND6_NUM_ROUTERS) {
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)) {
1438 if (++last_router >= LWIP_ND6_NUM_ROUTERS) {
1441 if (default_router_list[i].neighbor_entry != NULL &&
1442 (netif != NULL ? netif == default_router_list[i].neighbor_entry->netif : 1)) {
1461 nd6_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;
1483 nd6_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))) {
1508 nd6_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;
1536 for (router_index = LWIP_ND6_NUM_ROUTERS - 1; router_index >= 0; router_index--) {
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;
1547 if (free_router_index < LWIP_ND6_NUM_ROUTERS) {
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;
1569 nd6_get_onlink_prefix(ip6_addr_t *prefix,
struct netif *netif)
1575 if ((ip6_addr_netcmp(&(prefix_list[i].prefix), prefix)) &&
1576 (prefix_list[i].netif == netif)) {
1593 nd6_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;
1628 nd6_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);
1639 if (addr_hint < LWIP_ND6_NUM_DESTINATIONS) {
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;
1750 nd6_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;
1759 if ((neighbor_index < 0) || (neighbor_index >= LWIP_ND6_NUM_NEIGHBORS)) {
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 1861 nd6_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;
1890 if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) {
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;
1949 nd6_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);
1990 nd6_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 2020 nd6_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;
2063 nd6_cleanup_netif(
struct netif *netif)
2068 if (prefix_list[i].netif == netif) {
2069 prefix_list[i].netif = NULL;
2070 prefix_list[i].flags = 0;
2074 if (neighbor_cache[i].netif == netif) {
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);
2097 nd6_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);
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
struct netif * netif_list
void pbuf_ref(struct pbuf *p)
void memp_free(memp_t type, void *mem)
err_t pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from)
#define LWIP_ND6_NUM_PREFIXES
#define LWIP_ND6_MAX_MULTICAST_SOLICIT
#define ND6_OPTION_TYPE_MTU
#define LWIP_ND6_DELAY_FIRST_PROBE_TIME
#define LWIP_IPV6_DUP_DETECT_ATTEMPTS
#define ND6_OPTION_TYPE_ROUTE_INFO
#define LWIP_DEBUGF(debug, message)
#define LWIP_ND6_REACHABLE_TIME
#define LWIP_ND6_NUM_DESTINATIONS
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u16_t pbuf_copy_partial(const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
#define LWIP_ND6_NUM_NEIGHBORS
u8_t pbuf_free(struct pbuf *p)
#define ND6_OPTION_TYPE_SOURCE_LLADDR
#define ND6_OPTION_TYPE_PREFIX_INFO
#define LWIP_IPV6_NUM_ADDRESSES
void * memp_malloc(memp_t type)
#define LWIP_ND6_NUM_ROUTERS
#define LWIP_IPV6_SEND_ROUTER_SOLICIT
#define LWIP_ND6_RETRANS_TIMER