diff --git a/sys/include/net/gnrc/ipv6/nib/conf.h b/sys/include/net/gnrc/ipv6/nib/conf.h index 90a9bf4b9df3b..4c61a1f06ea02 100644 --- a/sys/include/net/gnrc/ipv6/nib/conf.h +++ b/sys/include/net/gnrc/ipv6/nib/conf.h @@ -125,12 +125,19 @@ extern "C" { #endif /** - * @brief activate router advertising at interface start-up + * @brief activate router advertising at interface start-up */ #ifndef CONFIG_GNRC_IPV6_NIB_ADV_ROUTER #define CONFIG_GNRC_IPV6_NIB_ADV_ROUTER 0 #endif +/** + * @brief activate authoritative border router functionality at interface start-up + */ +#ifndef CONFIG_GNRC_IPV6_NIB_ABR +#define CONFIG_GNRC_IPV6_NIB_ABR CONFIG_GNRC_IPV6_NIB_6LBR +#endif + /** * @brief Include a Route Information Option for subnets * on other interfaces in normal Router Advertisements diff --git a/sys/include/net/netopt.h b/sys/include/net/netopt.h index 213418a7c33f5..fcda72e04f10a 100644 --- a/sys/include/net/netopt.h +++ b/sys/include/net/netopt.h @@ -563,6 +563,11 @@ typedef enum { */ NETOPT_6LO_IPHC, + /** + * @brief + */ + NETOPT_6LO_ABR, + /** * @brief (uint8_t) retry amount from missing ACKs of the last transmission * diff --git a/sys/net/gnrc/netif/gnrc_netif.c b/sys/net/gnrc/netif/gnrc_netif.c index 6b6619bfc086c..fae2e4287b50f 100644 --- a/sys/net/gnrc/netif/gnrc_netif.c +++ b/sys/net/gnrc/netif/gnrc_netif.c @@ -304,6 +304,15 @@ int gnrc_netif_get_from_netdev(gnrc_netif_t *netif, gnrc_netapi_opt_t *opt) res = sizeof(netopt_enable_t); break; #endif /* MODULE_GNRC_SIXLOWPAN_IPHC */ +#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_6LBR) + case NETOPT_6LO_ABR: + assert(opt->data_len == sizeof(netopt_enable_t)); + *((netopt_enable_t *)opt->data) = (netif->flags & GNRC_NETIF_FLAGS_6LO_ABR) + ? NETOPT_ENABLE + : NETOPT_DISABLE; + res = sizeof(netopt_enable_t); + break; +#endif default: break; } @@ -409,6 +418,28 @@ int gnrc_netif_set_from_netdev(gnrc_netif_t *netif, res = sizeof(netopt_enable_t); break; #endif /* MODULE_GNRC_SIXLOWPAN_IPHC */ +#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_6LBR) + case NETOPT_6LO_ABR: + assert(opt->data_len == sizeof(netopt_enable_t)); + + extern void _start_search_rtr(gnrc_netif_t *netif); + extern void _stop_search_rtr(gnrc_netif_t *netif); + + if (*(((netopt_enable_t *)opt->data)) == NETOPT_ENABLE) { + netif->flags |= GNRC_NETIF_FLAGS_6LO_ABR; + if (!(netif->flags & GNRC_NETIF_FLAGS_6LO_ABR)) { + _stop_search_rtr(netif); + } + } + else { + if (netif->flags & GNRC_NETIF_FLAGS_6LO_ABR) { + _start_search_rtr(netif); + } + netif->flags &= ~GNRC_NETIF_FLAGS_6LO_ABR; + } + res = sizeof(netopt_enable_t); + break; +#endif case NETOPT_RAWMODE: if (*(((netopt_enable_t *)opt->data)) == NETOPT_ENABLE) { netif->flags |= GNRC_NETIF_FLAGS_RAWMODE; diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-router.h b/sys/net/gnrc/network_layer/ipv6/nib/_nib-router.h index df08b67de480a..b6dfd5bfc327a 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-router.h +++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-router.h @@ -50,7 +50,7 @@ static inline void _init_iface_router(gnrc_netif_t *netif) netif->flags |= GNRC_NETIF_FLAGS_IPV6_RTR_ADV; } - if (IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_6LBR)) { + if (IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ABR)) { netif->flags |= GNRC_NETIF_FLAGS_6LO_ABR; } } diff --git a/sys/net/gnrc/network_layer/ipv6/nib/nib.c b/sys/net/gnrc/network_layer/ipv6/nib/nib.c index fbf99cea2e6ad..3f559612890a7 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/nib.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/nib.c @@ -108,8 +108,10 @@ static inline bool _should_search_rtr(const gnrc_netif_t *netif) /* 6LBR interface does not send RS. A non-advertising router sends RS or a 6LN that is advertising or not has to refetch router information */ - return !gnrc_netif_is_6lbr(netif) && - (!gnrc_netif_is_rtr_adv(netif) || gnrc_netif_is_6ln(netif)); + if (gnrc_netif_is_6lbr(netif)) { + return false; + } + return !gnrc_netif_is_rtr_adv(netif) || gnrc_netif_is_6ln(netif); } void gnrc_ipv6_nib_init(void) @@ -167,6 +169,19 @@ static void _add_static_lladdr(gnrc_netif_t *netif) #endif } +void _start_search_rtr(gnrc_netif_t *netif) +{ + uint32_t next_rs_time = random_uint32_range(0, NDP_MAX_RS_MS_DELAY); + + _evtimer_add(netif, GNRC_IPV6_NIB_SEARCH_RTR, &netif->ipv6.search_rtr, + next_rs_time); +} + +void _stop_search_rtr(gnrc_netif_t *netif) +{ + _evtimer_del(&netif->ipv6.search_rtr); +} + void gnrc_ipv6_nib_iface_up(gnrc_netif_t *netif) { assert(netif != NULL); @@ -185,11 +200,9 @@ void gnrc_ipv6_nib_iface_up(gnrc_netif_t *netif) } _add_static_lladdr(netif); _auto_configure_addr(netif, &ipv6_addr_link_local_prefix, 64U); - if (_should_search_rtr(netif)) { - uint32_t next_rs_time = random_uint32_range(0, NDP_MAX_RS_MS_DELAY); - _evtimer_add(netif, GNRC_IPV6_NIB_SEARCH_RTR, &netif->ipv6.search_rtr, - next_rs_time); + if (_should_search_rtr(netif)) { + _start_search_rtr(netif); } #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER) else { @@ -208,7 +221,7 @@ void gnrc_ipv6_nib_iface_down(gnrc_netif_t *netif, bool send_final_ra) _deinit_iface_arsm(netif); if (_should_search_rtr(netif)) { - _evtimer_del(&netif->ipv6.search_rtr); + _stop_search_rtr(netif); } #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER) else { diff --git a/sys/shell/cmds/gnrc_netif.c b/sys/shell/cmds/gnrc_netif.c index c827939a1f7dd..227e8733af6bc 100644 --- a/sys/shell/cmds/gnrc_netif.c +++ b/sys/shell/cmds/gnrc_netif.c @@ -62,6 +62,7 @@ static const struct { netopt_t opt; } flag_cmds[] = { { "6lo", NETOPT_6LO }, + { "abr", NETOPT_6LO_ABR }, { "ack_req", NETOPT_ACK_REQ }, { "gts", NETOPT_GTS_TX }, { "pan_coord", NETOPT_PAN_COORD }, @@ -887,6 +888,9 @@ static void _netif_list(netif_t *iface) #ifdef MODULE_GNRC_SIXLOWPAN line_thresh = _netif_list_flag(iface, NETOPT_6LO, "6LO ", line_thresh); #endif +#if CONFIG_GNRC_IPV6_NIB_6LBR + line_thresh = _netif_list_flag(iface, NETOPT_6LO_ABR, "ABR ", line_thresh); +#endif #ifdef MODULE_GNRC_SIXLOWPAN_IPHC line_thresh += _LINE_THRESHOLD + 1; /* enforce linebreak after this option */ line_thresh = _netif_list_flag(iface, NETOPT_6LO_IPHC, "IPHC ",