LCOV - code coverage report
Current view: top level - lib - sflow_poller.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 37 48 77.1 %
Date: 2016-09-14 01:02:56 Functions: 6 11 54.5 %
Branches: 9 14 64.3 %

           Branch data     Line data    Source code
       1                 :            : /* Copyright (c) 2002-2009 InMon Corp. Licensed under the terms of either the
       2                 :            :  *   Sun Industry Standards Source License 1.1, that is available at:
       3                 :            :  *    http://host-sflow.sourceforge.net/sissl.html
       4                 :            :  * or the InMon sFlow License, that is available at:
       5                 :            :  *    http://www.inmon.com/technology/sflowlicense.txt
       6                 :            :  */
       7                 :            : 
       8                 :            : #include "sflow_api.h"
       9                 :            : 
      10                 :            : /*_________________--------------------------__________________
      11                 :            :   _________________    sfl_poller_init       __________________
      12                 :            :   -----------------__________________________------------------
      13                 :            : */
      14                 :            : 
      15                 :         14 : void sfl_poller_init(SFLPoller *poller,
      16                 :            :              SFLAgent *agent,
      17                 :            :              SFLDataSource_instance *pdsi,
      18                 :            :              void *magic,         /* ptr to pass back in getCountersFn() */
      19                 :            :              getCountersFn_t getCountersFn)
      20                 :            : {
      21                 :            :     /* copy the dsi in case it points to poller->dsi, which we are about to clear */
      22                 :         14 :     SFLDataSource_instance dsi = *pdsi;
      23                 :            : 
      24                 :            :     /* preserve the *nxt pointer too, in case we are resetting this poller and it is
      25                 :            :        already part of the agent's linked list (thanks to Matt Woodly for pointing this out) */
      26                 :         14 :     SFLPoller *nxtPtr = poller->nxt;
      27                 :            : 
      28                 :            :     /* clear everything */
      29                 :         14 :     memset(poller, 0, sizeof(*poller));
      30                 :            : 
      31                 :            :     /* restore the linked list ptr */
      32                 :         14 :     poller->nxt = nxtPtr;
      33                 :            : 
      34                 :            :     /* now copy in the parameters */
      35                 :         14 :     poller->agent = agent;
      36                 :         14 :     poller->dsi = dsi; /* structure copy */
      37                 :         14 :     poller->magic = magic;
      38                 :         14 :     poller->getCountersFn = getCountersFn;
      39                 :         14 : }
      40                 :            : 
      41                 :            : /*_________________--------------------------__________________
      42                 :            :   _________________       reset              __________________
      43                 :            :   -----------------__________________________------------------
      44                 :            : */
      45                 :            : 
      46                 :          0 : static void reset(SFLPoller *poller)
      47                 :            : {
      48                 :          0 :     SFLDataSource_instance dsi = poller->dsi;
      49                 :          0 :     sfl_poller_init(poller, poller->agent, &dsi, poller->magic, poller->getCountersFn);
      50                 :          0 : }
      51                 :            : 
      52                 :            : /*_________________---------------------------__________________
      53                 :            :   _________________      MIB access           __________________
      54                 :            :   -----------------___________________________------------------
      55                 :            : */
      56                 :          0 : u_int32_t sfl_poller_get_sFlowCpReceiver(SFLPoller *poller) {
      57                 :          0 :     return poller->sFlowCpReceiver;
      58                 :            : }
      59                 :            : 
      60                 :         14 : void sfl_poller_set_sFlowCpReceiver(SFLPoller *poller, u_int32_t sFlowCpReceiver) {
      61                 :         14 :     poller->sFlowCpReceiver = sFlowCpReceiver;
      62         [ -  + ]:         14 :     if(sFlowCpReceiver == 0) reset(poller);
      63                 :            :     else {
      64                 :            :     /* retrieve and cache a direct pointer to my receiver */
      65                 :         14 :     poller->myReceiver = sfl_agent_getReceiver(poller->agent, poller->sFlowCpReceiver);
      66                 :            :     }
      67                 :         14 : }
      68                 :            : 
      69                 :          0 : u_int32_t sfl_poller_get_sFlowCpInterval(SFLPoller *poller) {
      70                 :          0 :     return poller->sFlowCpInterval;
      71                 :            : }
      72                 :            : 
      73                 :         14 : void sfl_poller_set_sFlowCpInterval(SFLPoller *poller, u_int32_t sFlowCpInterval) {
      74                 :         14 :     poller->sFlowCpInterval = sFlowCpInterval;
      75         [ +  + ]:         14 :     if(sFlowCpInterval) {
      76                 :            :         /* Set the countersCountdown to be a randomly selected value between 1 and
      77                 :            :        sFlowCpInterval. That way the counter polling will be desynchronised
      78                 :            :        (on a 200-port switch, polling all the counters in one second could be harmful).
      79                 :            :        In a large network, even this might not be ideal if time-synchroniziation
      80                 :            :        between devices is close and counters are always polled on second boundaries. If
      81                 :            :        1000 different devices all send an sFlow datagram on the same second boundary
      82                 :            :        it could result in an antisocial burst.
      83                 :            :        However when counter-samples are packed into the export datagram they do not
      84                 :            :        always result in that datagram being sent immediately. It is more likely that
      85                 :            :        a subsequent packet-sample will be the one that triggers the datagram to be sent.
      86                 :            :        The packet-sample events are not sychronized to any clock, so that results in
      87                 :            :        excellent desynchronization (http://blog.sflow.com/2009/05/measurement-traffic.html).
      88                 :            :        Another smoothing factor is that the tick() function called here is usually
      89                 :            :        driven from a fairly "soft" polling loop rather than a hard real-time event.
      90                 :            :     */
      91                 :         10 :         poller->countersCountdown = 1 + (random() % sFlowCpInterval);
      92                 :            :     }
      93                 :            :     else {
      94                 :            :         /* Setting sFlowCpInterval to 0 disables counter polling altogether.  Thanks to
      95                 :            :        Andy Kitchingman for spotting this ommission. */
      96                 :          4 :         poller->countersCountdown = 0;
      97                 :            :     }
      98                 :         14 : }
      99                 :            : 
     100                 :            : /*_________________---------------------------------__________________
     101                 :            :   _________________          bridge port            __________________
     102                 :            :   -----------------_________________________________------------------
     103                 :            :   May need a separate number to reference the local bridge port
     104                 :            :   to get counters if it is not the same as the global ifIndex.
     105                 :            : */
     106                 :            : 
     107                 :          8 : void sfl_poller_set_bridgePort(SFLPoller *poller, u_int32_t port_no) {
     108                 :          8 :     poller->bridgePort = port_no;
     109                 :          8 : }
     110                 :            : 
     111                 :          0 : u_int32_t sfl_poller_get_bridgePort(SFLPoller *poller) {
     112                 :          0 :     return poller->bridgePort;
     113                 :            : }
     114                 :            : 
     115                 :            : /*_________________---------------------------------__________________
     116                 :            :   _________________   sequence number reset         __________________
     117                 :            :   -----------------_________________________________------------------
     118                 :            :   Used to indicate a counter discontinuity
     119                 :            :   so that the sflow collector will know to ignore the next delta.
     120                 :            : */
     121                 :          0 : void sfl_poller_resetCountersSeqNo(SFLPoller *poller) {  poller->countersSampleSeqNo = 0; }
     122                 :            : 
     123                 :            : /*_________________---------------------------__________________
     124                 :            :   _________________    sfl_poller_tick        __________________
     125                 :            :   -----------------___________________________------------------
     126                 :            : */
     127                 :            : 
     128                 :         32 : void sfl_poller_tick(SFLPoller *poller, time_t now)
     129                 :            : {
     130         [ +  + ]:         32 :     if(poller->countersCountdown == 0) return; /* counters retrieval was not enabled */
     131         [ -  + ]:         20 :     if(poller->sFlowCpReceiver == 0) return;
     132                 :            : 
     133         [ +  - ]:         20 :     if(--poller->countersCountdown == 0) {
     134         [ +  - ]:         20 :     if(poller->getCountersFn != NULL) {
     135                 :            :         /* call out for counters */
     136                 :            :         SFL_COUNTERS_SAMPLE_TYPE cs;
     137                 :         20 :         memset(&cs, 0, sizeof(cs));
     138                 :         20 :         poller->getCountersFn(poller->magic, poller, &cs);
     139                 :            :         /* this countersFn is expected to fill in some counter block elements
     140                 :            :            and then call sfl_poller_writeCountersSample(poller, &cs); */
     141                 :            :     }
     142                 :            :     /* reset the countdown */
     143                 :         20 :     poller->countersCountdown = poller->sFlowCpInterval;
     144                 :            :     }
     145                 :            : }
     146                 :            : 
     147                 :            : /*_________________---------------------------------__________________
     148                 :            :   _________________ sfl_poller_writeCountersSample  __________________
     149                 :            :   -----------------_________________________________------------------
     150                 :            : */
     151                 :            : 
     152                 :         20 : void sfl_poller_writeCountersSample(SFLPoller *poller, SFL_COUNTERS_SAMPLE_TYPE *cs)
     153                 :            : {
     154                 :            :     /* fill in the rest of the header fields, and send to the receiver */
     155                 :         20 :     cs->sequence_number = ++poller->countersSampleSeqNo;
     156                 :            : #ifdef SFL_USE_32BIT_INDEX
     157                 :            :     cs->ds_class = SFL_DS_CLASS(poller->dsi);
     158                 :            :     cs->ds_index = SFL_DS_INDEX(poller->dsi);
     159                 :            : #else
     160                 :         20 :     cs->source_id = SFL_DS_DATASOURCE(poller->dsi);
     161                 :            : #endif
     162                 :            :     /* sent to my receiver */
     163         [ +  - ]:         20 :     if(poller->myReceiver) sfl_receiver_writeCountersSample(poller->myReceiver, cs);
     164                 :         20 : }
     165                 :            : 

Generated by: LCOV version 1.12