mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-27 07:21:18 +01:00
Merge pull request #8128 from miri64/gnrc_rpl/fix/fix-todos
gnrc_rpl: do some important TODOs (like prefix list handling and netif checks)
This commit is contained in:
commit
bd6baab16b
@ -27,6 +27,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "byteorder.h"
|
||||
#include "net/ipv6/addr.h"
|
||||
#include "xtimer.h"
|
||||
#include "trickle.h"
|
||||
@ -189,14 +190,16 @@ typedef struct __attribute__((packed)) {
|
||||
* </a>
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type; /**< option type */
|
||||
uint8_t length; /**< option length without the first two bytes */
|
||||
uint8_t prefix_len; /**< prefix length */
|
||||
uint8_t LAR_flags; /**< flags and resereved */
|
||||
uint32_t valid_lifetime; /**< valid lifetime */
|
||||
uint32_t pref_lifetime; /**< preferred lifetime */
|
||||
uint32_t reserved; /**< reserved */
|
||||
ipv6_addr_t prefix; /**< prefix used for Stateless Address Autoconfiguration */
|
||||
uint8_t type; /**< option type */
|
||||
uint8_t length; /**< option length without the first
|
||||
* two bytes */
|
||||
uint8_t prefix_len; /**< prefix length */
|
||||
uint8_t LAR_flags; /**< flags and resereved */
|
||||
network_uint32_t valid_lifetime; /**< valid lifetime */
|
||||
network_uint32_t pref_lifetime; /**< preferred lifetime */
|
||||
uint32_t reserved; /**< reserved */
|
||||
ipv6_addr_t prefix; /**< prefix used for Stateless Address
|
||||
* Autoconfiguration */
|
||||
} gnrc_rpl_opt_prefix_info_t;
|
||||
|
||||
/**
|
||||
|
||||
@ -78,7 +78,7 @@ void gnrc_rpl_send(gnrc_pktsnip_t *pkt, kernel_pid_t iface, ipv6_addr_t *src, ip
|
||||
if (iface == KERNEL_PID_UNDEF) {
|
||||
netif = _find_interface_with_rpl_mcast();
|
||||
|
||||
if (netif == KERNEL_PID_UNDEF) {
|
||||
if (netif == NULL) {
|
||||
DEBUG("RPL: no suitable interface found for this destination address\n");
|
||||
gnrc_pktbuf_release(pkt);
|
||||
return;
|
||||
@ -150,10 +150,25 @@ gnrc_pktsnip_t *_dio_dodag_conf_build(gnrc_pktsnip_t *pkt, gnrc_rpl_dodag_t *dod
|
||||
}
|
||||
|
||||
#ifndef GNRC_RPL_WITHOUT_PIO
|
||||
static bool _get_pl_entry(unsigned iface, ipv6_addr_t *pfx,
|
||||
unsigned pfx_len, gnrc_ipv6_nib_pl_t *ple)
|
||||
{
|
||||
void *state = NULL;
|
||||
|
||||
while (gnrc_ipv6_nib_pl_iter(iface, &state, ple)) {
|
||||
if (ipv6_addr_match_prefix(&ple->pfx, pfx) >= pfx_len) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
gnrc_pktsnip_t *_dio_prefix_info_build(gnrc_pktsnip_t *pkt, gnrc_rpl_dodag_t *dodag)
|
||||
{
|
||||
gnrc_ipv6_nib_pl_t ple;
|
||||
gnrc_rpl_opt_prefix_info_t *prefix_info;
|
||||
gnrc_pktsnip_t *opt_snip;
|
||||
|
||||
if ((opt_snip = gnrc_pktbuf_add(pkt, NULL, sizeof(gnrc_rpl_opt_prefix_info_t),
|
||||
GNRC_NETTYPE_UNDEF)) == NULL) {
|
||||
DEBUG("RPL: BUILD PREFIX INFO - no space left in packet buffer\n");
|
||||
@ -165,10 +180,18 @@ gnrc_pktsnip_t *_dio_prefix_info_build(gnrc_pktsnip_t *pkt, gnrc_rpl_dodag_t *do
|
||||
prefix_info->length = GNRC_RPL_OPT_PREFIX_INFO_LEN;
|
||||
/* auto-address configuration */
|
||||
prefix_info->LAR_flags = GNRC_RPL_PREFIX_AUTO_ADDRESS_BIT;
|
||||
/* TODO: Get real values from NIB_PL */
|
||||
prefix_info->valid_lifetime = UINT32_MAX;
|
||||
prefix_info->pref_lifetime = UINT32_MAX;
|
||||
prefix_info->prefix_len = 64;
|
||||
if (_get_pl_entry(dodag->iface, &dodag->dodag_id, prefix_info->prefix_len,
|
||||
&ple)) {
|
||||
uint32_t now = (xtimer_now_usec64() / US_PER_MS) & UINT32_MAX;
|
||||
prefix_info->valid_lifetime = byteorder_htonl((ple.valid_until - now) / MS_PER_SEC);
|
||||
prefix_info->pref_lifetime = byteorder_htonl((ple.pref_until - now) / MS_PER_SEC);
|
||||
}
|
||||
else {
|
||||
DEBUG("RPL: Prefix of DODAG-ID not in prefix list\n");
|
||||
gnrc_pktbuf_release(pkt);
|
||||
return NULL;
|
||||
}
|
||||
prefix_info->reserved = 0;
|
||||
|
||||
memset(&prefix_info->prefix, 0, sizeof(prefix_info->prefix));
|
||||
@ -403,9 +426,13 @@ bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt_t *opt
|
||||
break;
|
||||
}
|
||||
ipv6_addr_set_aiid(&pi->prefix, iid.uint8);
|
||||
/* TODO: find a way to do this with DAD (i.e. state != VALID) */
|
||||
gnrc_netif_ipv6_addr_add(netif, &pi->prefix, pi->prefix_len,
|
||||
GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_VALID);
|
||||
/* TODO: add to prefix list */
|
||||
/* set lifetimes */
|
||||
gnrc_ipv6_nib_pl_set(netif->pid, &pi->prefix, pi->prefix_len,
|
||||
byteorder_ntohl(pi->valid_lifetime) * MS_PER_SEC,
|
||||
byteorder_ntohl(pi->pref_lifetime) * MS_PER_SEC);
|
||||
|
||||
break;
|
||||
|
||||
@ -488,6 +515,7 @@ void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src
|
||||
|
||||
if (gnrc_rpl_instance_add(dio->instance_id, &inst)) {
|
||||
/* new instance and DODAG */
|
||||
gnrc_netif_t *netif;
|
||||
|
||||
if (byteorder_ntohs(dio->rank) == GNRC_RPL_INFINITE_RANK) {
|
||||
DEBUG("RPL: ignore INFINITE_RANK DIO when we are not yet part of this DODAG\n");
|
||||
@ -499,13 +527,14 @@ void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src
|
||||
inst->of = gnrc_rpl_get_of_for_ocp(GNRC_RPL_DEFAULT_OCP);
|
||||
|
||||
if (iface == KERNEL_PID_UNDEF) {
|
||||
gnrc_netif_t *netif = _find_interface_with_rpl_mcast();
|
||||
|
||||
iface = netif->pid;
|
||||
assert(iface != KERNEL_PID_UNDEF);
|
||||
netif = _find_interface_with_rpl_mcast();
|
||||
}
|
||||
else {
|
||||
netif = gnrc_netif_get_by_pid(iface);
|
||||
}
|
||||
assert(netif != NULL);
|
||||
|
||||
gnrc_rpl_dodag_init(inst, &dio->dodag_id, iface);
|
||||
gnrc_rpl_dodag_init(inst, &dio->dodag_id, netif->pid);
|
||||
|
||||
dodag = &inst->dodag;
|
||||
|
||||
@ -546,7 +575,15 @@ void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src
|
||||
#endif
|
||||
}
|
||||
|
||||
/* TODO: create prefix list entry */
|
||||
/* if there was no address created manually or by a PIO on the interface,
|
||||
* leave this DODAG */
|
||||
if (gnrc_netif_ipv6_addr_match(netif, &dodag->dodag_id) < 0) {
|
||||
DEBUG("RPL: no IPv6 address configured on interface %i to match the "
|
||||
"given dodag id: %s\n", netif->pid,
|
||||
ipv6_addr_to_str(addr_str, &(dodag->dodag_id), sizeof(addr_str)));
|
||||
gnrc_rpl_instance_remove(inst);
|
||||
return;
|
||||
}
|
||||
|
||||
gnrc_rpl_delay_dao(dodag);
|
||||
trickle_start(gnrc_rpl_pid, &dodag->trickle, GNRC_RPL_MSG_TYPE_TRICKLE_MSG,
|
||||
|
||||
@ -131,8 +131,6 @@ gnrc_rpl_instance_t *gnrc_rpl_instance_get(uint8_t instance_id)
|
||||
|
||||
bool gnrc_rpl_dodag_init(gnrc_rpl_instance_t *instance, ipv6_addr_t *dodag_id, kernel_pid_t iface)
|
||||
{
|
||||
/* TODO: check if netif_addr belongs to iface */
|
||||
|
||||
assert(instance && (instance->state > 0));
|
||||
|
||||
gnrc_rpl_dodag_t *dodag = &instance->dodag;
|
||||
@ -342,7 +340,6 @@ gnrc_rpl_instance_t *gnrc_rpl_root_instance_init(uint8_t instance_id, ipv6_addr_
|
||||
gnrc_netif_t *netif;
|
||||
gnrc_rpl_instance_t *inst = NULL;
|
||||
gnrc_rpl_dodag_t *dodag = NULL;
|
||||
kernel_pid_t iface;
|
||||
|
||||
if (!(ipv6_addr_is_global(dodag_id) || ipv6_addr_is_unique_local_unicast(dodag_id))) {
|
||||
DEBUG("RPL: dodag id (%s) must be a global or unique local IPv6 address\n",
|
||||
@ -355,7 +352,6 @@ gnrc_rpl_instance_t *gnrc_rpl_root_instance_init(uint8_t instance_id, ipv6_addr_
|
||||
ipv6_addr_to_str(addr_str, dodag_id, sizeof(addr_str)));
|
||||
return NULL;
|
||||
}
|
||||
iface = netif->pid;
|
||||
|
||||
if (gnrc_rpl_instance_add(instance_id, &inst)) {
|
||||
inst->of = (gnrc_rpl_of_t *) gnrc_rpl_get_of_for_ocp(GNRC_RPL_DEFAULT_OCP);
|
||||
@ -372,7 +368,7 @@ gnrc_rpl_instance_t *gnrc_rpl_root_instance_init(uint8_t instance_id, ipv6_addr_
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!gnrc_rpl_dodag_init(inst, dodag_id, iface)) {
|
||||
if (!gnrc_rpl_dodag_init(inst, dodag_id, netif->pid)) {
|
||||
DEBUG("RPL: could not initialize DODAG\n");
|
||||
gnrc_rpl_instance_remove(inst);
|
||||
return NULL;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user