Make DS6 neighbors use neighbor-table, and move all DS6 neighbor management from uip-ds6 to a new uip-ds6-neighbor module.
This commit is contained in:
parent
5a1d8d8006
commit
ec609b49eb
|
@ -18,6 +18,7 @@ uaodv-rt.c \
|
||||||
uaodv.c \
|
uaodv.c \
|
||||||
uip-debug.c \
|
uip-debug.c \
|
||||||
uip-ds6-route.c \
|
uip-ds6-route.c \
|
||||||
|
uip-ds6-neighbor.c \
|
||||||
uip-ds6.c \
|
uip-ds6.c \
|
||||||
uip-fw-drv.c \
|
uip-fw-drv.c \
|
||||||
uip-fw.c \
|
uip-fw.c \
|
||||||
|
|
|
@ -142,21 +142,6 @@ rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ANNOTATE("#L %u 0\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
|
ANNOTATE("#L %u 0\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
|
||||||
|
|
||||||
#if 0
|
|
||||||
uip_ds6_route_t *locroute;
|
|
||||||
|
|
||||||
for(locroute = uip_ds6_routing_table;
|
|
||||||
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
|
|
||||||
locroute++) {
|
|
||||||
if(locroute->isused
|
|
||||||
&& uip_ipaddr_cmp(&locroute->nexthop, nexthop)
|
|
||||||
&& locroute->state.dag == dag) {
|
|
||||||
locroute->isused = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ANNOTATE("#L %u 0\n",nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
|
|
||||||
#endif /* 0 */
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_route_t *
|
uip_ds6_route_t *
|
||||||
|
@ -242,18 +227,16 @@ rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr)
|
||||||
rpl_instance_t *instance;
|
rpl_instance_t *instance;
|
||||||
rpl_instance_t *end;
|
rpl_instance_t *end;
|
||||||
|
|
||||||
if(!nbr->isused) {
|
PRINTF("RPL: Removing neighbor ");
|
||||||
PRINTF("RPL: Removing neighbor ");
|
PRINT6ADDR(&nbr->ipaddr);
|
||||||
PRINT6ADDR(&nbr->ipaddr);
|
PRINTF("\n");
|
||||||
PRINTF("\n");
|
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
|
||||||
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
|
if(instance->used == 1 ) {
|
||||||
if(instance->used == 1 ) {
|
p = rpl_find_parent_any_dag(instance, &nbr->ipaddr);
|
||||||
p = rpl_find_parent_any_dag(instance, &nbr->ipaddr);
|
if(p != NULL) {
|
||||||
if(p != NULL) {
|
p->rank = INFINITE_RANK;
|
||||||
p->rank = INFINITE_RANK;
|
/* Trigger DAG rank recalculation. */
|
||||||
/* Trigger DAG rank recalculation. */
|
p->updated = 1;
|
||||||
p->updated = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -567,6 +567,7 @@ tcpip_ipv6_output(void)
|
||||||
uip_ds6_route_t* locrt;
|
uip_ds6_route_t* locrt;
|
||||||
locrt = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);
|
locrt = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);
|
||||||
if(locrt == NULL) {
|
if(locrt == NULL) {
|
||||||
|
PRINTF("tcpip_ipv6_output: no route found, using default route\n");
|
||||||
if((nexthop = uip_ds6_defrt_choose()) == NULL) {
|
if((nexthop = uip_ds6_defrt_choose()) == NULL) {
|
||||||
#ifdef UIP_FALLBACK_INTERFACE
|
#ifdef UIP_FALLBACK_INTERFACE
|
||||||
PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n",
|
PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n",
|
||||||
|
@ -588,11 +589,14 @@ tcpip_ipv6_output(void)
|
||||||
} else {
|
} else {
|
||||||
nexthop = &locrt->nexthop;
|
nexthop = &locrt->nexthop;
|
||||||
}
|
}
|
||||||
#if TCPIP_CONF_ANNOTATE_TRANSMISSIONS
|
|
||||||
if(nexthop != NULL) {
|
if(nexthop != NULL) {
|
||||||
|
PRINTF("tcpip_ipv6_output: next hop ");
|
||||||
|
PRINT6ADDR(nexthop);
|
||||||
|
PRINTF("\n");
|
||||||
|
#if TCPIP_CONF_ANNOTATE_TRANSMISSIONS
|
||||||
printf("#L %u 1; red\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
|
printf("#L %u 1; red\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
|
||||||
}
|
|
||||||
#endif /* TCPIP_CONF_ANNOTATE_TRANSMISSIONS */
|
#endif /* TCPIP_CONF_ANNOTATE_TRANSMISSIONS */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* End of next hop determination */
|
/* End of next hop determination */
|
||||||
#if UIP_CONF_IPV6_RPL
|
#if UIP_CONF_IPV6_RPL
|
||||||
|
@ -655,7 +659,7 @@ tcpip_ipv6_output(void)
|
||||||
}
|
}
|
||||||
#endif /* UIP_ND6_SEND_NA */
|
#endif /* UIP_ND6_SEND_NA */
|
||||||
|
|
||||||
tcpip_output(&nbr->lladdr);
|
tcpip_output(uip_ds6_nbr_get_ll(nbr));
|
||||||
|
|
||||||
#if UIP_CONF_IPV6_QUEUE_PKT
|
#if UIP_CONF_IPV6_QUEUE_PKT
|
||||||
/*
|
/*
|
||||||
|
@ -668,7 +672,7 @@ tcpip_ipv6_output(void)
|
||||||
uip_len = uip_packetqueue_buflen(&nbr->packethandle);
|
uip_len = uip_packetqueue_buflen(&nbr->packethandle);
|
||||||
memcpy(UIP_IP_BUF, uip_packetqueue_buf(&nbr->packethandle), uip_len);
|
memcpy(UIP_IP_BUF, uip_packetqueue_buf(&nbr->packethandle), uip_len);
|
||||||
uip_packetqueue_free(&nbr->packethandle);
|
uip_packetqueue_free(&nbr->packethandle);
|
||||||
tcpip_output(&nbr->lladdr);
|
tcpip_output(uip_ds6_nbr_get_ll(nbr));
|
||||||
}
|
}
|
||||||
#endif /*UIP_CONF_IPV6_QUEUE_PKT*/
|
#endif /*UIP_CONF_IPV6_QUEUE_PKT*/
|
||||||
|
|
||||||
|
|
248
core/net/uip-ds6-neighbor.c
Normal file
248
core/net/uip-ds6-neighbor.c
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
* IPv6 Neighbor cache (link-layer/IPv6 address mapping)
|
||||||
|
* \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"
|
||||||
|
#include "net/rime/rimeaddr.h"
|
||||||
|
#include "net/packetbuf.h"
|
||||||
|
#include "net/uip-ds6-neighbor.h"
|
||||||
|
|
||||||
|
#define DEBUG DEBUG_NONE
|
||||||
|
#include "net/uip-debug.h"
|
||||||
|
|
||||||
|
#ifdef UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED
|
||||||
|
#define NEIGHBOR_STATE_CHANGED(n) UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED(n)
|
||||||
|
void NEIGHBOR_STATE_CHANGED(uip_ds6_nbr_t *n);
|
||||||
|
#else
|
||||||
|
#define NEIGHBOR_STATE_CHANGED(n)
|
||||||
|
#endif /* UIP_DS6_CONF_NEIGHBOR_STATE_CHANGED */
|
||||||
|
|
||||||
|
NEIGHBOR_TABLE_GLOBAL(uip_ds6_nbr_t, ds6_neighbors);
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_ds6_neighbors_init(void)
|
||||||
|
{
|
||||||
|
nbr_table_register(ds6_neighbors, (remove_callback_func *)uip_ds6_nbr_rm);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_ds6_nbr_t *
|
||||||
|
uip_ds6_nbr_add(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr,
|
||||||
|
uint8_t isrouter, uint8_t state)
|
||||||
|
{
|
||||||
|
uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (rimeaddr_t*)lladdr);
|
||||||
|
if(nbr) {
|
||||||
|
uip_ipaddr_copy(&nbr->ipaddr, ipaddr);
|
||||||
|
nbr->isrouter = isrouter;
|
||||||
|
nbr->state = state;
|
||||||
|
#if UIP_CONF_IPV6_QUEUE_PKT
|
||||||
|
uip_packetqueue_new(&nbr->packethandle);
|
||||||
|
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
|
||||||
|
/* timers are set separately, for now we put them in expired state */
|
||||||
|
stimer_set(&nbr->reachable, 0);
|
||||||
|
stimer_set(&nbr->sendns, 0);
|
||||||
|
nbr->nscount = 0;
|
||||||
|
PRINTF("Adding neighbor with ip addr ");
|
||||||
|
PRINT6ADDR(ipaddr);
|
||||||
|
PRINTF(" link addr ");
|
||||||
|
PRINTLLADDR(lladdr);
|
||||||
|
PRINTF(" state %u\n", state);
|
||||||
|
NEIGHBOR_STATE_CHANGED(nbr);
|
||||||
|
return nbr;
|
||||||
|
} else {
|
||||||
|
PRINTF("uip_ds6_nbr_add drop ip addr ");
|
||||||
|
PRINT6ADDR(ipaddr);
|
||||||
|
PRINTF(" link addr (%p) ", lladdr);
|
||||||
|
PRINTLLADDR(lladdr);
|
||||||
|
PRINTF(" state %u\n", state);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
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 */
|
||||||
|
NEIGHBOR_STATE_CHANGED(nbr);
|
||||||
|
nbr_table_remove(ds6_neighbors, nbr);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_ipaddr_t *
|
||||||
|
uip_ds6_nbr_get_ipaddr(uip_ds6_nbr_t *nbr)
|
||||||
|
{
|
||||||
|
return (nbr != NULL) ? &nbr->ipaddr : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_lladdr_t *
|
||||||
|
uip_ds6_nbr_get_ll(uip_ds6_nbr_t *nbr)
|
||||||
|
{
|
||||||
|
return (uip_lladdr_t *)nbr_table_get_lladdr(ds6_neighbors, nbr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_ds6_nbr_t *
|
||||||
|
uip_ds6_nbr_lookup(uip_ipaddr_t *ipaddr)
|
||||||
|
{
|
||||||
|
uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors);
|
||||||
|
while(nbr != NULL) {
|
||||||
|
if(uip_ipaddr_cmp(&nbr->ipaddr, ipaddr)) {
|
||||||
|
return nbr;
|
||||||
|
}
|
||||||
|
nbr = nbr_table_next(ds6_neighbors, nbr);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_ds6_nbr_t *
|
||||||
|
uip_ds6_nbr_ll_lookup(uip_lladdr_t *lladdr)
|
||||||
|
{
|
||||||
|
return nbr_table_get_from_lladdr(ds6_neighbors, (rimeaddr_t*)lladdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_ipaddr_t *
|
||||||
|
uip_ds6_nbr_ipaddr_from_lladdr(uip_lladdr_t *lladdr)
|
||||||
|
{
|
||||||
|
uip_ds6_nbr_t *nbr = uip_ds6_nbr_ll_lookup(lladdr);
|
||||||
|
return nbr ? &nbr->ipaddr : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_lladdr_t *
|
||||||
|
uip_ds6_nbr_lladdr_from_ipaddr(uip_ipaddr_t *ipaddr)
|
||||||
|
{
|
||||||
|
uip_ds6_nbr_t *nbr = uip_ds6_nbr_lookup(ipaddr);
|
||||||
|
return nbr ? uip_ds6_nbr_get_ll(nbr) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_ds6_neighbor_periodic()
|
||||||
|
{
|
||||||
|
/* Periodic processing on neighbors */
|
||||||
|
uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors);
|
||||||
|
while(nbr != NULL) {
|
||||||
|
switch(nbr->state) {
|
||||||
|
case NBR_REACHABLE:
|
||||||
|
if(stimer_expired(&nbr->reachable)) {
|
||||||
|
PRINTF("REACHABLE: moving to STALE (");
|
||||||
|
PRINT6ADDR(&nbr->ipaddr);
|
||||||
|
PRINTF(")\n");
|
||||||
|
nbr->state = NBR_STALE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#if UIP_ND6_SEND_NA
|
||||||
|
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++;
|
||||||
|
PRINTF("NBR_INCOMPLETE: NS %u\n", nbr->nscount);
|
||||||
|
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;
|
||||||
|
PRINTF("DELAY: moving to PROBE\n");
|
||||||
|
stimer_set(&nbr->sendns, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NBR_PROBE:
|
||||||
|
if(nbr->nscount >= UIP_ND6_MAX_UNICAST_SOLICIT) {
|
||||||
|
uip_ds6_defrt_t *locdefrt;
|
||||||
|
PRINTF("PROBE END\n");
|
||||||
|
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++;
|
||||||
|
PRINTF("PROBE: NS %u\n", nbr->nscount);
|
||||||
|
uip_nd6_ns_output(NULL, &nbr->ipaddr, &nbr->ipaddr);
|
||||||
|
stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif /* UIP_ND6_SEND_NA */
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nbr = nbr_table_next(ds6_neighbors, nbr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
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;
|
||||||
|
}
|
97
core/net/uip-ds6-neighbor.h
Normal file
97
core/net/uip-ds6-neighbor.h
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
* IPv6 Neighbor cache (link-layer/IPv6 address mapping)
|
||||||
|
* \author Mathilde Durvy <mdurvy@cisco.com>
|
||||||
|
* \author Julien Abeille <jabeille@cisco.com>
|
||||||
|
* \author Simon Duquennoy <simonduq@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UIP_DS6_NEIGHBOR_H__
|
||||||
|
#define __UIP_DS6_NEIGHBOR_H__
|
||||||
|
|
||||||
|
#include "net/uip-ds6.h"
|
||||||
|
#include "net/neighbor-table.h"
|
||||||
|
|
||||||
|
#if UIP_CONF_IPV6_QUEUE_PKT
|
||||||
|
#include "net/uip-packetqueue.h"
|
||||||
|
#endif /*UIP_CONF_QUEUE_PKT */
|
||||||
|
|
||||||
|
NEIGHBOR_TABLE_DECLARE(ds6_neighbors);
|
||||||
|
|
||||||
|
/** \brief An entry in the nbr cache */
|
||||||
|
typedef struct uip_ds6_nbr {
|
||||||
|
uip_ipaddr_t ipaddr;
|
||||||
|
struct stimer reachable;
|
||||||
|
struct stimer sendns;
|
||||||
|
uint8_t nscount;
|
||||||
|
uint8_t isrouter;
|
||||||
|
uint8_t state;
|
||||||
|
#if UIP_CONF_IPV6_QUEUE_PKT
|
||||||
|
struct uip_packetqueue_handle packethandle;
|
||||||
|
#define UIP_DS6_NBR_PACKET_LIFETIME CLOCK_SECOND * 4
|
||||||
|
#endif /*UIP_CONF_QUEUE_PKT */
|
||||||
|
} uip_ds6_nbr_t;
|
||||||
|
|
||||||
|
void uip_ds6_neighbors_init(void);
|
||||||
|
|
||||||
|
/** \brief Neighbor Cache basic routines */
|
||||||
|
uip_ds6_nbr_t *uip_ds6_nbr_add(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr,
|
||||||
|
uint8_t isrouter, uint8_t state);
|
||||||
|
void uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr);
|
||||||
|
uip_lladdr_t *uip_ds6_nbr_get_ll(uip_ds6_nbr_t *nbr);
|
||||||
|
uip_ipaddr_t *uip_ds6_nbr_get_ipaddr(uip_ds6_nbr_t *nbr);
|
||||||
|
uip_ds6_nbr_t *uip_ds6_nbr_lookup(uip_ipaddr_t *ipaddr);
|
||||||
|
uip_ds6_nbr_t *uip_ds6_nbr_ll_lookup(uip_lladdr_t *lladdr);
|
||||||
|
uip_ipaddr_t *uip_ds6_nbr_ipaddr_from_lladdr(uip_lladdr_t *lladdr);
|
||||||
|
uip_lladdr_t *uip_ds6_nbr_lladdr_from_ipaddr(uip_ipaddr_t *ipaddr);
|
||||||
|
void uip_ds6_neighbor_periodic();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief
|
||||||
|
* This searches inside the neighbor table for the neighbor that is about to
|
||||||
|
* expire the next.
|
||||||
|
*
|
||||||
|
* \return
|
||||||
|
* A reference to the neighbor about to expire the next or NULL if
|
||||||
|
* table is empty.
|
||||||
|
*/
|
||||||
|
uip_ds6_nbr_t *uip_ds6_get_least_lifetime_neighbor(void);
|
||||||
|
|
||||||
|
#endif /* __UIP_DS6_NEIGHBOR_H__ */
|
|
@ -53,13 +53,6 @@
|
||||||
#define DEBUG DEBUG_NONE
|
#define DEBUG DEBUG_NONE
|
||||||
#include "net/uip-debug.h"
|
#include "net/uip-debug.h"
|
||||||
|
|
||||||
#ifdef UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED
|
|
||||||
#define NEIGHBOR_STATE_CHANGED(n) UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED(n)
|
|
||||||
void NEIGHBOR_STATE_CHANGED(uip_ds6_nbr_t *n);
|
|
||||||
#else
|
|
||||||
#define NEIGHBOR_STATE_CHANGED(n)
|
|
||||||
#endif /* UIP_DS6_CONF_NEIGHBOR_STATE_CHANGED */
|
|
||||||
|
|
||||||
struct etimer uip_ds6_timer_periodic; /** \brief Timer for maintenance of data structures */
|
struct etimer uip_ds6_timer_periodic; /** \brief Timer for maintenance of data structures */
|
||||||
|
|
||||||
#if UIP_CONF_ROUTER
|
#if UIP_CONF_ROUTER
|
||||||
|
@ -76,10 +69,7 @@ static uint8_t rscount; /** \brief numbe
|
||||||
/** \name "DS6" Data structures */
|
/** \name "DS6" Data structures */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
uip_ds6_netif_t uip_ds6_if; /** \brief The single interface */
|
uip_ds6_netif_t uip_ds6_if; /** \brief The single interface */
|
||||||
uip_ds6_nbr_t uip_ds6_nbr_cache[UIP_DS6_NBR_NB]; /** \brief Neighor cache */
|
|
||||||
//uip_ds6_defrt_t uip_ds6_defrt_list[UIP_DS6_DEFRT_NB]; /** \brief Default rt list */
|
|
||||||
uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; /** \brief Prefix list */
|
uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; /** \brief Prefix list */
|
||||||
//uip_ds6_route_t uip_ds6_routing_table[UIP_DS6_ROUTE_NB]; /** \brief Routing table */
|
|
||||||
|
|
||||||
/* Used by Cooja to enable extraction of addresses from memory.*/
|
/* Used by Cooja to enable extraction of addresses from memory.*/
|
||||||
uint8_t uip_ds6_addr_size;
|
uint8_t uip_ds6_addr_size;
|
||||||
|
@ -95,25 +85,21 @@ static uip_ds6_addr_t *locaddr;
|
||||||
static uip_ds6_maddr_t *locmaddr;
|
static uip_ds6_maddr_t *locmaddr;
|
||||||
static uip_ds6_aaddr_t *locaaddr;
|
static uip_ds6_aaddr_t *locaaddr;
|
||||||
static uip_ds6_prefix_t *locprefix;
|
static uip_ds6_prefix_t *locprefix;
|
||||||
static uip_ds6_nbr_t *locnbr;
|
|
||||||
static uip_ds6_defrt_t *locdefrt;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_ds6_init(void)
|
uip_ds6_init(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
uip_ds6_neighbors_init();
|
||||||
uip_ds6_route_init();
|
uip_ds6_route_init();
|
||||||
|
|
||||||
PRINTF("Init of IPv6 data structures\n");
|
PRINTF("Init of IPv6 data structures\n");
|
||||||
PRINTF("%u neighbors\n%u default routers\n%u prefixes\n%u routes\n%u unicast addresses\n%u multicast addresses\n%u anycast addresses\n",
|
PRINTF("%u neighbors\n%u default routers\n%u prefixes\n%u routes\n%u unicast addresses\n%u multicast addresses\n%u anycast addresses\n",
|
||||||
UIP_DS6_NBR_NB, UIP_DS6_DEFRT_NB, UIP_DS6_PREFIX_NB, UIP_DS6_ROUTE_NB,
|
NEIGHBOR_TABLE_MAX_NEIGHBORS, UIP_DS6_DEFRT_NB, UIP_DS6_PREFIX_NB, UIP_DS6_ROUTE_NB,
|
||||||
UIP_DS6_ADDR_NB, UIP_DS6_MADDR_NB, UIP_DS6_AADDR_NB);
|
UIP_DS6_ADDR_NB, UIP_DS6_MADDR_NB, UIP_DS6_AADDR_NB);
|
||||||
memset(uip_ds6_nbr_cache, 0, sizeof(uip_ds6_nbr_cache));
|
|
||||||
// memset(uip_ds6_defrt_list, 0, sizeof(uip_ds6_defrt_list));
|
|
||||||
memset(uip_ds6_prefix_list, 0, sizeof(uip_ds6_prefix_list));
|
memset(uip_ds6_prefix_list, 0, sizeof(uip_ds6_prefix_list));
|
||||||
memset(&uip_ds6_if, 0, sizeof(uip_ds6_if));
|
memset(&uip_ds6_if, 0, sizeof(uip_ds6_if));
|
||||||
// memset(uip_ds6_routing_table, 0, sizeof(uip_ds6_routing_table));
|
|
||||||
uip_ds6_addr_size = sizeof(struct uip_ds6_addr);
|
uip_ds6_addr_size = sizeof(struct uip_ds6_addr);
|
||||||
uip_ds6_netif_addr_list_offset = offsetof(struct uip_ds6_netif, addr_list);
|
uip_ds6_netif_addr_list_offset = offsetof(struct uip_ds6_netif, addr_list);
|
||||||
|
|
||||||
|
@ -198,61 +184,7 @@ uip_ds6_periodic(void)
|
||||||
}
|
}
|
||||||
#endif /* !UIP_CONF_ROUTER */
|
#endif /* !UIP_CONF_ROUTER */
|
||||||
|
|
||||||
/* Periodic processing on neighbors */
|
uip_ds6_neighbor_periodic();
|
||||||
for(locnbr = uip_ds6_nbr_cache;
|
|
||||||
locnbr < uip_ds6_nbr_cache + UIP_DS6_NBR_NB;
|
|
||||||
locnbr++) {
|
|
||||||
if(locnbr->isused) {
|
|
||||||
switch(locnbr->state) {
|
|
||||||
case NBR_REACHABLE:
|
|
||||||
if(stimer_expired(&locnbr->reachable)) {
|
|
||||||
PRINTF("REACHABLE: moving to STALE (");
|
|
||||||
PRINT6ADDR(&locnbr->ipaddr);
|
|
||||||
PRINTF(")\n");
|
|
||||||
locnbr->state = NBR_STALE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#if UIP_ND6_SEND_NA
|
|
||||||
case NBR_INCOMPLETE:
|
|
||||||
if(locnbr->nscount >= UIP_ND6_MAX_MULTICAST_SOLICIT) {
|
|
||||||
uip_ds6_nbr_rm(locnbr);
|
|
||||||
} else if(stimer_expired(&locnbr->sendns) && (uip_len == 0)) {
|
|
||||||
locnbr->nscount++;
|
|
||||||
PRINTF("NBR_INCOMPLETE: NS %u\n", locnbr->nscount);
|
|
||||||
uip_nd6_ns_output(NULL, NULL, &locnbr->ipaddr);
|
|
||||||
stimer_set(&locnbr->sendns, uip_ds6_if.retrans_timer / 1000);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NBR_DELAY:
|
|
||||||
if(stimer_expired(&locnbr->reachable)) {
|
|
||||||
locnbr->state = NBR_PROBE;
|
|
||||||
locnbr->nscount = 0;
|
|
||||||
PRINTF("DELAY: moving to PROBE\n");
|
|
||||||
stimer_set(&locnbr->sendns, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NBR_PROBE:
|
|
||||||
if(locnbr->nscount >= UIP_ND6_MAX_UNICAST_SOLICIT) {
|
|
||||||
PRINTF("PROBE END\n");
|
|
||||||
if((locdefrt = uip_ds6_defrt_lookup(&locnbr->ipaddr)) != NULL) {
|
|
||||||
if (!locdefrt->isinfinite) {
|
|
||||||
uip_ds6_defrt_rm(locdefrt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uip_ds6_nbr_rm(locnbr);
|
|
||||||
} else if(stimer_expired(&locnbr->sendns) && (uip_len == 0)) {
|
|
||||||
locnbr->nscount++;
|
|
||||||
PRINTF("PROBE: NS %u\n", locnbr->nscount);
|
|
||||||
uip_nd6_ns_output(NULL, &locnbr->ipaddr, &locnbr->ipaddr);
|
|
||||||
stimer_set(&locnbr->sendns, uip_ds6_if.retrans_timer / 1000);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif /* UIP_ND6_SEND_NA */
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UIP_CONF_ROUTER & UIP_ND6_SEND_RA
|
#if UIP_CONF_ROUTER & UIP_ND6_SEND_RA
|
||||||
/* Periodic RA sending */
|
/* Periodic RA sending */
|
||||||
|
@ -291,118 +223,6 @@ uip_ds6_list_loop(uip_ds6_element_t *list, uint8_t size,
|
||||||
return *out_element != NULL ? FREESPACE : NOSPACE;
|
return *out_element != NULL ? FREESPACE : NOSPACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
uip_ds6_nbr_t *
|
|
||||||
uip_ds6_nbr_add(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr,
|
|
||||||
uint8_t isrouter, uint8_t state)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = uip_ds6_list_loop
|
|
||||||
((uip_ds6_element_t *)uip_ds6_nbr_cache, UIP_DS6_NBR_NB,
|
|
||||||
sizeof(uip_ds6_nbr_t), ipaddr, 128,
|
|
||||||
(uip_ds6_element_t **)&locnbr);
|
|
||||||
|
|
||||||
if(r == FREESPACE) {
|
|
||||||
locnbr->isused = 1;
|
|
||||||
uip_ipaddr_copy(&locnbr->ipaddr, ipaddr);
|
|
||||||
if(lladdr != NULL) {
|
|
||||||
memcpy(&locnbr->lladdr, lladdr, UIP_LLADDR_LEN);
|
|
||||||
} else {
|
|
||||||
memset(&locnbr->lladdr, 0, UIP_LLADDR_LEN);
|
|
||||||
}
|
|
||||||
locnbr->isrouter = isrouter;
|
|
||||||
locnbr->state = state;
|
|
||||||
#if UIP_CONF_IPV6_QUEUE_PKT
|
|
||||||
uip_packetqueue_new(&locnbr->packethandle);
|
|
||||||
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
|
|
||||||
/* timers are set separately, for now we put them in expired state */
|
|
||||||
stimer_set(&locnbr->reachable, 0);
|
|
||||||
stimer_set(&locnbr->sendns, 0);
|
|
||||||
locnbr->nscount = 0;
|
|
||||||
PRINTF("Adding neighbor with ip addr ");
|
|
||||||
PRINT6ADDR(ipaddr);
|
|
||||||
PRINTF("link addr ");
|
|
||||||
PRINTLLADDR((&(locnbr->lladdr)));
|
|
||||||
PRINTF("state %u\n", state);
|
|
||||||
NEIGHBOR_STATE_CHANGED(locnbr);
|
|
||||||
|
|
||||||
locnbr->last_lookup = clock_time();
|
|
||||||
return locnbr;
|
|
||||||
} else if(r == NOSPACE) {
|
|
||||||
/* We did not find any empty slot on the neighbor list, so we need
|
|
||||||
to remove one old entry to make room. */
|
|
||||||
uip_ds6_nbr_t *n, *oldest;
|
|
||||||
clock_time_t oldest_time;
|
|
||||||
|
|
||||||
oldest = NULL;
|
|
||||||
oldest_time = clock_time();
|
|
||||||
|
|
||||||
for(n = uip_ds6_nbr_cache;
|
|
||||||
n < &uip_ds6_nbr_cache[UIP_DS6_NBR_NB];
|
|
||||||
n++) {
|
|
||||||
if(n->isused && !uip_ds6_defrt_lookup(&n->ipaddr)) {
|
|
||||||
if(n->last_lookup < oldest_time) {
|
|
||||||
oldest = n;
|
|
||||||
oldest_time = n->last_lookup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(oldest != NULL) {
|
|
||||||
uip_ds6_nbr_rm(oldest);
|
|
||||||
return uip_ds6_nbr_add(ipaddr, lladdr, isrouter, state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PRINTF("uip_ds6_nbr_add drop\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr)
|
|
||||||
{
|
|
||||||
if(nbr != NULL) {
|
|
||||||
nbr->isused = 0;
|
|
||||||
#if UIP_CONF_IPV6_QUEUE_PKT
|
|
||||||
uip_packetqueue_free(&nbr->packethandle);
|
|
||||||
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
|
|
||||||
NEIGHBOR_STATE_CHANGED(nbr);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
uip_ds6_nbr_t *
|
|
||||||
uip_ds6_nbr_lookup(uip_ipaddr_t *ipaddr)
|
|
||||||
{
|
|
||||||
if(uip_ds6_list_loop
|
|
||||||
((uip_ds6_element_t *)uip_ds6_nbr_cache, UIP_DS6_NBR_NB,
|
|
||||||
sizeof(uip_ds6_nbr_t), ipaddr, 128,
|
|
||||||
(uip_ds6_element_t **)&locnbr) == FOUND) {
|
|
||||||
locnbr->last_lookup = clock_time();
|
|
||||||
return locnbr;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
uip_ds6_nbr_t *
|
|
||||||
uip_ds6_nbr_ll_lookup(uip_lladdr_t *lladdr)
|
|
||||||
{
|
|
||||||
uip_ds6_nbr_t *fin;
|
|
||||||
|
|
||||||
for(locnbr = uip_ds6_nbr_cache, fin = locnbr + UIP_DS6_NBR_NB;
|
|
||||||
locnbr < fin;
|
|
||||||
++locnbr) {
|
|
||||||
if(locnbr->isused) {
|
|
||||||
if(!memcmp(lladdr, &locnbr->lladdr, UIP_LLADDR_LEN)) {
|
|
||||||
return locnbr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if UIP_CONF_ROUTER
|
#if UIP_CONF_ROUTER
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -878,25 +698,5 @@ uip_ds6_compute_reachable_time(void)
|
||||||
UIP_ND6_MIN_RANDOM_FACTOR(uip_ds6_if.base_reachable_time));
|
UIP_ND6_MIN_RANDOM_FACTOR(uip_ds6_if.base_reachable_time));
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_nbr_t *
|
|
||||||
uip_ds6_get_least_lifetime_neighbor(void)
|
|
||||||
{
|
|
||||||
uip_ds6_nbr_t *nbr_expiring = NULL;
|
|
||||||
uint8_t i;
|
|
||||||
for(i = 0; i < UIP_DS6_NBR_NB; i++) {
|
|
||||||
if(uip_ds6_nbr_cache[i].isused) {
|
|
||||||
if(nbr_expiring != NULL) {
|
|
||||||
clock_time_t curr = stimer_remaining(&uip_ds6_nbr_cache[i].reachable);
|
|
||||||
if(curr < stimer_remaining(&nbr_expiring->reachable)) {
|
|
||||||
nbr_expiring = &uip_ds6_nbr_cache[i];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
nbr_expiring = &uip_ds6_nbr_cache[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nbr_expiring;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/** @} */
|
/** @} */
|
||||||
#endif /* UIP_CONF_IPV6 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
/* The size of uip_ds6_addr_t depends on UIP_ND6_DEF_MAXDADNS. Include uip-nd6.h to define it. */
|
/* The size of uip_ds6_addr_t depends on UIP_ND6_DEF_MAXDADNS. Include uip-nd6.h to define it. */
|
||||||
#include "net/uip-nd6.h"
|
#include "net/uip-nd6.h"
|
||||||
#include "net/uip-ds6-route.h"
|
#include "net/uip-ds6-route.h"
|
||||||
|
#include "net/uip-ds6-neighbor.h"
|
||||||
|
|
||||||
/*--------------------------------------------------*/
|
/*--------------------------------------------------*/
|
||||||
/** Configuration. For all tables (Neighbor cache, Prefix List, Routing Table,
|
/** Configuration. For all tables (Neighbor cache, Prefix List, Routing Table,
|
||||||
|
@ -56,14 +57,6 @@
|
||||||
* - the number of elements assigned by the system (name suffixed by _NBS)
|
* - the number of elements assigned by the system (name suffixed by _NBS)
|
||||||
* - the total number of elements is the sum (name suffixed by _NB)
|
* - the total number of elements is the sum (name suffixed by _NB)
|
||||||
*/
|
*/
|
||||||
/* Neighbor cache */
|
|
||||||
#define UIP_DS6_NBR_NBS 0
|
|
||||||
#ifndef UIP_CONF_DS6_NBR_NBU
|
|
||||||
#define UIP_DS6_NBR_NBU 4
|
|
||||||
#else
|
|
||||||
#define UIP_DS6_NBR_NBU UIP_CONF_DS6_NBR_NBU
|
|
||||||
#endif
|
|
||||||
#define UIP_DS6_NBR_NB UIP_DS6_NBR_NBS + UIP_DS6_NBR_NBU
|
|
||||||
|
|
||||||
/* Default router list */
|
/* Default router list */
|
||||||
#define UIP_DS6_DEFRT_NBS 0
|
#define UIP_DS6_DEFRT_NBS 0
|
||||||
|
@ -155,22 +148,6 @@
|
||||||
#if UIP_CONF_IPV6_QUEUE_PKT
|
#if UIP_CONF_IPV6_QUEUE_PKT
|
||||||
#include "net/uip-packetqueue.h"
|
#include "net/uip-packetqueue.h"
|
||||||
#endif /*UIP_CONF_QUEUE_PKT */
|
#endif /*UIP_CONF_QUEUE_PKT */
|
||||||
/** \brief An entry in the nbr cache */
|
|
||||||
typedef struct uip_ds6_nbr {
|
|
||||||
uint8_t isused;
|
|
||||||
uip_ipaddr_t ipaddr;
|
|
||||||
uip_lladdr_t lladdr;
|
|
||||||
struct stimer reachable;
|
|
||||||
struct stimer sendns;
|
|
||||||
clock_time_t last_lookup;
|
|
||||||
uint8_t nscount;
|
|
||||||
uint8_t isrouter;
|
|
||||||
uint8_t state;
|
|
||||||
#if UIP_CONF_IPV6_QUEUE_PKT
|
|
||||||
struct uip_packetqueue_handle packethandle;
|
|
||||||
#define UIP_DS6_NBR_PACKET_LIFETIME CLOCK_SECOND * 4
|
|
||||||
#endif /*UIP_CONF_QUEUE_PKT */
|
|
||||||
} uip_ds6_nbr_t;
|
|
||||||
|
|
||||||
/** \brief A prefix list entry */
|
/** \brief A prefix list entry */
|
||||||
#if UIP_CONF_ROUTER
|
#if UIP_CONF_ROUTER
|
||||||
|
@ -226,8 +203,6 @@ typedef struct uip_ds6_maddr {
|
||||||
#endif /* UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED */
|
#endif /* UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED */
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
#endif /* UIP_CONF_IPV6_RPL */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** \brief Interface structure (contains all the interface variables) */
|
/** \brief Interface structure (contains all the interface variables) */
|
||||||
typedef struct uip_ds6_netif {
|
typedef struct uip_ds6_netif {
|
||||||
uint32_t link_mtu;
|
uint32_t link_mtu;
|
||||||
|
@ -273,14 +248,6 @@ uint8_t uip_ds6_list_loop(uip_ds6_element_t *list, uint8_t size,
|
||||||
uint8_t ipaddrlen,
|
uint8_t ipaddrlen,
|
||||||
uip_ds6_element_t **out_element);
|
uip_ds6_element_t **out_element);
|
||||||
|
|
||||||
/** \name Neighbor Cache basic routines */
|
|
||||||
/** @{ */
|
|
||||||
uip_ds6_nbr_t *uip_ds6_nbr_add(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr,
|
|
||||||
uint8_t isrouter, uint8_t state);
|
|
||||||
void uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr);
|
|
||||||
uip_ds6_nbr_t *uip_ds6_nbr_lookup(uip_ipaddr_t *ipaddr);
|
|
||||||
uip_ds6_nbr_t *uip_ds6_nbr_ll_lookup(uip_lladdr_t *lladdr);
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
|
@ -371,15 +338,4 @@ uint32_t uip_ds6_compute_reachable_time(void); /** \brief compute random reachab
|
||||||
/** @} */
|
/** @} */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief
|
|
||||||
* This searches inside the neighbor table for the neighbor that is about to
|
|
||||||
* expire the next.
|
|
||||||
*
|
|
||||||
* \return
|
|
||||||
* A reference to the neighbor about to expire the next or NULL if
|
|
||||||
* table is empty.
|
|
||||||
*/
|
|
||||||
uip_ds6_nbr_t *uip_ds6_get_least_lifetime_neighbor(void);
|
|
||||||
|
|
||||||
#endif /* __UIP_DS6_H__ */
|
#endif /* __UIP_DS6_H__ */
|
||||||
|
|
|
@ -191,9 +191,10 @@ uip_nd6_ns_input(void)
|
||||||
(uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
(uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
||||||
0, NBR_STALE);
|
0, NBR_STALE);
|
||||||
} else {
|
} else {
|
||||||
|
uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr);
|
||||||
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
||||||
&nbr->lladdr, UIP_LLADDR_LEN) != 0) {
|
lladdr, UIP_LLADDR_LEN) != 0) {
|
||||||
memcpy(&nbr->lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
||||||
UIP_LLADDR_LEN);
|
UIP_LLADDR_LEN);
|
||||||
nbr->state = NBR_STALE;
|
nbr->state = NBR_STALE;
|
||||||
} else {
|
} else {
|
||||||
|
@ -460,20 +461,22 @@ uip_nd6_na_input(void)
|
||||||
PRINTF("NA received is bad\n");
|
PRINTF("NA received is bad\n");
|
||||||
goto discard;
|
goto discard;
|
||||||
} else {
|
} else {
|
||||||
|
uip_lladdr_t *lladdr;
|
||||||
nbr = uip_ds6_nbr_lookup(&UIP_ND6_NA_BUF->tgtipaddr);
|
nbr = uip_ds6_nbr_lookup(&UIP_ND6_NA_BUF->tgtipaddr);
|
||||||
|
lladdr = uip_ds6_nbr_get_ll(nbr);
|
||||||
if(nbr == NULL) {
|
if(nbr == NULL) {
|
||||||
goto discard;
|
goto discard;
|
||||||
}
|
}
|
||||||
if(nd6_opt_llao != 0) {
|
if(nd6_opt_llao != 0) {
|
||||||
is_llchange =
|
is_llchange =
|
||||||
memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], (void *)(&nbr->lladdr),
|
memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], (void *)lladdr,
|
||||||
UIP_LLADDR_LEN);
|
UIP_LLADDR_LEN);
|
||||||
}
|
}
|
||||||
if(nbr->state == NBR_INCOMPLETE) {
|
if(nbr->state == NBR_INCOMPLETE) {
|
||||||
if(nd6_opt_llao == NULL) {
|
if(nd6_opt_llao == NULL) {
|
||||||
goto discard;
|
goto discard;
|
||||||
}
|
}
|
||||||
memcpy(&nbr->lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
||||||
UIP_LLADDR_LEN);
|
UIP_LLADDR_LEN);
|
||||||
if(is_solicited) {
|
if(is_solicited) {
|
||||||
nbr->state = NBR_REACHABLE;
|
nbr->state = NBR_REACHABLE;
|
||||||
|
@ -496,7 +499,7 @@ uip_nd6_na_input(void)
|
||||||
if(is_override || (!is_override && nd6_opt_llao != 0 && !is_llchange)
|
if(is_override || (!is_override && nd6_opt_llao != 0 && !is_llchange)
|
||||||
|| nd6_opt_llao == 0) {
|
|| nd6_opt_llao == 0) {
|
||||||
if(nd6_opt_llao != 0) {
|
if(nd6_opt_llao != 0) {
|
||||||
memcpy(&nbr->lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
||||||
UIP_LLADDR_LEN);
|
UIP_LLADDR_LEN);
|
||||||
}
|
}
|
||||||
if(is_solicited) {
|
if(is_solicited) {
|
||||||
|
@ -583,7 +586,7 @@ uip_nd6_rs_input(void)
|
||||||
#endif /*UIP_CONF_IPV6_CHECKS */
|
#endif /*UIP_CONF_IPV6_CHECKS */
|
||||||
switch (UIP_ND6_OPT_HDR_BUF->type) {
|
switch (UIP_ND6_OPT_HDR_BUF->type) {
|
||||||
case UIP_ND6_OPT_SLLAO:
|
case UIP_ND6_OPT_SLLAO:
|
||||||
nd6_opt_llao = UIP_ND6_OPT_HDR_BUF;
|
nd6_opt_llao = (uint8_t *)UIP_ND6_OPT_HDR_BUF;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PRINTF("ND option not supported in RS\n");
|
PRINTF("ND option not supported in RS\n");
|
||||||
|
@ -602,14 +605,18 @@ uip_nd6_rs_input(void)
|
||||||
if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) {
|
if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) {
|
||||||
/* we need to add the neighbor */
|
/* we need to add the neighbor */
|
||||||
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr,
|
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr,
|
||||||
&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE);
|
(uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE);
|
||||||
} else {
|
} else {
|
||||||
/* If LL address changed, set neighbor state to stale */
|
/* If LL address changed, set neighbor state to stale */
|
||||||
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
||||||
&nbr->lladdr, UIP_LLADDR_LEN) != 0) {
|
uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN) != 0) {
|
||||||
memcpy(&nbr->lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
uip_ds6_nbr_t nbr_data = *nbr;
|
||||||
UIP_LLADDR_LEN);
|
uip_ds6_nbr_rm(nbr);
|
||||||
nbr->state = NBR_STALE;
|
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr,
|
||||||
|
(uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE);
|
||||||
|
nbr->reachable = nbr_data.reachable;
|
||||||
|
nbr->sendns = nbr_data.sendns;
|
||||||
|
nbr->nscount = nbr_data.nscount;
|
||||||
}
|
}
|
||||||
nbr->isrouter = 0;
|
nbr->isrouter = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue