50 #include "net/link-stats.h" 60 #define LOG_MODULE "IPv6 Nbr" 61 #define LOG_LEVEL LOG_LEVEL_IPV6 67 uip_ds6_neighbors_init(
void)
70 nbr_table_register(ds6_neighbors, (nbr_table_callback *)uip_ds6_nbr_rm);
75 uint8_t isrouter, uint8_t state, nbr_table_reason_t reason,
82 #if UIP_ND6_SEND_RA || !UIP_CONF_ROUTER 83 nbr->isrouter = isrouter;
86 #if UIP_CONF_IPV6_QUEUE_PKT 87 uip_packetqueue_new(&nbr->packethandle);
90 if(nbr->state == NBR_REACHABLE) {
91 stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
99 LOG_INFO(
"Adding neighbor with ip addr ");
100 LOG_INFO_6ADDR(ipaddr);
101 LOG_INFO_(
" link addr ");
102 LOG_INFO_LLADDR((linkaddr_t*)lladdr);
103 LOG_INFO_(
" state %u\n", state);
107 LOG_INFO(
"Add drop ip addr ");
108 LOG_INFO_6ADDR(ipaddr);
109 LOG_INFO_(
" link addr (%p) ", lladdr);
110 LOG_INFO_LLADDR((linkaddr_t*)lladdr);
111 LOG_INFO_(
" state %u\n", state);
121 #if UIP_CONF_IPV6_QUEUE_PKT 122 uip_packetqueue_free(&nbr->packethandle);
125 return nbr_table_remove(ds6_neighbors, nbr);
132 uip_ds6_nbr_update_ll(
uip_ds6_nbr_t **nbr_pp,
const uip_lladdr_t *new_ll_addr)
136 if(nbr_pp == NULL || new_ll_addr == NULL) {
137 LOG_ERR(
"%s: invalid argument\n", __func__);
142 if(uip_ds6_nbr_ll_lookup(new_ll_addr) != NULL) {
143 LOG_ERR(
"%s: new_ll_addr, ", __func__);
144 LOG_ERR_LLADDR((
const linkaddr_t *)new_ll_addr);
145 LOG_ERR_(
", is already used in another nbr\n");
150 if(uip_ds6_nbr_rm(*nbr_pp) == 0) {
151 LOG_ERR(
"%s: input nbr cannot be removed\n", __func__);
156 nbr_backup.isrouter, nbr_backup.state,
157 NBR_TABLE_REASON_IPV6_ND, NULL)) == NULL) {
158 LOG_ERR(
"%s: cannot allocate a new nbr for new_ll_addr\n", __func__);
169 return (nbr != NULL) ? &nbr->ipaddr : NULL;
176 return (
const uip_lladdr_t *)nbr_table_get_lladdr(ds6_neighbors, nbr);
180 uip_ds6_nbr_num(
void)
186 for(nbr = nbr_table_head(ds6_neighbors);
188 nbr = nbr_table_next(ds6_neighbors, nbr)) {
195 uip_ds6_nbr_head(
void)
197 return nbr_table_head(ds6_neighbors);
203 return nbr_table_next(ds6_neighbors, nbr);
207 uip_ds6_nbr_lookup(
const uip_ipaddr_t *
ipaddr)
212 if(uip_ipaddr_cmp(&nbr->ipaddr, ipaddr)) {
215 nbr = nbr_table_next(ds6_neighbors, nbr);
222 uip_ds6_nbr_ll_lookup(
const uip_lladdr_t *lladdr)
224 return nbr_table_get_from_lladdr(ds6_neighbors, (linkaddr_t*)lladdr);
229 uip_ds6_nbr_ipaddr_from_lladdr(
const uip_lladdr_t *lladdr)
232 return nbr ? &nbr->ipaddr : NULL;
237 uip_ds6_nbr_lladdr_from_ipaddr(
const uip_ipaddr_t *ipaddr)
240 return nbr ? uip_ds6_nbr_get_ll(nbr) : NULL;
244 uip_ds6_link_callback(
int status,
int numtx)
247 const linkaddr_t *dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
269 nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest);
271 nbr->state = NBR_REACHABLE;
272 stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
273 LOG_INFO(
"received a link layer ACK : ");
274 LOG_INFO_LLADDR((uip_lladdr_t *)dest);
275 LOG_INFO_(
" is reachable.\n");
284 uip_ds6_neighbor_periodic(
void)
298 if(uip_ds6_defrt_lookup(&nbr->ipaddr) != NULL) {
299 LOG_INFO(
"REACHABLE: defrt moving to DELAY (");
300 LOG_INFO_6ADDR(&nbr->ipaddr);
302 nbr->state = NBR_DELAY;
303 stimer_set(&nbr->reachable, UIP_ND6_DELAY_FIRST_PROBE_TIME);
306 LOG_INFO(
"REACHABLE: moving to STALE (");
307 LOG_INFO_6ADDR(&nbr->ipaddr);
309 nbr->state = NBR_STALE;
312 LOG_INFO(
"REACHABLE: moving to STALE (");
313 LOG_INFO_6ADDR(&nbr->ipaddr);
315 nbr->state = NBR_STALE;
320 if(nbr->nscount >= UIP_ND6_MAX_MULTICAST_SOLICIT) {
324 LOG_INFO(
"NBR_INCOMPLETE: NS %u\n", nbr->nscount);
331 nbr->state = NBR_PROBE;
333 LOG_INFO(
"DELAY: moving to PROBE\n");
338 if(nbr->nscount >= UIP_ND6_MAX_UNICAST_SOLICIT) {
340 LOG_INFO(
"PROBE END\n");
341 if((locdefrt = uip_ds6_defrt_lookup(&nbr->ipaddr)) != NULL) {
342 if (!locdefrt->isinfinite) {
343 uip_ds6_defrt_rm(locdefrt);
349 LOG_INFO(
"PROBE: NS %u\n", nbr->nscount);
357 nbr = nbr_table_next(ds6_neighbors, nbr);
362 uip_ds6_nbr_refresh_reachable_state(
const uip_ipaddr_t *ipaddr)
365 nbr = uip_ds6_nbr_lookup(ipaddr);
367 nbr->state = NBR_REACHABLE;
369 stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
379 if(nbr_expiring != NULL) {
387 nbr = nbr_table_next(ds6_neighbors, nbr);
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
An entry in the default router list.
static uip_ds6_nbr_t * nbr
Pointer to llao option in uip_buf.
unsigned long stimer_remaining(struct stimer *t)
The time until the timer expires.
uint16_t uip_len
The length of the packet in the uip_buf buffer.
Header file for the link-layer address representation
uip_ds6_nbr_t * uip_ds6_get_least_lifetime_neighbor(void)
This searches inside the neighbor table for the neighbor that is about to expire the next...
IPv6 Neighbor cache (link-layer/IPv6 address mapping)
int stimer_expired(struct stimer *t)
Check if a timer has expired.
const linkaddr_t linkaddr_null
The null link-layer address.
Header file for IPv6-related data structures.
void(* neighbor_state_changed)(uip_ds6_nbr_t *nbr)
Called by uIP to notify addition/removal of IPv6 neighbor entries.
void uip_nd6_ns_output(uip_ipaddr_t *src, uip_ipaddr_t *dest, uip_ipaddr_t *tgt)
Send a neighbor solicitation, send a Neighbor Advertisement.
void stimer_set(struct stimer *t, unsigned long interval)
Set a timer.
Linked list manipulation routines.
The MAC layer transmission was OK.
Routing driver header file
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
#define NBR_INCOMPLETE
Possible states for the nbr cache entries.
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two link-layer addresses.
uip_ds6_nbr_t * uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr, uint8_t isrouter, uint8_t state, nbr_table_reason_t reason, void *data)
Neighbor Cache basic routines.
Header file for IPv6 Neighbor discovery (RFC 4861)
uip_ds6_netif_t uip_ds6_if
The single interface.
Header file for the Packet buffer (packetbuf) management
Header file for the logging system
An entry in the nbr cache.