diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index f1b13d684..09b900a54 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -191,8 +191,8 @@ rpl_set_root(uip_ipaddr_t *dag_id) dag->max_rankinc = DEFAULT_MAX_RANKINC; dag->min_hoprankinc = DEFAULT_MIN_HOPRANKINC; - dag->default_lifetime = DEFAULT_RPL_DEF_LIFETIME; - dag->lifetime_unit = DEFAULT_RPL_LIFETIME_UNIT; + dag->default_lifetime = RPL_DEFAULT_LIFETIME; + dag->lifetime_unit = RPL_DEFAULT_LIFETIME_UNIT; dag->rank = ROOT_RANK(dag); @@ -238,11 +238,9 @@ rpl_set_default_route(rpl_dag_t *dag, uip_ipaddr_t *from) PRINTF("RPL: Adding default route through "); PRINT6ADDR(from); PRINTF("\n"); - if(DEFAULT_ROUTE_LIFETIME == INFINITE_LIFETIME) { - dag->def_route = uip_ds6_defrt_add(from, 0); - } else { - dag->def_route = uip_ds6_defrt_add(from, DEFAULT_ROUTE_LIFETIME); - } + dag->def_route = uip_ds6_defrt_add(from, + RPL_LIFETIME(dag, + dag->default_lifetime)); if(dag->def_route == NULL) { return 0; } diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index bd39a5405..d63b5c3c1 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -467,7 +467,7 @@ dao_input(void) unsigned char *buffer; uint16_t sequence; uint8_t instance_id; - uint32_t lifetime; + rpl_lifetime_t lifetime; uint8_t prefixlen; uint8_t flags; uint8_t subopt_type; @@ -482,7 +482,6 @@ dao_input(void) int learned_from; rpl_parent_t *p; - lifetime = 0; prefixlen = 0; uip_ipaddr_copy(&dao_sender_addr, &UIP_IP_BUF->srcipaddr); @@ -495,7 +494,7 @@ dao_input(void) buffer = UIP_ICMP_PAYLOAD; buffer_length = uip_len - uip_l2_l3_icmp_hdr_len; #if RPL_CONF_ADJUST_LLH_LEN - buffer_length+=UIP_LLH_LEN; //Add jackdaw, minimal-net ethernet header + buffer_length += UIP_LLH_LEN; /* Add jackdaw, minimal-net ethernet header */ #endif pos = 0; @@ -508,6 +507,8 @@ dao_input(void) return; } + lifetime = dag->default_lifetime; + flags = buffer[pos++]; /* reserved */ pos++; @@ -515,19 +516,19 @@ dao_input(void) /* Is the DAGID present? */ if(flags & RPL_DAO_D_FLAG) { - /* currently the DAG ID is ignored since we only use global - RPL Instance IDs... */ + /* Currently the DAG ID is ignored since we only use global + RPL Instance IDs. */ pos += 16; } - /* Check if there are any DIO suboptions. */ + /* Check if there are any DIO sub-options. */ i = pos; for(; i < buffer_length; i += len) { subopt_type = buffer[i]; if(subopt_type == RPL_DIO_SUBOPT_PAD1) { len = 1; } else { - /* Suboption with a two-byte header + payload */ + /* Sub-option with a two-byte header and payload */ len = 2 + buffer[i + 1]; } @@ -539,23 +540,24 @@ dao_input(void) memcpy(&prefix, buffer + i + 4, (prefixlen + 7) / CHAR_BIT); break; case RPL_DIO_SUBOPT_TRANSIT: - /* path sequence and control ignored */ + /* The path sequence and control are ignored. */ pathcontrol = buffer[i + 3]; pathsequence = buffer[i + 4]; lifetime = buffer[i + 5]; - /* parent address also ignored */ + /* The parent address is also ignored. */ break; } } - PRINTF("RPL: DAO lifetime: %lu, prefix length: %u prefix: ", - (unsigned long)lifetime, (unsigned)prefixlen); + PRINTF("RPL: DAO lifetime: %u, prefix length: %u prefix: ", + (unsigned)lifetime, (unsigned)prefixlen); PRINT6ADDR(&prefix); PRINTF("\n"); + rep = uip_ds6_route_lookup(&prefix); + if(lifetime == ZERO_LIFETIME) { /* No-Path DAO received; invoke the route purging routine. */ - rep = uip_ds6_route_lookup(&prefix); if(rep != NULL && rep->state.saved_lifetime == 0) { PRINTF("RPL: Setting expiration timer for prefix "); PRINT6ADDR(&prefix); @@ -570,12 +572,9 @@ dao_input(void) RPL_ROUTE_FROM_MULTICAST_DAO : RPL_ROUTE_FROM_UNICAST_DAO; if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) { - /* Check if this is a DAO forwarding loop. */ + /* Check whether this is a DAO forwarding loop. */ p = rpl_find_parent(dag, &dao_sender_addr); - /* check if this is a new DAO registration with an "illegal" rank */ - /* if we already route to this node it is likely */ - if(p != NULL && DAG_RANK(p->rank, dag) < DAG_RANK(dag->rank, dag) - /* && uip_ds6_route_lookup(&prefix) == NULL*/) { + if(p != NULL && DAG_RANK(p->rank, dag) < DAG_RANK(dag->rank, dag)) { PRINTF("RPL: Loop detected when receiving a unicast DAO from a node with a lower rank! (%u < %u)\n", DAG_RANK(p->rank, dag), DAG_RANK(dag->rank, dag)); p->rank = INFINITE_RANK; @@ -584,16 +583,18 @@ dao_input(void) } } - rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr); if(rep == NULL) { - RPL_STAT(rpl_stats.mem_overflows++); - PRINTF("RPL: Could not add a route after receiving a DAO\n"); - return; - } else { - rep->state.lifetime = lifetime * dag->lifetime_unit; - rep->state.learned_from = learned_from; + rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr); + if(rep == NULL) { + RPL_STAT(rpl_stats.mem_overflows++); + PRINTF("RPL: Could not add a route after receiving a DAO\n"); + return; + } } + rep->state.lifetime = RPL_LIFETIME(dag, lifetime); + rep->state.learned_from = learned_from; + if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) { if(dag->preferred_parent) { PRINTF("RPL: Forwarding DAO to parent "); @@ -608,7 +609,7 @@ dao_input(void) } /*---------------------------------------------------------------------------*/ void -dao_output(rpl_parent_t *n, uint32_t lifetime) +dao_output(rpl_parent_t *n, rpl_lifetime_t lifetime) { rpl_dag_t *dag; unsigned char *buffer; @@ -656,13 +657,13 @@ dao_output(rpl_parent_t *n, uint32_t lifetime) memcpy(buffer + pos, &prefix, (prefixlen + 7) / CHAR_BIT); pos += ((prefixlen + 7) / CHAR_BIT); - /* create a transit information subopt (RPL-18)*/ + /* Create a transit information sub-option. */ buffer[pos++] = RPL_DIO_SUBOPT_TRANSIT; buffer[pos++] = 4; buffer[pos++] = 0; /* flags - ignored */ buffer[pos++] = 0; /* path control - ignored */ buffer[pos++] = 0; /* path seq - ignored */ - buffer[pos++] = (lifetime / dag->lifetime_unit) & 0xff; + buffer[pos++] = lifetime; if(n == NULL) { uip_create_linklocal_rplnodes_mcast(&addr); diff --git a/core/net/rpl/rpl-private.h b/core/net/rpl/rpl-private.h index 4363c55ad..db3ef8515 100644 --- a/core/net/rpl/rpl-private.h +++ b/core/net/rpl/rpl-private.h @@ -101,14 +101,14 @@ /* Special value indicating immediate removal. */ #define ZERO_LIFETIME 0 -/* Special value indicating that a DAO should not expire. */ -#define INFINITE_LIFETIME 0xffffffff +/* Default route lifetime unit. */ +#define RPL_DEFAULT_LIFETIME_UNIT 0xffff -/* Default route lifetime in seconds. */ -#define DEFAULT_ROUTE_LIFETIME INFINITE_LIFETIME +/* Default route lifetime as a multiple of the lifetime unit. */ +#define RPL_DEFAULT_LIFETIME 0xff -#define DEFAULT_RPL_LIFETIME_UNIT 0xffff -#define DEFAULT_RPL_DEF_LIFETIME 0xff +#define RPL_LIFETIME(dag, lifetime) \ + ((unsigned long)(dag)->lifetime_unit * lifetime) #ifndef RPL_CONF_MIN_HOPRANKINC #define DEFAULT_MIN_HOPRANKINC 256 @@ -207,7 +207,7 @@ struct rpl_dio { uint8_t dag_intdoubl; uint8_t dag_intmin; uint8_t dag_redund; - uint8_t default_lifetime; + rpl_lifetime_t default_lifetime; uint16_t lifetime_unit; rpl_rank_t dag_max_rankinc; rpl_rank_t dag_min_hoprankinc; @@ -243,7 +243,7 @@ extern rpl_stats_t rpl_stats; /* ICMPv6 functions for RPL. */ void dis_output(uip_ipaddr_t *addr); void dio_output(rpl_dag_t *, uip_ipaddr_t *uc_addr); -void dao_output(rpl_parent_t *, uint32_t lifetime); +void dao_output(rpl_parent_t *, rpl_lifetime_t lifetime); void dao_ack_output(rpl_dag_t *, uip_ipaddr_t *, uint8_t); void uip_rpl_input(void); diff --git a/core/net/rpl/rpl-timers.c b/core/net/rpl/rpl-timers.c index aa5e6d086..dbb7d2392 100644 --- a/core/net/rpl/rpl-timers.c +++ b/core/net/rpl/rpl-timers.c @@ -201,14 +201,13 @@ handle_dao_timer(void *ptr) return; } - /* Send the DAO to the best parent. rpl-07 section C.2 lists the - fan-out as being under investigation. */ + /* Send the DAO to the DAO parent set -- the preferred parent in our case. */ if(dag->preferred_parent != NULL) { PRINTF("RPL: handle_dao_timer - sending DAO\n"); - /* set time to maxtime */ - dao_output(dag->preferred_parent, dag->lifetime_unit * 0xffUL); + /* Set the route lifetime to the default value. */ + dao_output(dag->preferred_parent, dag->default_lifetime); } else { - PRINTF("RPL: Could not find a parent to send a DAO to \n"); + PRINTF("RPL: No suitable DAO parent\n"); } ctimer_stop(&dag->dao_timer); } diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c index b41fbeea7..7c5e05d21 100644 --- a/core/net/rpl/rpl.c +++ b/core/net/rpl/rpl.c @@ -107,7 +107,7 @@ rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len, uip_ipaddr_copy(&rep->nexthop, next_hop); } rep->state.dag = dag; - rep->state.lifetime = DEFAULT_ROUTE_LIFETIME; + rep->state.lifetime = RPL_LIFETIME(dag, dag->default_lifetime); rep->state.learned_from = RPL_ROUTE_FROM_INTERNAL; PRINTF("RPL: Added a route to "); diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index c55ee6cd0..af16326d9 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -83,6 +83,7 @@ #define RPL_PARENT_COUNT(dag) list_length((dag)->parents) /*---------------------------------------------------------------------------*/ typedef uint16_t rpl_rank_t; +typedef uint8_t rpl_lifetime_t; typedef uint16_t rpl_ocp_t; /*---------------------------------------------------------------------------*/