Skip to content

Commit

Permalink
RPL tunnel force functionality update
Browse files Browse the repository at this point in the history
Added API to force Link local tunneling.

Limit creation of multi-hop RPL packets
Previous code created multi-hop RPL packets as much as possible,
sending direct to border router in particular.
This has caused WiSUN interop problems, so limit this.
a) When creating a basic packet, have a policy option that prevents
   direct RPL header insertion, forcing tunnelling. This means
   we never put a RPL header on the innermost packet. Option is
   off by default, except for WiSUN, as it increases packet size
   when talking to the border router (eg DAOs).
b) When putting a packet into a tunnel, set the tunnel exit to the
   next hop always, rather than having a special case for exiting
   at the border router. This is probably a net benefit to packet
   size because of the LL addresses used on the outer header, so
   this is an unconditional change. Exception remains for local
   DODAGs, where the destination address must be the DODAGID.
  • Loading branch information
Juha Heiskanen committed Jan 21, 2021
1 parent 3207e5c commit 3e1064a
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 6 deletions.
6 changes: 6 additions & 0 deletions source/RPL/rpl_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,12 @@ void rpl_control_set_mrhof_parent_set_size(uint16_t parent_set_size)
rpl_policy_set_mrhof_parent_set_size(parent_set_size);
}

/* True Force RPL to use IPv6 tunneling when it send and forward data to Border router direction, This feature is disabled by default */
void rpl_control_set_force_tunnel(bool requested)
{
rpl_policy_force_tunnel_set(requested);
}

/* Send address registration to either specified address, or to non-registered address */
void rpl_control_register_address(protocol_interface_info_entry_t *interface, const uint8_t addr[16])
{
Expand Down
1 change: 1 addition & 0 deletions source/RPL/rpl_control.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ bool rpl_control_find_worst_neighbor(struct protocol_interface_info_entry *inter

/* Parent link confirmation API extension */
void rpl_control_request_parent_link_confirmation(bool requested);
void rpl_control_set_force_tunnel(bool requested);
void rpl_control_set_dio_multicast_min_config_advertisment_count(uint8_t min_count);
void rpl_control_set_address_registration_timeout(uint16_t timeout_in_minutes);
void rpl_control_set_dao_retry_count(uint8_t count);
Expand Down
30 changes: 24 additions & 6 deletions source/RPL/rpl_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,8 +334,24 @@ static buffer_t *rpl_data_exthdr_provider_hbh_2(buffer_t *buf, rpl_instance_t *i

bool destination_in_instance = false;
uint16_t ext_size = 0;
if (addr_ipv6_equal(route_info->next_hop_addr, buf->dst_sa.address) ||
addr_ipv6_equal(buf->dst_sa.address, dodag->id)) {

// Limit creation of multi-hop RPL packets
// Previous code created multi-hop RPL packets as much as possible,
// sending direct to border router in particular.
// This has caused WiSUN interop problems, so limit this.
// a) When creating a basic packet, have a policy option that prevents
// direct RPL header insertion, forcing tunnelling. This means
// we never put a RPL header on the innermost packet. Option is
// off by default, except for WiSUN, as it increases packet size
// when talking to the border router (eg DAOs).
// b) When putting a packet into a tunnel, set the tunnel exit to the
// next hop always, rather than having a special case for exiting
// at the border router. This is probably a net benefit to packet
// size because of the LL addresses used on the outer header, so
// this is an unconditional change. Exception remains for local
// DODAGs, where the destination address must be the DODAGID.
if (addr_ipv6_equal(route_info->next_hop_addr, buf->dst_sa.address) || (!rpl_policy_force_tunnel() &&
addr_ipv6_equal(buf->dst_sa.address, dodag->id))) {
destination_in_instance = true;

if (buf->rpl_option) {
Expand Down Expand Up @@ -409,10 +425,12 @@ static buffer_t *rpl_data_exthdr_provider_hbh_2(buffer_t *buf, rpl_instance_t *i
rpl_data_locate_info(buf, &opt, NULL);
if (!opt) {
*result = IPV6_EXTHDR_MODIFY_TUNNEL;
// Tunnel to next hop in general case, but if going to DODAGID,
// it can tunnel all the way (and it HAS to if it is a local
// DODAG).
if (!addr_ipv6_equal(buf->dst_sa.address, dodag->id)) {
// Tunnel to next hop always, even if we could tunnel all
// the way to DODAG root (this may be better for
// packet compression, and it was found to be necessary for
// Wi-SUN interoperability). Except for local DODAGs the
// destination must be the DODAGID, so retain that in dst_sa.
if (!rpl_instance_id_is_local(instance->id)) {
memcpy(buf->dst_sa.address, route_info->next_hop_addr, 16);
}
buf->src_sa.addr_type = ADDR_NONE; // force auto-selection
Expand Down
11 changes: 11 additions & 0 deletions source/RPL/rpl_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ static uint8_t rpl_policy_mrhof_parent_set_size_conf = 3; // default parent set
static uint16_t rpl_policy_minimum_dao_target_refresh_conf = 0; // by default follow the configuration
static uint16_t rpl_policy_address_registration_timeout_value = 0; // Address registration timeouts in minutes 0 use address lifetime

static bool rpl_policy_force_tunnel_to_BR = false;

bool rpl_policy_force_tunnel(void)
{
return rpl_policy_force_tunnel_to_BR;
}

void rpl_policy_force_tunnel_set(bool enable)
{
rpl_policy_force_tunnel_to_BR = enable;
}
/* TODO - application API to control when to join new instances / DODAGs
*
* Eg, allow application to ignore local DODAGs, or specify known instance IDs,
Expand Down
3 changes: 3 additions & 0 deletions source/RPL/rpl_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#include "Core/include/ns_address_internal.h"
#include "rpl_control.h"

bool rpl_policy_force_tunnel(void);
void rpl_policy_force_tunnel_set(bool enable);

bool rpl_policy_join_instance(rpl_domain_t *domain, uint8_t instance_id, const uint8_t *dodagid);
bool rpl_policy_join_dodag(rpl_domain_t *domain, uint8_t g_mop_prf, uint8_t instance_id, const uint8_t *dodagid);
bool rpl_policy_join_config(rpl_domain_t *domain, const rpl_dodag_conf_t *conf, bool *leaf_only);
Expand Down
5 changes: 5 additions & 0 deletions test/nanostack/unittest/stub/rpl_control_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,11 @@ void rpl_control_set_minimum_dao_target_refresh(uint16_t seconds)

}

void rpl_control_set_force_tunnel(bool requested)
{

}

void rpl_control_set_initial_dao_ack_wait(uint16_t timeout_in_ms)
{

Expand Down
9 changes: 9 additions & 0 deletions test/nanostack/unittest/stub/rpl_policy_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@

#define TRACE_GROUP "RPLy"

bool rpl_policy_force_tunnel(void)
{
return false;
}
void rpl_policy_force_tunnel_set(bool enable)
{

}


bool rpl_policy_join_instance(rpl_domain_t *domain, uint8_t instance_id, const uint8_t *dodagid)
{
Expand Down

0 comments on commit 3e1064a

Please sign in to comment.