Show lqe_status.c syntax highlighted
/*
*
* Copyright (c) 2003 The Regents of the University of California. All
* rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of the University 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 REGENTS 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 REGENTS 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.
*
*/
/*
* lqe_status.c: Functions that provide the status interface to
* the users of the lqe service
*
* $Id: lqe_status.c,v 1.1 2005/01/26 01:30:59 cerpa Exp $
*/
char lqe_status_c_id[] = "$Id: lqe_status.c,v 1.1 2005/01/26 01:30:59 cerpa Exp $";
#include "lqe_i.h"
#define NULL_TIME(timeval) ((timeval).tv_sec == 0 && (timeval).tv_usec == 0)
/****************** Status Device Printing ************************/
static int marshal_status(neighbor_list_t *nl, buf_t *buf)
{
neighbor_el_t *ne;
int num = 0;
/* copy all the entries onto the buf */
for (ne = neighbor_list_top(nl); ne; ne = neighbor_list_next(ne)) {
bufcpy(buf, &ne->info, sizeof(ne->info));
num++;
}
return num;
}
char *print_ago(struct timeval *now, struct timeval *t)
{
DECLARE_STATIC_BUF_RING(buf, 5, 20);
if (NULL_TIME(*t))
sprintf(buf, "--");
else
sprintf(buf, "%.2f", misc_tv_offset(now, t) / MILLION_F);
return buf;
}
static int lqe_status_printable(status_context_t *info, buf_t *buf)
{
neighbor_list_t *nl = (neighbor_list_t *) sd_data(info);
buf_t *bin_buf = buf_new();
int num_neighbors = marshal_status(nl, bin_buf), i, j;
neigh_t *n = (neigh_t *) bin_buf->buf;
struct timeval now;
gettimeofday(&now, NULL);
bufprintf(buf, "Interface ID Sender ID Connectivity IN (RNP) Last Heard\n"
"------------ --------- --------------------- ----------\n");
for (i = 0; i < num_neighbors; n++, i++) {
for (j = 0; j < MAX_SRC; j++) {
if (n->conn_in[j] != nl->init_rnp[i]) {
bufprintf(buf, "%12s %9d %15.10f %10s\n", print_if_id(n->if_id),
j, n->conn_in[j], print_ago(&now, &n->last_heard));
}
}
}
buf_free(bin_buf);
return STATUS_MSG_COMPLETE;
}
static int lqe_status_binary(status_context_t *info, buf_t *buf)
{
neighbor_list_t *nl = (neighbor_list_t *) sd_data(info);
marshal_status(nl, buf);
return STATUS_MSG_COMPLETE;
}
void lqe_status_notify(neighbor_list_t *nl)
{
elog(LOG_DEBUG(4), "notifying status interface");
g_status_dev_notify(nl->status);
}
/************* Evaluation of Neighbor State ***********************/
/*
* Evaluate one neighbor. If the state has changed, return 1; else,
* return 0
*/
int lqe_evaluate_one(neighbor_list_t *nl, neighbor_el_t *ne)
{
int i, retval = 0;
elog(LOG_DEBUG(5), "evaluating neighbor id %s",
print_if_id(ne->info.if_id));
for (i = 0; i < MAX_SRC; i++) {
if (ne->info.conn_in[i] != 0) {
elog(LOG_DEBUG(7), "Source: %d -- Previous connectivity value: "
"%6.6f -- New connectivity value: %6.6f", i,
ne->status_conn[i], ne->info.conn_in[i]);
/* if connectivity has changed, update value and notify */
if(ne->status_conn[i] != ne->info.conn_in[i]) {
ne->status_conn[i] = ne->info.conn_in[i];
retval = 1;
}
}
}
return retval;
}
/* Evaluate the state of ONE neighbor */
void lqe_evaluate(neighbor_list_t *nl, neighbor_el_t *ne)
{
if (lqe_evaluate_one(nl, ne))
lqe_status_notify(nl);
}
/* Evaluate the state of ALL our neighbors */
void lqe_evaluate_all(neighbor_list_t *nl)
{
neighbor_el_t *ne;
//int notify = 1; /* force notification every second */
int notify = 0;
/* If there are new neighbors, we nofify */
if (nl->num_neighbors < neighbor_list_qlen(nl)) {
nl->num_neighbors = neighbor_list_qlen(nl);
notify = 1;
goto notify;
}
/* if there is new data from some neighbor, we notify */
for (ne = neighbor_list_top(nl); ne; ne = neighbor_list_next(ne))
notify += lqe_evaluate_one(nl, ne);
notify:
if (notify)
lqe_status_notify(nl);
}
/* Check neighbors connectivity values */
static int eval_periodic_timer(void *data, int interval, g_event_t *ev)
{
neighbor_list_t *nl = (neighbor_list_t *) data;
lqe_evaluate_all(nl);
return EVENT_RENEW;
}
void lqe_status_init(neighbor_list_t *nl)
{
/* Basic opts for our lqe status device */
status_dev_opts_t status_opts = {
device: {
devname: link_pass_name(nl->pass_context, "lqe"),
device_info: nl,
},
printable: lqe_status_printable,
binary: lqe_status_binary
};
/* Now create the status device */
if (g_status_dev(&status_opts, &nl->status) < 0) {
elog(LOG_CRIT, "can't create status device %s: %m",
status_opts.device.devname);
exit(1);
}
/* Every second, evaluate all neighbors connectivity values to check
* if they have chenged */
g_timer_add(1000, eval_periodic_timer, nl, NULL, NULL);
}
See more files for this project here