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 #endif
#define NETSTACK_CONF_LLSEC nullsec_driver #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 #ifndef NETSTACK_CONF_RADIO
/* #error "No radio configured, cannot continue!" */ /* #error "No radio configured, cannot continue!" */
#endif #endif

View file

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

View file

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

View file

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

View file

@ -59,6 +59,8 @@
#ifndef UIP_MCAST6_H_ #ifndef UIP_MCAST6_H_
#define UIP_MCAST6_H_ #define UIP_MCAST6_H_
#include <net/net_buf.h>
#include "contiki-conf.h" #include "contiki-conf.h"
#include "net/ipv6/multicast/uip-mcast6-engines.h" #include "net/ipv6/multicast/uip-mcast6-engines.h"
#include "net/ipv6/multicast/uip-mcast6-route.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 * return value whether the datagram needs delivered up the network
* stack. * 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_ext_len(buf) > 0) {
#if UIP_CONF_IPV6_RPL #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*/ /* If there were other extension headers*/
UIP_FIRST_EXT_BUF(buf)->next = UIP_PROTO_ICMP6; UIP_FIRST_EXT_BUF(buf)->next = UIP_PROTO_ICMP6;
if (uip_ext_len(buf) != temp_ext_len) { 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 #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 */ #else /* UIP_CONF_IPV6_RPL */
uip_ext_len(buf) = 0; uip_ext_len(buf) = 0;
#endif /* UIP_CONF_IPV6_RPL */ #endif /* UIP_CONF_IPV6_RPL */
@ -339,7 +339,7 @@ echo_reply_input(struct net_buf *buf)
if(uip_ext_len(buf) > 0) { if(uip_ext_len(buf) > 0) {
#if UIP_CONF_IPV6_RPL #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*/ /* If there were other extension headers*/
UIP_FIRST_EXT_BUF(buf)->next = UIP_PROTO_ICMP6; UIP_FIRST_EXT_BUF(buf)->next = UIP_PROTO_ICMP6;
if (uip_ext_len(buf) != temp_ext_len) { 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 #if UIP_CONF_IPV6_RPL
PRINTF("Processing RPL option\n"); 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"); PRINTF("RPL Option Error: Dropping Packet\n");
return 1; return 1;
} }
@ -1605,7 +1605,7 @@ uip_process(struct net_buf *buf, uint8_t flag)
#endif /* UIP_UDP_CHECKSUMS */ #endif /* UIP_UDP_CHECKSUMS */
#if UIP_CONF_IPV6_RPL #if UIP_CONF_IPV6_RPL
rpl_insert_header(); rpl_insert_header(buf);
#endif /* UIP_CONF_IPV6_RPL */ #endif /* UIP_CONF_IPV6_RPL */
UIP_STAT(++uip_stat.udp.sent); UIP_STAT(++uip_stat.udp.sent);

View file

@ -97,7 +97,7 @@ rpl_get_nbr(rpl_parent_t *parent)
static void static void
nbr_callback(void *ptr) nbr_callback(void *ptr)
{ {
rpl_remove_parent(ptr); rpl_remove_parent(rpl_get_netbuf(), ptr);
} }
void 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. */ /* Remove DAG parents with a rank that is at least the same as minimum_rank. */
static void 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; 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); p = nbr_table_head(rpl_parents);
while(p != NULL) { while(p != NULL) {
if(dag == p->dag && p->rank >= minimum_rank) { if(dag == p->dag && p->rank >= minimum_rank) {
rpl_remove_parent(p); rpl_remove_parent(buf, p);
} }
p = nbr_table_next(rpl_parents, p); p = nbr_table_next(rpl_parents, p);
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void 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; 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); p = nbr_table_head(rpl_parents);
while(p != NULL) { while(p != NULL) {
if(dag == p->dag && p->rank >= minimum_rank) { if(dag == p->dag && p->rank >= minimum_rank) {
rpl_nullify_parent(p); rpl_nullify_parent(buf, p);
} }
p = nbr_table_next(rpl_parents, 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_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_dag_t *dag;
rpl_instance_t *instance; 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) { if(dag == dag->instance->current_dag) {
dag->instance->current_dag = NULL; 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) { if(dag == NULL) {
PRINTF("RPL: Failed to allocate a DAG\n"); PRINTF("RPL: Failed to allocate a DAG\n");
return NULL; 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]); 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; return dag;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int int
rpl_repair_root(uint8_t instance_id) rpl_repair_root(struct net_buf *buf, uint8_t instance_id)
{ {
rpl_instance_t *instance; 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->current_dag->version);
RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); RPL_LOLLIPOP_INCREMENT(instance->dtsn_out);
PRINTF("RPL: rpl_repair_root initiating global repair with version %d\n", instance->current_dag->version); 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; return 1;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -481,7 +481,7 @@ rpl_alloc_instance(uint8_t instance_id)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
rpl_dag_t * 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_dag_t *dag, *end;
rpl_instance_t *instance; 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_STAT(rpl_stats.mem_overflows++);
rpl_free_instance(instance); rpl_free_instance(buf, instance);
return NULL; return NULL;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -518,7 +518,7 @@ rpl_set_default_instance(rpl_instance_t *instance)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void 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 *dag;
rpl_dag_t *end; rpl_dag_t *end;
@ -528,7 +528,7 @@ rpl_free_instance(rpl_instance_t *instance)
/* Remove any DAG inside this instance */ /* Remove any DAG inside this instance */
for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) { for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) {
if(dag->used) { if(dag->used) {
rpl_free_dag(dag); rpl_free_dag(buf, dag);
} }
} }
@ -546,7 +546,7 @@ rpl_free_instance(rpl_instance_t *instance)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
rpl_free_dag(rpl_dag_t *dag) rpl_free_dag(struct net_buf *buf, rpl_dag_t *dag)
{ {
if(dag->joined) { if(dag->joined) {
PRINTF("RPL: Leaving the DAG "); PRINTF("RPL: Leaving the DAG ");
@ -562,7 +562,7 @@ rpl_free_dag(rpl_dag_t *dag)
check_prefix(&dag->prefix_info, NULL); check_prefix(&dag->prefix_info, NULL);
} }
remove_parents(dag, 0); remove_parents(buf, dag, 0);
} }
dag->used = 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_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_parent_t *last_parent;
rpl_dag_t *dag, *end, *best_dag; 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); rpl_set_preferred_parent(instance->current_dag, NULL);
if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES && last_parent != NULL) { if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES && last_parent != NULL) {
/* Send a No-Path DAO to the removed preferred parent. */ /* 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; 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(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) {
if(last_parent != NULL) { if(last_parent != NULL) {
/* Send a No-Path DAO to the removed preferred parent. */ /* 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. */ /* The DAO parent set changed - schedule a DAO transmission. */
RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); 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) { } else if(best_dag->rank != old_rank) {
PRINTF("RPL: Preferred parent update, rank changed from %u to %u\n", PRINTF("RPL: Preferred parent update, rank changed from %u to %u\n",
(unsigned)old_rank, best_dag->rank); (unsigned)old_rank, best_dag->rank);
@ -771,19 +771,19 @@ rpl_select_parent(rpl_dag_t *dag)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
rpl_remove_parent(rpl_parent_t *parent) rpl_remove_parent(struct net_buf *buf, rpl_parent_t *parent)
{ {
PRINTF("RPL: Removing parent "); PRINTF("RPL: Removing parent ");
PRINT6ADDR(rpl_get_parent_ipaddr(parent)); PRINT6ADDR(rpl_get_parent_ipaddr(parent));
PRINTF("\n"); PRINTF("\n");
rpl_nullify_parent(parent); rpl_nullify_parent(buf, parent);
nbr_table_remove(rpl_parents, parent); nbr_table_remove(rpl_parents, parent);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void 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; rpl_dag_t *dag = parent->dag;
/* This function can be called when the preferred parent is NULL, so we /* 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 */ /* Send no-path DAO only to preferred parent, if any */
if(parent == dag->preferred_parent) { if(parent == dag->preferred_parent) {
dao_output(parent, RPL_ZERO_LIFETIME); dao_output(buf, parent, RPL_ZERO_LIFETIME);
rpl_set_preferred_parent(dag, NULL); rpl_set_preferred_parent(dag, NULL);
} }
} }
@ -880,14 +880,14 @@ rpl_find_of(rpl_ocp_t ocp)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void 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_instance_t *instance;
rpl_dag_t *dag; rpl_dag_t *dag;
rpl_parent_t *p; rpl_parent_t *p;
rpl_of_t *of; 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) { if(dag == NULL) {
PRINTF("RPL: Failed to allocate a DAG object!\n"); PRINTF("RPL: Failed to allocate a DAG object!\n");
return; return;
@ -913,7 +913,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
if(of == NULL) { if(of == NULL) {
PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF\n", PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF\n",
dio->instance_id); dio->instance_id);
rpl_remove_parent(p); rpl_remove_parent(buf, p);
instance->used = 0; instance->used = 0;
return; 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]); 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); rpl_set_default_route(instance, from);
if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) { if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) {
rpl_schedule_dao(instance); rpl_schedule_dao(buf, instance);
} else { } else {
PRINTF("RPL: The DIO does not meet the prerequisites for sending a DAO\n"); 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 #if RPL_MAX_DAG_PER_INSTANCE > 1
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void 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_instance_t *instance;
rpl_dag_t *dag, *previous_dag; rpl_dag_t *dag, *previous_dag;
rpl_parent_t *p; rpl_parent_t *p;
rpl_of_t *of; 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) { if(dag == NULL) {
PRINTF("RPL: Failed to allocate a DAG object!\n"); PRINTF("RPL: Failed to allocate a DAG object!\n");
return; return;
@ -1026,7 +1026,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
instance->lifetime_unit != dio->lifetime_unit) { instance->lifetime_unit != dio->lifetime_unit) {
PRINTF("RPL: DIO for DAG instance %u incompatible with previous DIO\n", PRINTF("RPL: DIO for DAG instance %u incompatible with previous DIO\n",
dio->instance_id); dio->instance_id);
rpl_remove_parent(p); rpl_remove_parent(buf, p);
dag->used = 0; dag->used = 0;
return; 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]); 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; p->dtsn = dio->dtsn;
} }
#endif /* RPL_MAX_DAG_PER_INSTANCE > 1 */ #endif /* RPL_MAX_DAG_PER_INSTANCE > 1 */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void 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; rpl_parent_t *p;
remove_parents(dag, 0); remove_parents(buf, dag, 0);
dag->version = dio->version; dag->version = dio->version;
/* copy parts of the configuration so that it propagates in the network */ /* 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->rank = dag->instance->of->calculate_rank(p, 0);
dag->min_rank = dag->rank; dag->min_rank = dag->rank;
PRINTF("RPL: rpl_process_parent_event global repair\n"); 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", 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 void
rpl_local_repair(rpl_instance_t *instance) rpl_local_repair(struct net_buf *buf, rpl_instance_t *instance)
{ {
int i; int i;
@ -1107,17 +1107,17 @@ rpl_local_repair(rpl_instance_t *instance)
for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; i++) { for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; i++) {
if(instance->dag_table[i].used) { if(instance->dag_table[i].used) {
instance->dag_table[i].rank = INFINITE_RANK; 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++); RPL_STAT(rpl_stats.local_repairs++);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
rpl_recalculate_ranks(void) rpl_recalculate_ranks(struct net_buf *buf)
{ {
rpl_parent_t *p; 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)) { if(p->dag != NULL && p->dag->instance && (p->flags & RPL_PARENT_FLAG_UPDATED)) {
p->flags &= ~RPL_PARENT_FLAG_UPDATED; p->flags &= ~RPL_PARENT_FLAG_UPDATED;
PRINTF("RPL: rpl_process_parent_event recalculate_ranks\n"); 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"); PRINTF("RPL: A parent was dropped\n");
} }
} }
@ -1140,7 +1140,7 @@ rpl_recalculate_ranks(void)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int 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; 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 /* The candidate parent is no longer valid: the rank increase resulting
from the choice of it as a parent would be too high. */ from the choice of it as a parent would be too high. */
PRINTF("RPL: Unacceptable rank %u\n", (unsigned)p->rank); 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) { if(p != instance->current_dag->preferred_parent) {
return 0; return 0;
} else { } 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. */ /* No suitable parent; trigger a local repair. */
PRINTF("RPL: No parents found in any DAG\n"); PRINTF("RPL: No parents found in any DAG\n");
rpl_local_repair(instance); rpl_local_repair(buf, instance);
return 0; return 0;
} }
@ -1189,7 +1189,7 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void 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_instance_t *instance;
rpl_dag_t *dag, *previous_dag; 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"); PRINTF("RPL: Root received inconsistent DIO version number\n");
dag->version = dio->version; dag->version = dio->version;
RPL_LOLLIPOP_INCREMENT(dag->version); RPL_LOLLIPOP_INCREMENT(dag->version);
rpl_reset_dio_timer(instance); rpl_reset_dio_timer(buf, instance);
} else { } else {
PRINTF("RPL: Global repair\n"); PRINTF("RPL: Global repair\n");
if(dio->prefix_info.length != 0) { 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); rpl_set_prefix(dag, &dio->prefix_info.prefix, dio->prefix_info.length);
} }
} }
global_repair(from, dag, dio); global_repair(buf, from, dag, dio);
} }
return; 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. */ /* The DIO sender is on an older version of the DAG. */
PRINTF("RPL: old version received => inconsistency detected\n"); PRINTF("RPL: old version received => inconsistency detected\n");
if(dag->joined) { if(dag->joined) {
rpl_reset_dio_timer(instance); rpl_reset_dio_timer(buf, instance);
return; return;
} }
} }
@ -1241,7 +1241,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
if(instance == NULL) { if(instance == NULL) {
PRINTF("RPL: New instance detected: Joining...\n"); PRINTF("RPL: New instance detected: Joining...\n");
rpl_join_instance(from, dio); rpl_join_instance(buf, from, dio);
return; return;
} }
@ -1253,7 +1253,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
if(dag == NULL) { if(dag == NULL) {
#if RPL_MAX_DAG_PER_INSTANCE > 1 #if RPL_MAX_DAG_PER_INSTANCE > 1
PRINTF("RPL: Adding new DAG to known instance.\n"); PRINTF("RPL: Adding new DAG to known instance.\n");
rpl_add_dag(from, dio); rpl_add_dag(buf, from, dio);
return; return;
#else /* RPL_MAX_DAG_PER_INSTANCE > 1 */ #else /* RPL_MAX_DAG_PER_INSTANCE > 1 */
PRINTF("RPL: Only one instance supported.\n"); 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); (unsigned)dio->rank);
return; return;
} else if(dio->rank == INFINITE_RANK && dag->joined) { } 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 */ /* 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 #if RPL_DAG_MC != RPL_DAG_MC_NONE
memcpy(&p->mc, &dio->mc, sizeof(p->mc)); memcpy(&p->mc, &dio->mc, sizeof(p->mc));
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ #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"); PRINTF("RPL: The candidate parent is rejected\n");
return; return;
} }
@ -1345,7 +1345,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
if(dag->joined && p == dag->preferred_parent) { if(dag->joined && p == dag->preferred_parent) {
if(should_send_dao(instance, dio, p)) { if(should_send_dao(instance, dio, p)) {
RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); RPL_LOLLIPOP_INCREMENT(instance->dtsn_out);
rpl_schedule_dao(instance); rpl_schedule_dao(buf, instance);
} }
/* We received a new DIO from our preferred parent. /* We received a new DIO from our preferred parent.
* Call uip_ds6_defrt_add to set a fresh value for the lifetime counter */ * 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/uip.h"
#include "net/ip/tcpip.h" #include "net/ip/tcpip.h"
#include "net/ipv6/uip-ds6.h" #include "net/ipv6/uip-ds6.h"
@ -57,16 +59,16 @@
#include <string.h> #include <string.h>
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#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])
#define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len]) #define UIP_EXT_BUF(buf) ((struct uip_ext_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)])
#define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len]) #define UIP_HBHO_BUF(buf) ((struct uip_hbho_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)])
#define UIP_HBHO_NEXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len + RPL_HOP_BY_HOP_LEN]) #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 ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset]) #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 ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + 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 ((struct uip_ext_hdr_opt_rpl *)&uip_buf[uip_l2_l3_hdr_len + 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 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; rpl_instance_t *instance;
int down; int down;
@ -74,41 +76,41 @@ rpl_verify_header(int uip_ext_opt_offset)
uint8_t sender_closer; uint8_t sender_closer;
uip_ds6_route_t *route; 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"); PRINTF("RPL: Hop-by-hop extension header has wrong size\n");
return 1; 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"); PRINTF("RPL: Non RPL Hop-by-hop option\n");
return 1; 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"); PRINTF("RPL: Bad header option! (wrong length)\n");
return 1; 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) { if(instance == NULL) {
PRINTF("RPL: Unknown instance: %u\n", PRINTF("RPL: Unknown instance: %u\n",
UIP_EXT_HDR_OPT_RPL_BUF->instance); UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance);
return 1; 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"); PRINTF("RPL: Forward error!\n");
/* We should try to repair it by removing the neighbor that caused /* We should try to repair it by removing the neighbor that caused
the packet to be forwareded in the first place. We drop any the packet to be forwareded in the first place. We drop any
routes that go through the neighbor that sent the packet to routes that go through the neighbor that sent the packet to
us. */ us. */
route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr); route = uip_ds6_route_lookup(&UIP_IP_BUF(buf)->destipaddr);
if(route != NULL) { if(route != NULL) {
uip_ds6_route_rm(route); uip_ds6_route_rm(route);
} }
RPL_STAT(rpl_stats.forward_errors++); RPL_STAT(rpl_stats.forward_errors++);
/* Trigger DAO retransmission */ /* Trigger DAO retransmission */
rpl_reset_dio_timer(instance); rpl_reset_dio_timer(buf, instance);
/* drop the packet as it is not routable */ /* drop the packet as it is not routable */
return 1; return 1;
} }
@ -119,11 +121,11 @@ rpl_verify_header(int uip_ext_opt_offset)
} }
down = 0; 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; 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; sender_closer = sender_rank < instance->current_dag->rank;
PRINTF("RPL: Packet going %s, sender closer %d (%d < %d)\n", down == 1 ? "down" : "up", 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", PRINTF("RPL: Loop detected - senderrank: %d my-rank: %d sender_closer: %d\n",
sender_rank, instance->current_dag->rank, sender_rank, instance->current_dag->rank,
sender_closer); 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++); RPL_STAT(rpl_stats.loop_errors++);
PRINTF("RPL: Rank error signalled in RPL option!\n"); PRINTF("RPL: Rank error signalled in RPL option!\n");
/* Packet must be dropped and dio trickle timer reset, see RFC6550 - 11.2.2.2 */ /* 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; return 1;
} }
PRINTF("RPL: Single error tolerated\n"); PRINTF("RPL: Single error tolerated\n");
RPL_STAT(rpl_stats.loop_warnings++); 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; return 0;
} }
@ -155,60 +157,60 @@ rpl_verify_header(int uip_ext_opt_offset)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void 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; uint8_t temp_len;
memmove(UIP_HBHO_NEXT_BUF, UIP_EXT_BUF, uip_len - UIP_IPH_LEN); memmove(UIP_HBHO_NEXT_BUF(buf), UIP_EXT_BUF(buf), uip_len(buf) - UIP_IPH_LEN);
memset(UIP_HBHO_BUF, 0, RPL_HOP_BY_HOP_LEN); memset(UIP_HBHO_BUF(buf), 0, RPL_HOP_BY_HOP_LEN);
UIP_HBHO_BUF->next = UIP_IP_BUF->proto; UIP_HBHO_BUF(buf)->next = UIP_IP_BUF(buf)->proto;
UIP_IP_BUF->proto = UIP_PROTO_HBHO; UIP_IP_BUF(buf)->proto = UIP_PROTO_HBHO;
UIP_HBHO_BUF->len = RPL_HOP_BY_HOP_LEN - 8; UIP_HBHO_BUF(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(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(buf)->opt_len = RPL_HDR_OPT_LEN;
UIP_EXT_HDR_OPT_RPL_BUF->flags = 0; UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags = 0;
UIP_EXT_HDR_OPT_RPL_BUF->instance = 0; UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance = 0;
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = 0; UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank = 0;
uip_len += RPL_HOP_BY_HOP_LEN; uip_len(buf) += RPL_HOP_BY_HOP_LEN;
temp_len = UIP_IP_BUF->len[1]; temp_len = UIP_IP_BUF(buf)->len[1];
UIP_IP_BUF->len[1] += UIP_HBHO_BUF->len + 8; UIP_IP_BUF(buf)->len[1] += UIP_HBHO_BUF(buf)->len + 8;
if(UIP_IP_BUF->len[1] < temp_len) { if(UIP_IP_BUF(buf)->len[1] < temp_len) {
UIP_IP_BUF->len[0]++; UIP_IP_BUF(buf)->len[0]++;
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int int
rpl_update_header_empty(void) rpl_update_header_empty(struct net_buf *buf)
{ {
rpl_instance_t *instance; rpl_instance_t *instance;
int uip_ext_opt_offset; int uip_ext_opt_offset;
int last_uip_ext_len; int last_uip_ext_len;
rpl_parent_t *parent; rpl_parent_t *parent;
last_uip_ext_len = uip_ext_len; last_uip_ext_len = uip_ext_len(buf);
uip_ext_len = 0; uip_ext_len(buf) = 0;
uip_ext_opt_offset = 2; uip_ext_opt_offset = 2;
PRINTF("RPL: Verifying the presence of the RPL header option\n"); 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: 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"); 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; 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"); 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; 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"); 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; 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) { if(instance == NULL || !instance->used || !instance->current_dag->joined) {
PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect instance\n"); PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect instance\n");
return 0; return 0;
@ -217,36 +219,36 @@ rpl_update_header_empty(void)
default: default:
#if RPL_INSERT_HBH_OPTION #if RPL_INSERT_HBH_OPTION
PRINTF("RPL: No hop-by-hop option found, creating it\n"); 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"); 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; return 0;
} }
set_rpl_opt(uip_ext_opt_offset); set_rpl_opt(buf, uip_ext_opt_offset);
uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN; uip_ext_len(buf) = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
#endif #endif
return 0; return 0;
} }
switch(UIP_EXT_HDR_OPT_BUF->type) { switch(UIP_EXT_HDR_OPT_BUF(buf)->type) {
case UIP_EXT_HDR_OPT_RPL: case UIP_EXT_HDR_OPT_RPL:
PRINTF("RPL: Updating RPL option\n"); 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, /* 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 which states that if a packet is going down it should in
general not go back up again. If this happens, a general not go back up again. If this happens, a
RPL_HDR_OPT_FWD_ERR should be flagged. */ RPL_HDR_OPT_FWD_ERR should be flagged. */
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)) {
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) { if(uip_ds6_route_lookup(&UIP_IP_BUF(buf)->destipaddr) == NULL) {
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_FWD_ERR; UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags |= RPL_HDR_OPT_FWD_ERR;
PRINTF("RPL forwarding error\n"); PRINTF("RPL forwarding error\n");
/* We should send back the packet to the originating parent, /* We should send back the packet to the originating parent,
but it is not feasible yet, so we send a No-Path DAO instead */ but it is not feasible yet, so we send a No-Path DAO instead */
PRINTF("RPL generate No-Path DAO\n"); 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) { 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 */ /* Drop packet */
return 1; return 1;
@ -255,47 +257,47 @@ rpl_update_header_empty(void)
/* Set the down extension flag correctly as described in Section /* Set the down extension flag correctly as described in Section
11.2 of RFC6550. If the packet progresses along a DAO route, 11.2 of RFC6550. If the packet progresses along a DAO route,
the down flag should be set. */ 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 /* No route was found, so this packet will go towards the RPL
root. If so, we should not set the down flag. */ 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"); PRINTF("RPL option going up\n");
} else { } else {
/* A DAO route was found so we set the down flag. */ /* 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"); PRINTF("RPL option going down\n");
} }
} }
uip_ext_len = last_uip_ext_len; uip_ext_len(buf) = last_uip_ext_len;
return 0; return 0;
default: default:
PRINTF("RPL: Multi Hop-by-hop options not implemented\n"); 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; return 0;
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int 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; rpl_parent_t *parent;
int uip_ext_opt_offset; int uip_ext_opt_offset;
int last_uip_ext_len; int last_uip_ext_len;
last_uip_ext_len = uip_ext_len; last_uip_ext_len = uip_ext_len(buf);
uip_ext_len = 0; uip_ext_len(buf) = 0;
uip_ext_opt_offset = 2; uip_ext_opt_offset = 2;
if(UIP_IP_BUF->proto == UIP_PROTO_HBHO) { if(UIP_IP_BUF(buf)->proto == 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: Non RPL Hop-by-hop options support not implemented\n"); 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; return 0;
} }
if(UIP_EXT_HDR_OPT_BUF->type == UIP_EXT_HDR_OPT_RPL) { if(UIP_EXT_HDR_OPT_BUF(buf)->type == UIP_EXT_HDR_OPT_RPL) {
if(UIP_EXT_HDR_OPT_RPL_BUF->senderrank == 0) { if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank == 0) {
PRINTF("RPL: Updating RPL option\n"); PRINTF("RPL: Updating RPL option\n");
if(default_instance == NULL || !default_instance->used || !default_instance->current_dag->joined) { 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"); 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); parent = rpl_find_parent(default_instance->current_dag, addr);
if(parent == NULL || parent != parent->dag->preferred_parent) { 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(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)->senderrank = UIP_HTONS(default_instance->current_dag->rank);
} }
} }
} }
@ -314,24 +316,24 @@ rpl_update_header_final(uip_ipaddr_t *addr)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
rpl_remove_header(void) rpl_remove_header(struct net_buf *buf)
{ {
uint8_t temp_len; uint8_t temp_len;
uip_ext_len = 0; uip_ext_len(buf) = 0;
PRINTF("RPL: Verifying the presence of the RPL header option\n"); 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: case UIP_PROTO_HBHO:
PRINTF("RPL: Removing the RPL header option\n"); PRINTF("RPL: Removing the RPL header option\n");
UIP_IP_BUF->proto = UIP_HBHO_BUF->next; UIP_IP_BUF(buf)->proto = UIP_HBHO_BUF(buf)->next;
temp_len = UIP_IP_BUF->len[1]; temp_len = UIP_IP_BUF(buf)->len[1];
uip_len -= UIP_HBHO_BUF->len + 8; uip_len(buf) -= UIP_HBHO_BUF(buf)->len + 8;
UIP_IP_BUF->len[1] -= UIP_HBHO_BUF->len + 8; UIP_IP_BUF(buf)->len[1] -= UIP_HBHO_BUF(buf)->len + 8;
if(UIP_IP_BUF->len[1] > temp_len) { if(UIP_IP_BUF(buf)->len[1] > temp_len) {
UIP_IP_BUF->len[0]--; 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; break;
default: default:
PRINTF("RPL: No hop-by-hop Option found\n"); PRINTF("RPL: No hop-by-hop Option found\n");
@ -339,46 +341,46 @@ rpl_remove_header(void)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uint8_t uint8_t
rpl_invert_header(void) rpl_invert_header(struct net_buf *buf)
{ {
uint8_t uip_ext_opt_offset; uint8_t uip_ext_opt_offset;
uint8_t last_uip_ext_len; uint8_t last_uip_ext_len;
last_uip_ext_len = uip_ext_len; last_uip_ext_len = uip_ext_len(buf);
uip_ext_len = 0; uip_ext_len(buf) = 0;
uip_ext_opt_offset = 2; uip_ext_opt_offset = 2;
PRINTF("RPL: Verifying the presence of the RPL header option\n"); 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: case UIP_PROTO_HBHO:
break; break;
default: default:
PRINTF("RPL: No hop-by-hop Option found\n"); 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; return 0;
} }
switch (UIP_EXT_HDR_OPT_BUF->type) { switch (UIP_EXT_HDR_OPT_BUF(buf)->type) {
case UIP_EXT_HDR_OPT_RPL: case UIP_EXT_HDR_OPT_RPL:
PRINTF("RPL: Updating RPL option (switching direction)\n"); 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(buf)->flags &= RPL_HDR_OPT_DOWN;
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->senderrank = UIP_HTONS(rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance)->current_dag->rank); 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 = last_uip_ext_len; uip_ext_len(buf) = last_uip_ext_len;
return RPL_HOP_BY_HOP_LEN; return RPL_HOP_BY_HOP_LEN;
default: default:
PRINTF("RPL: Multi Hop-by-hop options not implemented\n"); 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; return 0;
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
rpl_insert_header(void) rpl_insert_header(struct net_buf *buf)
{ {
#if RPL_INSERT_HBH_OPTION #if RPL_INSERT_HBH_OPTION
if(default_instance != NULL && !uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) { if(default_instance != NULL && !uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr)) {
rpl_update_header_empty(); rpl_update_header_empty(buf);
} }
#endif #endif
} }

View file

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

View file

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

View file

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

View file

@ -59,6 +59,12 @@
rpl_stats_t rpl_stats; rpl_stats_t rpl_stats;
#endif #endif
static struct net_buf netbuf;
struct net_buf *rpl_get_netbuf(void)
{
return &netbuf;
}
static enum rpl_mode mode = RPL_MODE_MESH; static enum rpl_mode mode = RPL_MODE_MESH;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
enum rpl_mode enum rpl_mode
@ -68,7 +74,7 @@ rpl_get_mode(void)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
enum rpl_mode 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; enum rpl_mode oldmode = mode;
@ -84,7 +90,7 @@ rpl_set_mode(enum rpl_mode m)
mode = m; mode = m;
if(default_instance != NULL) { if(default_instance != NULL) {
rpl_schedule_dao_immediately(default_instance); rpl_schedule_dao_immediately(buf, default_instance);
} }
} else if(m == RPL_MODE_FEATHER) { } else if(m == RPL_MODE_FEATHER) {
@ -102,7 +108,7 @@ rpl_set_mode(enum rpl_mode m)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
rpl_purge_routes(void) rpl_purge_routes(struct net_buf *buf)
{ {
uip_ds6_route_t *r; uip_ds6_route_t *r;
uip_ipaddr_t prefix; 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 */ /* 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)) { if(dag->rank != ROOT_RANK(default_instance)) {
PRINTF(" -> generate No-Path DAO\n"); 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 */ /* Don't schedule more than 1 No-Path DAO, let next iteration handle that */
return; return;
} }
@ -300,7 +306,7 @@ rpl_init(void)
default_instance = NULL; default_instance = NULL;
rpl_dag_init(); rpl_dag_init();
rpl_reset_periodic_timer(); rpl_reset_periodic_timer(rpl_get_netbuf());
rpl_icmp6_register_handlers(); rpl_icmp6_register_handlers();
/* add rpl multicast address */ /* add rpl multicast address */

View file

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