Commit a75fd3e6 authored by Baptiste Jonglez's avatar Baptiste Jonglez

Add a cost to neighbours, computed from the RTT

parent b295f15f
...@@ -79,6 +79,9 @@ add_interface(char *ifname, struct interface_conf *if_conf) ...@@ -79,6 +79,9 @@ add_interface(char *ifname, struct interface_conf *if_conf)
ifp->bucket_time = now.tv_sec; ifp->bucket_time = now.tv_sec;
ifp->bucket = BUCKET_TOKENS_MAX; ifp->bucket = BUCKET_TOKENS_MAX;
ifp->hello_seqno = (random() & 0xFFFF); ifp->hello_seqno = (random() & 0xFFFF);
ifp->rtt_min = 10000;
ifp->rtt_max = 120000;
ifp->max_rtt_penalty = 150;
if(interfaces == NULL) if(interfaces == NULL)
interfaces = ifp; interfaces = ifp;
......
...@@ -91,6 +91,10 @@ struct interface { ...@@ -91,6 +91,10 @@ struct interface {
unsigned short hello_seqno; unsigned short hello_seqno;
unsigned hello_interval; unsigned hello_interval;
unsigned update_interval; unsigned update_interval;
/* Parameters for computing the cost associated to RTT. */
unsigned int rtt_min;
unsigned int rtt_max;
unsigned int max_rtt_penalty;
}; };
#define IF_CONF(_ifp, _field) \ #define IF_CONF(_ifp, _field) \
......
...@@ -297,10 +297,29 @@ neighbour_rxcost(struct neighbour *neigh) ...@@ -297,10 +297,29 @@ neighbour_rxcost(struct neighbour *neigh)
} }
} }
unsigned
neighbour_rttcost(struct neighbour *neigh)
{
struct interface *ifp = neigh->ifp;
if(!ifp->max_rtt_penalty || !valid_rtt(neigh))
return 0;
/* Function: linear behaviour between rtt_min and rtt_max. */
if(neigh->rtt <= ifp->rtt_min) {
return 0;
} else if(neigh->rtt <= ifp->rtt_max) {
return (ifp->max_rtt_penalty * (neigh->rtt - ifp->rtt_min) /
(ifp->rtt_max - ifp->rtt_min));
} else {
return ifp->max_rtt_penalty;
}
}
unsigned unsigned
neighbour_cost(struct neighbour *neigh) neighbour_cost(struct neighbour *neigh)
{ {
unsigned a, b; unsigned a, b, cost;
if(!if_up(neigh->ifp)) if(!if_up(neigh->ifp))
return INFINITY; return INFINITY;
...@@ -315,7 +334,7 @@ neighbour_cost(struct neighbour *neigh) ...@@ -315,7 +334,7 @@ neighbour_cost(struct neighbour *neigh)
return INFINITY; return INFINITY;
if(!(neigh->ifp->flags & IF_LQ) || (a < 256 && b < 256)) { if(!(neigh->ifp->flags & IF_LQ) || (a < 256 && b < 256)) {
return a; cost = a;
} else { } else {
/* a = 256/alpha, b = 256/beta, where alpha and beta are the expected /* a = 256/alpha, b = 256/beta, where alpha and beta are the expected
probabilities of a packet getting through in the direct and reverse probabilities of a packet getting through in the direct and reverse
...@@ -324,8 +343,12 @@ neighbour_cost(struct neighbour *neigh) ...@@ -324,8 +343,12 @@ neighbour_cost(struct neighbour *neigh)
b = MAX(b, 256); b = MAX(b, 256);
/* 1/(alpha * beta), which is just plain ETX. */ /* 1/(alpha * beta), which is just plain ETX. */
/* Since a and b are capped to 16 bits, overflow is impossible. */ /* Since a and b are capped to 16 bits, overflow is impossible. */
return MIN((a * b + 128) >> 8, INFINITY); cost = (a * b + 128) >> 8;
} }
cost += neighbour_rttcost(neigh);
return MIN(cost, INFINITY);
} }
int int
......
...@@ -54,5 +54,6 @@ int update_neighbour(struct neighbour *neigh, int hello, int hello_interval); ...@@ -54,5 +54,6 @@ int update_neighbour(struct neighbour *neigh, int hello, int hello_interval);
unsigned check_neighbours(void); unsigned check_neighbours(void);
unsigned neighbour_txcost(struct neighbour *neigh); unsigned neighbour_txcost(struct neighbour *neigh);
unsigned neighbour_rxcost(struct neighbour *neigh); unsigned neighbour_rxcost(struct neighbour *neigh);
unsigned neighbour_rttcost(struct neighbour *neigh);
unsigned neighbour_cost(struct neighbour *neigh); unsigned neighbour_cost(struct neighbour *neigh);
int valid_rtt(struct neighbour *neigh); int valid_rtt(struct neighbour *neigh);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment