diff --git a/core/net/rpl/rpl-conf.h b/core/net/rpl/rpl-conf.h index 78f032252..c30183934 100644 --- a/core/net/rpl/rpl-conf.h +++ b/core/net/rpl/rpl-conf.h @@ -45,12 +45,38 @@ #define RPL_CONF_STATS 0 #endif /* RPL_CONF_STATS */ -/* - * Select routing metric supported at runtime. This must be a valid - * DAG Metric Container Object Type (see below). Currently, we only - * support RPL_DAG_MC_ETX and RPL_DAG_MC_ENERGY. - * When MRHOF (RFC6719) is used with ETX, no metric container must - * be used; instead the rank carries ETX directly. +/* + * The objective function (OF) used by a RPL root is configurable through + * the RPL_CONF_OF_OCP parameter. This is defined as the objective code + * point (OCP) of the OF, RPL_OCP_OF0 or RPL_OCP_MRHOF. This flag is of + * no relevance to non-root nodes, which run the OF advertised in the + * instance they join. + * Make sure the selected of is inRPL_SUPPORTED_OFS. + */ +#ifdef RPL_CONF_OF_OCP +#define RPL_OF_OCP RPL_CONF_OF_OCP +#else /* RPL_CONF_OF_OCP */ +#define RPL_OF_OCP RPL_OCP_MRHOF +#endif /* RPL_CONF_OF_OCP */ + +/* + * The set of objective functions supported at runtime. Nodes are only + * able to join instances that advertise an OF in this set. To include + * both OF0 and MRHOF, use {&rpl_of0, &rpl_mrhof}. + */ +#ifdef RPL_CONF_SUPPORTED_OFS +#define RPL_SUPPORTED_OFS RPL_CONF_SUPPORTED_OFS +#else /* RPL_CONF_SUPPORTED_OFS */ +#define RPL_SUPPORTED_OFS {&rpl_of0, &rpl_mrhof} +#endif /* RPL_CONF_SUPPORTED_OFS */ + +/* + * Enable/disable RPL Metric Containers (MC). The actual MC in use + * for a given DODAG is decided at runtime, when joining. Note that + * OF0 (RFC6552) operates without MC, and so does MRHOF (RFC6719) when + * used with ETX as a metric (the rank is the metric). We disable MC + * by default, but note it must be enabled to support joining a DODAG + * that requires MC (e.g., MRHOF with a metric other than ETX). */ #ifdef RPL_CONF_WITH_MC #define RPL_WITH_MC RPL_CONF_WITH_MC @@ -65,18 +91,6 @@ #define RPL_DAG_MC RPL_DAG_MC_NONE #endif /* RPL_CONF_DAG_MC */ -/* - * The objective function used by RPL is configurable through the - * RPL_CONF_OF parameter. This should be defined to be the name of an - * rpl_of object linked into the system image, e.g., rpl_of0. - */ -#ifdef RPL_CONF_OF -#define RPL_OF RPL_CONF_OF -#else -/* ETX is the default objective function. */ -#define RPL_OF rpl_mrhof -#endif /* RPL_CONF_OF */ - /* This value decides which DAG instance we should participate in by default. */ #ifdef RPL_CONF_DEFAULT_INSTANCE #define RPL_DEFAULT_INSTANCE RPL_CONF_DEFAULT_INSTANCE diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 6bbc99fab..8435ca207 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -67,8 +67,8 @@ void RPL_CALLBACK_PARENT_SWITCH(rpl_parent_t *old, rpl_parent_t *new); #endif /* RPL_CALLBACK_PARENT_SWITCH */ /*---------------------------------------------------------------------------*/ -extern rpl_of_t RPL_OF; -static rpl_of_t * const objective_functions[] = {&RPL_OF}; +extern rpl_of_t rpl_of0, rpl_mrhof; +static rpl_of_t * const objective_functions[] = RPL_SUPPORTED_OFS; /*---------------------------------------------------------------------------*/ /* RPL definitions. */ @@ -376,7 +376,12 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id) dag->grounded = RPL_GROUNDED; dag->preference = RPL_PREFERENCE; instance->mop = RPL_MOP_DEFAULT; - instance->of = &RPL_OF; + instance->of = rpl_find_of(RPL_OF_OCP); + if(instance->of == NULL) { + PRINTF("RPL: OF with OCP %u not supported\n", RPL_OF_OCP); + return NULL; + } + rpl_set_preferred_parent(dag, NULL); memcpy(&dag->dag_id, dag_id, sizeof(dag->dag_id)); diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 774e3ba6a..6ea9b3e02 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -91,8 +91,6 @@ void RPL_DEBUG_DAO_OUTPUT(rpl_parent_t *); static uint8_t dao_sequence = RPL_LOLLIPOP_INIT; -extern rpl_of_t RPL_OF; - #if RPL_CONF_MULTICAST static uip_mcast6_route_t *mcast_group; #endif @@ -302,7 +300,7 @@ dio_input(void) dio.dag_redund = RPL_DIO_REDUNDANCY; dio.dag_min_hoprankinc = RPL_MIN_HOPRANKINC; dio.dag_max_rankinc = RPL_MAX_RANKINC; - dio.ocp = RPL_OF.ocp; + dio.ocp = RPL_OF_OCP; dio.default_lifetime = RPL_DEFAULT_LIFETIME; dio.lifetime_unit = RPL_DEFAULT_LIFETIME_UNIT; diff --git a/core/net/rpl/rpl-private.h b/core/net/rpl/rpl-private.h index 062c4ab86..b127bb9c4 100644 --- a/core/net/rpl/rpl-private.h +++ b/core/net/rpl/rpl-private.h @@ -144,11 +144,28 @@ ((unsigned long)(instance)->lifetime_unit * (lifetime)) #ifndef RPL_CONF_MIN_HOPRANKINC +/* RFC6550 defines the default MIN_HOPRANKINC as 256. + * However, we use MRHOF as a default Objective Function (RFC6719), + * which recommends setting MIN_HOPRANKINC with care, in particular + * when used with ETX as a metric. ETX is computed as a fixed point + * real with a divisor of 128 (RFC6719, RFC6551). We choose to also + * use 128 for RPL_MIN_HOPRANKINC, resulting in a rank equal to the + * ETX path cost. Larger values may also be desirable, as discussed + * in section 6.1 of RFC6719. */ +#if RPL_OF_OCP == RPL_OCP_MRHOF +#define RPL_MIN_HOPRANKINC 128 +#else /* RPL_OF_OCP == RPL_OCP_MRHOF */ #define RPL_MIN_HOPRANKINC 256 -#else +#endif /* RPL_OF_OCP == RPL_OCP_MRHOF */ +#else /* RPL_CONF_MIN_HOPRANKINC */ #define RPL_MIN_HOPRANKINC RPL_CONF_MIN_HOPRANKINC -#endif +#endif /* RPL_CONF_MIN_HOPRANKINC */ + +#ifndef RPL_CONF_MAX_RANKINC #define RPL_MAX_RANKINC (7 * RPL_MIN_HOPRANKINC) +#else /* RPL_CONF_MAX_RANKINC */ +#define RPL_MAX_RANKINC RPL_CONF_MAX_RANKINC +#endif /* RPL_CONF_MAX_RANKINC */ #define DAG_RANK(fixpt_rank, instance) \ ((fixpt_rank) / (instance)->min_hoprankinc)