2013-07-03 17:32:26 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2013, Swedish Institute of Computer Science.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. Neither the name of the Institute nor the names of its contributors
|
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2015-02-15 18:02:07 +00:00
|
|
|
/**
|
2017-09-29 20:18:48 +00:00
|
|
|
* \addtogroup uip
|
2015-02-15 18:02:07 +00:00
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
2013-07-03 17:32:26 +00:00
|
|
|
/**
|
|
|
|
* \file
|
2015-02-15 18:02:07 +00:00
|
|
|
* IPv6 Neighbor cache (link-layer/IPv6 address mapping)
|
2013-07-03 17:32:26 +00:00
|
|
|
* \author Mathilde Durvy <mdurvy@cisco.com>
|
|
|
|
* \author Julien Abeille <jabeille@cisco.com>
|
|
|
|
* \author Simon Duquennoy <simonduq@sics.se>
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include "lib/list.h"
|
2015-11-29 20:31:59 +00:00
|
|
|
#include "net/link-stats.h"
|
2013-12-12 22:58:52 +00:00
|
|
|
#include "net/linkaddr.h"
|
2013-07-03 17:32:26 +00:00
|
|
|
#include "net/packetbuf.h"
|
2017-12-10 15:19:27 +00:00
|
|
|
#include "net/ipv6/uip-ds6.h"
|
2013-11-22 08:17:54 +00:00
|
|
|
#include "net/ipv6/uip-ds6-nbr.h"
|
2017-12-10 15:19:27 +00:00
|
|
|
#include "net/ipv6/uip-nd6.h"
|
2017-12-10 15:34:16 +00:00
|
|
|
#include "net/routing/routing.h"
|
2013-07-03 17:32:26 +00:00
|
|
|
|
2017-06-20 15:23:49 +00:00
|
|
|
/* Log configuration */
|
|
|
|
#include "sys/log.h"
|
2017-06-23 19:12:36 +00:00
|
|
|
#define LOG_MODULE "IPv6 Nbr"
|
2017-07-15 13:19:09 +00:00
|
|
|
#define LOG_LEVEL LOG_LEVEL_IPV6
|
2013-07-03 17:32:26 +00:00
|
|
|
|
2013-07-29 16:49:21 +00:00
|
|
|
NBR_TABLE_GLOBAL(uip_ds6_nbr_t, ds6_neighbors);
|
2013-07-03 17:32:26 +00:00
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
void
|
|
|
|
uip_ds6_neighbors_init(void)
|
|
|
|
{
|
2015-11-29 20:31:59 +00:00
|
|
|
link_stats_init();
|
2013-07-29 16:49:21 +00:00
|
|
|
nbr_table_register(ds6_neighbors, (nbr_table_callback *)uip_ds6_nbr_rm);
|
2013-07-03 17:32:26 +00:00
|
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
uip_ds6_nbr_t *
|
2013-11-16 13:42:57 +00:00
|
|
|
uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr,
|
2015-09-20 19:02:30 +00:00
|
|
|
uint8_t isrouter, uint8_t state, nbr_table_reason_t reason,
|
|
|
|
void *data)
|
2013-07-03 17:32:26 +00:00
|
|
|
{
|
2015-09-20 19:02:30 +00:00
|
|
|
uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr
|
2016-03-26 19:12:52 +00:00
|
|
|
, reason, data);
|
2013-07-03 17:32:26 +00:00
|
|
|
if(nbr) {
|
|
|
|
uip_ipaddr_copy(&nbr->ipaddr, ipaddr);
|
2017-01-16 12:44:15 +00:00
|
|
|
#if UIP_ND6_SEND_RA || !UIP_CONF_ROUTER
|
2013-07-03 17:32:26 +00:00
|
|
|
nbr->isrouter = isrouter;
|
2017-01-16 12:44:15 +00:00
|
|
|
#endif /* UIP_ND6_SEND_RA || !UIP_CONF_ROUTER */
|
2013-07-03 17:32:26 +00:00
|
|
|
nbr->state = state;
|
2015-11-20 18:07:20 +00:00
|
|
|
#if UIP_CONF_IPV6_QUEUE_PKT
|
2013-07-03 17:32:26 +00:00
|
|
|
uip_packetqueue_new(&nbr->packethandle);
|
2015-11-20 18:07:20 +00:00
|
|
|
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
|
2017-01-16 12:44:15 +00:00
|
|
|
#if UIP_ND6_SEND_NS
|
2016-06-12 15:55:48 +00:00
|
|
|
if(nbr->state == NBR_REACHABLE) {
|
|
|
|
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
|
|
|
|
} else {
|
|
|
|
/* We set the timer in expired state */
|
|
|
|
stimer_set(&nbr->reachable, 0);
|
|
|
|
}
|
2013-07-03 17:32:26 +00:00
|
|
|
stimer_set(&nbr->sendns, 0);
|
|
|
|
nbr->nscount = 0;
|
2017-01-16 12:44:15 +00:00
|
|
|
#endif /* UIP_ND6_SEND_NS */
|
2017-06-20 15:23:49 +00:00
|
|
|
LOG_INFO("Adding neighbor with ip addr ");
|
|
|
|
LOG_INFO_6ADDR(ipaddr);
|
2017-06-23 07:21:31 +00:00
|
|
|
LOG_INFO_(" link addr ");
|
2017-06-20 15:23:49 +00:00
|
|
|
LOG_INFO_LLADDR((linkaddr_t*)lladdr);
|
2017-06-23 07:21:31 +00:00
|
|
|
LOG_INFO_(" state %u\n", state);
|
2017-12-10 15:34:16 +00:00
|
|
|
NETSTACK_ROUTING.neighbor_state_changed(nbr);
|
2013-07-03 17:32:26 +00:00
|
|
|
return nbr;
|
|
|
|
} else {
|
2017-06-20 15:23:49 +00:00
|
|
|
LOG_INFO("Add drop ip addr ");
|
|
|
|
LOG_INFO_6ADDR(ipaddr);
|
2017-06-23 07:21:31 +00:00
|
|
|
LOG_INFO_(" link addr (%p) ", lladdr);
|
2017-06-20 15:23:49 +00:00
|
|
|
LOG_INFO_LLADDR((linkaddr_t*)lladdr);
|
2017-06-23 07:21:31 +00:00
|
|
|
LOG_INFO_(" state %u\n", state);
|
2013-07-03 17:32:26 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
2015-08-20 14:56:50 +00:00
|
|
|
int
|
2013-07-03 17:32:26 +00:00
|
|
|
uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr)
|
|
|
|
{
|
|
|
|
if(nbr != NULL) {
|
|
|
|
#if UIP_CONF_IPV6_QUEUE_PKT
|
|
|
|
uip_packetqueue_free(&nbr->packethandle);
|
|
|
|
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
|
2017-12-10 15:34:16 +00:00
|
|
|
NETSTACK_ROUTING.neighbor_state_changed(nbr);
|
2015-08-20 14:56:50 +00:00
|
|
|
return nbr_table_remove(ds6_neighbors, nbr);
|
2013-07-03 17:32:26 +00:00
|
|
|
}
|
2015-08-20 14:56:50 +00:00
|
|
|
return 0;
|
2013-07-03 17:32:26 +00:00
|
|
|
}
|
|
|
|
|
2018-03-23 13:51:27 +00:00
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
int
|
|
|
|
uip_ds6_nbr_update_ll(uip_ds6_nbr_t **nbr_pp, const uip_lladdr_t *new_ll_addr)
|
|
|
|
{
|
|
|
|
uip_ds6_nbr_t nbr_backup;
|
|
|
|
|
|
|
|
if(nbr_pp == NULL || new_ll_addr == NULL) {
|
|
|
|
LOG_ERR("%s: invalid argument\n", __func__);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* make sure new_ll_addr is not used in some other nbr */
|
|
|
|
if(uip_ds6_nbr_ll_lookup(new_ll_addr) != NULL) {
|
|
|
|
LOG_ERR("%s: new_ll_addr, ", __func__);
|
|
|
|
LOG_ERR_LLADDR((const linkaddr_t *)new_ll_addr);
|
|
|
|
LOG_ERR_(", is already used in another nbr\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(&nbr_backup, *nbr_pp, sizeof(uip_ds6_nbr_t));
|
|
|
|
if(uip_ds6_nbr_rm(*nbr_pp) == 0) {
|
|
|
|
LOG_ERR("%s: input nbr cannot be removed\n", __func__);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((*nbr_pp = uip_ds6_nbr_add(&nbr_backup.ipaddr, new_ll_addr,
|
|
|
|
nbr_backup.isrouter, nbr_backup.state,
|
|
|
|
NBR_TABLE_REASON_IPV6_ND, NULL)) == NULL) {
|
|
|
|
LOG_ERR("%s: cannot allocate a new nbr for new_ll_addr\n", __func__);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
memcpy(*nbr_pp, &nbr_backup, sizeof(uip_ds6_nbr_t));
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2013-07-03 17:32:26 +00:00
|
|
|
/*---------------------------------------------------------------------------*/
|
2013-11-16 13:42:57 +00:00
|
|
|
const uip_ipaddr_t *
|
|
|
|
uip_ds6_nbr_get_ipaddr(const uip_ds6_nbr_t *nbr)
|
2013-07-03 17:32:26 +00:00
|
|
|
{
|
|
|
|
return (nbr != NULL) ? &nbr->ipaddr : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
2013-11-16 13:42:57 +00:00
|
|
|
const uip_lladdr_t *
|
|
|
|
uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr)
|
2013-07-03 17:32:26 +00:00
|
|
|
{
|
2013-11-16 13:42:57 +00:00
|
|
|
return (const uip_lladdr_t *)nbr_table_get_lladdr(ds6_neighbors, nbr);
|
2013-07-03 17:32:26 +00:00
|
|
|
}
|
2013-08-11 21:55:08 +00:00
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
int
|
|
|
|
uip_ds6_nbr_num(void)
|
|
|
|
{
|
|
|
|
uip_ds6_nbr_t *nbr;
|
|
|
|
int num;
|
2013-07-03 17:32:26 +00:00
|
|
|
|
2013-08-11 21:55:08 +00:00
|
|
|
num = 0;
|
|
|
|
for(nbr = nbr_table_head(ds6_neighbors);
|
|
|
|
nbr != NULL;
|
|
|
|
nbr = nbr_table_next(ds6_neighbors, nbr)) {
|
|
|
|
num++;
|
|
|
|
}
|
|
|
|
return num;
|
|
|
|
}
|
2013-07-03 17:32:26 +00:00
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
uip_ds6_nbr_t *
|
2017-07-15 10:35:59 +00:00
|
|
|
uip_ds6_nbr_head(void)
|
|
|
|
{
|
|
|
|
return nbr_table_head(ds6_neighbors);
|
|
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
uip_ds6_nbr_t *
|
|
|
|
uip_ds6_nbr_next(uip_ds6_nbr_t *nbr)
|
|
|
|
{
|
|
|
|
return nbr_table_next(ds6_neighbors, nbr);
|
|
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
uip_ds6_nbr_t *
|
2013-11-16 13:42:57 +00:00
|
|
|
uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr)
|
2013-07-03 17:32:26 +00:00
|
|
|
{
|
|
|
|
uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors);
|
2013-08-11 22:19:12 +00:00
|
|
|
if(ipaddr != NULL) {
|
|
|
|
while(nbr != NULL) {
|
|
|
|
if(uip_ipaddr_cmp(&nbr->ipaddr, ipaddr)) {
|
|
|
|
return nbr;
|
|
|
|
}
|
|
|
|
nbr = nbr_table_next(ds6_neighbors, nbr);
|
2013-07-03 17:32:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
uip_ds6_nbr_t *
|
2013-11-16 13:42:57 +00:00
|
|
|
uip_ds6_nbr_ll_lookup(const uip_lladdr_t *lladdr)
|
2013-07-03 17:32:26 +00:00
|
|
|
{
|
2013-12-12 22:58:52 +00:00
|
|
|
return nbr_table_get_from_lladdr(ds6_neighbors, (linkaddr_t*)lladdr);
|
2013-07-03 17:32:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
uip_ipaddr_t *
|
2013-11-16 13:42:57 +00:00
|
|
|
uip_ds6_nbr_ipaddr_from_lladdr(const uip_lladdr_t *lladdr)
|
2013-07-03 17:32:26 +00:00
|
|
|
{
|
|
|
|
uip_ds6_nbr_t *nbr = uip_ds6_nbr_ll_lookup(lladdr);
|
|
|
|
return nbr ? &nbr->ipaddr : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
2013-11-16 13:42:57 +00:00
|
|
|
const uip_lladdr_t *
|
|
|
|
uip_ds6_nbr_lladdr_from_ipaddr(const uip_ipaddr_t *ipaddr)
|
2013-07-03 17:32:26 +00:00
|
|
|
{
|
|
|
|
uip_ds6_nbr_t *nbr = uip_ds6_nbr_lookup(ipaddr);
|
|
|
|
return nbr ? uip_ds6_nbr_get_ll(nbr) : NULL;
|
|
|
|
}
|
2013-07-29 19:50:33 +00:00
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
void
|
2017-06-24 09:46:37 +00:00
|
|
|
uip_ds6_link_callback(int status, int numtx)
|
2013-07-29 19:50:33 +00:00
|
|
|
{
|
2017-06-24 09:46:37 +00:00
|
|
|
#if UIP_DS6_LL_NUD
|
2013-12-12 22:58:52 +00:00
|
|
|
const linkaddr_t *dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
|
|
|
|
if(linkaddr_cmp(dest, &linkaddr_null)) {
|
2013-07-29 19:50:33 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-10-27 10:57:49 +00:00
|
|
|
/* From RFC4861, page 72, last paragraph of section 7.3.3:
|
|
|
|
*
|
2015-10-30 10:41:59 +00:00
|
|
|
* "In some cases, link-specific information may indicate that a path to
|
|
|
|
* a neighbor has failed (e.g., the resetting of a virtual circuit). In
|
|
|
|
* such cases, link-specific information may be used to purge Neighbor
|
|
|
|
* Cache entries before the Neighbor Unreachability Detection would do
|
|
|
|
* so. However, link-specific information MUST NOT be used to confirm
|
|
|
|
* the reachability of a neighbor; such information does not provide
|
|
|
|
* end-to-end confirmation between neighboring IP layers."
|
2014-10-27 10:57:49 +00:00
|
|
|
*
|
|
|
|
* However, we assume that receiving a link layer ack ensures the delivery
|
2015-10-30 10:41:59 +00:00
|
|
|
* of the transmitted packed to the IP stack of the neighbour. This is a
|
|
|
|
* fair assumption and allows battery powered nodes save some battery by
|
|
|
|
* not re-testing the state of a neighbour periodically if it
|
2014-10-27 10:57:49 +00:00
|
|
|
* acknowledges link packets. */
|
2013-07-29 19:50:33 +00:00
|
|
|
if(status == MAC_TX_OK) {
|
|
|
|
uip_ds6_nbr_t *nbr;
|
|
|
|
nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest);
|
2014-10-27 10:57:49 +00:00
|
|
|
if(nbr != NULL && nbr->state != NBR_INCOMPLETE) {
|
2013-09-10 00:48:11 +00:00
|
|
|
nbr->state = NBR_REACHABLE;
|
2013-07-29 19:50:33 +00:00
|
|
|
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
|
2017-06-20 15:23:49 +00:00
|
|
|
LOG_INFO("received a link layer ACK : ");
|
|
|
|
LOG_INFO_LLADDR((uip_lladdr_t *)dest);
|
2017-06-23 07:21:31 +00:00
|
|
|
LOG_INFO_(" is reachable.\n");
|
2013-07-29 19:50:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* UIP_DS6_LL_NUD */
|
|
|
|
}
|
2017-01-16 12:44:15 +00:00
|
|
|
#if UIP_ND6_SEND_NS
|
2013-07-03 17:32:26 +00:00
|
|
|
/*---------------------------------------------------------------------------*/
|
2015-10-30 07:55:11 +00:00
|
|
|
/** Periodic processing on neighbors */
|
2013-07-03 17:32:26 +00:00
|
|
|
void
|
2013-08-11 21:46:26 +00:00
|
|
|
uip_ds6_neighbor_periodic(void)
|
2013-07-03 17:32:26 +00:00
|
|
|
{
|
|
|
|
uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors);
|
|
|
|
while(nbr != NULL) {
|
|
|
|
switch(nbr->state) {
|
|
|
|
case NBR_REACHABLE:
|
|
|
|
if(stimer_expired(&nbr->reachable)) {
|
2017-12-10 19:51:26 +00:00
|
|
|
#if UIP_CONF_ROUTER
|
2015-11-20 18:07:20 +00:00
|
|
|
/* when a neighbor leave its REACHABLE state and is a default router,
|
2014-08-07 10:58:27 +00:00
|
|
|
instead of going to STALE state it enters DELAY state in order to
|
|
|
|
force a NUD on it. Otherwise, if there is no upward traffic, the
|
|
|
|
node never knows if the default router is still reachable. This
|
|
|
|
mimics the 6LoWPAN-ND behavior.
|
|
|
|
*/
|
|
|
|
if(uip_ds6_defrt_lookup(&nbr->ipaddr) != NULL) {
|
2017-06-20 15:23:49 +00:00
|
|
|
LOG_INFO("REACHABLE: defrt moving to DELAY (");
|
|
|
|
LOG_INFO_6ADDR(&nbr->ipaddr);
|
2017-06-23 07:21:31 +00:00
|
|
|
LOG_INFO_(")\n");
|
2014-08-07 10:58:27 +00:00
|
|
|
nbr->state = NBR_DELAY;
|
|
|
|
stimer_set(&nbr->reachable, UIP_ND6_DELAY_FIRST_PROBE_TIME);
|
|
|
|
nbr->nscount = 0;
|
|
|
|
} else {
|
2017-06-20 15:23:49 +00:00
|
|
|
LOG_INFO("REACHABLE: moving to STALE (");
|
|
|
|
LOG_INFO_6ADDR(&nbr->ipaddr);
|
2017-06-23 07:21:31 +00:00
|
|
|
LOG_INFO_(")\n");
|
2014-08-07 10:58:27 +00:00
|
|
|
nbr->state = NBR_STALE;
|
|
|
|
}
|
2017-12-10 19:51:26 +00:00
|
|
|
#else /* UIP_CONF_ROUTER */
|
2017-06-20 15:23:49 +00:00
|
|
|
LOG_INFO("REACHABLE: moving to STALE (");
|
|
|
|
LOG_INFO_6ADDR(&nbr->ipaddr);
|
2017-06-23 07:21:31 +00:00
|
|
|
LOG_INFO_(")\n");
|
2013-07-03 17:32:26 +00:00
|
|
|
nbr->state = NBR_STALE;
|
2017-12-10 19:51:26 +00:00
|
|
|
#endif /* UIP_CONF_ROUTER */
|
2013-07-03 17:32:26 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NBR_INCOMPLETE:
|
|
|
|
if(nbr->nscount >= UIP_ND6_MAX_MULTICAST_SOLICIT) {
|
|
|
|
uip_ds6_nbr_rm(nbr);
|
|
|
|
} else if(stimer_expired(&nbr->sendns) && (uip_len == 0)) {
|
|
|
|
nbr->nscount++;
|
2017-06-20 15:23:49 +00:00
|
|
|
LOG_INFO("NBR_INCOMPLETE: NS %u\n", nbr->nscount);
|
2013-07-03 17:32:26 +00:00
|
|
|
uip_nd6_ns_output(NULL, NULL, &nbr->ipaddr);
|
|
|
|
stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NBR_DELAY:
|
|
|
|
if(stimer_expired(&nbr->reachable)) {
|
|
|
|
nbr->state = NBR_PROBE;
|
|
|
|
nbr->nscount = 0;
|
2017-06-20 15:23:49 +00:00
|
|
|
LOG_INFO("DELAY: moving to PROBE\n");
|
2013-07-03 17:32:26 +00:00
|
|
|
stimer_set(&nbr->sendns, 0);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NBR_PROBE:
|
|
|
|
if(nbr->nscount >= UIP_ND6_MAX_UNICAST_SOLICIT) {
|
|
|
|
uip_ds6_defrt_t *locdefrt;
|
2017-06-20 15:23:49 +00:00
|
|
|
LOG_INFO("PROBE END\n");
|
2013-07-03 17:32:26 +00:00
|
|
|
if((locdefrt = uip_ds6_defrt_lookup(&nbr->ipaddr)) != NULL) {
|
|
|
|
if (!locdefrt->isinfinite) {
|
|
|
|
uip_ds6_defrt_rm(locdefrt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
uip_ds6_nbr_rm(nbr);
|
|
|
|
} else if(stimer_expired(&nbr->sendns) && (uip_len == 0)) {
|
|
|
|
nbr->nscount++;
|
2017-06-20 15:23:49 +00:00
|
|
|
LOG_INFO("PROBE: NS %u\n", nbr->nscount);
|
2013-07-03 17:32:26 +00:00
|
|
|
uip_nd6_ns_output(NULL, &nbr->ipaddr, &nbr->ipaddr);
|
|
|
|
stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
nbr = nbr_table_next(ds6_neighbors, nbr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
2015-11-26 00:07:58 +00:00
|
|
|
void
|
|
|
|
uip_ds6_nbr_refresh_reachable_state(const uip_ipaddr_t *ipaddr)
|
|
|
|
{
|
|
|
|
uip_ds6_nbr_t *nbr;
|
|
|
|
nbr = uip_ds6_nbr_lookup(ipaddr);
|
|
|
|
if(nbr != NULL) {
|
|
|
|
nbr->state = NBR_REACHABLE;
|
|
|
|
nbr->nscount = 0;
|
|
|
|
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
2013-07-03 17:32:26 +00:00
|
|
|
uip_ds6_nbr_t *
|
|
|
|
uip_ds6_get_least_lifetime_neighbor(void)
|
|
|
|
{
|
|
|
|
uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors);
|
|
|
|
uip_ds6_nbr_t *nbr_expiring = NULL;
|
|
|
|
while(nbr != NULL) {
|
|
|
|
if(nbr_expiring != NULL) {
|
|
|
|
clock_time_t curr = stimer_remaining(&nbr->reachable);
|
|
|
|
if(curr < stimer_remaining(&nbr->reachable)) {
|
|
|
|
nbr_expiring = nbr;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
nbr_expiring = nbr;
|
|
|
|
}
|
|
|
|
nbr = nbr_table_next(ds6_neighbors, nbr);
|
|
|
|
}
|
|
|
|
return nbr_expiring;
|
|
|
|
}
|
2017-01-16 12:44:15 +00:00
|
|
|
#endif /* UIP_ND6_SEND_NS */
|
2013-11-16 13:42:57 +00:00
|
|
|
/*---------------------------------------------------------------------------*/
|
2014-05-30 09:01:20 +00:00
|
|
|
/** @} */
|