aboutsummaryrefslogtreecommitdiff
path: root/lib/sflow_poller.c
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2009-11-20 09:45:26 -0800
committerBen Pfaff <blp@nicira.com>2009-12-21 13:18:35 -0800
commitc72e245a0e2c979f4c14279b56183e2200905c6c (patch)
tree5df768afcb9e5f0d51dcd8e69727bea331b626cd /lib/sflow_poller.c
parente4bfff8f0d2c01009759acb8adcab070327b5747 (diff)
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.
Diffstat (limited to 'lib/sflow_poller.c')
-rw-r--r--lib/sflow_poller.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/lib/sflow_poller.c b/lib/sflow_poller.c
new file mode 100644
index 00000000..ffd09d3c
--- /dev/null
+++ b/lib/sflow_poller.c
@@ -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);
+}
+