From 34b8313fb6d07b38e9869b657b98ecc8b787f53a Mon Sep 17 00:00:00 2001 From: joxe Date: Tue, 25 May 2010 19:19:43 +0000 Subject: [PATCH] added experimental support for disseminating autoconf prefix via DIO suboption --- core/net/rpl/rpl-dag.c | 23 +++++++++++++++- core/net/rpl/rpl-icmp6.c | 57 +++++++++++++++++++++++++++++++++++++--- core/net/rpl/rpl.h | 24 ++++++++++------- 3 files changed, 89 insertions(+), 15 deletions(-) diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 73f76b323..d2b605c9f 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -32,7 +32,7 @@ * * This file is part of the Contiki operating system. * - * $Id: rpl-dag.c,v 1.7 2010/05/24 16:38:56 nvt-se Exp $ + * $Id: rpl-dag.c,v 1.8 2010/05/25 19:19:43 joxe Exp $ */ /** * \file @@ -44,6 +44,7 @@ #include "net/rpl/rpl.h" #include "net/uip.h" +#include "net/uip-nd6.h" #include "net/rime/ctimer.h" #include "lib/list.h" #include "lib/memb.h" @@ -162,6 +163,22 @@ rpl_set_root(uip_ipaddr_t *dag_id) } /************************************************************************/ int +rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, int len) { + if(len <= 128) { + memset(&dag->destination_prefix.prefix, 0, 16); + memcpy(&dag->destination_prefix.prefix, prefix, (len + 7)/ 8); + dag->destination_prefix.length = len; + /* Note: this is an experiment to see if RPL can be used for + prefix-assignment for RPL nodes - this flag is originally + intended for Router Advertisements */ + dag->destination_prefix.preference = UIP_ND6_RA_FLAG_AUTONOMOUS; + PRINTF("RPL: Prefix set - will announce this in DIOs\n"); + return 0; + } + return -1; +} +/************************************************************************/ +int rpl_set_default_route(rpl_dag_t *dag, uip_ipaddr_t *from) { if(dag->def_route != NULL) { @@ -423,6 +440,10 @@ join_dag(uip_ipaddr_t *from, rpl_dio_t *dio) memcpy(&dag->dag_id, &dio->dag_id, sizeof(dio->dag_id)); + /* copy prefix information into the dag */ + memcpy(&dag->destination_prefix, &dio->destination_prefix, + sizeof(rpl_prefix_t)); + rpl_join_dag(dag); PRINTF("RPL: Joined DAG with instance ID %u, rank %hu, DAG ID ", diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 342a3fdd7..72147480d 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -33,7 +33,7 @@ * * This file is part of the Contiki operating system. * - * $Id: rpl-icmp6.c,v 1.9 2010/05/24 16:38:56 nvt-se Exp $ + * $Id: rpl-icmp6.c,v 1.10 2010/05/25 19:19:43 joxe Exp $ */ /** * \file @@ -164,7 +164,6 @@ dio_input(void) uint8_t subopt_type; int i; int len; - rpl_prefix_t prefix; uip_ipaddr_t from; uip_ds6_nbr_t *nbr; @@ -237,7 +236,37 @@ dio_input(void) PRINTF("RPL: Invalid destination prefix option, len = %d\n", len); return; } - prefix.preference = (buffer[3] >> 3) & 0x3; + /* prebference is both preference and flags for now */ + dio.destination_prefix.preference = buffer[i + 3]; + dio.destination_prefix.lifetime = get32(buffer, i + 4); + dio.destination_prefix.length = buffer[i + 8]; + if(((dio.destination_prefix.length + 7)/ 8) + 9 <= len && + dio.destination_prefix.length <= 128) { + PRINTF("RPL: Copying destination prefix\n"); + memcpy(&dio.destination_prefix.prefix, &buffer[i + 9], + (dio.destination_prefix.length + 7) / 8); + + /* NOTE: This is a test for adding autoconf prefix in RPL via */ + /* a destination prefix - this use one reserved flag bit */ + /* This should not be made until RPL decides to join the DAG */ + /* And not if there already is a global address configured for */ + /* the specific DAG */ + if((dio.destination_prefix.preference & UIP_ND6_RA_FLAG_AUTONOMOUS)) { + uip_ipaddr_t ipaddr; + memcpy(&ipaddr, &dio.destination_prefix.prefix, + (dio.destination_prefix.length + 7) / 8); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); + if(uip_ds6_addr_lookup(&ipaddr) == NULL) { + PRINTF("RPL: adding global IP address "); + PRINT6ADDR(&ipaddr); + PRINTF("\n"); + uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); + } + } + } else { + PRINTF("RPL: Invalid destination prefix option, len = %d\n", len); + } + break; case RPL_DIO_SUBOPT_DAG_CONF: dio.dag_intdoubl = buffer[i + 3]; @@ -309,6 +338,26 @@ dio_output(rpl_dag_t *dag, uip_ipaddr_t *uc_addr) buffer[pos++] = dag->max_rankinc; buffer[pos++] = dag->min_hoprankinc; + /* if prefix length > 0 then we have a prefix to send! */ + if(dag->destination_prefix.length > 0) { + buffer[pos++] = RPL_DIO_SUBOPT_DEST_PREFIX; + buffer[pos++] = 0; + buffer[pos++] = (dag->destination_prefix.length + 7)/ 8 + 9; + buffer[pos++] = dag->destination_prefix.preference; + set32(buffer, pos, dag->destination_prefix.lifetime); + pos += 4; + buffer[pos++] = dag->destination_prefix.length; + memcpy(&buffer[pos], &(dag->destination_prefix.prefix), + (dag->destination_prefix.length + 7)/ 8); + pos += (dag->destination_prefix.length + 7)/ 8; + PRINTF("RPL: Sending prefix info in DIO "); + PRINT6ADDR(&dag->destination_prefix.prefix); + PRINTF("\n"); + } else { + PRINTF("RPL: No prefix to announce. len:%d\n", + dag->destination_prefix.length); + } + /* buffer[len++] = RPL_DIO_SUBOPT_PAD1; */ /* Unicast requests get unicast replies! */ @@ -318,7 +367,7 @@ dio_output(rpl_dag_t *dag, uip_ipaddr_t *uc_addr) uip_create_linklocal_allrouters_mcast(&addr); uip_icmp6_send(&addr, ICMP6_RPL, RPL_CODE_DIO, pos); } else { - PRINTF("RPL: Sending unicast-DIO with rank %u to ", + PRINTF("RPL: Sending unicast-DIO with rank %u to ", (unsigned)dag->rank); PRINT6ADDR(uc_addr); PRINTF("\n"); diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index 99018cca8..52da38f5b 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -30,7 +30,7 @@ * * Author: Joakim Eriksson, Nicolas Tsiftes * - * $Id: rpl.h,v 1.2 2010/04/30 15:03:55 nvt-se Exp $ + * $Id: rpl.h,v 1.3 2010/05/25 19:19:43 joxe Exp $ */ #ifndef RPL_H @@ -146,6 +146,16 @@ struct rpl_of { typedef struct rpl_of rpl_of_t; +/* RPL DIO prefix suboption */ +struct rpl_prefix { + uip_ipaddr_t prefix; + uint32_t lifetime; + uint8_t length; + uint8_t preference; +}; + +typedef struct rpl_prefix rpl_prefix_t; + /* Logical representation of a DAG Information Object (DIO.) */ struct rpl_dio { uip_ipaddr_t dag_id; @@ -163,19 +173,11 @@ struct rpl_dio { uint8_t dag_redund; uint8_t dag_max_rankinc; uint8_t dag_min_hoprankinc; + rpl_prefix_t destination_prefix; }; typedef struct rpl_dio rpl_dio_t; -struct rpl_prefix { - uip_ipaddr_t prefix; - uint32_t lifetime; - uint8_t length; - uint8_t preference; -}; - -typedef struct rpl_prefix rpl_prefix_t; - /* Directed Acyclic Graph */ struct rpl_dag { /* DAG configuration */ @@ -213,6 +215,7 @@ struct rpl_dag { rpl_neighbor_t *best_parent; void *neighbor_list; list_t neighbors; + rpl_prefix_t destination_prefix; }; typedef struct rpl_dag rpl_dag_t; @@ -236,6 +239,7 @@ void uip_rpl_input(void); /* RPL logic functions. */ int rpl_set_root(uip_ipaddr_t *); +int rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, int len); int rpl_repair_dag(rpl_dag_t *dag); int rpl_set_default_route(rpl_dag_t *dag, uip_ipaddr_t *from); void rpl_process_dio(uip_ipaddr_t *, rpl_dio_t *);