37 #include "net/nbr-table.h"
59 LIST(defaultrouterlist);
62 #if UIP_DS6_NOTIFICATIONS
63 LIST(notificationlist);
66 static int num_routes = 0;
69 #define DEBUG DEBUG_NONE
72 static void rm_routelist_callback(nbr_table_item_t *ptr);
74 #if DEBUG != DEBUG_NONE
76 assert_nbr_routes_list_sane(
void)
82 for(r = uip_ds6_route_head(),
85 count < UIP_DS6_ROUTE_NB * 2;
86 r = uip_ds6_route_next(r),
89 if(count > UIP_DS6_ROUTE_NB) {
90 printf(
"uip-ds6-route.c: assert_nbr_routes_list_sane route list is in infinite loop\n");
95 if(count < num_routes) {
96 printf(
"uip-ds6-route.c: assert_nbr_routes_list_sane too few entries on route list: should be %d, is %d, max %d\n",
97 num_routes, count, UIP_CONF_MAX_ROUTES);
102 #if UIP_DS6_NOTIFICATIONS
104 call_route_callback(
int event, uip_ipaddr_t *route,
105 uip_ipaddr_t *nexthop)
108 struct uip_ds6_notification *n;
112 if(event == UIP_DS6_NOTIFICATION_DEFRT_ADD ||
113 event == UIP_DS6_NOTIFICATION_DEFRT_RM) {
118 n->callback(event, route, nexthop, num);
123 uip_ds6_notification_add(
struct uip_ds6_notification *n,
124 uip_ds6_notification_callback c)
133 uip_ds6_notification_rm(
struct uip_ds6_notification *n)
140 uip_ds6_route_init(
void)
144 nbr_table_register(nbr_routes,
145 (nbr_table_callback *)rm_routelist_callback);
150 #if UIP_DS6_NOTIFICATIONS
160 route->neighbor_routes);
170 return uip_ds6_nbr_ipaddr_from_lladdr(uip_ds6_route_nexthop_lladdr(route));
177 uip_ds6_route_head(
void)
193 uip_ds6_route_num_routes(
void)
199 uip_ds6_route_lookup(uip_ipaddr_t *addr)
203 uint8_t longestmatch;
205 PRINTF(
"uip-ds6-route: Looking up route for ");
212 for(r = uip_ds6_route_head();
214 r = uip_ds6_route_next(r)) {
215 if(r->length >= longestmatch &&
216 uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) {
217 longestmatch = r->length;
222 if(found_route !=
NULL) {
223 PRINTF(
"uip-ds6-route: Found route: ");
226 PRINT6ADDR(uip_ds6_route_nexthop(found_route));
229 PRINTF(
"uip-ds6-route: No route found\n");
232 if(found_route !=
NULL) {
245 uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
246 uip_ipaddr_t *nexthop)
251 #if DEBUG != DEBUG_NONE
252 assert_nbr_routes_list_sane();
256 const uip_lladdr_t *nexthop_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(nexthop);
257 if(nexthop_lladdr ==
NULL) {
258 PRINTF(
"uip_ds6_route_add: neighbor link-local address unknown for ");
267 r = uip_ds6_route_lookup(ipaddr);
269 PRINTF(
"uip_ds6_route_add: old route for ");
271 PRINTF(
" found, deleting it\n");
280 if(uip_ds6_route_num_routes() == UIP_DS6_ROUTE_NB) {
285 oldest = uip_ds6_route_head();
286 PRINTF(
"uip_ds6_route_add: dropping route to ");
287 PRINT6ADDR(&oldest->ipaddr);
289 uip_ds6_route_rm(oldest);
301 routes = nbr_table_get_from_lladdr(nbr_routes,
302 (linkaddr_t *)nexthop_lladdr);
310 routes = nbr_table_add_lladdr(nbr_routes,
311 (linkaddr_t *)nexthop_lladdr);
315 PRINTF(
"uip_ds6_route_add: could not allocate neighbor table entry\n");
327 PRINTF(
"uip_ds6_route_add: could not allocate route\n");
337 PRINTF(
"uip_ds6_route_add: could not allocate neighbor route list entry\n");
345 r->neighbor_routes = routes;
348 PRINTF(
"uip_ds6_route_add num %d\n", num_routes);
354 #ifdef UIP_DS6_ROUTE_STATE_TYPE
355 memset(&r->state, 0,
sizeof(UIP_DS6_ROUTE_STATE_TYPE));
358 PRINTF(
"uip_ds6_route_add: adding route: ");
363 ANNOTATE(
"#L %u 1;blue\n", nexthop->u8[
sizeof(uip_ipaddr_t) - 1]);
365 #if UIP_DS6_NOTIFICATIONS
366 call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_ADD, ipaddr, nexthop);
369 #if DEBUG != DEBUG_NONE
370 assert_nbr_routes_list_sane();
380 #if DEBUG != DEBUG_NONE
381 assert_nbr_routes_list_sane();
383 if(route !=
NULL && route->neighbor_routes !=
NULL) {
385 PRINTF(
"uip_ds6_route_rm: removing route: ");
386 PRINT6ADDR(&route->ipaddr);
393 for(neighbor_route =
list_head(route->neighbor_routes->route_list);
394 neighbor_route !=
NULL && neighbor_route->route != route;
397 if(neighbor_route ==
NULL) {
398 PRINTF(
"uip_ds6_route_rm: neighbor_route was NULL for ");
399 uip_debug_ipaddr_print(&route->ipaddr);
402 list_remove(route->neighbor_routes->route_list, neighbor_route);
406 PRINTF(
"uip_ds6_route_rm: removing neighbor too\n");
407 nbr_table_remove(nbr_routes, route->neighbor_routes->route_list);
410 memb_free(&neighborroutememb, neighbor_route);
414 PRINTF(
"uip_ds6_route_rm num %d\n", num_routes);
416 #if UIP_DS6_NOTIFICATIONS
417 call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM,
418 &route->ipaddr, uip_ds6_route_nexthop(route));
420 #if 0 //(DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE
424 for(r = uip_ds6_route_head();
426 r = uip_ds6_route_next(r)) {
427 uip_ipaddr_t *nextr, *nextroute;
428 nextr = uip_ds6_route_nexthop(r);
429 nextroute = uip_ds6_route_nexthop(route);
432 uip_ipaddr_cmp(nextr, nextroute)) {
437 ANNOTATE(
"#L %u 0\n", uip_ds6_route_nexthop(route)->u8[
sizeof(uip_ipaddr_t) - 1]);
441 #if DEBUG != DEBUG_NONE
442 assert_nbr_routes_list_sane();
450 #if DEBUG != DEBUG_NONE
451 assert_nbr_routes_list_sane();
453 PRINTF(
"uip_ds6_route_rm_routelist\n");
454 if(routes !=
NULL && routes->route_list !=
NULL) {
458 uip_ds6_route_rm(r->route);
461 nbr_table_remove(nbr_routes, routes);
463 #if DEBUG != DEBUG_NONE
464 assert_nbr_routes_list_sane();
469 rm_routelist_callback(nbr_table_item_t *ptr)
475 uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop)
481 nexthop_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(nexthop);
482 routes = nbr_table_get_from_lladdr(nbr_routes,
483 (linkaddr_t *)nexthop_lladdr);
484 rm_routelist(routes);
488 uip_ds6_defrt_add(uip_ipaddr_t *ipaddr,
unsigned long interval)
492 #if DEBUG != DEBUG_NONE
493 assert_nbr_routes_list_sane();
496 PRINTF(
"uip_ds6_defrt_add\n");
497 d = uip_ds6_defrt_lookup(ipaddr);
501 PRINTF(
"uip_ds6_defrt_add: could not add default route to ");
503 PRINTF(
", out of memory\n");
506 PRINTF(
"uip_ds6_defrt_add: adding default route to ");
522 ANNOTATE(
"#L %u 1\n", ipaddr->u8[
sizeof(uip_ipaddr_t) - 1]);
524 #if UIP_DS6_NOTIFICATIONS
525 call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr);
528 #if DEBUG != DEBUG_NONE
529 assert_nbr_routes_list_sane();
540 #if DEBUG != DEBUG_NONE
541 assert_nbr_routes_list_sane();
549 PRINTF(
"Removing default route\n");
552 ANNOTATE(
"#L %u 0\n", defrt->ipaddr.u8[
sizeof(uip_ipaddr_t) - 1]);
553 #if UIP_DS6_NOTIFICATIONS
554 call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_RM,
555 &defrt->ipaddr, &defrt->ipaddr);
560 #if DEBUG != DEBUG_NONE
561 assert_nbr_routes_list_sane();
567 uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr)
573 if(uip_ipaddr_cmp(&d->ipaddr, ipaddr)) {
581 uip_ds6_defrt_choose(
void)
591 PRINTF(
"Defrt, IP address ");
592 PRINT6ADDR(&d->ipaddr);
594 bestnbr = uip_ds6_nbr_lookup(&d->ipaddr);
596 PRINTF(
"Defrt found, IP address ");
597 PRINT6ADDR(&d->ipaddr);
602 PRINTF(
"Defrt INCOMPLETE found, IP address ");
603 PRINT6ADDR(&d->ipaddr);
611 uip_ds6_defrt_periodic(
void)
618 PRINTF(
"uip_ds6_defrt_periodic: defrt lifetime expired\n");
Linked list manipulation routines.
An entry in the routing table.
int stimer_expired(struct stimer *t)
Check if a timer has expired.
void memb_init(struct memb *m)
Initialize a memory block that was declared with MEMB().
void list_push(list_t list, void *item)
Add an item to the start of the list.
Header file for the uIP TCP/IP stack.
Network interface and stateless autoconfiguration (RFC 4862)
void * list_item_next(void *item)
Get the next item following this item.
char memb_free(struct memb *m, void *ptr)
Deallocate a memory block from a memory block previously declared with MEMB().
void * memb_alloc(struct memb *m)
Allocate a memory block from a block of memory declared with MEMB().
#define NULL
The null pointer.
#define NBR_INCOMPLETE
Possible states for the nbr cache entries.
void list_remove(list_t list, void *item)
Remove a specific element from a list.
void stimer_set(struct stimer *t, unsigned long interval)
Set a timer.
The neighbor routes hold a list of routing table entries that are attached to a specific neihbor...
int list_length(list_t list)
Get the length of a list.
void list_init(list_t list)
Initialize a list.
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
void * list_head(list_t list)
Get a pointer to the first element of a list.
#define MEMB(name, structure, num)
Declare a memory block.
void list_add(list_t list, void *item)
Add an item at the end of a list.
A neighbor route list entry, used on the uip_ds6_route->neighbor_routes->route_list list...
#define LIST(name)
Declare a linked list.
#define LIST_STRUCT_INIT(struct_ptr, name)
Initialize a linked list that is part of a structure.
A set of debugging macros.
Memory block allocation routines.
An entry in the default router list.
An entry in the nbr cache.