From afe13b22bc3c29fd80a5b58bc691f5819630c2d8 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 19:53:38 +0100 Subject: [PATCH] Rewrote the uIP IPv6 route handling code. Instead of being nested deeply inside the uip-ds6.c file, the route management code is now in a separate file, uip-ds6-route.c. This file presents a lib/list.h API for the routes, which makes the route list much easier to use. Additionally, the uip-ds6-route.c file adds a callback API that invokes a callback when routes are added and removed. --- core/net/rpl/rpl-dag.c | 38 ++-- core/net/rpl/rpl.c | 52 ++++-- core/net/uip-ds6-route.c | 371 +++++++++++++++++++++++++++++++++++++++ core/net/uip-ds6-route.h | 132 ++++++++++++++ core/net/uip-ds6.c | 27 +-- core/net/uip-ds6.h | 65 +------ 6 files changed, 579 insertions(+), 106 deletions(-) create mode 100644 core/net/uip-ds6-route.c create mode 100644 core/net/uip-ds6-route.h diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 1079b3178..02188d6d1 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -354,12 +354,10 @@ int rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from) { if(instance->def_route != NULL) { - if(instance->def_route->isused) { - PRINTF("RPL: Removing default route through "); - PRINT6ADDR(&instance->def_route->ipaddr); - PRINTF("\n"); - uip_ds6_defrt_rm(instance->def_route); - } + PRINTF("RPL: Removing default route through "); + PRINT6ADDR(&instance->def_route->ipaddr); + PRINTF("\n"); + uip_ds6_defrt_rm(instance->def_route); instance->def_route = NULL; } @@ -373,6 +371,13 @@ rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from) if(instance->def_route == NULL) { return 0; } + } else { + PRINTF("RPL: Removing default route\n"); + if(instance->def_route != NULL) { + uip_ds6_defrt_rm(instance->def_route); + } else { + PRINTF("RPL: Not actually removing default route, since instance had no default route\n"); + } } return 1; } @@ -691,12 +696,10 @@ rpl_nullify_parent(rpl_dag_t *dag, rpl_parent_t *parent) dag->rank = INFINITE_RANK; if(dag->joined) { if(dag->instance->def_route != NULL) { - if(dag->instance->def_route->isused) { - PRINTF("RPL: Removing default route "); - PRINT6ADDR(&parent->addr); - PRINTF("\n"); - uip_ds6_defrt_rm(dag->instance->def_route); - } + PRINTF("RPL: Removing default route "); + PRINT6ADDR(&parent->addr); + PRINTF("\n"); + uip_ds6_defrt_rm(dag->instance->def_route); dag->instance->def_route = NULL; } dao_output(parent, RPL_ZERO_LIFETIME); @@ -715,12 +718,11 @@ rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent) dag_src->preferred_parent = NULL; dag_src->rank = INFINITE_RANK; if(dag_src->joined && dag_src->instance->def_route != NULL) { - if(dag_src->instance->def_route->isused) { - PRINTF("RPL: Removing default route "); - PRINT6ADDR(&parent->addr); - PRINTF("\n"); - uip_ds6_defrt_rm(dag_src->instance->def_route); - } + PRINTF("RPL: Removing default route "); + PRINT6ADDR(&parent->addr); + PRINTF("\n"); + printf("rpl_move_parent\n"); + uip_ds6_defrt_rm(dag_src->instance->def_route); dag_src->instance->def_route = NULL; } } else if(dag_src->joined) { diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c index a79595ac3..f7936e553 100644 --- a/core/net/rpl/rpl.c +++ b/core/net/rpl/rpl.c @@ -56,21 +56,21 @@ rpl_stats_t rpl_stats; #endif -/************************************************************************/ -extern uip_ds6_route_t uip_ds6_routing_table[UIP_DS6_ROUTE_NB]; -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_purge_routes(void) { - int i; + uip_ds6_route_t *r; - for(i = 0; i < UIP_DS6_ROUTE_NB; i++) { - if(uip_ds6_routing_table[i].isused) { - if(uip_ds6_routing_table[i].state.lifetime <= 1) { - uip_ds6_route_rm(&uip_ds6_routing_table[i]); - } else { - uip_ds6_routing_table[i].state.lifetime--; - } + r = uip_ds6_route_list_head(); + + while(r != NULL) { + if(r->state.lifetime <= 1) { + uip_ds6_route_rm(r); + r = uip_ds6_route_list_head(); + } else { + r->state.lifetime--; + r = list_item_next(r); } } } @@ -78,11 +78,16 @@ rpl_purge_routes(void) void rpl_remove_routes(rpl_dag_t *dag) { - int i; + uip_ds6_route_t *r; - for(i = 0; i < UIP_DS6_ROUTE_NB; i++) { - if(uip_ds6_routing_table[i].state.dag == dag) { - uip_ds6_route_rm(&uip_ds6_routing_table[i]); + r = uip_ds6_route_list_head(); + + while(r != NULL) { + if(r->state.dag == dag) { + uip_ds6_route_rm(r); + r = uip_ds6_route_list_head(); + } else { + r = list_item_next(r); } } } @@ -90,6 +95,22 @@ rpl_remove_routes(rpl_dag_t *dag) void rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag) { + uip_ds6_route_t *r; + + r = uip_ds6_route_list_head(); + + while(r != NULL) { + if(uip_ipaddr_cmp(&r->nexthop, nexthop) && + r->state.dag == dag) { + uip_ds6_route_rm(r); + r = uip_ds6_route_list_head(); + } else { + r = list_item_next(r); + } + } + 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; @@ -102,6 +123,7 @@ 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]); +#endif /* 0 */ } /*---------------------------------------------------------------------------*/ uip_ds6_route_t * diff --git a/core/net/uip-ds6-route.c b/core/net/uip-ds6-route.c new file mode 100644 index 000000000..851c86e72 --- /dev/null +++ b/core/net/uip-ds6-route.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + * + */ +#include "net/uip-ds6.h" +#include "net/uip.h" + +#include "lib/list.h" +#include "lib/memb.h" + + +#include + +LIST(routelist); +MEMB(routememb, uip_ds6_route_t, UIP_DS6_ROUTE_NB); + +LIST(defaultrouterlist); +MEMB(defaultroutermemb, uip_ds6_defrt_t, UIP_DS6_DEFRT_NB); + +LIST(notificationlist); + +#define DEBUG DEBUG_NONE +#include "net/uip-debug.h" + +/*---------------------------------------------------------------------------*/ +static void +call_route_callback(int event, uip_ipaddr_t *route, + uip_ipaddr_t *nexthop) +{ + int num; + struct uip_ds6_notification *n; + for(n = list_head(notificationlist); + n != NULL; + n = list_item_next(n)) { + if(event == UIP_DS6_NOTIFICATION_DEFRT_ADD || + event == UIP_DS6_NOTIFICATION_DEFRT_RM) { + num = list_length(defaultrouterlist); + } else { + num = list_length(routelist); + } + n->callback(event, route, nexthop, num); + } +} +/*---------------------------------------------------------------------------*/ +void +uip_ds6_notification_add(struct uip_ds6_notification *n, + uip_ds6_notification_callback c) +{ + if(n != NULL && c != NULL) { + n->callback = c; + list_add(notificationlist, n); + } +} +/*---------------------------------------------------------------------------*/ +void +uip_ds6_notification_rm(struct uip_ds6_notification *n) +{ + list_remove(notificationlist, n); +} +/*---------------------------------------------------------------------------*/ +void +uip_ds6_route_init(void) +{ + memb_init(&routememb); + list_init(routelist); + + memb_init(&defaultroutermemb); + list_init(defaultrouterlist); + + list_init(notificationlist); +} +/*---------------------------------------------------------------------------*/ +uip_ds6_route_t * +uip_ds6_route_list_head(void) +{ + return list_head(routelist); +} +/*---------------------------------------------------------------------------*/ +int +uip_ds6_route_num_routes(void) +{ + return list_length(routelist); +} +/*---------------------------------------------------------------------------*/ +uip_ds6_route_t * +uip_ds6_route_lookup(uip_ipaddr_t *addr) +{ + uip_ds6_route_t *r; + uip_ds6_route_t *found_route; + uint8_t longestmatch; + + PRINTF("uip-ds6-route: Looking up route for "); + PRINT6ADDR(addr); + PRINTF("\n"); + + + found_route = NULL; + longestmatch = 0; + for(r = list_head(routelist); + r != NULL; + r = list_item_next(r)) { + if(r->length >= longestmatch && + uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) { + longestmatch = r->length; + found_route = r; + } + + } + + if(found_route != NULL) { + PRINTF("uip-ds6-route: Found route:"); + PRINT6ADDR(addr); + PRINTF(" via "); + PRINT6ADDR(&found_route->nexthop); + PRINTF("\n"); + } else { + PRINTF("uip-ds6-route: No route found\n"); + } + + return found_route; +} +/*---------------------------------------------------------------------------*/ +uip_ds6_route_t * +uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, + uip_ipaddr_t *nexthop, uint8_t metric) +{ + uip_ds6_route_t *r; + + /* 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 { + /* Allocate a routing entry and add the route to the list */ + 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; + } + list_add(routelist, r); + + // printf("uip_ds6_route_add num %d\n", list_length(routelist)); + } + + uip_ipaddr_copy(&(r->ipaddr), ipaddr); + r->length = length; + uip_ipaddr_copy(&(r->nexthop), nexthop); + r->metric = metric; + +#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]); + + call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_ADD, ipaddr, nexthop); + + return r; +} + +/*---------------------------------------------------------------------------*/ +void +uip_ds6_route_rm(uip_ds6_route_t *route) +{ + uip_ds6_route_t *r; + /* Make sure that the route is in the list before removing it. */ + for(r = list_head(routelist); + r != NULL; + r = list_item_next(r)) { + if(r == route) { + list_remove(routelist, route); + memb_free(&routememb, route); + + // printf("uip_ds6_route_rm num %d\n", list_length(routelist)); + + call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM, + &route->ipaddr, &route->nexthop); +#if (DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE + /* we need to check if this was the last route towards "nexthop" */ + /* if so - remove that link (annotation) */ + for(r = list_head(routelist); + r != NULL; + r = list_item_next(r)) { + if(uip_ipaddr_cmp(&r->nexthop, &route->nexthop)) { + /* we found another link using the specific nexthop, so keep the #L */ + return; + } + } + ANNOTATE("#L %u 0\n", route->nexthop.u8[sizeof(uip_ipaddr_t) - 1]); +#endif + return; + } + } +} +/*---------------------------------------------------------------------------*/ +void +uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop) +{ + uip_ds6_route_t *r; + + r = list_head(routelist); + while(r != NULL) { + if(uip_ipaddr_cmp(&r->nexthop, nexthop)) { + list_remove(routelist, r); + call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM, + &r->ipaddr, &r->nexthop); + r = list_head(routelist); + } else { + r = list_item_next(r); + } + } +} +/*---------------------------------------------------------------------------*/ +uip_ds6_defrt_t * +uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval) +{ + uip_ds6_defrt_t *d; + + 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]); + + call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr); + + return d; +} +/*---------------------------------------------------------------------------*/ +void +uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt) +{ + uip_ds6_defrt_t *d; + /* 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]); + call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_RM, + &defrt->ipaddr, &defrt->ipaddr); + return; + } + } +} +/*---------------------------------------------------------------------------*/ +uip_ds6_defrt_t * +uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr) +{ + uip_ds6_defrt_t *d; + for(d = list_head(defaultrouterlist); + d != NULL; + d = list_item_next(d)) { + if(uip_ipaddr_cmp(&d->ipaddr, ipaddr)) { + return d; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +uip_ipaddr_t * +uip_ds6_defrt_choose(void) +{ + uip_ds6_defrt_t *d; + uip_ds6_nbr_t *bestnbr; + uip_ipaddr_t *addr; + + addr = NULL; + for(d = list_head(defaultrouterlist); + d != NULL; + d = list_item_next(d)) { + PRINTF("Defrt, IP address "); + PRINT6ADDR(&d->ipaddr); + PRINTF("\n"); + bestnbr = uip_ds6_nbr_lookup(&d->ipaddr); + if(bestnbr != NULL && bestnbr->state != NBR_INCOMPLETE) { + PRINTF("Defrt found, IP address "); + PRINT6ADDR(&d->ipaddr); + PRINTF("\n"); + return &d->ipaddr; + } else { + addr = &d->ipaddr; + PRINTF("Defrt INCOMPLETE found, IP address "); + PRINT6ADDR(&d->ipaddr); + PRINTF("\n"); + } + } + return addr; +} +/*---------------------------------------------------------------------------*/ +void +uip_ds6_defrt_periodic(void) +{ + uip_ds6_defrt_t *d; + d = list_head(defaultrouterlist); + while(d != NULL) { + if(!d->isinfinite && + stimer_expired(&d->lifetime)) { + printf("defrt lifetime expired\n"); + uip_ds6_defrt_rm(d); + d = list_head(defaultrouterlist); + } else { + d = list_item_next(d); + } + } +} +/*---------------------------------------------------------------------------*/ + + diff --git a/core/net/uip-ds6-route.h b/core/net/uip-ds6-route.h new file mode 100644 index 000000000..59e13db81 --- /dev/null +++ b/core/net/uip-ds6-route.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + * + */ +#ifndef UIP_DS6_ROUTE_H +#define UIP_DS6_ROUTE_H + +void uip_ds6_route_init(void); + + +/* Event constants for the uip-ds6 route notification interface. The + notification interface allows for a user program to be notified via + a callback when a route has been added or removed and when the + system has added or removed a default route. */ +#define UIP_DS6_NOTIFICATION_DEFRT_ADD 0 +#define UIP_DS6_NOTIFICATION_DEFRT_RM 1 +#define UIP_DS6_NOTIFICATION_ROUTE_ADD 2 +#define UIP_DS6_NOTIFICATION_ROUTE_RM 3 + +typedef void (* uip_ds6_notification_callback)(int event, + uip_ipaddr_t *route, + uip_ipaddr_t *nexthop, + int num_routes); +struct uip_ds6_notification { + struct uip_ds6_notification *next; + uip_ds6_notification_callback callback; +}; + +void uip_ds6_notification_add(struct uip_ds6_notification *n, + uip_ds6_notification_callback c); +/*--------------------------------------------------*/ + + +/* Routing table */ +#define UIP_DS6_ROUTE_NBS 0 +#ifndef UIP_CONF_DS6_ROUTE_NBU +#define UIP_DS6_ROUTE_NBU 4 +#else +#define UIP_DS6_ROUTE_NBU UIP_CONF_DS6_ROUTE_NBU +#endif +#define UIP_DS6_ROUTE_NB UIP_DS6_ROUTE_NBS + UIP_DS6_ROUTE_NBU + +/** \brief define some additional RPL related route state and + * neighbor callback for RPL - if not a DS6_ROUTE_STATE is already set */ +#ifndef UIP_DS6_ROUTE_STATE_TYPE +#define UIP_DS6_ROUTE_STATE_TYPE rpl_route_entry_t +/* Needed for the extended route entry state when using ContikiRPL */ +typedef struct rpl_route_entry { + uint32_t lifetime; + uint32_t saved_lifetime; + void *dag; + uint8_t learned_from; +} rpl_route_entry_t; +#endif /* UIP_DS6_ROUTE_STATE_TYPE */ + + + +/** \brief An entry in the routing table */ +typedef struct uip_ds6_route { + struct uip_ds6_route *next; + uip_ipaddr_t ipaddr; + uip_ipaddr_t nexthop; + uint8_t length; + uint8_t metric; +#ifdef UIP_DS6_ROUTE_STATE_TYPE + UIP_DS6_ROUTE_STATE_TYPE state; +#endif +} uip_ds6_route_t; + + + +/** \brief An entry in the default router list */ +typedef struct uip_ds6_defrt { + struct uip_ds6_defrt *next; + uip_ipaddr_t ipaddr; + struct stimer lifetime; + uint8_t isinfinite; +} uip_ds6_defrt_t; + +/** \name Default router list basic routines */ +/** @{ */ +uip_ds6_defrt_t *uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, + unsigned long interval); +void uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt); +uip_ds6_defrt_t *uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr); +uip_ipaddr_t *uip_ds6_defrt_choose(void); + +void uip_ds6_defrt_periodic(void); +/** @} */ + + +/** \name Routing Table basic routines */ +/** @{ */ +uip_ds6_route_t *uip_ds6_route_lookup(uip_ipaddr_t *destipaddr); +uip_ds6_route_t *uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, + uip_ipaddr_t *next_hop, uint8_t metric); +void uip_ds6_route_rm(uip_ds6_route_t *route); +void uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop); + +int uip_ds6_route_num_routes(void); +uip_ds6_route_t *uip_ds6_route_list_head(void); + +/** @} */ + +#endif /* UIP_DS6_ROUTE_H */ diff --git a/core/net/uip-ds6.c b/core/net/uip-ds6.c index 056c74cd0..affec4ac0 100644 --- a/core/net/uip-ds6.c +++ b/core/net/uip-ds6.c @@ -75,9 +75,9 @@ static uint8_t rscount; /** \brief numbe /** @{ */ 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_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_route_t uip_ds6_routing_table[UIP_DS6_ROUTE_NB]; /** \brief Routing table */ +//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.*/ uint8_t uip_ds6_addr_size; @@ -89,28 +89,29 @@ uint8_t uip_ds6_netif_addr_list_offset; static uip_ipaddr_t loc_fipaddr; /* Pointers used in this file */ -static uip_ipaddr_t *locipaddr; static uip_ds6_addr_t *locaddr; static uip_ds6_maddr_t *locmaddr; static uip_ds6_aaddr_t *locaaddr; static uip_ds6_prefix_t *locprefix; static uip_ds6_nbr_t *locnbr; static uip_ds6_defrt_t *locdefrt; -static uip_ds6_route_t *locroute; /*---------------------------------------------------------------------------*/ void uip_ds6_init(void) { + + uip_ds6_route_init(); + 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", UIP_DS6_NBR_NB, UIP_DS6_DEFRT_NB, UIP_DS6_PREFIX_NB, UIP_DS6_ROUTE_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_defrt_list, 0, sizeof(uip_ds6_defrt_list)); memset(uip_ds6_prefix_list, 0, sizeof(uip_ds6_prefix_list)); memset(&uip_ds6_if, 0, sizeof(uip_ds6_if)); - memset(uip_ds6_routing_table, 0, sizeof(uip_ds6_routing_table)); + // memset(uip_ds6_routing_table, 0, sizeof(uip_ds6_routing_table)); uip_ds6_addr_size = sizeof(struct uip_ds6_addr); uip_ds6_netif_addr_list_offset = offsetof(struct uip_ds6_netif, addr_list); @@ -174,13 +175,14 @@ uip_ds6_periodic(void) } /* Periodic processing on default routers */ - for(locdefrt = uip_ds6_defrt_list; + uip_ds6_defrt_periodic(); + /* for(locdefrt = uip_ds6_defrt_list; locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) { if((locdefrt->isused) && (!locdefrt->isinfinite) && (stimer_expired(&(locdefrt->lifetime)))) { uip_ds6_defrt_rm(locdefrt); } - } + }*/ #if !UIP_CONF_ROUTER /* Periodic processing on prefixes */ @@ -398,6 +400,7 @@ uip_ds6_nbr_ll_lookup(uip_lladdr_t *lladdr) } /*---------------------------------------------------------------------------*/ +#if 0 uip_ds6_defrt_t * uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval) { @@ -477,7 +480,7 @@ uip_ds6_defrt_choose(void) } return locipaddr; } - +#endif /* 0 */ #if UIP_CONF_ROUTER /*---------------------------------------------------------------------------*/ uip_ds6_prefix_t * @@ -745,6 +748,7 @@ uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr) } /*---------------------------------------------------------------------------*/ +#if 0 uip_ds6_route_t * uip_ds6_route_lookup(uip_ipaddr_t *destipaddr) { @@ -825,7 +829,7 @@ uip_ds6_route_rm(uip_ds6_route_t *route) return; } } - ANNOTATE("#L %u 0\n",route->nexthop.u8[sizeof(uip_ipaddr_t) - 1]); + ANNOTATE("#L %u 0\n", route->nexthop.u8[sizeof(uip_ipaddr_t) - 1]); #endif } /*---------------------------------------------------------------------------*/ @@ -842,6 +846,9 @@ uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop) ANNOTATE("#L %u 0\n",nexthop->u8[sizeof(uip_ipaddr_t) - 1]); } + ANNOTATE("#L %u 0\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]); +} +#endif /* 0 */ /*---------------------------------------------------------------------------*/ void uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst) diff --git a/core/net/uip-ds6.h b/core/net/uip-ds6.h index a9ffb0e55..b697b45ac 100644 --- a/core/net/uip-ds6.h +++ b/core/net/uip-ds6.h @@ -46,6 +46,7 @@ #include "sys/stimer.h" /* 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-ds6-route.h" /*--------------------------------------------------*/ /** Configuration. For all tables (Neighbor cache, Prefix List, Routing Table, @@ -82,15 +83,6 @@ #endif #define UIP_DS6_PREFIX_NB UIP_DS6_PREFIX_NBS + UIP_DS6_PREFIX_NBU -/* Routing table */ -#define UIP_DS6_ROUTE_NBS 0 -#ifndef UIP_CONF_DS6_ROUTE_NBU -#define UIP_DS6_ROUTE_NBU 4 -#else -#define UIP_DS6_ROUTE_NBU UIP_CONF_DS6_ROUTE_NBU -#endif -#define UIP_DS6_ROUTE_NB UIP_DS6_ROUTE_NBS + UIP_DS6_ROUTE_NBU - /* Unicast address list*/ #define UIP_DS6_ADDR_NBS 1 #ifndef UIP_CONF_DS6_ADDR_NBU @@ -158,9 +150,8 @@ #define FOUND 0 #define FREESPACE 1 #define NOSPACE 2 - - /*--------------------------------------------------*/ + #if UIP_CONF_IPV6_QUEUE_PKT #include "net/uip-packetqueue.h" #endif /*UIP_CONF_QUEUE_PKT */ @@ -181,14 +172,6 @@ typedef struct uip_ds6_nbr { #endif /*UIP_CONF_QUEUE_PKT */ } uip_ds6_nbr_t; -/** \brief An entry in the default router list */ -typedef struct uip_ds6_defrt { - uint8_t isused; - uip_ipaddr_t ipaddr; - struct stimer lifetime; - uint8_t isinfinite; -} uip_ds6_defrt_t; - /** \brief A prefix list entry */ #if UIP_CONF_ROUTER typedef struct uip_ds6_prefix { @@ -236,19 +219,6 @@ typedef struct uip_ds6_maddr { uip_ipaddr_t ipaddr; } uip_ds6_maddr_t; -/** \brief define some additional RPL related route state and - * neighbor callback for RPL - if not a DS6_ROUTE_STATE is already set */ -#ifndef UIP_DS6_ROUTE_STATE_TYPE -#define UIP_DS6_ROUTE_STATE_TYPE rpl_route_entry_t -/* Needed for the extended route entry state when using ContikiRPL */ -typedef struct rpl_route_entry { - uint32_t lifetime; - uint32_t saved_lifetime; - void *dag; - uint8_t learned_from; -} rpl_route_entry_t; -#endif /* UIP_DS6_ROUTE_STATE_TYPE */ - /* only define the callback if RPL is active */ #if UIP_CONF_IPV6_RPL #ifndef UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED @@ -258,18 +228,6 @@ typedef struct rpl_route_entry { -/** \brief An entry in the routing table */ -typedef struct uip_ds6_route { - uint8_t isused; - uip_ipaddr_t ipaddr; - uint8_t length; - uint8_t metric; - uip_ipaddr_t nexthop; -#ifdef UIP_DS6_ROUTE_STATE_TYPE - UIP_DS6_ROUTE_STATE_TYPE state; -#endif -} uip_ds6_route_t; - /** \brief Interface structure (contains all the interface variables) */ typedef struct uip_ds6_netif { uint32_t link_mtu; @@ -325,15 +283,6 @@ uip_ds6_nbr_t *uip_ds6_nbr_ll_lookup(uip_lladdr_t *lladdr); /** @} */ -/** \name Default router list basic routines */ -/** @{ */ -uip_ds6_defrt_t *uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, - unsigned long interval); -void uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt); -uip_ds6_defrt_t *uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr); -uip_ipaddr_t *uip_ds6_defrt_choose(void); - -/** @} */ /** \name Prefix list basic routines */ /** @{ */ @@ -381,16 +330,6 @@ uip_ds6_aaddr_t *uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr); /** @} */ -/** \name Routing Table basic routines */ -/** @{ */ -uip_ds6_route_t *uip_ds6_route_lookup(uip_ipaddr_t *destipaddr); -uip_ds6_route_t *uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, - uip_ipaddr_t *next_hop, uint8_t metric); -void uip_ds6_route_rm(uip_ds6_route_t *route); -void uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop); - -/** @} */ - /** \brief set the last 64 bits of an IP address based on the MAC address */ void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr);