Merge pull request #46 from adamdunkels/ipv6-rpl-updates

Thingsquare IPv6/RPL updates
This commit is contained in:
Nicolas Tsiftes 2012-11-27 16:13:03 -08:00
commit 89603f7b78
31 changed files with 975 additions and 552 deletions

View file

@ -69,7 +69,7 @@ ifdef UIP_CONF_IPV6
UIP = uip6.c tcpip.c psock.c uip-udp-packet.c uip-split.c \
resolv.c tcpdump.c uiplib.c simple-udp.c
NET += $(UIP) uip-icmp6.c uip-nd6.c uip-packetqueue.c \
sicslowpan.c neighbor-attr.c neighbor-info.c uip-ds6.c
sicslowpan.c neighbor-attr.c neighbor-info.c uip-ds6.c uip-ds6-route.c
ifneq ($(UIP_CONF_RPL),0)
CFLAGS += -DUIP_CONF_IPV6_RPL=1
include $(CONTIKI)/core/net/rpl/Makefile.rpl

View file

@ -307,23 +307,25 @@ PT_THREAD(neighbors(struct httpd_state *s, char *ptr))
static unsigned short
make_routes(void *p)
{
static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR = "(%u (via ";
static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR = ") %us<br>";
static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")<br>";
uint8_t i,j=0;
uint16_t numprinted;
static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR = "(%u (via ";
static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR = ") %lus<br>";
static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")<br>";
uint8_t i,j=0;
uint16_t numprinted;
uip_ds6_route_t *r;
numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh);
for (i=0; i<UIP_DS6_ROUTE_NB;i++) {
if (uip_ds6_routing_table[i].isused) {
j++;
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].ipaddr, uip_appdata + numprinted);
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, uip_ds6_routing_table[i].length);
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].nexthop, uip_appdata + numprinted);
if(uip_ds6_routing_table[i].state.lifetime < 3600*24) {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, uip_ds6_routing_table[i].state.lifetime);
} else {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes3);
}
for(r = uip_ds6_route_list_head();
r != NULL;
r = list_item_next(r)) {
j++;
numprinted += httpd_cgi_sprint_ip6(r->ipaddr, uip_appdata + numprinted);
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, r->length);
numprinted += httpd_cgi_sprint_ip6(r->nexthop, uip_appdata + numprinted);
if(r->state.lifetime < 3600) {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, r->state.lifetime);
} else {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes3);
}
}
if (j==0) numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrn);

View file

@ -109,7 +109,7 @@ packetbuf_compact(void)
if(packetbuf_is_reference()) {
memcpy(&packetbuf[PACKETBUF_HDR_SIZE], packetbuf_reference_ptr(),
packetbuf_datalen());
} else if (bufptr > 0) {
} else if(bufptr > 0) {
len = packetbuf_datalen() + PACKETBUF_HDR_SIZE;
for(i = PACKETBUF_HDR_SIZE; i < len; i++) {
packetbuf[i] = packetbuf[bufptr + i];

View file

@ -57,18 +57,18 @@
#include "net/neighbor-info.h"
/************************************************************************/
/*---------------------------------------------------------------------------*/
extern rpl_of_t RPL_OF;
static rpl_of_t * const objective_functions[] = {&RPL_OF};
/************************************************************************/
/*---------------------------------------------------------------------------*/
#ifndef RPL_CONF_MAX_PARENTS_PER_DAG
#define RPL_MAX_PARENTS_PER_DAG 8
#else
#define RPL_MAX_PARENTS_PER_DAG RPL_CONF_MAX_PARENTS_PER_DAG
#endif /* !RPL_CONF_MAX_PARENTS_PER_DAG */
/************************************************************************/
/*---------------------------------------------------------------------------*/
/* RPL definitions. */
#ifndef RPL_CONF_GROUNDED
@ -77,17 +77,17 @@ static rpl_of_t * const objective_functions[] = {&RPL_OF};
#define RPL_GROUNDED RPL_CONF_GROUNDED
#endif /* !RPL_CONF_GROUNDED */
/************************************************************************/
/*---------------------------------------------------------------------------*/
/* Allocate parents from the same static MEMB chunk to reduce memory waste. */
MEMB(parent_memb, struct rpl_parent,
RPL_MAX_PARENTS_PER_DAG * RPL_MAX_INSTANCES * RPL_MAX_DAG_PER_INSTANCE);
/************************************************************************/
/*---------------------------------------------------------------------------*/
/* Allocate instance table. */
rpl_instance_t instance_table[RPL_MAX_INSTANCES];
rpl_instance_t *default_instance;
/************************************************************************/
/*---------------------------------------------------------------------------*/
/* Greater-than function for the lollipop counter. */
/************************************************************************/
/*---------------------------------------------------------------------------*/
static int
lollipop_greater_than(int a, int b)
{
@ -101,7 +101,7 @@ lollipop_greater_than(int a, int b)
(a < b && (b - a) > (RPL_LOLLIPOP_CIRCULAR_REGION + 1-
RPL_LOLLIPOP_SEQUENCE_WINDOWS));
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
/* 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)
@ -118,7 +118,7 @@ remove_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
}
}
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
static void
nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
{
@ -134,7 +134,7 @@ nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
}
}
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
static void
remove_worst_parent(rpl_dag_t *dag, rpl_rank_t min_worst_rank)
{
@ -155,7 +155,7 @@ remove_worst_parent(rpl_dag_t *dag, rpl_rank_t min_worst_rank)
rpl_remove_parent(dag, worst);
}
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
static int
should_send_dao(rpl_instance_t *instance, rpl_dio_t *dio, rpl_parent_t *p)
{
@ -167,7 +167,7 @@ should_send_dao(rpl_instance_t *instance, rpl_dio_t *dio, rpl_parent_t *p)
return p == instance->current_dag->preferred_parent &&
(lollipop_greater_than(dio->dtsn, p->dtsn));
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
static int
acceptable_rank(rpl_dag_t *dag, rpl_rank_t rank)
{
@ -175,7 +175,7 @@ acceptable_rank(rpl_dag_t *dag, rpl_rank_t rank)
((dag->instance->max_rankinc == 0) ||
DAG_RANK(rank, dag->instance) <= DAG_RANK(dag->min_rank + dag->instance->max_rankinc, dag->instance));
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
static rpl_dag_t *
get_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
{
@ -197,7 +197,7 @@ get_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
return NULL;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
rpl_dag_t *
rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
{
@ -270,7 +270,7 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
return dag;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
int
rpl_repair_root(uint8_t instance_id)
{
@ -287,7 +287,7 @@ rpl_repair_root(uint8_t instance_id)
rpl_reset_dio_timer(instance);
return 1;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
static void
set_ip_from_prefix(uip_ipaddr_t *ipaddr, rpl_prefix_t *prefix)
{
@ -295,7 +295,7 @@ set_ip_from_prefix(uip_ipaddr_t *ipaddr, rpl_prefix_t *prefix)
memcpy(ipaddr, &prefix->prefix, (prefix->length + 7) / 8);
uip_ds6_set_addr_iid(ipaddr, &uip_lladdr);
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
static void
check_prefix(rpl_prefix_t *last_prefix, rpl_prefix_t *new_prefix)
{
@ -331,7 +331,7 @@ check_prefix(rpl_prefix_t *last_prefix, rpl_prefix_t *new_prefix)
}
}
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
int
rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len)
{
@ -349,17 +349,15 @@ rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len)
check_prefix(NULL, &dag->prefix_info);
return 1;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
int
rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from)
{
if(instance->def_route != NULL) {
if(instance->def_route->isused) {
PRINTF("RPL: Removing default route through ");
PRINT6ADDR(&instance->def_route->ipaddr);
PRINTF("\n");
uip_ds6_defrt_rm(instance->def_route);
}
PRINTF("RPL: Removing default route through ");
PRINT6ADDR(&instance->def_route->ipaddr);
PRINTF("\n");
uip_ds6_defrt_rm(instance->def_route);
instance->def_route = NULL;
}
@ -373,16 +371,24 @@ rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from)
if(instance->def_route == NULL) {
return 0;
}
} else {
PRINTF("RPL: Removing default route\n");
if(instance->def_route != NULL) {
uip_ds6_defrt_rm(instance->def_route);
} else {
PRINTF("RPL: Not actually removing default route, since instance had no default route\n");
}
}
return 1;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
rpl_instance_t *
rpl_alloc_instance(uint8_t instance_id)
{
rpl_instance_t *instance, *end;
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES;
instance < end; ++instance) {
if(instance->used == 0) {
memset(instance, 0, sizeof(*instance));
instance->instance_id = instance_id;
@ -393,7 +399,7 @@ rpl_alloc_instance(uint8_t instance_id)
}
return NULL;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
rpl_dag_t *
rpl_alloc_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
{
@ -425,13 +431,13 @@ rpl_alloc_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
rpl_free_instance(instance);
return NULL;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_set_default_instance(rpl_instance_t *instance)
{
default_instance = instance;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_free_instance(rpl_instance_t *instance)
{
@ -458,7 +464,7 @@ rpl_free_instance(rpl_instance_t *instance)
instance->used = 0;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_free_dag(rpl_dag_t *dag)
{
@ -480,7 +486,7 @@ rpl_free_dag(rpl_dag_t *dag)
}
dag->used = 0;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
rpl_parent_t *
rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
{
@ -504,7 +510,7 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
list_add(dag->parents, p);
return p;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
rpl_parent_t *
rpl_find_parent(rpl_dag_t *dag, uip_ipaddr_t *addr)
{
@ -518,7 +524,7 @@ rpl_find_parent(rpl_dag_t *dag, uip_ipaddr_t *addr)
return NULL;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
static rpl_dag_t *
find_parent_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
{
@ -536,7 +542,7 @@ find_parent_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
}
return NULL;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
rpl_parent_t *
rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
{
@ -554,7 +560,7 @@ rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
}
return NULL;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
rpl_dag_t *
rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p)
{
@ -645,7 +651,7 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p)
}
return best_dag;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
rpl_parent_t *
rpl_select_parent(rpl_dag_t *dag)
{
@ -668,7 +674,7 @@ rpl_select_parent(rpl_dag_t *dag)
return best;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_remove_parent(rpl_dag_t *dag, rpl_parent_t *parent)
{
@ -681,7 +687,7 @@ rpl_remove_parent(rpl_dag_t *dag, rpl_parent_t *parent)
list_remove(dag->parents, parent);
memb_free(&parent_memb, parent);
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_nullify_parent(rpl_dag_t *dag, rpl_parent_t *parent)
{
@ -690,12 +696,10 @@ rpl_nullify_parent(rpl_dag_t *dag, rpl_parent_t *parent)
dag->rank = INFINITE_RANK;
if(dag->joined) {
if(dag->instance->def_route != NULL) {
if(dag->instance->def_route->isused) {
PRINTF("RPL: Removing default route ");
PRINT6ADDR(&parent->addr);
PRINTF("\n");
uip_ds6_defrt_rm(dag->instance->def_route);
}
PRINTF("RPL: Removing default route ");
PRINT6ADDR(&parent->addr);
PRINTF("\n");
uip_ds6_defrt_rm(dag->instance->def_route);
dag->instance->def_route = NULL;
}
dao_output(parent, RPL_ZERO_LIFETIME);
@ -706,7 +710,7 @@ rpl_nullify_parent(rpl_dag_t *dag, rpl_parent_t *parent)
PRINT6ADDR(&parent->addr);
PRINTF("\n");
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent)
{
@ -714,12 +718,11 @@ rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent)
dag_src->preferred_parent = NULL;
dag_src->rank = INFINITE_RANK;
if(dag_src->joined && dag_src->instance->def_route != NULL) {
if(dag_src->instance->def_route->isused) {
PRINTF("RPL: Removing default route ");
PRINT6ADDR(&parent->addr);
PRINTF("\n");
uip_ds6_defrt_rm(dag_src->instance->def_route);
}
PRINTF("RPL: Removing default route ");
PRINT6ADDR(&parent->addr);
PRINTF("\n");
PRINTF("rpl_move_parent\n");
uip_ds6_defrt_rm(dag_src->instance->def_route);
dag_src->instance->def_route = NULL;
}
} else if(dag_src->joined) {
@ -735,7 +738,7 @@ rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent)
parent->dag = dag_dst;
list_add(dag_dst->parents, parent);
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
rpl_dag_t *
rpl_get_any_dag(void)
{
@ -748,7 +751,7 @@ rpl_get_any_dag(void)
}
return NULL;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
rpl_instance_t *
rpl_get_instance(uint8_t instance_id)
{
@ -761,7 +764,7 @@ rpl_get_instance(uint8_t instance_id)
}
return NULL;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
rpl_of_t *
rpl_find_of(rpl_ocp_t ocp)
{
@ -777,7 +780,7 @@ rpl_find_of(rpl_ocp_t ocp)
return NULL;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
{
@ -874,7 +877,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
}
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
{
@ -954,7 +957,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
p->dtsn = dio->dtsn;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
static void
global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
{
@ -981,7 +984,7 @@ global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
RPL_STAT(rpl_stats.global_repairs++);
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_local_repair(rpl_instance_t *instance)
{
@ -999,7 +1002,7 @@ rpl_local_repair(rpl_instance_t *instance)
RPL_STAT(rpl_stats.local_repairs++);
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_recalculate_ranks(void)
{
@ -1035,7 +1038,7 @@ rpl_recalculate_ranks(void)
}
}
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
int
rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
{
@ -1082,7 +1085,7 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
return return_value;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
{
@ -1095,6 +1098,32 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
return;
}
dag = get_dag(dio->instance_id, &dio->dag_id);
instance = rpl_get_instance(dio->instance_id);
if(dag != NULL && instance != NULL) {
if(lollipop_greater_than(dio->version, dag->version)) {
if(dag->rank == ROOT_RANK(instance)) {
PRINTF("RPL: Root received inconsistent DIO version number\n");
dag->version = dio->version;
RPL_LOLLIPOP_INCREMENT(dag->version);
rpl_reset_dio_timer(instance);
} else {
global_repair(from, dag, dio);
}
return;
}
if(lollipop_greater_than(dag->version, dio->version)) {
/* 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);
return;
}
}
}
if(dio->rank == INFINITE_RANK) {
PRINTF("RPL: Ignoring DIO from node with infinite rank: ");
PRINT6ADDR(from);
@ -1102,40 +1131,18 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
return;
}
instance = rpl_get_instance(dio->instance_id);
if(instance == NULL) {
PRINTF("RPL: New instance detected: Joining...\n");
rpl_join_instance(from, dio);
return;
}
dag = get_dag(dio->instance_id, &dio->dag_id);
if(dag == NULL) {
PRINTF("RPL: Adding new DAG to known instance.\n");
rpl_add_dag(from, dio);
return;
}
if(lollipop_greater_than(dio->version, dag->version)) {
if(dag->rank == ROOT_RANK(instance)) {
PRINTF("RPL: Root received inconsistent DIO version number\n");
dag->version = dio->version;
RPL_LOLLIPOP_INCREMENT(dag->version);
rpl_reset_dio_timer(instance);
} else {
global_repair(from, dag, dio);
}
return;
}
if(lollipop_greater_than(dag->version, dio->version)) {
/* 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);
return;
}
}
if(dio->rank < ROOT_RANK(instance)) {
PRINTF("RPL: Ignoring DIO with too low rank: %u\n",
@ -1219,4 +1226,4 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
}
p->dtsn = dio->dtsn;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/

View file

@ -53,7 +53,7 @@
#include <limits.h>
#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])
@ -61,7 +61,7 @@
#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])
/************************************************************************/
/*---------------------------------------------------------------------------*/
int
rpl_verify_header(int uip_ext_opt_offset)
{
@ -97,9 +97,14 @@ rpl_verify_header(int uip_ext_opt_offset)
down = 1;
}
PRINTF("RPL: Packet going %s\n", down == 1 ? "down" : "up");
sender_closer = UIP_EXT_HDR_OPT_RPL_BUF->senderrank < instance->current_dag->rank;
PRINTF("RPL: Packet going %s, sender closer %d (%d < %d)\n", down == 1 ? "down" : "up",
sender_closer,
UIP_EXT_HDR_OPT_RPL_BUF->senderrank,
instance->current_dag->rank
);
if((down && !sender_closer) || (!down && sender_closer)) {
PRINTF("RPL: Loop detected - senderrank: %d my-rank: %d sender_closer: %d\n",
UIP_EXT_HDR_OPT_RPL_BUF->senderrank, instance->current_dag->rank,
@ -118,7 +123,7 @@ rpl_verify_header(int uip_ext_opt_offset)
return 0;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
static void
set_rpl_opt(unsigned uip_ext_opt_offset)
{
@ -141,7 +146,7 @@ set_rpl_opt(unsigned uip_ext_opt_offset)
UIP_IP_BUF->len[0]++;
}
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_update_header_empty(void)
{
@ -183,7 +188,22 @@ rpl_update_header_empty(void)
switch(UIP_EXT_HDR_OPT_BUF->type) {
case UIP_EXT_HDR_OPT_RPL:
PRINTF("RPL: Updating RPL option\n");
UIP_EXT_HDR_OPT_RPL_BUF->senderrank=instance->current_dag->rank;
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = instance->current_dag->rank;
/* 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) {
/* 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;
} 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_len = last_uip_ext_len;
return;
default:
@ -192,7 +212,7 @@ rpl_update_header_empty(void)
return;
}
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
int
rpl_update_header_final(uip_ipaddr_t *addr)
{
@ -230,7 +250,7 @@ rpl_update_header_final(uip_ipaddr_t *addr)
}
return 0;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_remove_header(void)
{
@ -257,7 +277,7 @@ rpl_remove_header(void)
PRINTF("RPL: No hop-by-hop Option found\n");
}
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
uint8_t
rpl_invert_header(void)
{
@ -292,4 +312,4 @@ rpl_invert_header(void)
return 0;
}
}
/************************************************************************/
/*---------------------------------------------------------------------------*/

View file

@ -103,7 +103,11 @@
/* Default values for RPL constants and variables. */
/* The default value for the DAO timer. */
#ifdef RPL_CONF_DAO_LATENCY
#define RPL_DAO_LATENCY RPL_CONF_DAO_LATENCY
#else /* RPL_CONF_DAO_LATENCY */
#define RPL_DAO_LATENCY (CLOCK_SECOND * 4)
#endif /* RPL_DAO_LATENCY */
/* Special value indicating immediate removal. */
#define RPL_ZERO_LIFETIME 0

View file

@ -47,7 +47,7 @@
#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"
/************************************************************************/
/*---------------------------------------------------------------------------*/
static struct ctimer periodic_timer;
static void handle_periodic_timer(void *ptr);
@ -59,7 +59,7 @@ static uint16_t next_dis;
/* dio_send_ok is true if the node is ready to send DIOs */
static uint8_t dio_send_ok;
/************************************************************************/
/*---------------------------------------------------------------------------*/
static void
handle_periodic_timer(void *ptr)
{
@ -76,30 +76,29 @@ handle_periodic_timer(void *ptr)
#endif
ctimer_reset(&periodic_timer);
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
static void
new_dio_interval(rpl_instance_t *instance)
{
uint32_t time;
clock_time_t ticks;
/* TODO: too small timer intervals for many cases */
time = 1UL << instance->dio_intcurrent;
/* Convert from milliseconds to CLOCK_TICKS. */
time = (time * CLOCK_SECOND) / 1000;
instance->dio_next_delay = time;
ticks = (time * CLOCK_SECOND) / 1000;
instance->dio_next_delay = ticks;
/* random number between I/2 and I */
time = time >> 1;
time += (time * random_rand()) / RANDOM_RAND_MAX;
ticks = ticks / 2 + (ticks / 2 * (uint32_t)random_rand()) / RANDOM_RAND_MAX;
/*
* The intervals must be equally long among the nodes for Trickle to
* operate efficiently. Therefore we need to calculate the delay between
* the randomized time and the start time of the next interval.
*/
instance->dio_next_delay -= time;
instance->dio_next_delay -= ticks;
instance->dio_send = 1;
#if RPL_CONF_STATS
@ -119,10 +118,10 @@ new_dio_interval(rpl_instance_t *instance)
instance->dio_counter = 0;
/* schedule the timer */
PRINTF("RPL: Scheduling DIO timer %lu ticks in future (Interval)\n", time);
ctimer_set(&instance->dio_timer, time, &handle_dio_timer, instance);
PRINTF("RPL: Scheduling DIO timer %lu ticks in future (Interval)\n", ticks);
ctimer_set(&instance->dio_timer, ticks, &handle_dio_timer, instance);
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
static void
handle_dio_timer(void *ptr)
{
@ -165,14 +164,16 @@ handle_dio_timer(void *ptr)
new_dio_interval(instance);
}
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_reset_periodic_timer(void)
{
next_dis = RPL_DIS_INTERVAL - RPL_DIS_START_DELAY;
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);
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
/* Resets the DIO timer in the instance to its minimal interval. */
void
rpl_reset_dio_timer(rpl_instance_t *instance)
@ -190,7 +191,7 @@ rpl_reset_dio_timer(rpl_instance_t *instance)
#endif /* RPL_CONF_STATS */
#endif /* RPL_LEAF_ONLY */
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
static void
handle_dao_timer(void *ptr)
{
@ -214,7 +215,7 @@ handle_dao_timer(void *ptr)
}
ctimer_stop(&instance->dao_timer);
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_schedule_dao(rpl_instance_t *instance)
{
@ -233,4 +234,4 @@ rpl_schedule_dao(rpl_instance_t *instance)
handle_dao_timer, instance);
}
}
/************************************************************************/
/*---------------------------------------------------------------------------*/

View file

@ -56,40 +56,61 @@
rpl_stats_t rpl_stats;
#endif
/************************************************************************/
extern uip_ds6_route_t uip_ds6_routing_table[UIP_DS6_ROUTE_NB];
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_purge_routes(void)
{
int i;
uip_ds6_route_t *r;
for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
if(uip_ds6_routing_table[i].isused) {
if(uip_ds6_routing_table[i].state.lifetime <= 1) {
uip_ds6_route_rm(&uip_ds6_routing_table[i]);
} else {
uip_ds6_routing_table[i].state.lifetime--;
}
r = uip_ds6_route_list_head();
while(r != NULL) {
if(r->state.lifetime <= 1) {
uip_ds6_route_rm(r);
r = uip_ds6_route_list_head();
} else {
r->state.lifetime--;
r = list_item_next(r);
}
}
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_remove_routes(rpl_dag_t *dag)
{
int i;
uip_ds6_route_t *r;
for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
if(uip_ds6_routing_table[i].state.dag == dag) {
uip_ds6_route_rm(&uip_ds6_routing_table[i]);
r = uip_ds6_route_list_head();
while(r != NULL) {
if(r->state.dag == dag) {
uip_ds6_route_rm(r);
r = uip_ds6_route_list_head();
} else {
r = list_item_next(r);
}
}
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag)
{
uip_ds6_route_t *r;
r = uip_ds6_route_list_head();
while(r != NULL) {
if(uip_ipaddr_cmp(&r->nexthop, nexthop) &&
r->state.dag == dag) {
uip_ds6_route_rm(r);
r = uip_ds6_route_list_head();
} else {
r = list_item_next(r);
}
}
ANNOTATE("#L %u 0\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
#if 0
uip_ds6_route_t *locroute;
for(locroute = uip_ds6_routing_table;
@ -102,8 +123,9 @@ rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag)
}
}
ANNOTATE("#L %u 0\n",nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
#endif /* 0 */
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len,
uip_ipaddr_t *next_hop)
@ -136,7 +158,7 @@ rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len,
return rep;
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
static void
rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
{
@ -179,7 +201,7 @@ rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
uip_ds6_route_rm_by_nexthop(&ipaddr);
}
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr)
{
@ -203,7 +225,7 @@ rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr)
}
}
}
/************************************************************************/
/*---------------------------------------------------------------------------*/
void
rpl_init(void)
{
@ -222,4 +244,4 @@ rpl_init(void)
memset(&rpl_stats, 0, sizeof(rpl_stats));
#endif
}
/************************************************************************/
/*---------------------------------------------------------------------------*/

View file

@ -221,7 +221,7 @@ struct rpl_instance {
uint16_t dio_totsend;
uint16_t dio_totrecv;
#endif /* RPL_CONF_STATS */
uint32_t dio_next_delay; /* delay for completion of dio interval */
clock_time_t dio_next_delay; /* delay for completion of dio interval */
struct ctimer dio_timer;
struct ctimer dao_timer;
};

View file

@ -1648,7 +1648,7 @@ input(void)
if((frag_size > 0) && (frag_size <= UIP_BUFSIZE)) {
sicslowpan_len = frag_size;
reass_tag = frag_tag;
timer_set(&reass_timer, SICSLOWPAN_REASS_MAXAGE*CLOCK_SECOND);
timer_set(&reass_timer, SICSLOWPAN_REASS_MAXAGE * CLOCK_SECOND / 16);
PRINTFI("sicslowpan input: INIT FRAGMENTATION (len %d, tag %d)\n",
sicslowpan_len, reass_tag);
rimeaddr_copy(&frag_sender, packetbuf_addr(PACKETBUF_ADDR_SENDER));

View file

@ -113,6 +113,34 @@ simple_udp_sendto(struct simple_udp_connection *c,
return 0;
}
/*---------------------------------------------------------------------------*/
/**
* \brief Send a UDP packet to a specified IP address and UDP port
* \param c A pointer to a struct simple_udp_connection
* \param data A pointer to the data to be sent
* \param datalen The length of the data
* \param to The IP address of the receiver
* \param port The UDP port of the receiver, in host byte order
*
* This function sends a UDP packet to a specified IP
* address and UDP port. The packet will be sent with the
* UDP ports that were specified when the connection wa
* registered with simple_udp_register().
*
* \sa simple_udp_sendto()
*/
int
simple_udp_sendto_port(struct simple_udp_connection *c,
const void *data, uint16_t datalen,
const uip_ipaddr_t *to,
uint16_t port)
{
if(c->udp_conn != NULL) {
uip_udp_packet_sendto(c->udp_conn, data, datalen,
to, UIP_HTONS(port));
}
return 0;
}
/*---------------------------------------------------------------------------*/
/**
* \brief Register a UDP connection
* \param c A pointer to a struct simple_udp_connection

View file

@ -86,6 +86,10 @@ int simple_udp_sendto(struct simple_udp_connection *c,
const void *data, uint16_t datalen,
const uip_ipaddr_t *to);
int simple_udp_sendto_port(struct simple_udp_connection *c,
const void *data, uint16_t datalen,
const uip_ipaddr_t *to, uint16_t to_port);
void simple_udp_init(void);
#endif /* SIMPLE_UDP_H */

View file

@ -373,7 +373,7 @@ eventhandler(process_event_t ev, process_data_t data)
register struct listenport *l;
#endif /*UIP_TCP*/
struct process *p;
switch(ev) {
case PROCESS_EVENT_EXITED:
/* This is the event we get if a process has exited. We go through
@ -471,13 +471,13 @@ eventhandler(process_event_t ev, process_data_t data)
}*/
#if !UIP_CONF_ROUTER
if(data == &uip_ds6_timer_rs &&
etimer_expired(&uip_ds6_timer_rs)){
etimer_expired(&uip_ds6_timer_rs)) {
uip_ds6_send_rs();
tcpip_ipv6_output();
}
#endif /* !UIP_CONF_ROUTER */
if(data == &uip_ds6_timer_periodic &&
etimer_expired(&uip_ds6_timer_periodic)){
etimer_expired(&uip_ds6_timer_periodic)) {
uip_ds6_periodic();
tcpip_ipv6_output();
}
@ -586,6 +586,11 @@ tcpip_ipv6_output(void)
} else {
nexthop = &locrt->nexthop;
}
#if TCPIP_CONF_ANNOTATE_TRANSMISSIONS
if(nexthop != NULL) {
printf("#L %u 1; red\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
}
#endif /* TCPIP_CONF_ANNOTATE_TRANSMISSIONS */
}
/* End of next hop determination */
#if UIP_CONF_IPV6_RPL

371
core/net/uip-ds6-route.c Normal file
View file

@ -0,0 +1,371 @@
/*
* Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "net/uip-ds6.h"
#include "net/uip.h"
#include "lib/list.h"
#include "lib/memb.h"
#include <string.h>
LIST(routelist);
MEMB(routememb, uip_ds6_route_t, UIP_DS6_ROUTE_NB);
LIST(defaultrouterlist);
MEMB(defaultroutermemb, uip_ds6_defrt_t, UIP_DS6_DEFRT_NB);
LIST(notificationlist);
#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"
/*---------------------------------------------------------------------------*/
static void
call_route_callback(int event, uip_ipaddr_t *route,
uip_ipaddr_t *nexthop)
{
int num;
struct uip_ds6_notification *n;
for(n = list_head(notificationlist);
n != NULL;
n = list_item_next(n)) {
if(event == UIP_DS6_NOTIFICATION_DEFRT_ADD ||
event == UIP_DS6_NOTIFICATION_DEFRT_RM) {
num = list_length(defaultrouterlist);
} else {
num = list_length(routelist);
}
n->callback(event, route, nexthop, num);
}
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_notification_add(struct uip_ds6_notification *n,
uip_ds6_notification_callback c)
{
if(n != NULL && c != NULL) {
n->callback = c;
list_add(notificationlist, n);
}
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_notification_rm(struct uip_ds6_notification *n)
{
list_remove(notificationlist, n);
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_route_init(void)
{
memb_init(&routememb);
list_init(routelist);
memb_init(&defaultroutermemb);
list_init(defaultrouterlist);
list_init(notificationlist);
}
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_list_head(void)
{
return list_head(routelist);
}
/*---------------------------------------------------------------------------*/
int
uip_ds6_route_num_routes(void)
{
return list_length(routelist);
}
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_lookup(uip_ipaddr_t *addr)
{
uip_ds6_route_t *r;
uip_ds6_route_t *found_route;
uint8_t longestmatch;
PRINTF("uip-ds6-route: Looking up route for ");
PRINT6ADDR(addr);
PRINTF("\n");
found_route = NULL;
longestmatch = 0;
for(r = list_head(routelist);
r != NULL;
r = list_item_next(r)) {
if(r->length >= longestmatch &&
uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) {
longestmatch = r->length;
found_route = r;
}
}
if(found_route != NULL) {
PRINTF("uip-ds6-route: Found route:");
PRINT6ADDR(addr);
PRINTF(" via ");
PRINT6ADDR(&found_route->nexthop);
PRINTF("\n");
} else {
PRINTF("uip-ds6-route: No route found\n");
}
return found_route;
}
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
uip_ipaddr_t *nexthop, uint8_t metric)
{
uip_ds6_route_t *r;
/* First make sure that we don't add a route twice. If we find an
existing route for our destination, we'll just update the old
one. */
r = uip_ds6_route_lookup(ipaddr);
if(r != NULL) {
PRINTF("uip_ds6_route_add: old route already found, updating this one instead: ");
PRINT6ADDR(ipaddr);
PRINTF("\n");
} else {
/* Allocate a routing entry and add the route to the list */
r = memb_alloc(&routememb);
if(r == NULL) {
PRINTF("uip_ds6_route_add: could not allocate memory for new route to ");
PRINT6ADDR(ipaddr);
PRINTF(", dropping it\n");
return NULL;
}
list_add(routelist, r);
PRINTF("uip_ds6_route_add num %d\n", list_length(routelist));
}
uip_ipaddr_copy(&(r->ipaddr), ipaddr);
r->length = length;
uip_ipaddr_copy(&(r->nexthop), nexthop);
r->metric = metric;
#ifdef UIP_DS6_ROUTE_STATE_TYPE
memset(&r->state, 0, sizeof(UIP_DS6_ROUTE_STATE_TYPE));
#endif
PRINTF("uip_ds6_route_add: adding route: ");
PRINT6ADDR(ipaddr);
PRINTF(" via ");
PRINT6ADDR(nexthop);
PRINTF("\n");
ANNOTATE("#L %u 1;blue\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_ADD, ipaddr, nexthop);
return r;
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_route_rm(uip_ds6_route_t *route)
{
uip_ds6_route_t *r;
/* Make sure that the route is in the list before removing it. */
for(r = list_head(routelist);
r != NULL;
r = list_item_next(r)) {
if(r == route) {
list_remove(routelist, route);
memb_free(&routememb, route);
PRINTF("uip_ds6_route_rm num %d\n", list_length(routelist));
call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM,
&route->ipaddr, &route->nexthop);
#if (DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE
/* we need to check if this was the last route towards "nexthop" */
/* if so - remove that link (annotation) */
for(r = list_head(routelist);
r != NULL;
r = list_item_next(r)) {
if(uip_ipaddr_cmp(&r->nexthop, &route->nexthop)) {
/* we found another link using the specific nexthop, so keep the #L */
return;
}
}
ANNOTATE("#L %u 0\n", route->nexthop.u8[sizeof(uip_ipaddr_t) - 1]);
#endif
return;
}
}
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop)
{
uip_ds6_route_t *r;
r = list_head(routelist);
while(r != NULL) {
if(uip_ipaddr_cmp(&r->nexthop, nexthop)) {
list_remove(routelist, r);
call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM,
&r->ipaddr, &r->nexthop);
r = list_head(routelist);
} else {
r = list_item_next(r);
}
}
}
/*---------------------------------------------------------------------------*/
uip_ds6_defrt_t *
uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
{
uip_ds6_defrt_t *d;
d = uip_ds6_defrt_lookup(ipaddr);
if(d == NULL) {
d = memb_alloc(&defaultroutermemb);
if(d == NULL) {
PRINTF("uip_ds6_defrt_add: could not add default route to ");
PRINT6ADDR(ipaddr);
PRINTF(", out of memory\n");
return NULL;
} else {
PRINTF("uip_ds6_defrt_add: adding default route to ");
PRINT6ADDR(ipaddr);
PRINTF("\n");
}
list_push(defaultrouterlist, d);
}
uip_ipaddr_copy(&d->ipaddr, ipaddr);
if(interval != 0) {
stimer_set(&d->lifetime, interval);
d->isinfinite = 0;
} else {
d->isinfinite = 1;
}
ANNOTATE("#L %u 1\n", ipaddr->u8[sizeof(uip_ipaddr_t) - 1]);
call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr);
return d;
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt)
{
uip_ds6_defrt_t *d;
/* Make sure that the defrt is in the list before we remove it. */
for(d = list_head(defaultrouterlist);
d != NULL;
d = list_item_next(d)) {
if(d == defrt) {
PRINTF("Removing default route\n");
list_remove(defaultrouterlist, defrt);
memb_free(&defaultroutermemb, defrt);
ANNOTATE("#L %u 0\n", defrt->ipaddr.u8[sizeof(uip_ipaddr_t) - 1]);
call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_RM,
&defrt->ipaddr, &defrt->ipaddr);
return;
}
}
}
/*---------------------------------------------------------------------------*/
uip_ds6_defrt_t *
uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr)
{
uip_ds6_defrt_t *d;
for(d = list_head(defaultrouterlist);
d != NULL;
d = list_item_next(d)) {
if(uip_ipaddr_cmp(&d->ipaddr, ipaddr)) {
return d;
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
uip_ipaddr_t *
uip_ds6_defrt_choose(void)
{
uip_ds6_defrt_t *d;
uip_ds6_nbr_t *bestnbr;
uip_ipaddr_t *addr;
addr = NULL;
for(d = list_head(defaultrouterlist);
d != NULL;
d = list_item_next(d)) {
PRINTF("Defrt, IP address ");
PRINT6ADDR(&d->ipaddr);
PRINTF("\n");
bestnbr = uip_ds6_nbr_lookup(&d->ipaddr);
if(bestnbr != NULL && bestnbr->state != NBR_INCOMPLETE) {
PRINTF("Defrt found, IP address ");
PRINT6ADDR(&d->ipaddr);
PRINTF("\n");
return &d->ipaddr;
} else {
addr = &d->ipaddr;
PRINTF("Defrt INCOMPLETE found, IP address ");
PRINT6ADDR(&d->ipaddr);
PRINTF("\n");
}
}
return addr;
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_defrt_periodic(void)
{
uip_ds6_defrt_t *d;
d = list_head(defaultrouterlist);
while(d != NULL) {
if(!d->isinfinite &&
stimer_expired(&d->lifetime)) {
PRINTF("uip_ds6_defrt_periodic: defrt lifetime expired\n");
uip_ds6_defrt_rm(d);
d = list_head(defaultrouterlist);
} else {
d = list_item_next(d);
}
}
}
/*---------------------------------------------------------------------------*/

132
core/net/uip-ds6-route.h Normal file
View file

@ -0,0 +1,132 @@
/*
* Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef UIP_DS6_ROUTE_H
#define UIP_DS6_ROUTE_H
void uip_ds6_route_init(void);
/* Event constants for the uip-ds6 route notification interface. The
notification interface allows for a user program to be notified via
a callback when a route has been added or removed and when the
system has added or removed a default route. */
#define UIP_DS6_NOTIFICATION_DEFRT_ADD 0
#define UIP_DS6_NOTIFICATION_DEFRT_RM 1
#define UIP_DS6_NOTIFICATION_ROUTE_ADD 2
#define UIP_DS6_NOTIFICATION_ROUTE_RM 3
typedef void (* uip_ds6_notification_callback)(int event,
uip_ipaddr_t *route,
uip_ipaddr_t *nexthop,
int num_routes);
struct uip_ds6_notification {
struct uip_ds6_notification *next;
uip_ds6_notification_callback callback;
};
void uip_ds6_notification_add(struct uip_ds6_notification *n,
uip_ds6_notification_callback c);
/*--------------------------------------------------*/
/* Routing table */
#define UIP_DS6_ROUTE_NBS 0
#ifndef UIP_CONF_DS6_ROUTE_NBU
#define UIP_DS6_ROUTE_NBU 4
#else
#define UIP_DS6_ROUTE_NBU UIP_CONF_DS6_ROUTE_NBU
#endif
#define UIP_DS6_ROUTE_NB UIP_DS6_ROUTE_NBS + UIP_DS6_ROUTE_NBU
/** \brief define some additional RPL related route state and
* neighbor callback for RPL - if not a DS6_ROUTE_STATE is already set */
#ifndef UIP_DS6_ROUTE_STATE_TYPE
#define UIP_DS6_ROUTE_STATE_TYPE rpl_route_entry_t
/* Needed for the extended route entry state when using ContikiRPL */
typedef struct rpl_route_entry {
uint32_t lifetime;
uint32_t saved_lifetime;
void *dag;
uint8_t learned_from;
} rpl_route_entry_t;
#endif /* UIP_DS6_ROUTE_STATE_TYPE */
/** \brief An entry in the routing table */
typedef struct uip_ds6_route {
struct uip_ds6_route *next;
uip_ipaddr_t ipaddr;
uip_ipaddr_t nexthop;
uint8_t length;
uint8_t metric;
#ifdef UIP_DS6_ROUTE_STATE_TYPE
UIP_DS6_ROUTE_STATE_TYPE state;
#endif
} uip_ds6_route_t;
/** \brief An entry in the default router list */
typedef struct uip_ds6_defrt {
struct uip_ds6_defrt *next;
uip_ipaddr_t ipaddr;
struct stimer lifetime;
uint8_t isinfinite;
} uip_ds6_defrt_t;
/** \name Default router list basic routines */
/** @{ */
uip_ds6_defrt_t *uip_ds6_defrt_add(uip_ipaddr_t *ipaddr,
unsigned long interval);
void uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt);
uip_ds6_defrt_t *uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr);
uip_ipaddr_t *uip_ds6_defrt_choose(void);
void uip_ds6_defrt_periodic(void);
/** @} */
/** \name Routing Table basic routines */
/** @{ */
uip_ds6_route_t *uip_ds6_route_lookup(uip_ipaddr_t *destipaddr);
uip_ds6_route_t *uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
uip_ipaddr_t *next_hop, uint8_t metric);
void uip_ds6_route_rm(uip_ds6_route_t *route);
void uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop);
int uip_ds6_route_num_routes(void);
uip_ds6_route_t *uip_ds6_route_list_head(void);
/** @} */
#endif /* UIP_DS6_ROUTE_H */

View file

@ -75,9 +75,9 @@ static uint8_t rscount; /** \brief numbe
/** @{ */
uip_ds6_netif_t uip_ds6_if; /** \brief The single interface */
uip_ds6_nbr_t uip_ds6_nbr_cache[UIP_DS6_NBR_NB]; /** \brief Neighor cache */
uip_ds6_defrt_t uip_ds6_defrt_list[UIP_DS6_DEFRT_NB]; /** \brief Default rt list */
//uip_ds6_defrt_t uip_ds6_defrt_list[UIP_DS6_DEFRT_NB]; /** \brief Default rt list */
uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; /** \brief Prefix list */
uip_ds6_route_t uip_ds6_routing_table[UIP_DS6_ROUTE_NB]; /** \brief Routing table */
//uip_ds6_route_t uip_ds6_routing_table[UIP_DS6_ROUTE_NB]; /** \brief Routing table */
/* Used by Cooja to enable extraction of addresses from memory.*/
uint8_t uip_ds6_addr_size;
@ -89,28 +89,29 @@ uint8_t uip_ds6_netif_addr_list_offset;
static uip_ipaddr_t loc_fipaddr;
/* Pointers used in this file */
static uip_ipaddr_t *locipaddr;
static uip_ds6_addr_t *locaddr;
static uip_ds6_maddr_t *locmaddr;
static uip_ds6_aaddr_t *locaaddr;
static uip_ds6_prefix_t *locprefix;
static uip_ds6_nbr_t *locnbr;
static uip_ds6_defrt_t *locdefrt;
static uip_ds6_route_t *locroute;
/*---------------------------------------------------------------------------*/
void
uip_ds6_init(void)
{
uip_ds6_route_init();
PRINTF("Init of IPv6 data structures\n");
PRINTF("%u neighbors\n%u default routers\n%u prefixes\n%u routes\n%u unicast addresses\n%u multicast addresses\n%u anycast addresses\n",
UIP_DS6_NBR_NB, UIP_DS6_DEFRT_NB, UIP_DS6_PREFIX_NB, UIP_DS6_ROUTE_NB,
UIP_DS6_ADDR_NB, UIP_DS6_MADDR_NB, UIP_DS6_AADDR_NB);
memset(uip_ds6_nbr_cache, 0, sizeof(uip_ds6_nbr_cache));
memset(uip_ds6_defrt_list, 0, sizeof(uip_ds6_defrt_list));
// memset(uip_ds6_defrt_list, 0, sizeof(uip_ds6_defrt_list));
memset(uip_ds6_prefix_list, 0, sizeof(uip_ds6_prefix_list));
memset(&uip_ds6_if, 0, sizeof(uip_ds6_if));
memset(uip_ds6_routing_table, 0, sizeof(uip_ds6_routing_table));
// memset(uip_ds6_routing_table, 0, sizeof(uip_ds6_routing_table));
uip_ds6_addr_size = sizeof(struct uip_ds6_addr);
uip_ds6_netif_addr_list_offset = offsetof(struct uip_ds6_netif, addr_list);
@ -174,13 +175,14 @@ uip_ds6_periodic(void)
}
/* Periodic processing on default routers */
for(locdefrt = uip_ds6_defrt_list;
uip_ds6_defrt_periodic();
/* for(locdefrt = uip_ds6_defrt_list;
locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) {
if((locdefrt->isused) && (!locdefrt->isinfinite) &&
(stimer_expired(&(locdefrt->lifetime)))) {
uip_ds6_defrt_rm(locdefrt);
}
}
}*/
#if !UIP_CONF_ROUTER
/* Periodic processing on prefixes */
@ -398,86 +400,6 @@ uip_ds6_nbr_ll_lookup(uip_lladdr_t *lladdr)
}
/*---------------------------------------------------------------------------*/
uip_ds6_defrt_t *
uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *)uip_ds6_defrt_list, UIP_DS6_DEFRT_NB,
sizeof(uip_ds6_defrt_t), ipaddr, 128,
(uip_ds6_element_t **)&locdefrt) == FREESPACE) {
locdefrt->isused = 1;
uip_ipaddr_copy(&locdefrt->ipaddr, ipaddr);
if(interval != 0) {
stimer_set(&locdefrt->lifetime, interval);
locdefrt->isinfinite = 0;
} else {
locdefrt->isinfinite = 1;
}
PRINTF("Adding defrouter with ip addr ");
PRINT6ADDR(&locdefrt->ipaddr);
PRINTF("\n");
ANNOTATE("#L %u 1\n", ipaddr->u8[sizeof(uip_ipaddr_t) - 1]);
return locdefrt;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt)
{
if(defrt != NULL) {
defrt->isused = 0;
ANNOTATE("#L %u 0\n", defrt->ipaddr.u8[sizeof(uip_ipaddr_t) - 1]);
}
return;
}
/*---------------------------------------------------------------------------*/
uip_ds6_defrt_t *
uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr)
{
if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_defrt_list,
UIP_DS6_DEFRT_NB, sizeof(uip_ds6_defrt_t), ipaddr, 128,
(uip_ds6_element_t **)&locdefrt) == FOUND) {
return locdefrt;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
uip_ipaddr_t *
uip_ds6_defrt_choose(void)
{
uip_ds6_nbr_t *bestnbr;
locipaddr = NULL;
for(locdefrt = uip_ds6_defrt_list;
locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) {
if(locdefrt->isused) {
PRINTF("Defrt, IP address ");
PRINT6ADDR(&locdefrt->ipaddr);
PRINTF("\n");
bestnbr = uip_ds6_nbr_lookup(&locdefrt->ipaddr);
if(bestnbr != NULL && bestnbr->state != NBR_INCOMPLETE) {
PRINTF("Defrt found, IP address ");
PRINT6ADDR(&locdefrt->ipaddr);
PRINTF("\n");
return &locdefrt->ipaddr;
} else {
locipaddr = &locdefrt->ipaddr;
PRINTF("Defrt INCOMPLETE found, IP address ");
PRINT6ADDR(&locdefrt->ipaddr);
PRINTF("\n");
}
}
}
return locipaddr;
}
#if UIP_CONF_ROUTER
/*---------------------------------------------------------------------------*/
uip_ds6_prefix_t *
@ -744,104 +666,6 @@ uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr)
return NULL;
}
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_lookup(uip_ipaddr_t *destipaddr)
{
uip_ds6_route_t *locrt = NULL;
uint8_t longestmatch = 0;
PRINTF("DS6: Looking up route for ");
PRINT6ADDR(destipaddr);
PRINTF("\n");
for(locroute = uip_ds6_routing_table;
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; locroute++) {
if((locroute->isused) && (locroute->length >= longestmatch)
&&
(uip_ipaddr_prefixcmp
(destipaddr, &locroute->ipaddr, locroute->length))) {
longestmatch = locroute->length;
locrt = locroute;
}
}
if(locrt != NULL) {
PRINTF("DS6: Found route:");
PRINT6ADDR(destipaddr);
PRINTF(" via ");
PRINT6ADDR(&locrt->nexthop);
PRINTF("\n");
} else {
PRINTF("DS6: No route found\n");
}
return locrt;
}
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, uip_ipaddr_t *nexthop,
uint8_t metric)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *)uip_ds6_routing_table, UIP_DS6_ROUTE_NB,
sizeof(uip_ds6_route_t), ipaddr, length,
(uip_ds6_element_t **)&locroute) == FREESPACE) {
locroute->isused = 1;
uip_ipaddr_copy(&(locroute->ipaddr), ipaddr);
locroute->length = length;
uip_ipaddr_copy(&(locroute->nexthop), nexthop);
locroute->metric = metric;
#ifdef UIP_DS6_ROUTE_STATE_TYPE
memset(&locroute->state, 0, sizeof(UIP_DS6_ROUTE_STATE_TYPE));
#endif
PRINTF("DS6: adding route: ");
PRINT6ADDR(ipaddr);
PRINTF(" via ");
PRINT6ADDR(nexthop);
PRINTF("\n");
ANNOTATE("#L %u 1;blue\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
}
return locroute;
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_route_rm(uip_ds6_route_t *route)
{
route->isused = 0;
#if (DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE
/* we need to check if this was the last route towards "nexthop" */
/* if so - remove that link (annotation) */
for(locroute = uip_ds6_routing_table;
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
locroute++) {
if(locroute->isused && uip_ipaddr_cmp(&locroute->nexthop, &route->nexthop)) {
/* we found another link using the specific nexthop, so keep the #L */
return;
}
}
ANNOTATE("#L %u 0\n",route->nexthop.u8[sizeof(uip_ipaddr_t) - 1]);
#endif
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop)
{
for(locroute = uip_ds6_routing_table;
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
locroute++) {
if(locroute->isused && uip_ipaddr_cmp(&locroute->nexthop, nexthop)) {
locroute->isused = 0;
}
}
ANNOTATE("#L %u 0\n",nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)

View file

@ -46,6 +46,7 @@
#include "sys/stimer.h"
/* The size of uip_ds6_addr_t depends on UIP_ND6_DEF_MAXDADNS. Include uip-nd6.h to define it. */
#include "net/uip-nd6.h"
#include "net/uip-ds6-route.h"
/*--------------------------------------------------*/
/** Configuration. For all tables (Neighbor cache, Prefix List, Routing Table,
@ -82,15 +83,6 @@
#endif
#define UIP_DS6_PREFIX_NB UIP_DS6_PREFIX_NBS + UIP_DS6_PREFIX_NBU
/* Routing table */
#define UIP_DS6_ROUTE_NBS 0
#ifndef UIP_CONF_DS6_ROUTE_NBU
#define UIP_DS6_ROUTE_NBU 4
#else
#define UIP_DS6_ROUTE_NBU UIP_CONF_DS6_ROUTE_NBU
#endif
#define UIP_DS6_ROUTE_NB UIP_DS6_ROUTE_NBS + UIP_DS6_ROUTE_NBU
/* Unicast address list*/
#define UIP_DS6_ADDR_NBS 1
#ifndef UIP_CONF_DS6_ADDR_NBU
@ -158,9 +150,8 @@
#define FOUND 0
#define FREESPACE 1
#define NOSPACE 2
/*--------------------------------------------------*/
#if UIP_CONF_IPV6_QUEUE_PKT
#include "net/uip-packetqueue.h"
#endif /*UIP_CONF_QUEUE_PKT */
@ -181,14 +172,6 @@ typedef struct uip_ds6_nbr {
#endif /*UIP_CONF_QUEUE_PKT */
} uip_ds6_nbr_t;
/** \brief An entry in the default router list */
typedef struct uip_ds6_defrt {
uint8_t isused;
uip_ipaddr_t ipaddr;
struct stimer lifetime;
uint8_t isinfinite;
} uip_ds6_defrt_t;
/** \brief A prefix list entry */
#if UIP_CONF_ROUTER
typedef struct uip_ds6_prefix {
@ -236,19 +219,6 @@ typedef struct uip_ds6_maddr {
uip_ipaddr_t ipaddr;
} uip_ds6_maddr_t;
/** \brief define some additional RPL related route state and
* neighbor callback for RPL - if not a DS6_ROUTE_STATE is already set */
#ifndef UIP_DS6_ROUTE_STATE_TYPE
#define UIP_DS6_ROUTE_STATE_TYPE rpl_route_entry_t
/* Needed for the extended route entry state when using ContikiRPL */
typedef struct rpl_route_entry {
uint32_t lifetime;
uint32_t saved_lifetime;
void *dag;
uint8_t learned_from;
} rpl_route_entry_t;
#endif /* UIP_DS6_ROUTE_STATE_TYPE */
/* only define the callback if RPL is active */
#if UIP_CONF_IPV6_RPL
#ifndef UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED
@ -258,18 +228,6 @@ typedef struct rpl_route_entry {
/** \brief An entry in the routing table */
typedef struct uip_ds6_route {
uint8_t isused;
uip_ipaddr_t ipaddr;
uint8_t length;
uint8_t metric;
uip_ipaddr_t nexthop;
#ifdef UIP_DS6_ROUTE_STATE_TYPE
UIP_DS6_ROUTE_STATE_TYPE state;
#endif
} uip_ds6_route_t;
/** \brief Interface structure (contains all the interface variables) */
typedef struct uip_ds6_netif {
uint32_t link_mtu;
@ -325,15 +283,6 @@ uip_ds6_nbr_t *uip_ds6_nbr_ll_lookup(uip_lladdr_t *lladdr);
/** @} */
/** \name Default router list basic routines */
/** @{ */
uip_ds6_defrt_t *uip_ds6_defrt_add(uip_ipaddr_t *ipaddr,
unsigned long interval);
void uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt);
uip_ds6_defrt_t *uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr);
uip_ipaddr_t *uip_ds6_defrt_choose(void);
/** @} */
/** \name Prefix list basic routines */
/** @{ */
@ -381,16 +330,6 @@ uip_ds6_aaddr_t *uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr);
/** @} */
/** \name Routing Table basic routines */
/** @{ */
uip_ds6_route_t *uip_ds6_route_lookup(uip_ipaddr_t *destipaddr);
uip_ds6_route_t *uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
uip_ipaddr_t *next_hop, uint8_t metric);
void uip_ds6_route_rm(uip_ds6_route_t *route);
void uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop);
/** @} */
/** \brief set the last 64 bits of an IP address based on the MAC address */
void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr);

View file

@ -102,7 +102,7 @@ uip_icmp6_echo_request_input(void)
if(uip_ext_len > 0) {
#if UIP_CONF_IPV6_RPL
if ((temp_ext_len=rpl_invert_header())) {
if((temp_ext_len = rpl_invert_header())) {
/* If there were other extension headers*/
UIP_FIRST_EXT_BUF->next = UIP_PROTO_ICMP6;
if (uip_ext_len != temp_ext_len) {
@ -118,7 +118,7 @@ uip_icmp6_echo_request_input(void)
(uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN,
(uip_len - UIP_IPH_LEN - temp_ext_len - UIP_ICMPH_LEN));
}
uip_ext_len=temp_ext_len;
uip_ext_len = temp_ext_len;
} else {
#endif /* UIP_CONF_IPV6_RPL */
/* If there were extension headers*/

View file

@ -98,17 +98,25 @@
/** \name RFC 4861 Node constant */
#define UIP_ND6_MAX_MULTICAST_SOLICIT 3
#ifdef UIP_CONF_ND6_MAX_UNICAST_SOLICIT
#define UIP_ND6_MAX_UNICAST_SOLICIT UIP_CONF_ND6_MAX_UNICAST_SOLICIT
#else /* UIP_CONF_ND6_MAX_UNICAST_SOLICIT */
#define UIP_ND6_MAX_UNICAST_SOLICIT 3
#endif /* UIP_CONF_ND6_MAX_UNICAST_SOLICIT */
#ifdef UIP_CONF_ND6_REACHABLE_TIME
#define UIP_ND6_REACHABLE_TIME UIP_CONF_ND6_REACHABLE_TIME
#else
#define UIP_ND6_REACHABLE_TIME 30000
#endif
#ifdef UIP_CONF_ND6_RETRANS_TIMER
#define UIP_ND6_RETRANS_TIMER UIP_CONF_ND6_RETRANS_TIMER
#else
#define UIP_ND6_RETRANS_TIMER 1000
#endif
#define UIP_ND6_DELAY_FIRST_PROBE_TIME 5
#define UIP_ND6_MIN_RANDOM_FACTOR(x) (x / 2)
#define UIP_ND6_MAX_RANDOM_FACTOR(x) ((x) + (x) / 2)

View file

@ -43,6 +43,12 @@
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
#ifdef UIP_SPLIT_CONF_SIZE
#define UIP_SPLIT_SIZE UIP_SPLIT_CONF_SIZE
#else /* UIP_SPLIT_CONF_SIZE */
#define UIP_SPLIT_SIZE UIP_TCP_MSS
#endif /* UIP_SPLIT_CONF_SIZE */
/*-----------------------------------------------------------------------------*/
void
uip_split_output(void)
@ -50,9 +56,11 @@ uip_split_output(void)
#if UIP_TCP
uint16_t tcplen, len1, len2;
/* We only try to split maximum sized TCP segments. */
/* We only split TCP segments that are larger than or equal to
UIP_SPLIT_SIZE, which is configurable through
UIP_SPLIT_CONF_SIZE. */
if(BUF->proto == UIP_PROTO_TCP &&
uip_len == UIP_TCP_MSS + UIP_TCPIP_HLEN) {
uip_len >= UIP_SPLIT_SIZE + UIP_TCPIP_HLEN) {
tcplen = uip_len - UIP_TCPIP_HLEN;
/* Split the segment in two. If the original packet length was

View file

@ -59,21 +59,19 @@
* Representation of an IP address.
*
*/
#if UIP_CONF_IPV6
typedef union uip_ip4addr_t {
uint8_t u8[4]; /* Initializer, must come first. */
uint16_t u16[2];
} uip_ip4addr_t;
typedef union uip_ip6addr_t {
uint8_t u8[16]; /* Initializer, must come first!!! */
uint8_t u8[16]; /* Initializer, must come first. */
uint16_t u16[8];
} uip_ip6addr_t;
#if UIP_CONF_IPV6
typedef uip_ip6addr_t uip_ipaddr_t;
#else /* UIP_CONF_IPV6 */
typedef union uip_ip4addr_t {
uint8_t u8[4]; /* Initializer, must come first!!! */
uint16_t u16[2];
#if 0
uint32_t u32;
#endif
} uip_ip4addr_t;
typedef uip_ip4addr_t uip_ipaddr_t;
#endif /* UIP_CONF_IPV6 */
@ -988,6 +986,12 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport);
#ifndef uip_ipaddr_copy
#define uip_ipaddr_copy(dest, src) (*(dest) = *(src))
#endif
#ifndef uip_ip4addr_copy
#define uip_ip4addr_copy(dest, src) (*(dest) = *(src))
#endif
#ifndef uip_ip6addr_copy
#define uip_ip6addr_copy(dest, src) (*(dest) = *(src))
#endif
/**
* Compare two IP addresses
@ -1009,11 +1013,14 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport);
*
* \hideinitializer
*/
#if !UIP_CONF_IPV6
#define uip_ipaddr_cmp(addr1, addr2) ((addr1)->u16[0] == (addr2)->u16[0] && \
#define uip_ip4addr_cmp(addr1, addr2) ((addr1)->u16[0] == (addr2)->u16[0] && \
(addr1)->u16[1] == (addr2)->u16[1])
#define uip_ip6addr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
#if !UIP_CONF_IPV6
#define uip_ipaddr_cmp(addr1, addr2) uip_ip4addr_cmp(addr1, addr2)
#else /* !UIP_CONF_IPV6 */
#define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
#define uip_ipaddr_cmp(addr1, addr2) uip_ip6addr_cmp(addr1, addr2)
#endif /* !UIP_CONF_IPV6 */
/**
@ -1040,15 +1047,15 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport);
*
* \hideinitializer
*/
#if !UIP_CONF_IPV6
#define uip_ipaddr_maskcmp(addr1, addr2, mask) \
(((((uint16_t *)addr1)[0] & ((uint16_t *)mask)[0]) == \
(((uint16_t *)addr2)[0] & ((uint16_t *)mask)[0])) && \
((((uint16_t *)addr1)[1] & ((uint16_t *)mask)[1]) == \
(((uint16_t *)addr2)[1] & ((uint16_t *)mask)[1])))
#else
#define uip_ipaddr_prefixcmp(addr1, addr2, length) (memcmp(addr1, addr2, length>>3) == 0)
#endif
/**

View file

@ -855,7 +855,7 @@ ext_hdr_options_process(void)
case UIP_EXT_HDR_OPT_RPL:
PRINTF("Processing RPL option\n");
if(rpl_verify_header(uip_ext_opt_offset)) {
PRINTF("RPL Option Error : Dropping Packet");
PRINTF("RPL Option Error: Dropping Packet\n");
return 1;
}
uip_ext_opt_offset += (UIP_EXT_HDR_OPT_RPL_BUF->opt_len) + 2;
@ -1123,17 +1123,19 @@ uip_process(uint8_t flag)
if(*uip_next_hdr == UIP_PROTO_HBHO) {
#if UIP_CONF_IPV6_CHECKS
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO;
#endif /*UIP_CONF_IPV6_CHECKS*/
#endif /* UIP_CONF_IPV6_CHECKS */
switch(ext_hdr_options_process()) {
case 0:
/*continue*/
/* continue */
uip_next_hdr = &UIP_EXT_BUF->next;
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
break;
case 1:
/*silently discard*/
PRINTF("Dropping packet after extension header processing\n");
/* silently discard */
goto drop;
case 2:
PRINTF("Sending error message after extension header processing\n");
/* send icmp error message (created in ext_hdr_options_process)
* and discard*/
goto send;
@ -1448,6 +1450,11 @@ uip_process(uint8_t flag)
#if UIP_UDP_CHECKSUMS
uip_len = uip_len - UIP_IPUDPH_LEN;
uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN];
/* XXX hack: UDP/IPv6 receivers should drop packets with UDP
checksum 0. Here, we explicitly receive UDP packets with checksum
0. This is to be able to debug code that for one reason or
another miscomputes UDP checksums. The reception of zero UDP
checksums should be turned into a configration option. */
if(UIP_UDP_BUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
UIP_STAT(++uip_stat.udp.drop);
UIP_STAT(++uip_stat.udp.chkerr);
@ -2211,19 +2218,18 @@ uip_process(uint8_t flag)
UIP_TCP_BUF->seqno[3] = uip_connr->snd_nxt[3];
UIP_IP_BUF->proto = UIP_PROTO_TCP;
UIP_TCP_BUF->srcport = uip_connr->lport;
UIP_TCP_BUF->destport = uip_connr->rport;
uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_connr->ripaddr);
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr,&UIP_IP_BUF->destipaddr);
PRINTF("Sending TCP packet to");
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
PRINTF("Sending TCP packet to ");
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
PRINTF("from");
PRINTF(" from ");
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
PRINTF("\n");
if(uip_connr->tcpstateflags & UIP_STOPPED) {
/* If the connection has issued uip_stop(), we advertise a zero
window so that the remote host will stop sending data. */

View file

@ -42,9 +42,8 @@
/*-----------------------------------------------------------------------------------*/
int
uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr)
uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *ipaddr)
{
#if UIP_CONF_IPV6
uint16_t value;
int tmp, zero;
unsigned int len;
@ -54,7 +53,7 @@ uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr)
zero = -1;
if(*addrstr == '[') addrstr++;
for(len = 0; len < sizeof(uip_ipaddr_t) - 1; addrstr++) {
for(len = 0; len < sizeof(uip_ip6addr_t) - 1; addrstr++) {
c = *addrstr;
if(c == ':' || c == '\0' || c == ']' || c == '/') {
ipaddr->u8[len] = (value >> 8) & 0xff;
@ -91,45 +90,63 @@ uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr)
PRINTF("uiplib: too large address\n");
return 0;
}
if(len < sizeof(uip_ipaddr_t)) {
if(len < sizeof(uip_ip6addr_t)) {
if(zero < 0) {
PRINTF("uiplib: too short address\n");
return 0;
}
memmove(&ipaddr->u8[zero + sizeof(uip_ipaddr_t) - len],
memmove(&ipaddr->u8[zero + sizeof(uip_ip6addr_t) - len],
&ipaddr->u8[zero], len - zero);
memset(&ipaddr->u8[zero], 0, sizeof(uip_ipaddr_t) - len);
memset(&ipaddr->u8[zero], 0, sizeof(uip_ip6addr_t) - len);
}
#else /* UIP_CONF_IPV6 */
return 1;
}
/*-----------------------------------------------------------------------------------*/
/* Parse a IPv4-address from a string. Returns the number of characters read
* for the address. */
int
uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *ipaddr)
{
unsigned char tmp;
char c;
unsigned char i, j;
uint8_t charsread = 0;
tmp = 0;
for(i = 0; i < 4; ++i) {
j = 0;
do {
c = *addrstr;
++j;
if(j > 4) {
return 0;
return 0;
}
if(c == '.' || c == 0) {
ipaddr->u8[i] = tmp;
tmp = 0;
if(c == '.' || c == 0 || c == ' ') {
ipaddr->u8[i] = tmp;
tmp = 0;
} else if(c >= '0' && c <= '9') {
tmp = (tmp * 10) + (c - '0');
tmp = (tmp * 10) + (c - '0');
} else {
return 0;
return 0;
}
++addrstr;
} while(c != '.' && c != 0);
++charsread;
} while(c != '.' && c != 0 && c != ' ');
}
return charsread-1;
}
/*-----------------------------------------------------------------------------------*/
int
uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr)
{
#if UIP_CONF_IPV6
return uiplib_ip6addrconv(addrstr, ipaddr);
#else /* UIP_CONF_IPV6 */
return uiplib_ip4addrconv(addrstr, ipaddr);
#endif /* UIP_CONF_IPV6 */
return 1;
}
/*-----------------------------------------------------------------------------------*/

View file

@ -60,7 +60,7 @@
* \param addrstr A pointer to a string containing the IP address in
* textual form.
*
* \param addr A pointer to a uip_ipaddr_t that will be filled in with
* \param addr A pointer to a uip_ip4addr_t that will be filled in with
* the numerical representation of the address.
*
* \retval 0 If the IP address could not be parsed.
@ -68,6 +68,8 @@
*/
CCIF int uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *addr);
CCIF int uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *addr);
CCIF int uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *addr);
/** @} */
#endif /* __UIPLIB_H__ */

View file

@ -149,6 +149,7 @@ static
PT_THREAD(generate_routes(struct httpd_state *s))
{
static int i;
static uip_ds6_route_t *r;
PSOCK_BEGIN(&s->sout);
SEND_STRING(&s->sout, TOP);
@ -169,19 +170,19 @@ PT_THREAD(generate_routes(struct httpd_state *s))
ADD("</pre>Routes<pre>");
SEND_STRING(&s->sout, buf);
blen = 0;
for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
if(uip_ds6_routing_table[i].isused) {
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
ADD("/%u (via ", uip_ds6_routing_table[i].length);
ipaddr_add(&uip_ds6_routing_table[i].nexthop);
if(uip_ds6_routing_table[i].state.lifetime < 600) {
ADD(") %lus\n", (unsigned long)uip_ds6_routing_table[i].state.lifetime);
} else {
ADD(")\n");
}
SEND_STRING(&s->sout, buf);
blen = 0;
for(r = uip_ds6_route_list_head();
r != NULL;
r = list_item_next(r)) {
ipaddr_add(&r->ipaddr);
ADD("/%u (via ", r->length);
ipaddr_add(&r->nexthop);
if(r->state.lifetime < 600) {
ADD(") %lus\n", (unsigned long)r->state.lifetime);
} else {
ADD(")\n");
}
SEND_STRING(&s->sout, buf);
blen = 0;
}
ADD("</pre>");
//if(blen > 0) {

View file

@ -57,7 +57,6 @@
uint16_t dag_id[] = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011};
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
extern uip_ds6_route_t uip_ds6_routing_table[];
static uip_ipaddr_t prefix;
static uint8_t prefix_set;
@ -149,6 +148,7 @@ static
PT_THREAD(generate_routes(struct httpd_state *s))
{
static int i;
static uip_ds6_route_t *r;
#if BUF_USES_STACK
char buf[256];
#endif
@ -220,45 +220,45 @@ PT_THREAD(generate_routes(struct httpd_state *s))
#else
blen = 0;
#endif
for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
if(uip_ds6_routing_table[i].isused) {
for(r = uip_ds6_route_list_head(); r != NULL; r = list_item_next(r)) {
#if BUF_USES_STACK
#if WEBSERVER_CONF_ROUTE_LINKS
ADD("<a href=http://[");
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
ADD("]/status.shtml>");
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
ADD("</a>");
ADD("<a href=http://[");
ipaddr_add(&r->ipaddr);
ADD("]/status.shtml>");
ipaddr_add(&r->ipaddr);
ADD("</a>");
#else
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
ipaddr_add(&r->ipaddr);
#endif
#else
#if WEBSERVER_CONF_ROUTE_LINKS
ADD("<a href=http://[");
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
ADD("]/status.shtml>");
SEND_STRING(&s->sout, buf); //TODO: why tunslip6 needs an output here, wpcapslip does not
blen = 0;
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
ADD("</a>");
ADD("<a href=http://[");
ipaddr_add(&r->ipaddr);
ADD("]/status.shtml>");
SEND_STRING(&s->sout, buf); //TODO: why tunslip6 needs an output here, wpcapslip does not
blen = 0;
ipaddr_add(&r->ipaddr);
ADD("</a>");
#else
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
ipaddr_add(&r->ipaddr);
#endif
#endif
ADD("/%u (via ", uip_ds6_routing_table[i].length);
ipaddr_add(&uip_ds6_routing_table[i].nexthop);
if(1 || (uip_ds6_routing_table[i].state.lifetime < 600)) {
ADD(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
} else {
ADD(")\n");
}
SEND_STRING(&s->sout, buf);
#if BUF_USES_STACK
bufptr = buf; bufend = bufptr + sizeof(buf);
#else
blen = 0;
#endif
ADD("/%u (via ", r->length);
ipaddr_add(&r->nexthop);
if(1 || (r->state.lifetime < 600)) {
ADD(") %lus\n", r->state.lifetime);
} else {
ADD(")\n");
}
SEND_STRING(&s->sout, buf);
#if BUF_USES_STACK
bufptr = buf; bufend = bufptr + sizeof(buf);
#else
blen = 0;
#endif
}
ADD("</pre>");

View file

@ -70,7 +70,8 @@ void
collect_common_net_print(void)
{
rpl_dag_t *dag;
int i;
uip_ds6_route_t *r;
/* Let's suppose we have only one instance */
dag = rpl_get_any_dag();
if(dag->preferred_parent != NULL) {
@ -78,12 +79,10 @@ collect_common_net_print(void)
PRINT6ADDR(&dag->preferred_parent->addr);
PRINTF("\n");
}
PRINTF("Route entries:\n");
for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
if(uip_ds6_routing_table[i].isused) {
PRINT6ADDR(&uip_ds6_routing_table[i].ipaddr);
PRINTF("\n");
}
for(r = uip_ds6_route_list_head();
r != NULL;
r = list_item_next(r)) {
PRINT6ADDR(&r->ipaddr);
}
PRINTF("---\n");
}

View file

@ -536,17 +536,22 @@ extern uip_ds6_netif_t uip_ds6_if;
}
if (j) PRINTF(" <none>");
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
if(uip_ds6_routing_table[i].isused) {
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
PRINTF("/%u (via ", uip_ds6_routing_table[i].length);
ipaddr_add(&uip_ds6_routing_table[i].nexthop);
{
uip_ds6_route_t *r;
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
j = 1;
for(r = uip_ds6_route_list_head();
r != NULL;
r = list_item_next(r)) {
ipaddr_add(&r->ipaddr);
PRINTF("/%u (via ", r->length);
ipaddr_add(&r->nexthop);
// if(uip_ds6_routing_table[i].state.lifetime < 600) {
PRINTF(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
// } else {
// PRINTF(")\n");
// }
j=0;
PRINTF(") %lus\n", r->state.lifetime);
// } else {
// PRINTF(")\n");
// }
j = 0;
}
}
if (j) PRINTF(" <none>");

View file

@ -354,23 +354,25 @@ PT_THREAD(neighbors(struct httpd_state *s, char *ptr))
static unsigned short
make_routes(void *p)
{
static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR = "(%u (via ";
static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR = ") %lus<br>";
static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")<br>";
uint8_t i,j=0;
uint16_t numprinted;
static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR = "(%u (via ";
static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR = ") %lus<br>";
static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")<br>";
uint8_t i,j=0;
uint16_t numprinted;
uip_ds6_route_t *r;
numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh);
for (i=0; i<UIP_DS6_ROUTE_NB;i++) {
if (uip_ds6_routing_table[i].isused) {
j++;
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].ipaddr, uip_appdata + numprinted);
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, uip_ds6_routing_table[i].length);
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].nexthop, uip_appdata + numprinted);
if(uip_ds6_routing_table[i].state.lifetime < 3600) {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, uip_ds6_routing_table[i].state.lifetime);
} else {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes3);
}
for(r = uip_ds6_route_list_head();
r != NULL;
r = list_item_next(r)) {
j++;
numprinted += httpd_cgi_sprint_ip6(r->ipaddr, uip_appdata + numprinted);
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, r->length);
numprinted += httpd_cgi_sprint_ip6(r->nexthop, uip_appdata + numprinted);
if(r->state.lifetime < 3600) {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, r->state.lifetime);
} else {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes3);
}
}
if (j==0) numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrn);

View file

@ -531,18 +531,22 @@ extern uip_ds6_netif_t uip_ds6_if;
}
}
if (j) PRINTF(" <none>");
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
if(uip_ds6_routing_table[i].isused) {
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
PRINTF("/%u (via ", uip_ds6_routing_table[i].length);
ipaddr_add(&uip_ds6_routing_table[i].nexthop);
{
uip_ds6_route_t *r;
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
j = 1;
for(r = uip_ds6_route_list_head();
r != NULL;
r = list_item_next(r)) {
ipaddr_add(&r->ipaddr);
PRINTF("/%u (via ", r->length);
ipaddr_add(&r->nexthop);
// if(uip_ds6_routing_table[i].state.lifetime < 600) {
PRINTF(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
// } else {
// PRINTF(")\n");
// }
j=0;
PRINTF(") %lus\n", r->state.lifetime);
// } else {
// PRINTF(")\n");
// }
j = 0;
}
}
if (j) PRINTF(" <none>");

View file

@ -614,18 +614,23 @@ extern uip_ds6_netif_t uip_ds6_if;
}
}
if (j) printf(" <none>");
printf("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
if(uip_ds6_routing_table[i].isused) {
uip_debug_ipaddr_print(&uip_ds6_routing_table[i].ipaddr);
printf("/%u (via ", uip_ds6_routing_table[i].length);
uip_debug_ipaddr_print(&uip_ds6_routing_table[i].nexthop);
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
{
uip_ds6_route_t *r;
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
j = 1;
for(r = uip_ds6_route_list_head();
r != NULL;
r = list_item_next(r)) {
ipaddr_add(&r->ipaddr);
PRINTF("/%u (via ", r->length);
ipaddr_add(&r->nexthop);
// if(uip_ds6_routing_table[i].state.lifetime < 600) {
printf(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
// } else {
// printf(")\n");
// }
j=0;
PRINTF(") %lus\n", r->state.lifetime);
// } else {
// PRINTF(")\n");
// }
j = 0;
}
}
if (j) printf(" <none>");