1 /** 2 * @file 3 * 4 * Neighbor discovery and stateless address autoconfiguration for IPv6. 5 * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 6 * (Address autoconfiguration). 7 */ 8 9 /* 10 * Copyright (c) 2010 Inico Technologies Ltd. 11 * All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without modification, 14 * are permitted provided that the following conditions are met: 15 * 16 * 1. Redistributions of source code must retain the above copyright notice, 17 * this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright notice, 19 * this list of conditions and the following disclaimer in the documentation 20 * and/or other materials provided with the distribution. 21 * 3. The name of the author may not be used to endorse or promote products 22 * derived from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 27 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 29 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 33 * OF SUCH DAMAGE. 34 * 35 * This file is part of the lwIP TCP/IP stack. 36 * 37 * Author: Ivan Delamer <delamer@inicotech.com> 38 * 39 * 40 * Please coordinate changes and requests with Ivan Delamer 41 * <delamer@inicotech.com> 42 */ 43 44 #include "lwip/opt.h" 45 46 #if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ 47 48 #include "lwip/nd6.h" 49 #include "lwip/priv/nd6_priv.h" 50 #include "lwip/prot/nd6.h" 51 #include "lwip/prot/icmp6.h" 52 #include "lwip/pbuf.h" 53 #include "lwip/mem.h" 54 #include "lwip/memp.h" 55 #include "lwip/ip6.h" 56 #include "lwip/ip6_addr.h" 57 #include "lwip/inet_chksum.h" 58 #include "lwip/netif.h" 59 #include "lwip/icmp6.h" 60 #include "lwip/mld6.h" 61 #include "lwip/ip.h" 62 #include "lwip/stats.h" 63 #include "lwip/dns.h" 64 65 #include <string.h> 66 67 #ifdef LWIP_HOOK_FILENAME 68 #include LWIP_HOOK_FILENAME 69 #endif 70 71 #if LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK 72 #error LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK 73 #endif 74 75 /* Router tables. */ 76 struct nd6_neighbor_cache_entry neighbor_cache[LWIP_ND6_NUM_NEIGHBORS]; 77 struct nd6_destination_cache_entry destination_cache[LWIP_ND6_NUM_DESTINATIONS]; 78 struct nd6_prefix_list_entry prefix_list[LWIP_ND6_NUM_PREFIXES]; 79 struct nd6_router_list_entry default_router_list[LWIP_ND6_NUM_ROUTERS]; 80 81 /* Default values, can be updated by a RA message. */ 82 u32_t reachable_time = LWIP_ND6_REACHABLE_TIME; 83 u32_t retrans_timer = LWIP_ND6_RETRANS_TIMER; /* @todo implement this value in timer */ 84 85 /* Index for cache entries. */ 86 static u8_t nd6_cached_neighbor_index; 87 static u8_t nd6_cached_destination_index; 88 89 /* Multicast address holder. */ 90 static ip6_addr_t multicast_address; 91 92 /* Static buffer to parse RA packet options */ 93 union ra_options { 94 struct lladdr_option lladdr; 95 struct mtu_option mtu; 96 struct prefix_option prefix; 97 #if LWIP_ND6_RDNSS_MAX_DNS_SERVERS 98 struct rdnss_option rdnss; 99 #endif 100 }; 101 static union ra_options nd6_ra_buffer; 102 103 /* Forward declarations. */ 104 static s8_t nd6_find_neighbor_cache_entry(const ip6_addr_t *ip6addr); 105 static s8_t nd6_new_neighbor_cache_entry(void); 106 static void nd6_free_neighbor_cache_entry(s8_t i); 107 static s8_t nd6_find_destination_cache_entry(const ip6_addr_t *ip6addr); 108 static s8_t nd6_new_destination_cache_entry(void); 109 static s8_t nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif); 110 static s8_t nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif); 111 static s8_t nd6_get_router(const ip6_addr_t *router_addr, struct netif *netif); 112 static s8_t nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif); 113 static s8_t nd6_get_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif); 114 static s8_t nd6_new_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif); 115 static s8_t nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif); 116 static err_t nd6_queue_packet(s8_t neighbor_index, struct pbuf *q); 117 118 #define ND6_SEND_FLAG_MULTICAST_DEST 0x01 119 #define ND6_SEND_FLAG_ALLNODES_DEST 0x02 120 #define ND6_SEND_FLAG_ANY_SRC 0x04 121 static void nd6_send_ns(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags); 122 static void nd6_send_na(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags); 123 static void nd6_send_neighbor_cache_probe(struct nd6_neighbor_cache_entry *entry, u8_t flags); 124 #if LWIP_IPV6_SEND_ROUTER_SOLICIT 125 static err_t nd6_send_rs(struct netif *netif); 126 #endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ 127 128 #if LWIP_ND6_QUEUEING 129 static void nd6_free_q(struct nd6_q_entry *q); 130 #else /* LWIP_ND6_QUEUEING */ 131 #define nd6_free_q(q) pbuf_free(q) 132 #endif /* LWIP_ND6_QUEUEING */ 133 static void nd6_send_q(s8_t i); 134 135 136 /** 137 * A local address has been determined to be a duplicate. Take the appropriate 138 * action(s) on the address and the interface as a whole. 139 * 140 * @param netif the netif that owns the address 141 * @param addr_idx the index of the address detected to be a duplicate 142 */ 143 static void 144 nd6_duplicate_addr_detected(struct netif *netif, s8_t addr_idx) 145 { 146 147 /* Mark the address as duplicate, but leave its lifetimes alone. If this was 148 * a manually assigned address, it will remain in existence as duplicate, and 149 * as such be unusable for any practical purposes until manual intervention. 150 * If this was an autogenerated address, the address will follow normal 151 * expiration rules, and thus disappear once its valid lifetime expires. */ 152 netif_ip6_addr_set_state(netif, addr_idx, IP6_ADDR_DUPLICATED); 153 154 #if LWIP_IPV6_AUTOCONFIG 155 /* If the affected address was the link-local address that we use to generate 156 * all other addresses, then we should not continue to use those derived 157 * addresses either, so mark them as duplicate as well. For autoconfig-only 158 * setups, this will make the interface effectively unusable, approaching the 159 * intention of RFC 4862 Sec. 5.4.5. @todo implement the full requirements */ 160 if (addr_idx == 0) { 161 s8_t i; 162 for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 163 if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i)) && 164 !netif_ip6_addr_isstatic(netif, i)) { 165 netif_ip6_addr_set_state(netif, i, IP6_ADDR_DUPLICATED); 166 } 167 } 168 } 169 #endif /* LWIP_IPV6_AUTOCONFIG */ 170 } 171 172 #if LWIP_IPV6_AUTOCONFIG 173 /** 174 * We received a router advertisement that contains a prefix with the 175 * autoconfiguration flag set. Add or update an associated autogenerated 176 * address. 177 * 178 * @param netif the netif on which the router advertisement arrived 179 * @param prefix_opt a pointer to the prefix option data 180 * @param prefix_addr an aligned copy of the prefix address 181 */ 182 static void 183 nd6_process_autoconfig_prefix(struct netif *netif, 184 struct prefix_option *prefix_opt, const ip6_addr_t *prefix_addr) 185 { 186 ip6_addr_t ip6addr; 187 u32_t valid_life, pref_life; 188 u8_t addr_state; 189 s8_t i, free_idx; 190 191 /* The caller already checks RFC 4862 Sec. 5.5.3 points (a) and (b). We do 192 * the rest, starting with checks for (c) and (d) here. */ 193 valid_life = lwip_htonl(prefix_opt->valid_lifetime); 194 pref_life = lwip_htonl(prefix_opt->preferred_lifetime); 195 if (pref_life > valid_life || prefix_opt->prefix_length != 64) { 196 return; /* silently ignore this prefix for autoconfiguration purposes */ 197 } 198 199 /* If an autogenerated address already exists for this prefix, update its 200 * lifetimes. An address is considered autogenerated if 1) it is not static 201 * (i.e., manually assigned), and 2) there is an advertised autoconfiguration 202 * prefix for it (the one we are processing here). This does not necessarily 203 * exclude the possibility that the address was actually assigned by, say, 204 * DHCPv6. If that distinction becomes important in the future, more state 205 * must be kept. As explained elsewhere we also update lifetimes of tentative 206 * and duplicate addresses. Skip address slot 0 (the link-local address). */ 207 for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 208 addr_state = netif_ip6_addr_state(netif, i); 209 if (!ip6_addr_isinvalid(addr_state) && !netif_ip6_addr_isstatic(netif, i) && 210 ip6_addr_netcmp(prefix_addr, netif_ip6_addr(netif, i))) { 211 /* Update the valid lifetime, as per RFC 4862 Sec. 5.5.3 point (e). 212 * The valid lifetime will never drop to zero as a result of this. */ 213 u32_t remaining_life = netif_ip6_addr_valid_life(netif, i); 214 if (valid_life > ND6_2HRS || valid_life > remaining_life) { 215 netif_ip6_addr_set_valid_life(netif, i, valid_life); 216 } else if (remaining_life > ND6_2HRS) { 217 netif_ip6_addr_set_valid_life(netif, i, ND6_2HRS); 218 } 219 LWIP_ASSERT("bad valid lifetime", !netif_ip6_addr_isstatic(netif, i)); 220 /* Update the preferred lifetime. No bounds checks are needed here. In 221 * rare cases the advertisement may un-deprecate the address, though. 222 * Deprecation is left to the timer code where it is handled anyway. */ 223 if (pref_life > 0 && addr_state == IP6_ADDR_DEPRECATED) { 224 netif_ip6_addr_set_state(netif, i, IP6_ADDR_PREFERRED); 225 } 226 netif_ip6_addr_set_pref_life(netif, i, pref_life); 227 return; /* there should be at most one matching address */ 228 } 229 } 230 231 /* No autogenerated address exists for this prefix yet. See if we can add a 232 * new one. However, if IPv6 autoconfiguration is administratively disabled, 233 * do not generate new addresses, but do keep updating lifetimes for existing 234 * addresses. Also, when adding new addresses, we must protect explicitly 235 * against a valid lifetime of zero, because again, we use that as a special 236 * value. The generated address would otherwise expire immediately anyway. 237 * Finally, the original link-local address must be usable at all. We start 238 * creating addresses even if the link-local address is still in tentative 239 * state though, and deal with the fallout of that upon DAD collision. */ 240 addr_state = netif_ip6_addr_state(netif, 0); 241 if (!netif->ip6_autoconfig_enabled || valid_life == IP6_ADDR_LIFE_STATIC || 242 ip6_addr_isinvalid(addr_state) || ip6_addr_isduplicated(addr_state)) { 243 return; 244 } 245 246 /* Construct the new address that we intend to use, and then see if that 247 * address really does not exist. It might have been added manually, after 248 * all. As a side effect, find a free slot. Note that we cannot use 249 * netif_add_ip6_address() here, as it would return ERR_OK if the address 250 * already did exist, resulting in that address being given lifetimes. */ 251 IP6_ADDR(&ip6addr, prefix_addr->addr[0], prefix_addr->addr[1], 252 netif_ip6_addr(netif, 0)->addr[2], netif_ip6_addr(netif, 0)->addr[3]); 253 ip6_addr_assign_zone(&ip6addr, IP6_UNICAST, netif); 254 255 free_idx = 0; 256 for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 257 if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i))) { 258 if (ip6_addr_cmp(&ip6addr, netif_ip6_addr(netif, i))) { 259 return; /* formed address already exists */ 260 } 261 } else if (free_idx == 0) { 262 free_idx = i; 263 } 264 } 265 if (free_idx == 0) { 266 return; /* no address slots available, try again on next advertisement */ 267 } 268 269 /* Assign the new address to the interface. */ 270 ip_addr_copy_from_ip6(netif->ip6_addr[free_idx], ip6addr); 271 netif_ip6_addr_set_valid_life(netif, free_idx, valid_life); 272 netif_ip6_addr_set_pref_life(netif, free_idx, pref_life); 273 netif_ip6_addr_set_state(netif, free_idx, IP6_ADDR_TENTATIVE); 274 } 275 #endif /* LWIP_IPV6_AUTOCONFIG */ 276 277 /** 278 * Process an incoming neighbor discovery message 279 * 280 * @param p the nd packet, p->payload pointing to the icmpv6 header 281 * @param inp the netif on which this packet was received 282 */ 283 void 284 nd6_input(struct pbuf *p, struct netif *inp) 285 { 286 u8_t msg_type; 287 s8_t i; 288 289 ND6_STATS_INC(nd6.recv); 290 291 msg_type = *((u8_t *)p->payload); 292 switch (msg_type) { 293 case ICMP6_TYPE_NA: /* Neighbor Advertisement. */ 294 { 295 struct na_header *na_hdr; 296 struct lladdr_option *lladdr_opt; 297 ip6_addr_t target_address; 298 299 /* Check that na header fits in packet. */ 300 if (p->len < (sizeof(struct na_header))) { 301 /* @todo debug message */ 302 pbuf_free(p); 303 ND6_STATS_INC(nd6.lenerr); 304 ND6_STATS_INC(nd6.drop); 305 return; 306 } 307 308 na_hdr = (struct na_header *)p->payload; 309 310 /* Create an aligned, zoned copy of the target address. */ 311 ip6_addr_copy_from_packed(target_address, na_hdr->target_address); 312 ip6_addr_assign_zone(&target_address, IP6_UNICAST, inp); 313 314 /* Check a subset of the other RFC 4861 Sec. 7.1.2 requirements. */ 315 if (IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM || na_hdr->code != 0 || 316 ip6_addr_ismulticast(&target_address)) { 317 pbuf_free(p); 318 ND6_STATS_INC(nd6.proterr); 319 ND6_STATS_INC(nd6.drop); 320 return; 321 } 322 323 /* @todo RFC MUST: if IP destination is multicast, Solicited flag is zero */ 324 /* @todo RFC MUST: all included options have a length greater than zero */ 325 326 /* Unsolicited NA?*/ 327 if (ip6_addr_ismulticast(ip6_current_dest_addr())) { 328 /* This is an unsolicited NA. 329 * link-layer changed? 330 * part of DAD mechanism? */ 331 332 #if LWIP_IPV6_DUP_DETECT_ATTEMPTS 333 /* If the target address matches this netif, it is a DAD response. */ 334 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 335 if (!ip6_addr_isinvalid(netif_ip6_addr_state(inp, i)) && 336 !ip6_addr_isduplicated(netif_ip6_addr_state(inp, i)) && 337 ip6_addr_cmp(&target_address, netif_ip6_addr(inp, i))) { 338 /* We are using a duplicate address. */ 339 nd6_duplicate_addr_detected(inp, i); 340 341 pbuf_free(p); 342 return; 343 } 344 } 345 #endif /* LWIP_IPV6_DUP_DETECT_ATTEMPTS */ 346 347 /* Check that link-layer address option also fits in packet. */ 348 if (p->len < (sizeof(struct na_header) + 2)) { 349 /* @todo debug message */ 350 pbuf_free(p); 351 ND6_STATS_INC(nd6.lenerr); 352 ND6_STATS_INC(nd6.drop); 353 return; 354 } 355 356 lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); 357 358 if (p->len < (sizeof(struct na_header) + (lladdr_opt->length << 3))) { 359 /* @todo debug message */ 360 pbuf_free(p); 361 ND6_STATS_INC(nd6.lenerr); 362 ND6_STATS_INC(nd6.drop); 363 return; 364 } 365 366 /* This is an unsolicited NA, most likely there was a LLADDR change. */ 367 i = nd6_find_neighbor_cache_entry(&target_address); 368 if (i >= 0) { 369 if (na_hdr->flags & ND6_FLAG_OVERRIDE) { 370 MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); 371 } 372 } 373 } else { 374 /* This is a solicited NA. 375 * neighbor address resolution response? 376 * neighbor unreachability detection response? */ 377 378 /* Find the cache entry corresponding to this na. */ 379 i = nd6_find_neighbor_cache_entry(&target_address); 380 if (i < 0) { 381 /* We no longer care about this target address. drop it. */ 382 pbuf_free(p); 383 return; 384 } 385 386 /* Update cache entry. */ 387 if ((na_hdr->flags & ND6_FLAG_OVERRIDE) || 388 (neighbor_cache[i].state == ND6_INCOMPLETE)) { 389 /* Check that link-layer address option also fits in packet. */ 390 if (p->len < (sizeof(struct na_header) + 2)) { 391 /* @todo debug message */ 392 pbuf_free(p); 393 ND6_STATS_INC(nd6.lenerr); 394 ND6_STATS_INC(nd6.drop); 395 return; 396 } 397 398 lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); 399 400 if (p->len < (sizeof(struct na_header) + (lladdr_opt->length << 3))) { 401 /* @todo debug message */ 402 pbuf_free(p); 403 ND6_STATS_INC(nd6.lenerr); 404 ND6_STATS_INC(nd6.drop); 405 return; 406 } 407 408 MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); 409 } 410 411 neighbor_cache[i].netif = inp; 412 neighbor_cache[i].state = ND6_REACHABLE; 413 neighbor_cache[i].counter.reachable_time = reachable_time; 414 415 /* Send queued packets, if any. */ 416 if (neighbor_cache[i].q != NULL) { 417 nd6_send_q(i); 418 } 419 } 420 421 break; /* ICMP6_TYPE_NA */ 422 } 423 case ICMP6_TYPE_NS: /* Neighbor solicitation. */ 424 { 425 struct ns_header *ns_hdr; 426 struct lladdr_option *lladdr_opt; 427 ip6_addr_t target_address; 428 u8_t accepted; 429 430 /* Check that ns header fits in packet. */ 431 if (p->len < sizeof(struct ns_header)) { 432 /* @todo debug message */ 433 pbuf_free(p); 434 ND6_STATS_INC(nd6.lenerr); 435 ND6_STATS_INC(nd6.drop); 436 return; 437 } 438 439 ns_hdr = (struct ns_header *)p->payload; 440 441 /* Create an aligned, zoned copy of the target address. */ 442 ip6_addr_copy_from_packed(target_address, ns_hdr->target_address); 443 ip6_addr_assign_zone(&target_address, IP6_UNICAST, inp); 444 445 /* Check a subset of the other RFC 4861 Sec. 7.1.1 requirements. */ 446 if (IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM || ns_hdr->code != 0 || 447 ip6_addr_ismulticast(&target_address)) { 448 pbuf_free(p); 449 ND6_STATS_INC(nd6.proterr); 450 ND6_STATS_INC(nd6.drop); 451 return; 452 } 453 454 /* @todo RFC MUST: all included options have a length greater than zero */ 455 /* @todo RFC MUST: if IP source is 'any', destination is solicited-node multicast address */ 456 /* @todo RFC MUST: if IP source is 'any', there is no source LL address option */ 457 458 /* Check if there is a link-layer address provided. Only point to it if in this buffer. */ 459 if (p->len >= (sizeof(struct ns_header) + 2)) { 460 lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct ns_header)); 461 if (p->len < (sizeof(struct ns_header) + (lladdr_opt->length << 3))) { 462 lladdr_opt = NULL; 463 } 464 } else { 465 lladdr_opt = NULL; 466 } 467 468 /* Check if the target address is configured on the receiving netif. */ 469 accepted = 0; 470 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { 471 if ((ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) || 472 (ip6_addr_istentative(netif_ip6_addr_state(inp, i)) && 473 ip6_addr_isany(ip6_current_src_addr()))) && 474 ip6_addr_cmp(&target_address, netif_ip6_addr(inp, i))) { 475 accepted = 1; 476 break; 477 } 478 } 479 480 /* NS not for us? */ 481 if (!accepted) { 482 pbuf_free(p); 483 return; 484 } 485 486 /* Check for ANY address in src (DAD algorithm). */ 487 if (ip6_addr_isany(ip6_current_src_addr())) { 488 /* Sender is validating this address. */ 489 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { 490 if (!ip6_addr_isinvalid(netif_ip6_addr_state(inp, i)) && 491 ip6_addr_cmp(&target_address, netif_ip6_addr(inp, i))) { 492 /* Send a NA back so that the sender does not use this address. */ 493 nd6_send_na(inp, netif_ip6_addr(inp, i), ND6_FLAG_OVERRIDE | ND6_SEND_FLAG_ALLNODES_DEST); 494 if (ip6_addr_istentative(netif_ip6_addr_state(inp, i))) { 495 /* We shouldn't use this address either. */ 496 nd6_duplicate_addr_detected(inp, i); 497 } 498 } 499 } 500 } else { 501 /* Sender is trying to resolve our address. */ 502 /* Verify that they included their own link-layer address. */ 503 if (lladdr_opt == NULL) { 504 /* Not a valid message. */ 505 pbuf_free(p); 506 ND6_STATS_INC(nd6.proterr); 507 ND6_STATS_INC(nd6.drop); 508 return; 509 } 510 511 i = nd6_find_neighbor_cache_entry(ip6_current_src_addr()); 512 if (i>= 0) { 513 /* We already have a record for the solicitor. */ 514 if (neighbor_cache[i].state == ND6_INCOMPLETE) { 515 neighbor_cache[i].netif = inp; 516 MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); 517 518 /* Delay probe in case we get confirmation of reachability from upper layer (TCP). */ 519 neighbor_cache[i].state = ND6_DELAY; 520 neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL; 521 } 522 } else { 523 /* Add their IPv6 address and link-layer address to neighbor cache. 524 * We will need it at least to send a unicast NA message, but most 525 * likely we will also be communicating with this node soon. */ 526 i = nd6_new_neighbor_cache_entry(); 527 if (i < 0) { 528 /* We couldn't assign a cache entry for this neighbor. 529 * we won't be able to reply. drop it. */ 530 pbuf_free(p); 531 ND6_STATS_INC(nd6.memerr); 532 return; 533 } 534 neighbor_cache[i].netif = inp; 535 MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); 536 ip6_addr_set(&(neighbor_cache[i].next_hop_address), ip6_current_src_addr()); 537 538 /* Receiving a message does not prove reachability: only in one direction. 539 * Delay probe in case we get confirmation of reachability from upper layer (TCP). */ 540 neighbor_cache[i].state = ND6_DELAY; 541 neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL; 542 } 543 544 /* Send back a NA for us. Allocate the reply pbuf. */ 545 nd6_send_na(inp, &target_address, ND6_FLAG_SOLICITED | ND6_FLAG_OVERRIDE); 546 } 547 548 break; /* ICMP6_TYPE_NS */ 549 } 550 case ICMP6_TYPE_RA: /* Router Advertisement. */ 551 { 552 struct ra_header *ra_hdr; 553 u8_t *buffer; /* Used to copy options. */ 554 u16_t offset; 555 #if LWIP_ND6_RDNSS_MAX_DNS_SERVERS 556 /* There can be multiple RDNSS options per RA */ 557 u8_t rdnss_server_idx = 0; 558 #endif /* LWIP_ND6_RDNSS_MAX_DNS_SERVERS */ 559 560 /* Check that RA header fits in packet. */ 561 if (p->len < sizeof(struct ra_header)) { 562 /* @todo debug message */ 563 pbuf_free(p); 564 ND6_STATS_INC(nd6.lenerr); 565 ND6_STATS_INC(nd6.drop); 566 return; 567 } 568 569 ra_hdr = (struct ra_header *)p->payload; 570 571 /* Check a subset of the other RFC 4861 Sec. 6.1.2 requirements. */ 572 if (!ip6_addr_islinklocal(ip6_current_src_addr()) || 573 IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM || ra_hdr->code != 0) { 574 pbuf_free(p); 575 ND6_STATS_INC(nd6.proterr); 576 ND6_STATS_INC(nd6.drop); 577 return; 578 } 579 580 /* @todo RFC MUST: all included options have a length greater than zero */ 581 582 /* If we are sending RS messages, stop. */ 583 #if LWIP_IPV6_SEND_ROUTER_SOLICIT 584 /* ensure at least one solicitation is sent */ 585 if ((inp->rs_count < LWIP_ND6_MAX_MULTICAST_SOLICIT) || 586 (nd6_send_rs(inp) == ERR_OK)) { 587 inp->rs_count = 0; 588 } 589 #endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ 590 591 /* Get the matching default router entry. */ 592 i = nd6_get_router(ip6_current_src_addr(), inp); 593 if (i < 0) { 594 /* Create a new router entry. */ 595 i = nd6_new_router(ip6_current_src_addr(), inp); 596 } 597 598 if (i < 0) { 599 /* Could not create a new router entry. */ 600 pbuf_free(p); 601 ND6_STATS_INC(nd6.memerr); 602 return; 603 } 604 605 /* Re-set invalidation timer. */ 606 default_router_list[i].invalidation_timer = lwip_htons(ra_hdr->router_lifetime); 607 608 /* Re-set default timer values. */ 609 #if LWIP_ND6_ALLOW_RA_UPDATES 610 if (ra_hdr->retrans_timer > 0) { 611 retrans_timer = lwip_htonl(ra_hdr->retrans_timer); 612 } 613 if (ra_hdr->reachable_time > 0) { 614 reachable_time = lwip_htonl(ra_hdr->reachable_time); 615 } 616 #endif /* LWIP_ND6_ALLOW_RA_UPDATES */ 617 618 /* @todo set default hop limit... */ 619 /* ra_hdr->current_hop_limit;*/ 620 621 /* Update flags in local entry (incl. preference). */ 622 default_router_list[i].flags = ra_hdr->flags; 623 624 /* Offset to options. */ 625 offset = sizeof(struct ra_header); 626 627 /* Process each option. */ 628 while ((p->tot_len - offset) >= 2) { 629 u8_t option_type; 630 u16_t option_len; 631 int option_len8 = pbuf_try_get_at(p, offset + 1); 632 if (option_len8 <= 0) { 633 /* read beyond end or zero length */ 634 goto lenerr_drop_free_return; 635 } 636 option_len = ((u8_t)option_len8) << 3; 637 if (option_len > p->tot_len - offset) { 638 /* short packet (option does not fit in) */ 639 goto lenerr_drop_free_return; 640 } 641 if (p->len == p->tot_len) { 642 /* no need to copy from contiguous pbuf */ 643 buffer = &((u8_t*)p->payload)[offset]; 644 } else { 645 /* check if this option fits into our buffer */ 646 if (option_len > sizeof(nd6_ra_buffer)) { 647 option_type = pbuf_get_at(p, offset); 648 /* invalid option length */ 649 if (option_type != ND6_OPTION_TYPE_RDNSS) { 650 goto lenerr_drop_free_return; 651 } 652 /* we allow RDNSS option to be longer - we'll just drop some servers */ 653 option_len = sizeof(nd6_ra_buffer); 654 } 655 buffer = (u8_t*)&nd6_ra_buffer; 656 option_len = pbuf_copy_partial(p, &nd6_ra_buffer, option_len, offset); 657 } 658 option_type = buffer[0]; 659 switch (option_type) { 660 case ND6_OPTION_TYPE_SOURCE_LLADDR: 661 { 662 struct lladdr_option *lladdr_opt; 663 if (option_len < sizeof(struct lladdr_option)) { 664 goto lenerr_drop_free_return; 665 } 666 lladdr_opt = (struct lladdr_option *)buffer; 667 if ((default_router_list[i].neighbor_entry != NULL) && 668 (default_router_list[i].neighbor_entry->state == ND6_INCOMPLETE)) { 669 SMEMCPY(default_router_list[i].neighbor_entry->lladdr, lladdr_opt->addr, inp->hwaddr_len); 670 default_router_list[i].neighbor_entry->state = ND6_REACHABLE; 671 default_router_list[i].neighbor_entry->counter.reachable_time = reachable_time; 672 } 673 break; 674 } 675 case ND6_OPTION_TYPE_MTU: 676 { 677 struct mtu_option *mtu_opt; 678 if (option_len < sizeof(struct mtu_option)) { 679 goto lenerr_drop_free_return; 680 } 681 mtu_opt = (struct mtu_option *)buffer; 682 if (lwip_htonl(mtu_opt->mtu) >= 1280) { 683 #if LWIP_ND6_ALLOW_RA_UPDATES 684 inp->mtu = (u16_t)lwip_htonl(mtu_opt->mtu); 685 #endif /* LWIP_ND6_ALLOW_RA_UPDATES */ 686 } 687 break; 688 } 689 case ND6_OPTION_TYPE_PREFIX_INFO: 690 { 691 struct prefix_option *prefix_opt; 692 ip6_addr_t prefix_addr; 693 if (option_len < sizeof(struct prefix_option)) { 694 goto lenerr_drop_free_return; 695 } 696 697 prefix_opt = (struct prefix_option *)buffer; 698 699 /* Get a memory-aligned copy of the prefix. */ 700 ip6_addr_copy_from_packed(prefix_addr, prefix_opt->prefix); 701 ip6_addr_assign_zone(&prefix_addr, IP6_UNICAST, inp); 702 703 if (!ip6_addr_islinklocal(&prefix_addr)) { 704 if ((prefix_opt->flags & ND6_PREFIX_FLAG_ON_LINK) && 705 (prefix_opt->prefix_length == 64)) { 706 /* Add to on-link prefix list. */ 707 u32_t valid_life; 708 s8_t prefix; 709 710 valid_life = lwip_htonl(prefix_opt->valid_lifetime); 711 712 /* find cache entry for this prefix. */ 713 prefix = nd6_get_onlink_prefix(&prefix_addr, inp); 714 if (prefix < 0 && valid_life > 0) { 715 /* Create a new cache entry. */ 716 prefix = nd6_new_onlink_prefix(&prefix_addr, inp); 717 } 718 if (prefix >= 0) { 719 prefix_list[prefix].invalidation_timer = valid_life; 720 } 721 } 722 #if LWIP_IPV6_AUTOCONFIG 723 if (prefix_opt->flags & ND6_PREFIX_FLAG_AUTONOMOUS) { 724 /* Perform processing for autoconfiguration. */ 725 nd6_process_autoconfig_prefix(inp, prefix_opt, &prefix_addr); 726 } 727 #endif /* LWIP_IPV6_AUTOCONFIG */ 728 } 729 730 break; 731 } 732 case ND6_OPTION_TYPE_ROUTE_INFO: 733 /* @todo implement preferred routes. 734 struct route_option * route_opt; 735 route_opt = (struct route_option *)buffer;*/ 736 737 break; 738 #if LWIP_ND6_RDNSS_MAX_DNS_SERVERS 739 case ND6_OPTION_TYPE_RDNSS: 740 { 741 u8_t num, n; 742 u16_t copy_offset = offset + SIZEOF_RDNSS_OPTION_BASE; 743 struct rdnss_option * rdnss_opt; 744 if (option_len < SIZEOF_RDNSS_OPTION_BASE) { 745 goto lenerr_drop_free_return; 746 } 747 748 rdnss_opt = (struct rdnss_option *)buffer; 749 num = (rdnss_opt->length - 1) / 2; 750 for (n = 0; (rdnss_server_idx < DNS_MAX_SERVERS) && (n < num); n++) { 751 ip_addr_t rdnss_address; 752 753 /* Copy directly from pbuf to get an aligned, zoned copy of the prefix. */ 754 if (pbuf_copy_partial(p, &rdnss_address, sizeof(ip6_addr_p_t), copy_offset) == sizeof(ip6_addr_p_t)) { 755 IP_SET_TYPE_VAL(rdnss_address, IPADDR_TYPE_V6); 756 ip6_addr_assign_zone(ip_2_ip6(&rdnss_address), IP6_UNKNOWN, inp); 757 758 if (htonl(rdnss_opt->lifetime) > 0) { 759 /* TODO implement Lifetime > 0 */ 760 dns_setserver(rdnss_server_idx++, &rdnss_address); 761 } else { 762 /* TODO implement DNS removal in dns.c */ 763 u8_t s; 764 for (s = 0; s < DNS_MAX_SERVERS; s++) { 765 const ip_addr_t *addr = dns_getserver(s); 766 if(ip_addr_cmp(addr, &rdnss_address)) { 767 dns_setserver(s, NULL); 768 } 769 } 770 } 771 } 772 } 773 break; 774 } 775 #endif /* LWIP_ND6_RDNSS_MAX_DNS_SERVERS */ 776 default: 777 /* Unrecognized option, abort. */ 778 ND6_STATS_INC(nd6.proterr); 779 break; 780 } 781 /* option length is checked earlier to be non-zero to make sure loop ends */ 782 offset += 8 * (u8_t)option_len8; 783 } 784 785 break; /* ICMP6_TYPE_RA */ 786 } 787 case ICMP6_TYPE_RD: /* Redirect */ 788 { 789 struct redirect_header *redir_hdr; 790 struct lladdr_option *lladdr_opt; 791 ip6_addr_t destination_address, target_address; 792 793 #if defined(__minix) 794 /* MINIX 3 only: if forwarding is enabled, do not accept redirects. */ 795 if (!lwip_ip6_forward) { 796 pbuf_free(p); 797 return; 798 } 799 #endif /* defined(__minix) */ 800 801 /* Check that Redir header fits in packet. */ 802 if (p->len < sizeof(struct redirect_header)) { 803 /* @todo debug message */ 804 pbuf_free(p); 805 ND6_STATS_INC(nd6.lenerr); 806 ND6_STATS_INC(nd6.drop); 807 return; 808 } 809 810 redir_hdr = (struct redirect_header *)p->payload; 811 812 /* Create an aligned, zoned copy of the destination address. */ 813 ip6_addr_copy_from_packed(destination_address, redir_hdr->destination_address); 814 ip6_addr_assign_zone(&destination_address, IP6_UNICAST, inp); 815 816 /* Check a subset of the other RFC 4861 Sec. 8.1 requirements. */ 817 if (!ip6_addr_islinklocal(ip6_current_src_addr()) || 818 IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM || 819 redir_hdr->code != 0 || ip6_addr_ismulticast(&destination_address)) { 820 pbuf_free(p); 821 ND6_STATS_INC(nd6.proterr); 822 ND6_STATS_INC(nd6.drop); 823 return; 824 } 825 826 /* @todo RFC MUST: IP source address equals first-hop router for destination_address */ 827 /* @todo RFC MUST: ICMP target address is either link-local address or same as destination_address */ 828 /* @todo RFC MUST: all included options have a length greater than zero */ 829 830 if (p->len >= (sizeof(struct redirect_header) + 2)) { 831 lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct redirect_header)); 832 if (p->len < (sizeof(struct redirect_header) + (lladdr_opt->length << 3))) { 833 lladdr_opt = NULL; 834 } 835 } else { 836 lladdr_opt = NULL; 837 } 838 839 /* Find dest address in cache */ 840 i = nd6_find_destination_cache_entry(&destination_address); 841 if (i < 0) { 842 /* Destination not in cache, drop packet. */ 843 pbuf_free(p); 844 return; 845 } 846 847 /* Create an aligned, zoned copy of the target address. */ 848 ip6_addr_copy_from_packed(target_address, redir_hdr->target_address); 849 ip6_addr_assign_zone(&target_address, IP6_UNICAST, inp); 850 851 /* Set the new target address. */ 852 ip6_addr_copy(destination_cache[i].next_hop_addr, target_address); 853 854 /* If Link-layer address of other router is given, try to add to neighbor cache. */ 855 if (lladdr_opt != NULL) { 856 if (lladdr_opt->type == ND6_OPTION_TYPE_TARGET_LLADDR) { 857 i = nd6_find_neighbor_cache_entry(&target_address); 858 if (i < 0) { 859 i = nd6_new_neighbor_cache_entry(); 860 if (i >= 0) { 861 neighbor_cache[i].netif = inp; 862 MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); 863 ip6_addr_copy(neighbor_cache[i].next_hop_address, target_address); 864 865 /* Receiving a message does not prove reachability: only in one direction. 866 * Delay probe in case we get confirmation of reachability from upper layer (TCP). */ 867 neighbor_cache[i].state = ND6_DELAY; 868 neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL; 869 } 870 } 871 if (i >= 0) { 872 if (neighbor_cache[i].state == ND6_INCOMPLETE) { 873 MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); 874 /* Receiving a message does not prove reachability: only in one direction. 875 * Delay probe in case we get confirmation of reachability from upper layer (TCP). */ 876 neighbor_cache[i].state = ND6_DELAY; 877 neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL; 878 } 879 } 880 } 881 } 882 break; /* ICMP6_TYPE_RD */ 883 } 884 case ICMP6_TYPE_PTB: /* Packet too big */ 885 { 886 struct icmp6_hdr *icmp6hdr; /* Packet too big message */ 887 struct ip6_hdr *ip6hdr; /* IPv6 header of the packet which caused the error */ 888 u32_t pmtu; 889 ip6_addr_t destination_address; 890 891 /* Check that ICMPv6 header + IPv6 header fit in payload */ 892 if (p->len < (sizeof(struct icmp6_hdr) + IP6_HLEN)) { 893 /* drop short packets */ 894 pbuf_free(p); 895 ND6_STATS_INC(nd6.lenerr); 896 ND6_STATS_INC(nd6.drop); 897 return; 898 } 899 900 icmp6hdr = (struct icmp6_hdr *)p->payload; 901 ip6hdr = (struct ip6_hdr *)((u8_t*)p->payload + sizeof(struct icmp6_hdr)); 902 903 /* Create an aligned, zoned copy of the destination address. */ 904 ip6_addr_copy_from_packed(destination_address, ip6hdr->dest); 905 ip6_addr_assign_zone(&destination_address, IP6_UNKNOWN, inp); 906 907 /* Look for entry in destination cache. */ 908 i = nd6_find_destination_cache_entry(&destination_address); 909 if (i < 0) { 910 /* Destination not in cache, drop packet. */ 911 pbuf_free(p); 912 return; 913 } 914 915 /* Change the Path MTU. */ 916 pmtu = lwip_htonl(icmp6hdr->data); 917 destination_cache[i].pmtu = (u16_t)LWIP_MIN(pmtu, 0xFFFF); 918 919 break; /* ICMP6_TYPE_PTB */ 920 } 921 922 default: 923 ND6_STATS_INC(nd6.proterr); 924 ND6_STATS_INC(nd6.drop); 925 break; /* default */ 926 } 927 928 pbuf_free(p); 929 return; 930 lenerr_drop_free_return: 931 ND6_STATS_INC(nd6.lenerr); 932 ND6_STATS_INC(nd6.drop); 933 pbuf_free(p); 934 } 935 936 937 /** 938 * Periodic timer for Neighbor discovery functions: 939 * 940 * - Update neighbor reachability states 941 * - Update destination cache entries age 942 * - Update invalidation timers of default routers and on-link prefixes 943 * - Update lifetimes of our addresses 944 * - Perform duplicate address detection (DAD) for our addresses 945 * - Send router solicitations 946 */ 947 void 948 nd6_tmr(void) 949 { 950 s8_t i; 951 struct netif *netif; 952 953 /* Process neighbor entries. */ 954 for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { 955 switch (neighbor_cache[i].state) { 956 case ND6_INCOMPLETE: 957 if ((neighbor_cache[i].counter.probes_sent >= LWIP_ND6_MAX_MULTICAST_SOLICIT) && 958 (!neighbor_cache[i].isrouter)) { 959 /* Retries exceeded. */ 960 nd6_free_neighbor_cache_entry(i); 961 } else { 962 /* Send a NS for this entry. */ 963 neighbor_cache[i].counter.probes_sent++; 964 nd6_send_neighbor_cache_probe(&neighbor_cache[i], ND6_SEND_FLAG_MULTICAST_DEST); 965 } 966 break; 967 case ND6_REACHABLE: 968 /* Send queued packets, if any are left. Should have been sent already. */ 969 if (neighbor_cache[i].q != NULL) { 970 nd6_send_q(i); 971 } 972 if (neighbor_cache[i].counter.reachable_time <= ND6_TMR_INTERVAL) { 973 /* Change to stale state. */ 974 neighbor_cache[i].state = ND6_STALE; 975 neighbor_cache[i].counter.stale_time = 0; 976 } else { 977 neighbor_cache[i].counter.reachable_time -= ND6_TMR_INTERVAL; 978 } 979 break; 980 case ND6_STALE: 981 neighbor_cache[i].counter.stale_time++; 982 break; 983 case ND6_DELAY: 984 if (neighbor_cache[i].counter.delay_time <= 1) { 985 /* Change to PROBE state. */ 986 neighbor_cache[i].state = ND6_PROBE; 987 neighbor_cache[i].counter.probes_sent = 0; 988 } else { 989 neighbor_cache[i].counter.delay_time--; 990 } 991 break; 992 case ND6_PROBE: 993 if ((neighbor_cache[i].counter.probes_sent >= LWIP_ND6_MAX_MULTICAST_SOLICIT) && 994 (!neighbor_cache[i].isrouter)) { 995 /* Retries exceeded. */ 996 nd6_free_neighbor_cache_entry(i); 997 } else { 998 /* Send a NS for this entry. */ 999 neighbor_cache[i].counter.probes_sent++; 1000 nd6_send_neighbor_cache_probe(&neighbor_cache[i], 0); 1001 } 1002 break; 1003 case ND6_NO_ENTRY: 1004 default: 1005 /* Do nothing. */ 1006 break; 1007 } 1008 } 1009 1010 /* Process destination entries. */ 1011 for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { 1012 destination_cache[i].age++; 1013 } 1014 1015 /* Process router entries. */ 1016 for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { 1017 if (default_router_list[i].neighbor_entry != NULL) { 1018 /* Active entry. */ 1019 if (default_router_list[i].invalidation_timer <= ND6_TMR_INTERVAL / 1000) { 1020 /* No more than 1 second remaining. Clear this entry. Also clear any of 1021 * its destination cache entries, as per RFC 4861 Sec. 5.3 and 6.3.5. */ 1022 s8_t j; 1023 for (j = 0; j < LWIP_ND6_NUM_DESTINATIONS; j++) { 1024 if (ip6_addr_cmp(&destination_cache[j].next_hop_addr, 1025 &default_router_list[i].neighbor_entry->next_hop_address)) { 1026 ip6_addr_set_any(&destination_cache[j].destination_addr); 1027 } 1028 } 1029 default_router_list[i].neighbor_entry->isrouter = 0; 1030 default_router_list[i].neighbor_entry = NULL; 1031 default_router_list[i].invalidation_timer = 0; 1032 default_router_list[i].flags = 0; 1033 } else { 1034 default_router_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000; 1035 } 1036 } 1037 } 1038 1039 /* Process prefix entries. */ 1040 for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) { 1041 if (prefix_list[i].netif != NULL) { 1042 if (prefix_list[i].invalidation_timer <= ND6_TMR_INTERVAL / 1000) { 1043 /* Entry timed out, remove it */ 1044 prefix_list[i].invalidation_timer = 0; 1045 prefix_list[i].netif = NULL; 1046 } else { 1047 prefix_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000; 1048 } 1049 } 1050 } 1051 1052 /* Process our own addresses, updating address lifetimes and/or DAD state. */ 1053 NETIF_FOREACH(netif) { 1054 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { 1055 u8_t addr_state; 1056 #if LWIP_IPV6_ADDRESS_LIFETIMES 1057 /* Step 1: update address lifetimes (valid and preferred). */ 1058 addr_state = netif_ip6_addr_state(netif, i); 1059 /* RFC 4862 is not entirely clear as to whether address lifetimes affect 1060 * tentative addresses, and is even less clear as to what should happen 1061 * with duplicate addresses. We choose to track and update lifetimes for 1062 * both those types, although for different reasons: 1063 * - for tentative addresses, the line of thought of Sec. 5.7 combined 1064 * with the potentially long period that an address may be in tentative 1065 * state (due to the interface being down) suggests that lifetimes 1066 * should be independent of external factors which would include DAD; 1067 * - for duplicate addresses, retiring them early could result in a new 1068 * but unwanted attempt at marking them as valid, while retiring them 1069 * late/never could clog up address slots on the netif. 1070 * As a result, we may end up expiring addresses of either type here. 1071 */ 1072 if (!ip6_addr_isinvalid(addr_state) && 1073 !netif_ip6_addr_isstatic(netif, i)) { 1074 u32_t life = netif_ip6_addr_valid_life(netif, i); 1075 if (life <= ND6_TMR_INTERVAL / 1000) { 1076 /* The address has expired. */ 1077 netif_ip6_addr_set_valid_life(netif, i, 0); 1078 netif_ip6_addr_set_pref_life(netif, i, 0); 1079 netif_ip6_addr_set_state(netif, i, IP6_ADDR_INVALID); 1080 } else { 1081 if (!ip6_addr_life_isinfinite(life)) { 1082 life -= ND6_TMR_INTERVAL / 1000; 1083 LWIP_ASSERT("bad valid lifetime", life != IP6_ADDR_LIFE_STATIC); 1084 netif_ip6_addr_set_valid_life(netif, i, life); 1085 } 1086 /* The address is still here. Update the preferred lifetime too. */ 1087 life = netif_ip6_addr_pref_life(netif, i); 1088 if (life <= ND6_TMR_INTERVAL / 1000) { 1089 /* This case must also trigger if 'life' was already zero, so as to 1090 * deal correctly with advertised preferred-lifetime reductions. */ 1091 netif_ip6_addr_set_pref_life(netif, i, 0); 1092 if (addr_state == IP6_ADDR_PREFERRED) 1093 netif_ip6_addr_set_state(netif, i, IP6_ADDR_DEPRECATED); 1094 } else if (!ip6_addr_life_isinfinite(life)) { 1095 life -= ND6_TMR_INTERVAL / 1000; 1096 netif_ip6_addr_set_pref_life(netif, i, life); 1097 } 1098 } 1099 } 1100 /* The address state may now have changed, so reobtain it next. */ 1101 #endif /* LWIP_IPV6_ADDRESS_LIFETIMES */ 1102 /* Step 2: update DAD state. */ 1103 addr_state = netif_ip6_addr_state(netif, i); 1104 if (ip6_addr_istentative(addr_state)) { 1105 if ((addr_state & IP6_ADDR_TENTATIVE_COUNT_MASK) >= LWIP_IPV6_DUP_DETECT_ATTEMPTS) { 1106 /* No NA received in response. Mark address as valid. For dynamic 1107 * addresses with an expired preferred lifetime, the state is set to 1108 * deprecated right away. That should almost never happen, though. */ 1109 addr_state = IP6_ADDR_PREFERRED; 1110 #if LWIP_IPV6_ADDRESS_LIFETIMES 1111 if (!netif_ip6_addr_isstatic(netif, i) && 1112 netif_ip6_addr_pref_life(netif, i) == 0) { 1113 addr_state = IP6_ADDR_DEPRECATED; 1114 } 1115 #endif /* LWIP_IPV6_ADDRESS_LIFETIMES */ 1116 netif_ip6_addr_set_state(netif, i, addr_state); 1117 } else if (netif_is_up(netif) && netif_is_link_up(netif)) { 1118 /* tentative: set next state by increasing by one */ 1119 netif_ip6_addr_set_state(netif, i, addr_state + 1); 1120 /* Send a NS for this address. Use the unspecified address as source 1121 * address in all cases (RFC 4862 Sec. 5.4.2), not in the least 1122 * because as it is, we only consider multicast replies for DAD. */ 1123 nd6_send_ns(netif, netif_ip6_addr(netif, i), 1124 ND6_SEND_FLAG_MULTICAST_DEST | ND6_SEND_FLAG_ANY_SRC); 1125 } 1126 } 1127 } 1128 } 1129 1130 #if LWIP_IPV6_SEND_ROUTER_SOLICIT 1131 /* Send router solicitation messages, if necessary. */ 1132 NETIF_FOREACH(netif) { 1133 if ((netif->rs_count > 0) && netif_is_up(netif) && 1134 netif_is_link_up(netif) && 1135 !ip6_addr_isinvalid(netif_ip6_addr_state(netif, 0)) && 1136 !ip6_addr_isduplicated(netif_ip6_addr_state(netif, 0))) { 1137 if (nd6_send_rs(netif) == ERR_OK) { 1138 netif->rs_count--; 1139 } 1140 } 1141 } 1142 #endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ 1143 1144 } 1145 1146 /** Send a neighbor solicitation message for a specific neighbor cache entry 1147 * 1148 * @param entry the neightbor cache entry for wich to send the message 1149 * @param flags one of ND6_SEND_FLAG_* 1150 */ 1151 static void 1152 nd6_send_neighbor_cache_probe(struct nd6_neighbor_cache_entry *entry, u8_t flags) 1153 { 1154 nd6_send_ns(entry->netif, &entry->next_hop_address, flags); 1155 } 1156 1157 /** 1158 * Send a neighbor solicitation message 1159 * 1160 * @param netif the netif on which to send the message 1161 * @param target_addr the IPv6 target address for the ND message 1162 * @param flags one of ND6_SEND_FLAG_* 1163 */ 1164 static void 1165 nd6_send_ns(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags) 1166 { 1167 struct ns_header *ns_hdr; 1168 struct pbuf *p; 1169 const ip6_addr_t *src_addr; 1170 u16_t lladdr_opt_len; 1171 1172 LWIP_ASSERT("target address is required", target_addr != NULL); 1173 1174 if (!(flags & ND6_SEND_FLAG_ANY_SRC) && 1175 ip6_addr_isvalid(netif_ip6_addr_state(netif,0))) { 1176 /* Use link-local address as source address. */ 1177 src_addr = netif_ip6_addr(netif, 0); 1178 /* calculate option length (in 8-byte-blocks) */ 1179 lladdr_opt_len = ((netif->hwaddr_len + 2) + 7) >> 3; 1180 } else { 1181 src_addr = IP6_ADDR_ANY6; 1182 /* Option "MUST NOT be included when the source IP address is the unspecified address." */ 1183 lladdr_opt_len = 0; 1184 } 1185 1186 /* Allocate a packet. */ 1187 p = pbuf_alloc(PBUF_IP, sizeof(struct ns_header) + (lladdr_opt_len << 3), PBUF_RAM); 1188 if (p == NULL) { 1189 ND6_STATS_INC(nd6.memerr); 1190 return; 1191 } 1192 1193 /* Set fields. */ 1194 ns_hdr = (struct ns_header *)p->payload; 1195 1196 ns_hdr->type = ICMP6_TYPE_NS; 1197 ns_hdr->code = 0; 1198 ns_hdr->chksum = 0; 1199 ns_hdr->reserved = 0; 1200 ip6_addr_copy_to_packed(ns_hdr->target_address, *target_addr); 1201 1202 if (lladdr_opt_len != 0) { 1203 struct lladdr_option *lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct ns_header)); 1204 lladdr_opt->type = ND6_OPTION_TYPE_SOURCE_LLADDR; 1205 lladdr_opt->length = (u8_t)lladdr_opt_len; 1206 SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len); 1207 } 1208 1209 /* Generate the solicited node address for the target address. */ 1210 if (flags & ND6_SEND_FLAG_MULTICAST_DEST) { 1211 ip6_addr_set_solicitednode(&multicast_address, target_addr->addr[3]); 1212 ip6_addr_assign_zone(&multicast_address, IP6_MULTICAST, netif); 1213 target_addr = &multicast_address; 1214 } 1215 1216 #if CHECKSUM_GEN_ICMP6 1217 IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) { 1218 ns_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, 1219 target_addr); 1220 } 1221 #endif /* CHECKSUM_GEN_ICMP6 */ 1222 1223 /* Send the packet out. */ 1224 ND6_STATS_INC(nd6.xmit); 1225 ip6_output_if(p, (src_addr == IP6_ADDR_ANY6) ? NULL : src_addr, target_addr, 1226 ND6_HOPLIM, 0, IP6_NEXTH_ICMP6, netif); 1227 pbuf_free(p); 1228 } 1229 1230 /** 1231 * Send a neighbor advertisement message 1232 * 1233 * @param netif the netif on which to send the message 1234 * @param target_addr the IPv6 target address for the ND message 1235 * @param flags one of ND6_SEND_FLAG_* 1236 */ 1237 static void 1238 nd6_send_na(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags) 1239 { 1240 struct na_header *na_hdr; 1241 struct lladdr_option *lladdr_opt; 1242 struct pbuf *p; 1243 const ip6_addr_t *src_addr; 1244 const ip6_addr_t *dest_addr; 1245 u16_t lladdr_opt_len; 1246 1247 LWIP_ASSERT("target address is required", target_addr != NULL); 1248 1249 /* Use link-local address as source address. */ 1250 /* src_addr = netif_ip6_addr(netif, 0); */ 1251 /* Use target address as source address. */ 1252 src_addr = target_addr; 1253 1254 /* Allocate a packet. */ 1255 lladdr_opt_len = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0); 1256 p = pbuf_alloc(PBUF_IP, sizeof(struct na_header) + (lladdr_opt_len << 3), PBUF_RAM); 1257 if (p == NULL) { 1258 ND6_STATS_INC(nd6.memerr); 1259 return; 1260 } 1261 1262 /* Set fields. */ 1263 na_hdr = (struct na_header *)p->payload; 1264 lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); 1265 1266 na_hdr->type = ICMP6_TYPE_NA; 1267 na_hdr->code = 0; 1268 na_hdr->chksum = 0; 1269 na_hdr->flags = flags & 0xf0; 1270 #if defined(__minix) 1271 /* MINIX 3 only: if forwarding is enabled, set the router bit. */ 1272 if (lwip_ip6_forward) { 1273 na_hdr->flags |= ND6_FLAG_ROUTER; 1274 } 1275 #endif /* defined(__minix) */ 1276 na_hdr->reserved[0] = 0; 1277 na_hdr->reserved[1] = 0; 1278 na_hdr->reserved[2] = 0; 1279 ip6_addr_copy_to_packed(na_hdr->target_address, *target_addr); 1280 1281 lladdr_opt->type = ND6_OPTION_TYPE_TARGET_LLADDR; 1282 lladdr_opt->length = (u8_t)lladdr_opt_len; 1283 SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len); 1284 1285 /* Generate the solicited node address for the target address. */ 1286 if (flags & ND6_SEND_FLAG_MULTICAST_DEST) { 1287 ip6_addr_set_solicitednode(&multicast_address, target_addr->addr[3]); 1288 ip6_addr_assign_zone(&multicast_address, IP6_MULTICAST, netif); 1289 dest_addr = &multicast_address; 1290 } else if (flags & ND6_SEND_FLAG_ALLNODES_DEST) { 1291 ip6_addr_set_allnodes_linklocal(&multicast_address); 1292 ip6_addr_assign_zone(&multicast_address, IP6_MULTICAST, netif); 1293 dest_addr = &multicast_address; 1294 } else { 1295 dest_addr = ip6_current_src_addr(); 1296 } 1297 1298 #if CHECKSUM_GEN_ICMP6 1299 IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) { 1300 na_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, 1301 dest_addr); 1302 } 1303 #endif /* CHECKSUM_GEN_ICMP6 */ 1304 1305 /* Send the packet out. */ 1306 ND6_STATS_INC(nd6.xmit); 1307 ip6_output_if(p, src_addr, dest_addr, 1308 ND6_HOPLIM, 0, IP6_NEXTH_ICMP6, netif); 1309 pbuf_free(p); 1310 } 1311 1312 #if LWIP_IPV6_SEND_ROUTER_SOLICIT 1313 /** 1314 * Send a router solicitation message 1315 * 1316 * @param netif the netif on which to send the message 1317 */ 1318 static err_t 1319 nd6_send_rs(struct netif *netif) 1320 { 1321 struct rs_header *rs_hdr; 1322 struct lladdr_option *lladdr_opt; 1323 struct pbuf *p; 1324 const ip6_addr_t *src_addr; 1325 err_t err; 1326 u16_t lladdr_opt_len = 0; 1327 1328 /* Link-local source address, or unspecified address? */ 1329 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, 0))) { 1330 src_addr = netif_ip6_addr(netif, 0); 1331 } else { 1332 src_addr = IP6_ADDR_ANY6; 1333 } 1334 1335 /* Generate the all routers target address. */ 1336 ip6_addr_set_allrouters_linklocal(&multicast_address); 1337 ip6_addr_assign_zone(&multicast_address, IP6_MULTICAST, netif); 1338 1339 /* Allocate a packet. */ 1340 if (src_addr != IP6_ADDR_ANY6) { 1341 lladdr_opt_len = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0); 1342 } 1343 p = pbuf_alloc(PBUF_IP, sizeof(struct rs_header) + (lladdr_opt_len << 3), PBUF_RAM); 1344 if (p == NULL) { 1345 ND6_STATS_INC(nd6.memerr); 1346 return ERR_BUF; 1347 } 1348 1349 /* Set fields. */ 1350 rs_hdr = (struct rs_header *)p->payload; 1351 1352 rs_hdr->type = ICMP6_TYPE_RS; 1353 rs_hdr->code = 0; 1354 rs_hdr->chksum = 0; 1355 rs_hdr->reserved = 0; 1356 1357 if (src_addr != IP6_ADDR_ANY6) { 1358 /* Include our hw address. */ 1359 lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct rs_header)); 1360 lladdr_opt->type = ND6_OPTION_TYPE_SOURCE_LLADDR; 1361 lladdr_opt->length = (u8_t)lladdr_opt_len; 1362 SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len); 1363 } 1364 1365 #if CHECKSUM_GEN_ICMP6 1366 IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) { 1367 rs_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, 1368 &multicast_address); 1369 } 1370 #endif /* CHECKSUM_GEN_ICMP6 */ 1371 1372 /* Send the packet out. */ 1373 ND6_STATS_INC(nd6.xmit); 1374 1375 err = ip6_output_if(p, (src_addr == IP6_ADDR_ANY6) ? NULL : src_addr, &multicast_address, 1376 ND6_HOPLIM, 0, IP6_NEXTH_ICMP6, netif); 1377 pbuf_free(p); 1378 1379 return err; 1380 } 1381 #endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ 1382 1383 /** 1384 * Search for a neighbor cache entry 1385 * 1386 * @param ip6addr the IPv6 address of the neighbor 1387 * @return The neighbor cache entry index that matched, -1 if no 1388 * entry is found 1389 */ 1390 static s8_t 1391 nd6_find_neighbor_cache_entry(const ip6_addr_t *ip6addr) 1392 { 1393 s8_t i; 1394 for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { 1395 if (ip6_addr_cmp(ip6addr, &(neighbor_cache[i].next_hop_address))) { 1396 return i; 1397 } 1398 } 1399 return -1; 1400 } 1401 1402 /** 1403 * Create a new neighbor cache entry. 1404 * 1405 * If no unused entry is found, will try to recycle an old entry 1406 * according to ad-hoc "age" heuristic. 1407 * 1408 * @return The neighbor cache entry index that was created, -1 if no 1409 * entry could be created 1410 */ 1411 static s8_t 1412 nd6_new_neighbor_cache_entry(void) 1413 { 1414 s8_t i; 1415 s8_t j; 1416 u32_t time; 1417 1418 1419 /* First, try to find an empty entry. */ 1420 for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { 1421 if (neighbor_cache[i].state == ND6_NO_ENTRY) { 1422 return i; 1423 } 1424 } 1425 1426 /* We need to recycle an entry. in general, do not recycle if it is a router. */ 1427 1428 /* Next, try to find a Stale entry. */ 1429 for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { 1430 if ((neighbor_cache[i].state == ND6_STALE) && 1431 (!neighbor_cache[i].isrouter)) { 1432 nd6_free_neighbor_cache_entry(i); 1433 return i; 1434 } 1435 } 1436 1437 /* Next, try to find a Probe entry. */ 1438 for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { 1439 if ((neighbor_cache[i].state == ND6_PROBE) && 1440 (!neighbor_cache[i].isrouter)) { 1441 nd6_free_neighbor_cache_entry(i); 1442 return i; 1443 } 1444 } 1445 1446 /* Next, try to find a Delayed entry. */ 1447 for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { 1448 if ((neighbor_cache[i].state == ND6_DELAY) && 1449 (!neighbor_cache[i].isrouter)) { 1450 nd6_free_neighbor_cache_entry(i); 1451 return i; 1452 } 1453 } 1454 1455 /* Next, try to find the oldest reachable entry. */ 1456 time = 0xfffffffful; 1457 j = -1; 1458 for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { 1459 if ((neighbor_cache[i].state == ND6_REACHABLE) && 1460 (!neighbor_cache[i].isrouter)) { 1461 if (neighbor_cache[i].counter.reachable_time < time) { 1462 j = i; 1463 time = neighbor_cache[i].counter.reachable_time; 1464 } 1465 } 1466 } 1467 if (j >= 0) { 1468 nd6_free_neighbor_cache_entry(j); 1469 return j; 1470 } 1471 1472 /* Next, find oldest incomplete entry without queued packets. */ 1473 time = 0; 1474 j = -1; 1475 for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { 1476 if ( 1477 (neighbor_cache[i].q == NULL) && 1478 (neighbor_cache[i].state == ND6_INCOMPLETE) && 1479 (!neighbor_cache[i].isrouter)) { 1480 if (neighbor_cache[i].counter.probes_sent >= time) { 1481 j = i; 1482 time = neighbor_cache[i].counter.probes_sent; 1483 } 1484 } 1485 } 1486 if (j >= 0) { 1487 nd6_free_neighbor_cache_entry(j); 1488 return j; 1489 } 1490 1491 /* Next, find oldest incomplete entry with queued packets. */ 1492 time = 0; 1493 j = -1; 1494 for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { 1495 if ((neighbor_cache[i].state == ND6_INCOMPLETE) && 1496 (!neighbor_cache[i].isrouter)) { 1497 if (neighbor_cache[i].counter.probes_sent >= time) { 1498 j = i; 1499 time = neighbor_cache[i].counter.probes_sent; 1500 } 1501 } 1502 } 1503 if (j >= 0) { 1504 nd6_free_neighbor_cache_entry(j); 1505 return j; 1506 } 1507 1508 /* No more entries to try. */ 1509 return -1; 1510 } 1511 1512 /** 1513 * Will free any resources associated with a neighbor cache 1514 * entry, and will mark it as unused. 1515 * 1516 * @param i the neighbor cache entry index to free 1517 */ 1518 static void 1519 nd6_free_neighbor_cache_entry(s8_t i) 1520 { 1521 if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) { 1522 return; 1523 } 1524 if (neighbor_cache[i].isrouter) { 1525 /* isrouter needs to be cleared before deleting a neighbor cache entry */ 1526 return; 1527 } 1528 1529 /* Free any queued packets. */ 1530 if (neighbor_cache[i].q != NULL) { 1531 nd6_free_q(neighbor_cache[i].q); 1532 neighbor_cache[i].q = NULL; 1533 } 1534 1535 neighbor_cache[i].state = ND6_NO_ENTRY; 1536 neighbor_cache[i].isrouter = 0; 1537 neighbor_cache[i].netif = NULL; 1538 neighbor_cache[i].counter.reachable_time = 0; 1539 ip6_addr_set_zero(&(neighbor_cache[i].next_hop_address)); 1540 } 1541 1542 /** 1543 * Search for a destination cache entry 1544 * 1545 * @param ip6addr the IPv6 address of the destination 1546 * @return The destination cache entry index that matched, -1 if no 1547 * entry is found 1548 */ 1549 static s8_t 1550 nd6_find_destination_cache_entry(const ip6_addr_t *ip6addr) 1551 { 1552 s8_t i; 1553 1554 IP6_ADDR_ZONECHECK(ip6addr); 1555 1556 for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { 1557 if (ip6_addr_cmp(ip6addr, &(destination_cache[i].destination_addr))) { 1558 return i; 1559 } 1560 } 1561 return -1; 1562 } 1563 1564 /** 1565 * Create a new destination cache entry. If no unused entry is found, 1566 * will recycle oldest entry. 1567 * 1568 * @return The destination cache entry index that was created, -1 if no 1569 * entry was created 1570 */ 1571 static s8_t 1572 nd6_new_destination_cache_entry(void) 1573 { 1574 s8_t i, j; 1575 u32_t age; 1576 1577 /* Find an empty entry. */ 1578 for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { 1579 if (ip6_addr_isany(&(destination_cache[i].destination_addr))) { 1580 return i; 1581 } 1582 } 1583 1584 /* Find oldest entry. */ 1585 age = 0; 1586 j = LWIP_ND6_NUM_DESTINATIONS - 1; 1587 for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { 1588 if (destination_cache[i].age > age) { 1589 j = i; 1590 } 1591 } 1592 1593 return j; 1594 } 1595 1596 /** 1597 * Clear the destination cache. 1598 * 1599 * This operation may be necessary for consistency in the light of changing 1600 * local addresses and/or use of the gateway hook. 1601 */ 1602 void 1603 nd6_clear_destination_cache(void) 1604 { 1605 int i; 1606 1607 for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { 1608 ip6_addr_set_any(&destination_cache[i].destination_addr); 1609 } 1610 } 1611 1612 /** 1613 * Determine whether an address matches an on-link prefix or the subnet of a 1614 * statically assigned address. 1615 * 1616 * @param ip6addr the IPv6 address to match 1617 * @return 1 if the address is on-link, 0 otherwise 1618 */ 1619 static s8_t 1620 nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif) 1621 { 1622 s8_t i; 1623 1624 /* Check to see if the address matches an on-link prefix. */ 1625 for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) { 1626 if ((prefix_list[i].netif == netif) && 1627 (prefix_list[i].invalidation_timer > 0) && 1628 ip6_addr_netcmp(ip6addr, &(prefix_list[i].prefix))) { 1629 return 1; 1630 } 1631 } 1632 /* Check to see if address prefix matches a manually configured (= static) 1633 * address. Static addresses have an implied /64 subnet assignment. Dynamic 1634 * addresses (from autoconfiguration) have no implied subnet assignment, and 1635 * are thus effectively /128 assignments. See RFC 5942 for more on this. */ 1636 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 1637 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && 1638 netif_ip6_addr_isstatic(netif, i) && 1639 ip6_addr_netcmp(ip6addr, netif_ip6_addr(netif, i))) { 1640 return 1; 1641 } 1642 } 1643 return 0; 1644 } 1645 1646 /** 1647 * Select a default router for a destination. 1648 * 1649 * This function is used both for routing and for finding a next-hop target for 1650 * a packet. In the former case, the given netif is NULL, and the returned 1651 * router entry must be for a netif suitable for sending packets (up, link up). 1652 * In the latter case, the given netif is not NULL and restricts router choice. 1653 * 1654 * @param ip6addr the destination address 1655 * @param netif the netif for the outgoing packet, if known 1656 * @return the default router entry index, or -1 if no suitable 1657 * router is found 1658 */ 1659 static s8_t 1660 nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif) 1661 { 1662 struct netif *router_netif; 1663 s8_t i, j, valid_router; 1664 static s8_t last_router; 1665 1666 LWIP_UNUSED_ARG(ip6addr); /* @todo match preferred routes!! (must implement ND6_OPTION_TYPE_ROUTE_INFO) */ 1667 1668 /* @todo: implement default router preference */ 1669 1670 /* Look for valid routers. A reachable router is preferred. */ 1671 valid_router = -1; 1672 for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { 1673 /* Is the router netif both set and apppropriate? */ 1674 if (default_router_list[i].neighbor_entry != NULL) { 1675 router_netif = default_router_list[i].neighbor_entry->netif; 1676 if ((router_netif != NULL) && (netif != NULL ? netif == router_netif : 1677 (netif_is_up(router_netif) && netif_is_link_up(router_netif)))) { 1678 /* Is the router valid, i.e., reachable or probably reachable as per 1679 * RFC 4861 Sec. 6.3.6? Note that we will never return a router that 1680 * has no neighbor cache entry, due to the netif association tests. */ 1681 if (default_router_list[i].neighbor_entry->state != ND6_INCOMPLETE) { 1682 /* Is the router known to be reachable? */ 1683 if (default_router_list[i].neighbor_entry->state == ND6_REACHABLE) { 1684 return i; /* valid and reachable - done! */ 1685 } else if (valid_router < 0) { 1686 valid_router = i; /* valid but not known to be reachable */ 1687 } 1688 } 1689 } 1690 } 1691 } 1692 if (valid_router >= 0) { 1693 return valid_router; 1694 } 1695 1696 /* Look for any router for which we have any information at all. */ 1697 /* last_router is used for round-robin selection of incomplete routers, as 1698 * recommended in RFC 4861 Sec. 6.3.6 point (2). Advance only when picking a 1699 * route, to select the same router as next-hop target in the common case. */ 1700 if ((netif == NULL) && (++last_router >= LWIP_ND6_NUM_ROUTERS)) { 1701 last_router = 0; 1702 } 1703 i = last_router; 1704 for (j = 0; j < LWIP_ND6_NUM_ROUTERS; j++) { 1705 if (default_router_list[i].neighbor_entry != NULL) { 1706 router_netif = default_router_list[i].neighbor_entry->netif; 1707 if ((router_netif != NULL) && (netif != NULL ? netif == router_netif : 1708 (netif_is_up(router_netif) && netif_is_link_up(router_netif)))) { 1709 return i; 1710 } 1711 } 1712 if (++i >= LWIP_ND6_NUM_ROUTERS) { 1713 i = 0; 1714 } 1715 } 1716 1717 /* no suitable router found. */ 1718 return -1; 1719 } 1720 1721 /** 1722 * Find a router-announced route to the given destination. This route may be 1723 * based on an on-link prefix or a default router. 1724 * 1725 * If a suitable route is found, the returned netif is guaranteed to be in a 1726 * suitable state (up, link up) to be used for packet transmission. 1727 * 1728 * @param ip6addr the destination IPv6 address 1729 * @return the netif to use for the destination, or NULL if none found 1730 */ 1731 struct netif * 1732 nd6_find_route(const ip6_addr_t *ip6addr) 1733 { 1734 struct netif *netif; 1735 s8_t i; 1736 1737 /* @todo decide if it makes sense to check the destination cache first */ 1738 1739 /* Check if there is a matching on-link prefix. There may be multiple 1740 * matches. Pick the first one that is associated with a suitable netif. */ 1741 for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) { 1742 netif = prefix_list[i].netif; 1743 if ((netif != NULL) && ip6_addr_netcmp(&prefix_list[i].prefix, ip6addr) && 1744 netif_is_up(netif) && netif_is_link_up(netif)) { 1745 return netif; 1746 } 1747 } 1748 1749 /* No on-link prefix match. Find a router that can forward the packet. */ 1750 i = nd6_select_router(ip6addr, NULL); 1751 if (i >= 0) { 1752 LWIP_ASSERT("selected router must have a neighbor entry", 1753 default_router_list[i].neighbor_entry != NULL); 1754 return default_router_list[i].neighbor_entry->netif; 1755 } 1756 1757 return NULL; 1758 } 1759 1760 /** 1761 * Find an entry for a default router. 1762 * 1763 * @param router_addr the IPv6 address of the router 1764 * @param netif the netif on which the router is found, if known 1765 * @return the index of the router entry, or -1 if not found 1766 */ 1767 static s8_t 1768 nd6_get_router(const ip6_addr_t *router_addr, struct netif *netif) 1769 { 1770 s8_t i; 1771 1772 IP6_ADDR_ZONECHECK_NETIF(router_addr, netif); 1773 1774 /* Look for router. */ 1775 for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { 1776 if ((default_router_list[i].neighbor_entry != NULL) && 1777 ((netif != NULL) ? netif == default_router_list[i].neighbor_entry->netif : 1) && 1778 ip6_addr_cmp(router_addr, &(default_router_list[i].neighbor_entry->next_hop_address))) { 1779 return i; 1780 } 1781 } 1782 1783 /* router not found. */ 1784 return -1; 1785 } 1786 1787 /** 1788 * Create a new entry for a default router. 1789 * 1790 * @param router_addr the IPv6 address of the router 1791 * @param netif the netif on which the router is connected, if known 1792 * @return the index on the router table, or -1 if could not be created 1793 */ 1794 static s8_t 1795 nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif) 1796 { 1797 s8_t router_index; 1798 s8_t free_router_index; 1799 s8_t neighbor_index; 1800 1801 IP6_ADDR_ZONECHECK_NETIF(router_addr, netif); 1802 1803 /* Do we have a neighbor entry for this router? */ 1804 neighbor_index = nd6_find_neighbor_cache_entry(router_addr); 1805 if (neighbor_index < 0) { 1806 /* Create a neighbor entry for this router. */ 1807 neighbor_index = nd6_new_neighbor_cache_entry(); 1808 if (neighbor_index < 0) { 1809 /* Could not create neighbor entry for this router. */ 1810 return -1; 1811 } 1812 ip6_addr_set(&(neighbor_cache[neighbor_index].next_hop_address), router_addr); 1813 neighbor_cache[neighbor_index].netif = netif; 1814 neighbor_cache[neighbor_index].q = NULL; 1815 neighbor_cache[neighbor_index].state = ND6_INCOMPLETE; 1816 neighbor_cache[neighbor_index].counter.probes_sent = 1; 1817 nd6_send_neighbor_cache_probe(&neighbor_cache[neighbor_index], ND6_SEND_FLAG_MULTICAST_DEST); 1818 } 1819 1820 /* Mark neighbor as router. */ 1821 neighbor_cache[neighbor_index].isrouter = 1; 1822 1823 /* Look for empty entry. */ 1824 free_router_index = LWIP_ND6_NUM_ROUTERS; 1825 for (router_index = LWIP_ND6_NUM_ROUTERS - 1; router_index >= 0; router_index--) { 1826 /* check if router already exists (this is a special case for 2 netifs on the same subnet 1827 - e.g. wifi and cable) */ 1828 if(default_router_list[router_index].neighbor_entry == &(neighbor_cache[neighbor_index])){ 1829 return router_index; 1830 } 1831 if (default_router_list[router_index].neighbor_entry == NULL) { 1832 /* remember lowest free index to create a new entry */ 1833 free_router_index = router_index; 1834 } 1835 } 1836 if (free_router_index < LWIP_ND6_NUM_ROUTERS) { 1837 default_router_list[free_router_index].neighbor_entry = &(neighbor_cache[neighbor_index]); 1838 return free_router_index; 1839 } 1840 1841 /* Could not create a router entry. */ 1842 1843 /* Mark neighbor entry as not-router. Entry might be useful as neighbor still. */ 1844 neighbor_cache[neighbor_index].isrouter = 0; 1845 1846 /* router not found. */ 1847 return -1; 1848 } 1849 1850 /** 1851 * Find the cached entry for an on-link prefix. 1852 * 1853 * @param prefix the IPv6 prefix that is on-link 1854 * @param netif the netif on which the prefix is on-link 1855 * @return the index on the prefix table, or -1 if not found 1856 */ 1857 static s8_t 1858 nd6_get_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif) 1859 { 1860 s8_t i; 1861 1862 /* Look for prefix in list. */ 1863 for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) { 1864 if ((ip6_addr_netcmp(&(prefix_list[i].prefix), prefix)) && 1865 (prefix_list[i].netif == netif)) { 1866 return i; 1867 } 1868 } 1869 1870 /* Entry not available. */ 1871 return -1; 1872 } 1873 1874 /** 1875 * Creates a new entry for an on-link prefix. 1876 * 1877 * @param prefix the IPv6 prefix that is on-link 1878 * @param netif the netif on which the prefix is on-link 1879 * @return the index on the prefix table, or -1 if not created 1880 */ 1881 static s8_t 1882 nd6_new_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif) 1883 { 1884 s8_t i; 1885 1886 /* Create new entry. */ 1887 for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) { 1888 if ((prefix_list[i].netif == NULL) || 1889 (prefix_list[i].invalidation_timer == 0)) { 1890 /* Found empty prefix entry. */ 1891 prefix_list[i].netif = netif; 1892 ip6_addr_set(&(prefix_list[i].prefix), prefix); 1893 return i; 1894 } 1895 } 1896 1897 /* Entry not available. */ 1898 return -1; 1899 } 1900 1901 /** 1902 * Determine the next hop for a destination. Will determine if the 1903 * destination is on-link, else a suitable on-link router is selected. 1904 * 1905 * The last entry index is cached for fast entry search. 1906 * 1907 * @param ip6addr the destination address 1908 * @param netif the netif on which the packet will be sent 1909 * @return the neighbor cache entry for the next hop, ERR_RTE if no 1910 * suitable next hop was found, ERR_MEM if no cache entry 1911 * could be created 1912 */ 1913 static s8_t 1914 nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif) 1915 { 1916 #ifdef LWIP_HOOK_ND6_GET_GW 1917 const ip6_addr_t *next_hop_addr; 1918 #endif /* LWIP_HOOK_ND6_GET_GW */ 1919 s8_t i; 1920 1921 IP6_ADDR_ZONECHECK_NETIF(ip6addr, netif); 1922 1923 #if LWIP_NETIF_HWADDRHINT 1924 if (netif->addr_hint != NULL) { 1925 /* per-pcb cached entry was given */ 1926 u8_t addr_hint = *(netif->addr_hint); 1927 if (addr_hint < LWIP_ND6_NUM_DESTINATIONS) { 1928 nd6_cached_destination_index = addr_hint; 1929 } 1930 } 1931 #endif /* LWIP_NETIF_HWADDRHINT */ 1932 1933 /* Look for ip6addr in destination cache. */ 1934 if (ip6_addr_cmp(ip6addr, &(destination_cache[nd6_cached_destination_index].destination_addr))) { 1935 /* the cached entry index is the right one! */ 1936 /* do nothing. */ 1937 ND6_STATS_INC(nd6.cachehit); 1938 } else { 1939 /* Search destination cache. */ 1940 i = nd6_find_destination_cache_entry(ip6addr); 1941 if (i >= 0) { 1942 /* found destination entry. make it our new cached index. */ 1943 nd6_cached_destination_index = i; 1944 } else { 1945 /* Not found. Create a new destination entry. */ 1946 i = nd6_new_destination_cache_entry(); 1947 if (i >= 0) { 1948 /* got new destination entry. make it our new cached index. */ 1949 nd6_cached_destination_index = i; 1950 } else { 1951 /* Could not create a destination cache entry. */ 1952 return ERR_MEM; 1953 } 1954 1955 /* Copy dest address to destination cache. */ 1956 ip6_addr_set(&(destination_cache[nd6_cached_destination_index].destination_addr), ip6addr); 1957 1958 /* Now find the next hop. is it a neighbor? */ 1959 if (ip6_addr_islinklocal(ip6addr) || 1960 nd6_is_prefix_in_netif(ip6addr, netif)) { 1961 /* Destination in local link. */ 1962 destination_cache[nd6_cached_destination_index].pmtu = netif->mtu; 1963 ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, destination_cache[nd6_cached_destination_index].destination_addr); 1964 #ifdef LWIP_HOOK_ND6_GET_GW 1965 } else if ((next_hop_addr = LWIP_HOOK_ND6_GET_GW(netif, ip6addr)) != NULL) { 1966 /* Next hop for destination provided by hook function. */ 1967 destination_cache[nd6_cached_destination_index].pmtu = netif->mtu; 1968 ip6_addr_set(&destination_cache[nd6_cached_destination_index].next_hop_addr, next_hop_addr); 1969 #endif /* LWIP_HOOK_ND6_GET_GW */ 1970 } else { 1971 /* We need to select a router. */ 1972 i = nd6_select_router(ip6addr, netif); 1973 if (i < 0) { 1974 /* No router found. */ 1975 ip6_addr_set_any(&(destination_cache[nd6_cached_destination_index].destination_addr)); 1976 return ERR_RTE; 1977 } 1978 destination_cache[nd6_cached_destination_index].pmtu = netif->mtu; /* Start with netif mtu, correct through ICMPv6 if necessary */ 1979 ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, default_router_list[i].neighbor_entry->next_hop_address); 1980 } 1981 } 1982 } 1983 1984 #if LWIP_NETIF_HWADDRHINT 1985 if (netif->addr_hint != NULL) { 1986 /* per-pcb cached entry was given */ 1987 *(netif->addr_hint) = nd6_cached_destination_index; 1988 } 1989 #endif /* LWIP_NETIF_HWADDRHINT */ 1990 1991 /* Look in neighbor cache for the next-hop address. */ 1992 if (ip6_addr_cmp(&(destination_cache[nd6_cached_destination_index].next_hop_addr), 1993 &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) { 1994 /* Cache hit. */ 1995 /* Do nothing. */ 1996 ND6_STATS_INC(nd6.cachehit); 1997 } else { 1998 i = nd6_find_neighbor_cache_entry(&(destination_cache[nd6_cached_destination_index].next_hop_addr)); 1999 if (i >= 0) { 2000 /* Found a matching record, make it new cached entry. */ 2001 nd6_cached_neighbor_index = i; 2002 } else { 2003 /* Neighbor not in cache. Make a new entry. */ 2004 i = nd6_new_neighbor_cache_entry(); 2005 if (i >= 0) { 2006 /* got new neighbor entry. make it our new cached index. */ 2007 nd6_cached_neighbor_index = i; 2008 } else { 2009 /* Could not create a neighbor cache entry. */ 2010 return ERR_MEM; 2011 } 2012 2013 /* Initialize fields. */ 2014 ip6_addr_copy(neighbor_cache[i].next_hop_address, 2015 destination_cache[nd6_cached_destination_index].next_hop_addr); 2016 neighbor_cache[i].isrouter = 0; 2017 neighbor_cache[i].netif = netif; 2018 neighbor_cache[i].state = ND6_INCOMPLETE; 2019 neighbor_cache[i].counter.probes_sent = 1; 2020 nd6_send_neighbor_cache_probe(&neighbor_cache[i], ND6_SEND_FLAG_MULTICAST_DEST); 2021 } 2022 } 2023 2024 /* Reset this destination's age. */ 2025 destination_cache[nd6_cached_destination_index].age = 0; 2026 2027 return nd6_cached_neighbor_index; 2028 } 2029 2030 /** 2031 * Queue a packet for a neighbor. 2032 * 2033 * @param neighbor_index the index in the neighbor cache table 2034 * @param q packet to be queued 2035 * @return ERR_OK if succeeded, ERR_MEM if out of memory 2036 */ 2037 static err_t 2038 nd6_queue_packet(s8_t neighbor_index, struct pbuf *q) 2039 { 2040 err_t result = ERR_MEM; 2041 struct pbuf *p; 2042 int copy_needed = 0; 2043 #if LWIP_ND6_QUEUEING 2044 struct nd6_q_entry *new_entry, *r; 2045 #endif /* LWIP_ND6_QUEUEING */ 2046 2047 if ((neighbor_index < 0) || (neighbor_index >= LWIP_ND6_NUM_NEIGHBORS)) { 2048 return ERR_ARG; 2049 } 2050 2051 /* IF q includes a pbuf that must be copied, we have to copy the whole chain 2052 * into a new PBUF_RAM. See the definition of PBUF_NEEDS_COPY for details. */ 2053 p = q; 2054 while (p) { 2055 if (PBUF_NEEDS_COPY(p)) { 2056 copy_needed = 1; 2057 break; 2058 } 2059 p = p->next; 2060 } 2061 if (copy_needed) { 2062 /* copy the whole packet into new pbufs */ 2063 p = pbuf_alloc(PBUF_LINK, q->tot_len, PBUF_RAM); 2064 while ((p == NULL) && (neighbor_cache[neighbor_index].q != NULL)) { 2065 /* Free oldest packet (as per RFC recommendation) */ 2066 #if LWIP_ND6_QUEUEING 2067 r = neighbor_cache[neighbor_index].q; 2068 neighbor_cache[neighbor_index].q = r->next; 2069 r->next = NULL; 2070 nd6_free_q(r); 2071 #else /* LWIP_ND6_QUEUEING */ 2072 pbuf_free(neighbor_cache[neighbor_index].q); 2073 neighbor_cache[neighbor_index].q = NULL; 2074 #endif /* LWIP_ND6_QUEUEING */ 2075 p = pbuf_alloc(PBUF_LINK, q->tot_len, PBUF_RAM); 2076 } 2077 if (p != NULL) { 2078 if (pbuf_copy(p, q) != ERR_OK) { 2079 pbuf_free(p); 2080 p = NULL; 2081 } 2082 } 2083 } else { 2084 /* referencing the old pbuf is enough */ 2085 p = q; 2086 pbuf_ref(p); 2087 } 2088 /* packet was copied/ref'd? */ 2089 if (p != NULL) { 2090 /* queue packet ... */ 2091 #if LWIP_ND6_QUEUEING 2092 /* allocate a new nd6 queue entry */ 2093 new_entry = (struct nd6_q_entry *)memp_malloc(MEMP_ND6_QUEUE); 2094 if ((new_entry == NULL) && (neighbor_cache[neighbor_index].q != NULL)) { 2095 /* Free oldest packet (as per RFC recommendation) */ 2096 r = neighbor_cache[neighbor_index].q; 2097 neighbor_cache[neighbor_index].q = r->next; 2098 r->next = NULL; 2099 nd6_free_q(r); 2100 new_entry = (struct nd6_q_entry *)memp_malloc(MEMP_ND6_QUEUE); 2101 } 2102 if (new_entry != NULL) { 2103 new_entry->next = NULL; 2104 new_entry->p = p; 2105 if (neighbor_cache[neighbor_index].q != NULL) { 2106 /* queue was already existent, append the new entry to the end */ 2107 r = neighbor_cache[neighbor_index].q; 2108 while (r->next != NULL) { 2109 r = r->next; 2110 } 2111 r->next = new_entry; 2112 } else { 2113 /* queue did not exist, first item in queue */ 2114 neighbor_cache[neighbor_index].q = new_entry; 2115 } 2116 LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: queued packet %p on neighbor entry %"S16_F"\n", (void *)p, (s16_t)neighbor_index)); 2117 result = ERR_OK; 2118 } else { 2119 /* the pool MEMP_ND6_QUEUE is empty */ 2120 pbuf_free(p); 2121 LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: could not queue a copy of packet %p (out of memory)\n", (void *)p)); 2122 /* { result == ERR_MEM } through initialization */ 2123 } 2124 #else /* LWIP_ND6_QUEUEING */ 2125 /* Queue a single packet. If an older packet is already queued, free it as per RFC. */ 2126 if (neighbor_cache[neighbor_index].q != NULL) { 2127 pbuf_free(neighbor_cache[neighbor_index].q); 2128 } 2129 neighbor_cache[neighbor_index].q = p; 2130 LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: queued packet %p on neighbor entry %"S16_F"\n", (void *)p, (s16_t)neighbor_index)); 2131 result = ERR_OK; 2132 #endif /* LWIP_ND6_QUEUEING */ 2133 } else { 2134 LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: could not queue a copy of packet %p (out of memory)\n", (void *)q)); 2135 /* { result == ERR_MEM } through initialization */ 2136 } 2137 2138 return result; 2139 } 2140 2141 #if LWIP_ND6_QUEUEING 2142 /** 2143 * Free a complete queue of nd6 q entries 2144 * 2145 * @param q a queue of nd6_q_entry to free 2146 */ 2147 static void 2148 nd6_free_q(struct nd6_q_entry *q) 2149 { 2150 struct nd6_q_entry *r; 2151 LWIP_ASSERT("q != NULL", q != NULL); 2152 LWIP_ASSERT("q->p != NULL", q->p != NULL); 2153 while (q) { 2154 r = q; 2155 q = q->next; 2156 LWIP_ASSERT("r->p != NULL", (r->p != NULL)); 2157 pbuf_free(r->p); 2158 memp_free(MEMP_ND6_QUEUE, r); 2159 } 2160 } 2161 #endif /* LWIP_ND6_QUEUEING */ 2162 2163 /** 2164 * Send queued packets for a neighbor 2165 * 2166 * @param i the neighbor to send packets to 2167 */ 2168 static void 2169 nd6_send_q(s8_t i) 2170 { 2171 struct ip6_hdr *ip6hdr; 2172 ip6_addr_t dest; 2173 #if LWIP_ND6_QUEUEING 2174 struct nd6_q_entry *q; 2175 #endif /* LWIP_ND6_QUEUEING */ 2176 2177 if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) { 2178 return; 2179 } 2180 2181 #if LWIP_ND6_QUEUEING 2182 while (neighbor_cache[i].q != NULL) { 2183 /* remember first in queue */ 2184 q = neighbor_cache[i].q; 2185 /* pop first item off the queue */ 2186 neighbor_cache[i].q = q->next; 2187 /* Get ipv6 header. */ 2188 ip6hdr = (struct ip6_hdr *)(q->p->payload); 2189 /* Create an aligned copy. */ 2190 ip6_addr_copy_from_packed(dest, ip6hdr->dest); 2191 /* Restore the zone, if applicable. */ 2192 ip6_addr_assign_zone(&dest, IP6_UNKNOWN, neighbor_cache[i].netif); 2193 /* send the queued IPv6 packet */ 2194 (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, q->p, &dest); 2195 /* free the queued IP packet */ 2196 pbuf_free(q->p); 2197 /* now queue entry can be freed */ 2198 memp_free(MEMP_ND6_QUEUE, q); 2199 } 2200 #else /* LWIP_ND6_QUEUEING */ 2201 if (neighbor_cache[i].q != NULL) { 2202 /* Get ipv6 header. */ 2203 ip6hdr = (struct ip6_hdr *)(neighbor_cache[i].q->payload); 2204 /* Create an aligned copy. */ 2205 ip6_addr_copy_from_packed(dest, ip6hdr->dest); 2206 /* Restore the zone, if applicable. */ 2207 ip6_addr_assign_zone(&dest, IP6_UNKNOWN, neighbor_cache[i].netif); 2208 /* send the queued IPv6 packet */ 2209 (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, neighbor_cache[i].q, &dest); 2210 /* free the queued IP packet */ 2211 pbuf_free(neighbor_cache[i].q); 2212 neighbor_cache[i].q = NULL; 2213 } 2214 #endif /* LWIP_ND6_QUEUEING */ 2215 } 2216 2217 /** 2218 * A packet is to be transmitted to a specific IPv6 destination on a specific 2219 * interface. Check if we can find the hardware address of the next hop to use 2220 * for the packet. If so, give the hardware address to the caller, which should 2221 * use it to send the packet right away. Otherwise, enqueue the packet for 2222 * later transmission while looking up the hardware address, if possible. 2223 * 2224 * As such, this function returns one of three different possible results: 2225 * 2226 * - ERR_OK with a non-NULL 'hwaddrp': the caller should send the packet now. 2227 * - ERR_OK with a NULL 'hwaddrp': the packet has been enqueued for later. 2228 * - not ERR_OK: something went wrong; forward the error upward in the stack. 2229 * 2230 * @param netif The lwIP network interface on which the IP packet will be sent. 2231 * @param q The pbuf(s) containing the IP packet to be sent. 2232 * @param ip6addr The destination IPv6 address of the packet. 2233 * @param hwaddrp On success, filled with a pointer to a HW address or NULL (meaning 2234 * the packet has been queued). 2235 * @return 2236 * - ERR_OK on success, ERR_RTE if no route was found for the packet, 2237 * or ERR_MEM if low memory conditions prohibit sending the packet at all. 2238 */ 2239 err_t 2240 nd6_get_next_hop_addr_or_queue(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr, const u8_t **hwaddrp) 2241 { 2242 s8_t i; 2243 2244 /* Get next hop record. */ 2245 i = nd6_get_next_hop_entry(ip6addr, netif); 2246 if (i < 0) { 2247 /* failed to get a next hop neighbor record. */ 2248 return i; 2249 } 2250 2251 /* Now that we have a destination record, send or queue the packet. */ 2252 if (neighbor_cache[i].state == ND6_STALE) { 2253 /* Switch to delay state. */ 2254 neighbor_cache[i].state = ND6_DELAY; 2255 neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL; 2256 } 2257 /* @todo should we send or queue if PROBE? send for now, to let unicast NS pass. */ 2258 if ((neighbor_cache[i].state == ND6_REACHABLE) || 2259 (neighbor_cache[i].state == ND6_DELAY) || 2260 (neighbor_cache[i].state == ND6_PROBE)) { 2261 2262 /* Tell the caller to send out the packet now. */ 2263 *hwaddrp = neighbor_cache[i].lladdr; 2264 return ERR_OK; 2265 } 2266 2267 /* We should queue packet on this interface. */ 2268 *hwaddrp = NULL; 2269 return nd6_queue_packet(i, q); 2270 } 2271 2272 2273 /** 2274 * Get the Path MTU for a destination. 2275 * 2276 * @param ip6addr the destination address 2277 * @param netif the netif on which the packet will be sent 2278 * @return the Path MTU, if known, or the netif default MTU 2279 */ 2280 u16_t 2281 nd6_get_destination_mtu(const ip6_addr_t *ip6addr, struct netif *netif) 2282 { 2283 s8_t i; 2284 2285 i = nd6_find_destination_cache_entry(ip6addr); 2286 if (i >= 0) { 2287 if (destination_cache[i].pmtu > 0) { 2288 return destination_cache[i].pmtu; 2289 } 2290 } 2291 2292 if (netif != NULL) { 2293 return netif->mtu; 2294 } 2295 2296 return 1280; /* Minimum MTU */ 2297 } 2298 2299 2300 #if LWIP_ND6_TCP_REACHABILITY_HINTS 2301 /** 2302 * Provide the Neighbor discovery process with a hint that a 2303 * destination is reachable. Called by tcp_receive when ACKs are 2304 * received or sent (as per RFC). This is useful to avoid sending 2305 * NS messages every 30 seconds. 2306 * 2307 * @param ip6addr the destination address which is know to be reachable 2308 * by an upper layer protocol (TCP) 2309 */ 2310 void 2311 nd6_reachability_hint(const ip6_addr_t *ip6addr) 2312 { 2313 s8_t i; 2314 2315 /* Find destination in cache. */ 2316 if (ip6_addr_cmp(ip6addr, &(destination_cache[nd6_cached_destination_index].destination_addr))) { 2317 i = nd6_cached_destination_index; 2318 ND6_STATS_INC(nd6.cachehit); 2319 } else { 2320 i = nd6_find_destination_cache_entry(ip6addr); 2321 } 2322 if (i < 0) { 2323 return; 2324 } 2325 2326 /* Find next hop neighbor in cache. */ 2327 if (ip6_addr_cmp(&(destination_cache[i].next_hop_addr), &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) { 2328 i = nd6_cached_neighbor_index; 2329 ND6_STATS_INC(nd6.cachehit); 2330 } else { 2331 i = nd6_find_neighbor_cache_entry(&(destination_cache[i].next_hop_addr)); 2332 } 2333 if (i < 0) { 2334 return; 2335 } 2336 2337 /* For safety: don't set as reachable if we don't have a LL address yet. Misuse protection. */ 2338 if (neighbor_cache[i].state == ND6_INCOMPLETE || neighbor_cache[i].state == ND6_NO_ENTRY) { 2339 return; 2340 } 2341 2342 /* Set reachability state. */ 2343 neighbor_cache[i].state = ND6_REACHABLE; 2344 neighbor_cache[i].counter.reachable_time = reachable_time; 2345 } 2346 #endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ 2347 2348 /** 2349 * Remove all prefix, neighbor_cache and router entries of the specified netif. 2350 * 2351 * @param netif points to a network interface 2352 */ 2353 void 2354 nd6_cleanup_netif(struct netif *netif) 2355 { 2356 u8_t i; 2357 s8_t router_index; 2358 for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) { 2359 if (prefix_list[i].netif == netif) { 2360 prefix_list[i].netif = NULL; 2361 } 2362 } 2363 for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { 2364 if (neighbor_cache[i].netif == netif) { 2365 for (router_index = 0; router_index < LWIP_ND6_NUM_ROUTERS; router_index++) { 2366 if (default_router_list[router_index].neighbor_entry == &neighbor_cache[i]) { 2367 default_router_list[router_index].neighbor_entry = NULL; 2368 default_router_list[router_index].flags = 0; 2369 } 2370 } 2371 neighbor_cache[i].isrouter = 0; 2372 nd6_free_neighbor_cache_entry(i); 2373 } 2374 } 2375 /* Clear the destination cache, since many entries may now have become 2376 * invalid for one of several reasons. As destination cache entries have no 2377 * netif association, use a sledgehammer approach (this can be improved). */ 2378 nd6_clear_destination_cache(); 2379 } 2380 2381 #if LWIP_IPV6_MLD 2382 /** 2383 * The state of a local IPv6 address entry is about to change. If needed, join 2384 * or leave the solicited-node multicast group for the address. 2385 * 2386 * @param netif The netif that owns the address. 2387 * @param addr_idx The index of the address. 2388 * @param new_state The new (IP6_ADDR_) state for the address. 2389 */ 2390 void 2391 nd6_adjust_mld_membership(struct netif *netif, s8_t addr_idx, u8_t new_state) 2392 { 2393 u8_t old_state, old_member, new_member; 2394 2395 old_state = netif_ip6_addr_state(netif, addr_idx); 2396 2397 /* Determine whether we were, and should be, a member of the solicited-node 2398 * multicast group for this address. For tentative addresses, the group is 2399 * not joined until the address enters the TENTATIVE_1 (or VALID) state. */ 2400 old_member = (old_state != IP6_ADDR_INVALID && old_state != IP6_ADDR_DUPLICATED && old_state != IP6_ADDR_TENTATIVE); 2401 new_member = (new_state != IP6_ADDR_INVALID && new_state != IP6_ADDR_DUPLICATED && new_state != IP6_ADDR_TENTATIVE); 2402 2403 if (old_member != new_member) { 2404 ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(netif, addr_idx)->addr[3]); 2405 ip6_addr_assign_zone(&multicast_address, IP6_MULTICAST, netif); 2406 2407 if (new_member) { 2408 mld6_joingroup_netif(netif, &multicast_address); 2409 } else { 2410 mld6_leavegroup_netif(netif, &multicast_address); 2411 } 2412 } 2413 } 2414 #endif /* LWIP_IPV6_MLD */ 2415 2416 #endif /* LWIP_IPV6 */ 2417