diff --git a/sys/include/net/gnrc/netif/internal.h b/sys/include/net/gnrc/netif/internal.h index ef0b192038..4f26fad810 100644 --- a/sys/include/net/gnrc/netif/internal.h +++ b/sys/include/net/gnrc/netif/internal.h @@ -716,6 +716,26 @@ static inline int gnrc_netif_ipv6_group_to_l2_group(gnrc_netif_t *netif, return l2util_ipv6_group_to_l2_group(netif->device_type, ipv6_group, l2_group); } + +/** + * @brief Configures a prefix on a network interface. + * + * If the interface is a 6LoWPAN interface, this will also + * take care of setting up a compression context. + * + * @param[in] netif Network interface the prefix should be added to + * @param[in] pfx Prefix to configure + * @param[in] pfx_len Length of @p pfx in bits + * @param[in] valid Valid lifetime of the prefix in seconds + * @param[in] pref Preferred lifetime of the prefix in seconds + * + * @return >= 0, on success + * @return -ENOMEM, when no space for new addresses (or its solicited nodes + * multicast address) is left on the interface + */ +int gnrc_netif_ipv6_add_prefix(gnrc_netif_t *netif, + const ipv6_addr_t *pfx, uint8_t pfx_len, + uint32_t valid, uint32_t pref); #else /* IS_USED(MODULE_GNRC_NETIF_IPV6) || defined(DOXYGEN) */ #define gnrc_netif_ipv6_init_mtu(netif) (void)netif #define gnrc_netif_ipv6_iid_from_addr(netif, addr, addr_len, iid) (-ENOTSUP) diff --git a/sys/include/net/gnrc/rpl.h b/sys/include/net/gnrc/rpl.h index 90a477da79..e5fb179075 100644 --- a/sys/include/net/gnrc/rpl.h +++ b/sys/include/net/gnrc/rpl.h @@ -583,7 +583,7 @@ kernel_pid_t gnrc_rpl_init(kernel_pid_t if_pid); * @return Pointer to the new RPL Instance, on success. * @return NULL, otherwise. */ -gnrc_rpl_instance_t *gnrc_rpl_root_init(uint8_t instance_id, ipv6_addr_t *dodag_id, +gnrc_rpl_instance_t *gnrc_rpl_root_init(uint8_t instance_id, const ipv6_addr_t *dodag_id, bool gen_inst_id, bool local_inst_id); /** @@ -695,7 +695,7 @@ void gnrc_rpl_long_delay_dao(gnrc_rpl_dodag_t *dodag); * @return Pointer to the new RPL instance, on success. * @return NULL, otherwise. */ -gnrc_rpl_instance_t *gnrc_rpl_root_instance_init(uint8_t instance_id, ipv6_addr_t *dodag_id, +gnrc_rpl_instance_t *gnrc_rpl_root_instance_init(uint8_t instance_id, const ipv6_addr_t *dodag_id, uint8_t mop); /** @@ -736,6 +736,18 @@ static inline void gnrc_rpl_config_pio(gnrc_rpl_dodag_t *dodag, bool status) } } +#if IS_USED(MODULE_GNRC_RPL) || DOXYGEN +/** + * @brief Convenience function to start a RPL root using the default configuration. + * + * @param[in] netif Network interface to use as RPL root + * @param[in] dodag_id Id of the DODAG + */ +void gnrc_rpl_configure_root(gnrc_netif_t *netif, const ipv6_addr_t *dodag_id); +#else +#define gnrc_rpl_configure_root(netif, dodag_id) ((void)netif) +#endif + #ifdef __cplusplus } #endif diff --git a/sys/include/net/gnrc/rpl/dodag.h b/sys/include/net/gnrc/rpl/dodag.h index 17ee7ec6d6..62245a451d 100644 --- a/sys/include/net/gnrc/rpl/dodag.h +++ b/sys/include/net/gnrc/rpl/dodag.h @@ -107,7 +107,8 @@ gnrc_rpl_instance_t *gnrc_rpl_instance_get(uint8_t instance_id); * @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, const ipv6_addr_t *dodag_id, + kernel_pid_t iface); /** * @brief Remove all parents from the @p dodag. diff --git a/sys/include/net/gnrc/sixlowpan/ctx.h b/sys/include/net/gnrc/sixlowpan/ctx.h index 71132728b6..73aeb1b382 100644 --- a/sys/include/net/gnrc/sixlowpan/ctx.h +++ b/sys/include/net/gnrc/sixlowpan/ctx.h @@ -30,6 +30,7 @@ #include #include "net/ipv6/addr.h" +#include "timex.h" #ifdef __cplusplus extern "C" { @@ -113,7 +114,6 @@ gnrc_sixlowpan_ctx_t *gnrc_sixlowpan_ctx_update(uint8_t id, const ipv6_addr_t *p uint8_t prefix_len, uint16_t ltime, bool comp); -#ifdef MODULE_GNRC_SIXLOWPAN_CTX /** * @brief Removes context. * @@ -121,9 +121,72 @@ gnrc_sixlowpan_ctx_t *gnrc_sixlowpan_ctx_update(uint8_t id, const ipv6_addr_t *p */ static inline void gnrc_sixlowpan_ctx_remove(uint8_t id) { - gnrc_sixlowpan_ctx_lookup_id(id)->prefix_len = 0; + if (IS_USED(MODULE_GNRC_SIXLOWPAN_CTX)) { + gnrc_sixlowpan_ctx_lookup_id(id)->prefix_len = 0; + } +} + +/** + * @brief Check if a prefix matches a compression context + * + * @param[in] ctx The compression context + * @param[in] prefix IPv6 prefix + * @param[in] prefix_len Length of the IPv6 prefix + * + * @return true if the prefix matches the compression context. + */ +static inline bool gnrc_sixlowpan_ctx_match(const gnrc_sixlowpan_ctx_t *ctx, + const ipv6_addr_t *prefix, uint8_t prefix_len) +{ + return (ctx != NULL) && + (ctx->prefix_len == prefix_len) && + (ipv6_addr_match_prefix(&ctx->prefix, prefix) >= prefix_len); +} + +/** + * @brief Create or update a compression context + * + * @param[in] prefix IPv6 prefix of the compression context + * @param[in] prefix_len Length of the IPv6 prefix + * @param[in] valid Lifetime of the prefix in seconds + * + * @return true if a new compression context was created or an existing context + * was updated. + * false if no new context could be added + */ +static inline bool gnrc_sixlowpan_ctx_update_6ctx(const ipv6_addr_t *prefix, uint8_t prefix_len, + uint32_t valid) +{ + if (!IS_USED(MODULE_GNRC_SIXLOWPAN_CTX)) { + return false; + } + + gnrc_sixlowpan_ctx_t *ctx = gnrc_sixlowpan_ctx_lookup_addr(prefix); + uint8_t cid = 0; + + if (!gnrc_sixlowpan_ctx_match(ctx, prefix, prefix_len)) { + /* While the context is a prefix match, the defined prefix within the + * context does not match => use new context */ + ctx = NULL; + } + else { + cid = ctx->flags_id & GNRC_SIXLOWPAN_CTX_FLAGS_CID_MASK; + } + /* find first free context ID */ + if (ctx == NULL) { + while (((ctx = gnrc_sixlowpan_ctx_lookup_id(cid)) != NULL) && + !gnrc_sixlowpan_ctx_match(ctx, prefix, prefix_len)) { + cid++; + } + } + if (cid < GNRC_SIXLOWPAN_CTX_SIZE) { + return gnrc_sixlowpan_ctx_update(cid, (ipv6_addr_t *)prefix, prefix_len, + valid / (60 * MS_PER_SEC), + true); + } + + return false; } -#endif #ifdef TEST_SUITES /** diff --git a/sys/net/gnrc/application_layer/dhcpv6/client.c b/sys/net/gnrc/application_layer/dhcpv6/client.c index 0139ea623a..4c878b1613 100644 --- a/sys/net/gnrc/application_layer/dhcpv6/client.c +++ b/sys/net/gnrc/application_layer/dhcpv6/client.c @@ -32,8 +32,6 @@ #define ENABLE_DEBUG 0 #include "debug.h" -static char addr_str[IPV6_ADDR_MAX_STR_LEN]; - unsigned dhcpv6_client_get_duid_l2(unsigned iface, dhcpv6_duid_l2_t *duid) { gnrc_netif_t *netif; @@ -80,100 +78,14 @@ unsigned dhcpv6_client_get_duid_l2(unsigned iface, dhcpv6_duid_l2_t *duid) return (uint8_t)res + sizeof(dhcpv6_duid_l2_t); } -static bool _ctx_match(const gnrc_sixlowpan_ctx_t *ctx, - const ipv6_addr_t *prefix, uint8_t prefix_len) -{ - return (ctx != NULL) && - (ctx->prefix_len == prefix_len) && - (ipv6_addr_match_prefix(&ctx->prefix, prefix) >= prefix_len); -} - -static void _update_6ctx(const ipv6_addr_t *prefix, uint8_t prefix_len) -{ - gnrc_sixlowpan_ctx_t *ctx = gnrc_sixlowpan_ctx_lookup_addr(prefix); - uint8_t cid = 0; - - if (!_ctx_match(ctx, prefix, prefix_len)) { - /* While the context is a prefix match, the defined prefix within the - * context does not match => use new context */ - ctx = NULL; - } - else { - cid = ctx->flags_id & GNRC_SIXLOWPAN_CTX_FLAGS_CID_MASK; - } - /* find first free context ID */ - if (ctx == NULL) { - while (((ctx = gnrc_sixlowpan_ctx_lookup_id(cid)) != NULL) && - !_ctx_match(ctx, prefix, prefix_len)) { - cid++; - } - } - if (cid < GNRC_SIXLOWPAN_CTX_SIZE) { - DEBUG("DHCP client: add compression context %u for prefix %s/%u\n", cid, - ipv6_addr_to_str(addr_str, prefix, sizeof(addr_str)), - prefix_len); - gnrc_sixlowpan_ctx_update(cid, (ipv6_addr_t *)prefix, prefix_len, - CONFIG_GNRC_DHCPV6_CLIENT_6LBR_6LO_CTX_MIN, - true); - } -} - void dhcpv6_client_conf_prefix(unsigned iface, const ipv6_addr_t *pfx, unsigned pfx_len, uint32_t valid, uint32_t pref) { gnrc_netif_t *netif = gnrc_netif_get_by_pid(iface); - eui64_t iid; - ipv6_addr_t addr; - - assert(netif != NULL); - DEBUG("GNRC DHCPv6 client: (re-)configure prefix %s/%d\n", - ipv6_addr_to_str(addr_str, pfx, sizeof(addr_str)), pfx_len); - if (gnrc_netapi_get(netif->pid, NETOPT_IPV6_IID, 0, &iid, - sizeof(eui64_t)) >= 0) { - ipv6_addr_set_aiid(&addr, iid.uint8); - } - else { - LOG_WARNING("GNRC DHCPv6 client: cannot get IID of netif %u\n", netif->pid); - return; - } - ipv6_addr_init_prefix(&addr, pfx, pfx_len); - /* add address as tentative */ - if (gnrc_netif_ipv6_addr_add(netif, &addr, pfx_len, - GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_TENTATIVE & 0x1) > 0) { - /* update lifetime */ - if (valid < UINT32_MAX) { /* UINT32_MAX means infinite lifetime */ - /* the valid lifetime is given in seconds, but the NIB's timers work - * in microseconds, so we have to scale down to the smallest - * possible value (UINT32_MAX - 1). */ - valid = (valid > (UINT32_MAX / MS_PER_SEC)) ? - (UINT32_MAX - 1) : valid * MS_PER_SEC; - } - if (pref < UINT32_MAX) { /* UINT32_MAX means infinite lifetime */ - /* same treatment for pref */ - pref = (pref > (UINT32_MAX / MS_PER_SEC)) ? - (UINT32_MAX - 1) : pref * MS_PER_SEC; - } - gnrc_ipv6_nib_pl_set(netif->pid, pfx, pfx_len, valid, pref); - if (IS_USED(MODULE_GNRC_IPV6_NIB) && - IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_6LBR) && - IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_MULTIHOP_P6C) && - gnrc_netif_is_6ln(netif)) { - if (IS_USED(MODULE_GNRC_SIXLOWPAN_CTX)) { - _update_6ctx(pfx, pfx_len); - } - (void)gnrc_ipv6_nib_abr_add(&addr); - } - if (IS_USED(MODULE_GNRC_RPL)) { - gnrc_rpl_init(netif->pid); - gnrc_rpl_instance_t *inst = gnrc_rpl_instance_get( - CONFIG_GNRC_RPL_DEFAULT_INSTANCE - ); - if (inst) { - gnrc_rpl_instance_remove(inst); - } - gnrc_rpl_root_init(CONFIG_GNRC_RPL_DEFAULT_INSTANCE, &addr, false, false); - } + int idx = gnrc_netif_ipv6_add_prefix(netif, pfx, pfx_len, valid, pref); + if (idx >= 0) { + gnrc_rpl_configure_root(netif, &netif->ipv6.addrs[idx]); } } diff --git a/sys/net/gnrc/application_layer/uhcpc/gnrc_uhcpc.c b/sys/net/gnrc/application_layer/uhcpc/gnrc_uhcpc.c index c0bf12c90e..407360c51e 100644 --- a/sys/net/gnrc/application_layer/uhcpc/gnrc_uhcpc.c +++ b/sys/net/gnrc/application_layer/uhcpc/gnrc_uhcpc.c @@ -12,12 +12,7 @@ #include "net/gnrc/ipv6.h" #include "net/gnrc/netapi.h" #include "net/gnrc/netif.h" -#ifdef MODULE_GNRC_RPL #include "net/gnrc/rpl.h" -#endif -#ifdef MODULE_GNRC_SIXLOWPAN_CTX -#include "net/gnrc/sixlowpan/ctx.h" -#endif #include "net/ipv6/addr.h" #include "net/netdev.h" #include "net/netopt.h" @@ -26,7 +21,6 @@ #include "log.h" #include "fmt.h" -static char addr_str[IPV6_ADDR_MAX_STR_LEN]; static kernel_pid_t gnrc_border_interface; static kernel_pid_t gnrc_wireless_interface; @@ -69,58 +63,13 @@ static void set_interface_roles(void) "interface.\n", gnrc_border_interface, gnrc_wireless_interface); } -static ipv6_addr_t _prefix; -static uint8_t _prefix_len; - -#ifdef MODULE_GNRC_SIXLOWPAN_CTX -#define SIXLO_CTX_LTIME_MIN (60U) /**< context lifetime in minutes */ - -static bool _ctx_match(const gnrc_sixlowpan_ctx_t *ctx, - const ipv6_addr_t *prefix, uint8_t prefix_len) -{ - return (ctx != NULL) && - (ctx->prefix_len == prefix_len) && - (ipv6_addr_match_prefix(&ctx->prefix, prefix) >= prefix_len); -} - -static void _update_6ctx(const ipv6_addr_t *prefix, uint8_t prefix_len) -{ - gnrc_sixlowpan_ctx_t *ctx = gnrc_sixlowpan_ctx_lookup_addr(prefix); - uint8_t cid = 0; - - if (!_ctx_match(ctx, prefix, prefix_len)) { - /* While the context is a prefix match, the defined prefix within the - * context does not match => use new context */ - ctx = NULL; - } - else { - cid = ctx->flags_id & GNRC_SIXLOWPAN_CTX_FLAGS_CID_MASK; - } - /* find first free context ID */ - if (ctx == NULL) { - while (((ctx = gnrc_sixlowpan_ctx_lookup_id(cid)) != NULL) && - !_ctx_match(ctx, prefix, prefix_len)) { - cid++; - } - } - if (cid < GNRC_SIXLOWPAN_CTX_SIZE) { - LOG_INFO("gnrc_uhcpc: uhcp_handle_prefix(): add compression context " - "%u for prefix %s/%u\n", cid, - ipv6_addr_to_str(addr_str, prefix, sizeof(addr_str)), - prefix_len); - gnrc_sixlowpan_ctx_update(cid, (ipv6_addr_t *)prefix, prefix_len, - SIXLO_CTX_LTIME_MIN, true); - } -} -#endif - void uhcp_handle_prefix(uint8_t *prefix, uint8_t prefix_len, uint16_t lifetime, uint8_t *src, uhcp_iface_t iface) { - (void)lifetime; + int idx; + gnrc_netif_t *wireless; (void)src; - eui64_t iid; if (!gnrc_wireless_interface) { LOG_WARNING("gnrc_uhcpc: uhcp_handle_prefix(): received prefix, but " "don't know any wireless interface\n"); @@ -133,71 +82,12 @@ void uhcp_handle_prefix(uint8_t *prefix, uint8_t prefix_len, uint16_t lifetime, return; } - if (gnrc_netapi_get(gnrc_wireless_interface, NETOPT_IPV6_IID, 0, &iid, - sizeof(eui64_t)) >= 0) { - ipv6_addr_set_aiid((ipv6_addr_t*)prefix, iid.uint8); + wireless = gnrc_netif_get_by_pid(gnrc_wireless_interface); + idx = gnrc_netif_ipv6_add_prefix(wireless, (ipv6_addr_t *)prefix, prefix_len, + lifetime, lifetime); + if (idx >= 0) { + gnrc_rpl_configure_root(wireless, &wireless->ipv6.addrs[idx]); } - else { - LOG_WARNING("gnrc_uhcpc: uhcp_handle_prefix(): cannot get IID of " - "wireless interface\n"); - return; - } - - if ((_prefix_len == prefix_len) && - (ipv6_addr_match_prefix(&_prefix, - (ipv6_addr_t *)prefix) >= prefix_len)) { - LOG_INFO("gnrc_uhcpc: uhcp_handle_prefix(): got same prefix " - "again\n"); -#ifdef MODULE_GNRC_SIXLOWPAN_CTX - if (gnrc_netif_is_6ln(gnrc_netif_get_by_pid(gnrc_wireless_interface))) { - /* always update 6LoWPAN compression context so it does not time - * out, we can't just remove it anyway according to the RFC */ - _update_6ctx((ipv6_addr_t *)prefix, prefix_len); - } -#endif - return; - } - else if (!ipv6_addr_is_unspecified(&_prefix)) { - gnrc_netapi_set(gnrc_wireless_interface, NETOPT_IPV6_ADDR_REMOVE, 0, - &_prefix, sizeof(_prefix)); -#if defined(MODULE_GNRC_IPV6_NIB) && IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_6LBR) && \ - IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_MULTIHOP_P6C) - gnrc_ipv6_nib_abr_del(&_prefix); -#endif - LOG_INFO("gnrc_uhcpc: uhcp_handle_prefix(): removed old prefix %s/%u\n", - ipv6_addr_to_str(addr_str, &_prefix, sizeof(addr_str)), - prefix_len); - } - memcpy(&_prefix, prefix, sizeof(_prefix)); - _prefix_len = prefix_len; - gnrc_netapi_set(gnrc_wireless_interface, NETOPT_IPV6_ADDR, - (prefix_len << 8), prefix, sizeof(ipv6_addr_t)); - /* only configure 6Lo-ND features when wireless interface uses - * 6Lo-ND */ - if (gnrc_netif_is_6ln(gnrc_netif_get_by_pid(gnrc_wireless_interface))) { -#ifdef MODULE_GNRC_SIXLOWPAN_CTX - /* add compression before ABR to add it automatically to its context - * list */ - _update_6ctx((ipv6_addr_t *)prefix, prefix_len); -#endif -#if defined(MODULE_GNRC_IPV6_NIB) && IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_6LBR) && \ - IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_MULTIHOP_P6C) - gnrc_ipv6_nib_abr_add((ipv6_addr_t *)prefix); -#endif - } -#ifdef MODULE_GNRC_RPL - gnrc_rpl_init(gnrc_wireless_interface); - gnrc_rpl_instance_t *inst = gnrc_rpl_instance_get( - CONFIG_GNRC_RPL_DEFAULT_INSTANCE); - if (inst) { - gnrc_rpl_instance_remove(inst); - } - gnrc_rpl_root_init(CONFIG_GNRC_RPL_DEFAULT_INSTANCE, (ipv6_addr_t*)prefix, false, - false); -#endif - LOG_INFO("gnrc_uhcpc: uhcp_handle_prefix(): configured new prefix %s/%u\n", - ipv6_addr_to_str(addr_str, (ipv6_addr_t *)prefix, - sizeof(addr_str)), prefix_len); } extern void uhcp_client(uhcp_iface_t iface); diff --git a/sys/net/gnrc/netif/gnrc_netif.c b/sys/net/gnrc/netif/gnrc_netif.c index 59e9ca8c3f..522c941153 100644 --- a/sys/net/gnrc/netif/gnrc_netif.c +++ b/sys/net/gnrc/netif/gnrc_netif.c @@ -32,6 +32,7 @@ #if IS_USED(MODULE_GNRC_NETIF_PKTQ) #include "net/gnrc/netif/pktq.h" #endif /* IS_USED(MODULE_GNRC_NETIF_PKTQ) */ +#include "net/gnrc/sixlowpan/ctx.h" #if IS_USED(MODULE_GNRC_SIXLOWPAN_FRAG_SFR) #include "net/gnrc/sixlowpan/frag/sfr.h" #endif /* IS_USED(MODULE_GNRC_SIXLOWPAN_FRAG_SFR) */ @@ -1235,6 +1236,68 @@ static ipv6_addr_t *_src_addr_selection(gnrc_netif_t *netif, return &netif->ipv6.addrs[idx]; } } + +int gnrc_netif_ipv6_add_prefix(gnrc_netif_t *netif, + const ipv6_addr_t *pfx, uint8_t pfx_len, + uint32_t valid, uint32_t pref) +{ + int res; + eui64_t iid; + ipv6_addr_t addr; + + assert(netif != NULL); + DEBUG("gnrc_netif: (re-)configure prefix %s/%d\n", + ipv6_addr_to_str(addr_str, pfx, sizeof(addr_str)), pfx_len); + if (gnrc_netapi_get(netif->pid, NETOPT_IPV6_IID, 0, &iid, + sizeof(eui64_t)) >= 0) { + ipv6_addr_set_aiid(&addr, iid.uint8); + } + else { + LOG_WARNING("gnrc_netif: cannot get IID of netif %u\n", netif->pid); + return -ENODEV; + } + ipv6_addr_init_prefix(&addr, pfx, pfx_len); + + /* add address as valid */ + res = gnrc_netif_ipv6_addr_add_internal(netif, &addr, pfx_len, + GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_VALID); + if (res < 0) { + goto out; + } + + /* update lifetime */ + if (valid < UINT32_MAX) { /* UINT32_MAX means infinite lifetime */ + /* the valid lifetime is given in seconds, but the NIB's timers work + * in microseconds, so we have to scale down to the smallest + * possible value (UINT32_MAX - 1). */ + valid = (valid > (UINT32_MAX / MS_PER_SEC)) + ? (UINT32_MAX - 1) : valid * MS_PER_SEC; + } + if (pref < UINT32_MAX) { /* UINT32_MAX means infinite lifetime */ + /* same treatment for pref */ + pref = (pref > (UINT32_MAX / MS_PER_SEC)) + ? (UINT32_MAX - 1) : pref * MS_PER_SEC; + } + gnrc_ipv6_nib_pl_set(netif->pid, pfx, pfx_len, valid, pref); + + /* configure 6LoWPAN specific options */ + if (IS_USED(MODULE_GNRC_IPV6_NIB) && + IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_6LBR) && + IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_MULTIHOP_P6C) && + gnrc_netif_is_6ln(netif)) { + + /* configure compression context */ + if (gnrc_sixlowpan_ctx_update_6ctx(pfx, pfx_len, valid)) { + DEBUG("gnrc_netif: add compression context for prefix %s/%u\n", + ipv6_addr_to_str(addr_str, pfx, sizeof(addr_str)), pfx_len); + } + + (void)gnrc_ipv6_nib_abr_add(&addr); + } + +out: + return res; +} #endif /* IS_USED(MODULE_GNRC_NETIF_IPV6) */ static void _update_l2addr_from_dev(gnrc_netif_t *netif) diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl.c b/sys/net/gnrc/routing/rpl/gnrc_rpl.c index cc42f6453b..1b4c7c80e2 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl.c @@ -128,7 +128,7 @@ kernel_pid_t gnrc_rpl_init(kernel_pid_t if_pid) return gnrc_rpl_pid; } -gnrc_rpl_instance_t *gnrc_rpl_root_init(uint8_t instance_id, ipv6_addr_t *dodag_id, +gnrc_rpl_instance_t *gnrc_rpl_root_init(uint8_t instance_id, const ipv6_addr_t *dodag_id, bool gen_inst_id, bool local_inst_id) { if (gen_inst_id) { @@ -419,6 +419,18 @@ uint8_t gnrc_rpl_gen_instance_id(bool local) return instance_id; } +void gnrc_rpl_configure_root(gnrc_netif_t *netif, const ipv6_addr_t *dodag_id) +{ + gnrc_rpl_init(netif->pid); + gnrc_rpl_instance_t *inst = gnrc_rpl_instance_get( + CONFIG_GNRC_RPL_DEFAULT_INSTANCE + ); + if (inst) { + gnrc_rpl_instance_remove(inst); + } + gnrc_rpl_root_init(CONFIG_GNRC_RPL_DEFAULT_INSTANCE, dodag_id, false, false); +} + /** * @} */ diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c index 8b5e389c41..806c606be7 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c @@ -144,7 +144,8 @@ 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, const ipv6_addr_t *dodag_id, + kernel_pid_t iface) { assert(instance && (instance->state > 0)); @@ -370,7 +371,7 @@ static gnrc_rpl_parent_t *_gnrc_rpl_find_preferred_parent(gnrc_rpl_dodag_t *doda return dodag->parents; } -gnrc_rpl_instance_t *gnrc_rpl_root_instance_init(uint8_t instance_id, ipv6_addr_t *dodag_id, +gnrc_rpl_instance_t *gnrc_rpl_root_instance_init(uint8_t instance_id, const ipv6_addr_t *dodag_id, uint8_t mop) { if (gnrc_rpl_pid == KERNEL_PID_UNDEF) {