net: rpl: Fix compile errors

This fixes RPL compile errors if CONFIG_NETWORKING_WITH_RPL is
enabled. The end result is not tested atm so RPL might not yet
work as expected.

Change-Id: I458c20f8f8c7c750cc17f24acf425f244399699d
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2015-06-12 16:15:47 +03:00 committed by Anas Nashif
commit e0509c5e6f
14 changed files with 337 additions and 313 deletions

View file

@ -52,6 +52,11 @@ typedef unsigned int uip_stats_t;
#endif
#define NETSTACK_CONF_LLSEC nullsec_driver
#ifdef CONFIG_NETWORKING_WITH_RPL
#define UIP_MCAST6_CONF_ENGINE UIP_MCAST6_ENGINE_SMRF
#define UIP_CONF_IPV6_MULTICAST 1
#endif
#ifndef NETSTACK_CONF_RADIO
/* #error "No radio configured, cannot continue!" */
#endif

View file

@ -641,7 +641,7 @@ tcpip_ipv6_output(struct net_buf *buf)
if(dag != NULL) {
instance = dag->instance;
rpl_repair_root(instance->instance_id);
rpl_repair_root(buf, instance->instance_id);
}
#endif /* UIP_CONF_IPV6_RPL */
uip_ds6_route_rm(route);
@ -669,7 +669,7 @@ tcpip_ipv6_output(struct net_buf *buf)
/* End of next hop determination */
#if UIP_CONF_IPV6_RPL
if(rpl_update_header_final(nexthop)) {
if(rpl_update_header_final(buf, nexthop)) {
uip_len(buf) = 0;
return 0;
}

View file

@ -1741,7 +1741,7 @@ typedef struct uip_ext_hdr {
typedef struct uip_hbho_hdr {
uint8_t next;
uint8_t len;
} uip_hbho_hdr;
} PACK_ALIAS_STRUCT uip_hbho_hdr;
/* destination option header */
typedef struct uip_desto_hdr {
@ -1796,7 +1796,7 @@ typedef struct uip_ext_hdr_opt_rpl {
uint8_t flags;
uint8_t instance;
uint16_t senderrank;
} uip_ext_hdr_opt_rpl;
} PACK_ALIAS_STRUCT uip_ext_hdr_opt_rpl;
/* TCP header */
struct uip_tcp_hdr {

View file

@ -41,6 +41,8 @@
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include <net/net_buf.h>
#include "contiki.h"
#include "contiki-net.h"
#include "net/ipv6/multicast/uip-mcast6.h"
@ -49,6 +51,7 @@
#include "net/ipv6/multicast/smrf.h"
#include "net/rpl/rpl.h"
#include "net/netstack.h"
#include "contiki/os/lib/random.h"
#include <string.h>
#define DEBUG DEBUG_NONE
@ -65,27 +68,27 @@
/* Internal Data */
/*---------------------------------------------------------------------------*/
static struct ctimer mcast_periodic;
static uint8_t mcast_len;
static uip_buf_t mcast_buf;
static struct net_buf netbuf;
static uint8_t fwd_delay;
static uint8_t fwd_spread;
/*---------------------------------------------------------------------------*/
/* uIPv6 Pointers */
/*---------------------------------------------------------------------------*/
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN])
/*---------------------------------------------------------------------------*/
static void
mcast_fwd(void *p)
mcast_fwd(struct net_mbuf *mbuf, void *p)
{
memcpy(uip_buf, &mcast_buf, mcast_len);
uip_len = mcast_len;
UIP_IP_BUF->ttl--;
tcpip_output(NULL);
uip_len = 0;
struct net_buf *buf = (struct net_buf *)mbuf;
UIP_IP_BUF(buf)->ttl--;
tcpip_output(buf, NULL);
uip_len(buf) = 0;
}
/*---------------------------------------------------------------------------*/
static uint8_t
in()
in(struct net_buf *buf)
{
rpl_dag_t *d; /* Our DODAG */
uip_ipaddr_t *parent_ipaddr; /* Our pref. parent's IPv6 address */
@ -118,14 +121,14 @@ in()
* We accept a datagram if it arrived from our preferred parent, discard
* otherwise.
*/
if(memcmp(parent_lladdr, packetbuf_addr(PACKETBUF_ADDR_SENDER),
if(memcmp(parent_lladdr, &buf->src,
UIP_LLADDR_LEN)) {
PRINTF("SMRF: Routable in but SMRF ignored it\n");
UIP_MCAST6_STATS_ADD(mcast_dropped);
return UIP_MCAST6_DROP;
}
if(UIP_IP_BUF->ttl <= 1) {
if(UIP_IP_BUF(buf)->ttl <= 1) {
UIP_MCAST6_STATS_ADD(mcast_dropped);
return UIP_MCAST6_DROP;
}
@ -135,7 +138,7 @@ in()
/* If we have an entry in the mcast routing table, something with
* a higher RPL rank (somewhere down the tree) is a group member */
if(uip_mcast6_route_lookup(&UIP_IP_BUF->destipaddr)) {
if(uip_mcast6_route_lookup(&UIP_IP_BUF(buf)->destipaddr)) {
/* If we enter here, we will definitely forward */
UIP_MCAST6_STATS_ADD(mcast_fwd);
@ -155,9 +158,9 @@ in()
if(fwd_delay == 0) {
/* No delay required, send it, do it now, why wait? */
UIP_IP_BUF->ttl--;
tcpip_output(NULL);
UIP_IP_BUF->ttl++; /* Restore before potential upstack delivery */
UIP_IP_BUF(buf)->ttl--;
tcpip_output(buf, NULL);
UIP_IP_BUF(buf)->ttl++; /* Restore before potential upstack delivery */
} else {
/* Randomise final delay in [D , D*Spread], step D */
fwd_spread = SMRF_INTERVAL_COUNT;
@ -168,16 +171,15 @@ in()
fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread));
}
memcpy(&mcast_buf, uip_buf, uip_len);
mcast_len = uip_len;
ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL);
memcpy(&netbuf, buf, sizeof(*buf));
ctimer_set((struct net_mbuf *)&netbuf, &mcast_periodic, fwd_delay, mcast_fwd, NULL);
}
PRINTF("SMRF: %u bytes: fwd in %u [%u]\n",
uip_len, fwd_delay, fwd_spread);
uip_len(buf), fwd_delay, fwd_spread);
}
/* Done with this packet unless we are a member of the mcast group */
if(!uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) {
if(!uip_ds6_is_my_maddr(&UIP_IP_BUF(buf)->destipaddr)) {
PRINTF("SMRF: Not a group member. No further processing\n");
return UIP_MCAST6_DROP;
} else {

View file

@ -59,6 +59,8 @@
#ifndef UIP_MCAST6_H_
#define UIP_MCAST6_H_
#include <net/net_buf.h>
#include "contiki-conf.h"
#include "net/ipv6/multicast/uip-mcast6-engines.h"
#include "net/ipv6/multicast/uip-mcast6-route.h"
@ -134,7 +136,7 @@ struct uip_mcast6_driver {
* return value whether the datagram needs delivered up the network
* stack.
*/
uint8_t (* in)(void);
uint8_t (* in)(struct net_buf *buf);
};
/*---------------------------------------------------------------------------*/
/**

View file

@ -155,7 +155,7 @@ echo_request_input(struct net_buf *buf)
if(uip_ext_len(buf) > 0) {
#if UIP_CONF_IPV6_RPL
if((temp_ext_len = rpl_invert_header())) {
if((temp_ext_len = rpl_invert_header(buf))) {
/* If there were other extension headers*/
UIP_FIRST_EXT_BUF(buf)->next = UIP_PROTO_ICMP6;
if (uip_ext_len(buf) != temp_ext_len) {
@ -230,7 +230,7 @@ uip_icmp6_error_output(struct net_buf *buf, uint8_t type, uint8_t code, uint32_t
}
#if UIP_CONF_IPV6_RPL
uip_ext_len(buf) = rpl_invert_header();
uip_ext_len(buf) = rpl_invert_header(buf);
#else /* UIP_CONF_IPV6_RPL */
uip_ext_len(buf) = 0;
#endif /* UIP_CONF_IPV6_RPL */
@ -339,7 +339,7 @@ echo_reply_input(struct net_buf *buf)
if(uip_ext_len(buf) > 0) {
#if UIP_CONF_IPV6_RPL
if((temp_ext_len = rpl_invert_header())) {
if((temp_ext_len = rpl_invert_header(buf))) {
/* If there were other extension headers*/
UIP_FIRST_EXT_BUF(buf)->next = UIP_PROTO_ICMP6;
if (uip_ext_len(buf) != temp_ext_len) {

View file

@ -903,7 +903,7 @@ ext_hdr_options_process(struct net_buf *buf)
*/
#if UIP_CONF_IPV6_RPL
PRINTF("Processing RPL option\n");
if(rpl_verify_header(uip_ext_opt_offset(buf))) {
if(rpl_verify_header(buf, uip_ext_opt_offset(buf))) {
PRINTF("RPL Option Error: Dropping Packet\n");
return 1;
}
@ -1605,7 +1605,7 @@ uip_process(struct net_buf *buf, uint8_t flag)
#endif /* UIP_UDP_CHECKSUMS */
#if UIP_CONF_IPV6_RPL
rpl_insert_header();
rpl_insert_header(buf);
#endif /* UIP_CONF_IPV6_RPL */
UIP_STAT(++uip_stat.udp.sent);

View file

@ -97,7 +97,7 @@ rpl_get_nbr(rpl_parent_t *parent)
static void
nbr_callback(void *ptr)
{
rpl_remove_parent(ptr);
rpl_remove_parent(rpl_get_netbuf(), ptr);
}
void
@ -188,7 +188,7 @@ lollipop_greater_than(int a, int b)
/*---------------------------------------------------------------------------*/
/* Remove DAG parents with a rank that is at least the same as minimum_rank. */
static void
remove_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
remove_parents(struct net_buf *buf, rpl_dag_t *dag, rpl_rank_t minimum_rank)
{
rpl_parent_t *p;
@ -198,14 +198,14 @@ remove_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
p = nbr_table_head(rpl_parents);
while(p != NULL) {
if(dag == p->dag && p->rank >= minimum_rank) {
rpl_remove_parent(p);
rpl_remove_parent(buf, p);
}
p = nbr_table_next(rpl_parents, p);
}
}
/*---------------------------------------------------------------------------*/
static void
nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
nullify_parents(struct net_buf *buf, rpl_dag_t *dag, rpl_rank_t minimum_rank)
{
rpl_parent_t *p;
@ -215,7 +215,7 @@ nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
p = nbr_table_head(rpl_parents);
while(p != NULL) {
if(dag == p->dag && p->rank >= minimum_rank) {
rpl_nullify_parent(p);
rpl_nullify_parent(buf, p);
}
p = nbr_table_next(rpl_parents, p);
}
@ -264,7 +264,7 @@ get_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
}
/*---------------------------------------------------------------------------*/
rpl_dag_t *
rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
rpl_set_root(struct net_buf *buf, uint8_t instance_id, uip_ipaddr_t *dag_id)
{
rpl_dag_t *dag;
rpl_instance_t *instance;
@ -279,10 +279,10 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
if(dag == dag->instance->current_dag) {
dag->instance->current_dag = NULL;
}
rpl_free_dag(dag);
rpl_free_dag(buf, dag);
}
dag = rpl_alloc_dag(instance_id, dag_id);
dag = rpl_alloc_dag(buf, instance_id, dag_id);
if(dag == NULL) {
PRINTF("RPL: Failed to allocate a DAG\n");
return NULL;
@ -332,13 +332,13 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
ANNOTATE("#A root=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]);
rpl_reset_dio_timer(instance);
rpl_reset_dio_timer(buf, instance);
return dag;
}
/*---------------------------------------------------------------------------*/
int
rpl_repair_root(uint8_t instance_id)
rpl_repair_root(struct net_buf *buf, uint8_t instance_id)
{
rpl_instance_t *instance;
@ -353,7 +353,7 @@ rpl_repair_root(uint8_t instance_id)
RPL_LOLLIPOP_INCREMENT(instance->current_dag->version);
RPL_LOLLIPOP_INCREMENT(instance->dtsn_out);
PRINTF("RPL: rpl_repair_root initiating global repair with version %d\n", instance->current_dag->version);
rpl_reset_dio_timer(instance);
rpl_reset_dio_timer(buf, instance);
return 1;
}
/*---------------------------------------------------------------------------*/
@ -481,7 +481,7 @@ rpl_alloc_instance(uint8_t instance_id)
}
/*---------------------------------------------------------------------------*/
rpl_dag_t *
rpl_alloc_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
rpl_alloc_dag(struct net_buf *buf, uint8_t instance_id, uip_ipaddr_t *dag_id)
{
rpl_dag_t *dag, *end;
rpl_instance_t *instance;
@ -507,7 +507,7 @@ rpl_alloc_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
}
RPL_STAT(rpl_stats.mem_overflows++);
rpl_free_instance(instance);
rpl_free_instance(buf, instance);
return NULL;
}
/*---------------------------------------------------------------------------*/
@ -518,7 +518,7 @@ rpl_set_default_instance(rpl_instance_t *instance)
}
/*---------------------------------------------------------------------------*/
void
rpl_free_instance(rpl_instance_t *instance)
rpl_free_instance(struct net_buf *buf, rpl_instance_t *instance)
{
rpl_dag_t *dag;
rpl_dag_t *end;
@ -528,7 +528,7 @@ rpl_free_instance(rpl_instance_t *instance)
/* Remove any DAG inside this instance */
for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) {
if(dag->used) {
rpl_free_dag(dag);
rpl_free_dag(buf, dag);
}
}
@ -546,7 +546,7 @@ rpl_free_instance(rpl_instance_t *instance)
}
/*---------------------------------------------------------------------------*/
void
rpl_free_dag(rpl_dag_t *dag)
rpl_free_dag(struct net_buf *buf, rpl_dag_t *dag)
{
if(dag->joined) {
PRINTF("RPL: Leaving the DAG ");
@ -562,7 +562,7 @@ rpl_free_dag(rpl_dag_t *dag)
check_prefix(&dag->prefix_info, NULL);
}
remove_parents(dag, 0);
remove_parents(buf, dag, 0);
}
dag->used = 0;
}
@ -646,7 +646,7 @@ rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
}
/*---------------------------------------------------------------------------*/
rpl_dag_t *
rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p)
rpl_select_dag(struct net_buf *buf, rpl_instance_t *instance, rpl_parent_t *p)
{
rpl_parent_t *last_parent;
rpl_dag_t *dag, *end, *best_dag;
@ -709,7 +709,7 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p)
rpl_set_preferred_parent(instance->current_dag, NULL);
if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES && last_parent != NULL) {
/* Send a No-Path DAO to the removed preferred parent. */
dao_output(last_parent, RPL_ZERO_LIFETIME);
dao_output(buf, last_parent, RPL_ZERO_LIFETIME);
}
return NULL;
}
@ -722,13 +722,13 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p)
if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) {
if(last_parent != NULL) {
/* Send a No-Path DAO to the removed preferred parent. */
dao_output(last_parent, RPL_ZERO_LIFETIME);
dao_output(buf, last_parent, RPL_ZERO_LIFETIME);
}
/* The DAO parent set changed - schedule a DAO transmission. */
RPL_LOLLIPOP_INCREMENT(instance->dtsn_out);
rpl_schedule_dao(instance);
rpl_schedule_dao(buf, instance);
}
rpl_reset_dio_timer(instance);
rpl_reset_dio_timer(buf, instance);
} else if(best_dag->rank != old_rank) {
PRINTF("RPL: Preferred parent update, rank changed from %u to %u\n",
(unsigned)old_rank, best_dag->rank);
@ -771,19 +771,19 @@ rpl_select_parent(rpl_dag_t *dag)
}
/*---------------------------------------------------------------------------*/
void
rpl_remove_parent(rpl_parent_t *parent)
rpl_remove_parent(struct net_buf *buf, rpl_parent_t *parent)
{
PRINTF("RPL: Removing parent ");
PRINT6ADDR(rpl_get_parent_ipaddr(parent));
PRINTF("\n");
rpl_nullify_parent(parent);
rpl_nullify_parent(buf, parent);
nbr_table_remove(rpl_parents, parent);
}
/*---------------------------------------------------------------------------*/
void
rpl_nullify_parent(rpl_parent_t *parent)
rpl_nullify_parent(struct net_buf *buf, rpl_parent_t *parent)
{
rpl_dag_t *dag = parent->dag;
/* This function can be called when the preferred parent is NULL, so we
@ -800,7 +800,7 @@ rpl_nullify_parent(rpl_parent_t *parent)
}
/* Send no-path DAO only to preferred parent, if any */
if(parent == dag->preferred_parent) {
dao_output(parent, RPL_ZERO_LIFETIME);
dao_output(buf, parent, RPL_ZERO_LIFETIME);
rpl_set_preferred_parent(dag, NULL);
}
}
@ -880,14 +880,14 @@ rpl_find_of(rpl_ocp_t ocp)
}
/*---------------------------------------------------------------------------*/
void
rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
rpl_join_instance(struct net_buf *buf, uip_ipaddr_t *from, rpl_dio_t *dio)
{
rpl_instance_t *instance;
rpl_dag_t *dag;
rpl_parent_t *p;
rpl_of_t *of;
dag = rpl_alloc_dag(dio->instance_id, &dio->dag_id);
dag = rpl_alloc_dag(buf, dio->instance_id, &dio->dag_id);
if(dag == NULL) {
PRINTF("RPL: Failed to allocate a DAG object!\n");
return;
@ -913,7 +913,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
if(of == NULL) {
PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF\n",
dio->instance_id);
rpl_remove_parent(p);
rpl_remove_parent(buf, p);
instance->used = 0;
return;
}
@ -965,11 +965,11 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
ANNOTATE("#A join=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]);
rpl_reset_dio_timer(instance);
rpl_reset_dio_timer(buf, instance);
rpl_set_default_route(instance, from);
if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) {
rpl_schedule_dao(instance);
rpl_schedule_dao(buf, instance);
} else {
PRINTF("RPL: The DIO does not meet the prerequisites for sending a DAO\n");
}
@ -978,14 +978,14 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
#if RPL_MAX_DAG_PER_INSTANCE > 1
/*---------------------------------------------------------------------------*/
void
rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
rpl_add_dag(struct net_buf *buf, uip_ipaddr_t *from, rpl_dio_t *dio)
{
rpl_instance_t *instance;
rpl_dag_t *dag, *previous_dag;
rpl_parent_t *p;
rpl_of_t *of;
dag = rpl_alloc_dag(dio->instance_id, &dio->dag_id);
dag = rpl_alloc_dag(buf, dio->instance_id, &dio->dag_id);
if(dag == NULL) {
PRINTF("RPL: Failed to allocate a DAG object!\n");
return;
@ -1026,7 +1026,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
instance->lifetime_unit != dio->lifetime_unit) {
PRINTF("RPL: DIO for DAG instance %u incompatible with previous DIO\n",
dio->instance_id);
rpl_remove_parent(p);
rpl_remove_parent(buf, p);
dag->used = 0;
return;
}
@ -1052,18 +1052,18 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
ANNOTATE("#A join=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]);
rpl_process_parent_event(instance, p);
rpl_process_parent_event(buf, instance, p);
p->dtsn = dio->dtsn;
}
#endif /* RPL_MAX_DAG_PER_INSTANCE > 1 */
/*---------------------------------------------------------------------------*/
static void
global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
global_repair(struct net_buf *buf, uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
{
rpl_parent_t *p;
remove_parents(dag, 0);
remove_parents(buf, dag, 0);
dag->version = dio->version;
/* copy parts of the configuration so that it propagates in the network */
@ -1085,7 +1085,7 @@ global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
dag->rank = dag->instance->of->calculate_rank(p, 0);
dag->min_rank = dag->rank;
PRINTF("RPL: rpl_process_parent_event global repair\n");
rpl_process_parent_event(dag->instance, p);
rpl_process_parent_event(buf, dag->instance, p);
}
PRINTF("RPL: Participating in a global repair (version=%u, rank=%hu)\n",
@ -1095,7 +1095,7 @@ global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
}
/*---------------------------------------------------------------------------*/
void
rpl_local_repair(rpl_instance_t *instance)
rpl_local_repair(struct net_buf *buf, rpl_instance_t *instance)
{
int i;
@ -1107,17 +1107,17 @@ rpl_local_repair(rpl_instance_t *instance)
for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; i++) {
if(instance->dag_table[i].used) {
instance->dag_table[i].rank = INFINITE_RANK;
nullify_parents(&instance->dag_table[i], 0);
nullify_parents(buf, &instance->dag_table[i], 0);
}
}
rpl_reset_dio_timer(instance);
rpl_reset_dio_timer(buf, instance);
RPL_STAT(rpl_stats.local_repairs++);
}
/*---------------------------------------------------------------------------*/
void
rpl_recalculate_ranks(void)
rpl_recalculate_ranks(struct net_buf *buf)
{
rpl_parent_t *p;
@ -1131,7 +1131,7 @@ rpl_recalculate_ranks(void)
if(p->dag != NULL && p->dag->instance && (p->flags & RPL_PARENT_FLAG_UPDATED)) {
p->flags &= ~RPL_PARENT_FLAG_UPDATED;
PRINTF("RPL: rpl_process_parent_event recalculate_ranks\n");
if(!rpl_process_parent_event(p->dag->instance, p)) {
if(!rpl_process_parent_event(buf, p->dag->instance, p)) {
PRINTF("RPL: A parent was dropped\n");
}
}
@ -1140,7 +1140,7 @@ rpl_recalculate_ranks(void)
}
/*---------------------------------------------------------------------------*/
int
rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
rpl_process_parent_event(struct net_buf *buf, rpl_instance_t *instance, rpl_parent_t *p)
{
int return_value;
@ -1155,7 +1155,7 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
/* The candidate parent is no longer valid: the rank increase resulting
from the choice of it as a parent would be too high. */
PRINTF("RPL: Unacceptable rank %u\n", (unsigned)p->rank);
rpl_nullify_parent(p);
rpl_nullify_parent(buf, p);
if(p != instance->current_dag->preferred_parent) {
return 0;
} else {
@ -1163,10 +1163,10 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
}
}
if(rpl_select_dag(instance, p) == NULL) {
if(rpl_select_dag(buf, instance, p) == NULL) {
/* No suitable parent; trigger a local repair. */
PRINTF("RPL: No parents found in any DAG\n");
rpl_local_repair(instance);
rpl_local_repair(buf, instance);
return 0;
}
@ -1189,7 +1189,7 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
}
/*---------------------------------------------------------------------------*/
void
rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
rpl_process_dio(struct net_buf *buf, uip_ipaddr_t *from, rpl_dio_t *dio)
{
rpl_instance_t *instance;
rpl_dag_t *dag, *previous_dag;
@ -1215,7 +1215,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
PRINTF("RPL: Root received inconsistent DIO version number\n");
dag->version = dio->version;
RPL_LOLLIPOP_INCREMENT(dag->version);
rpl_reset_dio_timer(instance);
rpl_reset_dio_timer(buf, instance);
} else {
PRINTF("RPL: Global repair\n");
if(dio->prefix_info.length != 0) {
@ -1224,7 +1224,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
rpl_set_prefix(dag, &dio->prefix_info.prefix, dio->prefix_info.length);
}
}
global_repair(from, dag, dio);
global_repair(buf, from, dag, dio);
}
return;
}
@ -1233,7 +1233,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
/* The DIO sender is on an older version of the DAG. */
PRINTF("RPL: old version received => inconsistency detected\n");
if(dag->joined) {
rpl_reset_dio_timer(instance);
rpl_reset_dio_timer(buf, instance);
return;
}
}
@ -1241,7 +1241,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
if(instance == NULL) {
PRINTF("RPL: New instance detected: Joining...\n");
rpl_join_instance(from, dio);
rpl_join_instance(buf, from, dio);
return;
}
@ -1253,7 +1253,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
if(dag == NULL) {
#if RPL_MAX_DAG_PER_INSTANCE > 1
PRINTF("RPL: Adding new DAG to known instance.\n");
rpl_add_dag(from, dio);
rpl_add_dag(buf, from, dio);
return;
#else /* RPL_MAX_DAG_PER_INSTANCE > 1 */
PRINTF("RPL: Only one instance supported.\n");
@ -1267,7 +1267,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
(unsigned)dio->rank);
return;
} else if(dio->rank == INFINITE_RANK && dag->joined) {
rpl_reset_dio_timer(instance);
rpl_reset_dio_timer(buf, instance);
}
/* Prefix Information Option treated to add new prefix */
@ -1336,7 +1336,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
#if RPL_DAG_MC != RPL_DAG_MC_NONE
memcpy(&p->mc, &dio->mc, sizeof(p->mc));
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
if(rpl_process_parent_event(instance, p) == 0) {
if(rpl_process_parent_event(buf, instance, p) == 0) {
PRINTF("RPL: The candidate parent is rejected\n");
return;
}
@ -1345,7 +1345,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
if(dag->joined && p == dag->preferred_parent) {
if(should_send_dao(instance, dio, p)) {
RPL_LOLLIPOP_INCREMENT(instance->dtsn_out);
rpl_schedule_dao(instance);
rpl_schedule_dao(buf, instance);
}
/* We received a new DIO from our preferred parent.
* Call uip_ds6_defrt_add to set a fresh value for the lifetime counter */

View file

@ -44,6 +44,8 @@
* @{
*/
#include <net/net_buf.h>
#include "net/ip/uip.h"
#include "net/ip/tcpip.h"
#include "net/ipv6/uip-ds6.h"
@ -57,16 +59,16 @@
#include <string.h>
/*---------------------------------------------------------------------------*/
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
#define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len])
#define UIP_HBHO_NEXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len + RPL_HOP_BY_HOP_LEN])
#define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
#define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
#define UIP_EXT_HDR_OPT_RPL_BUF ((struct uip_ext_hdr_opt_rpl *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN])
#define UIP_EXT_BUF(buf) ((struct uip_ext_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)])
#define UIP_HBHO_BUF(buf) ((struct uip_hbho_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)])
#define UIP_HBHO_NEXT_BUF(buf) ((struct uip_ext_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf) + RPL_HOP_BY_HOP_LEN])
#define UIP_EXT_HDR_OPT_BUF(buf) ((struct uip_ext_hdr_opt *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf) + uip_ext_opt_offset])
#define UIP_EXT_HDR_OPT_PADN_BUF(buf) ((struct uip_ext_hdr_opt_padn *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf) + uip_ext_opt_offset])
#define UIP_EXT_HDR_OPT_RPL_BUF(buf) ((struct uip_ext_hdr_opt_rpl *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf) + uip_ext_opt_offset])
/*---------------------------------------------------------------------------*/
int
rpl_verify_header(int uip_ext_opt_offset)
rpl_verify_header(struct net_buf *buf, int uip_ext_opt_offset)
{
rpl_instance_t *instance;
int down;
@ -74,41 +76,41 @@ rpl_verify_header(int uip_ext_opt_offset)
uint8_t sender_closer;
uip_ds6_route_t *route;
if(UIP_HBHO_BUF->len != RPL_HOP_BY_HOP_LEN - 8) {
if(UIP_HBHO_BUF(buf)->len != RPL_HOP_BY_HOP_LEN - 8) {
PRINTF("RPL: Hop-by-hop extension header has wrong size\n");
return 1;
}
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL) {
if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_type != UIP_EXT_HDR_OPT_RPL) {
PRINTF("RPL: Non RPL Hop-by-hop option\n");
return 1;
}
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_len != RPL_HDR_OPT_LEN) {
PRINTF("RPL: Bad header option! (wrong length)\n");
return 1;
}
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance);
if(instance == NULL) {
PRINTF("RPL: Unknown instance: %u\n",
UIP_EXT_HDR_OPT_RPL_BUF->instance);
UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance);
return 1;
}
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) {
if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags & RPL_HDR_OPT_FWD_ERR) {
PRINTF("RPL: Forward error!\n");
/* We should try to repair it by removing the neighbor that caused
the packet to be forwareded in the first place. We drop any
routes that go through the neighbor that sent the packet to
us. */
route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);
route = uip_ds6_route_lookup(&UIP_IP_BUF(buf)->destipaddr);
if(route != NULL) {
uip_ds6_route_rm(route);
}
RPL_STAT(rpl_stats.forward_errors++);
/* Trigger DAO retransmission */
rpl_reset_dio_timer(instance);
rpl_reset_dio_timer(buf, instance);
/* drop the packet as it is not routable */
return 1;
}
@ -119,11 +121,11 @@ rpl_verify_header(int uip_ext_opt_offset)
}
down = 0;
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN) {
if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags & RPL_HDR_OPT_DOWN) {
down = 1;
}
sender_rank = UIP_HTONS(UIP_EXT_HDR_OPT_RPL_BUF->senderrank);
sender_rank = UIP_HTONS(UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank);
sender_closer = sender_rank < instance->current_dag->rank;
PRINTF("RPL: Packet going %s, sender closer %d (%d < %d)\n", down == 1 ? "down" : "up",
@ -136,16 +138,16 @@ rpl_verify_header(int uip_ext_opt_offset)
PRINTF("RPL: Loop detected - senderrank: %d my-rank: %d sender_closer: %d\n",
sender_rank, instance->current_dag->rank,
sender_closer);
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_RANK_ERR) {
if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags & RPL_HDR_OPT_RANK_ERR) {
RPL_STAT(rpl_stats.loop_errors++);
PRINTF("RPL: Rank error signalled in RPL option!\n");
/* Packet must be dropped and dio trickle timer reset, see RFC6550 - 11.2.2.2 */
rpl_reset_dio_timer(instance);
rpl_reset_dio_timer(buf, instance);
return 1;
}
PRINTF("RPL: Single error tolerated\n");
RPL_STAT(rpl_stats.loop_warnings++);
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_RANK_ERR;
UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags |= RPL_HDR_OPT_RANK_ERR;
return 0;
}
@ -155,60 +157,60 @@ rpl_verify_header(int uip_ext_opt_offset)
}
/*---------------------------------------------------------------------------*/
static void
set_rpl_opt(unsigned uip_ext_opt_offset)
set_rpl_opt(struct net_buf *buf, unsigned uip_ext_opt_offset)
{
uint8_t temp_len;
memmove(UIP_HBHO_NEXT_BUF, UIP_EXT_BUF, uip_len - UIP_IPH_LEN);
memset(UIP_HBHO_BUF, 0, RPL_HOP_BY_HOP_LEN);
UIP_HBHO_BUF->next = UIP_IP_BUF->proto;
UIP_IP_BUF->proto = UIP_PROTO_HBHO;
UIP_HBHO_BUF->len = RPL_HOP_BY_HOP_LEN - 8;
UIP_EXT_HDR_OPT_RPL_BUF->opt_type = UIP_EXT_HDR_OPT_RPL;
UIP_EXT_HDR_OPT_RPL_BUF->opt_len = RPL_HDR_OPT_LEN;
UIP_EXT_HDR_OPT_RPL_BUF->flags = 0;
UIP_EXT_HDR_OPT_RPL_BUF->instance = 0;
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = 0;
uip_len += RPL_HOP_BY_HOP_LEN;
temp_len = UIP_IP_BUF->len[1];
UIP_IP_BUF->len[1] += UIP_HBHO_BUF->len + 8;
if(UIP_IP_BUF->len[1] < temp_len) {
UIP_IP_BUF->len[0]++;
memmove(UIP_HBHO_NEXT_BUF(buf), UIP_EXT_BUF(buf), uip_len(buf) - UIP_IPH_LEN);
memset(UIP_HBHO_BUF(buf), 0, RPL_HOP_BY_HOP_LEN);
UIP_HBHO_BUF(buf)->next = UIP_IP_BUF(buf)->proto;
UIP_IP_BUF(buf)->proto = UIP_PROTO_HBHO;
UIP_HBHO_BUF(buf)->len = RPL_HOP_BY_HOP_LEN - 8;
UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_type = UIP_EXT_HDR_OPT_RPL;
UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_len = RPL_HDR_OPT_LEN;
UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags = 0;
UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance = 0;
UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank = 0;
uip_len(buf) += RPL_HOP_BY_HOP_LEN;
temp_len = UIP_IP_BUF(buf)->len[1];
UIP_IP_BUF(buf)->len[1] += UIP_HBHO_BUF(buf)->len + 8;
if(UIP_IP_BUF(buf)->len[1] < temp_len) {
UIP_IP_BUF(buf)->len[0]++;
}
}
/*---------------------------------------------------------------------------*/
int
rpl_update_header_empty(void)
rpl_update_header_empty(struct net_buf *buf)
{
rpl_instance_t *instance;
int uip_ext_opt_offset;
int last_uip_ext_len;
rpl_parent_t *parent;
last_uip_ext_len = uip_ext_len;
uip_ext_len = 0;
last_uip_ext_len = uip_ext_len(buf);
uip_ext_len(buf) = 0;
uip_ext_opt_offset = 2;
PRINTF("RPL: Verifying the presence of the RPL header option\n");
switch(UIP_IP_BUF->proto) {
switch(UIP_IP_BUF(buf)->proto) {
case UIP_PROTO_HBHO:
if(UIP_HBHO_BUF->len != RPL_HOP_BY_HOP_LEN - 8) {
if(UIP_HBHO_BUF(buf)->len != RPL_HOP_BY_HOP_LEN - 8) {
PRINTF("RPL: Hop-by-hop extension header has wrong size\n");
uip_ext_len = last_uip_ext_len;
uip_ext_len(buf) = last_uip_ext_len;
return 0;
}
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL) {
if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_type != UIP_EXT_HDR_OPT_RPL) {
PRINTF("RPL: Non RPL Hop-by-hop option support not implemented\n");
uip_ext_len = last_uip_ext_len;
uip_ext_len(buf) = last_uip_ext_len;
return 0;
}
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_len != RPL_HDR_OPT_LEN) {
PRINTF("RPL: RPL Hop-by-hop option has wrong length\n");
uip_ext_len = last_uip_ext_len;
uip_ext_len(buf) = last_uip_ext_len;
return 0;
}
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance);
if(instance == NULL || !instance->used || !instance->current_dag->joined) {
PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect instance\n");
return 0;
@ -217,36 +219,36 @@ rpl_update_header_empty(void)
default:
#if RPL_INSERT_HBH_OPTION
PRINTF("RPL: No hop-by-hop option found, creating it\n");
if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE) {
if(uip_len(buf) + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE) {
PRINTF("RPL: Packet too long: impossible to add hop-by-hop option\n");
uip_ext_len = last_uip_ext_len;
uip_ext_len(buf) = last_uip_ext_len;
return 0;
}
set_rpl_opt(uip_ext_opt_offset);
uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
set_rpl_opt(buf, uip_ext_opt_offset);
uip_ext_len(buf) = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
#endif
return 0;
}
switch(UIP_EXT_HDR_OPT_BUF->type) {
switch(UIP_EXT_HDR_OPT_BUF(buf)->type) {
case UIP_EXT_HDR_OPT_RPL:
PRINTF("RPL: Updating RPL option\n");
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(instance->current_dag->rank);
UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank = UIP_HTONS(instance->current_dag->rank);
/* Check the direction of the down flag, as per Section 11.2.2.3,
which states that if a packet is going down it should in
general not go back up again. If this happens, a
RPL_HDR_OPT_FWD_ERR should be flagged. */
if((UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN)) {
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_FWD_ERR;
if((UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags & RPL_HDR_OPT_DOWN)) {
if(uip_ds6_route_lookup(&UIP_IP_BUF(buf)->destipaddr) == NULL) {
UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags |= RPL_HDR_OPT_FWD_ERR;
PRINTF("RPL forwarding error\n");
/* We should send back the packet to the originating parent,
but it is not feasible yet, so we send a No-Path DAO instead */
PRINTF("RPL generate No-Path DAO\n");
parent = rpl_get_parent((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
parent = rpl_get_parent((uip_lladdr_t *)&buf->src);
if(parent != NULL) {
dao_output_target(parent, &UIP_IP_BUF->destipaddr, RPL_ZERO_LIFETIME);
dao_output_target(buf, parent, &UIP_IP_BUF(buf)->destipaddr, RPL_ZERO_LIFETIME);
}
/* Drop packet */
return 1;
@ -255,47 +257,47 @@ rpl_update_header_empty(void)
/* Set the down extension flag correctly as described in Section
11.2 of RFC6550. If the packet progresses along a DAO route,
the down flag should be set. */
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
if(uip_ds6_route_lookup(&UIP_IP_BUF(buf)->destipaddr) == NULL) {
/* No route was found, so this packet will go towards the RPL
root. If so, we should not set the down flag. */
UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_DOWN;
UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags &= ~RPL_HDR_OPT_DOWN;
PRINTF("RPL option going up\n");
} else {
/* A DAO route was found so we set the down flag. */
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_DOWN;
UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags |= RPL_HDR_OPT_DOWN;
PRINTF("RPL option going down\n");
}
}
uip_ext_len = last_uip_ext_len;
uip_ext_len(buf) = last_uip_ext_len;
return 0;
default:
PRINTF("RPL: Multi Hop-by-hop options not implemented\n");
uip_ext_len = last_uip_ext_len;
uip_ext_len(buf) = last_uip_ext_len;
return 0;
}
}
/*---------------------------------------------------------------------------*/
int
rpl_update_header_final(uip_ipaddr_t *addr)
rpl_update_header_final(struct net_buf *buf, uip_ipaddr_t *addr)
{
rpl_parent_t *parent;
int uip_ext_opt_offset;
int last_uip_ext_len;
last_uip_ext_len = uip_ext_len;
uip_ext_len = 0;
last_uip_ext_len = uip_ext_len(buf);
uip_ext_len(buf) = 0;
uip_ext_opt_offset = 2;
if(UIP_IP_BUF->proto == UIP_PROTO_HBHO) {
if(UIP_HBHO_BUF->len != RPL_HOP_BY_HOP_LEN - 8) {
if(UIP_IP_BUF(buf)->proto == UIP_PROTO_HBHO) {
if(UIP_HBHO_BUF(buf)->len != RPL_HOP_BY_HOP_LEN - 8) {
PRINTF("RPL: Non RPL Hop-by-hop options support not implemented\n");
uip_ext_len = last_uip_ext_len;
uip_ext_len(buf) = last_uip_ext_len;
return 0;
}
if(UIP_EXT_HDR_OPT_BUF->type == UIP_EXT_HDR_OPT_RPL) {
if(UIP_EXT_HDR_OPT_RPL_BUF->senderrank == 0) {
if(UIP_EXT_HDR_OPT_BUF(buf)->type == UIP_EXT_HDR_OPT_RPL) {
if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank == 0) {
PRINTF("RPL: Updating RPL option\n");
if(default_instance == NULL || !default_instance->used || !default_instance->current_dag->joined) {
PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect default instance\n");
@ -303,10 +305,10 @@ rpl_update_header_final(uip_ipaddr_t *addr)
}
parent = rpl_find_parent(default_instance->current_dag, addr);
if(parent == NULL || parent != parent->dag->preferred_parent) {
UIP_EXT_HDR_OPT_RPL_BUF->flags = RPL_HDR_OPT_DOWN;
UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags = RPL_HDR_OPT_DOWN;
}
UIP_EXT_HDR_OPT_RPL_BUF->instance = default_instance->instance_id;
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(default_instance->current_dag->rank);
UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance = default_instance->instance_id;
UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank = UIP_HTONS(default_instance->current_dag->rank);
}
}
}
@ -314,24 +316,24 @@ rpl_update_header_final(uip_ipaddr_t *addr)
}
/*---------------------------------------------------------------------------*/
void
rpl_remove_header(void)
rpl_remove_header(struct net_buf *buf)
{
uint8_t temp_len;
uip_ext_len = 0;
uip_ext_len(buf) = 0;
PRINTF("RPL: Verifying the presence of the RPL header option\n");
switch(UIP_IP_BUF->proto){
switch(UIP_IP_BUF(buf)->proto){
case UIP_PROTO_HBHO:
PRINTF("RPL: Removing the RPL header option\n");
UIP_IP_BUF->proto = UIP_HBHO_BUF->next;
temp_len = UIP_IP_BUF->len[1];
uip_len -= UIP_HBHO_BUF->len + 8;
UIP_IP_BUF->len[1] -= UIP_HBHO_BUF->len + 8;
if(UIP_IP_BUF->len[1] > temp_len) {
UIP_IP_BUF->len[0]--;
UIP_IP_BUF(buf)->proto = UIP_HBHO_BUF(buf)->next;
temp_len = UIP_IP_BUF(buf)->len[1];
uip_len(buf) -= UIP_HBHO_BUF(buf)->len + 8;
UIP_IP_BUF(buf)->len[1] -= UIP_HBHO_BUF(buf)->len + 8;
if(UIP_IP_BUF(buf)->len[1] > temp_len) {
UIP_IP_BUF(buf)->len[0]--;
}
memmove(UIP_EXT_BUF, UIP_HBHO_NEXT_BUF, uip_len - UIP_IPH_LEN);
memmove(UIP_EXT_BUF(buf), UIP_HBHO_NEXT_BUF(buf), uip_len(buf) - UIP_IPH_LEN);
break;
default:
PRINTF("RPL: No hop-by-hop Option found\n");
@ -339,46 +341,46 @@ rpl_remove_header(void)
}
/*---------------------------------------------------------------------------*/
uint8_t
rpl_invert_header(void)
rpl_invert_header(struct net_buf *buf)
{
uint8_t uip_ext_opt_offset;
uint8_t last_uip_ext_len;
last_uip_ext_len = uip_ext_len;
uip_ext_len = 0;
last_uip_ext_len = uip_ext_len(buf);
uip_ext_len(buf) = 0;
uip_ext_opt_offset = 2;
PRINTF("RPL: Verifying the presence of the RPL header option\n");
switch(UIP_IP_BUF->proto) {
switch(UIP_IP_BUF(buf)->proto) {
case UIP_PROTO_HBHO:
break;
default:
PRINTF("RPL: No hop-by-hop Option found\n");
uip_ext_len = last_uip_ext_len;
uip_ext_len(buf) = last_uip_ext_len;
return 0;
}
switch (UIP_EXT_HDR_OPT_BUF->type) {
switch (UIP_EXT_HDR_OPT_BUF(buf)->type) {
case UIP_EXT_HDR_OPT_RPL:
PRINTF("RPL: Updating RPL option (switching direction)\n");
UIP_EXT_HDR_OPT_RPL_BUF->flags &= RPL_HDR_OPT_DOWN;
UIP_EXT_HDR_OPT_RPL_BUF->flags ^= RPL_HDR_OPT_DOWN;
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance)->current_dag->rank);
uip_ext_len = last_uip_ext_len;
UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags &= RPL_HDR_OPT_DOWN;
UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags ^= RPL_HDR_OPT_DOWN;
UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank = UIP_HTONS(rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance)->current_dag->rank);
uip_ext_len(buf) = last_uip_ext_len;
return RPL_HOP_BY_HOP_LEN;
default:
PRINTF("RPL: Multi Hop-by-hop options not implemented\n");
uip_ext_len = last_uip_ext_len;
uip_ext_len(buf) = last_uip_ext_len;
return 0;
}
}
/*---------------------------------------------------------------------------*/
void
rpl_insert_header(void)
rpl_insert_header(struct net_buf *buf)
{
#if RPL_INSERT_HBH_OPTION
if(default_instance != NULL && !uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
rpl_update_header_empty();
if(default_instance != NULL && !uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr)) {
rpl_update_header_empty(buf);
}
#endif
}

View file

@ -45,13 +45,14 @@
* @{
*/
#include <net/net_buf.h>
#include "net/ip/tcpip.h"
#include "net/ip/uip.h"
#include "net/ipv6/uip-ds6.h"
#include "net/ipv6/uip-nd6.h"
#include "net/ipv6/uip-icmp6.h"
#include "net/rpl/rpl-private.h"
#include "net/packetbuf.h"
#include "net/ipv6/multicast/uip-mcast6.h"
#include <limits.h>
@ -67,14 +68,14 @@
#define RPL_DIO_MOP_MASK 0x38
#define RPL_DIO_PREFERENCE_MASK 0x07
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
#define UIP_ICMP_PAYLOAD ((unsigned char *)&uip_buf[uip_l2_l3_icmp_hdr_len])
#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN])
#define UIP_ICMP_BUF(buf) ((struct uip_icmp_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)])
#define UIP_ICMP_PAYLOAD(buf) ((unsigned char *)&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf)])
/*---------------------------------------------------------------------------*/
static void dis_input(void);
static void dio_input(void);
static void dao_input(void);
static void dao_ack_input(void);
static void dis_input(struct net_buf *buf);
static void dio_input(struct net_buf *buf);
static void dao_input(struct net_buf *buf);
static void dao_ack_input(struct net_buf *buf);
/* some debug callbacks useful when debugging RPL networks */
#ifdef RPL_DEBUG_DIO_INPUT
@ -148,38 +149,38 @@ set16(uint8_t *buffer, int pos, uint16_t value)
}
/*---------------------------------------------------------------------------*/
static void
dis_input(void)
dis_input(struct net_buf *buf)
{
rpl_instance_t *instance;
rpl_instance_t *end;
/* DAG Information Solicitation */
PRINTF("RPL: Received a DIS from ");
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr);
PRINTF("\n");
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES;
instance < end; ++instance) {
if(instance->used == 1) {
#if RPL_LEAF_ONLY
if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
if(!uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr)) {
PRINTF("RPL: LEAF ONLY Multicast DIS will NOT reset DIO timer\n");
#else /* !RPL_LEAF_ONLY */
if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
if(uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr)) {
PRINTF("RPL: Multicast DIS => reset DIO timer\n");
rpl_reset_dio_timer(instance);
rpl_reset_dio_timer(buf, instance);
} else {
#endif /* !RPL_LEAF_ONLY */
PRINTF("RPL: Unicast DIS, reply to sender\n");
dio_output(instance, &UIP_IP_BUF->srcipaddr);
dio_output(buf, instance, &UIP_IP_BUF(buf)->srcipaddr);
}
}
}
uip_len = 0;
uip_len(buf) = 0;
}
/*---------------------------------------------------------------------------*/
void
dis_output(uip_ipaddr_t *addr)
dis_output(struct net_buf *buf, uip_ipaddr_t *addr)
{
unsigned char *buffer;
uip_ipaddr_t tmpaddr;
@ -193,7 +194,7 @@ dis_output(uip_ipaddr_t *addr)
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
buffer = UIP_ICMP_PAYLOAD;
buffer = UIP_ICMP_PAYLOAD(buf);
buffer[0] = buffer[1] = 0;
if(addr == NULL) {
@ -205,11 +206,11 @@ dis_output(uip_ipaddr_t *addr)
PRINT6ADDR(addr);
PRINTF("\n");
uip_icmp6_send(addr, ICMP6_RPL, RPL_CODE_DIS, 2);
uip_icmp6_send(buf, addr, ICMP6_RPL, RPL_CODE_DIS, 2);
}
/*---------------------------------------------------------------------------*/
static void
dio_input(void)
dio_input(struct net_buf *buf)
{
unsigned char *buffer;
uint8_t buffer_length;
@ -232,7 +233,7 @@ dio_input(void)
dio.default_lifetime = RPL_DEFAULT_LIFETIME;
dio.lifetime_unit = RPL_DEFAULT_LIFETIME_UNIT;
uip_ipaddr_copy(&from, &UIP_IP_BUF->srcipaddr);
uip_ipaddr_copy(&from, &UIP_IP_BUF(buf)->srcipaddr);
/* DAG Information Object */
PRINTF("RPL: Received a DIO from ");
@ -240,21 +241,20 @@ dio_input(void)
PRINTF("\n");
if((nbr = uip_ds6_nbr_lookup(&from)) == NULL) {
if((nbr = uip_ds6_nbr_add(&from, (uip_lladdr_t *)
packetbuf_addr(PACKETBUF_ADDR_SENDER),
if((nbr = uip_ds6_nbr_add(&from, (uip_lladdr_t *)&buf->src,
0, NBR_REACHABLE)) != NULL) {
/* set reachable timer */
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
PRINTF("RPL: Neighbor added to neighbor cache ");
PRINT6ADDR(&from);
PRINTF(", ");
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
PRINTLLADDR((uip_lladdr_t *)buf->src);
PRINTF("\n");
} else {
PRINTF("RPL: Out of memory, dropping DIO from ");
PRINT6ADDR(&from);
PRINTF(", ");
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
PRINTLLADDR((uip_lladdr_t *)buf->src);
PRINTF("\n");
return;
}
@ -262,11 +262,11 @@ dio_input(void)
PRINTF("RPL: Neighbor already in neighbor cache\n");
}
buffer_length = uip_len - uip_l3_icmp_hdr_len;
buffer_length = uip_len(buf) - uip_l3_icmp_hdr_len(buf);
/* Process the DIO base option. */
i = 0;
buffer = UIP_ICMP_PAYLOAD;
buffer = UIP_ICMP_PAYLOAD(buf);
dio.instance_id = buffer[i++];
dio.version = buffer[i++];
@ -416,13 +416,13 @@ dio_input(void)
RPL_DEBUG_DIO_INPUT(&from, &dio);
#endif
rpl_process_dio(&from, &dio);
rpl_process_dio(buf, &from, &dio);
uip_len = 0;
uip_len(buf) = 0;
}
/*---------------------------------------------------------------------------*/
void
dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr)
dio_output(struct net_buf *buf, rpl_instance_t *instance, uip_ipaddr_t *uc_addr)
{
unsigned char *buffer;
int pos;
@ -443,7 +443,7 @@ dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr)
/* DAG Information Object */
pos = 0;
buffer = UIP_ICMP_PAYLOAD;
buffer = UIP_ICMP_PAYLOAD(buf);
buffer[pos++] = instance->instance_id;
buffer[pos++] = dag->version;
@ -553,26 +553,26 @@ dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr)
(unsigned)dag->rank);
PRINT6ADDR(uc_addr);
PRINTF("\n");
uip_icmp6_send(uc_addr, ICMP6_RPL, RPL_CODE_DIO, pos);
uip_icmp6_send(buf, uc_addr, ICMP6_RPL, RPL_CODE_DIO, pos);
#else /* RPL_LEAF_ONLY */
/* Unicast requests get unicast replies! */
if(uc_addr == NULL) {
PRINTF("RPL: Sending a multicast-DIO with rank %u\n",
(unsigned)instance->current_dag->rank);
uip_create_linklocal_rplnodes_mcast(&addr);
uip_icmp6_send(&addr, ICMP6_RPL, RPL_CODE_DIO, pos);
uip_icmp6_send(buf, &addr, ICMP6_RPL, RPL_CODE_DIO, pos);
} else {
PRINTF("RPL: Sending unicast-DIO with rank %u to ",
(unsigned)instance->current_dag->rank);
PRINT6ADDR(uc_addr);
PRINTF("\n");
uip_icmp6_send(uc_addr, ICMP6_RPL, RPL_CODE_DIO, pos);
uip_icmp6_send(buf, uc_addr, ICMP6_RPL, RPL_CODE_DIO, pos);
}
#endif /* RPL_LEAF_ONLY */
}
/*---------------------------------------------------------------------------*/
static void
dao_input(void)
dao_input(struct net_buf *buf)
{
uip_ipaddr_t dao_sender_addr;
rpl_dag_t *dag;
@ -601,15 +601,15 @@ dao_input(void)
prefixlen = 0;
parent = NULL;
uip_ipaddr_copy(&dao_sender_addr, &UIP_IP_BUF->srcipaddr);
uip_ipaddr_copy(&dao_sender_addr, &UIP_IP_BUF(buf)->srcipaddr);
/* Destination Advertisement Object */
PRINTF("RPL: Received a DAO from ");
PRINT6ADDR(&dao_sender_addr);
PRINTF("\n");
buffer = UIP_ICMP_PAYLOAD;
buffer_length = uip_len - uip_l3_icmp_hdr_len;
buffer = UIP_ICMP_PAYLOAD(buf);
buffer_length = uip_len(buf) - uip_l3_icmp_hdr_len(buf);
pos = 0;
instance_id = buffer[pos++];
@ -732,11 +732,11 @@ dao_input(void)
PRINTF("RPL: Forwarding no-path DAO to parent ");
PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent));
PRINTF("\n");
uip_icmp6_send(rpl_get_parent_ipaddr(dag->preferred_parent),
uip_icmp6_send(buf, rpl_get_parent_ipaddr(dag->preferred_parent),
ICMP6_RPL, RPL_CODE_DAO, buffer_length);
}
if(flags & RPL_DAO_K_FLAG) {
dao_ack_output(instance, &dao_sender_addr, sequence);
dao_ack_output(buf, instance, &dao_sender_addr, sequence);
}
}
return;
@ -746,20 +746,20 @@ dao_input(void)
if((nbr = uip_ds6_nbr_lookup(&dao_sender_addr)) == NULL) {
if((nbr = uip_ds6_nbr_add(&dao_sender_addr,
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER),
(uip_lladdr_t *)&buf->src,
0, NBR_REACHABLE)) != NULL) {
/* set reachable timer */
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
PRINTF("RPL: Neighbor added to neighbor cache ");
PRINT6ADDR(&dao_sender_addr);
PRINTF(", ");
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
PRINTLLADDR((uip_lladdr_t *)buf->src);
PRINTF("\n");
} else {
PRINTF("RPL: Out of Memory, dropping DAO from ");
PRINT6ADDR(&dao_sender_addr);
PRINTF(", ");
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
PRINTLLADDR((uip_lladdr_t *)buf->src);
PRINTF("\n");
return;
}
@ -790,18 +790,18 @@ fwd_dao:
PRINTF("RPL: Forwarding DAO to parent ");
PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent));
PRINTF("\n");
uip_icmp6_send(rpl_get_parent_ipaddr(dag->preferred_parent),
uip_icmp6_send(buf, rpl_get_parent_ipaddr(dag->preferred_parent),
ICMP6_RPL, RPL_CODE_DAO, buffer_length);
}
if(flags & RPL_DAO_K_FLAG) {
dao_ack_output(instance, &dao_sender_addr, sequence);
dao_ack_output(buf, instance, &dao_sender_addr, sequence);
}
}
uip_len = 0;
uip_len(buf) = 0;
}
/*---------------------------------------------------------------------------*/
void
dao_output(rpl_parent_t *parent, uint8_t lifetime)
dao_output(struct net_buf *buf, rpl_parent_t *parent, uint8_t lifetime)
{
/* Destination Advertisement Object */
uip_ipaddr_t prefix;
@ -812,11 +812,11 @@ dao_output(rpl_parent_t *parent, uint8_t lifetime)
}
/* Sending a DAO with own prefix as target */
dao_output_target(parent, &prefix, lifetime);
dao_output_target(buf, parent, &prefix, lifetime);
}
/*---------------------------------------------------------------------------*/
void
dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime)
dao_output_target(struct net_buf *buf, rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime)
{
rpl_dag_t *dag;
rpl_instance_t *instance;
@ -856,7 +856,7 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime)
RPL_DEBUG_DAO_OUTPUT(parent);
#endif
buffer = UIP_ICMP_PAYLOAD;
buffer = UIP_ICMP_PAYLOAD(buf);
RPL_LOLLIPOP_INCREMENT(dao_sequence);
pos = 0;
@ -901,12 +901,12 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime)
PRINTF("\n");
if(rpl_get_parent_ipaddr(parent) != NULL) {
uip_icmp6_send(rpl_get_parent_ipaddr(parent), ICMP6_RPL, RPL_CODE_DAO, pos);
uip_icmp6_send(buf, rpl_get_parent_ipaddr(parent), ICMP6_RPL, RPL_CODE_DAO, pos);
}
}
/*---------------------------------------------------------------------------*/
static void
dao_ack_input(void)
dao_ack_input(struct net_buf *buf)
{
#if DEBUG
unsigned char *buffer;
@ -915,8 +915,8 @@ dao_ack_input(void)
uint8_t sequence;
uint8_t status;
buffer = UIP_ICMP_PAYLOAD;
buffer_length = uip_len - uip_l3_icmp_hdr_len;
buffer = UIP_ICMP_PAYLOAD(buf);
buffer_length = uip_len(buf) - uip_l3_icmp_hdr_len(buf);
instance_id = buffer[0];
sequence = buffer[2];
@ -924,14 +924,14 @@ dao_ack_input(void)
PRINTF("RPL: Received a DAO ACK with sequence number %d and status %d from ",
sequence, status);
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr);
PRINTF("\n");
#endif /* DEBUG */
uip_len = 0;
uip_len(buf) = 0;
}
/*---------------------------------------------------------------------------*/
void
dao_ack_output(rpl_instance_t *instance, uip_ipaddr_t *dest, uint8_t sequence)
dao_ack_output(struct net_buf *buf, rpl_instance_t *instance, uip_ipaddr_t *dest, uint8_t sequence)
{
unsigned char *buffer;
@ -939,14 +939,14 @@ dao_ack_output(rpl_instance_t *instance, uip_ipaddr_t *dest, uint8_t sequence)
PRINT6ADDR(dest);
PRINTF("\n");
buffer = UIP_ICMP_PAYLOAD;
buffer = UIP_ICMP_PAYLOAD(buf);
buffer[0] = instance->instance_id;
buffer[1] = 0;
buffer[2] = sequence;
buffer[3] = 0;
uip_icmp6_send(dest, ICMP6_RPL, RPL_CODE_DAO_ACK, 4);
uip_icmp6_send(buf, dest, ICMP6_RPL, RPL_CODE_DAO_ACK, 4);
}
/*---------------------------------------------------------------------------*/
void

View file

@ -265,43 +265,43 @@ extern rpl_instance_t instance_table[];
extern rpl_instance_t *default_instance;
/* ICMPv6 functions for RPL. */
void dis_output(uip_ipaddr_t *addr);
void dio_output(rpl_instance_t *, uip_ipaddr_t *uc_addr);
void dao_output(rpl_parent_t *, uint8_t lifetime);
void dao_output_target(rpl_parent_t *, uip_ipaddr_t *, uint8_t lifetime);
void dao_ack_output(rpl_instance_t *, uip_ipaddr_t *, uint8_t);
void dis_output(struct net_buf *buf, uip_ipaddr_t *addr);
void dio_output(struct net_buf *buf, rpl_instance_t *, uip_ipaddr_t *uc_addr);
void dao_output(struct net_buf *buf, rpl_parent_t *, uint8_t lifetime);
void dao_output_target(struct net_buf *buf, rpl_parent_t *, uip_ipaddr_t *, uint8_t lifetime);
void dao_ack_output(struct net_buf *buf, rpl_instance_t *, uip_ipaddr_t *, uint8_t);
void rpl_icmp6_register_handlers(void);
/* RPL logic functions. */
void rpl_join_dag(uip_ipaddr_t *from, rpl_dio_t *dio);
void rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio);
void rpl_local_repair(rpl_instance_t *instance);
void rpl_process_dio(uip_ipaddr_t *, rpl_dio_t *);
int rpl_process_parent_event(rpl_instance_t *, rpl_parent_t *);
void rpl_join_instance(struct net_buf *buf, uip_ipaddr_t *from, rpl_dio_t *dio);
void rpl_local_repair(struct net_buf *buf, rpl_instance_t *instance);
void rpl_process_dio(struct net_buf *buf, uip_ipaddr_t *, rpl_dio_t *);
int rpl_process_parent_event(struct net_buf *buf, rpl_instance_t *, rpl_parent_t *);
/* DAG object management. */
rpl_dag_t *rpl_alloc_dag(uint8_t, uip_ipaddr_t *);
rpl_dag_t *rpl_alloc_dag(struct net_buf *buf, uint8_t, uip_ipaddr_t *);
rpl_instance_t *rpl_alloc_instance(uint8_t);
void rpl_free_dag(rpl_dag_t *);
void rpl_free_instance(rpl_instance_t *);
void rpl_free_dag(struct net_buf *buf, rpl_dag_t *);
void rpl_free_instance(struct net_buf *buf, rpl_instance_t *);
/* DAG parent management function. */
rpl_parent_t *rpl_add_parent(rpl_dag_t *, rpl_dio_t *dio, uip_ipaddr_t *);
rpl_parent_t *rpl_find_parent(rpl_dag_t *, uip_ipaddr_t *);
rpl_parent_t *rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr);
void rpl_nullify_parent(rpl_parent_t *);
void rpl_remove_parent(rpl_parent_t *);
void rpl_nullify_parent(struct net_buf *buf, rpl_parent_t *);
void rpl_remove_parent(struct net_buf *buf, rpl_parent_t *);
void rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent);
rpl_parent_t *rpl_select_parent(rpl_dag_t *dag);
rpl_dag_t *rpl_select_dag(rpl_instance_t *instance,rpl_parent_t *parent);
void rpl_recalculate_ranks(void);
rpl_dag_t *rpl_select_dag(struct net_buf *buf, rpl_instance_t *instance,rpl_parent_t *parent);
void rpl_recalculate_ranks(struct net_buf *buf);
/* RPL routing table functions. */
void rpl_remove_routes(rpl_dag_t *dag);
void rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag);
uip_ds6_route_t *rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix,
int prefix_len, uip_ipaddr_t *next_hop);
void rpl_purge_routes(void);
void rpl_purge_routes(struct net_buf *buf);
/* Lock a parent in the neighbor cache. */
void rpl_lock_parent(rpl_parent_t *p);
@ -310,14 +310,16 @@ void rpl_lock_parent(rpl_parent_t *p);
rpl_of_t *rpl_find_of(rpl_ocp_t);
/* Timer functions. */
void rpl_schedule_dao(rpl_instance_t *);
void rpl_schedule_dao_immediately(rpl_instance_t *);
void rpl_schedule_dao(struct net_buf *buf, rpl_instance_t *);
void rpl_schedule_dao_immediately(struct net_buf *buf, rpl_instance_t *);
void rpl_cancel_dao(rpl_instance_t *instance);
void rpl_reset_dio_timer(rpl_instance_t *);
void rpl_reset_periodic_timer(void);
void rpl_reset_dio_timer(struct net_buf *buf, rpl_instance_t *);
void rpl_reset_periodic_timer(struct net_buf *buf);
/* Route poisoning. */
void rpl_poison_routes(rpl_dag_t *, rpl_parent_t *);
struct net_buf *rpl_get_netbuf(void);
#endif /* RPL_PRIVATE_H */

View file

@ -53,9 +53,9 @@
/*---------------------------------------------------------------------------*/
static struct ctimer periodic_timer;
static void handle_periodic_timer(void *ptr);
static void new_dio_interval(rpl_instance_t *instance);
static void handle_dio_timer(void *ptr);
static void handle_periodic_timer(struct net_mbuf *mbuf, void *ptr);
static void new_dio_interval(struct net_buf *buf, rpl_instance_t *instance);
static void handle_dio_timer(struct net_mbuf *mbuf, void *ptr);
static uint16_t next_dis;
@ -64,24 +64,25 @@ static uint8_t dio_send_ok;
/*---------------------------------------------------------------------------*/
static void
handle_periodic_timer(void *ptr)
handle_periodic_timer(struct net_mbuf *mbuf, void *ptr)
{
rpl_purge_routes();
rpl_recalculate_ranks();
struct net_buf *buf = (struct net_buf *)mbuf;
rpl_purge_routes(buf);
rpl_recalculate_ranks(buf);
/* handle DIS */
#if RPL_DIS_SEND
next_dis++;
if(rpl_get_any_dag() == NULL && next_dis >= RPL_DIS_INTERVAL) {
next_dis = 0;
dis_output(NULL);
dis_output(buf, NULL);
}
#endif
ctimer_reset(&periodic_timer);
}
/*---------------------------------------------------------------------------*/
static void
new_dio_interval(rpl_instance_t *instance)
new_dio_interval(struct net_buf *buf, rpl_instance_t *instance)
{
uint32_t time;
clock_time_t ticks;
@ -122,12 +123,13 @@ new_dio_interval(rpl_instance_t *instance)
/* schedule the timer */
PRINTF("RPL: Scheduling DIO timer %lu ticks in future (Interval)\n", ticks);
ctimer_set(&instance->dio_timer, ticks, &handle_dio_timer, instance);
ctimer_set((struct net_mbuf *)buf, &instance->dio_timer, ticks, &handle_dio_timer, instance);
}
/*---------------------------------------------------------------------------*/
static void
handle_dio_timer(void *ptr)
handle_dio_timer(struct net_mbuf *mbuf, void *ptr)
{
struct net_buf *buf = (struct net_buf *)mbuf;
rpl_instance_t *instance;
instance = (rpl_instance_t *)ptr;
@ -138,7 +140,7 @@ handle_dio_timer(void *ptr)
dio_send_ok = 1;
} else {
PRINTF("RPL: Postponing DIO transmission since link local address is not ok\n");
ctimer_set(&instance->dio_timer, CLOCK_SECOND, &handle_dio_timer, instance);
ctimer_set((struct net_mbuf *)buf, &instance->dio_timer, CLOCK_SECOND, &handle_dio_timer, instance);
return;
}
}
@ -149,7 +151,7 @@ handle_dio_timer(void *ptr)
#if RPL_CONF_STATS
instance->dio_totsend++;
#endif /* RPL_CONF_STATS */
dio_output(instance, NULL);
dio_output(buf, instance, NULL);
} else {
PRINTF("RPL: Supressing DIO transmission (%d >= %d)\n",
instance->dio_counter, instance->dio_redundancy);
@ -157,29 +159,29 @@ handle_dio_timer(void *ptr)
instance->dio_send = 0;
PRINTF("RPL: Scheduling DIO timer %lu ticks in future (sent)\n",
instance->dio_next_delay);
ctimer_set(&instance->dio_timer, instance->dio_next_delay, handle_dio_timer, instance);
ctimer_set((struct net_mbuf *)buf, &instance->dio_timer, instance->dio_next_delay, handle_dio_timer, instance);
} else {
/* check if we need to double interval */
if(instance->dio_intcurrent < instance->dio_intmin + instance->dio_intdoubl) {
instance->dio_intcurrent++;
PRINTF("RPL: DIO Timer interval doubled %d\n", instance->dio_intcurrent);
}
new_dio_interval(instance);
new_dio_interval(buf, instance);
}
}
/*---------------------------------------------------------------------------*/
void
rpl_reset_periodic_timer(void)
rpl_reset_periodic_timer(struct net_buf *buf)
{
next_dis = RPL_DIS_INTERVAL / 2 +
((uint32_t)RPL_DIS_INTERVAL * (uint32_t)random_rand()) / RANDOM_RAND_MAX -
RPL_DIS_START_DELAY;
ctimer_set(&periodic_timer, CLOCK_SECOND, handle_periodic_timer, NULL);
ctimer_set((struct net_mbuf *)buf, &periodic_timer, CLOCK_SECOND, handle_periodic_timer, NULL);
}
/*---------------------------------------------------------------------------*/
/* Resets the DIO timer in the instance to its minimal interval. */
void
rpl_reset_dio_timer(rpl_instance_t *instance)
rpl_reset_dio_timer(struct net_buf *buf, rpl_instance_t *instance)
{
#if !RPL_LEAF_ONLY
/* Do not reset if we are already on the minimum interval,
@ -187,7 +189,7 @@ rpl_reset_dio_timer(rpl_instance_t *instance)
if(instance->dio_intcurrent > instance->dio_intmin) {
instance->dio_counter = 0;
instance->dio_intcurrent = instance->dio_intmin;
new_dio_interval(instance);
new_dio_interval(buf, instance);
}
#if RPL_CONF_STATS
rpl_stats.resets++;
@ -195,9 +197,9 @@ rpl_reset_dio_timer(rpl_instance_t *instance)
#endif /* RPL_LEAF_ONLY */
}
/*---------------------------------------------------------------------------*/
static void handle_dao_timer(void *ptr);
static void handle_dao_timer(struct net_mbuf *mbuf, void *ptr);
static void
set_dao_lifetime_timer(rpl_instance_t *instance)
set_dao_lifetime_timer(struct net_buf *buf, rpl_instance_t *instance)
{
if(rpl_get_mode() == RPL_MODE_FEATHER) {
return;
@ -212,14 +214,15 @@ set_dao_lifetime_timer(rpl_instance_t *instance)
CLOCK_SECOND / 2;
PRINTF("RPL: Scheduling DAO lifetime timer %u ticks in the future\n",
(unsigned)expiration_time);
ctimer_set(&instance->dao_lifetime_timer, expiration_time,
ctimer_set((struct net_mbuf *)buf, &instance->dao_lifetime_timer, expiration_time,
handle_dao_timer, instance);
}
}
/*---------------------------------------------------------------------------*/
static void
handle_dao_timer(void *ptr)
handle_dao_timer(struct net_mbuf *mbuf, void *ptr)
{
struct net_buf *buf = (struct net_buf *)mbuf;
rpl_instance_t *instance;
#if RPL_CONF_MULTICAST
uip_mcast6_route_t *mcast_route;
@ -230,7 +233,7 @@ handle_dao_timer(void *ptr)
if(!dio_send_ok && uip_ds6_get_link_local(ADDR_PREFERRED) == NULL) {
PRINTF("RPL: Postpone DAO transmission\n");
ctimer_set(&instance->dao_timer, CLOCK_SECOND, handle_dao_timer, instance);
ctimer_set((struct net_mbuf *)buf, &instance->dao_timer, CLOCK_SECOND, handle_dao_timer, instance);
return;
}
@ -238,7 +241,7 @@ handle_dao_timer(void *ptr)
if(instance->current_dag->preferred_parent != NULL) {
PRINTF("RPL: handle_dao_timer - sending DAO\n");
/* Set the route lifetime to the default value. */
dao_output(instance->current_dag->preferred_parent, instance->default_lifetime);
dao_output(buf, instance->current_dag->preferred_parent, instance->default_lifetime);
#if RPL_CONF_MULTICAST
/* Send DAOs for multicast prefixes only if the instance is in MOP 3 */
@ -247,7 +250,7 @@ handle_dao_timer(void *ptr)
for(i = 0; i < UIP_DS6_MADDR_NB; i++) {
if(uip_ds6_if.maddr_list[i].isused
&& uip_is_addr_mcast_global(&uip_ds6_if.maddr_list[i].ipaddr)) {
dao_output_target(instance->current_dag->preferred_parent,
dao_output_target(buf, instance->current_dag->preferred_parent,
&uip_ds6_if.maddr_list[i].ipaddr, RPL_MCAST_LIFETIME);
}
}
@ -257,7 +260,7 @@ handle_dao_timer(void *ptr)
while(mcast_route != NULL) {
/* Don't send if it's also our own address, done that already */
if(uip_ds6_maddr_lookup(&mcast_route->group) == NULL) {
dao_output_target(instance->current_dag->preferred_parent,
dao_output_target(buf, instance->current_dag->preferred_parent,
&mcast_route->group, RPL_MCAST_LIFETIME);
}
mcast_route = list_item_next(mcast_route);
@ -271,12 +274,12 @@ handle_dao_timer(void *ptr)
ctimer_stop(&instance->dao_timer);
if(etimer_expired(&instance->dao_lifetime_timer.etimer)) {
set_dao_lifetime_timer(instance);
set_dao_lifetime_timer(buf, instance);
}
}
/*---------------------------------------------------------------------------*/
static void
schedule_dao(rpl_instance_t *instance, clock_time_t latency)
schedule_dao(struct net_buf *buf, rpl_instance_t *instance, clock_time_t latency)
{
clock_time_t expiration_time;
@ -297,23 +300,23 @@ schedule_dao(rpl_instance_t *instance, clock_time_t latency)
}
PRINTF("RPL: Scheduling DAO timer %u ticks in the future\n",
(unsigned)expiration_time);
ctimer_set(&instance->dao_timer, expiration_time,
ctimer_set((struct net_mbuf *)buf, &instance->dao_timer, expiration_time,
handle_dao_timer, instance);
set_dao_lifetime_timer(instance);
set_dao_lifetime_timer(buf, instance);
}
}
/*---------------------------------------------------------------------------*/
void
rpl_schedule_dao(rpl_instance_t *instance)
rpl_schedule_dao(struct net_buf *buf, rpl_instance_t *instance)
{
schedule_dao(instance, RPL_DAO_LATENCY);
schedule_dao(buf, instance, RPL_DAO_LATENCY);
}
/*---------------------------------------------------------------------------*/
void
rpl_schedule_dao_immediately(rpl_instance_t *instance)
rpl_schedule_dao_immediately(struct net_buf *buf, rpl_instance_t *instance)
{
schedule_dao(instance, 0);
schedule_dao(buf, instance, 0);
}
/*---------------------------------------------------------------------------*/
void

View file

@ -59,6 +59,12 @@
rpl_stats_t rpl_stats;
#endif
static struct net_buf netbuf;
struct net_buf *rpl_get_netbuf(void)
{
return &netbuf;
}
static enum rpl_mode mode = RPL_MODE_MESH;
/*---------------------------------------------------------------------------*/
enum rpl_mode
@ -68,7 +74,7 @@ rpl_get_mode(void)
}
/*---------------------------------------------------------------------------*/
enum rpl_mode
rpl_set_mode(enum rpl_mode m)
rpl_set_mode(struct net_buf *buf, enum rpl_mode m)
{
enum rpl_mode oldmode = mode;
@ -84,7 +90,7 @@ rpl_set_mode(enum rpl_mode m)
mode = m;
if(default_instance != NULL) {
rpl_schedule_dao_immediately(default_instance);
rpl_schedule_dao_immediately(buf, default_instance);
}
} else if(m == RPL_MODE_FEATHER) {
@ -102,7 +108,7 @@ rpl_set_mode(enum rpl_mode m)
}
/*---------------------------------------------------------------------------*/
void
rpl_purge_routes(void)
rpl_purge_routes(struct net_buf *buf)
{
uip_ds6_route_t *r;
uip_ipaddr_t prefix;
@ -142,7 +148,7 @@ rpl_purge_routes(void)
/* Propagate this information with a No-Path DAO to preferred parent if we are not a RPL Root */
if(dag->rank != ROOT_RANK(default_instance)) {
PRINTF(" -> generate No-Path DAO\n");
dao_output_target(dag->preferred_parent, &prefix, RPL_ZERO_LIFETIME);
dao_output_target(buf, dag->preferred_parent, &prefix, RPL_ZERO_LIFETIME);
/* Don't schedule more than 1 No-Path DAO, let next iteration handle that */
return;
}
@ -300,7 +306,7 @@ rpl_init(void)
default_instance = NULL;
rpl_dag_init();
rpl_reset_periodic_timer();
rpl_reset_periodic_timer(rpl_get_netbuf());
rpl_icmp6_register_handlers();
/* add rpl multicast address */

View file

@ -38,6 +38,8 @@
#ifndef RPL_H
#define RPL_H
#include <net/net_buf.h>
#include "rpl-conf.h"
#include "lib/list.h"
@ -233,18 +235,18 @@ struct rpl_instance {
/* Public RPL functions. */
void rpl_init(void);
void uip_rpl_input(void);
rpl_dag_t *rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id);
rpl_dag_t *rpl_set_root(struct net_buf *buf, uint8_t instance_id, uip_ipaddr_t *dag_id);
int rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len);
int rpl_repair_root(uint8_t instance_id);
int rpl_repair_root(struct net_buf *buf, uint8_t instance_id);
int rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from);
rpl_dag_t *rpl_get_any_dag(void);
rpl_instance_t *rpl_get_instance(uint8_t instance_id);
int rpl_update_header_empty(void);
int rpl_update_header_final(uip_ipaddr_t *addr);
int rpl_verify_header(int);
void rpl_insert_header(void);
void rpl_remove_header(void);
uint8_t rpl_invert_header(void);
int rpl_update_header_empty(struct net_buf *buf);
int rpl_update_header_final(struct net_buf *buf, uip_ipaddr_t *addr);
int rpl_verify_header(struct net_buf *buf, int);
void rpl_insert_header(struct net_buf *buf);
void rpl_remove_header(struct net_buf *buf);
uint8_t rpl_invert_header(struct net_buf *buf);
uip_ipaddr_t *rpl_get_parent_ipaddr(rpl_parent_t *nbr);
rpl_parent_t *rpl_get_parent(uip_lladdr_t *addr);
rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
@ -274,7 +276,7 @@ enum rpl_mode {
* \param mode The new RPL mode
* \retval The previous RPL mode
*/
enum rpl_mode rpl_set_mode(enum rpl_mode mode);
enum rpl_mode rpl_set_mode(struct net_buf *buf, enum rpl_mode mode);
/**
* Get the RPL mode