SFLSampler *sfl_agent_addSampler(SFLAgent *agent, SFLDataSource_instance *pdsi) { /* Keep the list sorted. */ SFLSampler *prev = NULL, *sm = agent->samplers; for(; sm != NULL; prev = sm, sm = sm->nxt) { int64_t cmp = sfl_dsi_compare(pdsi, &sm->dsi); if(cmp == 0) return sm; /* found - return existing one */ if(cmp < 0) break; /* insert here */ } /* either we found the insert point, or reached the end of the list...*/ { SFLSampler *newsm = (SFLSampler *)sflAlloc(agent, sizeof(SFLSampler)); sfl_sampler_init(newsm, agent, pdsi); if(prev) prev->nxt = newsm; else agent->samplers = newsm; newsm->nxt = sm; /* see if we should go in the ifIndex jumpTable */ if(SFL_DS_CLASS(newsm->dsi) == 0) { SFLSampler *test = sfl_agent_getSamplerByIfIndex(agent, SFL_DS_INDEX(newsm->dsi)); if(test && (SFL_DS_INSTANCE(newsm->dsi) < SFL_DS_INSTANCE(test->dsi))) { /* replace with this new one because it has a lower ds_instance number */ sfl_agent_jumpTableRemove(agent, test); test = NULL; } if(test == NULL) sfl_agent_jumpTableAdd(agent, newsm); } return newsm; } }
/** * Removes the queued poller at the head of the queue, uses the * poller's dsClass to determine which set of counters are to be * polled: * SFL_DSCLASS_PHYSICAL_ENTITY = physical host counters * SFL_DSCLASS_IFINDEX = switch port counters * SFL_DSCLASS_LOGICAL_ENTITY = vm counters * then calls the appropriate function to assemble and export the counters. * Updates the queue head and tail pointers. */ void processQueuedPoller(HSP *sp) { if (sp->pollerQHead != NULL) { HSPPollerQ *pollerQ = sp->pollerQHead; sp->pollerQHead = pollerQ->nxt; pollerQ->nxt = NULL; if (sp->pollerQHead == NULL) { sp->pollerQTail = NULL; } uint32_t dsClass = SFL_DS_CLASS(pollerQ->poller->dsi); SFL_COUNTERS_SAMPLE_TYPE cs; memset(&cs, 0, sizeof(cs)); switch (dsClass) { case SFL_DSCLASS_PHYSICAL_ENTITY: getCounters_host(pollerQ->magic, pollerQ->poller, &cs); break; case SFL_DSCLASS_IFINDEX: getCounters_interface(pollerQ->magic, pollerQ->poller, &cs); break; case SFL_DSCLASS_LOGICAL_ENTITY: getCounters_vm(pollerQ->magic, pollerQ->poller, &cs); break; } my_free(pollerQ); } }
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); }
void sfl_sampler_writeFlowSample(SFLSampler *sampler, SFL_FLOW_SAMPLE_TYPE *fs) { if(fs == NULL) return; sampler->samplesThisTick++; /* increment the sequence number */ fs->sequence_number = ++sampler->flowSampleSeqNo; /* copy the other header fields in */ #ifdef SFL_USE_32BIT_INDEX fs->ds_class = SFL_DS_CLASS(sampler->dsi); fs->ds_index = SFL_DS_INDEX(sampler->dsi); #else fs->source_id = SFL_DS_DATASOURCE(sampler->dsi); #endif /* the sampling rate may have been set already. */ if(fs->sampling_rate == 0) fs->sampling_rate = sampler->sFlowFsPacketSamplingRate; /* the samplePool may be maintained upstream too. */ if( fs->sample_pool == 0) fs->sample_pool = sampler->samplePool; /* sent to my receiver */ if(sampler->myReceiver) sfl_receiver_writeFlowSample(sampler->myReceiver, fs); }