Merge pull request #8576 from miri64/gnrc_uhcpc/enh/update-context

gnrc_uhcpc: update compression context with new prefix
This commit is contained in:
Koen Zandberg 2020-02-26 14:20:44 +01:00 committed by GitHub
commit ad7c19d584
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -13,6 +13,9 @@
#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"
@ -21,6 +24,7 @@
#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;
@ -54,6 +58,47 @@ static void set_interface_roles(void)
static ipv6_addr_t _prefix;
#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->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)prefix_len;
@ -82,10 +127,17 @@ void uhcp_handle_prefix(uint8_t *prefix, uint8_t prefix_len, uint16_t lifetime,
if (ipv6_addr_equal(&_prefix, (ipv6_addr_t*)prefix)) {
LOG_WARNING("gnrc_uhcpc: uhcp_handle_prefix(): got same prefix again\n");
#ifdef MODULE_GNRC_SIXLOWPAN_CTX
/* 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, 64);
#endif
return;
}
gnrc_netapi_set(gnrc_wireless_interface, NETOPT_IPV6_ADDR, (64 << 8),
/* always update 6LoWPAN compression context so it does not time out, we
* can't just remove it anyway according to the RFC */
prefix, sizeof(ipv6_addr_t));
#if defined(MODULE_GNRC_IPV6_NIB) && GNRC_IPV6_NIB_CONF_6LBR && \
GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
@ -101,9 +153,8 @@ void uhcp_handle_prefix(uint8_t *prefix, uint8_t prefix_len, uint16_t lifetime,
#endif
gnrc_netapi_set(gnrc_wireless_interface, NETOPT_IPV6_ADDR_REMOVE, 0,
&_prefix, sizeof(_prefix));
print_str("gnrc_uhcpc: uhcp_handle_prefix(): configured new prefix ");
ipv6_addr_print((ipv6_addr_t*)prefix);
puts("/64");
LOG_INFO("gnrc_uhcpc: uhcp_handle_prefix(): configured new prefix %s/64\n",
ipv6_addr_to_str(addr_str, (ipv6_addr_t *)prefix, sizeof(addr_str)));
if (!ipv6_addr_is_unspecified(&_prefix)) {
gnrc_netapi_set(gnrc_wireless_interface, NETOPT_IPV6_ADDR_REMOVE, 0,
@ -112,11 +163,15 @@ void uhcp_handle_prefix(uint8_t *prefix, uint8_t prefix_len, uint16_t lifetime,
GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
gnrc_ipv6_nib_abr_del(&_prefix);
#endif
print_str("gnrc_uhcpc: uhcp_handle_prefix(): removed old prefix ");
ipv6_addr_print(&_prefix);
puts("/64");
LOG_INFO("gnrc_uhcpc: uhcp_handle_prefix(): removed old prefix %s/64\n",
ipv6_addr_to_str(addr_str, &_prefix, sizeof(addr_str)));
}
#ifdef MODULE_GNRC_SIXLOWPAN_CTX
/* update compression context last in case previous context was removed by
* gnrc_ipv6_nib_abr_del() above */
_update_6ctx((ipv6_addr_t *)prefix, 64);
#endif
memcpy(&_prefix, prefix, 16);
}