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:
parent
5d11691aa6
commit
e0509c5e6f
14 changed files with 337 additions and 313 deletions
|
@ -52,6 +52,11 @@ typedef unsigned int uip_stats_t;
|
|||
#endif
|
||||
#define NETSTACK_CONF_LLSEC nullsec_driver
|
||||
|
||||
#ifdef CONFIG_NETWORKING_WITH_RPL
|
||||
#define UIP_MCAST6_CONF_ENGINE UIP_MCAST6_ENGINE_SMRF
|
||||
#define UIP_CONF_IPV6_MULTICAST 1
|
||||
#endif
|
||||
|
||||
#ifndef NETSTACK_CONF_RADIO
|
||||
/* #error "No radio configured, cannot continue!" */
|
||||
#endif
|
||||
|
|
|
@ -641,7 +641,7 @@ tcpip_ipv6_output(struct net_buf *buf)
|
|||
if(dag != NULL) {
|
||||
instance = dag->instance;
|
||||
|
||||
rpl_repair_root(instance->instance_id);
|
||||
rpl_repair_root(buf, instance->instance_id);
|
||||
}
|
||||
#endif /* UIP_CONF_IPV6_RPL */
|
||||
uip_ds6_route_rm(route);
|
||||
|
@ -669,7 +669,7 @@ tcpip_ipv6_output(struct net_buf *buf)
|
|||
/* End of next hop determination */
|
||||
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
if(rpl_update_header_final(nexthop)) {
|
||||
if(rpl_update_header_final(buf, nexthop)) {
|
||||
uip_len(buf) = 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1741,7 +1741,7 @@ typedef struct uip_ext_hdr {
|
|||
typedef struct uip_hbho_hdr {
|
||||
uint8_t next;
|
||||
uint8_t len;
|
||||
} uip_hbho_hdr;
|
||||
} PACK_ALIAS_STRUCT uip_hbho_hdr;
|
||||
|
||||
/* destination option header */
|
||||
typedef struct uip_desto_hdr {
|
||||
|
@ -1796,7 +1796,7 @@ typedef struct uip_ext_hdr_opt_rpl {
|
|||
uint8_t flags;
|
||||
uint8_t instance;
|
||||
uint16_t senderrank;
|
||||
} uip_ext_hdr_opt_rpl;
|
||||
} PACK_ALIAS_STRUCT uip_ext_hdr_opt_rpl;
|
||||
|
||||
/* TCP header */
|
||||
struct uip_tcp_hdr {
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
#include <net/net_buf.h>
|
||||
|
||||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||
|
@ -49,6 +51,7 @@
|
|||
#include "net/ipv6/multicast/smrf.h"
|
||||
#include "net/rpl/rpl.h"
|
||||
#include "net/netstack.h"
|
||||
#include "contiki/os/lib/random.h"
|
||||
#include <string.h>
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
|
@ -65,27 +68,27 @@
|
|||
/* Internal Data */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static struct ctimer mcast_periodic;
|
||||
static uint8_t mcast_len;
|
||||
static uip_buf_t mcast_buf;
|
||||
static struct net_buf netbuf;
|
||||
static uint8_t fwd_delay;
|
||||
static uint8_t fwd_spread;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* uIPv6 Pointers */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN])
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
mcast_fwd(void *p)
|
||||
mcast_fwd(struct net_mbuf *mbuf, void *p)
|
||||
{
|
||||
memcpy(uip_buf, &mcast_buf, mcast_len);
|
||||
uip_len = mcast_len;
|
||||
UIP_IP_BUF->ttl--;
|
||||
tcpip_output(NULL);
|
||||
uip_len = 0;
|
||||
struct net_buf *buf = (struct net_buf *)mbuf;
|
||||
|
||||
UIP_IP_BUF(buf)->ttl--;
|
||||
tcpip_output(buf, NULL);
|
||||
uip_len(buf) = 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
in()
|
||||
in(struct net_buf *buf)
|
||||
{
|
||||
rpl_dag_t *d; /* Our DODAG */
|
||||
uip_ipaddr_t *parent_ipaddr; /* Our pref. parent's IPv6 address */
|
||||
|
@ -118,14 +121,14 @@ in()
|
|||
* We accept a datagram if it arrived from our preferred parent, discard
|
||||
* otherwise.
|
||||
*/
|
||||
if(memcmp(parent_lladdr, packetbuf_addr(PACKETBUF_ADDR_SENDER),
|
||||
if(memcmp(parent_lladdr, &buf->src,
|
||||
UIP_LLADDR_LEN)) {
|
||||
PRINTF("SMRF: Routable in but SMRF ignored it\n");
|
||||
UIP_MCAST6_STATS_ADD(mcast_dropped);
|
||||
return UIP_MCAST6_DROP;
|
||||
}
|
||||
|
||||
if(UIP_IP_BUF->ttl <= 1) {
|
||||
if(UIP_IP_BUF(buf)->ttl <= 1) {
|
||||
UIP_MCAST6_STATS_ADD(mcast_dropped);
|
||||
return UIP_MCAST6_DROP;
|
||||
}
|
||||
|
@ -135,7 +138,7 @@ in()
|
|||
|
||||
/* If we have an entry in the mcast routing table, something with
|
||||
* a higher RPL rank (somewhere down the tree) is a group member */
|
||||
if(uip_mcast6_route_lookup(&UIP_IP_BUF->destipaddr)) {
|
||||
if(uip_mcast6_route_lookup(&UIP_IP_BUF(buf)->destipaddr)) {
|
||||
/* If we enter here, we will definitely forward */
|
||||
UIP_MCAST6_STATS_ADD(mcast_fwd);
|
||||
|
||||
|
@ -155,9 +158,9 @@ in()
|
|||
|
||||
if(fwd_delay == 0) {
|
||||
/* No delay required, send it, do it now, why wait? */
|
||||
UIP_IP_BUF->ttl--;
|
||||
tcpip_output(NULL);
|
||||
UIP_IP_BUF->ttl++; /* Restore before potential upstack delivery */
|
||||
UIP_IP_BUF(buf)->ttl--;
|
||||
tcpip_output(buf, NULL);
|
||||
UIP_IP_BUF(buf)->ttl++; /* Restore before potential upstack delivery */
|
||||
} else {
|
||||
/* Randomise final delay in [D , D*Spread], step D */
|
||||
fwd_spread = SMRF_INTERVAL_COUNT;
|
||||
|
@ -168,16 +171,15 @@ in()
|
|||
fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread));
|
||||
}
|
||||
|
||||
memcpy(&mcast_buf, uip_buf, uip_len);
|
||||
mcast_len = uip_len;
|
||||
ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL);
|
||||
memcpy(&netbuf, buf, sizeof(*buf));
|
||||
ctimer_set((struct net_mbuf *)&netbuf, &mcast_periodic, fwd_delay, mcast_fwd, NULL);
|
||||
}
|
||||
PRINTF("SMRF: %u bytes: fwd in %u [%u]\n",
|
||||
uip_len, fwd_delay, fwd_spread);
|
||||
uip_len(buf), fwd_delay, fwd_spread);
|
||||
}
|
||||
|
||||
/* Done with this packet unless we are a member of the mcast group */
|
||||
if(!uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) {
|
||||
if(!uip_ds6_is_my_maddr(&UIP_IP_BUF(buf)->destipaddr)) {
|
||||
PRINTF("SMRF: Not a group member. No further processing\n");
|
||||
return UIP_MCAST6_DROP;
|
||||
} else {
|
||||
|
|
|
@ -59,6 +59,8 @@
|
|||
#ifndef UIP_MCAST6_H_
|
||||
#define UIP_MCAST6_H_
|
||||
|
||||
#include <net/net_buf.h>
|
||||
|
||||
#include "contiki-conf.h"
|
||||
#include "net/ipv6/multicast/uip-mcast6-engines.h"
|
||||
#include "net/ipv6/multicast/uip-mcast6-route.h"
|
||||
|
@ -134,7 +136,7 @@ struct uip_mcast6_driver {
|
|||
* return value whether the datagram needs delivered up the network
|
||||
* stack.
|
||||
*/
|
||||
uint8_t (* in)(void);
|
||||
uint8_t (* in)(struct net_buf *buf);
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
|
|
@ -155,7 +155,7 @@ echo_request_input(struct net_buf *buf)
|
|||
|
||||
if(uip_ext_len(buf) > 0) {
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
if((temp_ext_len = rpl_invert_header())) {
|
||||
if((temp_ext_len = rpl_invert_header(buf))) {
|
||||
/* If there were other extension headers*/
|
||||
UIP_FIRST_EXT_BUF(buf)->next = UIP_PROTO_ICMP6;
|
||||
if (uip_ext_len(buf) != temp_ext_len) {
|
||||
|
@ -230,7 +230,7 @@ uip_icmp6_error_output(struct net_buf *buf, uint8_t type, uint8_t code, uint32_t
|
|||
}
|
||||
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
uip_ext_len(buf) = rpl_invert_header();
|
||||
uip_ext_len(buf) = rpl_invert_header(buf);
|
||||
#else /* UIP_CONF_IPV6_RPL */
|
||||
uip_ext_len(buf) = 0;
|
||||
#endif /* UIP_CONF_IPV6_RPL */
|
||||
|
@ -339,7 +339,7 @@ echo_reply_input(struct net_buf *buf)
|
|||
|
||||
if(uip_ext_len(buf) > 0) {
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
if((temp_ext_len = rpl_invert_header())) {
|
||||
if((temp_ext_len = rpl_invert_header(buf))) {
|
||||
/* If there were other extension headers*/
|
||||
UIP_FIRST_EXT_BUF(buf)->next = UIP_PROTO_ICMP6;
|
||||
if (uip_ext_len(buf) != temp_ext_len) {
|
||||
|
|
|
@ -903,7 +903,7 @@ ext_hdr_options_process(struct net_buf *buf)
|
|||
*/
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
PRINTF("Processing RPL option\n");
|
||||
if(rpl_verify_header(uip_ext_opt_offset(buf))) {
|
||||
if(rpl_verify_header(buf, uip_ext_opt_offset(buf))) {
|
||||
PRINTF("RPL Option Error: Dropping Packet\n");
|
||||
return 1;
|
||||
}
|
||||
|
@ -1605,7 +1605,7 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
#endif /* UIP_UDP_CHECKSUMS */
|
||||
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
rpl_insert_header();
|
||||
rpl_insert_header(buf);
|
||||
#endif /* UIP_CONF_IPV6_RPL */
|
||||
|
||||
UIP_STAT(++uip_stat.udp.sent);
|
||||
|
|
|
@ -97,7 +97,7 @@ rpl_get_nbr(rpl_parent_t *parent)
|
|||
static void
|
||||
nbr_callback(void *ptr)
|
||||
{
|
||||
rpl_remove_parent(ptr);
|
||||
rpl_remove_parent(rpl_get_netbuf(), ptr);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -188,7 +188,7 @@ lollipop_greater_than(int a, int b)
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/* Remove DAG parents with a rank that is at least the same as minimum_rank. */
|
||||
static void
|
||||
remove_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
|
||||
remove_parents(struct net_buf *buf, rpl_dag_t *dag, rpl_rank_t minimum_rank)
|
||||
{
|
||||
rpl_parent_t *p;
|
||||
|
||||
|
@ -198,14 +198,14 @@ remove_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
|
|||
p = nbr_table_head(rpl_parents);
|
||||
while(p != NULL) {
|
||||
if(dag == p->dag && p->rank >= minimum_rank) {
|
||||
rpl_remove_parent(p);
|
||||
rpl_remove_parent(buf, p);
|
||||
}
|
||||
p = nbr_table_next(rpl_parents, p);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
|
||||
nullify_parents(struct net_buf *buf, rpl_dag_t *dag, rpl_rank_t minimum_rank)
|
||||
{
|
||||
rpl_parent_t *p;
|
||||
|
||||
|
@ -215,7 +215,7 @@ nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
|
|||
p = nbr_table_head(rpl_parents);
|
||||
while(p != NULL) {
|
||||
if(dag == p->dag && p->rank >= minimum_rank) {
|
||||
rpl_nullify_parent(p);
|
||||
rpl_nullify_parent(buf, p);
|
||||
}
|
||||
p = nbr_table_next(rpl_parents, p);
|
||||
}
|
||||
|
@ -264,7 +264,7 @@ get_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
rpl_dag_t *
|
||||
rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
|
||||
rpl_set_root(struct net_buf *buf, uint8_t instance_id, uip_ipaddr_t *dag_id)
|
||||
{
|
||||
rpl_dag_t *dag;
|
||||
rpl_instance_t *instance;
|
||||
|
@ -279,10 +279,10 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
|
|||
if(dag == dag->instance->current_dag) {
|
||||
dag->instance->current_dag = NULL;
|
||||
}
|
||||
rpl_free_dag(dag);
|
||||
rpl_free_dag(buf, dag);
|
||||
}
|
||||
|
||||
dag = rpl_alloc_dag(instance_id, dag_id);
|
||||
dag = rpl_alloc_dag(buf, instance_id, dag_id);
|
||||
if(dag == NULL) {
|
||||
PRINTF("RPL: Failed to allocate a DAG\n");
|
||||
return NULL;
|
||||
|
@ -332,13 +332,13 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
|
|||
|
||||
ANNOTATE("#A root=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]);
|
||||
|
||||
rpl_reset_dio_timer(instance);
|
||||
rpl_reset_dio_timer(buf, instance);
|
||||
|
||||
return dag;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rpl_repair_root(uint8_t instance_id)
|
||||
rpl_repair_root(struct net_buf *buf, uint8_t instance_id)
|
||||
{
|
||||
rpl_instance_t *instance;
|
||||
|
||||
|
@ -353,7 +353,7 @@ rpl_repair_root(uint8_t instance_id)
|
|||
RPL_LOLLIPOP_INCREMENT(instance->current_dag->version);
|
||||
RPL_LOLLIPOP_INCREMENT(instance->dtsn_out);
|
||||
PRINTF("RPL: rpl_repair_root initiating global repair with version %d\n", instance->current_dag->version);
|
||||
rpl_reset_dio_timer(instance);
|
||||
rpl_reset_dio_timer(buf, instance);
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -481,7 +481,7 @@ rpl_alloc_instance(uint8_t instance_id)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
rpl_dag_t *
|
||||
rpl_alloc_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
|
||||
rpl_alloc_dag(struct net_buf *buf, uint8_t instance_id, uip_ipaddr_t *dag_id)
|
||||
{
|
||||
rpl_dag_t *dag, *end;
|
||||
rpl_instance_t *instance;
|
||||
|
@ -507,7 +507,7 @@ rpl_alloc_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
|
|||
}
|
||||
|
||||
RPL_STAT(rpl_stats.mem_overflows++);
|
||||
rpl_free_instance(instance);
|
||||
rpl_free_instance(buf, instance);
|
||||
return NULL;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -518,7 +518,7 @@ rpl_set_default_instance(rpl_instance_t *instance)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_free_instance(rpl_instance_t *instance)
|
||||
rpl_free_instance(struct net_buf *buf, rpl_instance_t *instance)
|
||||
{
|
||||
rpl_dag_t *dag;
|
||||
rpl_dag_t *end;
|
||||
|
@ -528,7 +528,7 @@ rpl_free_instance(rpl_instance_t *instance)
|
|||
/* Remove any DAG inside this instance */
|
||||
for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) {
|
||||
if(dag->used) {
|
||||
rpl_free_dag(dag);
|
||||
rpl_free_dag(buf, dag);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,7 +546,7 @@ rpl_free_instance(rpl_instance_t *instance)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_free_dag(rpl_dag_t *dag)
|
||||
rpl_free_dag(struct net_buf *buf, rpl_dag_t *dag)
|
||||
{
|
||||
if(dag->joined) {
|
||||
PRINTF("RPL: Leaving the DAG ");
|
||||
|
@ -562,7 +562,7 @@ rpl_free_dag(rpl_dag_t *dag)
|
|||
check_prefix(&dag->prefix_info, NULL);
|
||||
}
|
||||
|
||||
remove_parents(dag, 0);
|
||||
remove_parents(buf, dag, 0);
|
||||
}
|
||||
dag->used = 0;
|
||||
}
|
||||
|
@ -646,7 +646,7 @@ rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
rpl_dag_t *
|
||||
rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p)
|
||||
rpl_select_dag(struct net_buf *buf, rpl_instance_t *instance, rpl_parent_t *p)
|
||||
{
|
||||
rpl_parent_t *last_parent;
|
||||
rpl_dag_t *dag, *end, *best_dag;
|
||||
|
@ -709,7 +709,7 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p)
|
|||
rpl_set_preferred_parent(instance->current_dag, NULL);
|
||||
if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES && last_parent != NULL) {
|
||||
/* Send a No-Path DAO to the removed preferred parent. */
|
||||
dao_output(last_parent, RPL_ZERO_LIFETIME);
|
||||
dao_output(buf, last_parent, RPL_ZERO_LIFETIME);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -722,13 +722,13 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p)
|
|||
if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) {
|
||||
if(last_parent != NULL) {
|
||||
/* Send a No-Path DAO to the removed preferred parent. */
|
||||
dao_output(last_parent, RPL_ZERO_LIFETIME);
|
||||
dao_output(buf, last_parent, RPL_ZERO_LIFETIME);
|
||||
}
|
||||
/* The DAO parent set changed - schedule a DAO transmission. */
|
||||
RPL_LOLLIPOP_INCREMENT(instance->dtsn_out);
|
||||
rpl_schedule_dao(instance);
|
||||
rpl_schedule_dao(buf, instance);
|
||||
}
|
||||
rpl_reset_dio_timer(instance);
|
||||
rpl_reset_dio_timer(buf, instance);
|
||||
} else if(best_dag->rank != old_rank) {
|
||||
PRINTF("RPL: Preferred parent update, rank changed from %u to %u\n",
|
||||
(unsigned)old_rank, best_dag->rank);
|
||||
|
@ -771,19 +771,19 @@ rpl_select_parent(rpl_dag_t *dag)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_remove_parent(rpl_parent_t *parent)
|
||||
rpl_remove_parent(struct net_buf *buf, rpl_parent_t *parent)
|
||||
{
|
||||
PRINTF("RPL: Removing parent ");
|
||||
PRINT6ADDR(rpl_get_parent_ipaddr(parent));
|
||||
PRINTF("\n");
|
||||
|
||||
rpl_nullify_parent(parent);
|
||||
rpl_nullify_parent(buf, parent);
|
||||
|
||||
nbr_table_remove(rpl_parents, parent);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_nullify_parent(rpl_parent_t *parent)
|
||||
rpl_nullify_parent(struct net_buf *buf, rpl_parent_t *parent)
|
||||
{
|
||||
rpl_dag_t *dag = parent->dag;
|
||||
/* This function can be called when the preferred parent is NULL, so we
|
||||
|
@ -800,7 +800,7 @@ rpl_nullify_parent(rpl_parent_t *parent)
|
|||
}
|
||||
/* Send no-path DAO only to preferred parent, if any */
|
||||
if(parent == dag->preferred_parent) {
|
||||
dao_output(parent, RPL_ZERO_LIFETIME);
|
||||
dao_output(buf, parent, RPL_ZERO_LIFETIME);
|
||||
rpl_set_preferred_parent(dag, NULL);
|
||||
}
|
||||
}
|
||||
|
@ -880,14 +880,14 @@ rpl_find_of(rpl_ocp_t ocp)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||
rpl_join_instance(struct net_buf *buf, uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||
{
|
||||
rpl_instance_t *instance;
|
||||
rpl_dag_t *dag;
|
||||
rpl_parent_t *p;
|
||||
rpl_of_t *of;
|
||||
|
||||
dag = rpl_alloc_dag(dio->instance_id, &dio->dag_id);
|
||||
dag = rpl_alloc_dag(buf, dio->instance_id, &dio->dag_id);
|
||||
if(dag == NULL) {
|
||||
PRINTF("RPL: Failed to allocate a DAG object!\n");
|
||||
return;
|
||||
|
@ -913,7 +913,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
if(of == NULL) {
|
||||
PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF\n",
|
||||
dio->instance_id);
|
||||
rpl_remove_parent(p);
|
||||
rpl_remove_parent(buf, p);
|
||||
instance->used = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -965,11 +965,11 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
|
||||
ANNOTATE("#A join=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]);
|
||||
|
||||
rpl_reset_dio_timer(instance);
|
||||
rpl_reset_dio_timer(buf, instance);
|
||||
rpl_set_default_route(instance, from);
|
||||
|
||||
if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) {
|
||||
rpl_schedule_dao(instance);
|
||||
rpl_schedule_dao(buf, instance);
|
||||
} else {
|
||||
PRINTF("RPL: The DIO does not meet the prerequisites for sending a DAO\n");
|
||||
}
|
||||
|
@ -978,14 +978,14 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
#if RPL_MAX_DAG_PER_INSTANCE > 1
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||
rpl_add_dag(struct net_buf *buf, uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||
{
|
||||
rpl_instance_t *instance;
|
||||
rpl_dag_t *dag, *previous_dag;
|
||||
rpl_parent_t *p;
|
||||
rpl_of_t *of;
|
||||
|
||||
dag = rpl_alloc_dag(dio->instance_id, &dio->dag_id);
|
||||
dag = rpl_alloc_dag(buf, dio->instance_id, &dio->dag_id);
|
||||
if(dag == NULL) {
|
||||
PRINTF("RPL: Failed to allocate a DAG object!\n");
|
||||
return;
|
||||
|
@ -1026,7 +1026,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
instance->lifetime_unit != dio->lifetime_unit) {
|
||||
PRINTF("RPL: DIO for DAG instance %u incompatible with previous DIO\n",
|
||||
dio->instance_id);
|
||||
rpl_remove_parent(p);
|
||||
rpl_remove_parent(buf, p);
|
||||
dag->used = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -1052,18 +1052,18 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
|
||||
ANNOTATE("#A join=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]);
|
||||
|
||||
rpl_process_parent_event(instance, p);
|
||||
rpl_process_parent_event(buf, instance, p);
|
||||
p->dtsn = dio->dtsn;
|
||||
}
|
||||
#endif /* RPL_MAX_DAG_PER_INSTANCE > 1 */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
|
||||
global_repair(struct net_buf *buf, uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
|
||||
{
|
||||
rpl_parent_t *p;
|
||||
|
||||
remove_parents(dag, 0);
|
||||
remove_parents(buf, dag, 0);
|
||||
dag->version = dio->version;
|
||||
|
||||
/* copy parts of the configuration so that it propagates in the network */
|
||||
|
@ -1085,7 +1085,7 @@ global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
|
|||
dag->rank = dag->instance->of->calculate_rank(p, 0);
|
||||
dag->min_rank = dag->rank;
|
||||
PRINTF("RPL: rpl_process_parent_event global repair\n");
|
||||
rpl_process_parent_event(dag->instance, p);
|
||||
rpl_process_parent_event(buf, dag->instance, p);
|
||||
}
|
||||
|
||||
PRINTF("RPL: Participating in a global repair (version=%u, rank=%hu)\n",
|
||||
|
@ -1095,7 +1095,7 @@ global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_local_repair(rpl_instance_t *instance)
|
||||
rpl_local_repair(struct net_buf *buf, rpl_instance_t *instance)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -1107,17 +1107,17 @@ rpl_local_repair(rpl_instance_t *instance)
|
|||
for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; i++) {
|
||||
if(instance->dag_table[i].used) {
|
||||
instance->dag_table[i].rank = INFINITE_RANK;
|
||||
nullify_parents(&instance->dag_table[i], 0);
|
||||
nullify_parents(buf, &instance->dag_table[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
rpl_reset_dio_timer(instance);
|
||||
rpl_reset_dio_timer(buf, instance);
|
||||
|
||||
RPL_STAT(rpl_stats.local_repairs++);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_recalculate_ranks(void)
|
||||
rpl_recalculate_ranks(struct net_buf *buf)
|
||||
{
|
||||
rpl_parent_t *p;
|
||||
|
||||
|
@ -1131,7 +1131,7 @@ rpl_recalculate_ranks(void)
|
|||
if(p->dag != NULL && p->dag->instance && (p->flags & RPL_PARENT_FLAG_UPDATED)) {
|
||||
p->flags &= ~RPL_PARENT_FLAG_UPDATED;
|
||||
PRINTF("RPL: rpl_process_parent_event recalculate_ranks\n");
|
||||
if(!rpl_process_parent_event(p->dag->instance, p)) {
|
||||
if(!rpl_process_parent_event(buf, p->dag->instance, p)) {
|
||||
PRINTF("RPL: A parent was dropped\n");
|
||||
}
|
||||
}
|
||||
|
@ -1140,7 +1140,7 @@ rpl_recalculate_ranks(void)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
|
||||
rpl_process_parent_event(struct net_buf *buf, rpl_instance_t *instance, rpl_parent_t *p)
|
||||
{
|
||||
int return_value;
|
||||
|
||||
|
@ -1155,7 +1155,7 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
|
|||
/* The candidate parent is no longer valid: the rank increase resulting
|
||||
from the choice of it as a parent would be too high. */
|
||||
PRINTF("RPL: Unacceptable rank %u\n", (unsigned)p->rank);
|
||||
rpl_nullify_parent(p);
|
||||
rpl_nullify_parent(buf, p);
|
||||
if(p != instance->current_dag->preferred_parent) {
|
||||
return 0;
|
||||
} else {
|
||||
|
@ -1163,10 +1163,10 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
|
|||
}
|
||||
}
|
||||
|
||||
if(rpl_select_dag(instance, p) == NULL) {
|
||||
if(rpl_select_dag(buf, instance, p) == NULL) {
|
||||
/* No suitable parent; trigger a local repair. */
|
||||
PRINTF("RPL: No parents found in any DAG\n");
|
||||
rpl_local_repair(instance);
|
||||
rpl_local_repair(buf, instance);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1189,7 +1189,7 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||
rpl_process_dio(struct net_buf *buf, uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||
{
|
||||
rpl_instance_t *instance;
|
||||
rpl_dag_t *dag, *previous_dag;
|
||||
|
@ -1215,7 +1215,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
PRINTF("RPL: Root received inconsistent DIO version number\n");
|
||||
dag->version = dio->version;
|
||||
RPL_LOLLIPOP_INCREMENT(dag->version);
|
||||
rpl_reset_dio_timer(instance);
|
||||
rpl_reset_dio_timer(buf, instance);
|
||||
} else {
|
||||
PRINTF("RPL: Global repair\n");
|
||||
if(dio->prefix_info.length != 0) {
|
||||
|
@ -1224,7 +1224,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
rpl_set_prefix(dag, &dio->prefix_info.prefix, dio->prefix_info.length);
|
||||
}
|
||||
}
|
||||
global_repair(from, dag, dio);
|
||||
global_repair(buf, from, dag, dio);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1233,7 +1233,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
/* The DIO sender is on an older version of the DAG. */
|
||||
PRINTF("RPL: old version received => inconsistency detected\n");
|
||||
if(dag->joined) {
|
||||
rpl_reset_dio_timer(instance);
|
||||
rpl_reset_dio_timer(buf, instance);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1241,7 +1241,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
|
||||
if(instance == NULL) {
|
||||
PRINTF("RPL: New instance detected: Joining...\n");
|
||||
rpl_join_instance(from, dio);
|
||||
rpl_join_instance(buf, from, dio);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1253,7 +1253,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
if(dag == NULL) {
|
||||
#if RPL_MAX_DAG_PER_INSTANCE > 1
|
||||
PRINTF("RPL: Adding new DAG to known instance.\n");
|
||||
rpl_add_dag(from, dio);
|
||||
rpl_add_dag(buf, from, dio);
|
||||
return;
|
||||
#else /* RPL_MAX_DAG_PER_INSTANCE > 1 */
|
||||
PRINTF("RPL: Only one instance supported.\n");
|
||||
|
@ -1267,7 +1267,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
(unsigned)dio->rank);
|
||||
return;
|
||||
} else if(dio->rank == INFINITE_RANK && dag->joined) {
|
||||
rpl_reset_dio_timer(instance);
|
||||
rpl_reset_dio_timer(buf, instance);
|
||||
}
|
||||
|
||||
/* Prefix Information Option treated to add new prefix */
|
||||
|
@ -1336,7 +1336,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
#if RPL_DAG_MC != RPL_DAG_MC_NONE
|
||||
memcpy(&p->mc, &dio->mc, sizeof(p->mc));
|
||||
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
|
||||
if(rpl_process_parent_event(instance, p) == 0) {
|
||||
if(rpl_process_parent_event(buf, instance, p) == 0) {
|
||||
PRINTF("RPL: The candidate parent is rejected\n");
|
||||
return;
|
||||
}
|
||||
|
@ -1345,7 +1345,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||
if(dag->joined && p == dag->preferred_parent) {
|
||||
if(should_send_dao(instance, dio, p)) {
|
||||
RPL_LOLLIPOP_INCREMENT(instance->dtsn_out);
|
||||
rpl_schedule_dao(instance);
|
||||
rpl_schedule_dao(buf, instance);
|
||||
}
|
||||
/* We received a new DIO from our preferred parent.
|
||||
* Call uip_ds6_defrt_add to set a fresh value for the lifetime counter */
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
#include <net/net_buf.h>
|
||||
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ip/tcpip.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
|
@ -57,16 +59,16 @@
|
|||
#include <string.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_HBHO_NEXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len + RPL_HOP_BY_HOP_LEN])
|
||||
#define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
#define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
#define UIP_EXT_HDR_OPT_RPL_BUF ((struct uip_ext_hdr_opt_rpl *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN])
|
||||
#define UIP_EXT_BUF(buf) ((struct uip_ext_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)])
|
||||
#define UIP_HBHO_BUF(buf) ((struct uip_hbho_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)])
|
||||
#define UIP_HBHO_NEXT_BUF(buf) ((struct uip_ext_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf) + RPL_HOP_BY_HOP_LEN])
|
||||
#define UIP_EXT_HDR_OPT_BUF(buf) ((struct uip_ext_hdr_opt *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf) + uip_ext_opt_offset])
|
||||
#define UIP_EXT_HDR_OPT_PADN_BUF(buf) ((struct uip_ext_hdr_opt_padn *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf) + uip_ext_opt_offset])
|
||||
#define UIP_EXT_HDR_OPT_RPL_BUF(buf) ((struct uip_ext_hdr_opt_rpl *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf) + uip_ext_opt_offset])
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rpl_verify_header(int uip_ext_opt_offset)
|
||||
rpl_verify_header(struct net_buf *buf, int uip_ext_opt_offset)
|
||||
{
|
||||
rpl_instance_t *instance;
|
||||
int down;
|
||||
|
@ -74,41 +76,41 @@ rpl_verify_header(int uip_ext_opt_offset)
|
|||
uint8_t sender_closer;
|
||||
uip_ds6_route_t *route;
|
||||
|
||||
if(UIP_HBHO_BUF->len != RPL_HOP_BY_HOP_LEN - 8) {
|
||||
if(UIP_HBHO_BUF(buf)->len != RPL_HOP_BY_HOP_LEN - 8) {
|
||||
PRINTF("RPL: Hop-by-hop extension header has wrong size\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL) {
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_type != UIP_EXT_HDR_OPT_RPL) {
|
||||
PRINTF("RPL: Non RPL Hop-by-hop option\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_len != RPL_HDR_OPT_LEN) {
|
||||
PRINTF("RPL: Bad header option! (wrong length)\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
||||
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance);
|
||||
if(instance == NULL) {
|
||||
PRINTF("RPL: Unknown instance: %u\n",
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) {
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags & RPL_HDR_OPT_FWD_ERR) {
|
||||
PRINTF("RPL: Forward error!\n");
|
||||
/* We should try to repair it by removing the neighbor that caused
|
||||
the packet to be forwareded in the first place. We drop any
|
||||
routes that go through the neighbor that sent the packet to
|
||||
us. */
|
||||
route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);
|
||||
route = uip_ds6_route_lookup(&UIP_IP_BUF(buf)->destipaddr);
|
||||
if(route != NULL) {
|
||||
uip_ds6_route_rm(route);
|
||||
}
|
||||
RPL_STAT(rpl_stats.forward_errors++);
|
||||
/* Trigger DAO retransmission */
|
||||
rpl_reset_dio_timer(instance);
|
||||
rpl_reset_dio_timer(buf, instance);
|
||||
/* drop the packet as it is not routable */
|
||||
return 1;
|
||||
}
|
||||
|
@ -119,11 +121,11 @@ rpl_verify_header(int uip_ext_opt_offset)
|
|||
}
|
||||
|
||||
down = 0;
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN) {
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags & RPL_HDR_OPT_DOWN) {
|
||||
down = 1;
|
||||
}
|
||||
|
||||
sender_rank = UIP_HTONS(UIP_EXT_HDR_OPT_RPL_BUF->senderrank);
|
||||
sender_rank = UIP_HTONS(UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank);
|
||||
sender_closer = sender_rank < instance->current_dag->rank;
|
||||
|
||||
PRINTF("RPL: Packet going %s, sender closer %d (%d < %d)\n", down == 1 ? "down" : "up",
|
||||
|
@ -136,16 +138,16 @@ rpl_verify_header(int uip_ext_opt_offset)
|
|||
PRINTF("RPL: Loop detected - senderrank: %d my-rank: %d sender_closer: %d\n",
|
||||
sender_rank, instance->current_dag->rank,
|
||||
sender_closer);
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_RANK_ERR) {
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags & RPL_HDR_OPT_RANK_ERR) {
|
||||
RPL_STAT(rpl_stats.loop_errors++);
|
||||
PRINTF("RPL: Rank error signalled in RPL option!\n");
|
||||
/* Packet must be dropped and dio trickle timer reset, see RFC6550 - 11.2.2.2 */
|
||||
rpl_reset_dio_timer(instance);
|
||||
rpl_reset_dio_timer(buf, instance);
|
||||
return 1;
|
||||
}
|
||||
PRINTF("RPL: Single error tolerated\n");
|
||||
RPL_STAT(rpl_stats.loop_warnings++);
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_RANK_ERR;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags |= RPL_HDR_OPT_RANK_ERR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -155,60 +157,60 @@ rpl_verify_header(int uip_ext_opt_offset)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_rpl_opt(unsigned uip_ext_opt_offset)
|
||||
set_rpl_opt(struct net_buf *buf, unsigned uip_ext_opt_offset)
|
||||
{
|
||||
uint8_t temp_len;
|
||||
|
||||
memmove(UIP_HBHO_NEXT_BUF, UIP_EXT_BUF, uip_len - UIP_IPH_LEN);
|
||||
memset(UIP_HBHO_BUF, 0, RPL_HOP_BY_HOP_LEN);
|
||||
UIP_HBHO_BUF->next = UIP_IP_BUF->proto;
|
||||
UIP_IP_BUF->proto = UIP_PROTO_HBHO;
|
||||
UIP_HBHO_BUF->len = RPL_HOP_BY_HOP_LEN - 8;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_type = UIP_EXT_HDR_OPT_RPL;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_len = RPL_HDR_OPT_LEN;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags = 0;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->instance = 0;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = 0;
|
||||
uip_len += RPL_HOP_BY_HOP_LEN;
|
||||
temp_len = UIP_IP_BUF->len[1];
|
||||
UIP_IP_BUF->len[1] += UIP_HBHO_BUF->len + 8;
|
||||
if(UIP_IP_BUF->len[1] < temp_len) {
|
||||
UIP_IP_BUF->len[0]++;
|
||||
memmove(UIP_HBHO_NEXT_BUF(buf), UIP_EXT_BUF(buf), uip_len(buf) - UIP_IPH_LEN);
|
||||
memset(UIP_HBHO_BUF(buf), 0, RPL_HOP_BY_HOP_LEN);
|
||||
UIP_HBHO_BUF(buf)->next = UIP_IP_BUF(buf)->proto;
|
||||
UIP_IP_BUF(buf)->proto = UIP_PROTO_HBHO;
|
||||
UIP_HBHO_BUF(buf)->len = RPL_HOP_BY_HOP_LEN - 8;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_type = UIP_EXT_HDR_OPT_RPL;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_len = RPL_HDR_OPT_LEN;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags = 0;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance = 0;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank = 0;
|
||||
uip_len(buf) += RPL_HOP_BY_HOP_LEN;
|
||||
temp_len = UIP_IP_BUF(buf)->len[1];
|
||||
UIP_IP_BUF(buf)->len[1] += UIP_HBHO_BUF(buf)->len + 8;
|
||||
if(UIP_IP_BUF(buf)->len[1] < temp_len) {
|
||||
UIP_IP_BUF(buf)->len[0]++;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rpl_update_header_empty(void)
|
||||
rpl_update_header_empty(struct net_buf *buf)
|
||||
{
|
||||
rpl_instance_t *instance;
|
||||
int uip_ext_opt_offset;
|
||||
int last_uip_ext_len;
|
||||
rpl_parent_t *parent;
|
||||
|
||||
last_uip_ext_len = uip_ext_len;
|
||||
uip_ext_len = 0;
|
||||
last_uip_ext_len = uip_ext_len(buf);
|
||||
uip_ext_len(buf) = 0;
|
||||
uip_ext_opt_offset = 2;
|
||||
|
||||
PRINTF("RPL: Verifying the presence of the RPL header option\n");
|
||||
|
||||
switch(UIP_IP_BUF->proto) {
|
||||
switch(UIP_IP_BUF(buf)->proto) {
|
||||
case UIP_PROTO_HBHO:
|
||||
if(UIP_HBHO_BUF->len != RPL_HOP_BY_HOP_LEN - 8) {
|
||||
if(UIP_HBHO_BUF(buf)->len != RPL_HOP_BY_HOP_LEN - 8) {
|
||||
PRINTF("RPL: Hop-by-hop extension header has wrong size\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
uip_ext_len(buf) = last_uip_ext_len;
|
||||
return 0;
|
||||
}
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL) {
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_type != UIP_EXT_HDR_OPT_RPL) {
|
||||
PRINTF("RPL: Non RPL Hop-by-hop option support not implemented\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
uip_ext_len(buf) = last_uip_ext_len;
|
||||
return 0;
|
||||
}
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->opt_len != RPL_HDR_OPT_LEN) {
|
||||
PRINTF("RPL: RPL Hop-by-hop option has wrong length\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
uip_ext_len(buf) = last_uip_ext_len;
|
||||
return 0;
|
||||
}
|
||||
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
||||
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance);
|
||||
if(instance == NULL || !instance->used || !instance->current_dag->joined) {
|
||||
PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect instance\n");
|
||||
return 0;
|
||||
|
@ -217,36 +219,36 @@ rpl_update_header_empty(void)
|
|||
default:
|
||||
#if RPL_INSERT_HBH_OPTION
|
||||
PRINTF("RPL: No hop-by-hop option found, creating it\n");
|
||||
if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE) {
|
||||
if(uip_len(buf) + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE) {
|
||||
PRINTF("RPL: Packet too long: impossible to add hop-by-hop option\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
uip_ext_len(buf) = last_uip_ext_len;
|
||||
return 0;
|
||||
}
|
||||
set_rpl_opt(uip_ext_opt_offset);
|
||||
uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
|
||||
set_rpl_opt(buf, uip_ext_opt_offset);
|
||||
uip_ext_len(buf) = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(UIP_EXT_HDR_OPT_BUF->type) {
|
||||
switch(UIP_EXT_HDR_OPT_BUF(buf)->type) {
|
||||
case UIP_EXT_HDR_OPT_RPL:
|
||||
PRINTF("RPL: Updating RPL option\n");
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(instance->current_dag->rank);
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank = UIP_HTONS(instance->current_dag->rank);
|
||||
|
||||
/* Check the direction of the down flag, as per Section 11.2.2.3,
|
||||
which states that if a packet is going down it should in
|
||||
general not go back up again. If this happens, a
|
||||
RPL_HDR_OPT_FWD_ERR should be flagged. */
|
||||
if((UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN)) {
|
||||
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_FWD_ERR;
|
||||
if((UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags & RPL_HDR_OPT_DOWN)) {
|
||||
if(uip_ds6_route_lookup(&UIP_IP_BUF(buf)->destipaddr) == NULL) {
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags |= RPL_HDR_OPT_FWD_ERR;
|
||||
PRINTF("RPL forwarding error\n");
|
||||
/* We should send back the packet to the originating parent,
|
||||
but it is not feasible yet, so we send a No-Path DAO instead */
|
||||
PRINTF("RPL generate No-Path DAO\n");
|
||||
parent = rpl_get_parent((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
parent = rpl_get_parent((uip_lladdr_t *)&buf->src);
|
||||
if(parent != NULL) {
|
||||
dao_output_target(parent, &UIP_IP_BUF->destipaddr, RPL_ZERO_LIFETIME);
|
||||
dao_output_target(buf, parent, &UIP_IP_BUF(buf)->destipaddr, RPL_ZERO_LIFETIME);
|
||||
}
|
||||
/* Drop packet */
|
||||
return 1;
|
||||
|
@ -255,47 +257,47 @@ rpl_update_header_empty(void)
|
|||
/* Set the down extension flag correctly as described in Section
|
||||
11.2 of RFC6550. If the packet progresses along a DAO route,
|
||||
the down flag should be set. */
|
||||
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
|
||||
if(uip_ds6_route_lookup(&UIP_IP_BUF(buf)->destipaddr) == NULL) {
|
||||
/* No route was found, so this packet will go towards the RPL
|
||||
root. If so, we should not set the down flag. */
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_DOWN;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags &= ~RPL_HDR_OPT_DOWN;
|
||||
PRINTF("RPL option going up\n");
|
||||
} else {
|
||||
/* A DAO route was found so we set the down flag. */
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_DOWN;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags |= RPL_HDR_OPT_DOWN;
|
||||
PRINTF("RPL option going down\n");
|
||||
}
|
||||
}
|
||||
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
uip_ext_len(buf) = last_uip_ext_len;
|
||||
return 0;
|
||||
default:
|
||||
PRINTF("RPL: Multi Hop-by-hop options not implemented\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
uip_ext_len(buf) = last_uip_ext_len;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rpl_update_header_final(uip_ipaddr_t *addr)
|
||||
rpl_update_header_final(struct net_buf *buf, uip_ipaddr_t *addr)
|
||||
{
|
||||
rpl_parent_t *parent;
|
||||
int uip_ext_opt_offset;
|
||||
int last_uip_ext_len;
|
||||
|
||||
last_uip_ext_len = uip_ext_len;
|
||||
uip_ext_len = 0;
|
||||
last_uip_ext_len = uip_ext_len(buf);
|
||||
uip_ext_len(buf) = 0;
|
||||
uip_ext_opt_offset = 2;
|
||||
|
||||
if(UIP_IP_BUF->proto == UIP_PROTO_HBHO) {
|
||||
if(UIP_HBHO_BUF->len != RPL_HOP_BY_HOP_LEN - 8) {
|
||||
if(UIP_IP_BUF(buf)->proto == UIP_PROTO_HBHO) {
|
||||
if(UIP_HBHO_BUF(buf)->len != RPL_HOP_BY_HOP_LEN - 8) {
|
||||
PRINTF("RPL: Non RPL Hop-by-hop options support not implemented\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
uip_ext_len(buf) = last_uip_ext_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(UIP_EXT_HDR_OPT_BUF->type == UIP_EXT_HDR_OPT_RPL) {
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF->senderrank == 0) {
|
||||
if(UIP_EXT_HDR_OPT_BUF(buf)->type == UIP_EXT_HDR_OPT_RPL) {
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank == 0) {
|
||||
PRINTF("RPL: Updating RPL option\n");
|
||||
if(default_instance == NULL || !default_instance->used || !default_instance->current_dag->joined) {
|
||||
PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect default instance\n");
|
||||
|
@ -303,10 +305,10 @@ rpl_update_header_final(uip_ipaddr_t *addr)
|
|||
}
|
||||
parent = rpl_find_parent(default_instance->current_dag, addr);
|
||||
if(parent == NULL || parent != parent->dag->preferred_parent) {
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags = RPL_HDR_OPT_DOWN;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags = RPL_HDR_OPT_DOWN;
|
||||
}
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->instance = default_instance->instance_id;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(default_instance->current_dag->rank);
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance = default_instance->instance_id;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank = UIP_HTONS(default_instance->current_dag->rank);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -314,24 +316,24 @@ rpl_update_header_final(uip_ipaddr_t *addr)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_remove_header(void)
|
||||
rpl_remove_header(struct net_buf *buf)
|
||||
{
|
||||
uint8_t temp_len;
|
||||
|
||||
uip_ext_len = 0;
|
||||
uip_ext_len(buf) = 0;
|
||||
|
||||
PRINTF("RPL: Verifying the presence of the RPL header option\n");
|
||||
switch(UIP_IP_BUF->proto){
|
||||
switch(UIP_IP_BUF(buf)->proto){
|
||||
case UIP_PROTO_HBHO:
|
||||
PRINTF("RPL: Removing the RPL header option\n");
|
||||
UIP_IP_BUF->proto = UIP_HBHO_BUF->next;
|
||||
temp_len = UIP_IP_BUF->len[1];
|
||||
uip_len -= UIP_HBHO_BUF->len + 8;
|
||||
UIP_IP_BUF->len[1] -= UIP_HBHO_BUF->len + 8;
|
||||
if(UIP_IP_BUF->len[1] > temp_len) {
|
||||
UIP_IP_BUF->len[0]--;
|
||||
UIP_IP_BUF(buf)->proto = UIP_HBHO_BUF(buf)->next;
|
||||
temp_len = UIP_IP_BUF(buf)->len[1];
|
||||
uip_len(buf) -= UIP_HBHO_BUF(buf)->len + 8;
|
||||
UIP_IP_BUF(buf)->len[1] -= UIP_HBHO_BUF(buf)->len + 8;
|
||||
if(UIP_IP_BUF(buf)->len[1] > temp_len) {
|
||||
UIP_IP_BUF(buf)->len[0]--;
|
||||
}
|
||||
memmove(UIP_EXT_BUF, UIP_HBHO_NEXT_BUF, uip_len - UIP_IPH_LEN);
|
||||
memmove(UIP_EXT_BUF(buf), UIP_HBHO_NEXT_BUF(buf), uip_len(buf) - UIP_IPH_LEN);
|
||||
break;
|
||||
default:
|
||||
PRINTF("RPL: No hop-by-hop Option found\n");
|
||||
|
@ -339,46 +341,46 @@ rpl_remove_header(void)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
rpl_invert_header(void)
|
||||
rpl_invert_header(struct net_buf *buf)
|
||||
{
|
||||
uint8_t uip_ext_opt_offset;
|
||||
uint8_t last_uip_ext_len;
|
||||
|
||||
last_uip_ext_len = uip_ext_len;
|
||||
uip_ext_len = 0;
|
||||
last_uip_ext_len = uip_ext_len(buf);
|
||||
uip_ext_len(buf) = 0;
|
||||
uip_ext_opt_offset = 2;
|
||||
|
||||
PRINTF("RPL: Verifying the presence of the RPL header option\n");
|
||||
switch(UIP_IP_BUF->proto) {
|
||||
switch(UIP_IP_BUF(buf)->proto) {
|
||||
case UIP_PROTO_HBHO:
|
||||
break;
|
||||
default:
|
||||
PRINTF("RPL: No hop-by-hop Option found\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
uip_ext_len(buf) = last_uip_ext_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (UIP_EXT_HDR_OPT_BUF->type) {
|
||||
switch (UIP_EXT_HDR_OPT_BUF(buf)->type) {
|
||||
case UIP_EXT_HDR_OPT_RPL:
|
||||
PRINTF("RPL: Updating RPL option (switching direction)\n");
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags &= RPL_HDR_OPT_DOWN;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags ^= RPL_HDR_OPT_DOWN;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance)->current_dag->rank);
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags &= RPL_HDR_OPT_DOWN;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->flags ^= RPL_HDR_OPT_DOWN;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF(buf)->senderrank = UIP_HTONS(rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF(buf)->instance)->current_dag->rank);
|
||||
uip_ext_len(buf) = last_uip_ext_len;
|
||||
return RPL_HOP_BY_HOP_LEN;
|
||||
default:
|
||||
PRINTF("RPL: Multi Hop-by-hop options not implemented\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
uip_ext_len(buf) = last_uip_ext_len;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_insert_header(void)
|
||||
rpl_insert_header(struct net_buf *buf)
|
||||
{
|
||||
#if RPL_INSERT_HBH_OPTION
|
||||
if(default_instance != NULL && !uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
|
||||
rpl_update_header_empty();
|
||||
if(default_instance != NULL && !uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr)) {
|
||||
rpl_update_header_empty(buf);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -45,13 +45,14 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
#include <net/net_buf.h>
|
||||
|
||||
#include "net/ip/tcpip.h"
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#include "net/ipv6/uip-nd6.h"
|
||||
#include "net/ipv6/uip-icmp6.h"
|
||||
#include "net/rpl/rpl-private.h"
|
||||
#include "net/packetbuf.h"
|
||||
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
@ -67,14 +68,14 @@
|
|||
#define RPL_DIO_MOP_MASK 0x38
|
||||
#define RPL_DIO_PREFERENCE_MASK 0x07
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_ICMP_PAYLOAD ((unsigned char *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN])
|
||||
#define UIP_ICMP_BUF(buf) ((struct uip_icmp_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)])
|
||||
#define UIP_ICMP_PAYLOAD(buf) ((unsigned char *)&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf)])
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void dis_input(void);
|
||||
static void dio_input(void);
|
||||
static void dao_input(void);
|
||||
static void dao_ack_input(void);
|
||||
static void dis_input(struct net_buf *buf);
|
||||
static void dio_input(struct net_buf *buf);
|
||||
static void dao_input(struct net_buf *buf);
|
||||
static void dao_ack_input(struct net_buf *buf);
|
||||
|
||||
/* some debug callbacks useful when debugging RPL networks */
|
||||
#ifdef RPL_DEBUG_DIO_INPUT
|
||||
|
@ -148,38 +149,38 @@ set16(uint8_t *buffer, int pos, uint16_t value)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
dis_input(void)
|
||||
dis_input(struct net_buf *buf)
|
||||
{
|
||||
rpl_instance_t *instance;
|
||||
rpl_instance_t *end;
|
||||
|
||||
/* DAG Information Solicitation */
|
||||
PRINTF("RPL: Received a DIS from ");
|
||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||
PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr);
|
||||
PRINTF("\n");
|
||||
|
||||
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES;
|
||||
instance < end; ++instance) {
|
||||
if(instance->used == 1) {
|
||||
#if RPL_LEAF_ONLY
|
||||
if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
|
||||
if(!uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr)) {
|
||||
PRINTF("RPL: LEAF ONLY Multicast DIS will NOT reset DIO timer\n");
|
||||
#else /* !RPL_LEAF_ONLY */
|
||||
if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
|
||||
if(uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr)) {
|
||||
PRINTF("RPL: Multicast DIS => reset DIO timer\n");
|
||||
rpl_reset_dio_timer(instance);
|
||||
rpl_reset_dio_timer(buf, instance);
|
||||
} else {
|
||||
#endif /* !RPL_LEAF_ONLY */
|
||||
PRINTF("RPL: Unicast DIS, reply to sender\n");
|
||||
dio_output(instance, &UIP_IP_BUF->srcipaddr);
|
||||
dio_output(buf, instance, &UIP_IP_BUF(buf)->srcipaddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
uip_len = 0;
|
||||
uip_len(buf) = 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
dis_output(uip_ipaddr_t *addr)
|
||||
dis_output(struct net_buf *buf, uip_ipaddr_t *addr)
|
||||
{
|
||||
unsigned char *buffer;
|
||||
uip_ipaddr_t tmpaddr;
|
||||
|
@ -193,7 +194,7 @@ dis_output(uip_ipaddr_t *addr)
|
|||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
buffer = UIP_ICMP_PAYLOAD;
|
||||
buffer = UIP_ICMP_PAYLOAD(buf);
|
||||
buffer[0] = buffer[1] = 0;
|
||||
|
||||
if(addr == NULL) {
|
||||
|
@ -205,11 +206,11 @@ dis_output(uip_ipaddr_t *addr)
|
|||
PRINT6ADDR(addr);
|
||||
PRINTF("\n");
|
||||
|
||||
uip_icmp6_send(addr, ICMP6_RPL, RPL_CODE_DIS, 2);
|
||||
uip_icmp6_send(buf, addr, ICMP6_RPL, RPL_CODE_DIS, 2);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
dio_input(void)
|
||||
dio_input(struct net_buf *buf)
|
||||
{
|
||||
unsigned char *buffer;
|
||||
uint8_t buffer_length;
|
||||
|
@ -232,7 +233,7 @@ dio_input(void)
|
|||
dio.default_lifetime = RPL_DEFAULT_LIFETIME;
|
||||
dio.lifetime_unit = RPL_DEFAULT_LIFETIME_UNIT;
|
||||
|
||||
uip_ipaddr_copy(&from, &UIP_IP_BUF->srcipaddr);
|
||||
uip_ipaddr_copy(&from, &UIP_IP_BUF(buf)->srcipaddr);
|
||||
|
||||
/* DAG Information Object */
|
||||
PRINTF("RPL: Received a DIO from ");
|
||||
|
@ -240,21 +241,20 @@ dio_input(void)
|
|||
PRINTF("\n");
|
||||
|
||||
if((nbr = uip_ds6_nbr_lookup(&from)) == NULL) {
|
||||
if((nbr = uip_ds6_nbr_add(&from, (uip_lladdr_t *)
|
||||
packetbuf_addr(PACKETBUF_ADDR_SENDER),
|
||||
if((nbr = uip_ds6_nbr_add(&from, (uip_lladdr_t *)&buf->src,
|
||||
0, NBR_REACHABLE)) != NULL) {
|
||||
/* set reachable timer */
|
||||
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
|
||||
PRINTF("RPL: Neighbor added to neighbor cache ");
|
||||
PRINT6ADDR(&from);
|
||||
PRINTF(", ");
|
||||
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
PRINTLLADDR((uip_lladdr_t *)buf->src);
|
||||
PRINTF("\n");
|
||||
} else {
|
||||
PRINTF("RPL: Out of memory, dropping DIO from ");
|
||||
PRINT6ADDR(&from);
|
||||
PRINTF(", ");
|
||||
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
PRINTLLADDR((uip_lladdr_t *)buf->src);
|
||||
PRINTF("\n");
|
||||
return;
|
||||
}
|
||||
|
@ -262,11 +262,11 @@ dio_input(void)
|
|||
PRINTF("RPL: Neighbor already in neighbor cache\n");
|
||||
}
|
||||
|
||||
buffer_length = uip_len - uip_l3_icmp_hdr_len;
|
||||
buffer_length = uip_len(buf) - uip_l3_icmp_hdr_len(buf);
|
||||
|
||||
/* Process the DIO base option. */
|
||||
i = 0;
|
||||
buffer = UIP_ICMP_PAYLOAD;
|
||||
buffer = UIP_ICMP_PAYLOAD(buf);
|
||||
|
||||
dio.instance_id = buffer[i++];
|
||||
dio.version = buffer[i++];
|
||||
|
@ -416,13 +416,13 @@ dio_input(void)
|
|||
RPL_DEBUG_DIO_INPUT(&from, &dio);
|
||||
#endif
|
||||
|
||||
rpl_process_dio(&from, &dio);
|
||||
rpl_process_dio(buf, &from, &dio);
|
||||
|
||||
uip_len = 0;
|
||||
uip_len(buf) = 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr)
|
||||
dio_output(struct net_buf *buf, rpl_instance_t *instance, uip_ipaddr_t *uc_addr)
|
||||
{
|
||||
unsigned char *buffer;
|
||||
int pos;
|
||||
|
@ -443,7 +443,7 @@ dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr)
|
|||
/* DAG Information Object */
|
||||
pos = 0;
|
||||
|
||||
buffer = UIP_ICMP_PAYLOAD;
|
||||
buffer = UIP_ICMP_PAYLOAD(buf);
|
||||
buffer[pos++] = instance->instance_id;
|
||||
buffer[pos++] = dag->version;
|
||||
|
||||
|
@ -553,26 +553,26 @@ dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr)
|
|||
(unsigned)dag->rank);
|
||||
PRINT6ADDR(uc_addr);
|
||||
PRINTF("\n");
|
||||
uip_icmp6_send(uc_addr, ICMP6_RPL, RPL_CODE_DIO, pos);
|
||||
uip_icmp6_send(buf, uc_addr, ICMP6_RPL, RPL_CODE_DIO, pos);
|
||||
#else /* RPL_LEAF_ONLY */
|
||||
/* Unicast requests get unicast replies! */
|
||||
if(uc_addr == NULL) {
|
||||
PRINTF("RPL: Sending a multicast-DIO with rank %u\n",
|
||||
(unsigned)instance->current_dag->rank);
|
||||
uip_create_linklocal_rplnodes_mcast(&addr);
|
||||
uip_icmp6_send(&addr, ICMP6_RPL, RPL_CODE_DIO, pos);
|
||||
uip_icmp6_send(buf, &addr, ICMP6_RPL, RPL_CODE_DIO, pos);
|
||||
} else {
|
||||
PRINTF("RPL: Sending unicast-DIO with rank %u to ",
|
||||
(unsigned)instance->current_dag->rank);
|
||||
PRINT6ADDR(uc_addr);
|
||||
PRINTF("\n");
|
||||
uip_icmp6_send(uc_addr, ICMP6_RPL, RPL_CODE_DIO, pos);
|
||||
uip_icmp6_send(buf, uc_addr, ICMP6_RPL, RPL_CODE_DIO, pos);
|
||||
}
|
||||
#endif /* RPL_LEAF_ONLY */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
dao_input(void)
|
||||
dao_input(struct net_buf *buf)
|
||||
{
|
||||
uip_ipaddr_t dao_sender_addr;
|
||||
rpl_dag_t *dag;
|
||||
|
@ -601,15 +601,15 @@ dao_input(void)
|
|||
prefixlen = 0;
|
||||
parent = NULL;
|
||||
|
||||
uip_ipaddr_copy(&dao_sender_addr, &UIP_IP_BUF->srcipaddr);
|
||||
uip_ipaddr_copy(&dao_sender_addr, &UIP_IP_BUF(buf)->srcipaddr);
|
||||
|
||||
/* Destination Advertisement Object */
|
||||
PRINTF("RPL: Received a DAO from ");
|
||||
PRINT6ADDR(&dao_sender_addr);
|
||||
PRINTF("\n");
|
||||
|
||||
buffer = UIP_ICMP_PAYLOAD;
|
||||
buffer_length = uip_len - uip_l3_icmp_hdr_len;
|
||||
buffer = UIP_ICMP_PAYLOAD(buf);
|
||||
buffer_length = uip_len(buf) - uip_l3_icmp_hdr_len(buf);
|
||||
|
||||
pos = 0;
|
||||
instance_id = buffer[pos++];
|
||||
|
@ -732,11 +732,11 @@ dao_input(void)
|
|||
PRINTF("RPL: Forwarding no-path DAO to parent ");
|
||||
PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent));
|
||||
PRINTF("\n");
|
||||
uip_icmp6_send(rpl_get_parent_ipaddr(dag->preferred_parent),
|
||||
uip_icmp6_send(buf, rpl_get_parent_ipaddr(dag->preferred_parent),
|
||||
ICMP6_RPL, RPL_CODE_DAO, buffer_length);
|
||||
}
|
||||
if(flags & RPL_DAO_K_FLAG) {
|
||||
dao_ack_output(instance, &dao_sender_addr, sequence);
|
||||
dao_ack_output(buf, instance, &dao_sender_addr, sequence);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -746,20 +746,20 @@ dao_input(void)
|
|||
|
||||
if((nbr = uip_ds6_nbr_lookup(&dao_sender_addr)) == NULL) {
|
||||
if((nbr = uip_ds6_nbr_add(&dao_sender_addr,
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER),
|
||||
(uip_lladdr_t *)&buf->src,
|
||||
0, NBR_REACHABLE)) != NULL) {
|
||||
/* set reachable timer */
|
||||
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
|
||||
PRINTF("RPL: Neighbor added to neighbor cache ");
|
||||
PRINT6ADDR(&dao_sender_addr);
|
||||
PRINTF(", ");
|
||||
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
PRINTLLADDR((uip_lladdr_t *)buf->src);
|
||||
PRINTF("\n");
|
||||
} else {
|
||||
PRINTF("RPL: Out of Memory, dropping DAO from ");
|
||||
PRINT6ADDR(&dao_sender_addr);
|
||||
PRINTF(", ");
|
||||
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
PRINTLLADDR((uip_lladdr_t *)buf->src);
|
||||
PRINTF("\n");
|
||||
return;
|
||||
}
|
||||
|
@ -790,18 +790,18 @@ fwd_dao:
|
|||
PRINTF("RPL: Forwarding DAO to parent ");
|
||||
PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent));
|
||||
PRINTF("\n");
|
||||
uip_icmp6_send(rpl_get_parent_ipaddr(dag->preferred_parent),
|
||||
uip_icmp6_send(buf, rpl_get_parent_ipaddr(dag->preferred_parent),
|
||||
ICMP6_RPL, RPL_CODE_DAO, buffer_length);
|
||||
}
|
||||
if(flags & RPL_DAO_K_FLAG) {
|
||||
dao_ack_output(instance, &dao_sender_addr, sequence);
|
||||
dao_ack_output(buf, instance, &dao_sender_addr, sequence);
|
||||
}
|
||||
}
|
||||
uip_len = 0;
|
||||
uip_len(buf) = 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
dao_output(rpl_parent_t *parent, uint8_t lifetime)
|
||||
dao_output(struct net_buf *buf, rpl_parent_t *parent, uint8_t lifetime)
|
||||
{
|
||||
/* Destination Advertisement Object */
|
||||
uip_ipaddr_t prefix;
|
||||
|
@ -812,11 +812,11 @@ dao_output(rpl_parent_t *parent, uint8_t lifetime)
|
|||
}
|
||||
|
||||
/* Sending a DAO with own prefix as target */
|
||||
dao_output_target(parent, &prefix, lifetime);
|
||||
dao_output_target(buf, parent, &prefix, lifetime);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime)
|
||||
dao_output_target(struct net_buf *buf, rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime)
|
||||
{
|
||||
rpl_dag_t *dag;
|
||||
rpl_instance_t *instance;
|
||||
|
@ -856,7 +856,7 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime)
|
|||
RPL_DEBUG_DAO_OUTPUT(parent);
|
||||
#endif
|
||||
|
||||
buffer = UIP_ICMP_PAYLOAD;
|
||||
buffer = UIP_ICMP_PAYLOAD(buf);
|
||||
|
||||
RPL_LOLLIPOP_INCREMENT(dao_sequence);
|
||||
pos = 0;
|
||||
|
@ -901,12 +901,12 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime)
|
|||
PRINTF("\n");
|
||||
|
||||
if(rpl_get_parent_ipaddr(parent) != NULL) {
|
||||
uip_icmp6_send(rpl_get_parent_ipaddr(parent), ICMP6_RPL, RPL_CODE_DAO, pos);
|
||||
uip_icmp6_send(buf, rpl_get_parent_ipaddr(parent), ICMP6_RPL, RPL_CODE_DAO, pos);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
dao_ack_input(void)
|
||||
dao_ack_input(struct net_buf *buf)
|
||||
{
|
||||
#if DEBUG
|
||||
unsigned char *buffer;
|
||||
|
@ -915,8 +915,8 @@ dao_ack_input(void)
|
|||
uint8_t sequence;
|
||||
uint8_t status;
|
||||
|
||||
buffer = UIP_ICMP_PAYLOAD;
|
||||
buffer_length = uip_len - uip_l3_icmp_hdr_len;
|
||||
buffer = UIP_ICMP_PAYLOAD(buf);
|
||||
buffer_length = uip_len(buf) - uip_l3_icmp_hdr_len(buf);
|
||||
|
||||
instance_id = buffer[0];
|
||||
sequence = buffer[2];
|
||||
|
@ -924,14 +924,14 @@ dao_ack_input(void)
|
|||
|
||||
PRINTF("RPL: Received a DAO ACK with sequence number %d and status %d from ",
|
||||
sequence, status);
|
||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||
PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr);
|
||||
PRINTF("\n");
|
||||
#endif /* DEBUG */
|
||||
uip_len = 0;
|
||||
uip_len(buf) = 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
dao_ack_output(rpl_instance_t *instance, uip_ipaddr_t *dest, uint8_t sequence)
|
||||
dao_ack_output(struct net_buf *buf, rpl_instance_t *instance, uip_ipaddr_t *dest, uint8_t sequence)
|
||||
{
|
||||
unsigned char *buffer;
|
||||
|
||||
|
@ -939,14 +939,14 @@ dao_ack_output(rpl_instance_t *instance, uip_ipaddr_t *dest, uint8_t sequence)
|
|||
PRINT6ADDR(dest);
|
||||
PRINTF("\n");
|
||||
|
||||
buffer = UIP_ICMP_PAYLOAD;
|
||||
buffer = UIP_ICMP_PAYLOAD(buf);
|
||||
|
||||
buffer[0] = instance->instance_id;
|
||||
buffer[1] = 0;
|
||||
buffer[2] = sequence;
|
||||
buffer[3] = 0;
|
||||
|
||||
uip_icmp6_send(dest, ICMP6_RPL, RPL_CODE_DAO_ACK, 4);
|
||||
uip_icmp6_send(buf, dest, ICMP6_RPL, RPL_CODE_DAO_ACK, 4);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
|
|
@ -265,43 +265,43 @@ extern rpl_instance_t instance_table[];
|
|||
extern rpl_instance_t *default_instance;
|
||||
|
||||
/* ICMPv6 functions for RPL. */
|
||||
void dis_output(uip_ipaddr_t *addr);
|
||||
void dio_output(rpl_instance_t *, uip_ipaddr_t *uc_addr);
|
||||
void dao_output(rpl_parent_t *, uint8_t lifetime);
|
||||
void dao_output_target(rpl_parent_t *, uip_ipaddr_t *, uint8_t lifetime);
|
||||
void dao_ack_output(rpl_instance_t *, uip_ipaddr_t *, uint8_t);
|
||||
void dis_output(struct net_buf *buf, uip_ipaddr_t *addr);
|
||||
void dio_output(struct net_buf *buf, rpl_instance_t *, uip_ipaddr_t *uc_addr);
|
||||
void dao_output(struct net_buf *buf, rpl_parent_t *, uint8_t lifetime);
|
||||
void dao_output_target(struct net_buf *buf, rpl_parent_t *, uip_ipaddr_t *, uint8_t lifetime);
|
||||
void dao_ack_output(struct net_buf *buf, rpl_instance_t *, uip_ipaddr_t *, uint8_t);
|
||||
void rpl_icmp6_register_handlers(void);
|
||||
|
||||
/* RPL logic functions. */
|
||||
void rpl_join_dag(uip_ipaddr_t *from, rpl_dio_t *dio);
|
||||
void rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio);
|
||||
void rpl_local_repair(rpl_instance_t *instance);
|
||||
void rpl_process_dio(uip_ipaddr_t *, rpl_dio_t *);
|
||||
int rpl_process_parent_event(rpl_instance_t *, rpl_parent_t *);
|
||||
void rpl_join_instance(struct net_buf *buf, uip_ipaddr_t *from, rpl_dio_t *dio);
|
||||
void rpl_local_repair(struct net_buf *buf, rpl_instance_t *instance);
|
||||
void rpl_process_dio(struct net_buf *buf, uip_ipaddr_t *, rpl_dio_t *);
|
||||
int rpl_process_parent_event(struct net_buf *buf, rpl_instance_t *, rpl_parent_t *);
|
||||
|
||||
/* DAG object management. */
|
||||
rpl_dag_t *rpl_alloc_dag(uint8_t, uip_ipaddr_t *);
|
||||
rpl_dag_t *rpl_alloc_dag(struct net_buf *buf, uint8_t, uip_ipaddr_t *);
|
||||
rpl_instance_t *rpl_alloc_instance(uint8_t);
|
||||
void rpl_free_dag(rpl_dag_t *);
|
||||
void rpl_free_instance(rpl_instance_t *);
|
||||
void rpl_free_dag(struct net_buf *buf, rpl_dag_t *);
|
||||
void rpl_free_instance(struct net_buf *buf, rpl_instance_t *);
|
||||
|
||||
/* DAG parent management function. */
|
||||
rpl_parent_t *rpl_add_parent(rpl_dag_t *, rpl_dio_t *dio, uip_ipaddr_t *);
|
||||
rpl_parent_t *rpl_find_parent(rpl_dag_t *, uip_ipaddr_t *);
|
||||
rpl_parent_t *rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr);
|
||||
void rpl_nullify_parent(rpl_parent_t *);
|
||||
void rpl_remove_parent(rpl_parent_t *);
|
||||
void rpl_nullify_parent(struct net_buf *buf, rpl_parent_t *);
|
||||
void rpl_remove_parent(struct net_buf *buf, rpl_parent_t *);
|
||||
void rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent);
|
||||
rpl_parent_t *rpl_select_parent(rpl_dag_t *dag);
|
||||
rpl_dag_t *rpl_select_dag(rpl_instance_t *instance,rpl_parent_t *parent);
|
||||
void rpl_recalculate_ranks(void);
|
||||
rpl_dag_t *rpl_select_dag(struct net_buf *buf, rpl_instance_t *instance,rpl_parent_t *parent);
|
||||
void rpl_recalculate_ranks(struct net_buf *buf);
|
||||
|
||||
/* RPL routing table functions. */
|
||||
void rpl_remove_routes(rpl_dag_t *dag);
|
||||
void rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag);
|
||||
uip_ds6_route_t *rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix,
|
||||
int prefix_len, uip_ipaddr_t *next_hop);
|
||||
void rpl_purge_routes(void);
|
||||
void rpl_purge_routes(struct net_buf *buf);
|
||||
|
||||
/* Lock a parent in the neighbor cache. */
|
||||
void rpl_lock_parent(rpl_parent_t *p);
|
||||
|
@ -310,14 +310,16 @@ void rpl_lock_parent(rpl_parent_t *p);
|
|||
rpl_of_t *rpl_find_of(rpl_ocp_t);
|
||||
|
||||
/* Timer functions. */
|
||||
void rpl_schedule_dao(rpl_instance_t *);
|
||||
void rpl_schedule_dao_immediately(rpl_instance_t *);
|
||||
void rpl_schedule_dao(struct net_buf *buf, rpl_instance_t *);
|
||||
void rpl_schedule_dao_immediately(struct net_buf *buf, rpl_instance_t *);
|
||||
void rpl_cancel_dao(rpl_instance_t *instance);
|
||||
|
||||
void rpl_reset_dio_timer(rpl_instance_t *);
|
||||
void rpl_reset_periodic_timer(void);
|
||||
void rpl_reset_dio_timer(struct net_buf *buf, rpl_instance_t *);
|
||||
void rpl_reset_periodic_timer(struct net_buf *buf);
|
||||
|
||||
/* Route poisoning. */
|
||||
void rpl_poison_routes(rpl_dag_t *, rpl_parent_t *);
|
||||
|
||||
struct net_buf *rpl_get_netbuf(void);
|
||||
|
||||
#endif /* RPL_PRIVATE_H */
|
||||
|
|
|
@ -53,9 +53,9 @@
|
|||
/*---------------------------------------------------------------------------*/
|
||||
static struct ctimer periodic_timer;
|
||||
|
||||
static void handle_periodic_timer(void *ptr);
|
||||
static void new_dio_interval(rpl_instance_t *instance);
|
||||
static void handle_dio_timer(void *ptr);
|
||||
static void handle_periodic_timer(struct net_mbuf *mbuf, void *ptr);
|
||||
static void new_dio_interval(struct net_buf *buf, rpl_instance_t *instance);
|
||||
static void handle_dio_timer(struct net_mbuf *mbuf, void *ptr);
|
||||
|
||||
static uint16_t next_dis;
|
||||
|
||||
|
@ -64,24 +64,25 @@ static uint8_t dio_send_ok;
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
handle_periodic_timer(void *ptr)
|
||||
handle_periodic_timer(struct net_mbuf *mbuf, void *ptr)
|
||||
{
|
||||
rpl_purge_routes();
|
||||
rpl_recalculate_ranks();
|
||||
struct net_buf *buf = (struct net_buf *)mbuf;
|
||||
rpl_purge_routes(buf);
|
||||
rpl_recalculate_ranks(buf);
|
||||
|
||||
/* handle DIS */
|
||||
#if RPL_DIS_SEND
|
||||
next_dis++;
|
||||
if(rpl_get_any_dag() == NULL && next_dis >= RPL_DIS_INTERVAL) {
|
||||
next_dis = 0;
|
||||
dis_output(NULL);
|
||||
dis_output(buf, NULL);
|
||||
}
|
||||
#endif
|
||||
ctimer_reset(&periodic_timer);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
new_dio_interval(rpl_instance_t *instance)
|
||||
new_dio_interval(struct net_buf *buf, rpl_instance_t *instance)
|
||||
{
|
||||
uint32_t time;
|
||||
clock_time_t ticks;
|
||||
|
@ -122,12 +123,13 @@ new_dio_interval(rpl_instance_t *instance)
|
|||
|
||||
/* schedule the timer */
|
||||
PRINTF("RPL: Scheduling DIO timer %lu ticks in future (Interval)\n", ticks);
|
||||
ctimer_set(&instance->dio_timer, ticks, &handle_dio_timer, instance);
|
||||
ctimer_set((struct net_mbuf *)buf, &instance->dio_timer, ticks, &handle_dio_timer, instance);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
handle_dio_timer(void *ptr)
|
||||
handle_dio_timer(struct net_mbuf *mbuf, void *ptr)
|
||||
{
|
||||
struct net_buf *buf = (struct net_buf *)mbuf;
|
||||
rpl_instance_t *instance;
|
||||
|
||||
instance = (rpl_instance_t *)ptr;
|
||||
|
@ -138,7 +140,7 @@ handle_dio_timer(void *ptr)
|
|||
dio_send_ok = 1;
|
||||
} else {
|
||||
PRINTF("RPL: Postponing DIO transmission since link local address is not ok\n");
|
||||
ctimer_set(&instance->dio_timer, CLOCK_SECOND, &handle_dio_timer, instance);
|
||||
ctimer_set((struct net_mbuf *)buf, &instance->dio_timer, CLOCK_SECOND, &handle_dio_timer, instance);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -149,7 +151,7 @@ handle_dio_timer(void *ptr)
|
|||
#if RPL_CONF_STATS
|
||||
instance->dio_totsend++;
|
||||
#endif /* RPL_CONF_STATS */
|
||||
dio_output(instance, NULL);
|
||||
dio_output(buf, instance, NULL);
|
||||
} else {
|
||||
PRINTF("RPL: Supressing DIO transmission (%d >= %d)\n",
|
||||
instance->dio_counter, instance->dio_redundancy);
|
||||
|
@ -157,29 +159,29 @@ handle_dio_timer(void *ptr)
|
|||
instance->dio_send = 0;
|
||||
PRINTF("RPL: Scheduling DIO timer %lu ticks in future (sent)\n",
|
||||
instance->dio_next_delay);
|
||||
ctimer_set(&instance->dio_timer, instance->dio_next_delay, handle_dio_timer, instance);
|
||||
ctimer_set((struct net_mbuf *)buf, &instance->dio_timer, instance->dio_next_delay, handle_dio_timer, instance);
|
||||
} else {
|
||||
/* check if we need to double interval */
|
||||
if(instance->dio_intcurrent < instance->dio_intmin + instance->dio_intdoubl) {
|
||||
instance->dio_intcurrent++;
|
||||
PRINTF("RPL: DIO Timer interval doubled %d\n", instance->dio_intcurrent);
|
||||
}
|
||||
new_dio_interval(instance);
|
||||
new_dio_interval(buf, instance);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_reset_periodic_timer(void)
|
||||
rpl_reset_periodic_timer(struct net_buf *buf)
|
||||
{
|
||||
next_dis = RPL_DIS_INTERVAL / 2 +
|
||||
((uint32_t)RPL_DIS_INTERVAL * (uint32_t)random_rand()) / RANDOM_RAND_MAX -
|
||||
RPL_DIS_START_DELAY;
|
||||
ctimer_set(&periodic_timer, CLOCK_SECOND, handle_periodic_timer, NULL);
|
||||
ctimer_set((struct net_mbuf *)buf, &periodic_timer, CLOCK_SECOND, handle_periodic_timer, NULL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Resets the DIO timer in the instance to its minimal interval. */
|
||||
void
|
||||
rpl_reset_dio_timer(rpl_instance_t *instance)
|
||||
rpl_reset_dio_timer(struct net_buf *buf, rpl_instance_t *instance)
|
||||
{
|
||||
#if !RPL_LEAF_ONLY
|
||||
/* Do not reset if we are already on the minimum interval,
|
||||
|
@ -187,7 +189,7 @@ rpl_reset_dio_timer(rpl_instance_t *instance)
|
|||
if(instance->dio_intcurrent > instance->dio_intmin) {
|
||||
instance->dio_counter = 0;
|
||||
instance->dio_intcurrent = instance->dio_intmin;
|
||||
new_dio_interval(instance);
|
||||
new_dio_interval(buf, instance);
|
||||
}
|
||||
#if RPL_CONF_STATS
|
||||
rpl_stats.resets++;
|
||||
|
@ -195,9 +197,9 @@ rpl_reset_dio_timer(rpl_instance_t *instance)
|
|||
#endif /* RPL_LEAF_ONLY */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void handle_dao_timer(void *ptr);
|
||||
static void handle_dao_timer(struct net_mbuf *mbuf, void *ptr);
|
||||
static void
|
||||
set_dao_lifetime_timer(rpl_instance_t *instance)
|
||||
set_dao_lifetime_timer(struct net_buf *buf, rpl_instance_t *instance)
|
||||
{
|
||||
if(rpl_get_mode() == RPL_MODE_FEATHER) {
|
||||
return;
|
||||
|
@ -212,14 +214,15 @@ set_dao_lifetime_timer(rpl_instance_t *instance)
|
|||
CLOCK_SECOND / 2;
|
||||
PRINTF("RPL: Scheduling DAO lifetime timer %u ticks in the future\n",
|
||||
(unsigned)expiration_time);
|
||||
ctimer_set(&instance->dao_lifetime_timer, expiration_time,
|
||||
ctimer_set((struct net_mbuf *)buf, &instance->dao_lifetime_timer, expiration_time,
|
||||
handle_dao_timer, instance);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
handle_dao_timer(void *ptr)
|
||||
handle_dao_timer(struct net_mbuf *mbuf, void *ptr)
|
||||
{
|
||||
struct net_buf *buf = (struct net_buf *)mbuf;
|
||||
rpl_instance_t *instance;
|
||||
#if RPL_CONF_MULTICAST
|
||||
uip_mcast6_route_t *mcast_route;
|
||||
|
@ -230,7 +233,7 @@ handle_dao_timer(void *ptr)
|
|||
|
||||
if(!dio_send_ok && uip_ds6_get_link_local(ADDR_PREFERRED) == NULL) {
|
||||
PRINTF("RPL: Postpone DAO transmission\n");
|
||||
ctimer_set(&instance->dao_timer, CLOCK_SECOND, handle_dao_timer, instance);
|
||||
ctimer_set((struct net_mbuf *)buf, &instance->dao_timer, CLOCK_SECOND, handle_dao_timer, instance);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -238,7 +241,7 @@ handle_dao_timer(void *ptr)
|
|||
if(instance->current_dag->preferred_parent != NULL) {
|
||||
PRINTF("RPL: handle_dao_timer - sending DAO\n");
|
||||
/* Set the route lifetime to the default value. */
|
||||
dao_output(instance->current_dag->preferred_parent, instance->default_lifetime);
|
||||
dao_output(buf, instance->current_dag->preferred_parent, instance->default_lifetime);
|
||||
|
||||
#if RPL_CONF_MULTICAST
|
||||
/* Send DAOs for multicast prefixes only if the instance is in MOP 3 */
|
||||
|
@ -247,7 +250,7 @@ handle_dao_timer(void *ptr)
|
|||
for(i = 0; i < UIP_DS6_MADDR_NB; i++) {
|
||||
if(uip_ds6_if.maddr_list[i].isused
|
||||
&& uip_is_addr_mcast_global(&uip_ds6_if.maddr_list[i].ipaddr)) {
|
||||
dao_output_target(instance->current_dag->preferred_parent,
|
||||
dao_output_target(buf, instance->current_dag->preferred_parent,
|
||||
&uip_ds6_if.maddr_list[i].ipaddr, RPL_MCAST_LIFETIME);
|
||||
}
|
||||
}
|
||||
|
@ -257,7 +260,7 @@ handle_dao_timer(void *ptr)
|
|||
while(mcast_route != NULL) {
|
||||
/* Don't send if it's also our own address, done that already */
|
||||
if(uip_ds6_maddr_lookup(&mcast_route->group) == NULL) {
|
||||
dao_output_target(instance->current_dag->preferred_parent,
|
||||
dao_output_target(buf, instance->current_dag->preferred_parent,
|
||||
&mcast_route->group, RPL_MCAST_LIFETIME);
|
||||
}
|
||||
mcast_route = list_item_next(mcast_route);
|
||||
|
@ -271,12 +274,12 @@ handle_dao_timer(void *ptr)
|
|||
ctimer_stop(&instance->dao_timer);
|
||||
|
||||
if(etimer_expired(&instance->dao_lifetime_timer.etimer)) {
|
||||
set_dao_lifetime_timer(instance);
|
||||
set_dao_lifetime_timer(buf, instance);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
schedule_dao(rpl_instance_t *instance, clock_time_t latency)
|
||||
schedule_dao(struct net_buf *buf, rpl_instance_t *instance, clock_time_t latency)
|
||||
{
|
||||
clock_time_t expiration_time;
|
||||
|
||||
|
@ -297,23 +300,23 @@ schedule_dao(rpl_instance_t *instance, clock_time_t latency)
|
|||
}
|
||||
PRINTF("RPL: Scheduling DAO timer %u ticks in the future\n",
|
||||
(unsigned)expiration_time);
|
||||
ctimer_set(&instance->dao_timer, expiration_time,
|
||||
ctimer_set((struct net_mbuf *)buf, &instance->dao_timer, expiration_time,
|
||||
handle_dao_timer, instance);
|
||||
|
||||
set_dao_lifetime_timer(instance);
|
||||
set_dao_lifetime_timer(buf, instance);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_schedule_dao(rpl_instance_t *instance)
|
||||
rpl_schedule_dao(struct net_buf *buf, rpl_instance_t *instance)
|
||||
{
|
||||
schedule_dao(instance, RPL_DAO_LATENCY);
|
||||
schedule_dao(buf, instance, RPL_DAO_LATENCY);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_schedule_dao_immediately(rpl_instance_t *instance)
|
||||
rpl_schedule_dao_immediately(struct net_buf *buf, rpl_instance_t *instance)
|
||||
{
|
||||
schedule_dao(instance, 0);
|
||||
schedule_dao(buf, instance, 0);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
|
|
@ -59,6 +59,12 @@
|
|||
rpl_stats_t rpl_stats;
|
||||
#endif
|
||||
|
||||
static struct net_buf netbuf;
|
||||
struct net_buf *rpl_get_netbuf(void)
|
||||
{
|
||||
return &netbuf;
|
||||
}
|
||||
|
||||
static enum rpl_mode mode = RPL_MODE_MESH;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
enum rpl_mode
|
||||
|
@ -68,7 +74,7 @@ rpl_get_mode(void)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
enum rpl_mode
|
||||
rpl_set_mode(enum rpl_mode m)
|
||||
rpl_set_mode(struct net_buf *buf, enum rpl_mode m)
|
||||
{
|
||||
enum rpl_mode oldmode = mode;
|
||||
|
||||
|
@ -84,7 +90,7 @@ rpl_set_mode(enum rpl_mode m)
|
|||
mode = m;
|
||||
|
||||
if(default_instance != NULL) {
|
||||
rpl_schedule_dao_immediately(default_instance);
|
||||
rpl_schedule_dao_immediately(buf, default_instance);
|
||||
}
|
||||
} else if(m == RPL_MODE_FEATHER) {
|
||||
|
||||
|
@ -102,7 +108,7 @@ rpl_set_mode(enum rpl_mode m)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_purge_routes(void)
|
||||
rpl_purge_routes(struct net_buf *buf)
|
||||
{
|
||||
uip_ds6_route_t *r;
|
||||
uip_ipaddr_t prefix;
|
||||
|
@ -142,7 +148,7 @@ rpl_purge_routes(void)
|
|||
/* Propagate this information with a No-Path DAO to preferred parent if we are not a RPL Root */
|
||||
if(dag->rank != ROOT_RANK(default_instance)) {
|
||||
PRINTF(" -> generate No-Path DAO\n");
|
||||
dao_output_target(dag->preferred_parent, &prefix, RPL_ZERO_LIFETIME);
|
||||
dao_output_target(buf, dag->preferred_parent, &prefix, RPL_ZERO_LIFETIME);
|
||||
/* Don't schedule more than 1 No-Path DAO, let next iteration handle that */
|
||||
return;
|
||||
}
|
||||
|
@ -300,7 +306,7 @@ rpl_init(void)
|
|||
default_instance = NULL;
|
||||
|
||||
rpl_dag_init();
|
||||
rpl_reset_periodic_timer();
|
||||
rpl_reset_periodic_timer(rpl_get_netbuf());
|
||||
rpl_icmp6_register_handlers();
|
||||
|
||||
/* add rpl multicast address */
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#ifndef RPL_H
|
||||
#define RPL_H
|
||||
|
||||
#include <net/net_buf.h>
|
||||
|
||||
#include "rpl-conf.h"
|
||||
|
||||
#include "lib/list.h"
|
||||
|
@ -233,18 +235,18 @@ struct rpl_instance {
|
|||
/* Public RPL functions. */
|
||||
void rpl_init(void);
|
||||
void uip_rpl_input(void);
|
||||
rpl_dag_t *rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id);
|
||||
rpl_dag_t *rpl_set_root(struct net_buf *buf, uint8_t instance_id, uip_ipaddr_t *dag_id);
|
||||
int rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len);
|
||||
int rpl_repair_root(uint8_t instance_id);
|
||||
int rpl_repair_root(struct net_buf *buf, uint8_t instance_id);
|
||||
int rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from);
|
||||
rpl_dag_t *rpl_get_any_dag(void);
|
||||
rpl_instance_t *rpl_get_instance(uint8_t instance_id);
|
||||
int rpl_update_header_empty(void);
|
||||
int rpl_update_header_final(uip_ipaddr_t *addr);
|
||||
int rpl_verify_header(int);
|
||||
void rpl_insert_header(void);
|
||||
void rpl_remove_header(void);
|
||||
uint8_t rpl_invert_header(void);
|
||||
int rpl_update_header_empty(struct net_buf *buf);
|
||||
int rpl_update_header_final(struct net_buf *buf, uip_ipaddr_t *addr);
|
||||
int rpl_verify_header(struct net_buf *buf, int);
|
||||
void rpl_insert_header(struct net_buf *buf);
|
||||
void rpl_remove_header(struct net_buf *buf);
|
||||
uint8_t rpl_invert_header(struct net_buf *buf);
|
||||
uip_ipaddr_t *rpl_get_parent_ipaddr(rpl_parent_t *nbr);
|
||||
rpl_parent_t *rpl_get_parent(uip_lladdr_t *addr);
|
||||
rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
|
||||
|
@ -274,7 +276,7 @@ enum rpl_mode {
|
|||
* \param mode The new RPL mode
|
||||
* \retval The previous RPL mode
|
||||
*/
|
||||
enum rpl_mode rpl_set_mode(enum rpl_mode mode);
|
||||
enum rpl_mode rpl_set_mode(struct net_buf *buf, enum rpl_mode mode);
|
||||
|
||||
/**
|
||||
* Get the RPL mode
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue