1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-25 22:43:50 +01:00

gnrc_uhcpc: update compression context with new prefix

This updates (or adds) a compression context whenever a new prefix
arrives at the border router. This allows 6LoWPAN to compress said
prefix in the network.

Sadly, there is now way to just remove the context when the prefix is
overwritten, so I do not do it. If an administrator chooses to reset the
prefix they can use `6ctx del` which timeouts the prefix appropriately,
but IMHO it doesn't hurt to keep the old contexts.
This commit is contained in:
Martine Lenders 2018-02-16 12:53:57 +01:00 committed by Martine S. Lenders
parent 6a416f894c
commit 8cc9c5ebe7
No known key found for this signature in database
GPG Key ID: CCD317364F63286F

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"
@ -54,6 +57,48 @@ 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) {
static ipv6_addr_t addr_str[IPV6_ADDR_MAX_STR_LEN];
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
@ -117,6 +169,11 @@ void uhcp_handle_prefix(uint8_t *prefix, uint8_t prefix_len, uint16_t lifetime,
puts("/64");
}
#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);
}