static void tick(HSP *sp) { if (sp->clk%5 == 0) { calcLoad(); } if ((sp->clk % HSP_REFRESH_PORTS) == 0 && HSP_FILTER_ACTIVE(sp->filter)) { readFilterSwitchPorts(sp); } if (sp->refreshVms || (sp->clk % HSP_REFRESH_VMS) == 0) { sp->refreshVms = FALSE; if (HSP_FILTER_ACTIVE(sp->filter) || sp->hyperV) { //it would be better to do this only when we detect a switch port change. //However, we need the vm friendly names to be current and changes to //friendly names will not be detected by the filter. //We also need to handle the case where there is no filter or the filter //is not installed in all the switches. readVms(sp); } } if (sp->nio_polling_secs && (sp->clk % sp->nio_polling_secs) == 0) { updateNioCounters(sp); } if (sp->vmStoreInvalid) { writeGuidStore(sp->vmStore, sp->f_vmStore); sp->vmStoreInvalid = FALSE; } if (sp->portStoreInvalid) { writeGuidStore(sp->portStore, sp->f_portStore); sp->portStoreInvalid = FALSE; } if ((sp->clk % HSP_REFRESH_ADAPTORS) == 0) { readInterfaces(sp, false); } sfl_agent_tick(sp->sFlow->agent, sp->clk); }
int readNioCounters(HSP *sp, SFLHost_nio_counters *nio) { // may need to schedule intermediate calls to updateNioCounters() // too (to avoid undetected wraps), but at the very least we need to do // it here to make sure the data is up to the second. updateNioCounters(sp); int gotData = NO; // just add up all the counters for(uint32_t i = 0; i < sp->adaptorList->num_adaptors; i++) { SFLAdaptor *ad = sp->adaptorList->adaptors[i]; if(ad) { HSPAdaptorNIO *ctrs = (HSPAdaptorNIO *)ad->userData; if(ctrs) { gotData = YES; nio->bytes_in += ctrs->nio.bytes_in; nio->pkts_in += ctrs->nio.pkts_in; nio->errs_in += ctrs->nio.errs_in; nio->drops_in += ctrs->nio.drops_in; nio->bytes_out += ctrs->nio.bytes_out; nio->pkts_out += ctrs->nio.pkts_out; nio->errs_out += ctrs->nio.errs_out; nio->drops_out += ctrs->nio.drops_out; } } } myLog(LOG_INFO,"readNioCounters:\n\trbytes:\t%lu\n\trdrops:\t%lu\n\trerrs:\t%lu\n\trpkts:\t%lu\n\ttbytes:\t%lu\n\ttdrops:\t%lu\n\tterrs:\t%lu\n\ttpkts:\t%lu\n", nio->bytes_in,nio->drops_in,nio->errs_in,nio->pkts_in,nio->bytes_out,nio->drops_out,nio->errs_out,nio->pkts_out); return gotData; }
int readNioCounters(HSP *sp, SFLHost_nio_counters *nio, char *devFilter, SFLAdaptorList *adList) { int interface_count = 0; size_t devFilterLen = devFilter ? strlen(devFilter) : 0; // may need to schedule intermediate calls to updateNioCounters() // too (to avoid undetected wraps), but at the very least we need to do // it here to make sure the data is up to the second. updateNioCounters(sp); for(int i = 0; i < sp->adaptorNIOList.num_adaptors; i++) { HSPAdaptorNIO *adaptor = sp->adaptorNIOList.adaptors[i]; if(devFilter == NULL || !strncmp(devFilter, adaptor->deviceName, devFilterLen)) { if(adList == NULL || adaptorListGet(adList, adaptor->deviceName) != NULL) { interface_count++; // report the sum over all devices that match the filter nio->bytes_in += adaptor->nio.bytes_in; nio->pkts_in += adaptor->nio.pkts_in; nio->errs_in += adaptor->nio.errs_in; nio->drops_in += adaptor->nio.drops_in; nio->bytes_out += adaptor->nio.bytes_out; nio->pkts_out += adaptor->nio.pkts_out; nio->errs_out += adaptor->nio.errs_out; nio->drops_out += adaptor->nio.drops_out; } } } return interface_count; }
/** * Populates nio with the counters accumulated for all of the non-virtual * adaptors, first ensuring that the accumulated counters are current. * Returns TRUE if there are adaptors for which their are counters 0, * FALSE otherwise. */ BOOL readNioCounters(HSP *sp, SFLHost_nio_counters *nio) { // may need to schedule intermediate calls to updateNioCounters() // too (to avoid undetected wraps), but at the very least we need to do // it here to make sure the data is up to the second. updateNioCounters(sp); BOOL gotData = FALSE; // just add up all the counters for the non-virtual adaptors for (uint32_t i = 0; i < sp->adaptorList->num_adaptors; i++) { SFLAdaptor *ad = sp->adaptorList->adaptors[i]; if (ad != NULL) { HSPAdaptorNIO *ctrs = (HSPAdaptorNIO *)ad->userData; if (ctrs != NULL && !ctrs->isVirtual) { gotData = TRUE; myLog(LOG_INFO, "readNioCounters: accumulating: pkts_in=%lu (device=%S virtual=%d)", ctrs->nio.pkts_in, ctrs->countersInstance, ctrs->isVirtual); nio->bytes_in += ctrs->nio.bytes_in; nio->pkts_in += ctrs->nio.pkts_in; nio->errs_in += ctrs->nio.errs_in; nio->drops_in += ctrs->nio.drops_in; nio->bytes_out += ctrs->nio.bytes_out; nio->pkts_out += ctrs->nio.pkts_out; nio->errs_out += ctrs->nio.errs_out; nio->drops_out += ctrs->nio.drops_out; } } } myLog(LOG_INFO,"readNioCounters: %lu adaptors\n\trbytes:\t%llu\n\trpkts:\t%lu\n\trdrops:\t%lu\n\trerrs:\t%lu\n\ttbytes:\t%llu\n\ttpkts:\t%lu\n\ttdrops:\t%lu\n\tterrs:\t%lu\n", sp->adaptorList->num_adaptors,nio->bytes_in,nio->pkts_in,nio->drops_in,nio->errs_in,nio->bytes_out,nio->pkts_out,nio->drops_out,nio->errs_out); return gotData; }
void agentCB_getCounters_interface(void *magic, SFLPoller *poller, SFL_COUNTERS_SAMPLE_TYPE *cs) { assert(poller->magic); HSP *sp = (HSP *)poller->magic; // device name was copied as userData char *devName = (char *)poller->userData; if(devName) { // look up the adaptor objects SFLAdaptor *adaptor = adaptorListGet(sp->adaptorList, devName); HSPAdaptorNIO *adaptorNIO = getAdaptorNIO(&sp->adaptorNIOList, devName); if(adaptor && adaptorNIO) { // make sure the counters are up to the second updateNioCounters(sp); // generic interface counters SFLCounters_sample_element elem = { 0 }; elem.tag = SFLCOUNTERS_GENERIC; elem.counterBlock.generic.ifIndex = poller->dsi.ds_index; elem.counterBlock.generic.ifType = 6; // assume ethernet elem.counterBlock.generic.ifSpeed = adaptor->ifSpeed; elem.counterBlock.generic.ifDirection = adaptor->ifDirection; elem.counterBlock.generic.ifStatus = 3; // ifAdminStatus==up, ifOperstatus==up elem.counterBlock.generic.ifPromiscuousMode = adaptor->promiscuous; elem.counterBlock.generic.ifInOctets = adaptorNIO->nio.bytes_in; elem.counterBlock.generic.ifInUcastPkts = adaptorNIO->nio.pkts_in; #define UNSUPPORTED_SFLOW_COUNTER32 (uint32_t)-1 elem.counterBlock.generic.ifInMulticastPkts = UNSUPPORTED_SFLOW_COUNTER32; elem.counterBlock.generic.ifInBroadcastPkts = UNSUPPORTED_SFLOW_COUNTER32; elem.counterBlock.generic.ifInDiscards = adaptorNIO->nio.drops_in; elem.counterBlock.generic.ifInErrors = adaptorNIO->nio.errs_in; elem.counterBlock.generic.ifInUnknownProtos = UNSUPPORTED_SFLOW_COUNTER32; elem.counterBlock.generic.ifOutOctets = adaptorNIO->nio.bytes_out; elem.counterBlock.generic.ifOutUcastPkts = adaptorNIO->nio.pkts_out; elem.counterBlock.generic.ifOutMulticastPkts = UNSUPPORTED_SFLOW_COUNTER32; elem.counterBlock.generic.ifOutBroadcastPkts = UNSUPPORTED_SFLOW_COUNTER32; elem.counterBlock.generic.ifOutDiscards = adaptorNIO->nio.drops_out; elem.counterBlock.generic.ifOutErrors = adaptorNIO->nio.errs_out; SFLADD_ELEMENT(cs, &elem); sfl_poller_writeCountersSample(poller, cs); } } }
int readNioCounters(HSP *sp, SFLHost_nio_counters *nio, char *devFilter, SFLAdaptorList *adList) { int interface_count = 0; size_t devFilterLen = devFilter ? strlen(devFilter) : 0; // may need to schedule intermediate calls to updateNioCounters() // too (to avoid undetected wraps), but at the very least we need to do // it here to make sure the data is up to the second. updateNioCounters(sp); for(int i = 0; i < sp->adaptorList->num_adaptors; i++) { SFLAdaptor *adaptor = sp->adaptorList->adaptors[i]; // note that the devFilter here is a prefix-match if(devFilter == NULL || !strncmp(devFilter, adaptor->deviceName, devFilterLen)) { if(adList == NULL || adaptorListGet(adList, adaptor->deviceName) != NULL) { HSPAdaptorNIO *niostate = (HSPAdaptorNIO *)adaptor->userData; // in the case where we are adding up across all // interfaces, be careful to avoid double-counting. // By leaving this test until now we make it possible // to know the counters for any interface or sub-interface // if required (e.g. for the readPackets() module). if(devFilter == NULL && (niostate->up == NO || niostate->vlan != HSP_VLAN_ALL || niostate->loopback || niostate->bond_master)) { continue; } interface_count++; // report the sum over all devices that match the filter nio->bytes_in += niostate->nio.bytes_in; nio->pkts_in += niostate->nio.pkts_in; nio->errs_in += niostate->nio.errs_in; nio->drops_in += niostate->nio.drops_in; nio->bytes_out += niostate->nio.bytes_out; nio->pkts_out += niostate->nio.pkts_out; nio->errs_out += niostate->nio.errs_out; nio->drops_out += niostate->nio.drops_out; } } } return interface_count; }
void agentCB_getCounters_interface(void *magic, SFLPoller *poller, SFL_COUNTERS_SAMPLE_TYPE *cs) { assert(poller->magic); HSP *sp = (HSP *)poller->magic; // device name was copied as userData char *devName = (char *)poller->userData; if(devName) { // look up the adaptor objects SFLAdaptor *adaptor = adaptorListGet(sp->adaptorList, devName); if(adaptor && adaptor->userData) { HSPAdaptorNIO *adaptorNIO = (HSPAdaptorNIO *)adaptor->userData; // make sure the counters are up to the second updateNioCounters(sp); // see if we were able to discern multicast and broadcast counters // by polling for ethtool stats. Be careful to use unsigned 32-bit // arithmetic here: #define UNSUPPORTED_SFLOW_COUNTER32 (uint32_t)-1 uint32_t pkts_in = adaptorNIO->nio.pkts_in; uint32_t pkts_out = adaptorNIO->nio.pkts_out; uint32_t mcasts_in = UNSUPPORTED_SFLOW_COUNTER32; uint32_t mcasts_out = UNSUPPORTED_SFLOW_COUNTER32; uint32_t bcasts_in = UNSUPPORTED_SFLOW_COUNTER32; uint32_t bcasts_out = UNSUPPORTED_SFLOW_COUNTER32; #ifdef HSP_ETHTOOL_STATS // only do this if we were able to find all four // via ethtool, otherwise it would just be too weird... if(adaptorNIO->et_nfound == 4) { mcasts_in = (uint32_t)adaptorNIO->et_total.mcasts_in; bcasts_in = (uint32_t)adaptorNIO->et_total.bcasts_in; pkts_in -= (mcasts_in + bcasts_in); mcasts_out = (uint32_t)adaptorNIO->et_total.mcasts_out; bcasts_out = (uint32_t)adaptorNIO->et_total.bcasts_out; pkts_out -= (mcasts_out + bcasts_out); } #endif // generic interface counters SFLCounters_sample_element elem = { 0 }; elem.tag = SFLCOUNTERS_GENERIC; elem.counterBlock.generic.ifIndex = poller->dsi.ds_index; elem.counterBlock.generic.ifType = 6; // assume ethernet elem.counterBlock.generic.ifSpeed = adaptor->ifSpeed; elem.counterBlock.generic.ifDirection = adaptor->ifDirection; elem.counterBlock.generic.ifStatus = adaptorNIO->up ? (SFLSTATUS_ADMIN_UP | SFLSTATUS_OPER_UP) : 0; elem.counterBlock.generic.ifPromiscuousMode = adaptor->promiscuous; elem.counterBlock.generic.ifInOctets = adaptorNIO->nio.bytes_in; elem.counterBlock.generic.ifInUcastPkts = pkts_in; elem.counterBlock.generic.ifInMulticastPkts = mcasts_in; elem.counterBlock.generic.ifInBroadcastPkts = bcasts_in; elem.counterBlock.generic.ifInDiscards = adaptorNIO->nio.drops_in; elem.counterBlock.generic.ifInErrors = adaptorNIO->nio.errs_in; elem.counterBlock.generic.ifInUnknownProtos = UNSUPPORTED_SFLOW_COUNTER32; elem.counterBlock.generic.ifOutOctets = adaptorNIO->nio.bytes_out; elem.counterBlock.generic.ifOutUcastPkts = pkts_out; elem.counterBlock.generic.ifOutMulticastPkts = mcasts_out; elem.counterBlock.generic.ifOutBroadcastPkts = bcasts_out; elem.counterBlock.generic.ifOutDiscards = adaptorNIO->nio.drops_out; elem.counterBlock.generic.ifOutErrors = adaptorNIO->nio.errs_out; SFLADD_ELEMENT(cs, &elem); // add optional interface name struct SFLCounters_sample_element pn_elem = { 0 }; pn_elem.tag = SFLCOUNTERS_PORTNAME; pn_elem.counterBlock.portName.portName.len = my_strlen(devName); pn_elem.counterBlock.portName.portName.str = devName; SFLADD_ELEMENT(cs, &pn_elem); // possibly include LACP struct for bond master or slave SFLCounters_sample_element lacp_elem = { 0 }; if(adaptorNIO->bond_master || adaptorNIO->bond_slave) { updateBondCounters(sp, adaptor); lacp_elem.tag = SFLCOUNTERS_LACP; lacp_elem.counterBlock.lacp = adaptorNIO->lacp; // struct copy SFLADD_ELEMENT(cs, &lacp_elem); } sfl_poller_writeCountersSample(poller, cs); } } }