LCOV - code coverage report
Current view: top level - lib - sflow_sampler.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 38 55 69.1 %
Date: 2016-09-14 01:02:56 Functions: 7 14 50.0 %
Branches: 6 14 42.9 %

           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                 :            : /*_________________--------------------------__________________
      12                 :            :   _________________   sfl_sampler_init       __________________
      13                 :            :   -----------------__________________________------------------
      14                 :            : */
      15                 :            : 
      16                 :          6 : void sfl_sampler_init(SFLSampler *sampler, SFLAgent *agent, SFLDataSource_instance *pdsi)
      17                 :            : {
      18                 :            :     /* copy the dsi in case it points to sampler->dsi, which we are about to clear.
      19                 :            :        (Thanks to Jagjit Choudray of Force 10 Networks for pointing out this bug) */
      20                 :          6 :     SFLDataSource_instance dsi = *pdsi;
      21                 :            : 
      22                 :            :     /* preserve the *nxt pointer too, in case we are resetting this poller and it is
      23                 :            :        already part of the agent's linked list (thanks to Matt Woodly for pointing this out,
      24                 :            :        and to Andy Kitchingman for pointing out that it applies to the hash_nxt ptr too) */
      25                 :          6 :     SFLSampler *nxtPtr = sampler->nxt;
      26                 :          6 :     SFLSampler *hashPtr = sampler->hash_nxt;
      27                 :            : 
      28                 :            :     /* clear everything */
      29                 :          6 :     memset(sampler, 0, sizeof(*sampler));
      30                 :            : 
      31                 :            :     /* restore the linked list and hash-table ptr */
      32                 :          6 :     sampler->nxt = nxtPtr;
      33                 :          6 :     sampler->hash_nxt = hashPtr;
      34                 :            : 
      35                 :            :     /* now copy in the parameters */
      36                 :          6 :     sampler->agent = agent;
      37                 :          6 :     sampler->dsi = dsi;
      38                 :            : 
      39                 :            :     /* set defaults */
      40                 :          6 :     sampler->sFlowFsMaximumHeaderSize = SFL_DEFAULT_HEADER_SIZE;
      41                 :          6 :     sampler->sFlowFsPacketSamplingRate = SFL_DEFAULT_SAMPLING_RATE;
      42                 :          6 : }
      43                 :            : 
      44                 :            : /*_________________--------------------------__________________
      45                 :            :   _________________       reset              __________________
      46                 :            :   -----------------__________________________------------------
      47                 :            : */
      48                 :            : 
      49                 :          0 : static void reset(SFLSampler *sampler)
      50                 :            : {
      51                 :          0 :     SFLDataSource_instance dsi = sampler->dsi;
      52                 :          0 :     sfl_sampler_init(sampler, sampler->agent, &dsi);
      53                 :          0 : }
      54                 :            : 
      55                 :            : /*_________________---------------------------__________________
      56                 :            :   _________________      MIB access           __________________
      57                 :            :   -----------------___________________________------------------
      58                 :            : */
      59                 :          0 : u_int32_t sfl_sampler_get_sFlowFsReceiver(SFLSampler *sampler) {
      60                 :          0 :     return sampler->sFlowFsReceiver;
      61                 :            : }
      62                 :          6 : void sfl_sampler_set_sFlowFsReceiver(SFLSampler *sampler, u_int32_t sFlowFsReceiver) {
      63                 :          6 :     sampler->sFlowFsReceiver = sFlowFsReceiver;
      64         [ -  + ]:          6 :     if(sFlowFsReceiver == 0) reset(sampler);
      65                 :            :     else {
      66                 :            :     /* retrieve and cache a direct pointer to my receiver */
      67                 :          6 :     sampler->myReceiver = sfl_agent_getReceiver(sampler->agent, sampler->sFlowFsReceiver);
      68                 :            :     }
      69                 :          6 : }
      70                 :         14 : u_int32_t sfl_sampler_get_sFlowFsPacketSamplingRate(SFLSampler *sampler) {
      71                 :         14 :     return sampler->sFlowFsPacketSamplingRate;
      72                 :            : }
      73                 :          6 : void sfl_sampler_set_sFlowFsPacketSamplingRate(SFLSampler *sampler, u_int32_t sFlowFsPacketSamplingRate) {
      74                 :          6 :     sampler->sFlowFsPacketSamplingRate = sFlowFsPacketSamplingRate;
      75                 :          6 : }
      76                 :          0 : u_int32_t sfl_sampler_get_sFlowFsMaximumHeaderSize(SFLSampler *sampler) {
      77                 :          0 :     return sampler->sFlowFsMaximumHeaderSize;
      78                 :            : }
      79                 :          6 : void sfl_sampler_set_sFlowFsMaximumHeaderSize(SFLSampler *sampler, u_int32_t sFlowFsMaximumHeaderSize) {
      80                 :          6 :     sampler->sFlowFsMaximumHeaderSize = sFlowFsMaximumHeaderSize;
      81                 :          6 : }
      82                 :            : 
      83                 :            : /* call this to set a maximum samples-per-second threshold. If the sampler reaches this
      84                 :            :    threshold it will automatically back off the sampling rate. A value of 0 disables the
      85                 :            :    mechanism */
      86                 :          0 : void sfl_sampler_set_backoffThreshold(SFLSampler *sampler, u_int32_t samplesPerSecond) {
      87                 :          0 :     sampler->backoffThreshold = samplesPerSecond;
      88                 :          0 : }
      89                 :          0 : u_int32_t sfl_sampler_get_backoffThreshold(SFLSampler *sampler) {
      90                 :          0 :     return sampler->backoffThreshold;
      91                 :            : }
      92                 :          0 : u_int32_t sfl_sampler_get_samplesLastTick(SFLSampler *sampler) {
      93                 :          0 :     return sampler->samplesLastTick;
      94                 :            : }
      95                 :            : 
      96                 :            : /*_________________---------------------------------__________________
      97                 :            :   _________________   sequence number reset         __________________
      98                 :            :   -----------------_________________________________------------------
      99                 :            :   Used by the agent to indicate a samplePool discontinuity
     100                 :            :   so that the sflow collector will know to ignore the next delta.
     101                 :            : */
     102                 :          0 : void sfl_sampler_resetFlowSeqNo(SFLSampler *sampler) { sampler->flowSampleSeqNo = 0; }
     103                 :            : 
     104                 :            : 
     105                 :            : /*_________________---------------------------__________________
     106                 :            :   _________________    sfl_sampler_tick       __________________
     107                 :            :   -----------------___________________________------------------
     108                 :            : */
     109                 :            : 
     110                 :         15 : void sfl_sampler_tick(SFLSampler *sampler, time_t now)
     111                 :            : {
     112 [ -  + ][ #  # ]:         15 :     if(sampler->backoffThreshold && sampler->samplesThisTick > sampler->backoffThreshold) {
     113                 :            :     /* automatic backoff.  If using hardware sampling then this is where you have to
     114                 :            :      * call out to change the sampling rate and make sure that any other registers/variables
     115                 :            :      * that hold this value are updated.
     116                 :            :      */
     117                 :          0 :     sampler->sFlowFsPacketSamplingRate *= 2;
     118                 :            :     }
     119                 :         15 :     sampler->samplesLastTick = sampler->samplesThisTick;
     120                 :         15 :     sampler->samplesThisTick = 0;
     121                 :         15 : }
     122                 :            : 
     123                 :            : 
     124                 :            : 
     125                 :            : /*_________________------------------------------__________________
     126                 :            :   _________________ sfl_sampler_writeFlowSample  __________________
     127                 :            :   -----------------______________________________------------------
     128                 :            : */
     129                 :            : 
     130                 :         14 : void sfl_sampler_writeFlowSample(SFLSampler *sampler, SFL_FLOW_SAMPLE_TYPE *fs)
     131                 :            : {
     132         [ -  + ]:         14 :     if(fs == NULL) return;
     133                 :         14 :     sampler->samplesThisTick++;
     134                 :            :     /* increment the sequence number */
     135                 :         14 :     fs->sequence_number = ++sampler->flowSampleSeqNo;
     136                 :            :     /* copy the other header fields in */
     137                 :            : #ifdef SFL_USE_32BIT_INDEX
     138                 :            :     fs->ds_class = SFL_DS_CLASS(sampler->dsi);
     139                 :            :     fs->ds_index = SFL_DS_INDEX(sampler->dsi);
     140                 :            : #else
     141                 :         14 :     fs->source_id = SFL_DS_DATASOURCE(sampler->dsi);
     142                 :            : #endif
     143                 :            :     /* the sampling rate may have been set already. */
     144         [ +  - ]:         14 :     if(fs->sampling_rate == 0) fs->sampling_rate = sampler->sFlowFsPacketSamplingRate;
     145                 :            :     /* the samplePool may be maintained upstream too. */
     146         [ +  - ]:         14 :     if( fs->sample_pool == 0) fs->sample_pool = sampler->samplePool;
     147                 :            :     /* sent to my receiver */
     148         [ +  - ]:         14 :     if(sampler->myReceiver) sfl_receiver_writeFlowSample(sampler->myReceiver, fs);
     149                 :            : }
     150                 :            : 
     151                 :            : #ifdef SFLOW_SOFTWARE_SAMPLING
     152                 :            : 
     153                 :            : /* ================== software sampling ========================*/
     154                 :            : 
     155                 :            : /*_________________---------------------------__________________
     156                 :            :   _________________     nextRandomSkip        __________________
     157                 :            :   -----------------___________________________------------------
     158                 :            : */
     159                 :            : 
     160                 :            : inline static u_int32_t nextRandomSkip(u_int32_t mean)
     161                 :            : {
     162                 :            :     if(mean == 0 || mean == 1) return 1;
     163                 :            :     return ((random() % ((2 * mean) - 1)) + 1);
     164                 :            : }
     165                 :            : 
     166                 :            : /*_________________---------------------------__________________
     167                 :            :   _________________  sfl_sampler_takeSample   __________________
     168                 :            :   -----------------___________________________------------------
     169                 :            : */
     170                 :            : 
     171                 :            : int sfl_sampler_takeSample(SFLSampler *sampler)
     172                 :            : {
     173                 :            :     if(sampler->skip == 0) {
     174                 :            :     /* first time - seed the random number generator */
     175                 :            :     srandom(SFL_DS_INDEX(sampler->dsi));
     176                 :            :     sampler->skip = nextRandomSkip(sampler->sFlowFsPacketSamplingRate);
     177                 :            :     }
     178                 :            : 
     179                 :            :     /* increment the samplePool */
     180                 :            :     sampler->samplePool++;
     181                 :            : 
     182                 :            :     if(--sampler->skip == 0) {
     183                 :            :     /* reached zero. Set the next skip and return true. */
     184                 :            :     sampler->skip = nextRandomSkip(sampler->sFlowFsPacketSamplingRate);
     185                 :            :     return 1;
     186                 :            :     }
     187                 :            :     return 0;
     188                 :            : }
     189                 :            : 
     190                 :            : #endif /* SFLOW_SOFTWARE_SAMPLING */

Generated by: LCOV version 1.12