diff --git a/sys/include/net/gnrc/rpl/dodag.h b/sys/include/net/gnrc/rpl/dodag.h index 3621cacd7f0792fc36ecd3e6ac26b4967e5f4414..95ed66d5b3837e842e9d0ece52c4deacf1eeea50 100644 --- a/sys/include/net/gnrc/rpl/dodag.h +++ b/sys/include/net/gnrc/rpl/dodag.h @@ -103,11 +103,13 @@ gnrc_rpl_instance_t *gnrc_rpl_instance_get(uint8_t instance_id); * @param[in] instance Pointer to the instance to add the DODAG to * @param[in] dodag_id The DODAG-ID of the new DODAG * @param[in] iface Interface PID where the DODAG operates + * @param[in] netif_addr netif address for this DODAG * * @return true, if DODAG could be created. * @return false, if DODAG could not be created or exists already. */ -bool gnrc_rpl_dodag_init(gnrc_rpl_instance_t *instance, ipv6_addr_t *dodag_id, kernel_pid_t iface); +bool gnrc_rpl_dodag_init(gnrc_rpl_instance_t *instance, ipv6_addr_t *dodag_id, kernel_pid_t iface, + gnrc_ipv6_netif_addr_t *netif_addr); /** * @brief Remove all parents from the @p dodag. diff --git a/sys/include/net/gnrc/rpl/structs.h b/sys/include/net/gnrc/rpl/structs.h index 325db5b64d13dc07c62e71594ee869af310a65e8..7554621460a021fbd82f22c85225074938d6b33c 100644 --- a/sys/include/net/gnrc/rpl/structs.h +++ b/sys/include/net/gnrc/rpl/structs.h @@ -27,6 +27,7 @@ extern "C" { #endif +#include "net/gnrc/ipv6/netif.h" #include "net/ipv6/addr.h" #include "xtimer.h" #include "trickle.h" @@ -212,11 +213,9 @@ typedef struct { */ struct gnrc_rpl_dodag { ipv6_addr_t dodag_id; /**< id of the DODAG */ + gnrc_ipv6_netif_addr_t *netif_addr; /**< netif address for this DODAG */ gnrc_rpl_parent_t *parents; /**< pointer to the parents list of this DODAG */ gnrc_rpl_instance_t *instance; /**< pointer to the instance that this dodag is part of */ - uint8_t prefix_len; /**< length of the prefix for the DODAG id */ - uint32_t addr_preferred; /**< time in seconds the DODAG id is preferred */ - uint32_t addr_valid; /**< time in seconds the DODAG id is valid */ uint8_t dtsn; /**< DAO Trigger Sequence Number */ uint8_t prf; /**< preferred flag */ uint8_t dio_interval_doubl; /**< trickle Imax parameter */ diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl.c b/sys/net/gnrc/routing/rpl/gnrc_rpl.c index 8da5ee211649a9cd5eb55c9c1682739bfdf5bc4c..6acd978c2851f11a0a02016e31ca1dee2bcf8f79 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl.c @@ -84,7 +84,7 @@ gnrc_rpl_instance_t *gnrc_rpl_root_init(uint8_t instance_id, ipv6_addr_t *dodag_ gnrc_rpl_dodag_t *dodag = NULL; gnrc_rpl_instance_t *inst = gnrc_rpl_root_instance_init(instance_id, dodag_id, - GNRC_RPL_DEFAULT_MOP); + GNRC_RPL_DEFAULT_MOP); if (!inst) { return NULL; diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c index a47ba29db6de3c4bf69a1df3208da869418c7058..3287df9b3cebe0b9c56c48299648d0f6510695ef 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c @@ -140,13 +140,13 @@ gnrc_pktsnip_t *_dio_prefix_info_build(gnrc_pktsnip_t *pkt, gnrc_rpl_dodag_t *do prefix_info->length = GNRC_RPL_OPT_PREFIX_INFO_LEN; /* auto-address configuration */ prefix_info->LAR_flags = GNRC_RPL_PREFIX_AUTO_ADDRESS_BIT; - prefix_info->valid_lifetime = dodag->addr_valid; - prefix_info->pref_lifetime = dodag->addr_preferred; - prefix_info->prefix_len = dodag->prefix_len; + prefix_info->valid_lifetime = dodag->netif_addr->valid; + prefix_info->pref_lifetime = dodag->netif_addr->preferred; + prefix_info->prefix_len = dodag->netif_addr->prefix_len; prefix_info->reserved = 0; memset(&prefix_info->prefix, 0, sizeof(prefix_info->prefix)); - ipv6_addr_init_prefix(&prefix_info->prefix, &dodag->dodag_id, dodag->prefix_len); + ipv6_addr_init_prefix(&prefix_info->prefix, &dodag->dodag_id, dodag->netif_addr->prefix_len); return opt_snip; } #endif @@ -375,6 +375,7 @@ bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt_t *opt gnrc_rpl_dodag_t *dodag = &inst->dodag; eui64_t iid; *included_opts = 0; + ipv6_addr_t *me; if (!_gnrc_rpl_check_options_validity(msg_type, inst, opt, len)) { return false; @@ -432,7 +433,10 @@ bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt_t *opt break; } ipv6_addr_set_aiid(&pi->prefix, iid.uint8); - gnrc_ipv6_netif_add_addr(dodag->iface, &pi->prefix, pi->prefix_len, 0); + me = gnrc_ipv6_netif_add_addr(dodag->iface, &pi->prefix, pi->prefix_len, 0); + if (me) { + dodag->netif_addr = gnrc_ipv6_netif_addr_get(me); + } break; @@ -542,12 +546,12 @@ void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src assert(iface != KERNEL_PID_UNDEF); } - gnrc_rpl_dodag_init(inst, &dio->dodag_id, iface); + gnrc_rpl_dodag_init(inst, &dio->dodag_id, iface, NULL); dodag = &inst->dodag; DEBUG("RPL: Joined DODAG (%s).\n", - ipv6_addr_to_str(addr_str, &dio->dodag_id, sizeof(addr_str))); + ipv6_addr_to_str(addr_str, &dio->dodag_id, sizeof(addr_str))); gnrc_rpl_parent_t *parent = NULL; @@ -583,6 +587,25 @@ void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src #endif } + /* if there was no netif_addr created manually or by a PIO, then leave this DODAG */ + if (!dodag->netif_addr) { + ipv6_addr_t *configured_addr; + + if (!(configured_addr = gnrc_ipv6_netif_match_prefix(dodag->iface, &dodag->dodag_id))) { + DEBUG("RPL: no IPv6 address configured to match the given dodag id: %s\n", + ipv6_addr_to_str(addr_str, dodag_id, sizeof(addr_str))); + gnrc_rpl_instance_remove(inst); + return; + } + + if (!(dodag->netif_addr = gnrc_ipv6_netif_addr_get(configured_addr))) { + DEBUG("RPL: no netif address found for %s\n", + ipv6_addr_to_str(addr_str, configured_addr, sizeof(addr_str))); + gnrc_rpl_instance_remove(inst); + return; + } + } + gnrc_rpl_delay_dao(dodag); trickle_start(gnrc_rpl_pid, &dodag->trickle, GNRC_RPL_MSG_TYPE_TRICKLE_INTERVAL, GNRC_RPL_MSG_TYPE_TRICKLE_CALLBACK, (1 << dodag->dio_min), diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c index 3cbfc083725c68e1570584463394cbc064d27363..ec75700950d7f48df786439433f2eedfccd11b5d 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c @@ -113,21 +113,16 @@ gnrc_rpl_instance_t *gnrc_rpl_instance_get(uint8_t instance_id) return NULL; } -bool gnrc_rpl_dodag_init(gnrc_rpl_instance_t *instance, ipv6_addr_t *dodag_id, kernel_pid_t iface) +bool gnrc_rpl_dodag_init(gnrc_rpl_instance_t *instance, ipv6_addr_t *dodag_id, kernel_pid_t iface, + gnrc_ipv6_netif_addr_t *netif_addr) { - gnrc_rpl_dodag_t *dodag = NULL; + /* TODO: check if netif_addr belongs to iface */ - if ((instance == NULL) || instance->state == 0) { - DEBUG("Instance is NULL or unused\n"); - return false; - } + assert(instance && (instance->state > 0)); - dodag = &instance->dodag; + gnrc_rpl_dodag_t *dodag = &instance->dodag; dodag->dodag_id = *dodag_id; - dodag->prefix_len = GNRC_RPL_DEFAULT_PREFIX_LEN; - dodag->addr_preferred = GNRC_RPL_DEFAULT_PREFIX_LIFETIME; - dodag->addr_valid = GNRC_RPL_DEFAULT_PREFIX_LIFETIME; dodag->my_rank = GNRC_RPL_INFINITE_RANK; dodag->trickle.callback.func = &_rpl_trickle_send_dio; dodag->trickle.callback.args = instance; @@ -143,6 +138,7 @@ bool gnrc_rpl_dodag_init(gnrc_rpl_instance_t *instance, ipv6_addr_t *dodag_id, k dodag->dao_counter = 0; dodag->instance = instance; dodag->iface = iface; + dodag->netif_addr = netif_addr; return true; } @@ -373,15 +369,13 @@ gnrc_rpl_instance_t *gnrc_rpl_root_instance_init(uint8_t instance_id, ipv6_addr_ return NULL; } - if (!gnrc_rpl_dodag_init(inst, dodag_id, iface)) { + if (!gnrc_rpl_dodag_init(inst, dodag_id, iface, netif_addr)) { DEBUG("RPL: could not initialize DODAG"); + gnrc_rpl_instance_remove(inst); return NULL; } dodag = &inst->dodag; - dodag->prefix_len = netif_addr->prefix_len; - dodag->addr_preferred = netif_addr->preferred; - dodag->addr_valid = netif_addr->valid; dodag->instance = inst; return inst;