46 #include "net/nbr-table.h"
51 #ifdef NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK
52 void NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK(
const linkaddr_t *
addr);
56 #ifdef NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK
57 void NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK(
const linkaddr_t *
addr);
60 #if (UIP_CONF_MAX_ROUTES != 0)
75 static int num_routes = 0;
76 static void rm_routelist_callback(nbr_table_item_t *ptr);
82 LIST(defaultrouterlist);
85 #if UIP_DS6_NOTIFICATIONS
86 LIST(notificationlist);
90 #define DEBUG DEBUG_NONE
94 #if DEBUG != DEBUG_NONE
96 assert_nbr_routes_list_sane(
void)
102 for(r = uip_ds6_route_head(),
105 count < UIP_DS6_ROUTE_NB * 2;
106 r = uip_ds6_route_next(r),
109 if(count > UIP_DS6_ROUTE_NB) {
110 printf(
"uip-ds6-route.c: assert_nbr_routes_list_sane route list is in infinite loop\n");
115 if(count < num_routes) {
116 printf(
"uip-ds6-route.c: assert_nbr_routes_list_sane too few entries on route list: should be %d, is %d, max %d\n",
117 num_routes, count, UIP_CONF_MAX_ROUTES);
122 #if UIP_DS6_NOTIFICATIONS
124 call_route_callback(
int event, uip_ipaddr_t *
route,
125 uip_ipaddr_t *nexthop)
128 struct uip_ds6_notification *n;
132 if(event == UIP_DS6_NOTIFICATION_DEFRT_ADD ||
133 event == UIP_DS6_NOTIFICATION_DEFRT_RM) {
138 n->callback(event, route, nexthop, num);
143 uip_ds6_notification_add(
struct uip_ds6_notification *n,
144 uip_ds6_notification_callback c)
153 uip_ds6_notification_rm(
struct uip_ds6_notification *n)
160 uip_ds6_route_init(
void)
162 #if (UIP_CONF_MAX_ROUTES != 0)
165 nbr_table_register(nbr_routes,
166 (nbr_table_callback *)rm_routelist_callback);
172 #if UIP_DS6_NOTIFICATIONS
176 #if (UIP_CONF_MAX_ROUTES != 0)
183 route->neighbor_routes);
193 #if (UIP_CONF_MAX_ROUTES != 0)
195 return uip_ds6_nbr_ipaddr_from_lladdr(uip_ds6_route_nexthop_lladdr(route));
205 uip_ds6_route_head(
void)
207 #if (UIP_CONF_MAX_ROUTES != 0)
217 #if (UIP_CONF_MAX_ROUTES != 0)
227 uip_ds6_route_is_nexthop(
const uip_ipaddr_t *
ipaddr)
229 #if (UIP_CONF_MAX_ROUTES != 0)
231 lladdr = uip_ds6_nbr_lladdr_from_ipaddr(ipaddr);
237 return nbr_table_get_from_lladdr(nbr_routes, (linkaddr_t *)lladdr) !=
NULL;
244 uip_ds6_route_num_routes(
void)
246 #if (UIP_CONF_MAX_ROUTES != 0)
254 uip_ds6_route_lookup(uip_ipaddr_t *
addr)
256 #if (UIP_CONF_MAX_ROUTES != 0)
259 uint8_t longestmatch;
261 PRINTF(
"uip-ds6-route: Looking up route for ");
268 for(r = uip_ds6_route_head();
270 r = uip_ds6_route_next(r)) {
271 if(r->length >= longestmatch &&
272 uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) {
273 longestmatch = r->length;
276 if(longestmatch == 128) {
282 if(found_route !=
NULL) {
283 PRINTF(
"uip-ds6-route: Found route: ");
286 PRINT6ADDR(uip_ds6_route_nexthop(found_route));
289 PRINTF(
"uip-ds6-route: No route found\n");
292 if(found_route !=
NULL && found_route !=
list_head(routelist)) {
309 uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
310 uip_ipaddr_t *nexthop)
312 #if (UIP_CONF_MAX_ROUTES != 0)
316 #if DEBUG != DEBUG_NONE
317 assert_nbr_routes_list_sane();
321 const uip_lladdr_t *nexthop_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(nexthop);
322 if(nexthop_lladdr ==
NULL) {
323 PRINTF(
"uip_ds6_route_add: neighbor link-local address unknown for ");
332 r = uip_ds6_route_lookup(ipaddr);
334 uip_ipaddr_t *current_nexthop;
335 current_nexthop = uip_ds6_route_nexthop(r);
336 if(current_nexthop !=
NULL && uip_ipaddr_cmp(nexthop, current_nexthop)) {
340 PRINTF(
"uip_ds6_route_add: old route for ");
342 PRINTF(
" found, deleting it\n");
352 if(uip_ds6_route_num_routes() == UIP_DS6_ROUTE_NB) {
355 #if UIP_DS6_ROUTE_REMOVE_LEAST_RECENTLY_USED
363 PRINTF(
"uip_ds6_route_add: dropping route to ");
364 PRINT6ADDR(&oldest->ipaddr);
366 uip_ds6_route_rm(oldest);
378 routes = nbr_table_get_from_lladdr(nbr_routes,
379 (linkaddr_t *)nexthop_lladdr);
387 routes = nbr_table_add_lladdr(nbr_routes,
388 (linkaddr_t *)nexthop_lladdr,
389 NBR_TABLE_REASON_ROUTE,
NULL);
393 PRINTF(
"uip_ds6_route_add: could not allocate neighbor table entry\n");
397 #ifdef NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK
398 NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK((
const linkaddr_t *)nexthop_lladdr);
408 PRINTF(
"uip_ds6_route_add: could not allocate route\n");
420 PRINTF(
"uip_ds6_route_add: could not allocate neighbor route list entry\n");
428 r->neighbor_routes = routes;
431 PRINTF(
"uip_ds6_route_add num %d\n", num_routes);
434 nbr_table_lock(nbr_routes, routes);
440 #ifdef UIP_DS6_ROUTE_STATE_TYPE
444 PRINTF(
"uip_ds6_route_add: adding route: ");
449 ANNOTATE(
"#L %u 1;blue\n", nexthop->u8[
sizeof(uip_ipaddr_t) - 1]);
451 #if UIP_DS6_NOTIFICATIONS
452 call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_ADD, ipaddr, nexthop);
455 #if DEBUG != DEBUG_NONE
456 assert_nbr_routes_list_sane();
469 #if (UIP_CONF_MAX_ROUTES != 0)
471 #if DEBUG != DEBUG_NONE
472 assert_nbr_routes_list_sane();
474 if(route !=
NULL && route->neighbor_routes !=
NULL) {
476 PRINTF(
"uip_ds6_route_rm: removing route: ");
477 PRINT6ADDR(&route->ipaddr);
484 for(neighbor_route =
list_head(route->neighbor_routes->route_list);
485 neighbor_route !=
NULL && neighbor_route->route != route;
488 if(neighbor_route ==
NULL) {
489 PRINTF(
"uip_ds6_route_rm: neighbor_route was NULL for ");
490 uip_debug_ipaddr_print(&route->ipaddr);
493 list_remove(route->neighbor_routes->route_list, neighbor_route);
497 #if (DEBUG) & DEBUG_ANNOTATE
498 uip_ipaddr_t *nexthop = uip_ds6_route_nexthop(route);
499 if(nexthop !=
NULL) {
500 ANNOTATE(
"#L %u 0\n", nexthop->u8[
sizeof(uip_ipaddr_t) - 1]);
503 PRINTF(
"uip_ds6_route_rm: removing neighbor too\n");
504 nbr_table_remove(nbr_routes, route->neighbor_routes->route_list);
505 #ifdef NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK
506 NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK(
507 (
const linkaddr_t *)nbr_table_get_lladdr(nbr_routes, route->neighbor_routes->route_list));
511 memb_free(&neighborroutememb, neighbor_route);
515 PRINTF(
"uip_ds6_route_rm num %d\n", num_routes);
517 #if UIP_DS6_NOTIFICATIONS
518 call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM,
519 &route->ipaddr, uip_ds6_route_nexthop(route));
523 #if DEBUG != DEBUG_NONE
524 assert_nbr_routes_list_sane();
530 #if (UIP_CONF_MAX_ROUTES != 0)
535 #if DEBUG != DEBUG_NONE
536 assert_nbr_routes_list_sane();
538 PRINTF(
"uip_ds6_route_rm_routelist\n");
539 if(routes !=
NULL && routes->route_list !=
NULL) {
543 uip_ds6_route_rm(r->route);
546 nbr_table_remove(nbr_routes, routes);
548 #if DEBUG != DEBUG_NONE
549 assert_nbr_routes_list_sane();
554 rm_routelist_callback(nbr_table_item_t *ptr)
561 uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop)
563 #if (UIP_CONF_MAX_ROUTES != 0)
568 nexthop_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(nexthop);
569 routes = nbr_table_get_from_lladdr(nbr_routes,
570 (linkaddr_t *)nexthop_lladdr);
571 rm_routelist(routes);
576 uip_ds6_defrt_add(uip_ipaddr_t *ipaddr,
unsigned long interval)
580 #if DEBUG != DEBUG_NONE
581 assert_nbr_routes_list_sane();
584 PRINTF(
"uip_ds6_defrt_add\n");
585 d = uip_ds6_defrt_lookup(ipaddr);
589 PRINTF(
"uip_ds6_defrt_add: could not add default route to ");
591 PRINTF(
", out of memory\n");
594 PRINTF(
"uip_ds6_defrt_add: adding default route to ");
610 ANNOTATE(
"#L %u 1\n", ipaddr->u8[
sizeof(uip_ipaddr_t) - 1]);
612 #if UIP_DS6_NOTIFICATIONS
613 call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr);
616 #if DEBUG != DEBUG_NONE
617 assert_nbr_routes_list_sane();
628 #if DEBUG != DEBUG_NONE
629 assert_nbr_routes_list_sane();
637 PRINTF(
"Removing default route\n");
640 ANNOTATE(
"#L %u 0\n", defrt->ipaddr.u8[
sizeof(uip_ipaddr_t) - 1]);
641 #if UIP_DS6_NOTIFICATIONS
642 call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_RM,
643 &defrt->ipaddr, &defrt->ipaddr);
648 #if DEBUG != DEBUG_NONE
649 assert_nbr_routes_list_sane();
655 uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr)
661 if(uip_ipaddr_cmp(&d->ipaddr, ipaddr)) {
669 uip_ds6_defrt_choose(
void)
679 PRINTF(
"Defrt, IP address ");
680 PRINT6ADDR(&d->ipaddr);
682 bestnbr = uip_ds6_nbr_lookup(&d->ipaddr);
684 PRINTF(
"Defrt found, IP address ");
685 PRINT6ADDR(&d->ipaddr);
690 PRINTF(
"Defrt INCOMPLETE found, IP address ");
691 PRINT6ADDR(&d->ipaddr);
699 uip_ds6_defrt_periodic(
void)
706 PRINTF(
"uip_ds6_defrt_periodic: defrt lifetime expired\n");
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
void list_remove(list_t list, void *item)
Remove a specific element from a list.
#define LIST(name)
Declare a linked list.
static uip_ds6_addr_t * addr
Pointer to a router list entry.
A neighbor route list entry, used on the uip_ds6_route->neighbor_routes->route_list list...
Header file for IPv6-related data structures.
#define MEMB(name, structure, num)
Declare a memory block.
int stimer_expired(struct stimer *t)
Check if a timer has expired.
void * list_item_next(void *item)
Get the next item following this item.
#define UIP_DS6_ROUTE_STATE_TYPE
define some additional RPL related route state and neighbor callback for RPL - if not a DS6_ROUTE_STA...
An entry in the default router list.
#define NBR_INCOMPLETE
Possible states for the nbr cache entries.
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
static uip_ds6_defrt_t * defrt
Pointer to a nbr cache entry.
An entry in the nbr cache.
static uip_ds6_route_t * route
The next route to use.
void list_init(list_t list)
Initialize a list.
void memb_init(struct memb *m)
Initialize a memory block that was declared with MEMB().
void * list_head(list_t list)
Get a pointer to the first element of a list.
#define NULL
The null pointer.
void stimer_set(struct stimer *t, unsigned long interval)
Set a timer.
void list_add(list_t list, void *item)
Add an item at the end of a list.
Linked list manipulation routines.
static volatile clock_time_t count
These routines define the AVR-specific calls declared in /core/sys/clock.h CLOCK_SECOND is the number...
Header file for the uIP TCP/IP stack.
void * list_tail(list_t list)
Get the tail of a list.
Memory block allocation routines.
A set of debugging macros for the IP stack
int list_length(list_t list)
Get the length of a list.
#define LIST_STRUCT_INIT(struct_ptr, name)
Initialize a linked list that is part of a structure.
The neighbor routes hold a list of routing table entries that are attached to a specific neihbor...
void * memb_alloc(struct memb *m)
Allocate a memory block from a block of memory declared with MEMB().
An entry in the routing table.
char memb_free(struct memb *m, void *ptr)
Deallocate a memory block from a memory block previously declared with MEMB().
void list_push(list_t list, void *item)
Add an item to the start of the list.