mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
sys/nhdp: Add link metric calculation
This commit is contained in:
parent
41aad42d8f
commit
5fbafbf8ad
@ -24,11 +24,13 @@
|
||||
#include "utlist.h"
|
||||
#include "kernel_types.h"
|
||||
|
||||
#include "rfc5444/rfc5444.h"
|
||||
#include "rfc5444/rfc5444_iana.h"
|
||||
#include "rfc5444/rfc5444_writer.h"
|
||||
|
||||
#include "iib_table.h"
|
||||
#include "nhdp_address.h"
|
||||
#include "nhdp_metric.h"
|
||||
#include "nhdp_writer.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
@ -38,6 +40,10 @@
|
||||
static mutex_t mtx_iib_access = MUTEX_INIT;
|
||||
static iib_base_entry_t *iib_base_entry_head = NULL;
|
||||
|
||||
#if (NHDP_METRIC == NHDP_LMT_DAT)
|
||||
static const double const_dat = (((double)DAT_CONSTANT) / DAT_MAXIMUM_LOSS);
|
||||
#endif
|
||||
|
||||
/* Internal function prototypes */
|
||||
static void rem_link_set_entry(iib_base_entry_t *base_entry, iib_link_set_entry_t *ls_entry);
|
||||
static void cleanup_link_sets(void);
|
||||
@ -64,6 +70,11 @@ static void rem_not_heard_nb_tuple(iib_link_set_entry_t *ls_entry, timex_t *now)
|
||||
static inline timex_t get_max_timex(timex_t time_one, timex_t time_two);
|
||||
static iib_link_tuple_status_t get_tuple_status(iib_link_set_entry_t *ls_entry, timex_t *now);
|
||||
|
||||
#if (NHDP_METRIC == NHDP_LMT_DAT)
|
||||
static void queue_rem(uint8_t *queue);
|
||||
static uint16_t queue_sum(uint8_t *queue);
|
||||
static void dat_metric_refresh(void);
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Interface Information Base API *
|
||||
@ -86,10 +97,12 @@ int iib_register_if(kernel_pid_t pid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iib_process_hello(kernel_pid_t if_pid, nib_entry_t *nb_elt,
|
||||
uint64_t validity_time, uint8_t is_sym_nb, uint8_t is_lost)
|
||||
iib_link_set_entry_t *iib_process_hello(kernel_pid_t if_pid, nib_entry_t *nb_elt,
|
||||
uint64_t validity_time, uint8_t is_sym_nb,
|
||||
uint8_t is_lost)
|
||||
{
|
||||
iib_base_entry_t *base_elt;
|
||||
iib_link_set_entry_t *ls_entry = NULL;
|
||||
timex_t now;
|
||||
|
||||
mutex_lock(&mtx_iib_access);
|
||||
@ -108,8 +121,7 @@ int iib_process_hello(kernel_pid_t if_pid, nib_entry_t *nb_elt,
|
||||
vtimer_now(&now);
|
||||
|
||||
/* Create a new link tuple for the neighbor that originated the hello */
|
||||
iib_link_set_entry_t *ls_entry = update_link_set(base_elt, nb_elt, &now,
|
||||
validity_time, is_sym_nb, is_lost);
|
||||
ls_entry = update_link_set(base_elt, nb_elt, &now, validity_time, is_sym_nb, is_lost);
|
||||
|
||||
/* Create new two hop tuples for signaled symmetric neighbors */
|
||||
if (ls_entry) {
|
||||
@ -119,7 +131,7 @@ int iib_process_hello(kernel_pid_t if_pid, nib_entry_t *nb_elt,
|
||||
|
||||
mutex_unlock(&mtx_iib_access);
|
||||
|
||||
return 0;
|
||||
return ls_entry;
|
||||
}
|
||||
|
||||
void iib_fill_wr_addresses(kernel_pid_t if_pid, struct rfc5444_writer *wr)
|
||||
@ -149,14 +161,18 @@ void iib_fill_wr_addresses(kernel_pid_t if_pid, struct rfc5444_writer *wr)
|
||||
case IIB_LT_STATUS_SYM:
|
||||
nhdp_writer_add_addr(wr, addr_elt->address,
|
||||
RFC5444_ADDRTLV_LINK_STATUS,
|
||||
RFC5444_LINKSTATUS_SYMMETRIC);
|
||||
RFC5444_LINKSTATUS_SYMMETRIC,
|
||||
rfc5444_metric_encode(ls_elt->metric_in),
|
||||
rfc5444_metric_encode(ls_elt->metric_out));
|
||||
addr_elt->address->in_tmp_table = NHDP_ADDR_TMP_SYM;
|
||||
break;
|
||||
|
||||
case IIB_LT_STATUS_HEARD:
|
||||
nhdp_writer_add_addr(wr, addr_elt->address,
|
||||
RFC5444_ADDRTLV_LINK_STATUS,
|
||||
RFC5444_LINKSTATUS_HEARD);
|
||||
RFC5444_LINKSTATUS_HEARD,
|
||||
rfc5444_metric_encode(ls_elt->metric_in),
|
||||
rfc5444_metric_encode(ls_elt->metric_out));
|
||||
addr_elt->address->in_tmp_table = NHDP_ADDR_TMP_ANY;
|
||||
break;
|
||||
|
||||
@ -166,7 +182,9 @@ void iib_fill_wr_addresses(kernel_pid_t if_pid, struct rfc5444_writer *wr)
|
||||
case IIB_LT_STATUS_LOST:
|
||||
nhdp_writer_add_addr(wr, addr_elt->address,
|
||||
RFC5444_ADDRTLV_LINK_STATUS,
|
||||
RFC5444_LINKSTATUS_LOST);
|
||||
RFC5444_LINKSTATUS_LOST,
|
||||
rfc5444_metric_encode(ls_elt->metric_in),
|
||||
rfc5444_metric_encode(ls_elt->metric_out));
|
||||
addr_elt->address->in_tmp_table = NHDP_ADDR_TMP_ANY;
|
||||
break;
|
||||
|
||||
@ -216,6 +234,120 @@ void iib_propagate_nb_entry_change(nib_entry_t *old_entry, nib_entry_t *new_entr
|
||||
}
|
||||
}
|
||||
|
||||
void iib_process_metric_msg(iib_link_set_entry_t *ls_entry, uint64_t int_time)
|
||||
{
|
||||
#if (NHDP_METRIC == NHDP_LMT_HOP_COUNT)
|
||||
/* Hop metric value for an existing direct link is always 1 */
|
||||
(void)int_time;
|
||||
ls_entry->metric_in = 1;
|
||||
ls_entry->metric_out = 1;
|
||||
if (ls_entry->nb_elt) {
|
||||
ls_entry->nb_elt->metric_in = 1;
|
||||
ls_entry->nb_elt->metric_out = 1;
|
||||
}
|
||||
#elif (NHDP_METRIC == NHDP_LMT_DAT)
|
||||
/* Process required DAT metric steps */
|
||||
ls_entry->hello_interval = rfc5444_timetlv_encode(int_time);
|
||||
if (ls_entry->last_seq_no == 0) {
|
||||
timex_t now, i_time;
|
||||
vtimer_now(&now);
|
||||
i_time = timex_from_uint64(int_time * MS_IN_USEC * DAT_HELLO_TIMEOUT_FACTOR);
|
||||
ls_entry->dat_received[0]++;
|
||||
ls_entry->dat_total[0]++;
|
||||
ls_entry->dat_time = timex_add(now, i_time);
|
||||
}
|
||||
#else
|
||||
/* NHDP_METRIC is not set properly */
|
||||
(void)ls_entry;
|
||||
(void)int_time;
|
||||
DEBUGF("[WARNING] Unknown NHDP_METRIC setting\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void iib_process_metric_pckt(iib_link_set_entry_t *ls_entry, uint32_t metric_out, uint16_t seq_no)
|
||||
{
|
||||
#if (NHDP_METRIC == NHDP_LMT_HOP_COUNT)
|
||||
/* Nothing to do here */
|
||||
(void)ls_entry;
|
||||
(void)metric_out;
|
||||
(void)seq_no;
|
||||
#elif (NHDP_METRIC == NHDP_LMT_DAT)
|
||||
/* Metric packet processing */
|
||||
if (ls_entry->last_seq_no == 0) {
|
||||
ls_entry->dat_received[0] = 1;
|
||||
ls_entry->dat_total[0] = 1;
|
||||
}
|
||||
/* Don't add values to the queue for duplicate packets */
|
||||
else if (seq_no != ls_entry->last_seq_no) {
|
||||
uint16_t seq_diff;
|
||||
if (seq_no < ls_entry->last_seq_no) {
|
||||
seq_diff = (uint16_t) ((((uint32_t) seq_no) + 0xFFFF) - ls_entry->last_seq_no);
|
||||
}
|
||||
else {
|
||||
seq_diff = seq_no - ls_entry->last_seq_no;
|
||||
}
|
||||
ls_entry->dat_total[0] += (seq_diff > NHDP_SEQNO_RESTART_DETECT) ? 1 : seq_diff;
|
||||
ls_entry->dat_received[0]++;
|
||||
}
|
||||
|
||||
ls_entry->last_seq_no = seq_no;
|
||||
ls_entry->lost_hellos = 0;
|
||||
|
||||
if (ls_entry->hello_interval != 0) {
|
||||
timex_t now, i_time;
|
||||
vtimer_now(&now);
|
||||
i_time = timex_from_uint64(rfc5444_timetlv_decode(ls_entry->hello_interval)
|
||||
* MS_IN_USEC * DAT_HELLO_TIMEOUT_FACTOR);
|
||||
ls_entry->dat_time = timex_add(now, i_time);
|
||||
}
|
||||
|
||||
/* Refresh metric value for link tuple and corresponding neighbor tuple */
|
||||
if (ls_entry->nb_elt) {
|
||||
if ((metric_out <= ls_entry->nb_elt->metric_out) ||
|
||||
(ls_entry->nb_elt->metric_out == NHDP_METRIC_UNKNOWN)) {
|
||||
/* Better value, use it also for your neighbor */
|
||||
ls_entry->nb_elt->metric_out = metric_out;
|
||||
}
|
||||
else if (ls_entry->metric_out == ls_entry->nb_elt->metric_out){
|
||||
/* The corresponding neighbor tuples metric needs to be updated */
|
||||
iib_base_entry_t *base_elt;
|
||||
iib_link_set_entry_t *ls_elt;
|
||||
ls_entry->nb_elt->metric_out = metric_out;
|
||||
LL_FOREACH(iib_base_entry_head, base_elt) {
|
||||
LL_FOREACH(base_elt->link_set_head, ls_elt) {
|
||||
if ((ls_elt->nb_elt == ls_entry->nb_elt) && (ls_elt != ls_entry)) {
|
||||
if (ls_elt->metric_out < ls_entry->nb_elt->metric_out) {
|
||||
/* Smaller DAT value is better */
|
||||
ls_entry->nb_elt->metric_out = ls_elt->metric_out;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ls_entry->metric_out = metric_out;
|
||||
#else
|
||||
/* NHDP_METRIC is not set properly */
|
||||
(void)ls_entry;
|
||||
(void)metric_out;
|
||||
(void)seq_no;
|
||||
DEBUGF("[WARNING] Unknown NHDP_METRIC setting\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void iib_process_metric_refresh(void)
|
||||
{
|
||||
#if (NHDP_METRIC == NHDP_LMT_HOP_COUNT)
|
||||
/* Nothing to do here */
|
||||
#elif (NHDP_METRIC == NHDP_LMT_DAT)
|
||||
dat_metric_refresh();
|
||||
#else
|
||||
/* NHDP_METRIC is not set properly */
|
||||
DEBUGF("[WARNING] Unknown NHDP_METRIC setting\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
/* Internal functions */
|
||||
@ -427,7 +559,6 @@ static iib_link_set_entry_t *add_default_link_set_entry(iib_base_entry_t *base_e
|
||||
uint64_t val_time)
|
||||
{
|
||||
iib_link_set_entry_t *new_entry;
|
||||
timex_t v_time = timex_from_uint64(val_time * MS_IN_USEC);
|
||||
|
||||
new_entry = (iib_link_set_entry_t *) malloc(sizeof(iib_link_set_entry_t));
|
||||
|
||||
@ -437,15 +568,7 @@ static iib_link_set_entry_t *add_default_link_set_entry(iib_base_entry_t *base_e
|
||||
}
|
||||
|
||||
new_entry->address_list_head = NULL;
|
||||
new_entry->heard_time.microseconds = 0;
|
||||
new_entry->heard_time.seconds = 0;
|
||||
new_entry->sym_time.microseconds = 0;
|
||||
new_entry->sym_time.seconds = 0;
|
||||
new_entry->pending = NHDP_INITIAL_PENDING;
|
||||
new_entry->lost = 0;
|
||||
new_entry->exp_time = timex_add(*now, v_time);
|
||||
new_entry->last_status = IIB_LT_STATUS_UNKNOWN;
|
||||
new_entry->nb_elt = NULL;
|
||||
reset_link_set_entry(new_entry, now, val_time);
|
||||
LL_PREPEND(base_entry->link_set_head, new_entry);
|
||||
|
||||
return new_entry;
|
||||
@ -468,6 +591,18 @@ static void reset_link_set_entry(iib_link_set_entry_t *ls_entry, timex_t *now, u
|
||||
ls_entry->exp_time = timex_add(*now, v_time);
|
||||
ls_entry->nb_elt = NULL;
|
||||
ls_entry->last_status = IIB_LT_STATUS_UNKNOWN;
|
||||
ls_entry->metric_in = NHDP_METRIC_UNKNOWN;
|
||||
ls_entry->metric_out = NHDP_METRIC_UNKNOWN;
|
||||
#if (NHDP_METRIC == NHDP_LMT_DAT)
|
||||
memset(ls_entry->dat_received, 0, NHDP_Q_MEM_LENGTH);
|
||||
memset(ls_entry->dat_total, 0, NHDP_Q_MEM_LENGTH);
|
||||
ls_entry->dat_time.microseconds = 0;
|
||||
ls_entry->dat_time.seconds = 0;
|
||||
ls_entry->hello_interval = 0;
|
||||
ls_entry->lost_hellos = 0;
|
||||
ls_entry->rx_bitrate = 100000;
|
||||
ls_entry->last_seq_no = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -554,6 +689,15 @@ static int add_two_hop_entry(iib_base_entry_t *base_entry, iib_link_set_entry_t
|
||||
new_entry->th_nb_addr = th_addr;
|
||||
new_entry->ls_elt = ls_entry;
|
||||
new_entry->exp_time = timex_add(*now, v_time);
|
||||
if (th_addr->tmp_metric_val != NHDP_METRIC_UNKNOWN) {
|
||||
new_entry->metric_in = rfc5444_metric_decode(th_addr->tmp_metric_val);
|
||||
new_entry->metric_out = rfc5444_metric_decode(th_addr->tmp_metric_val);
|
||||
}
|
||||
else {
|
||||
new_entry->metric_in = NHDP_METRIC_UNKNOWN;
|
||||
new_entry->metric_out = NHDP_METRIC_UNKNOWN;
|
||||
}
|
||||
|
||||
LL_PREPEND(base_entry->two_hop_set_head, new_entry);
|
||||
|
||||
return 0;
|
||||
@ -665,3 +809,111 @@ static inline timex_t get_max_timex(timex_t time_one, timex_t time_two)
|
||||
|
||||
return time_two;
|
||||
}
|
||||
|
||||
#if (NHDP_METRIC == NHDP_LMT_DAT)
|
||||
/**
|
||||
* Sum all elements in the queue
|
||||
*/
|
||||
static uint16_t queue_sum(uint8_t *queue)
|
||||
{
|
||||
uint16_t sum = 0;
|
||||
|
||||
for (int i = 0; i < NHDP_Q_MEM_LENGTH; i++) {
|
||||
sum += queue[i];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the oldest element in the queue
|
||||
*/
|
||||
static void queue_rem(uint8_t *queue)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t prev_value = queue[0];
|
||||
|
||||
/* Clear spot for a new element */
|
||||
queue[0] = 0;
|
||||
|
||||
/* Shift elements */
|
||||
for (int i = 1; i < NHDP_Q_MEM_LENGTH; i++) {
|
||||
temp = queue[i];
|
||||
queue[i] = prev_value;
|
||||
prev_value = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update DAT metric values for all Link Tuples
|
||||
*/
|
||||
static void dat_metric_refresh(void)
|
||||
{
|
||||
iib_base_entry_t *base_elt;
|
||||
iib_link_set_entry_t *ls_elt;
|
||||
uint32_t metric_temp;
|
||||
double sum_total, sum_rcvd, loss;
|
||||
|
||||
LL_FOREACH(iib_base_entry_head, base_elt) {
|
||||
LL_FOREACH(base_elt->link_set_head, ls_elt) {
|
||||
sum_rcvd = queue_sum(ls_elt->dat_received);
|
||||
sum_total = queue_sum(ls_elt->dat_total);
|
||||
metric_temp = ls_elt->metric_in;
|
||||
|
||||
if ((ls_elt->hello_interval != 0) && (ls_elt->lost_hellos > 0)) {
|
||||
/* Compute lost time proportion */
|
||||
loss = (((double)ls_elt->hello_interval) * ((double)ls_elt->lost_hellos))
|
||||
/ DAT_MEMORY_LENGTH;
|
||||
if (loss >= 1.0) {
|
||||
sum_rcvd = 0.0;
|
||||
}
|
||||
else {
|
||||
sum_rcvd *= (1.0 - loss);
|
||||
}
|
||||
}
|
||||
|
||||
if (sum_rcvd < 1.0) {
|
||||
ls_elt->metric_in = NHDP_METRIC_MAXIMUM;
|
||||
}
|
||||
else {
|
||||
loss = sum_total / sum_rcvd;
|
||||
if (loss > DAT_MAXIMUM_LOSS) {
|
||||
loss = DAT_MAXIMUM_LOSS;
|
||||
}
|
||||
ls_elt->metric_in = (const_dat * loss) / (ls_elt->rx_bitrate / DAT_MINIMUM_BITRATE);
|
||||
if (ls_elt->metric_in > NHDP_METRIC_MAXIMUM) {
|
||||
ls_elt->metric_in = NHDP_METRIC_MAXIMUM;
|
||||
}
|
||||
}
|
||||
|
||||
if (ls_elt->nb_elt) {
|
||||
if (ls_elt->metric_in <= ls_elt->nb_elt->metric_in ||
|
||||
(ls_elt->nb_elt->metric_in == NHDP_METRIC_UNKNOWN)) {
|
||||
/* Better value, use it also for your neighbor */
|
||||
ls_elt->nb_elt->metric_in = ls_elt->metric_in;
|
||||
}
|
||||
else if (metric_temp == ls_elt->nb_elt->metric_in){
|
||||
/* The corresponding neighbor tuples metric needs to be updated */
|
||||
iib_base_entry_t *base_entry;
|
||||
iib_link_set_entry_t *ls_entry;
|
||||
ls_elt->nb_elt->metric_in = ls_elt->metric_in;
|
||||
LL_FOREACH(iib_base_entry_head, base_entry) {
|
||||
LL_FOREACH(base_entry->link_set_head, ls_entry) {
|
||||
if ((ls_elt->nb_elt == ls_entry->nb_elt) && (ls_elt != ls_entry)) {
|
||||
if (ls_entry->metric_in < ls_elt->nb_elt->metric_in) {
|
||||
/* Smaller DAT value is better */
|
||||
ls_elt->nb_elt->metric_in = ls_entry->metric_in;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
queue_rem(ls_elt->dat_received);
|
||||
queue_rem(ls_elt->dat_total);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "nib_table.h"
|
||||
#include "nhdp_address.h"
|
||||
#include "nhdp_metric.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -52,6 +53,17 @@ typedef struct iib_link_set_entry_t {
|
||||
timex_t exp_time; /**< Time at which entry expires */
|
||||
nib_entry_t *nb_elt; /**< Pointer to corresponding nb tuple */
|
||||
enum iib_link_tuple_status_t last_status; /**< Last processed status of link tuple */
|
||||
uint32_t metric_in; /**< Metric value for incoming link */
|
||||
uint32_t metric_out; /**< Metric value for outgoing link */
|
||||
#if (NHDP_METRIC == NHDP_LMT_DAT)
|
||||
uint8_t dat_received[NHDP_Q_MEM_LENGTH]; /**< Queue for containing sums of rcvd packets */
|
||||
uint8_t dat_total[NHDP_Q_MEM_LENGTH]; /**< Queue for containing sums of xpctd packets */
|
||||
timex_t dat_time; /**< Time next HELLO is expected */
|
||||
uint8_t hello_interval; /**< Encoded HELLO interval value */
|
||||
uint8_t lost_hellos; /**< Lost HELLO count after last received HELLO */
|
||||
uint32_t rx_bitrate; /**< Incoming Bitrate for this link in Bit/s */
|
||||
uint16_t last_seq_no; /**< The last received packet sequence number */
|
||||
#endif
|
||||
struct iib_link_set_entry_t *next; /**< Pointer to next list entry */
|
||||
} iib_link_set_entry_t;
|
||||
|
||||
@ -62,6 +74,8 @@ typedef struct iib_two_hop_set_entry_t {
|
||||
struct iib_link_set_entry_t *ls_elt; /**< Pointer to corresponding link tuple */
|
||||
nhdp_addr_t *th_nb_addr; /**< Address of symmetric 2-hop neighbor */
|
||||
timex_t exp_time; /**< Time at which entry expires */
|
||||
uint32_t metric_in; /**< Metric value for incoming link */
|
||||
uint32_t metric_out; /**< Metric value for outgoing link */
|
||||
struct iib_two_hop_set_entry_t *next; /**< Pointer to next list entry */
|
||||
} iib_two_hop_set_entry_t;
|
||||
|
||||
@ -100,10 +114,12 @@ int iib_register_if(kernel_pid_t pid);
|
||||
* @param[in] is_sym_nb Flag whether the link to the originator is symmetric
|
||||
* @param[in] is_lost Flag whether the originator marked this link as lost
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return Pointer to the new or updated Link Tuple
|
||||
* @return NULL on error
|
||||
*/
|
||||
int iib_process_hello(kernel_pid_t if_pid, nib_entry_t *nb_elt,
|
||||
uint64_t validity_time, uint8_t is_sym_nb, uint8_t is_lost);
|
||||
iib_link_set_entry_t *iib_process_hello(kernel_pid_t if_pid, nib_entry_t *nb_elt,
|
||||
uint64_t validity_time, uint8_t is_sym_nb,
|
||||
uint8_t is_lost);
|
||||
|
||||
/**
|
||||
* @brief Add addresses to the currently constructed HELLO message
|
||||
@ -137,6 +153,34 @@ void iib_update_lt_status(timex_t *now);
|
||||
*/
|
||||
void iib_propagate_nb_entry_change(nib_entry_t *old_entry, nib_entry_t *new_entry);
|
||||
|
||||
/**
|
||||
* @brief Process steps for the chosen NHDP metric for a message
|
||||
*
|
||||
* @note
|
||||
* Must not be called from outside the NHDP reader's message processing.
|
||||
*
|
||||
* @param[in] ls_entry Pointer to the Link Tuple that needs to be updated
|
||||
* @param[in] int_time Interval time in milliseconds for the originator's HELLO
|
||||
*/
|
||||
void iib_process_metric_msg(iib_link_set_entry_t *ls_entry, uint64_t int_time);
|
||||
|
||||
/**
|
||||
* @brief Process steps for the chosen NHDP metric for a packet
|
||||
*
|
||||
* @note
|
||||
* Must not be called from outside the NHDP reader's packet processing.
|
||||
*
|
||||
* @param[in] ls_entry Pointer to the Link Tuple that needs to be updated
|
||||
* @param[in] metric_out Metric value for outgoing link direction
|
||||
* @param[in] seq_no The sequence number from the received packet
|
||||
*/
|
||||
void iib_process_metric_pckt(iib_link_set_entry_t *ls_entry, uint32_t metric_out, uint16_t seq_no);
|
||||
|
||||
/**
|
||||
* @brief Update metric values for the chosen NHDP metric for all Link Tuples
|
||||
*/
|
||||
void iib_process_metric_refresh(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -109,7 +109,8 @@ void lib_fill_wr_addresses(kernel_pid_t if_pid, struct rfc5444_writer *wr)
|
||||
if (lib_elt->if_pid == if_pid) {
|
||||
LL_FOREACH(lib_elt->if_addr_list_head, add_tmp) {
|
||||
nhdp_writer_add_addr(wr, add_tmp->address,
|
||||
RFC5444_ADDRTLV_LOCAL_IF, RFC5444_LOCALIF_THIS_IF);
|
||||
RFC5444_ADDRTLV_LOCAL_IF, RFC5444_LOCALIF_THIS_IF,
|
||||
NHDP_METRIC_UNKNOWN, NHDP_METRIC_UNKNOWN);
|
||||
add_tmp->address->in_tmp_table = NHDP_ADDR_TMP_ANY;
|
||||
}
|
||||
break;
|
||||
@ -124,7 +125,8 @@ void lib_fill_wr_addresses(kernel_pid_t if_pid, struct rfc5444_writer *wr)
|
||||
if (!NHDP_ADDR_TMP_IN_ANY(add_tmp->address)) {
|
||||
/* Address can be added */
|
||||
nhdp_writer_add_addr(wr, add_tmp->address,
|
||||
RFC5444_ADDRTLV_LOCAL_IF, RFC5444_LOCALIF_OTHER_IF);
|
||||
RFC5444_ADDRTLV_LOCAL_IF, RFC5444_LOCALIF_OTHER_IF,
|
||||
NHDP_METRIC_UNKNOWN, NHDP_METRIC_UNKNOWN);
|
||||
add_tmp->address->in_tmp_table = NHDP_ADDR_TMP_ANY;
|
||||
}
|
||||
}
|
||||
|
@ -47,6 +47,11 @@ static mutex_t send_rcv_mutex = MUTEX_INIT;
|
||||
static sockaddr6_t sa_bcast;
|
||||
static int sock_rcv;
|
||||
|
||||
#if (NHDP_METRIC_NEEDS_TIMER)
|
||||
static vtimer_t metric_timer;
|
||||
static timex_t metric_interval;
|
||||
#endif
|
||||
|
||||
/* Internal function prototypes */
|
||||
static void *_nhdp_runner(void *arg __attribute__((unused)));
|
||||
static void *_nhdp_receiver(void *arg __attribute__((unused)));
|
||||
@ -90,6 +95,14 @@ kernel_pid_t nhdp_start(void)
|
||||
/* Start the NHDP thread */
|
||||
nhdp_pid = thread_create(nhdp_stack, sizeof(nhdp_stack), THREAD_PRIORITY_MAIN - 1,
|
||||
CREATE_STACKTEST, _nhdp_runner, NULL, "NHDP");
|
||||
|
||||
#if (NHDP_METRIC_NEEDS_TIMER)
|
||||
/* Configure periodic timer message to refresh metric values */
|
||||
if (nhdp_pid != KERNEL_PID_UNDEF) {
|
||||
metric_interval = timex_from_uint64(DAT_REFRESH_INTERVAL * SEC_IN_USEC);
|
||||
vtimer_set_msg(&metric_timer, metric_interval, nhdp_pid, NHDP_METRIC_TIMER, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return nhdp_pid;
|
||||
@ -248,6 +261,18 @@ static void *_nhdp_runner(void *arg)
|
||||
mutex_unlock(&send_rcv_mutex);
|
||||
break;
|
||||
|
||||
#if (NHDP_METRIC_NEEDS_TIMER)
|
||||
case NHDP_METRIC_TIMER:
|
||||
mutex_lock(&send_rcv_mutex);
|
||||
/* Process necessary metric computations */
|
||||
iib_process_metric_refresh();
|
||||
|
||||
/* Schedule next sending */
|
||||
vtimer_set_msg(&metric_timer, metric_interval,
|
||||
thread_getpid(), NHDP_METRIC_TIMER, NULL);
|
||||
mutex_unlock(&send_rcv_mutex);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "kernel_types.h"
|
||||
#include "socket_base/socket.h"
|
||||
|
||||
#include "nhdp_metric.h"
|
||||
#include "rfc5444/rfc5444_writer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -71,6 +71,7 @@ nhdp_addr_t *nhdp_addr_db_get_address(uint8_t *addr, size_t addr_size, uint8_t a
|
||||
addr_elt->addr_type = addr_type;
|
||||
addr_elt->usg_count = 0;
|
||||
addr_elt->in_tmp_table = NHDP_ADDR_TMP_NONE;
|
||||
addr_elt->tmp_metric_val = NHDP_METRIC_UNKNOWN;
|
||||
LL_PREPEND(nhdp_addr_db_head, addr_elt);
|
||||
}
|
||||
|
||||
@ -146,6 +147,7 @@ void nhdp_reset_addresses_tmp_usg(uint8_t decr_usg)
|
||||
nhdp_addr_t *addr_elt, *addr_tmp;
|
||||
|
||||
LL_FOREACH_SAFE(nhdp_addr_db_head, addr_elt, addr_tmp) {
|
||||
addr_elt->tmp_metric_val = NHDP_METRIC_UNKNOWN;
|
||||
if (addr_elt->in_tmp_table) {
|
||||
addr_elt->in_tmp_table = NHDP_ADDR_TMP_NONE;
|
||||
if (decr_usg) {
|
||||
|
@ -32,6 +32,7 @@ typedef struct nhdp_addr_t {
|
||||
uint8_t addr_type; /**< AF type for the address */
|
||||
uint8_t usg_count; /**< Usage count in information bases */
|
||||
uint8_t in_tmp_table; /**< Signals usage in a writers temp table */
|
||||
uint16_t tmp_metric_val; /**< Encoded metric value used during HELLO processing */
|
||||
struct nhdp_addr_t *next; /**< Pointer to next address (used in central storage) */
|
||||
} nhdp_addr_t;
|
||||
|
||||
|
93
sys/net/routing/nhdp/nhdp_metric.h
Normal file
93
sys/net/routing/nhdp/nhdp_metric.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup nhdp
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Macros for NHDP metric computation
|
||||
*
|
||||
* The used infrastructure for exchanging metric values is based on the rules defined in the RFC
|
||||
* of <a href="https://tools.ietf.org/html/rfc7181">OLSRv2</a>. The calculations for the
|
||||
* Directional Airtime Metric (DAT) are based on
|
||||
* <a href="https://tools.ietf.org/html/draft-ietf-manet-olsrv2-dat-metric-05">DAT Draft v5</a>.
|
||||
*
|
||||
* @author Fabian Nack <nack@inf.fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef NHDP_METRIC_H_
|
||||
#define NHDP_METRIC_H_
|
||||
|
||||
#include "rfc5444/rfc5444.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name NHDP protocol macros
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/** @brief Hop Count metric extension value for metric TLV extension field */
|
||||
#define NHDP_LMT_HOP_COUNT (163)
|
||||
/** @brief DAT metric extension value for metric TLV extension field */
|
||||
#define NHDP_LMT_DAT (165)
|
||||
|
||||
/** @brief Used metric (change to switch to another metric type) */
|
||||
#define NHDP_METRIC (NHDP_LMT_HOP_COUNT)
|
||||
|
||||
/** @brief Randomly chosen number for NHDP's metric timer event */
|
||||
#define NHDP_METRIC_TIMER (5445)
|
||||
/** @brief Macro controlling the start of a periodic timer event for matric computation */
|
||||
#define NHDP_METRIC_NEEDS_TIMER (NHDP_METRIC == NHDP_LMT_DAT)
|
||||
|
||||
#define NHDP_METRIC_UNKNOWN (0)
|
||||
#define NHDP_METRIC_MINIMUM (RFC5444_METRIC_MIN)
|
||||
#define NHDP_METRIC_MAXIMUM (RFC5444_METRIC_MAX)
|
||||
|
||||
/** @brief Default queue size for metrics using a queue to determine link loss */
|
||||
#define NHDP_Q_MEM_LENGTH (64)
|
||||
/** @brief Restart detection value for packet sequence number based link loss computation */
|
||||
#define NHDP_SEQNO_RESTART_DETECT (256)
|
||||
|
||||
/** @brief Encoding for an incoming link metric value in metric TLV */
|
||||
#define NHDP_KD_LM_INC (0x8000)
|
||||
/** @brief Encoding for an outgoing link metric value in metric TLV */
|
||||
#define NHDP_KD_LM_OUT (0x4000)
|
||||
/** @brief Encoding for an incoming neighbor metric value in metric TLV */
|
||||
#define NHDP_KD_NM_INC (0x2000)
|
||||
/** @brief Encoding for an outgoing neighbor metric value in metric TLV */
|
||||
#define NHDP_KD_NM_OUT (0x1000)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name DAT metric specific macros
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/** @brief Length of RCVD and TOTAL queue of DAT metric */
|
||||
#define DAT_MEMORY_LENGTH (NHDP_Q_MEM_LENGTH)
|
||||
/** @brief Time between DAT metric refreshal */
|
||||
#define DAT_REFRESH_INTERVAL (1)
|
||||
/** @brief Factor to spread HELLO interval */
|
||||
#define DAT_HELLO_TIMEOUT_FACTOR (1.2)
|
||||
/** @brief Minimal supported bit rate in bps (default value for new links) */
|
||||
#define DAT_MINIMUM_BITRATE (1000)
|
||||
/** @brief Maximum allowed loss in expected/rcvd HELLOs (should not be changed) */
|
||||
#define DAT_MAXIMUM_LOSS (8)
|
||||
/** @brief Constant value needed for DAT metric computation (should not be changed) */
|
||||
#define DAT_CONSTANT (16777216)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NHDP_METRIC_H_ */
|
@ -36,6 +36,9 @@
|
||||
struct rfc5444_reader reader;
|
||||
static mutex_t mtx_packet_handler = MUTEX_INIT;
|
||||
|
||||
static iib_link_set_entry_t *originator_link_tuple = NULL;
|
||||
static uint32_t lt_metric_val = NHDP_METRIC_UNKNOWN;
|
||||
|
||||
static kernel_pid_t if_pid;
|
||||
static uint64_t val_time;
|
||||
static uint64_t int_time;
|
||||
@ -43,6 +46,8 @@ static uint8_t sym = 0;
|
||||
static uint8_t lost = 0;
|
||||
|
||||
/* Internal function prototypes */
|
||||
static enum rfc5444_result _nhdp_pkt_end_cb(struct rfc5444_reader_tlvblock_context *context,
|
||||
bool dropped);
|
||||
static enum rfc5444_result _nhdp_blocktlv_msg_cb(struct rfc5444_reader_tlvblock_context *cont);
|
||||
static enum rfc5444_result _nhdp_blocktlv_address_cb(struct rfc5444_reader_tlvblock_context *cont);
|
||||
static enum rfc5444_result _nhdp_msg_end_cb(struct rfc5444_reader_tlvblock_context *cont,
|
||||
@ -50,6 +55,7 @@ static enum rfc5444_result _nhdp_msg_end_cb(struct rfc5444_reader_tlvblock_conte
|
||||
static enum rfc5444_result check_msg_validity(struct rfc5444_reader_tlvblock_context *cont);
|
||||
static enum rfc5444_result check_addr_validity(nhdp_addr_t *addr);
|
||||
static nhdp_addr_t *get_nhdp_db_addr(uint8_t *addr, uint8_t prefix);
|
||||
static void add_temp_metric_value(nhdp_addr_t *address);
|
||||
static void process_temp_tables(void);
|
||||
|
||||
/* Array containing the processable message TLVs for HELLO messages */
|
||||
@ -63,6 +69,14 @@ static struct rfc5444_reader_tlvblock_consumer_entry _nhdp_addr_tlvs[] = {
|
||||
[RFC5444_ADDRTLV_LOCAL_IF] = { .type = RFC5444_ADDRTLV_LOCAL_IF },
|
||||
[RFC5444_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS },
|
||||
[RFC5444_ADDRTLV_OTHER_NEIGHB] = { .type = RFC5444_ADDRTLV_OTHER_NEIGHB },
|
||||
[RFC5444_ADDRTLV_LINK_METRIC] = { .type = RFC5444_ADDRTLV_LINK_METRIC, .type_ext = NHDP_METRIC,
|
||||
.match_type_ext = true, .min_length = 0x02,
|
||||
.max_length = 0x02, .match_length = true },
|
||||
};
|
||||
|
||||
/* oonf_api packet consumer used for RFC5444 packet consumption */
|
||||
static struct rfc5444_reader_tlvblock_consumer _nhdp_packet_consumer = {
|
||||
.end_callback = _nhdp_pkt_end_cb,
|
||||
};
|
||||
|
||||
/* oonf_api message consumer used for HELLO message consumption */
|
||||
@ -89,6 +103,9 @@ void nhdp_reader_init(void)
|
||||
/* Initialize reader */
|
||||
rfc5444_reader_init(&reader);
|
||||
|
||||
/* Register packet consumer for sequence number processing */
|
||||
rfc5444_reader_add_packet_consumer(&reader, &_nhdp_packet_consumer, NULL, 0);
|
||||
|
||||
/* Register HELLO message consumer */
|
||||
rfc5444_reader_add_message_consumer(&reader, &_nhdp_msg_consumer,
|
||||
_nhdp_msg_tlvs, ARRAYSIZE(_nhdp_msg_tlvs));
|
||||
@ -122,6 +139,25 @@ void nhdp_reader_cleanup(void)
|
||||
/* Internal functions */
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Process metric steps for packet with packet sequence number
|
||||
* Called by oonf_api after the whole packet was processed
|
||||
*/
|
||||
static enum rfc5444_result _nhdp_pkt_end_cb(struct rfc5444_reader_tlvblock_context *context,
|
||||
bool dropped __attribute__((unused)))
|
||||
{
|
||||
/* Process metric changes */
|
||||
if ((originator_link_tuple != NULL) && (context->has_pktseqno)) {
|
||||
iib_process_metric_pckt(originator_link_tuple, lt_metric_val, context->pkt_seqno);
|
||||
}
|
||||
|
||||
/* Reset originator temp fields */
|
||||
originator_link_tuple = NULL;
|
||||
lt_metric_val = NHDP_METRIC_UNKNOWN;
|
||||
|
||||
return RFC5444_OKAY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle one address and its corresponding TLVs
|
||||
* Called by oonf_api for every included address to allow parsing
|
||||
@ -186,12 +222,24 @@ _nhdp_blocktlv_address_cb(struct rfc5444_reader_tlvblock_context *cont)
|
||||
}
|
||||
}
|
||||
|
||||
if (lt_metric_val == NHDP_METRIC_UNKNOWN
|
||||
&& _nhdp_addr_tlvs[RFC5444_ADDRTLV_LINK_METRIC].tlv != NULL) {
|
||||
/* Determine our outgoing link metric value to the originator interface */
|
||||
uint16_t metric_enc = *((uint16_t*)_nhdp_addr_tlvs[RFC5444_ADDRTLV_LINK_METRIC]
|
||||
.tlv->single_value);
|
||||
if (metric_enc & NHDP_KD_LM_INC) {
|
||||
/* Incoming metric value at the neighbor if is outgoing value for our if */
|
||||
lt_metric_val = rfc5444_metric_decode(metric_enc);
|
||||
}
|
||||
}
|
||||
|
||||
/* Address is one of our own addresses, ignore it */
|
||||
nhdp_decrement_addr_usage(current_addr);
|
||||
}
|
||||
else if (_nhdp_addr_tlvs[RFC5444_ADDRTLV_LINK_STATUS].tlv) {
|
||||
switch (*_nhdp_addr_tlvs[RFC5444_ADDRTLV_LINK_STATUS].tlv->single_value) {
|
||||
case RFC5444_LINKSTATUS_SYMMETRIC:
|
||||
add_temp_metric_value(current_addr);
|
||||
current_addr->in_tmp_table = NHDP_ADDR_TMP_TH_SYM_LIST;
|
||||
break;
|
||||
|
||||
@ -203,6 +251,7 @@ _nhdp_blocktlv_address_cb(struct rfc5444_reader_tlvblock_context *cont)
|
||||
&& *_nhdp_addr_tlvs[RFC5444_ADDRTLV_OTHER_NEIGHB].tlv->single_value
|
||||
== RFC5444_OTHERNEIGHB_SYMMETRIC) {
|
||||
/* Symmetric has higher priority */
|
||||
add_temp_metric_value(current_addr);
|
||||
current_addr->in_tmp_table = NHDP_ADDR_TMP_TH_SYM_LIST;
|
||||
}
|
||||
else {
|
||||
@ -220,6 +269,7 @@ _nhdp_blocktlv_address_cb(struct rfc5444_reader_tlvblock_context *cont)
|
||||
else if (_nhdp_addr_tlvs[RFC5444_ADDRTLV_OTHER_NEIGHB].tlv) {
|
||||
switch (*_nhdp_addr_tlvs[RFC5444_ADDRTLV_OTHER_NEIGHB].tlv->single_value) {
|
||||
case RFC5444_OTHERNEIGHB_SYMMETRIC:
|
||||
add_temp_metric_value(current_addr);
|
||||
current_addr->in_tmp_table = NHDP_ADDR_TMP_TH_SYM_LIST;
|
||||
break;
|
||||
|
||||
@ -384,6 +434,20 @@ static nhdp_addr_t *get_nhdp_db_addr(uint8_t *addr, uint8_t prefix)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a metric value to the address if a corresponding TLV exists in the message
|
||||
*/
|
||||
static void add_temp_metric_value(nhdp_addr_t *address)
|
||||
{
|
||||
if (_nhdp_addr_tlvs[RFC5444_ADDRTLV_LINK_METRIC].tlv) {
|
||||
uint16_t metric_enc = *((uint16_t*)_nhdp_addr_tlvs[RFC5444_ADDRTLV_LINK_METRIC]
|
||||
.tlv->single_value);
|
||||
if (metric_enc & (NHDP_KD_LM_INC | NHDP_KD_NM_INC)) {
|
||||
address->tmp_metric_val = metric_enc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process address lists from the HELLO msg in the information bases
|
||||
*/
|
||||
@ -398,6 +462,10 @@ static void process_temp_tables(void)
|
||||
nib_elt = nib_process_hello();
|
||||
|
||||
if (nib_elt) {
|
||||
iib_process_hello(if_pid, nib_elt, val_time, sym, lost);
|
||||
originator_link_tuple = iib_process_hello(if_pid, nib_elt, val_time, sym, lost);
|
||||
|
||||
if (originator_link_tuple) {
|
||||
iib_process_metric_msg(originator_link_tuple, int_time != 0 ? int_time : val_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ static struct rfc5444_writer_tlvtype _nhdp_addrtlvs[] = {
|
||||
[RFC5444_ADDRTLV_LOCAL_IF] = { .type = RFC5444_ADDRTLV_LOCAL_IF },
|
||||
[RFC5444_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS },
|
||||
[RFC5444_ADDRTLV_OTHER_NEIGHB] = { .type = RFC5444_ADDRTLV_OTHER_NEIGHB },
|
||||
[RFC5444_ADDRTLV_LINK_METRIC] = { .type = RFC5444_ADDRTLV_LINK_METRIC, .exttype = NHDP_METRIC }
|
||||
};
|
||||
|
||||
/* Writer content provider for HELLO messages */
|
||||
@ -134,7 +135,8 @@ void nhdp_writer_send_hello(nhdp_if_entry_t *if_entry)
|
||||
}
|
||||
|
||||
void nhdp_writer_add_addr(struct rfc5444_writer *wr, nhdp_addr_t *addr,
|
||||
enum rfc5444_addrtlv_iana type, uint8_t value)
|
||||
enum rfc5444_addrtlv_iana type, uint8_t value,
|
||||
uint16_t metric_in, uint16_t metric_out)
|
||||
{
|
||||
struct rfc5444_writer_address *wr_addr;
|
||||
struct netaddr n_addr;
|
||||
@ -164,6 +166,25 @@ void nhdp_writer_add_addr(struct rfc5444_writer *wr, nhdp_addr_t *addr,
|
||||
|
||||
rfc5444_writer_add_addrtlv(wr, wr_addr, &_nhdp_addrtlvs[type],
|
||||
&value, sizeof(uint8_t), false);
|
||||
|
||||
/* Add LINK_METRIC TLV if necessary */
|
||||
if ((NHDP_METRIC == NHDP_LMT_DAT) && (metric_in != NHDP_METRIC_UNKNOWN)) {
|
||||
switch(type) {
|
||||
case RFC5444_ADDRTLV_LINK_STATUS:
|
||||
metric_in |= NHDP_KD_LM_INC;
|
||||
metric_in |= (metric_in == metric_out) ? NHDP_KD_LM_OUT : 0x00;
|
||||
break;
|
||||
case RFC5444_ADDRTLV_OTHER_NEIGHB:
|
||||
metric_in |= NHDP_KD_NM_INC;
|
||||
metric_in |= (metric_in == metric_out) ? NHDP_KD_NM_OUT : 0x00;
|
||||
break;
|
||||
default:
|
||||
/* Other types are not used and therefore no address tlv is added */
|
||||
return;
|
||||
}
|
||||
rfc5444_writer_add_addrtlv(wr, wr_addr, &_nhdp_addrtlvs[RFC5444_ADDRTLV_LINK_METRIC],
|
||||
&metric_in, sizeof(metric_in), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -65,9 +65,12 @@ void nhdp_writer_send_hello(nhdp_if_entry_t *if_entry);
|
||||
* @param[in] addr Pointer to a NHDP address to add to the HELLO message
|
||||
* @param[in] type TLV type for the address
|
||||
* @param[in] value TLV value for the address
|
||||
* @param[in] metric_in Encoded incoming link metric value
|
||||
* @param[in] metric_out Encoded outgoing link metric value
|
||||
*/
|
||||
void nhdp_writer_add_addr(struct rfc5444_writer *wr, nhdp_addr_t *addr,
|
||||
enum rfc5444_addrtlv_iana type, uint8_t value);
|
||||
enum rfc5444_addrtlv_iana type, uint8_t value,
|
||||
uint16_t metric_in, uint16_t metric_out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -122,7 +122,9 @@ void nib_fill_wr_addresses(struct rfc5444_writer *wr)
|
||||
/* Check whether address is not already included with link status symmetric */
|
||||
if (!NHDP_ADDR_TMP_IN_SYM(addr_elt->address)) {
|
||||
nhdp_writer_add_addr(wr, addr_elt->address, RFC5444_ADDRTLV_OTHER_NEIGHB,
|
||||
RFC5444_OTHERNEIGHB_SYMMETRIC);
|
||||
RFC5444_OTHERNEIGHB_SYMMETRIC,
|
||||
rfc5444_metric_encode(nib_elt->metric_in),
|
||||
rfc5444_metric_encode(nib_elt->metric_out));
|
||||
addr_elt->address->in_tmp_table = NHDP_ADDR_TMP_SYM;
|
||||
}
|
||||
}
|
||||
@ -140,7 +142,8 @@ void nib_fill_wr_addresses(struct rfc5444_writer *wr)
|
||||
if (!NHDP_ADDR_TMP_IN_ANY(lost_elt->address)) {
|
||||
/* Address is not present in one of the lists, add it */
|
||||
nhdp_writer_add_addr(wr, lost_elt->address, RFC5444_ADDRTLV_OTHER_NEIGHB,
|
||||
RFC5444_OTHERNEIGHB_LOST);
|
||||
RFC5444_OTHERNEIGHB_LOST, NHDP_METRIC_UNKNOWN,
|
||||
NHDP_METRIC_UNKNOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -215,6 +218,8 @@ static nib_entry_t *add_nib_entry_for_nb_addr_list(void)
|
||||
}
|
||||
|
||||
new_elem->symmetric = 0;
|
||||
new_elem->metric_in = NHDP_METRIC_UNKNOWN;
|
||||
new_elem->metric_out = NHDP_METRIC_UNKNOWN;
|
||||
LL_PREPEND(nib_entry_head, new_elem);
|
||||
|
||||
return new_elem;
|
||||
|
@ -35,6 +35,8 @@ extern "C" {
|
||||
typedef struct nib_entry_t {
|
||||
nhdp_addr_entry_t *address_list_head; /**< Pointer to this tuple's addresses*/
|
||||
uint8_t symmetric; /**< Flag whether sym link to this nb exists */
|
||||
uint32_t metric_in; /**< Lowest metric value for incoming link */
|
||||
uint32_t metric_out; /**< Lowest metric value for outgoing link */
|
||||
struct nib_entry_t *next; /**< Pointer to next list entry */
|
||||
} nib_entry_t;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user