2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-29 15:28:56 +00:00

Add InMon's sFlow Agent library to the build system.

The C source and header files added in this commit is covered under the
InMon sFlow license at http://www.inmon.com/technology/sflowlicense.txt

The library requires -Wno-unused to compile without warnings, so this
commit adds that for building the sFlow code only.  Automake can only
change compiler flags on a per-library or per-program basis, so sFlow
is built as a separate library.

The library will be used in upcoming commits.
This commit is contained in:
Ben Pfaff
2009-11-20 09:45:26 -08:00
parent e4bfff8f0d
commit c72e245a0e
10 changed files with 2565 additions and 0 deletions

142
lib/sflow_poller.c Normal file
View File

@@ -0,0 +1,142 @@
/* Copyright (c) 2002-2009 InMon Corp. Licensed under the terms of the InMon sFlow licence: */
/* http://www.inmon.com/technology/sflowlicense.txt */
#include "sflow_api.h"
/*_________________--------------------------__________________
_________________ sfl_poller_init __________________
-----------------__________________________------------------
*/
void sfl_poller_init(SFLPoller *poller,
SFLAgent *agent,
SFLDataSource_instance *pdsi,
void *magic, /* ptr to pass back in getCountersFn() */
getCountersFn_t getCountersFn)
{
/* copy the dsi in case it points to poller->dsi, which we are about to clear */
SFLDataSource_instance dsi = *pdsi;
/* preserve the *nxt pointer too, in case we are resetting this poller and it is
already part of the agent's linked list (thanks to Matt Woodly for pointing this out) */
SFLPoller *nxtPtr = poller->nxt;
/* clear everything */
memset(poller, 0, sizeof(*poller));
/* restore the linked list ptr */
poller->nxt = nxtPtr;
/* now copy in the parameters */
poller->agent = agent;
poller->dsi = dsi; /* structure copy */
poller->magic = magic;
poller->getCountersFn = getCountersFn;
}
/*_________________--------------------------__________________
_________________ reset __________________
-----------------__________________________------------------
*/
static void reset(SFLPoller *poller)
{
SFLDataSource_instance dsi = poller->dsi;
sfl_poller_init(poller, poller->agent, &dsi, poller->magic, poller->getCountersFn);
}
/*_________________---------------------------__________________
_________________ MIB access __________________
-----------------___________________________------------------
*/
u_int32_t sfl_poller_get_sFlowCpReceiver(SFLPoller *poller) {
return poller->sFlowCpReceiver;
}
void sfl_poller_set_sFlowCpReceiver(SFLPoller *poller, u_int32_t sFlowCpReceiver) {
poller->sFlowCpReceiver = sFlowCpReceiver;
if(sFlowCpReceiver == 0) reset(poller);
else {
/* retrieve and cache a direct pointer to my receiver */
poller->myReceiver = sfl_agent_getReceiver(poller->agent, poller->sFlowCpReceiver);
}
}
u_int32_t sfl_poller_get_sFlowCpInterval(SFLPoller *poller) {
return poller->sFlowCpInterval;
}
void sfl_poller_set_sFlowCpInterval(SFLPoller *poller, u_int32_t sFlowCpInterval) {
poller->sFlowCpInterval = sFlowCpInterval;
/* Set the countersCountdown to be a randomly selected value between 1 and
sFlowCpInterval. That way the counter polling would be desynchronised
(on a 200-port switch, polling all the counters in one second could be harmful). */
poller->countersCountdown = 1 + (random() % sFlowCpInterval);
}
/*_________________---------------------------------__________________
_________________ bridge port __________________
-----------------_________________________________------------------
May need a separate number to reference the local bridge port
to get counters if it is not the same as the global ifIndex.
*/
void sfl_poller_set_bridgePort(SFLPoller *poller, u_int32_t port_no) {
poller->bridgePort = port_no;
}
u_int32_t sfl_poller_get_bridgePort(SFLPoller *poller) {
return poller->bridgePort;
}
/*_________________---------------------------------__________________
_________________ sequence number reset __________________
-----------------_________________________________------------------
Used to indicate a counter discontinuity
so that the sflow collector will know to ignore the next delta.
*/
void sfl_poller_resetCountersSeqNo(SFLPoller *poller) { poller->countersSampleSeqNo = 0; }
/*_________________---------------------------__________________
_________________ sfl_poller_tick __________________
-----------------___________________________------------------
*/
void sfl_poller_tick(SFLPoller *poller, time_t now)
{
if(poller->countersCountdown == 0) return; /* counters retrieval was not enabled */
if(poller->sFlowCpReceiver == 0) return;
if(--poller->countersCountdown == 0) {
if(poller->getCountersFn != NULL) {
/* call out for counters */
SFL_COUNTERS_SAMPLE_TYPE cs;
memset(&cs, 0, sizeof(cs));
poller->getCountersFn(poller->magic, poller, &cs);
/* this countersFn is expected to fill in some counter block elements
and then call sfl_poller_writeCountersSample(poller, &cs); */
}
/* reset the countdown */
poller->countersCountdown = poller->sFlowCpInterval;
}
}
/*_________________---------------------------------__________________
_________________ sfl_poller_writeCountersSample __________________
-----------------_________________________________------------------
*/
void sfl_poller_writeCountersSample(SFLPoller *poller, SFL_COUNTERS_SAMPLE_TYPE *cs)
{
/* fill in the rest of the header fields, and send to the receiver */
cs->sequence_number = ++poller->countersSampleSeqNo;
#ifdef SFL_USE_32BIT_INDEX
cs->ds_class = SFL_DS_CLASS(poller->dsi);
cs->ds_index = SFL_DS_INDEX(poller->dsi);
#else
cs->source_id = SFL_DS_DATASOURCE(poller->dsi);
#endif
/* sent to my receiver */
if(poller->myReceiver) sfl_receiver_writeCountersSample(poller->myReceiver, cs);
}