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);