/*---------------------------------------------------------------------------*/ void uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt) { uip_ds6_defrt_t *d; #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ /* Make sure that the defrt is in the list before we remove it. */ for(d = list_head(defaultrouterlist); d != NULL; d = list_item_next(d)) { if(d == defrt) { PRINTF("Removing default route\n"); list_remove(defaultrouterlist, defrt); memb_free(&defaultroutermemb, defrt); ANNOTATE("#L %u 0\n", defrt->ipaddr.u8[sizeof(uip_ipaddr_t) - 1]); #if UIP_DS6_NOTIFICATIONS call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_RM, &defrt->ipaddr, &defrt->ipaddr); #endif return; } } #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ }
/*---------------------------------------------------------------------------*/ uip_ds6_defrt_t * uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval) { uip_ds6_defrt_t *d; #if _DEBUG_ != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* _DEBUG_ != DEBUG_NONE */ PRINTF("uip_ds6_defrt_add\n"); d = uip_ds6_defrt_lookup(ipaddr); if(d == NULL) { d = memb_alloc(&defaultroutermemb); if(d == NULL) { PRINTF("uip_ds6_defrt_add: could not add default route to "); PRINT6ADDR(ipaddr); PRINTF(", out of memory\n"); return NULL; } else { PRINTF("uip_ds6_defrt_add: adding default route to "); PRINT6ADDR(ipaddr); PRINTF("\n"); } list_push(defaultrouterlist, d); } if(ipaddr == NULL) { /* A special case: if uip_ds6_defrt_add() is called with a NULL route, this is an indication that we want to force packets to go out to the fallback interface. If so, we add an unspecified route to the list of default routes. uip_ds6_defrt_choose() will trap this and ensure that packets go to the fallback interface. */ uip_create_unspecified(&d->ipaddr); ipaddr = &d->ipaddr; } else { uip_ipaddr_copy(&d->ipaddr, ipaddr); } if(interval != 0) { stimer_set(&d->lifetime, interval); d->isinfinite = 0; } else { d->isinfinite = 1; } ANNOTATE("#L %u 1\n", ipaddr->u8[sizeof(uip_ipaddr_t) - 1]); #if UIP_DS6_NOTIFICATIONS call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr); #endif #if _DEBUG_ != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* _DEBUG_ != DEBUG_NONE */ return d; }
/*---------------------------------------------------------------------------*/ uip_ds6_defrt_t * uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval) { uip_ds6_defrt_t *d; #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ PRINTF("uip_ds6_defrt_add\n"); d = uip_ds6_defrt_lookup(ipaddr); if(d == NULL) { d = memb_alloc(&defaultroutermemb); if(d == NULL) { PRINTF("uip_ds6_defrt_add: could not add default route to "); PRINT6ADDR(ipaddr); PRINTF(", out of memory\n"); return NULL; } else { PRINTF("uip_ds6_defrt_add: adding default route to "); PRINT6ADDR(ipaddr); PRINTF("\n"); } list_push(defaultrouterlist, d); } uip_ipaddr_copy(&d->ipaddr, ipaddr); //ADILA EDIT 03/11/14 //d->parentCh = cc2420_get_channel(); /*if(d->parentCh == 0) { d->parentCh = 26; }*/ //printf("\n\nINITIALISE D->PARENTCH %d\n\n", d->parentCh); //------------------- if(interval != 0) { stimer_set(&d->lifetime, interval); d->isinfinite = 0; } else { d->isinfinite = 1; } ANNOTATE("#L %u 1\n", ipaddr->u8[sizeof(uip_ipaddr_t) - 1]); #if UIP_DS6_NOTIFICATIONS call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr); #endif #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ return d; }
/*---------------------------------------------------------------------------*/ void uip_ds6_route_rm(uip_ds6_route_t *route) { #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ if(route != NULL && route->routes != NULL) { PRINTF("uip_ds6_route_rm: removing route: "); PRINT6ADDR(&route->ipaddr); PRINTF("\n"); list_remove(route->routes->route_list, route); if(list_head(route->routes->route_list) == NULL) { /* If this was the only route using this neighbor, remove the neibhor from the table */ PRINTF("uip_ds6_route_rm: removing neighbor too\n"); nbr_table_remove(nbr_routes, route->routes->route_list); } memb_free(&routememb, route); num_routes--; PRINTF("uip_ds6_route_rm num %d\n", num_routes); #if UIP_DS6_NOTIFICATIONS call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM, &route->ipaddr, uip_ds6_route_nexthop(route)); #endif #if 0 //(DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE /* we need to check if this was the last route towards "nexthop" */ /* if so - remove that link (annotation) */ uip_ds6_route_t *r; for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { uip_ipaddr_t *nextr, *nextroute; nextr = uip_ds6_route_nexthop(r); nextroute = uip_ds6_route_nexthop(route); if(nextr != NULL && nextroute != NULL && uip_ipaddr_cmp(nextr, nextroute)) { /* we found another link using the specific nexthop, so keep the #L */ return; } } ANNOTATE("#L %u 0\n", uip_ds6_route_nexthop(route)->u8[sizeof(uip_ipaddr_t) - 1]); #endif } #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ return; }
/*---------------------------------------------------------------------------*/ uip_ds6_defrt_t * uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval) { uip_ds6_defrt_t *d; #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ PRINTF("uip_ds6_defrt_add\n"); d = uip_ds6_defrt_lookup(ipaddr); if(d == NULL) { d = memb_alloc(&defaultroutermemb); if(d == NULL) { PRINTF("uip_ds6_defrt_add: could not add default route to "); PRINT6ADDR(ipaddr); PRINTF(", out of memory\n"); return NULL; } else { PRINTF("uip_ds6_defrt_add: adding default route to "); PRINT6ADDR(ipaddr); PRINTF("\n"); } list_push(defaultrouterlist, d); } uip_ipaddr_copy(&d->ipaddr, ipaddr); if(interval != 0) { stimer_set(&d->lifetime, interval); d->isinfinite = 0; } else { d->isinfinite = 1; } ANNOTATE("#L %u 1\n", ipaddr->u8[sizeof(uip_ipaddr_t) - 1]); #if UIP_DS6_NOTIFICATIONS call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr); #endif #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ return d; }
/*---------------------------------------------------------------------------*/ uip_ds6_route_t * uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, uip_ipaddr_t *nexthop) { uip_ds6_route_t *r; struct uip_ds6_route_neighbor_route *nbrr; #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ /* Get link-layer address of next hop, make sure it is in neighbor table */ const uip_lladdr_t *nexthop_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(nexthop); if(nexthop_lladdr == NULL) { PRINTF("uip_ds6_route_add: neighbor link-local address unknown for "); PRINT6ADDR(nexthop); PRINTF("\n"); return NULL; } /* First make sure that we don't add a route twice. If we find an existing route for our destination, we'll delete the old one first. */ r = uip_ds6_route_lookup(ipaddr); if(r != NULL) { PRINTF("uip_ds6_route_add: old route for "); PRINT6ADDR(ipaddr); PRINTF(" found, deleting it\n"); uip_ds6_route_rm(r); } { struct uip_ds6_route_neighbor_routes *routes; /* If there is no routing entry, create one. We first need to check if we have room for this route. If not, we remove the least recently used one we have. */ if(uip_ds6_route_num_routes() == UIP_DS6_ROUTE_NB) { /* Removing the oldest route entry from the route table. The least recently used route is the first route on the list. */ uip_ds6_route_t *oldest; oldest = list_tail(routelist); /* uip_ds6_route_head(); */ PRINTF("uip_ds6_route_add: dropping route to "); PRINT6ADDR(&oldest->ipaddr); PRINTF("\n"); uip_ds6_route_rm(oldest); } /* Every neighbor on our neighbor table holds a struct uip_ds6_route_neighbor_routes which holds a list of routes that go through the neighbor. We add our route entry to this list. We first check to see if we already have this neighbor in our nbr_route table. If so, the neighbor already has a route entry list. */ routes = nbr_table_get_from_lladdr(nbr_routes, (linkaddr_t *)nexthop_lladdr); if(routes == NULL) { /* If the neighbor did not have an entry in our neighbor table, we create one. The nbr_table_add_lladdr() function returns a pointer to a pointer that we may use for our own purposes. We initialize this pointer with the list of routing entries that are attached to this neighbor. */ routes = nbr_table_add_lladdr(nbr_routes, (linkaddr_t *)nexthop_lladdr); if(routes == NULL) { /* This should not happen, as we explicitly deallocated one route table entry above. */ PRINTF("uip_ds6_route_add: could not allocate neighbor table entry\n"); return NULL; } LIST_STRUCT_INIT(routes, route_list); } /* Allocate a routing entry and populate it. */ r = memb_alloc(&routememb); if(r == NULL) { /* This should not happen, as we explicitly deallocated one route table entry above. */ PRINTF("uip_ds6_route_add: could not allocate route\n"); return NULL; } /* add new routes first - assuming that there is a reason to add this and that there is a packet coming soon. */ list_push(routelist, r); nbrr = memb_alloc(&neighborroutememb); if(nbrr == NULL) { /* This should not happen, as we explicitly deallocated one route table entry above. */ PRINTF("uip_ds6_route_add: could not allocate neighbor route list entry\n"); memb_free(&routememb, r); return NULL; } nbrr->route = r; /* Add the route to this neighbor */ list_add(routes->route_list, nbrr); r->neighbor_routes = routes; num_routes++; PRINTF("uip_ds6_route_add num %d\n", num_routes); } uip_ipaddr_copy(&(r->ipaddr), ipaddr); r->length = length; #ifdef UIP_DS6_ROUTE_STATE_TYPE memset(&r->state, 0, sizeof(UIP_DS6_ROUTE_STATE_TYPE)); #endif PRINTF("uip_ds6_route_add: adding route: "); PRINT6ADDR(ipaddr); PRINTF(" via "); PRINT6ADDR(nexthop); PRINTF("\n"); ANNOTATE("#L %u 1;blue\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]); #if UIP_DS6_NOTIFICATIONS call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_ADD, ipaddr, nexthop); #endif #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ return r; }
/*---------------------------------------------------------------------------*/ uip_ds6_route_t * uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, uip_ipaddr_t *nexthop) { uip_ds6_route_t *r; #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ /* Get link-layer address of next hop, make sure it is in neighbor table */ const uip_lladdr_t *nexthop_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(nexthop); if(nexthop_lladdr == NULL) { PRINTF("uip_ds6_route_add: neighbor link-local address unknown "); PRINT6ADDR(ipaddr); PRINTF("\n"); return NULL; } /* First make sure that we don't add a route twice. If we find an existing route for our destination, we'll just update the old one. */ r = uip_ds6_route_lookup(ipaddr); if(r != NULL) { PRINTF("uip_ds6_route_add: old route already found, updating this one instead: "); PRINT6ADDR(ipaddr); PRINTF("\n"); } else { struct uip_ds6_route_neighbor_routes *routes; /* If there is no routing entry, create one */ /* Every neighbor on our neighbor table holds a struct uip_ds6_route_neighbor_routes which holds a list of routes that go through the neighbor. We add our route entry to this list. We first check to see if we already have this neighbor in our nbr_route table. If so, the neighbor already has a route entry list. */ routes = nbr_table_get_from_lladdr(nbr_routes, (rimeaddr_t *)nexthop_lladdr); if(routes == NULL) { /* If the neighbor did not have an entry in our neighbor table, we create one. The nbr_table_add_lladdr() function returns a pointer to a pointer that we may use for our own purposes. We initialize this pointer with the list of routing entries that are attached to this neighbor. */ routes = nbr_table_add_lladdr(nbr_routes, (rimeaddr_t *)nexthop_lladdr); if(routes == NULL) { PRINTF("uip_ds6_route_add: could not allocate a neighbor table entri for new route to "); PRINT6ADDR(ipaddr); PRINTF(", dropping it\n"); return NULL; } LIST_STRUCT_INIT(routes, route_list); } /* Allocate a routing entry and populate it. */ r = memb_alloc(&routememb); if(r == NULL) { PRINTF("uip_ds6_route_add: could not allocate memory for new route to "); PRINT6ADDR(ipaddr); PRINTF(", dropping it\n"); return NULL; } /* Add the route to this neighbor */ list_add(routes->route_list, r); num_routes++; PRINTF("uip_ds6_route_add num %d\n", num_routes); r->routes = routes; } uip_ipaddr_copy(&(r->ipaddr), ipaddr); r->length = length; #ifdef UIP_DS6_ROUTE_STATE_TYPE memset(&r->state, 0, sizeof(UIP_DS6_ROUTE_STATE_TYPE)); #endif PRINTF("uip_ds6_route_add: adding route: "); PRINT6ADDR(ipaddr); PRINTF(" via "); PRINT6ADDR(nexthop); PRINTF("\n"); ANNOTATE("#L %u 1;blue\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]); #if UIP_DS6_NOTIFICATIONS call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_ADD, ipaddr, nexthop); #endif #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ return r; }
/*---------------------------------------------------------------------------*/ void uip_ds6_route_rm(uip_ds6_route_t *route) { struct uip_ds6_route_neighbor_route *neighbor_route; #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ if(route != NULL && route->neighbor_routes != NULL) { PRINTF("uip_ds6_route_rm: removing route: "); PRINT6ADDR(&route->ipaddr); PRINTF("\n"); /* Remove the route from the route list */ list_remove(routelist, route); /* Find the corresponding neighbor_route and remove it. */ for(neighbor_route = list_head(route->neighbor_routes->route_list); neighbor_route != NULL && neighbor_route->route != route; neighbor_route = list_item_next(neighbor_route)); if(neighbor_route == NULL) { PRINTF("uip_ds6_route_rm: neighbor_route was NULL for "); uip_debug_ipaddr_print(&route->ipaddr); PRINTF("\n"); } list_remove(route->neighbor_routes->route_list, neighbor_route); if(list_head(route->neighbor_routes->route_list) == NULL) { /* If this was the only route using this neighbor, remove the neighbor from the table - this implicitly unlocks nexthop */ #if (DEBUG) & DEBUG_ANNOTATE uip_ipaddr_t *nexthop = uip_ds6_route_nexthop(route); if(nexthop != NULL) { ANNOTATE("#L %u 0\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]); } #endif /* (DEBUG) & DEBUG_ANNOTATE */ PRINTF("uip_ds6_route_rm: removing neighbor too\n"); nbr_table_remove(nbr_routes, route->neighbor_routes->route_list); #ifdef NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK( (const linkaddr_t *)nbr_table_get_lladdr(nbr_routes, route->neighbor_routes->route_list)); #endif } memb_free(&routememb, route); memb_free(&neighborroutememb, neighbor_route); num_routes--; PRINTF("uip_ds6_route_rm num %d\n", num_routes); #if UIP_DS6_NOTIFICATIONS call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM, &route->ipaddr, uip_ds6_route_nexthop(route)); #endif #ifdef NETSTACK_CONF_ROUTE_REMOVED_CALLBACK NETSTACK_CONF_ROUTE_REMOVED_CALLBACK(&route->ipaddr); #endif /* NETSTACK_CONF_ROUTE_REMOVED_CALLBACK*/ } #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ return; }