|
|
|
@ -95,6 +95,17 @@ static void _add_ctx(gnrc_sixlowpan_nd_router_abr_t *abr, sixlowpan_nd_opt_6ctx_
|
|
|
|
|
bf_set(abr->ctxs, sixlowpan_nd_opt_6ctx_get_cid(ctx_opt));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER
|
|
|
|
|
static inline bool _is_me(ipv6_addr_t *addr)
|
|
|
|
|
{
|
|
|
|
|
ipv6_addr_t *res;
|
|
|
|
|
|
|
|
|
|
return (gnrc_ipv6_netif_find_by_addr(&res, addr) != KERNEL_PID_UNDEF);
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
#define _is_me(ignore) (false)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
gnrc_sixlowpan_nd_router_abr_t *gnrc_sixlowpan_nd_router_abr_get(void)
|
|
|
|
|
{
|
|
|
|
|
if (ipv6_addr_is_unspecified(&_abrs[0].addr)) {
|
|
|
|
@ -113,6 +124,10 @@ bool gnrc_sixlowpan_nd_router_abr_older(sixlowpan_nd_opt_abr_t *abr_opt)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_is_me(&abr_opt->braddr)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
abr = _get_abr(&abr_opt->braddr);
|
|
|
|
|
|
|
|
|
|
if (abr == NULL) {
|
|
|
|
@ -155,9 +170,11 @@ void gnrc_sixlowpan_nd_opt_abr_handle(kernel_pid_t iface, ndp_rtr_adv_t *rtr_adv
|
|
|
|
|
gnrc_sixlowpan_nd_router_abr_t *abr;
|
|
|
|
|
timex_t t = { 0, 0 };
|
|
|
|
|
|
|
|
|
|
if (_is_me(&abr_opt->braddr)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/* validity and version was checked in previously called
|
|
|
|
|
* gnrc_sixlowpan_nd_router_abr_older() */
|
|
|
|
|
|
|
|
|
|
abr = _get_abr(&abr_opt->braddr);
|
|
|
|
|
|
|
|
|
|
if (abr == NULL) {
|
|
|
|
@ -167,7 +184,7 @@ void gnrc_sixlowpan_nd_opt_abr_handle(kernel_pid_t iface, ndp_rtr_adv_t *rtr_adv
|
|
|
|
|
abr->ltime = byteorder_ntohs(abr_opt->ltime);
|
|
|
|
|
|
|
|
|
|
if (abr->ltime == 0) {
|
|
|
|
|
gnrc_sixlowpan_nd_router_abr_remove(abr);
|
|
|
|
|
abr->ltime = GNRC_SIXLOWPAN_ND_BORDER_ROUTER_DEFAULT_LTIME;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -242,4 +259,99 @@ gnrc_pktsnip_t *gnrc_sixlowpan_nd_opt_abr_build(uint32_t version, uint16_t ltime
|
|
|
|
|
return pkt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER
|
|
|
|
|
gnrc_sixlowpan_nd_router_abr_t *gnrc_sixlowpan_nd_router_abr_create(ipv6_addr_t *addr,
|
|
|
|
|
unsigned int ltime)
|
|
|
|
|
{
|
|
|
|
|
assert(addr != NULL);
|
|
|
|
|
gnrc_sixlowpan_nd_router_abr_t *abr = _get_abr(addr);
|
|
|
|
|
if (abr == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
/* TODO: store and get this somewhere stable */
|
|
|
|
|
abr->version = 0;
|
|
|
|
|
abr->ltime = (uint16_t)ltime;
|
|
|
|
|
abr->addr.u64[0] = addr->u64[0];
|
|
|
|
|
abr->addr.u64[1] = addr->u64[1];
|
|
|
|
|
memset(abr->ctxs, 0, sizeof(abr->ctxs));
|
|
|
|
|
abr->prfs = NULL;
|
|
|
|
|
return abr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int gnrc_sixlowpan_nd_router_abr_add_prf(gnrc_sixlowpan_nd_router_abr_t* abr,
|
|
|
|
|
gnrc_ipv6_netif_t *iface, gnrc_ipv6_netif_addr_t *prefix)
|
|
|
|
|
{
|
|
|
|
|
assert((iface != NULL) && (prefix != NULL));
|
|
|
|
|
gnrc_sixlowpan_nd_router_prf_t *prf_ent;
|
|
|
|
|
if ((abr < _abrs) || (abr > (_abrs + GNRC_SIXLOWPAN_ND_ROUTER_ABR_NUMOF))) {
|
|
|
|
|
return -ENOENT;
|
|
|
|
|
}
|
|
|
|
|
prf_ent = _get_free_prefix(&prefix->addr, prefix->prefix_len);
|
|
|
|
|
if (prf_ent == NULL) {
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
}
|
|
|
|
|
prf_ent->iface = iface;
|
|
|
|
|
prf_ent->prefix = prefix;
|
|
|
|
|
LL_PREPEND(abr->prfs, prf_ent);
|
|
|
|
|
abr->version++; /* TODO: store somewhere stable */
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void gnrc_sixlowpan_nd_router_abr_rem_prf(gnrc_sixlowpan_nd_router_abr_t *abr,
|
|
|
|
|
gnrc_ipv6_netif_t *iface, gnrc_ipv6_netif_addr_t *prefix)
|
|
|
|
|
{
|
|
|
|
|
assert((iface != NULL) && (prefix != NULL));
|
|
|
|
|
gnrc_sixlowpan_nd_router_prf_t *prf_ent = abr->prfs, *prev = NULL;
|
|
|
|
|
if ((abr < _abrs) || (abr > (_abrs + GNRC_SIXLOWPAN_ND_ROUTER_ABR_NUMOF))) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
while (prf_ent) {
|
|
|
|
|
if (prf_ent->prefix == prefix) {
|
|
|
|
|
if (prev == NULL) {
|
|
|
|
|
abr->prfs = prf_ent->next;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
prev->next = prf_ent->next;
|
|
|
|
|
}
|
|
|
|
|
prf_ent->next = NULL;
|
|
|
|
|
prf_ent->iface = NULL;
|
|
|
|
|
prf_ent->prefix = NULL;
|
|
|
|
|
abr->version++; /* TODO: store somewhere stable */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
prev = prf_ent;
|
|
|
|
|
prf_ent = prf_ent->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int gnrc_sixlowpan_nd_router_abr_add_ctx(gnrc_sixlowpan_nd_router_abr_t *abr, uint8_t cid)
|
|
|
|
|
{
|
|
|
|
|
if ((abr < _abrs) || (abr > (_abrs + GNRC_SIXLOWPAN_ND_ROUTER_ABR_NUMOF))) {
|
|
|
|
|
return -ENOENT;
|
|
|
|
|
}
|
|
|
|
|
if (cid >= GNRC_SIXLOWPAN_CTX_SIZE) {
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
if (bf_isset(abr->ctxs, cid)) {
|
|
|
|
|
return -EADDRINUSE;
|
|
|
|
|
}
|
|
|
|
|
bf_set(abr->ctxs, cid);
|
|
|
|
|
abr->version++; /* TODO: store somewhere stable */
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void gnrc_sixlowpan_nd_router_abr_rem_ctx(gnrc_sixlowpan_nd_router_abr_t *abr, uint8_t cid)
|
|
|
|
|
{
|
|
|
|
|
if ((abr < _abrs) || (abr > (_abrs + GNRC_SIXLOWPAN_ND_ROUTER_ABR_NUMOF))) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (cid >= GNRC_SIXLOWPAN_CTX_SIZE) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
bf_unset(abr->ctxs, cid);
|
|
|
|
|
abr->version++; /* TODO: store somewhere stable */
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
/** @} */
|
|
|
|
|