Skip to content

Commit

Permalink
mod_sonic: accept max_header_size setting in Redis sFlow Global table…
Browse files Browse the repository at this point in the history
…, and disseminate to existing samplers
  • Loading branch information
sflow committed Jul 15, 2024
1 parent 2bb54ed commit 3acd3a1
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 2 deletions.
44 changes: 44 additions & 0 deletions src/Linux/hsflowd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1776,6 +1776,45 @@ extern "C" {
return NO;
}

/*_________________---------------------------__________________
_________________ evt_all_header_bytes __________________
-----------------___________________________------------------
*/

static void evt_all_header_bytes(EVMod *mod, EVEvent *evt, void *data, size_t dataLen) {
HSP *sp = (HSP *)EVROOTDATA(mod);
if(dataLen == sizeof(uint32_t)) {
uint32_t headerBytes = *(uint32_t *)data;
SFLSampler *samplers=NULL;
if(EVCurrentBus() == sp->packetBus)
samplers = sp->agent->samplers;
if(EVCurrentBus() == sp->pollBus)
samplers = sp->poll_agent->samplers;
for(SFLSampler *sm = samplers; sm; sm = sm->nxt) {
sfl_sampler_set_sFlowFsMaximumHeaderSize(sm, headerBytes);
}
}
}

/*_________________---------------------------__________________
_________________ updateHeaderBytes __________________
-----------------___________________________------------------
*/

static void updateHeaderBytes(HSP *sp) {
if(sp->sFlowSettings) {
// pick up the configured headerBytes
uint32_t headerBytes = sp->sFlowSettings->headerBytes;
// apply constraints
if(headerBytes > HSP_MAX_HEADER_BYTES) {
headerBytes = HSP_MAX_HEADER_BYTES;
myDebug(1, "limiting headerBytes to max: %u", headerBytes);
}
// make sure any existing samplers get the memo, in any thread
EVEventTxAll(sp->rootModule, HSPEVENT_HEADER_BYTES, &headerBytes, sizeof(headerBytes));
}
}

/*_________________---------------------------__________________
_________________ evt_config_first __________________
-----------------___________________________------------------
Expand Down Expand Up @@ -2016,6 +2055,9 @@ extern "C" {
// adjust the polling schedule to respect constraints. (This is also called
// if the interfaces change)
configSwitchPorts(sp); // in readPackets.c

// did the headerBytes setting change?
updateHeaderBytes(sp);
}

/*_________________---------------------------__________________
Expand Down Expand Up @@ -2571,6 +2613,8 @@ extern "C" {
}
// make sure every thread is notified on a change to the actual polling interval
EVEventRxAll(sp->rootModule, HSPEVENT_POLL_INTERVAL, evt_all_poll_interval);
// make sure every thread is notified on a change to the header bytes setting
EVEventRxAll(sp->rootModule, HSPEVENT_HEADER_BYTES, evt_all_header_bytes);

if(sp->DNSSD.DNSSD) {
EVLoadModule(sp->rootModule, "mod_dnssd", sp->modulesPath);
Expand Down
1 change: 1 addition & 0 deletions src/Linux/hsflowd.h
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ extern "C" {
#define HSPEVENT_REQUEST_POLLER "request_poller" // get counter samples for a switch port
#define HSPEVENT_FLUSH_DATAGRAM "flush_datagram" // flush datagram (e.g. on counters batch)
#define HSPEVENT_POLL_INTERVAL "poll_interval" // sent when actualPollingInterval changed
#define HSPEVENT_HEADER_BYTES "header_bytes" // (headerBytes) sent on config change

typedef struct _HSPPendingSample {
SFL_FLOW_SAMPLE_TYPE *fs;
Expand Down
5 changes: 4 additions & 1 deletion src/Linux/mod_pcap.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,10 @@ extern "C" {
}

// snaplen
if(pcap_set_snaplen(bpfs->pcap, sp->sFlowSettings_file->headerBytes) != 0)
// note that doing this here means we will not pick up any dynamic-config increase
// in the configured headerBytes (e.g. via DNS-SD). But it's not a problem for agents
// that require a restart on any change to the hsflowd.conf config file.
if(pcap_set_snaplen(bpfs->pcap, sp->sFlowSettings->headerBytes) != 0)
myLog(LOG_ERR, "pcap: pcap_set_snaplen(%s) failed", bpfs->deviceName);

// promiscuous mode
Expand Down
12 changes: 12 additions & 0 deletions src/Linux/mod_sonic.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ extern "C" {
#define HSP_SONIC_FIELD_SFLOW_AGENT "agent_id"
#define HSP_SONIC_FIELD_SFLOW_DROP_MONITOR_LIMIT "drop_monitor_limit" // *proposed*
#define HSP_SONIC_FIELD_SFLOW_SAMPLE_DIRECTION "sample_direction" // *proposed*
#define HSP_SONIC_FIELD_SFLOW_HEADER_BYTES "max_header_size" // *proposed*

#define HSP_SONIC_FIELD_COLLECTOR_IP "collector_ip"
#define HSP_SONIC_FIELD_COLLECTOR_PORT "collector_port"
Expand Down Expand Up @@ -207,6 +208,7 @@ extern "C" {
// sFlow config
bool sflow_enable;
uint32_t sflow_polling;
uint32_t sflow_headerBytes;
char *sflow_agent;
uint32_t sflow_dropLimit;
bool sflow_dropLimit_set;
Expand Down Expand Up @@ -1773,6 +1775,7 @@ extern "C" {
bool sflow_enable = NO;
char *sflow_agent = NULL;
uint32_t sflow_polling = HSP_SONIC_DEFAULT_POLLING_INTERVAL;
uint32_t sflow_headerBytes = SFL_DEFAULT_HEADER_SIZE;
uint32_t sflow_dropLimit = 0;
char *sflow_direction = NULL;
if(reply->type == REDIS_REPLY_ARRAY
Expand All @@ -1793,6 +1796,9 @@ extern "C" {
if(my_strequal(f_name->str, HSP_SONIC_FIELD_SFLOW_POLLING))
sflow_polling = db_getU32(f_val);

if(my_strequal(f_name->str, HSP_SONIC_FIELD_SFLOW_HEADER_BYTES))
sflow_headerBytes = db_getU32(f_val);

if(my_strequal(f_name->str, HSP_SONIC_FIELD_SFLOW_DROP_MONITOR_LIMIT)) {
sflow_dropLimit = db_getU32(f_val);
mdata->sflow_dropLimit_set = YES;
Expand Down Expand Up @@ -1820,6 +1826,10 @@ extern "C" {
EVDebug(mod, 1, "sflow_polling %u -> %u", mdata->sflow_polling, sflow_polling);
mdata->sflow_polling = sflow_polling;
}
if(sflow_headerBytes != mdata->sflow_headerBytes) {
EVDebug(mod, 1, "sflow_headerBytes %u -> %u", mdata->sflow_headerBytes, sflow_headerBytes);
mdata->sflow_headerBytes = sflow_headerBytes;
}
if(sflow_dropLimit != mdata->sflow_dropLimit) {
EVDebug(mod, 1, "sflow_dropLimit %u -> %u", mdata->sflow_dropLimit, sflow_dropLimit);
mdata->sflow_dropLimit = sflow_dropLimit;
Expand Down Expand Up @@ -2177,6 +2187,8 @@ extern "C" {
}
snprintf(cfgLine, EV_MAX_EVT_DATALEN, "polling=%u", mdata->sflow_polling);
EVEventTx(mod, mdata->configEvent, cfgLine, my_strlen(cfgLine));
snprintf(cfgLine, EV_MAX_EVT_DATALEN, "headerBytes=%u", mdata->sflow_headerBytes);
EVEventTx(mod, mdata->configEvent, cfgLine, my_strlen(cfgLine));
if(mdata->sflow_dropLimit_set) {
snprintf(cfgLine, EV_MAX_EVT_DATALEN, "dropLimit=%u", mdata->sflow_dropLimit);
EVEventTx(mod, mdata->configEvent, cfgLine, my_strlen(cfgLine));
Expand Down
2 changes: 1 addition & 1 deletion src/Linux/readPackets.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ extern "C" {
sfl_sampler_set_sFlowFsReceiver(adaptorNIO->sampler, HSP_SFLOW_RECEIVER_INDEX);
// TODO: adapt if headerBytes changes dynamically in config settings - broadcast event?
// same as for changes in polling interval or datagram size?
sfl_sampler_set_sFlowFsMaximumHeaderSize(adaptorNIO->sampler, sp->sFlowSettings_file->headerBytes);
sfl_sampler_set_sFlowFsMaximumHeaderSize(adaptorNIO->sampler, sp->sFlowSettings->headerBytes);
}
return adaptorNIO->sampler;
}
Expand Down

0 comments on commit 3acd3a1

Please sign in to comment.