Added functionality for decaying routes: when a packet is sent over a route, it is decayed. If the route is not refreshed within four packets (with the route_refresh() function, which is called when a new packet arrives), the route is dropped. A route can be decayed at most once per second
This commit is contained in:
parent
a220da3e88
commit
fe30886b37
|
@ -33,7 +33,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of the Contiki operating system.
|
* This file is part of the Contiki operating system.
|
||||||
*
|
*
|
||||||
* $Id: route.c,v 1.14 2009/05/04 11:23:30 adamdunkels Exp $
|
* $Id: route.c,v 1.15 2009/05/10 21:08:01 adamdunkels Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,15 +57,36 @@
|
||||||
#define NUM_RT_ENTRIES 8
|
#define NUM_RT_ENTRIES 8
|
||||||
#endif /* ROUTE_CONF_ENTRIES */
|
#endif /* ROUTE_CONF_ENTRIES */
|
||||||
|
|
||||||
|
#ifdef ROUTE_CONF_DECAY_THRESHOLD
|
||||||
|
#define DECAY_THRESHOLD ROUTE_CONF_DECAY_THRESHOLD
|
||||||
|
#else /* ROUTE_CONF_DECAY_THRESHOLD */
|
||||||
|
#define DECAY_THRESHOLD 8
|
||||||
|
#endif /* ROUTE_CONF_DECAY_THRESHOLD */
|
||||||
|
|
||||||
|
#ifdef ROUTE_CONF_DEFAULT_LIFETIME
|
||||||
|
#define DEFAULT_LIFETIME ROUTE_CONF_DEFAULT_LIFETIME
|
||||||
|
#else /* ROUTE_CONF_DEFAULT_LIFETIME */
|
||||||
|
#define DEFAULT_LIFETIME 60
|
||||||
|
#endif /* ROUTE_CONF_DEFAULT_LIFETIME */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LRU (with respect to insertion time) list of route entries.
|
* List of route entries.
|
||||||
*/
|
*/
|
||||||
LIST(route_table);
|
LIST(route_table);
|
||||||
MEMB(route_mem, struct route_entry, NUM_RT_ENTRIES);
|
MEMB(route_mem, struct route_entry, NUM_RT_ENTRIES);
|
||||||
|
|
||||||
static struct ctimer t;
|
static struct ctimer t;
|
||||||
|
|
||||||
static int max_time = 60;
|
static int max_time = DEFAULT_LIFETIME;
|
||||||
|
|
||||||
|
#define DEBUG 0
|
||||||
|
#if DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#define PRINTF(...) printf(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define PRINTF(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
|
@ -76,8 +97,10 @@ periodic(void *ptr)
|
||||||
for(e = list_head(route_table); e != NULL; e = e->next) {
|
for(e = list_head(route_table); e != NULL; e = e->next) {
|
||||||
e->time++;
|
e->time++;
|
||||||
if(e->time >= max_time) {
|
if(e->time >= max_time) {
|
||||||
/* printf("Route to %d.%d dropped\n",
|
PRINTF("route periodic: removing entry to %d.%d with nexthop %d.%d and cost %d\n",
|
||||||
e->dest.u8[0], e->dest.u8[1]);*/
|
e->dest.u8[0], e->dest.u8[1],
|
||||||
|
e->nexthop.u8[0], e->nexthop.u8[1],
|
||||||
|
e->cost);
|
||||||
list_remove(route_table, e);
|
list_remove(route_table, e);
|
||||||
memb_free(&route_mem, e);
|
memb_free(&route_mem, e);
|
||||||
}
|
}
|
||||||
|
@ -97,31 +120,42 @@ route_init(void)
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
route_add(const rimeaddr_t *dest, const rimeaddr_t *nexthop,
|
route_add(const rimeaddr_t *dest, const rimeaddr_t *nexthop,
|
||||||
uint8_t hop_count, uint8_t seqno)
|
uint8_t cost, uint8_t seqno)
|
||||||
{
|
{
|
||||||
struct route_entry *e;
|
struct route_entry *e;
|
||||||
|
|
||||||
/* Avoid inserting duplicate entries. */
|
/* Avoid inserting duplicate entries. */
|
||||||
e = route_lookup(dest);
|
e = route_lookup(dest);
|
||||||
if(e != NULL) {
|
if(e != NULL && rimeaddr_cmp(&e->nexthop, nexthop)) {
|
||||||
list_remove(route_table, e);
|
list_remove(route_table, e);
|
||||||
} else {
|
} else {
|
||||||
/* Allocate a new entry or reuse the oldest. */
|
/* Allocate a new entry or reuse the oldest entry with highest cost. */
|
||||||
e = memb_alloc(&route_mem);
|
e = memb_alloc(&route_mem);
|
||||||
if(e == NULL) {
|
if(e == NULL) {
|
||||||
e = list_chop(route_table); /* Remove oldest entry. */
|
/* Remove oldest entry. XXX */
|
||||||
|
e = list_chop(route_table);
|
||||||
|
PRINTF("route_add: removing entry to %d.%d with nexthop %d.%d and cost %d\n",
|
||||||
|
e->dest.u8[0], e->dest.u8[1],
|
||||||
|
e->nexthop.u8[0], e->nexthop.u8[1],
|
||||||
|
e->cost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rimeaddr_copy(&e->dest, dest);
|
rimeaddr_copy(&e->dest, dest);
|
||||||
rimeaddr_copy(&e->nexthop, nexthop);
|
rimeaddr_copy(&e->nexthop, nexthop);
|
||||||
e->hop_count = hop_count;
|
e->cost = cost;
|
||||||
e->seqno = seqno;
|
e->seqno = seqno;
|
||||||
e->time = 0;
|
e->time = 0;
|
||||||
|
e->decay = 0;
|
||||||
|
|
||||||
/* New entry goes first. */
|
/* New entry goes first. */
|
||||||
list_push(route_table, e);
|
list_push(route_table, e);
|
||||||
|
|
||||||
|
PRINTF("route_add: new entry to %d.%d with nexthop %d.%d and cost %d\n",
|
||||||
|
e->dest.u8[0], e->dest.u8[1],
|
||||||
|
e->nexthop.u8[0], e->nexthop.u8[1],
|
||||||
|
e->cost);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -129,16 +163,25 @@ struct route_entry *
|
||||||
route_lookup(const rimeaddr_t *dest)
|
route_lookup(const rimeaddr_t *dest)
|
||||||
{
|
{
|
||||||
struct route_entry *e;
|
struct route_entry *e;
|
||||||
|
uint8_t lowest_cost;
|
||||||
|
struct route_entry *best_entry;
|
||||||
|
|
||||||
|
lowest_cost = -1;
|
||||||
|
best_entry = NULL;
|
||||||
|
|
||||||
|
/* Find the route with the lowest cost. */
|
||||||
for(e = list_head(route_table); e != NULL; e = e->next) {
|
for(e = list_head(route_table); e != NULL; e = e->next) {
|
||||||
/* printf("route_lookup: comparing %d.%d.%d.%d with %d.%d.%d.%d\n",
|
/* printf("route_lookup: comparing %d.%d.%d.%d with %d.%d.%d.%d\n",
|
||||||
uip_ipaddr_to_quad(dest), uip_ipaddr_to_quad(&e->dest));*/
|
uip_ipaddr_to_quad(dest), uip_ipaddr_to_quad(&e->dest));*/
|
||||||
|
|
||||||
if(rimeaddr_cmp(dest, &e->dest)) {
|
if(rimeaddr_cmp(dest, &e->dest)) {
|
||||||
return e;
|
if(e->cost < lowest_cost) {
|
||||||
|
best_entry = e;
|
||||||
|
lowest_cost = e->cost;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return best_entry;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -148,6 +191,34 @@ route_refresh(struct route_entry *e)
|
||||||
/* Refresh age of route so that used routes do not get thrown
|
/* Refresh age of route so that used routes do not get thrown
|
||||||
out. */
|
out. */
|
||||||
e->time = 0;
|
e->time = 0;
|
||||||
|
e->decay = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
route_decay(struct route_entry *e)
|
||||||
|
{
|
||||||
|
/* If routes are not refreshed, they decay over time. This function
|
||||||
|
is called to decay a route. The route can only be decayed once
|
||||||
|
per second. */
|
||||||
|
PRINTF("route_decay: time %d last %d decay %d for entry to %d.%d with nexthop %d.%d and cost %d\n",
|
||||||
|
e->time, e->time_last_decay, e->decay,
|
||||||
|
e->dest.u8[0], e->dest.u8[1],
|
||||||
|
e->nexthop.u8[0], e->nexthop.u8[1],
|
||||||
|
e->cost);
|
||||||
|
|
||||||
|
if(e->time != e->time_last_decay) {
|
||||||
|
/* Do not decay a route too often - not more than once per second. */
|
||||||
|
e->time_last_decay = e->time;
|
||||||
|
e->decay++;
|
||||||
|
|
||||||
|
if(e->decay >= DECAY_THRESHOLD) {
|
||||||
|
PRINTF("route_decay: removing entry to %d.%d with nexthop %d.%d and cost %d\n",
|
||||||
|
e->dest.u8[0], e->dest.u8[1],
|
||||||
|
e->nexthop.u8[0], e->nexthop.u8[1],
|
||||||
|
e->cost);
|
||||||
|
route_remove(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of the Contiki operating system.
|
* This file is part of the Contiki operating system.
|
||||||
*
|
*
|
||||||
* $Id: route.h,v 1.10 2009/05/04 11:23:30 adamdunkels Exp $
|
* $Id: route.h,v 1.11 2009/05/10 21:08:01 adamdunkels Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,13 +59,16 @@ struct route_entry {
|
||||||
rimeaddr_t dest;
|
rimeaddr_t dest;
|
||||||
rimeaddr_t nexthop;
|
rimeaddr_t nexthop;
|
||||||
uint8_t seqno;
|
uint8_t seqno;
|
||||||
uint8_t hop_count;
|
uint8_t cost;
|
||||||
uint8_t time;
|
uint8_t time;
|
||||||
|
|
||||||
|
uint8_t decay;
|
||||||
|
uint8_t time_last_decay;
|
||||||
};
|
};
|
||||||
|
|
||||||
void route_init(void);
|
void route_init(void);
|
||||||
int route_add(const rimeaddr_t *dest, const rimeaddr_t *nexthop,
|
int route_add(const rimeaddr_t *dest, const rimeaddr_t *nexthop,
|
||||||
uint8_t hop_count, uint8_t seqno);
|
uint8_t cost, uint8_t seqno);
|
||||||
struct route_entry *route_lookup(const rimeaddr_t *dest);
|
struct route_entry *route_lookup(const rimeaddr_t *dest);
|
||||||
void route_refresh(struct route_entry *e);
|
void route_refresh(struct route_entry *e);
|
||||||
void route_remove(struct route_entry *e);
|
void route_remove(struct route_entry *e);
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of the Contiki operating system.
|
* This file is part of the Contiki operating system.
|
||||||
*
|
*
|
||||||
* $Id: uip-over-mesh.c,v 1.13 2009/05/04 11:24:04 adamdunkels Exp $
|
* $Id: uip-over-mesh.c,v 1.14 2009/05/10 21:08:01 adamdunkels Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,11 +81,19 @@ static void
|
||||||
recv_data(struct unicast_conn *c, rimeaddr_t *from)
|
recv_data(struct unicast_conn *c, rimeaddr_t *from)
|
||||||
{
|
{
|
||||||
struct route_entry *e;
|
struct route_entry *e;
|
||||||
|
rimeaddr_t source;
|
||||||
|
|
||||||
|
uip_len = packetbuf_copyto(&uip_buf[UIP_LLH_LEN]);
|
||||||
|
|
||||||
|
source.u8[0] = BUF->srcipaddr.u8[2];
|
||||||
|
source.u8[1] = BUF->srcipaddr.u8[3];
|
||||||
|
|
||||||
e = route_lookup(from);
|
e = route_lookup(from);
|
||||||
route_refresh(e);
|
if(e == NULL) {
|
||||||
|
route_add(&source, from, 10, 0);
|
||||||
uip_len = packetbuf_copyto(&uip_buf[UIP_LLH_LEN]);
|
} else {
|
||||||
|
route_refresh(e);
|
||||||
|
}
|
||||||
|
|
||||||
/* uip_len = hc_inflate(&uip_buf[UIP_LLH_LEN], uip_len);*/
|
/* uip_len = hc_inflate(&uip_buf[UIP_LLH_LEN], uip_len);*/
|
||||||
|
|
||||||
|
@ -117,6 +125,7 @@ new_route(struct route_discovery_conn *c, rimeaddr_t *to)
|
||||||
|
|
||||||
rt = route_lookup(&queued_receiver);
|
rt = route_lookup(&queued_receiver);
|
||||||
if(rt) {
|
if(rt) {
|
||||||
|
route_decay(rt);
|
||||||
send_data(&queued_receiver);
|
send_data(&queued_receiver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,7 +188,7 @@ void
|
||||||
uip_over_mesh_init(u16_t channels)
|
uip_over_mesh_init(u16_t channels)
|
||||||
{
|
{
|
||||||
|
|
||||||
printf("Our address is %d.%d (%d.%d.%d.%d)\n",
|
PRINTF("Our address is %d.%d (%d.%d.%d.%d)\n",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
||||||
uip_hostaddr.u8[0], uip_hostaddr.u8[1],
|
uip_hostaddr.u8[0], uip_hostaddr.u8[1],
|
||||||
uip_hostaddr.u8[2], uip_hostaddr.u8[3]);
|
uip_hostaddr.u8[2], uip_hostaddr.u8[3]);
|
||||||
|
@ -191,7 +200,7 @@ uip_over_mesh_init(u16_t channels)
|
||||||
&trickle_call);
|
&trickle_call);
|
||||||
|
|
||||||
/* Set lifetime to 10 seconds for non-refreshed routes. */
|
/* Set lifetime to 10 seconds for non-refreshed routes. */
|
||||||
route_set_lifetime(10);
|
route_set_lifetime(30);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
u8_t
|
u8_t
|
||||||
|
@ -257,6 +266,7 @@ uip_over_mesh_send(void)
|
||||||
route_discovery_discover(&route_discovery, &receiver, ROUTE_TIMEOUT);
|
route_discovery_discover(&route_discovery, &receiver, ROUTE_TIMEOUT);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
route_decay(rt);
|
||||||
send_data(&rt->nexthop);
|
send_data(&rt->nexthop);
|
||||||
}
|
}
|
||||||
return UIP_FW_OK;
|
return UIP_FW_OK;
|
||||||
|
|
Loading…
Reference in a new issue