From db7cb567f5f24e84c7db6753af6f3df67827e20c Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Sun, 25 Nov 2012 11:47:02 +0100 Subject: [PATCH 01/20] Updated the RPL code to better match the Contiki code style --- core/net/rpl/rpl-dag.c | 91 ++++++++++++++++++----------------- core/net/rpl/rpl-ext-header.c | 16 +++--- core/net/rpl/rpl-timers.c | 18 +++---- core/net/rpl/rpl.c | 14 +++--- 4 files changed, 70 insertions(+), 69 deletions(-) diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 76f30d356..f0a004486 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -57,18 +57,18 @@ #include "net/neighbor-info.h" -/************************************************************************/ +/*---------------------------------------------------------------------------*/ extern rpl_of_t RPL_OF; static rpl_of_t * const objective_functions[] = {&RPL_OF}; -/************************************************************************/ +/*---------------------------------------------------------------------------*/ #ifndef RPL_CONF_MAX_PARENTS_PER_DAG #define RPL_MAX_PARENTS_PER_DAG 8 #else #define RPL_MAX_PARENTS_PER_DAG RPL_CONF_MAX_PARENTS_PER_DAG #endif /* !RPL_CONF_MAX_PARENTS_PER_DAG */ -/************************************************************************/ +/*---------------------------------------------------------------------------*/ /* RPL definitions. */ #ifndef RPL_CONF_GROUNDED @@ -77,17 +77,17 @@ static rpl_of_t * const objective_functions[] = {&RPL_OF}; #define RPL_GROUNDED RPL_CONF_GROUNDED #endif /* !RPL_CONF_GROUNDED */ -/************************************************************************/ +/*---------------------------------------------------------------------------*/ /* Allocate parents from the same static MEMB chunk to reduce memory waste. */ MEMB(parent_memb, struct rpl_parent, RPL_MAX_PARENTS_PER_DAG * RPL_MAX_INSTANCES * RPL_MAX_DAG_PER_INSTANCE); -/************************************************************************/ +/*---------------------------------------------------------------------------*/ /* Allocate instance table. */ rpl_instance_t instance_table[RPL_MAX_INSTANCES]; rpl_instance_t *default_instance; -/************************************************************************/ +/*---------------------------------------------------------------------------*/ /* Greater-than function for the lollipop counter. */ -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static int lollipop_greater_than(int a, int b) { @@ -101,7 +101,7 @@ lollipop_greater_than(int a, int b) (a < b && (b - a) > (RPL_LOLLIPOP_CIRCULAR_REGION + 1- RPL_LOLLIPOP_SEQUENCE_WINDOWS)); } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ /* Remove DAG parents with a rank that is at least the same as minimum_rank. */ static void remove_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank) @@ -118,7 +118,7 @@ remove_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank) } } } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static void nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank) { @@ -134,7 +134,7 @@ nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank) } } } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static void remove_worst_parent(rpl_dag_t *dag, rpl_rank_t min_worst_rank) { @@ -155,7 +155,7 @@ remove_worst_parent(rpl_dag_t *dag, rpl_rank_t min_worst_rank) rpl_remove_parent(dag, worst); } } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static int should_send_dao(rpl_instance_t *instance, rpl_dio_t *dio, rpl_parent_t *p) { @@ -167,7 +167,7 @@ should_send_dao(rpl_instance_t *instance, rpl_dio_t *dio, rpl_parent_t *p) return p == instance->current_dag->preferred_parent && (lollipop_greater_than(dio->dtsn, p->dtsn)); } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static int acceptable_rank(rpl_dag_t *dag, rpl_rank_t rank) { @@ -175,7 +175,7 @@ acceptable_rank(rpl_dag_t *dag, rpl_rank_t rank) ((dag->instance->max_rankinc == 0) || DAG_RANK(rank, dag->instance) <= DAG_RANK(dag->min_rank + dag->instance->max_rankinc, dag->instance)); } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static rpl_dag_t * get_dag(uint8_t instance_id, uip_ipaddr_t *dag_id) { @@ -197,7 +197,7 @@ get_dag(uint8_t instance_id, uip_ipaddr_t *dag_id) return NULL; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ rpl_dag_t * rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id) { @@ -270,7 +270,7 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id) return dag; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ int rpl_repair_root(uint8_t instance_id) { @@ -287,7 +287,7 @@ rpl_repair_root(uint8_t instance_id) rpl_reset_dio_timer(instance); return 1; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static void set_ip_from_prefix(uip_ipaddr_t *ipaddr, rpl_prefix_t *prefix) { @@ -295,7 +295,7 @@ set_ip_from_prefix(uip_ipaddr_t *ipaddr, rpl_prefix_t *prefix) memcpy(ipaddr, &prefix->prefix, (prefix->length + 7) / 8); uip_ds6_set_addr_iid(ipaddr, &uip_lladdr); } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static void check_prefix(rpl_prefix_t *last_prefix, rpl_prefix_t *new_prefix) { @@ -331,7 +331,7 @@ check_prefix(rpl_prefix_t *last_prefix, rpl_prefix_t *new_prefix) } } } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ int rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len) { @@ -349,7 +349,7 @@ rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len) check_prefix(NULL, &dag->prefix_info); return 1; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ int rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from) { @@ -376,13 +376,14 @@ rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from) } return 1; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ rpl_instance_t * rpl_alloc_instance(uint8_t instance_id) { rpl_instance_t *instance, *end; - for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) { + for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; + instance < end; ++instance) { if(instance->used == 0) { memset(instance, 0, sizeof(*instance)); instance->instance_id = instance_id; @@ -393,7 +394,7 @@ rpl_alloc_instance(uint8_t instance_id) } return NULL; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ rpl_dag_t * rpl_alloc_dag(uint8_t instance_id, uip_ipaddr_t *dag_id) { @@ -425,13 +426,13 @@ rpl_alloc_dag(uint8_t instance_id, uip_ipaddr_t *dag_id) rpl_free_instance(instance); return NULL; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_set_default_instance(rpl_instance_t *instance) { default_instance = instance; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_free_instance(rpl_instance_t *instance) { @@ -458,7 +459,7 @@ rpl_free_instance(rpl_instance_t *instance) instance->used = 0; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_free_dag(rpl_dag_t *dag) { @@ -480,7 +481,7 @@ rpl_free_dag(rpl_dag_t *dag) } dag->used = 0; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ rpl_parent_t * rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr) { @@ -504,7 +505,7 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr) list_add(dag->parents, p); return p; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ rpl_parent_t * rpl_find_parent(rpl_dag_t *dag, uip_ipaddr_t *addr) { @@ -518,7 +519,7 @@ rpl_find_parent(rpl_dag_t *dag, uip_ipaddr_t *addr) return NULL; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static rpl_dag_t * find_parent_dag(rpl_instance_t *instance, uip_ipaddr_t *addr) { @@ -536,7 +537,7 @@ find_parent_dag(rpl_instance_t *instance, uip_ipaddr_t *addr) } return NULL; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ rpl_parent_t * rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr) { @@ -554,7 +555,7 @@ rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr) } return NULL; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ rpl_dag_t * rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p) { @@ -645,7 +646,7 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p) } return best_dag; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ rpl_parent_t * rpl_select_parent(rpl_dag_t *dag) { @@ -668,7 +669,7 @@ rpl_select_parent(rpl_dag_t *dag) return best; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_remove_parent(rpl_dag_t *dag, rpl_parent_t *parent) { @@ -681,7 +682,7 @@ rpl_remove_parent(rpl_dag_t *dag, rpl_parent_t *parent) list_remove(dag->parents, parent); memb_free(&parent_memb, parent); } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_nullify_parent(rpl_dag_t *dag, rpl_parent_t *parent) { @@ -706,7 +707,7 @@ rpl_nullify_parent(rpl_dag_t *dag, rpl_parent_t *parent) PRINT6ADDR(&parent->addr); PRINTF("\n"); } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent) { @@ -735,7 +736,7 @@ rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent) parent->dag = dag_dst; list_add(dag_dst->parents, parent); } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ rpl_dag_t * rpl_get_any_dag(void) { @@ -748,7 +749,7 @@ rpl_get_any_dag(void) } return NULL; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ rpl_instance_t * rpl_get_instance(uint8_t instance_id) { @@ -761,7 +762,7 @@ rpl_get_instance(uint8_t instance_id) } return NULL; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ rpl_of_t * rpl_find_of(rpl_ocp_t ocp) { @@ -777,7 +778,7 @@ rpl_find_of(rpl_ocp_t ocp) return NULL; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio) { @@ -874,7 +875,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio) } } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio) { @@ -954,7 +955,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio) p->dtsn = dio->dtsn; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static void global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio) { @@ -981,7 +982,7 @@ global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio) RPL_STAT(rpl_stats.global_repairs++); } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_local_repair(rpl_instance_t *instance) { @@ -999,7 +1000,7 @@ rpl_local_repair(rpl_instance_t *instance) RPL_STAT(rpl_stats.local_repairs++); } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_recalculate_ranks(void) { @@ -1035,7 +1036,7 @@ rpl_recalculate_ranks(void) } } } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ int rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p) { @@ -1082,7 +1083,7 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p) return return_value; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) { @@ -1219,4 +1220,4 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) } p->dtsn = dio->dtsn; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ diff --git a/core/net/rpl/rpl-ext-header.c b/core/net/rpl/rpl-ext-header.c index f94a00c3c..75961f27a 100644 --- a/core/net/rpl/rpl-ext-header.c +++ b/core/net/rpl/rpl-ext-header.c @@ -53,7 +53,7 @@ #include #include -/************************************************************************/ +/*---------------------------------------------------------------------------*/ #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) #define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len]) #define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len]) @@ -61,7 +61,7 @@ #define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset]) #define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset]) #define UIP_EXT_HDR_OPT_RPL_BUF ((struct uip_ext_hdr_opt_rpl *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset]) -/************************************************************************/ +/*---------------------------------------------------------------------------*/ int rpl_verify_header(int uip_ext_opt_offset) { @@ -118,7 +118,7 @@ rpl_verify_header(int uip_ext_opt_offset) return 0; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static void set_rpl_opt(unsigned uip_ext_opt_offset) { @@ -141,7 +141,7 @@ set_rpl_opt(unsigned uip_ext_opt_offset) UIP_IP_BUF->len[0]++; } } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_update_header_empty(void) { @@ -192,7 +192,7 @@ rpl_update_header_empty(void) return; } } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ int rpl_update_header_final(uip_ipaddr_t *addr) { @@ -230,7 +230,7 @@ rpl_update_header_final(uip_ipaddr_t *addr) } return 0; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_remove_header(void) { @@ -257,7 +257,7 @@ rpl_remove_header(void) PRINTF("RPL: No hop-by-hop Option found\n"); } } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ uint8_t rpl_invert_header(void) { @@ -292,4 +292,4 @@ rpl_invert_header(void) return 0; } } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ diff --git a/core/net/rpl/rpl-timers.c b/core/net/rpl/rpl-timers.c index 0527d5363..e76cdcd93 100644 --- a/core/net/rpl/rpl-timers.c +++ b/core/net/rpl/rpl-timers.c @@ -47,7 +47,7 @@ #define DEBUG DEBUG_NONE #include "net/uip-debug.h" -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static struct ctimer periodic_timer; static void handle_periodic_timer(void *ptr); @@ -59,7 +59,7 @@ static uint16_t next_dis; /* dio_send_ok is true if the node is ready to send DIOs */ static uint8_t dio_send_ok; -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static void handle_periodic_timer(void *ptr) { @@ -76,7 +76,7 @@ handle_periodic_timer(void *ptr) #endif ctimer_reset(&periodic_timer); } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static void new_dio_interval(rpl_instance_t *instance) { @@ -122,7 +122,7 @@ new_dio_interval(rpl_instance_t *instance) PRINTF("RPL: Scheduling DIO timer %lu ticks in future (Interval)\n", time); ctimer_set(&instance->dio_timer, time, &handle_dio_timer, instance); } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static void handle_dio_timer(void *ptr) { @@ -165,14 +165,14 @@ handle_dio_timer(void *ptr) new_dio_interval(instance); } } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_reset_periodic_timer(void) { next_dis = RPL_DIS_INTERVAL - RPL_DIS_START_DELAY; ctimer_set(&periodic_timer, CLOCK_SECOND, handle_periodic_timer, NULL); } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ /* Resets the DIO timer in the instance to its minimal interval. */ void rpl_reset_dio_timer(rpl_instance_t *instance) @@ -190,7 +190,7 @@ rpl_reset_dio_timer(rpl_instance_t *instance) #endif /* RPL_CONF_STATS */ #endif /* RPL_LEAF_ONLY */ } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static void handle_dao_timer(void *ptr) { @@ -214,7 +214,7 @@ handle_dao_timer(void *ptr) } ctimer_stop(&instance->dao_timer); } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_schedule_dao(rpl_instance_t *instance) { @@ -233,4 +233,4 @@ rpl_schedule_dao(rpl_instance_t *instance) handle_dao_timer, instance); } } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c index bbdfb1117..a79595ac3 100644 --- a/core/net/rpl/rpl.c +++ b/core/net/rpl/rpl.c @@ -74,7 +74,7 @@ rpl_purge_routes(void) } } } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_remove_routes(rpl_dag_t *dag) { @@ -86,7 +86,7 @@ rpl_remove_routes(rpl_dag_t *dag) } } } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag) { @@ -103,7 +103,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]); } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ uip_ds6_route_t * rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len, uip_ipaddr_t *next_hop) @@ -136,7 +136,7 @@ rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len, return rep; } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ static void rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx) { @@ -179,7 +179,7 @@ rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx) uip_ds6_route_rm_by_nexthop(&ipaddr); } } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr) { @@ -203,7 +203,7 @@ rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr) } } } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ void rpl_init(void) { @@ -222,4 +222,4 @@ rpl_init(void) memset(&rpl_stats, 0, sizeof(rpl_stats)); #endif } -/************************************************************************/ +/*---------------------------------------------------------------------------*/ From 15deb37e64c311eb72561d2a2ad453ebe966b187 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 19:31:44 +0100 Subject: [PATCH 02/20] Updated DAG version processing to occur even for infinite rank DIOs. This makes it possible for the RPL root to infer the DAG version number from a network that hasn't had a root for a while, and where the rank has increased to infinity. --- core/net/rpl/rpl-dag.c | 48 +++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index f0a004486..1079b3178 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -1096,6 +1096,32 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) return; } + dag = get_dag(dio->instance_id, &dio->dag_id); + instance = rpl_get_instance(dio->instance_id); + + if(dag != NULL && instance != NULL) { + if(lollipop_greater_than(dio->version, dag->version)) { + if(dag->rank == ROOT_RANK(instance)) { + PRINTF("RPL: Root received inconsistent DIO version number\n"); + dag->version = dio->version; + RPL_LOLLIPOP_INCREMENT(dag->version); + rpl_reset_dio_timer(instance); + } else { + global_repair(from, dag, dio); + } + return; + } + + if(lollipop_greater_than(dag->version, dio->version)) { + /* The DIO sender is on an older version of the DAG. */ + PRINTF("RPL: old version received => inconsistency detected\n"); + if(dag->joined) { + rpl_reset_dio_timer(instance); + return; + } + } + } + if(dio->rank == INFINITE_RANK) { PRINTF("RPL: Ignoring DIO from node with infinite rank: "); PRINT6ADDR(from); @@ -1103,40 +1129,18 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) return; } - instance = rpl_get_instance(dio->instance_id); if(instance == NULL) { PRINTF("RPL: New instance detected: Joining...\n"); rpl_join_instance(from, dio); return; } - dag = get_dag(dio->instance_id, &dio->dag_id); if(dag == NULL) { PRINTF("RPL: Adding new DAG to known instance.\n"); rpl_add_dag(from, dio); return; } - if(lollipop_greater_than(dio->version, dag->version)) { - if(dag->rank == ROOT_RANK(instance)) { - PRINTF("RPL: Root received inconsistent DIO version number\n"); - dag->version = dio->version; - RPL_LOLLIPOP_INCREMENT(dag->version); - rpl_reset_dio_timer(instance); - } else { - global_repair(from, dag, dio); - } - return; - } - - if(lollipop_greater_than(dag->version, dio->version)) { - /* The DIO sender is on an older version of the DAG. */ - PRINTF("RPL: old version received => inconsistency detected\n"); - if(dag->joined) { - rpl_reset_dio_timer(instance); - return; - } - } if(dio->rank < ROOT_RANK(instance)) { PRINTF("RPL: Ignoring DIO with too low rank: %u\n", From 357b13b3d332c26c3aa3db1b040b0ff22eac56cd Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 19:33:54 +0100 Subject: [PATCH 03/20] Correctly handle upward and downward routes according to Section 1.2 of RFC6550 --- core/net/rpl/rpl-ext-header.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/core/net/rpl/rpl-ext-header.c b/core/net/rpl/rpl-ext-header.c index 75961f27a..8a161b665 100644 --- a/core/net/rpl/rpl-ext-header.c +++ b/core/net/rpl/rpl-ext-header.c @@ -97,9 +97,14 @@ rpl_verify_header(int uip_ext_opt_offset) down = 1; } - PRINTF("RPL: Packet going %s\n", down == 1 ? "down" : "up"); - sender_closer = UIP_EXT_HDR_OPT_RPL_BUF->senderrank < instance->current_dag->rank; + + PRINTF("RPL: Packet going %s, sender closer %d (%d < %d)\n", down == 1 ? "down" : "up", + sender_closer, + UIP_EXT_HDR_OPT_RPL_BUF->senderrank, + instance->current_dag->rank + ); + if((down && !sender_closer) || (!down && sender_closer)) { PRINTF("RPL: Loop detected - senderrank: %d my-rank: %d sender_closer: %d\n", UIP_EXT_HDR_OPT_RPL_BUF->senderrank, instance->current_dag->rank, @@ -183,7 +188,22 @@ rpl_update_header_empty(void) switch(UIP_EXT_HDR_OPT_BUF->type) { case UIP_EXT_HDR_OPT_RPL: PRINTF("RPL: Updating RPL option\n"); - UIP_EXT_HDR_OPT_RPL_BUF->senderrank=instance->current_dag->rank; + UIP_EXT_HDR_OPT_RPL_BUF->senderrank = instance->current_dag->rank; + + + /* Set the down extension flag correctly as described in Section + 11.2 of RFC6550. If the packet progresses along a DAO route, + the down flag should be set. */ + + if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) { + /* No route was found, so this packet will go towards the RPL + root. If so, we should not set the down flag. */ + UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_DOWN; + } else { + /* A DAO route was found so we set the down flag. */ + UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_DOWN; + } + uip_ext_len = last_uip_ext_len; return; default: From 8538aaf655fcfe3974c6487fec5abf5f09a43858 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 19:34:22 +0100 Subject: [PATCH 04/20] Made RPL DAO latency configurable --- core/net/rpl/rpl-private.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/net/rpl/rpl-private.h b/core/net/rpl/rpl-private.h index 808321d21..9dfd91927 100644 --- a/core/net/rpl/rpl-private.h +++ b/core/net/rpl/rpl-private.h @@ -103,7 +103,11 @@ /* Default values for RPL constants and variables. */ /* The default value for the DAO timer. */ +#ifdef RPL_CONF_DAO_LATENCY +#define RPL_DAO_LATENCY RPL_CONF_DAO_LATENCY +#else /* RPL_CONF_DAO_LATENCY */ #define RPL_DAO_LATENCY (CLOCK_SECOND * 4) +#endif /* RPL_DAO_LATENCY */ /* Special value indicating immediate removal. */ #define RPL_ZERO_LIFETIME 0 From 2396f9b8eaea79b7f5f5ffd0117a38589365bfca Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 19:35:39 +0100 Subject: [PATCH 05/20] Made DIO interval processing a little easier to follow. Explicitly state that the delay is handled as clock timer ticks. --- core/net/rpl/rpl-timers.c | 15 +++++++-------- core/net/rpl/rpl.h | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/core/net/rpl/rpl-timers.c b/core/net/rpl/rpl-timers.c index e76cdcd93..d2eebea5e 100644 --- a/core/net/rpl/rpl-timers.c +++ b/core/net/rpl/rpl-timers.c @@ -81,25 +81,24 @@ static void new_dio_interval(rpl_instance_t *instance) { uint32_t time; + clock_time_t ticks; /* TODO: too small timer intervals for many cases */ time = 1UL << instance->dio_intcurrent; /* Convert from milliseconds to CLOCK_TICKS. */ - time = (time * CLOCK_SECOND) / 1000; - - instance->dio_next_delay = time; + ticks = (time * CLOCK_SECOND) / 1000; + instance->dio_next_delay = ticks; /* random number between I/2 and I */ - time = time >> 1; - time += (time * random_rand()) / RANDOM_RAND_MAX; + ticks = ticks / 2 + (ticks / 2 * (uint32_t)random_rand()) / RANDOM_RAND_MAX; /* * The intervals must be equally long among the nodes for Trickle to * operate efficiently. Therefore we need to calculate the delay between * the randomized time and the start time of the next interval. */ - instance->dio_next_delay -= time; + instance->dio_next_delay -= ticks; instance->dio_send = 1; #if RPL_CONF_STATS @@ -119,8 +118,8 @@ new_dio_interval(rpl_instance_t *instance) instance->dio_counter = 0; /* schedule the timer */ - PRINTF("RPL: Scheduling DIO timer %lu ticks in future (Interval)\n", time); - ctimer_set(&instance->dio_timer, time, &handle_dio_timer, instance); + PRINTF("RPL: Scheduling DIO timer %lu ticks in future (Interval)\n", ticks); + ctimer_set(&instance->dio_timer, ticks, &handle_dio_timer, instance); } /*---------------------------------------------------------------------------*/ static void diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index 1a03549b5..d1f66bf83 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -221,7 +221,7 @@ struct rpl_instance { uint16_t dio_totsend; uint16_t dio_totrecv; #endif /* RPL_CONF_STATS */ - uint32_t dio_next_delay; /* delay for completion of dio interval */ + clock_time_t dio_next_delay; /* delay for completion of dio interval */ struct ctimer dio_timer; struct ctimer dao_timer; }; From 2a2175a2149e0a11af0fb5dfb514a3e5d182f46d Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 19:36:51 +0100 Subject: [PATCH 06/20] Make RPL DIS transmission interval random in the interval [0, INTERVAL/2]. This is needed to avoid synchronization in large RPL networks. --- core/net/rpl/rpl-timers.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/net/rpl/rpl-timers.c b/core/net/rpl/rpl-timers.c index d2eebea5e..fc584e0bd 100644 --- a/core/net/rpl/rpl-timers.c +++ b/core/net/rpl/rpl-timers.c @@ -168,7 +168,9 @@ handle_dio_timer(void *ptr) void rpl_reset_periodic_timer(void) { - next_dis = RPL_DIS_INTERVAL - RPL_DIS_START_DELAY; + next_dis = RPL_DIS_INTERVAL / 2 + + ((uint32_t)RPL_DIS_INTERVAL * (uint32_t)random_rand()) / RANDOM_RAND_MAX - + RPL_DIS_START_DELAY; ctimer_set(&periodic_timer, CLOCK_SECOND, handle_periodic_timer, NULL); } /*---------------------------------------------------------------------------*/ From b24157631faef02c6f869568fc0917dccfa7da49 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 19:40:14 +0100 Subject: [PATCH 07/20] Made nd6 maximum unicast solicitation messages configurable --- core/net/uip-nd6.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/net/uip-nd6.h b/core/net/uip-nd6.h index c62e0363e..265c4f3db 100644 --- a/core/net/uip-nd6.h +++ b/core/net/uip-nd6.h @@ -98,17 +98,25 @@ /** \name RFC 4861 Node constant */ #define UIP_ND6_MAX_MULTICAST_SOLICIT 3 + +#ifdef UIP_CONF_ND6_MAX_UNICAST_SOLICIT +#define UIP_ND6_MAX_UNICAST_SOLICIT UIP_CONF_ND6_MAX_UNICAST_SOLICIT +#else /* UIP_CONF_ND6_MAX_UNICAST_SOLICIT */ #define UIP_ND6_MAX_UNICAST_SOLICIT 3 +#endif /* UIP_CONF_ND6_MAX_UNICAST_SOLICIT */ + #ifdef UIP_CONF_ND6_REACHABLE_TIME #define UIP_ND6_REACHABLE_TIME UIP_CONF_ND6_REACHABLE_TIME #else #define UIP_ND6_REACHABLE_TIME 30000 #endif + #ifdef UIP_CONF_ND6_RETRANS_TIMER #define UIP_ND6_RETRANS_TIMER UIP_CONF_ND6_RETRANS_TIMER #else #define UIP_ND6_RETRANS_TIMER 1000 #endif + #define UIP_ND6_DELAY_FIRST_PROBE_TIME 5 #define UIP_ND6_MIN_RANDOM_FACTOR(x) (x / 2) #define UIP_ND6_MAX_RANDOM_FACTOR(x) ((x) + (x) / 2) From 0bad2b1748c10ea1c866b0af58eaec10b7b6db7f Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 19:41:11 +0100 Subject: [PATCH 08/20] Added a configuration option to annotate IP transmissions with red arrows in Cooja. --- core/net/tcpip.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/net/tcpip.c b/core/net/tcpip.c index f6184144a..018a6a982 100644 --- a/core/net/tcpip.c +++ b/core/net/tcpip.c @@ -586,6 +586,11 @@ tcpip_ipv6_output(void) } else { nexthop = &locrt->nexthop; } +#if TCPIP_CONF_ANNOTATE_TRANSMISSIONS + if(nexthop != NULL) { + printf("#L %u 1; red\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]); + } +#endif /* TCPIP_CONF_ANNOTATE_TRANSMISSIONS */ } /* End of next hop determination */ #if UIP_CONF_IPV6_RPL From 289a01b389c43ab47051501c247ab638358f7eb8 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 19:43:17 +0100 Subject: [PATCH 09/20] Added explicit functions uiplib_ip6addrconv and uiplib_ip4addrconv for converting IPv6 and IPv4 addresses, regardless of whether uIP was configured to run as an IPv4 or an IPv6 stack. --- core/net/uiplib.c | 51 +++++++++++++++++++++++++++++++---------------- core/net/uiplib.h | 4 +++- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/core/net/uiplib.c b/core/net/uiplib.c index 88911d2bc..b062b0867 100644 --- a/core/net/uiplib.c +++ b/core/net/uiplib.c @@ -42,9 +42,8 @@ /*-----------------------------------------------------------------------------------*/ int -uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr) +uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *ipaddr) { -#if UIP_CONF_IPV6 uint16_t value; int tmp, zero; unsigned int len; @@ -54,7 +53,7 @@ uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr) zero = -1; if(*addrstr == '[') addrstr++; - for(len = 0; len < sizeof(uip_ipaddr_t) - 1; addrstr++) { + for(len = 0; len < sizeof(uip_ip6addr_t) - 1; addrstr++) { c = *addrstr; if(c == ':' || c == '\0' || c == ']' || c == '/') { ipaddr->u8[len] = (value >> 8) & 0xff; @@ -91,45 +90,63 @@ uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr) PRINTF("uiplib: too large address\n"); return 0; } - if(len < sizeof(uip_ipaddr_t)) { + if(len < sizeof(uip_ip6addr_t)) { if(zero < 0) { PRINTF("uiplib: too short address\n"); return 0; } - memmove(&ipaddr->u8[zero + sizeof(uip_ipaddr_t) - len], + memmove(&ipaddr->u8[zero + sizeof(uip_ip6addr_t) - len], &ipaddr->u8[zero], len - zero); - memset(&ipaddr->u8[zero], 0, sizeof(uip_ipaddr_t) - len); + memset(&ipaddr->u8[zero], 0, sizeof(uip_ip6addr_t) - len); } -#else /* UIP_CONF_IPV6 */ - + return 1; +} +/*-----------------------------------------------------------------------------------*/ +/* Parse a IPv4-address from a string. Returns the number of characters read + * for the address. */ +int +uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *ipaddr) +{ unsigned char tmp; char c; unsigned char i, j; + uint8_t charsread = 0; tmp = 0; - + for(i = 0; i < 4; ++i) { j = 0; do { c = *addrstr; ++j; if(j > 4) { - return 0; + return 0; } - if(c == '.' || c == 0) { - ipaddr->u8[i] = tmp; - tmp = 0; + if(c == '.' || c == 0 || c == ' ') { + ipaddr->u8[i] = tmp; + tmp = 0; } else if(c >= '0' && c <= '9') { - tmp = (tmp * 10) + (c - '0'); + tmp = (tmp * 10) + (c - '0'); } else { - return 0; + return 0; } ++addrstr; - } while(c != '.' && c != 0); + ++charsread; + } while(c != '.' && c != 0 && c != ' '); + } + return charsread-1; +} +/*-----------------------------------------------------------------------------------*/ +int +uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr) +{ +#if UIP_CONF_IPV6 + return uiplib_ip6addrconv(addrstr, ipaddr); +#else /* UIP_CONF_IPV6 */ + return uiplib_ip4addrconv(addrstr, ipaddr); #endif /* UIP_CONF_IPV6 */ - return 1; } /*-----------------------------------------------------------------------------------*/ diff --git a/core/net/uiplib.h b/core/net/uiplib.h index 508c83db4..f9ba9a3bf 100644 --- a/core/net/uiplib.h +++ b/core/net/uiplib.h @@ -60,7 +60,7 @@ * \param addrstr A pointer to a string containing the IP address in * textual form. * - * \param addr A pointer to a uip_ipaddr_t that will be filled in with + * \param addr A pointer to a uip_ip4addr_t that will be filled in with * the numerical representation of the address. * * \retval 0 If the IP address could not be parsed. @@ -68,6 +68,8 @@ */ CCIF int uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *addr); +CCIF int uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *addr); +CCIF int uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *addr); /** @} */ #endif /* __UIPLIB_H__ */ From 5c5545ba7dc1a381d4460131785da03de8d669a0 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 19:47:11 +0100 Subject: [PATCH 10/20] Code style and debugging updates --- core/net/packetbuf.c | 2 +- core/net/sicslowpan.c | 2 +- core/net/tcpip.c | 6 +++--- core/net/uip-icmp6.c | 4 ++-- core/net/uip6.c | 26 ++++++++++++++++---------- 5 files changed, 23 insertions(+), 17 deletions(-) diff --git a/core/net/packetbuf.c b/core/net/packetbuf.c index 06f2c0037..82f85377c 100644 --- a/core/net/packetbuf.c +++ b/core/net/packetbuf.c @@ -109,7 +109,7 @@ packetbuf_compact(void) if(packetbuf_is_reference()) { memcpy(&packetbuf[PACKETBUF_HDR_SIZE], packetbuf_reference_ptr(), packetbuf_datalen()); - } else if (bufptr > 0) { + } else if(bufptr > 0) { len = packetbuf_datalen() + PACKETBUF_HDR_SIZE; for(i = PACKETBUF_HDR_SIZE; i < len; i++) { packetbuf[i] = packetbuf[bufptr + i]; diff --git a/core/net/sicslowpan.c b/core/net/sicslowpan.c index c0ceb641e..2bb94574f 100644 --- a/core/net/sicslowpan.c +++ b/core/net/sicslowpan.c @@ -1648,7 +1648,7 @@ input(void) if((frag_size > 0) && (frag_size <= UIP_BUFSIZE)) { sicslowpan_len = frag_size; reass_tag = frag_tag; - timer_set(&reass_timer, SICSLOWPAN_REASS_MAXAGE*CLOCK_SECOND); + timer_set(&reass_timer, SICSLOWPAN_REASS_MAXAGE * CLOCK_SECOND / 16); PRINTFI("sicslowpan input: INIT FRAGMENTATION (len %d, tag %d)\n", sicslowpan_len, reass_tag); rimeaddr_copy(&frag_sender, packetbuf_addr(PACKETBUF_ADDR_SENDER)); diff --git a/core/net/tcpip.c b/core/net/tcpip.c index 018a6a982..4b178a1db 100644 --- a/core/net/tcpip.c +++ b/core/net/tcpip.c @@ -373,7 +373,7 @@ eventhandler(process_event_t ev, process_data_t data) register struct listenport *l; #endif /*UIP_TCP*/ struct process *p; - + switch(ev) { case PROCESS_EVENT_EXITED: /* This is the event we get if a process has exited. We go through @@ -471,13 +471,13 @@ eventhandler(process_event_t ev, process_data_t data) }*/ #if !UIP_CONF_ROUTER if(data == &uip_ds6_timer_rs && - etimer_expired(&uip_ds6_timer_rs)){ + etimer_expired(&uip_ds6_timer_rs)) { uip_ds6_send_rs(); tcpip_ipv6_output(); } #endif /* !UIP_CONF_ROUTER */ if(data == &uip_ds6_timer_periodic && - etimer_expired(&uip_ds6_timer_periodic)){ + etimer_expired(&uip_ds6_timer_periodic)) { uip_ds6_periodic(); tcpip_ipv6_output(); } diff --git a/core/net/uip-icmp6.c b/core/net/uip-icmp6.c index 4d6ae90b3..59a71013d 100644 --- a/core/net/uip-icmp6.c +++ b/core/net/uip-icmp6.c @@ -102,7 +102,7 @@ uip_icmp6_echo_request_input(void) if(uip_ext_len > 0) { #if UIP_CONF_IPV6_RPL - if ((temp_ext_len=rpl_invert_header())) { + if((temp_ext_len = rpl_invert_header())) { /* If there were other extension headers*/ UIP_FIRST_EXT_BUF->next = UIP_PROTO_ICMP6; if (uip_ext_len != temp_ext_len) { @@ -118,7 +118,7 @@ uip_icmp6_echo_request_input(void) (uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN, (uip_len - UIP_IPH_LEN - temp_ext_len - UIP_ICMPH_LEN)); } - uip_ext_len=temp_ext_len; + uip_ext_len = temp_ext_len; } else { #endif /* UIP_CONF_IPV6_RPL */ /* If there were extension headers*/ diff --git a/core/net/uip6.c b/core/net/uip6.c index e18defdec..af6f442e0 100644 --- a/core/net/uip6.c +++ b/core/net/uip6.c @@ -855,7 +855,7 @@ ext_hdr_options_process(void) case UIP_EXT_HDR_OPT_RPL: PRINTF("Processing RPL option\n"); if(rpl_verify_header(uip_ext_opt_offset)) { - PRINTF("RPL Option Error : Dropping Packet"); + PRINTF("RPL Option Error: Dropping Packet\n"); return 1; } uip_ext_opt_offset += (UIP_EXT_HDR_OPT_RPL_BUF->opt_len) + 2; @@ -1123,17 +1123,19 @@ uip_process(uint8_t flag) if(*uip_next_hdr == UIP_PROTO_HBHO) { #if UIP_CONF_IPV6_CHECKS uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO; -#endif /*UIP_CONF_IPV6_CHECKS*/ +#endif /* UIP_CONF_IPV6_CHECKS */ switch(ext_hdr_options_process()) { case 0: - /*continue*/ + /* continue */ uip_next_hdr = &UIP_EXT_BUF->next; uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; break; case 1: - /*silently discard*/ + PRINTF("Dropping packet after extension header processing\n"); + /* silently discard */ goto drop; case 2: + PRINTF("Sending error message after extension header processing\n"); /* send icmp error message (created in ext_hdr_options_process) * and discard*/ goto send; @@ -1448,6 +1450,11 @@ uip_process(uint8_t flag) #if UIP_UDP_CHECKSUMS uip_len = uip_len - UIP_IPUDPH_LEN; uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN]; + /* XXX hack: UDP/IPv6 receivers should drop packets with UDP + checksum 0. Here, we explicitly receive UDP packets with checksum + 0. This is to be able to debug code that for one reason or + another miscomputes UDP checksums. The reception of zero UDP + checksums should be turned into a configration option. */ if(UIP_UDP_BUF->udpchksum != 0 && uip_udpchksum() != 0xffff) { UIP_STAT(++uip_stat.udp.drop); UIP_STAT(++uip_stat.udp.chkerr); @@ -2211,19 +2218,18 @@ uip_process(uint8_t flag) UIP_TCP_BUF->seqno[3] = uip_connr->snd_nxt[3]; UIP_IP_BUF->proto = UIP_PROTO_TCP; - + UIP_TCP_BUF->srcport = uip_connr->lport; UIP_TCP_BUF->destport = uip_connr->rport; - uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_connr->ripaddr); - uip_ds6_select_src(&UIP_IP_BUF->srcipaddr,&UIP_IP_BUF->destipaddr); - PRINTF("Sending TCP packet to"); + uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); + PRINTF("Sending TCP packet to "); PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF("from"); + PRINTF(" from "); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF("\n"); - + if(uip_connr->tcpstateflags & UIP_STOPPED) { /* If the connection has issued uip_stop(), we advertise a zero window so that the remote host will stop sending data. */ From f561bfc205fdd746f9d6307b8f86920ece0b9f8d Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 19:48:27 +0100 Subject: [PATCH 11/20] Added a function simple_udp_sendto_port() for sending a UDP packet to a specified port. --- core/net/simple-udp.c | 28 ++++++++++++++++++++++++++++ core/net/simple-udp.h | 4 ++++ 2 files changed, 32 insertions(+) diff --git a/core/net/simple-udp.c b/core/net/simple-udp.c index 97a39c89b..61197f452 100644 --- a/core/net/simple-udp.c +++ b/core/net/simple-udp.c @@ -113,6 +113,34 @@ simple_udp_sendto(struct simple_udp_connection *c, return 0; } /*---------------------------------------------------------------------------*/ +/** + * \brief Send a UDP packet to a specified IP address and UDP port + * \param c A pointer to a struct simple_udp_connection + * \param data A pointer to the data to be sent + * \param datalen The length of the data + * \param to The IP address of the receiver + * \param port The UDP port of the receiver, in host byte order + * + * This function sends a UDP packet to a specified IP + * address and UDP port. The packet will be sent with the + * UDP ports that were specified when the connection wa + * registered with simple_udp_register(). + * + * \sa simple_udp_sendto() + */ +int +simple_udp_sendto_port(struct simple_udp_connection *c, + const void *data, uint16_t datalen, + const uip_ipaddr_t *to, + uint16_t port) +{ + if(c->udp_conn != NULL) { + uip_udp_packet_sendto(c->udp_conn, data, datalen, + to, UIP_HTONS(port)); + } + return 0; +} +/*---------------------------------------------------------------------------*/ /** * \brief Register a UDP connection * \param c A pointer to a struct simple_udp_connection diff --git a/core/net/simple-udp.h b/core/net/simple-udp.h index 8579dc497..0198c2f10 100644 --- a/core/net/simple-udp.h +++ b/core/net/simple-udp.h @@ -86,6 +86,10 @@ int simple_udp_sendto(struct simple_udp_connection *c, const void *data, uint16_t datalen, const uip_ipaddr_t *to); +int simple_udp_sendto_port(struct simple_udp_connection *c, + const void *data, uint16_t datalen, + const uip_ipaddr_t *to, uint16_t to_port); + void simple_udp_init(void); #endif /* SIMPLE_UDP_H */ From b2063953baeb01f5bd7eb8efd2e319b3f9cfaec2 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 19:49:54 +0100 Subject: [PATCH 12/20] Added a configuration option, UIP_SPLIT_CONF_SIZE, for setting the threshold at which point TCP packets get split into two. --- core/net/uip-split.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/net/uip-split.c b/core/net/uip-split.c index cbcc48e15..4d247e478 100644 --- a/core/net/uip-split.c +++ b/core/net/uip-split.c @@ -43,6 +43,12 @@ #define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) +#ifdef UIP_SPLIT_CONF_SIZE +#define UIP_SPLIT_SIZE UIP_SPLIT_CONF_SIZE +#else /* UIP_SPLIT_CONF_SIZE */ +#define UIP_SPLIT_SIZE UIP_TCP_MSS +#endif /* UIP_SPLIT_CONF_SIZE */ + /*-----------------------------------------------------------------------------*/ void uip_split_output(void) @@ -50,9 +56,11 @@ uip_split_output(void) #if UIP_TCP uint16_t tcplen, len1, len2; - /* We only try to split maximum sized TCP segments. */ + /* We only split TCP segments that are larger than or equal to + UIP_SPLIT_SIZE, which is configurable through + UIP_SPLIT_CONF_SIZE. */ if(BUF->proto == UIP_PROTO_TCP && - uip_len == UIP_TCP_MSS + UIP_TCPIP_HLEN) { + uip_len >= UIP_SPLIT_SIZE + UIP_TCPIP_HLEN) { tcplen = uip_len - UIP_TCPIP_HLEN; /* Split the segment in two. If the original packet length was From afe13b22bc3c29fd80a5b58bc691f5819630c2d8 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 19:53:38 +0100 Subject: [PATCH 13/20] 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); From a9cab81d4e52d3c7818ab5135f01e86571d234d1 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 19:56:16 +0100 Subject: [PATCH 14/20] Added macros that allow handling IPv4 addresses even when uIP is configured to be an IPv6 stack --- core/net/uip.h | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/core/net/uip.h b/core/net/uip.h index d938f9df0..a9aef800d 100644 --- a/core/net/uip.h +++ b/core/net/uip.h @@ -59,21 +59,19 @@ * Representation of an IP address. * */ -#if UIP_CONF_IPV6 +typedef union uip_ip4addr_t { + uint8_t u8[4]; /* Initializer, must come first. */ + uint16_t u16[2]; +} uip_ip4addr_t; + typedef union uip_ip6addr_t { - uint8_t u8[16]; /* Initializer, must come first!!! */ + uint8_t u8[16]; /* Initializer, must come first. */ uint16_t u16[8]; } uip_ip6addr_t; +#if UIP_CONF_IPV6 typedef uip_ip6addr_t uip_ipaddr_t; #else /* UIP_CONF_IPV6 */ -typedef union uip_ip4addr_t { - uint8_t u8[4]; /* Initializer, must come first!!! */ - uint16_t u16[2]; -#if 0 - uint32_t u32; -#endif -} uip_ip4addr_t; typedef uip_ip4addr_t uip_ipaddr_t; #endif /* UIP_CONF_IPV6 */ @@ -988,6 +986,12 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport); #ifndef uip_ipaddr_copy #define uip_ipaddr_copy(dest, src) (*(dest) = *(src)) #endif +#ifndef uip_ip4addr_copy +#define uip_ip4addr_copy(dest, src) (*(dest) = *(src)) +#endif +#ifndef uip_ip6addr_copy +#define uip_ip6addr_copy(dest, src) (*(dest) = *(src)) +#endif /** * Compare two IP addresses @@ -1009,11 +1013,14 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport); * * \hideinitializer */ -#if !UIP_CONF_IPV6 -#define uip_ipaddr_cmp(addr1, addr2) ((addr1)->u16[0] == (addr2)->u16[0] && \ +#define uip_ip4addr_cmp(addr1, addr2) ((addr1)->u16[0] == (addr2)->u16[0] && \ (addr1)->u16[1] == (addr2)->u16[1]) +#define uip_ip6addr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0) + +#if !UIP_CONF_IPV6 +#define uip_ipaddr_cmp(addr1, addr2) uip_ip4addr_cmp(addr1, addr2) #else /* !UIP_CONF_IPV6 */ -#define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0) +#define uip_ipaddr_cmp(addr1, addr2) uip_ip6addr_cmp(addr1, addr2) #endif /* !UIP_CONF_IPV6 */ /** @@ -1040,15 +1047,15 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport); * * \hideinitializer */ -#if !UIP_CONF_IPV6 + #define uip_ipaddr_maskcmp(addr1, addr2, mask) \ (((((uint16_t *)addr1)[0] & ((uint16_t *)mask)[0]) == \ (((uint16_t *)addr2)[0] & ((uint16_t *)mask)[0])) && \ ((((uint16_t *)addr1)[1] & ((uint16_t *)mask)[1]) == \ (((uint16_t *)addr2)[1] & ((uint16_t *)mask)[1]))) -#else + #define uip_ipaddr_prefixcmp(addr1, addr2, length) (memcmp(addr1, addr2, length>>3) == 0) -#endif + /** From 43ecad5a998d15384e4a3bf35f4250fba3559e26 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 19:56:52 +0100 Subject: [PATCH 15/20] Call the route callback API functions. --- core/net/uip-ds6.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/net/uip-ds6.c b/core/net/uip-ds6.c index affec4ac0..238d16495 100644 --- a/core/net/uip-ds6.c +++ b/core/net/uip-ds6.c @@ -423,6 +423,8 @@ uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval) ANNOTATE("#L %u 1\n", ipaddr->u8[sizeof(uip_ipaddr_t) - 1]); + call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr); + return locdefrt; } return NULL; @@ -435,6 +437,8 @@ uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt) if(defrt != NULL) { defrt->isused = 0; 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; } @@ -808,6 +812,8 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, uip_ipaddr_t *nexthop, 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 locroute; @@ -818,6 +824,8 @@ void uip_ds6_route_rm(uip_ds6_route_t *route) { route->isused = 0; + 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) */ @@ -843,8 +851,8 @@ uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop) locroute->isused = 0; } } - ANNOTATE("#L %u 0\n",nexthop->u8[sizeof(uip_ipaddr_t) - 1]); -} + call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM, + &locroute->ipaddr, &locroute->nexthop); ANNOTATE("#L %u 0\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]); } From 5406dd8b1824259bd0dbcb5594321f4d93c92e55 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 19:58:52 +0100 Subject: [PATCH 16/20] Updated to use the new uip-ds6-route API --- .../ipv6/rpl-border-router/border-router.c | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/examples/ipv6/rpl-border-router/border-router.c b/examples/ipv6/rpl-border-router/border-router.c index 3c3a60de5..9a40f84a1 100644 --- a/examples/ipv6/rpl-border-router/border-router.c +++ b/examples/ipv6/rpl-border-router/border-router.c @@ -57,7 +57,6 @@ uint16_t dag_id[] = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011}; extern uip_ds6_nbr_t uip_ds6_nbr_cache[]; -extern uip_ds6_route_t uip_ds6_routing_table[]; static uip_ipaddr_t prefix; static uint8_t prefix_set; @@ -149,6 +148,7 @@ static PT_THREAD(generate_routes(struct httpd_state *s)) { static int i; + static uip_ds6_route_t *r; #if BUF_USES_STACK char buf[256]; #endif @@ -220,45 +220,45 @@ PT_THREAD(generate_routes(struct httpd_state *s)) #else blen = 0; #endif - for(i = 0; i < UIP_DS6_ROUTE_NB; i++) { - if(uip_ds6_routing_table[i].isused) { + + for(r = uip_ds6_route_list_head(); r != NULL; r = list_item_next(r)) { + #if BUF_USES_STACK #if WEBSERVER_CONF_ROUTE_LINKS - ADD(""); - ipaddr_add(&uip_ds6_routing_table[i].ipaddr); - ADD(""); + ADD("ipaddr); + ADD("]/status.shtml>"); + ipaddr_add(&r->ipaddr); + ADD(""); #else - ipaddr_add(&uip_ds6_routing_table[i].ipaddr); + ipaddr_add(&r->ipaddr); #endif #else #if WEBSERVER_CONF_ROUTE_LINKS - ADD(""); - SEND_STRING(&s->sout, buf); //TODO: why tunslip6 needs an output here, wpcapslip does not - blen = 0; - ipaddr_add(&uip_ds6_routing_table[i].ipaddr); - ADD(""); + ADD("ipaddr); + ADD("]/status.shtml>"); + SEND_STRING(&s->sout, buf); //TODO: why tunslip6 needs an output here, wpcapslip does not + blen = 0; + ipaddr_add(&r->ipaddr); + ADD(""); #else - ipaddr_add(&uip_ds6_routing_table[i].ipaddr); + ipaddr_add(&r->ipaddr); #endif #endif - ADD("/%u (via ", uip_ds6_routing_table[i].length); - ipaddr_add(&uip_ds6_routing_table[i].nexthop); - if(1 || (uip_ds6_routing_table[i].state.lifetime < 600)) { - ADD(") %lus\n", uip_ds6_routing_table[i].state.lifetime); - } else { - ADD(")\n"); - } - SEND_STRING(&s->sout, buf); -#if BUF_USES_STACK - bufptr = buf; bufend = bufptr + sizeof(buf); -#else - blen = 0; -#endif + ADD("/%u (via ", r->length); + ipaddr_add(&r->nexthop); + if(1 || (r->state.lifetime < 600)) { + ADD(") %lus\n", r->state.lifetime); + } else { + ADD(")\n"); } + SEND_STRING(&s->sout, buf); +#if BUF_USES_STACK + bufptr = buf; bufend = bufptr + sizeof(buf); +#else + blen = 0; +#endif } ADD(""); From 4218a733c9b6452e3145bfd5db94ba184ba3fadb Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 20:11:14 +0100 Subject: [PATCH 17/20] Add the uipv6 route function uip-ds6-route.c --- Makefile.include | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.include b/Makefile.include index d257eeabb..fa3c9d65a 100644 --- a/Makefile.include +++ b/Makefile.include @@ -69,7 +69,7 @@ ifdef UIP_CONF_IPV6 UIP = uip6.c tcpip.c psock.c uip-udp-packet.c uip-split.c \ resolv.c tcpdump.c uiplib.c simple-udp.c NET += $(UIP) uip-icmp6.c uip-nd6.c uip-packetqueue.c \ - sicslowpan.c neighbor-attr.c neighbor-info.c uip-ds6.c + sicslowpan.c neighbor-attr.c neighbor-info.c uip-ds6.c uip-ds6-route.c ifneq ($(UIP_CONF_RPL),0) CFLAGS += -DUIP_CONF_IPV6_RPL=1 include $(CONTIKI)/core/net/rpl/Makefile.rpl From 99f541e8fd30b9329e04bfc9ed9aa718dc246a3f Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Mon, 26 Nov 2012 21:30:01 +0100 Subject: [PATCH 18/20] Updated to the latest uip-ds6-route API --- apps/webserver/httpd-cgi.c | 34 ++++++++++--------- .../ipv6/native-border-router/border-router.c | 25 +++++++------- examples/ipv6/rpl-collect/udp-sender.c | 13 ++++--- platform/avr-atmega128rfa1/contiki-main.c | 25 ++++++++------ .../apps/raven-webserver/httpd-cgi.c | 34 ++++++++++--------- platform/avr-raven/contiki-raven-main.c | 26 ++++++++------ .../redbee-econotag/contiki-mc1322x-main.c | 27 +++++++++------ 7 files changed, 101 insertions(+), 83 deletions(-) diff --git a/apps/webserver/httpd-cgi.c b/apps/webserver/httpd-cgi.c index f1cf87bbf..85ce3a521 100644 --- a/apps/webserver/httpd-cgi.c +++ b/apps/webserver/httpd-cgi.c @@ -307,23 +307,25 @@ PT_THREAD(neighbors(struct httpd_state *s, char *ptr)) static unsigned short make_routes(void *p) { -static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR = "(%u (via "; -static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR = ") %us
"; -static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")
"; -uint8_t i,j=0; -uint16_t numprinted; + static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR = "(%u (via "; + static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR = ") %lus
"; + static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")
"; + uint8_t i,j=0; + uint16_t numprinted; + uip_ds6_route_t *r; + numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh); - for (i=0; iipaddr, uip_appdata + numprinted); + numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, r->length); + numprinted += httpd_cgi_sprint_ip6(r->nexthop, uip_appdata + numprinted); + if(r->state.lifetime < 3600) { + numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, r->state.lifetime); + } else { + numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes3); } } if (j==0) numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrn); diff --git a/examples/ipv6/native-border-router/border-router.c b/examples/ipv6/native-border-router/border-router.c index e3f5af2ac..b8d01f2bb 100644 --- a/examples/ipv6/native-border-router/border-router.c +++ b/examples/ipv6/native-border-router/border-router.c @@ -149,6 +149,7 @@ static PT_THREAD(generate_routes(struct httpd_state *s)) { static int i; + static uip_ds6_route_t *r; PSOCK_BEGIN(&s->sout); SEND_STRING(&s->sout, TOP); @@ -169,19 +170,19 @@ PT_THREAD(generate_routes(struct httpd_state *s)) ADD("Routes
");
   SEND_STRING(&s->sout, buf);
   blen = 0;
-  for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
-    if(uip_ds6_routing_table[i].isused) {
-      ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
-      ADD("/%u (via ", uip_ds6_routing_table[i].length);
-      ipaddr_add(&uip_ds6_routing_table[i].nexthop);
-      if(uip_ds6_routing_table[i].state.lifetime < 600) {
-        ADD(") %lus\n", (unsigned long)uip_ds6_routing_table[i].state.lifetime);
-      } else {
-        ADD(")\n");
-      }
-      SEND_STRING(&s->sout, buf);
-      blen = 0;
+  for(r = uip_ds6_route_list_head();
+      r != NULL;
+      r = list_item_next(r)) {
+    ipaddr_add(&r->ipaddr);
+    ADD("/%u (via ", r->length);
+    ipaddr_add(&r->nexthop);
+    if(r->state.lifetime < 600) {
+      ADD(") %lus\n", (unsigned long)r->state.lifetime);
+    } else {
+      ADD(")\n");
     }
+    SEND_STRING(&s->sout, buf);
+    blen = 0;
   }
   ADD("
"); //if(blen > 0) { diff --git a/examples/ipv6/rpl-collect/udp-sender.c b/examples/ipv6/rpl-collect/udp-sender.c index fa5c80790..113afdc4a 100644 --- a/examples/ipv6/rpl-collect/udp-sender.c +++ b/examples/ipv6/rpl-collect/udp-sender.c @@ -70,7 +70,8 @@ void collect_common_net_print(void) { rpl_dag_t *dag; - int i; + uip_ds6_route_t *r; + /* Let's suppose we have only one instance */ dag = rpl_get_any_dag(); if(dag->preferred_parent != NULL) { @@ -78,12 +79,10 @@ collect_common_net_print(void) PRINT6ADDR(&dag->preferred_parent->addr); PRINTF("\n"); } - PRINTF("Route entries:\n"); - for(i = 0; i < UIP_DS6_ROUTE_NB; i++) { - if(uip_ds6_routing_table[i].isused) { - PRINT6ADDR(&uip_ds6_routing_table[i].ipaddr); - PRINTF("\n"); - } + for(r = uip_ds6_route_list_head(); + r != NULL; + r = list_item_next(r)) { + PRINT6ADDR(&r->ipaddr); } PRINTF("---\n"); } diff --git a/platform/avr-atmega128rfa1/contiki-main.c b/platform/avr-atmega128rfa1/contiki-main.c index 995960151..05a9ee392 100644 --- a/platform/avr-atmega128rfa1/contiki-main.c +++ b/platform/avr-atmega128rfa1/contiki-main.c @@ -536,17 +536,22 @@ extern uip_ds6_netif_t uip_ds6_if; } if (j) PRINTF(" "); PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); - for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) { - if(uip_ds6_routing_table[i].isused) { - ipaddr_add(&uip_ds6_routing_table[i].ipaddr); - PRINTF("/%u (via ", uip_ds6_routing_table[i].length); - ipaddr_add(&uip_ds6_routing_table[i].nexthop); + { + uip_ds6_route_t *r; + PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); + j = 1; + for(r = uip_ds6_route_list_head(); + r != NULL; + r = list_item_next(r)) { + ipaddr_add(&r->ipaddr); + PRINTF("/%u (via ", r->length); + ipaddr_add(&r->nexthop); // if(uip_ds6_routing_table[i].state.lifetime < 600) { - PRINTF(") %lus\n", uip_ds6_routing_table[i].state.lifetime); - // } else { - // PRINTF(")\n"); - // } - j=0; + PRINTF(") %lus\n", r->state.lifetime); + // } else { + // PRINTF(")\n"); + // } + j = 0; } } if (j) PRINTF(" "); diff --git a/platform/avr-raven/apps/raven-webserver/httpd-cgi.c b/platform/avr-raven/apps/raven-webserver/httpd-cgi.c index 793aefbe3..a9ed784f8 100644 --- a/platform/avr-raven/apps/raven-webserver/httpd-cgi.c +++ b/platform/avr-raven/apps/raven-webserver/httpd-cgi.c @@ -354,23 +354,25 @@ PT_THREAD(neighbors(struct httpd_state *s, char *ptr)) static unsigned short make_routes(void *p) { -static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR = "(%u (via "; -static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR = ") %lus
"; -static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")
"; -uint8_t i,j=0; -uint16_t numprinted; + static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR = "(%u (via "; + static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR = ") %lus
"; + static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")
"; + uint8_t i,j=0; + uint16_t numprinted; + uip_ds6_route_t *r; + numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh); - for (i=0; iipaddr, uip_appdata + numprinted); + numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, r->length); + numprinted += httpd_cgi_sprint_ip6(r->nexthop, uip_appdata + numprinted); + if(r->state.lifetime < 3600) { + numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, r->state.lifetime); + } else { + numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes3); } } if (j==0) numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrn); diff --git a/platform/avr-raven/contiki-raven-main.c b/platform/avr-raven/contiki-raven-main.c index 1d939ebc9..c9521c124 100644 --- a/platform/avr-raven/contiki-raven-main.c +++ b/platform/avr-raven/contiki-raven-main.c @@ -531,18 +531,22 @@ extern uip_ds6_netif_t uip_ds6_if; } } if (j) PRINTF(" "); - PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); - for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) { - if(uip_ds6_routing_table[i].isused) { - ipaddr_add(&uip_ds6_routing_table[i].ipaddr); - PRINTF("/%u (via ", uip_ds6_routing_table[i].length); - ipaddr_add(&uip_ds6_routing_table[i].nexthop); + { + uip_ds6_route_t *r; + PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); + j = 1; + for(r = uip_ds6_route_list_head(); + r != NULL; + r = list_item_next(r)) { + ipaddr_add(&r->ipaddr); + PRINTF("/%u (via ", r->length); + ipaddr_add(&r->nexthop); // if(uip_ds6_routing_table[i].state.lifetime < 600) { - PRINTF(") %lus\n", uip_ds6_routing_table[i].state.lifetime); - // } else { - // PRINTF(")\n"); - // } - j=0; + PRINTF(") %lus\n", r->state.lifetime); + // } else { + // PRINTF(")\n"); + // } + j = 0; } } if (j) PRINTF(" "); diff --git a/platform/redbee-econotag/contiki-mc1322x-main.c b/platform/redbee-econotag/contiki-mc1322x-main.c index f3bc8f5a3..d43d34661 100644 --- a/platform/redbee-econotag/contiki-mc1322x-main.c +++ b/platform/redbee-econotag/contiki-mc1322x-main.c @@ -614,18 +614,23 @@ extern uip_ds6_netif_t uip_ds6_if; } } if (j) printf(" "); - printf("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); - for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) { - if(uip_ds6_routing_table[i].isused) { - uip_debug_ipaddr_print(&uip_ds6_routing_table[i].ipaddr); - printf("/%u (via ", uip_ds6_routing_table[i].length); - uip_debug_ipaddr_print(&uip_ds6_routing_table[i].nexthop); + PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); + { + uip_ds6_route_t *r; + PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); + j = 1; + for(r = uip_ds6_route_list_head(); + r != NULL; + r = list_item_next(r)) { + ipaddr_add(&r->ipaddr); + PRINTF("/%u (via ", r->length); + ipaddr_add(&r->nexthop); // if(uip_ds6_routing_table[i].state.lifetime < 600) { - printf(") %lus\n", uip_ds6_routing_table[i].state.lifetime); - // } else { - // printf(")\n"); - // } - j=0; + PRINTF(") %lus\n", r->state.lifetime); + // } else { + // PRINTF(")\n"); + // } + j = 0; } } if (j) printf(" "); From edf141046bf5e68720ff35251ac57504a12bdbcb Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Tue, 27 Nov 2012 23:01:10 +0100 Subject: [PATCH 19/20] Clean up of a few missing printf() that were converted into PRINTF()s --- core/net/rpl/rpl-dag.c | 2 +- core/net/uip-ds6-route.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 02188d6d1..9cca22b12 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -721,7 +721,7 @@ rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent) PRINTF("RPL: Removing default route "); PRINT6ADDR(&parent->addr); PRINTF("\n"); - printf("rpl_move_parent\n"); + PRINTF("rpl_move_parent\n"); uip_ds6_defrt_rm(dag_src->instance->def_route); dag_src->instance->def_route = NULL; } diff --git a/core/net/uip-ds6-route.c b/core/net/uip-ds6-route.c index 851c86e72..a83c28ffb 100644 --- a/core/net/uip-ds6-route.c +++ b/core/net/uip-ds6-route.c @@ -172,7 +172,7 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, } list_add(routelist, r); - // printf("uip_ds6_route_add num %d\n", list_length(routelist)); + PRINTF("uip_ds6_route_add num %d\n", list_length(routelist)); } uip_ipaddr_copy(&(r->ipaddr), ipaddr); @@ -209,7 +209,7 @@ uip_ds6_route_rm(uip_ds6_route_t *route) list_remove(routelist, route); memb_free(&routememb, route); - // printf("uip_ds6_route_rm num %d\n", list_length(routelist)); + PRINTF("uip_ds6_route_rm num %d\n", list_length(routelist)); call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM, &route->ipaddr, &route->nexthop); @@ -358,7 +358,7 @@ uip_ds6_defrt_periodic(void) while(d != NULL) { if(!d->isinfinite && stimer_expired(&d->lifetime)) { - printf("defrt lifetime expired\n"); + PRINTF("uip_ds6_defrt_periodic: defrt lifetime expired\n"); uip_ds6_defrt_rm(d); d = list_head(defaultrouterlist); } else { From 83eb9a4ec3c0f4ec8da9cc02669fcd9de91e5286 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Tue, 27 Nov 2012 23:02:34 +0100 Subject: [PATCH 20/20] Cleanup: removed the old routing table management functions that had previously been removed from compilation with #if 0 --- core/net/uip-ds6.c | 191 --------------------------------------------- 1 file changed, 191 deletions(-) diff --git a/core/net/uip-ds6.c b/core/net/uip-ds6.c index 238d16495..16cc67606 100644 --- a/core/net/uip-ds6.c +++ b/core/net/uip-ds6.c @@ -400,91 +400,6 @@ 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) -{ - if(uip_ds6_list_loop - ((uip_ds6_element_t *)uip_ds6_defrt_list, UIP_DS6_DEFRT_NB, - sizeof(uip_ds6_defrt_t), ipaddr, 128, - (uip_ds6_element_t **)&locdefrt) == FREESPACE) { - locdefrt->isused = 1; - uip_ipaddr_copy(&locdefrt->ipaddr, ipaddr); - if(interval != 0) { - stimer_set(&locdefrt->lifetime, interval); - locdefrt->isinfinite = 0; - } else { - locdefrt->isinfinite = 1; - } - - PRINTF("Adding defrouter with ip addr "); - PRINT6ADDR(&locdefrt->ipaddr); - PRINTF("\n"); - - ANNOTATE("#L %u 1\n", ipaddr->u8[sizeof(uip_ipaddr_t) - 1]); - - call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr); - - return locdefrt; - } - return NULL; -} - -/*---------------------------------------------------------------------------*/ -void -uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt) -{ - if(defrt != NULL) { - defrt->isused = 0; - 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) -{ - if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_defrt_list, - UIP_DS6_DEFRT_NB, sizeof(uip_ds6_defrt_t), ipaddr, 128, - (uip_ds6_element_t **)&locdefrt) == FOUND) { - return locdefrt; - } - return NULL; -} - -/*---------------------------------------------------------------------------*/ -uip_ipaddr_t * -uip_ds6_defrt_choose(void) -{ - uip_ds6_nbr_t *bestnbr; - - locipaddr = NULL; - for(locdefrt = uip_ds6_defrt_list; - locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) { - if(locdefrt->isused) { - PRINTF("Defrt, IP address "); - PRINT6ADDR(&locdefrt->ipaddr); - PRINTF("\n"); - bestnbr = uip_ds6_nbr_lookup(&locdefrt->ipaddr); - if(bestnbr != NULL && bestnbr->state != NBR_INCOMPLETE) { - PRINTF("Defrt found, IP address "); - PRINT6ADDR(&locdefrt->ipaddr); - PRINTF("\n"); - return &locdefrt->ipaddr; - } else { - locipaddr = &locdefrt->ipaddr; - PRINTF("Defrt INCOMPLETE found, IP address "); - PRINT6ADDR(&locdefrt->ipaddr); - PRINTF("\n"); - } - } - } - return locipaddr; -} -#endif /* 0 */ #if UIP_CONF_ROUTER /*---------------------------------------------------------------------------*/ uip_ds6_prefix_t * @@ -751,112 +666,6 @@ uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr) return NULL; } -/*---------------------------------------------------------------------------*/ -#if 0 -uip_ds6_route_t * -uip_ds6_route_lookup(uip_ipaddr_t *destipaddr) -{ - uip_ds6_route_t *locrt = NULL; - uint8_t longestmatch = 0; - - PRINTF("DS6: Looking up route for "); - PRINT6ADDR(destipaddr); - PRINTF("\n"); - - for(locroute = uip_ds6_routing_table; - locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; locroute++) { - if((locroute->isused) && (locroute->length >= longestmatch) - && - (uip_ipaddr_prefixcmp - (destipaddr, &locroute->ipaddr, locroute->length))) { - longestmatch = locroute->length; - locrt = locroute; - } - } - - if(locrt != NULL) { - PRINTF("DS6: Found route:"); - PRINT6ADDR(destipaddr); - PRINTF(" via "); - PRINT6ADDR(&locrt->nexthop); - PRINTF("\n"); - } else { - PRINTF("DS6: No route found\n"); - } - - return locrt; -} - -/*---------------------------------------------------------------------------*/ -uip_ds6_route_t * -uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, uip_ipaddr_t *nexthop, - uint8_t metric) -{ - if(uip_ds6_list_loop - ((uip_ds6_element_t *)uip_ds6_routing_table, UIP_DS6_ROUTE_NB, - sizeof(uip_ds6_route_t), ipaddr, length, - (uip_ds6_element_t **)&locroute) == FREESPACE) { - locroute->isused = 1; - uip_ipaddr_copy(&(locroute->ipaddr), ipaddr); - locroute->length = length; - uip_ipaddr_copy(&(locroute->nexthop), nexthop); - locroute->metric = metric; - -#ifdef UIP_DS6_ROUTE_STATE_TYPE - memset(&locroute->state, 0, sizeof(UIP_DS6_ROUTE_STATE_TYPE)); -#endif - - PRINTF("DS6: 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 locroute; -} - -/*---------------------------------------------------------------------------*/ -void -uip_ds6_route_rm(uip_ds6_route_t *route) -{ - route->isused = 0; - 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(locroute = uip_ds6_routing_table; - locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; - locroute++) { - if(locroute->isused && uip_ipaddr_cmp(&locroute->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 -} -/*---------------------------------------------------------------------------*/ -void -uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop) -{ - for(locroute = uip_ds6_routing_table; - locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; - locroute++) { - if(locroute->isused && uip_ipaddr_cmp(&locroute->nexthop, nexthop)) { - locroute->isused = 0; - } - } - call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM, - &locroute->ipaddr, &locroute->nexthop); - - 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)