void readBondState(HSP *sp) { for(uint32_t i = 0; i < sp->adaptorList->num_adaptors; i++) { SFLAdaptor *adaptor = sp->adaptorList->adaptors[i]; if(adaptor && adaptor->ifIndex) { HSPAdaptorNIO *niostate = (HSPAdaptorNIO *)adaptor->userData; if(niostate) { if(niostate->bond_master) { updateBondCounters(sp, adaptor); } } } } }
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); } } }