]> git.proxmox.com Git - mirror_ovs.git/blame - lib/sflow_api.h
netdev-offload-tc: Use single 'once' variable for probing tc features
[mirror_ovs.git] / lib / sflow_api.h
CommitLineData
7dd32dff
NM
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 */
c72e245a
BP
7
8#ifndef SFLOW_API_H
9#define SFLOW_API_H 1
10
11/* define SFLOW_DO_SOCKET to 1 if you want the agent
12 to send the packets itself, otherwise set the sendFn
13 callback in sfl_agent_init.*/
14/* #define SFLOW_DO_SOCKET */
15
b2befd5b
BP
16#include <sys/types.h>
17#include <netinet/in.h>
18#include <arpa/inet.h>
c72e245a
BP
19#include <stdio.h>
20#include <stdlib.h>
21#include <unistd.h>
22#include <errno.h>
23#include <string.h>
c72e245a
BP
24
25#ifdef SFLOW_DO_SOCKET
26#include <sys/socket.h>
27#include <netinet/in_systm.h>
c72e245a
BP
28#include <netinet/ip.h>
29#endif
30
31#include "sflow.h"
d295e8e9 32
c72e245a
BP
33/* define SFLOW_SOFTWARE_SAMPLING to 1 if you need to use the
34 sfl_sampler_takeSample routine and give it every packet */
35/* #define SFLOW_SOFTWARE_SAMPLING */
36
37/*
38 uncomment this preprocessor flag (or compile with -DSFL_USE_32BIT_INDEX)
39 if your ds_index numbers can ever be >= 2^30-1 (i.e. >= 0x3FFFFFFF)
40*/
41/* #define SFL_USE_32BIT_INDEX */
42
43
44/* Used to combine ds_class, ds_index and instance into
45 a single 64-bit number like this:
46 __________________________________
47 | cls| index | instance |
48 ----------------------------------
d295e8e9 49
c72e245a
BP
50 but now is opened up to a 12-byte struct to ensure
51 that ds_index has a full 32-bit field, and to make
52 accessing the components simpler. The macros have
53 the same behavior as before, so this change should
54 be transparent. The only difference is that these
55 objects are now passed around by reference instead
56 of by value, and the comparison is done using a fn.
57*/
58
59typedef struct _SFLDataSource_instance {
60 u_int32_t ds_class;
61 u_int32_t ds_index;
62 u_int32_t ds_instance;
63} SFLDataSource_instance;
64
65#ifdef SFL_USE_32BIT_INDEX
66#define SFL_FLOW_SAMPLE_TYPE SFLFlow_sample_expanded
67#define SFL_COUNTERS_SAMPLE_TYPE SFLCounters_sample_expanded
68#else
69#define SFL_FLOW_SAMPLE_TYPE SFLFlow_sample
70#define SFL_COUNTERS_SAMPLE_TYPE SFLCounters_sample
71/* if index numbers are not going to use all 32 bits, then we can use
72 the more compact encoding, with the dataSource class and index merged */
73#define SFL_DS_DATASOURCE(dsi) (((dsi).ds_class << 24) + (dsi).ds_index)
74#endif
75
76#define SFL_DS_INSTANCE(dsi) (dsi).ds_instance
77#define SFL_DS_CLASS(dsi) (dsi).ds_class
78#define SFL_DS_INDEX(dsi) (dsi).ds_index
79#define SFL_DS_SET(dsi,clss,indx,inst) \
80 do { \
81 (dsi).ds_class = (clss); \
82 (dsi).ds_index = (indx); \
83 (dsi).ds_instance = (inst); \
84 } while(0)
85
86typedef struct _SFLSampleCollector {
87 u_int32_t data[(SFL_MAX_DATAGRAM_SIZE + SFL_DATA_PAD) / sizeof(u_int32_t)];
88 u_int32_t *datap; /* packet fill pointer */
89 u_int32_t pktlen; /* accumulated size */
90 u_int32_t packetSeqNo;
91 u_int32_t numSamples;
92} SFLSampleCollector;
93
94struct _SFLAgent; /* forward decl */
95
96typedef struct _SFLReceiver {
97 struct _SFLReceiver *nxt;
98 /* MIB fields */
99 char *sFlowRcvrOwner;
100 time_t sFlowRcvrTimeout;
101 u_int32_t sFlowRcvrMaximumDatagramSize;
102 SFLAddress sFlowRcvrAddress;
103 u_int32_t sFlowRcvrPort;
104 u_int32_t sFlowRcvrDatagramVersion;
105 /* public fields */
106 struct _SFLAgent *agent; /* pointer to my agent */
107 /* private fields */
108 SFLSampleCollector sampleCollector;
109#ifdef SFLOW_DO_SOCKET
110 struct sockaddr_in receiver4;
111 struct sockaddr_in6 receiver6;
112#endif
113} SFLReceiver;
114
115typedef struct _SFLSampler {
116 /* for linked list */
117 struct _SFLSampler *nxt;
118 /* for hash lookup table */
119 struct _SFLSampler *hash_nxt;
120 /* MIB fields */
121 SFLDataSource_instance dsi;
122 u_int32_t sFlowFsReceiver;
123 u_int32_t sFlowFsPacketSamplingRate;
124 u_int32_t sFlowFsMaximumHeaderSize;
125 /* public fields */
126 struct _SFLAgent *agent; /* pointer to my agent */
127 /* private fields */
128 SFLReceiver *myReceiver;
129 u_int32_t skip;
130 u_int32_t samplePool;
131 u_int32_t flowSampleSeqNo;
132 /* rate checking */
133 u_int32_t samplesThisTick;
134 u_int32_t samplesLastTick;
135 u_int32_t backoffThreshold;
136} SFLSampler;
137
138/* declare */
139struct _SFLPoller;
140
141typedef void (*getCountersFn_t)(void *magic, /* callback to get counters */
142 struct _SFLPoller *sampler, /* called with self */
143 SFL_COUNTERS_SAMPLE_TYPE *cs); /* struct to fill in */
144
145typedef struct _SFLPoller {
146 /* for linked list */
147 struct _SFLPoller *nxt;
148 /* MIB fields */
149 SFLDataSource_instance dsi;
150 u_int32_t sFlowCpReceiver;
151 time_t sFlowCpInterval;
152 /* public fields */
153 struct _SFLAgent *agent; /* pointer to my agent */
154 void *magic; /* ptr to pass back in getCountersFn() */
155 getCountersFn_t getCountersFn;
156 u_int32_t bridgePort; /* port number local to bridge */
157 /* private fields */
158 SFLReceiver *myReceiver;
159 time_t countersCountdown;
160 u_int32_t countersSampleSeqNo;
161} SFLPoller;
162
163typedef void *(*allocFn_t)(void *magic, /* callback to allocate space on heap */
164 struct _SFLAgent *agent, /* called with self */
165 size_t bytes); /* bytes requested */
166
167typedef int (*freeFn_t)(void *magic, /* callback to free space on heap */
168 struct _SFLAgent *agent, /* called with self */
169 void *obj); /* obj to free */
170
171typedef void (*errorFn_t)(void *magic, /* callback to log error message */
172 struct _SFLAgent *agent, /* called with self */
173 char *msg); /* error message */
174
175typedef void (*sendFn_t)(void *magic, /* optional override fn to send packet */
176 struct _SFLAgent *agent,
177 SFLReceiver *receiver,
178 u_char *pkt,
179 u_int32_t pktLen);
180
181
182/* prime numbers are good for hash tables */
183#define SFL_HASHTABLE_SIZ 199
184
185typedef struct _SFLAgent {
186 SFLSampler *jumpTable[SFL_HASHTABLE_SIZ]; /* fast lookup table for samplers (by ifIndex) */
187 SFLSampler *samplers; /* the list of samplers */
188 SFLPoller *pollers; /* the list of samplers */
189 SFLReceiver *receivers; /* the array of receivers */
190 time_t bootTime; /* time when we booted or started */
191 time_t now; /* time now */
192 SFLAddress myIP; /* IP address of this node */
193 u_int32_t subId; /* sub_agent_id */
194 void *magic; /* ptr to pass back in logging and alloc fns */
195 allocFn_t allocFn;
196 freeFn_t freeFn;
197 errorFn_t errorFn;
198 sendFn_t sendFn;
199#ifdef SFLOW_DO_SOCKET
200 int receiverSocket4;
201 int receiverSocket6;
202#endif
203} SFLAgent;
204
205/* call this at the start with a newly created agent */
206void sfl_agent_init(SFLAgent *agent,
207 SFLAddress *myIP, /* IP address of this agent */
208 u_int32_t subId, /* agent_sub_id */
209 time_t bootTime, /* agent boot time */
210 time_t now, /* time now */
211 void *magic, /* ptr to pass back in logging and alloc fns */
212 allocFn_t allocFn,
213 freeFn_t freeFn,
214 errorFn_t errorFn,
215 sendFn_t sendFn);
216
217/* call this to create samplers */
218SFLSampler *sfl_agent_addSampler(SFLAgent *agent, SFLDataSource_instance *pdsi);
219
220/* call this to create pollers */
221SFLPoller *sfl_agent_addPoller(SFLAgent *agent,
222 SFLDataSource_instance *pdsi,
223 void *magic, /* ptr to pass back in getCountersFn() */
224 getCountersFn_t getCountersFn);
225
226/* call this to create receivers */
227SFLReceiver *sfl_agent_addReceiver(SFLAgent *agent);
228
229/* call this to remove samplers */
230int sfl_agent_removeSampler(SFLAgent *agent, SFLDataSource_instance *pdsi);
231
232/* call this to remove pollers */
233int sfl_agent_removePoller(SFLAgent *agent, SFLDataSource_instance *pdsi);
234
235/* note: receivers should not be removed. Typically the receivers
236 list will be created at init time and never changed */
237
238/* call these fns to retrieve sampler, poller or receiver (e.g. for SNMP GET or GETNEXT operation) */
239SFLSampler *sfl_agent_getSampler(SFLAgent *agent, SFLDataSource_instance *pdsi);
240SFLSampler *sfl_agent_getNextSampler(SFLAgent *agent, SFLDataSource_instance *pdsi);
241SFLPoller *sfl_agent_getPoller(SFLAgent *agent, SFLDataSource_instance *pdsi);
242SFLPoller *sfl_agent_getNextPoller(SFLAgent *agent, SFLDataSource_instance *pdsi);
243SFLReceiver *sfl_agent_getReceiver(SFLAgent *agent, u_int32_t receiverIndex);
244SFLReceiver *sfl_agent_getNextReceiver(SFLAgent *agent, u_int32_t receiverIndex);
245
246/* jump table access - for performance */
247SFLSampler *sfl_agent_getSamplerByIfIndex(SFLAgent *agent, u_int32_t ifIndex);
248
249/* call these functions to GET and SET MIB values */
250
251/* receiver */
252char * sfl_receiver_get_sFlowRcvrOwner(SFLReceiver *receiver);
253void sfl_receiver_set_sFlowRcvrOwner(SFLReceiver *receiver, char *sFlowRcvrOwner);
254time_t sfl_receiver_get_sFlowRcvrTimeout(SFLReceiver *receiver);
255void sfl_receiver_set_sFlowRcvrTimeout(SFLReceiver *receiver, time_t sFlowRcvrTimeout);
256u_int32_t sfl_receiver_get_sFlowRcvrMaximumDatagramSize(SFLReceiver *receiver);
257void sfl_receiver_set_sFlowRcvrMaximumDatagramSize(SFLReceiver *receiver, u_int32_t sFlowRcvrMaximumDatagramSize);
258SFLAddress *sfl_receiver_get_sFlowRcvrAddress(SFLReceiver *receiver);
259void sfl_receiver_set_sFlowRcvrAddress(SFLReceiver *receiver, SFLAddress *sFlowRcvrAddress);
260u_int32_t sfl_receiver_get_sFlowRcvrPort(SFLReceiver *receiver);
261void sfl_receiver_set_sFlowRcvrPort(SFLReceiver *receiver, u_int32_t sFlowRcvrPort);
262/* sampler */
263u_int32_t sfl_sampler_get_sFlowFsReceiver(SFLSampler *sampler);
264void sfl_sampler_set_sFlowFsReceiver(SFLSampler *sampler, u_int32_t sFlowFsReceiver);
265u_int32_t sfl_sampler_get_sFlowFsPacketSamplingRate(SFLSampler *sampler);
266void sfl_sampler_set_sFlowFsPacketSamplingRate(SFLSampler *sampler, u_int32_t sFlowFsPacketSamplingRate);
267u_int32_t sfl_sampler_get_sFlowFsMaximumHeaderSize(SFLSampler *sampler);
268void sfl_sampler_set_sFlowFsMaximumHeaderSize(SFLSampler *sampler, u_int32_t sFlowFsMaximumHeaderSize);
269u_int32_t sfl_sampler_get_samplesLastTick(SFLSampler *sampler);
270/* poller */
271u_int32_t sfl_poller_get_sFlowCpReceiver(SFLPoller *poller);
272void sfl_poller_set_sFlowCpReceiver(SFLPoller *poller, u_int32_t sFlowCpReceiver);
273u_int32_t sfl_poller_get_sFlowCpInterval(SFLPoller *poller);
274void sfl_poller_set_sFlowCpInterval(SFLPoller *poller, u_int32_t sFlowCpInterval);
275
276/* fns to set the sflow agent address or sub-id */
277void sfl_agent_set_agentAddress(SFLAgent *agent, SFLAddress *addr);
278void sfl_agent_set_agentSubId(SFLAgent *agent, u_int32_t subId);
279
280/* The poller may need a separate number to reference the local bridge port
281 to get counters if it is not the same as the global ifIndex */
282void sfl_poller_set_bridgePort(SFLPoller *poller, u_int32_t port_no);
283u_int32_t sfl_poller_get_bridgePort(SFLPoller *poller);
50b9699f 284SFLPoller *sfl_agent_getPollerByBridgePort(SFLAgent *agent, u_int32_t port_no);
c72e245a
BP
285
286/* call this to indicate a discontinuity with a counter like samplePool so that the
287 sflow collector will ignore the next delta */
288void sfl_sampler_resetFlowSeqNo(SFLSampler *sampler);
289
290/* call this to indicate a discontinuity with one or more of the counters so that the
291 sflow collector will ignore the next delta */
292void sfl_poller_resetCountersSeqNo(SFLPoller *poller);
293
294#ifdef SFLOW_SOFTWARE_SAMLING
295/* software sampling: call this with every packet - returns non-zero if the packet
296 should be sampled (in which case you then call sfl_sampler_writeFlowSample()) */
297int sfl_sampler_takeSample(SFLSampler *sampler);
298#endif
299
300/* call this to set a maximum samples-per-second threshold. If the sampler reaches this
301 threshold it will automatically back off the sampling rate. A value of 0 disables the
302 mechanism */
303void sfl_sampler_set_backoffThreshold(SFLSampler *sampler, u_int32_t samplesPerSecond);
304u_int32_t sfl_sampler_get_backoffThreshold(SFLSampler *sampler);
305
306/* call this once per second (N.B. not on interrupt stack i.e. not hard real-time) */
307void sfl_agent_tick(SFLAgent *agent, time_t now);
308
309/* call this with each flow sample */
310void sfl_sampler_writeFlowSample(SFLSampler *sampler, SFL_FLOW_SAMPLE_TYPE *fs);
311
312/* call this to push counters samples (usually done in the getCountersFn callback) */
313void sfl_poller_writeCountersSample(SFLPoller *poller, SFL_COUNTERS_SAMPLE_TYPE *cs);
314
315/* call this to deallocate resources */
316void sfl_agent_release(SFLAgent *agent);
317
318
319/* internal fns */
320
321void sfl_receiver_init(SFLReceiver *receiver, SFLAgent *agent);
322void sfl_sampler_init(SFLSampler *sampler, SFLAgent *agent, SFLDataSource_instance *pdsi);
323void sfl_poller_init(SFLPoller *poller, SFLAgent *agent, SFLDataSource_instance *pdsi, void *magic, getCountersFn_t getCountersFn);
324
325
326void sfl_receiver_tick(SFLReceiver *receiver, time_t now);
327void sfl_poller_tick(SFLPoller *poller, time_t now);
328void sfl_sampler_tick(SFLSampler *sampler, time_t now);
329
330int sfl_receiver_writeFlowSample(SFLReceiver *receiver, SFL_FLOW_SAMPLE_TYPE *fs);
331int sfl_receiver_writeCountersSample(SFLReceiver *receiver, SFL_COUNTERS_SAMPLE_TYPE *cs);
332
333void sfl_agent_resetReceiver(SFLAgent *agent, SFLReceiver *receiver);
334
335void sfl_agent_error(SFLAgent *agent, char *modName, char *msg);
336void sfl_agent_sysError(SFLAgent *agent, char *modName, char *msg);
337
338u_int32_t sfl_receiver_samplePacketsSent(SFLReceiver *receiver);
339
340#define SFL_ALLOC malloc
341#define SFL_FREE free
342
343#endif /* SFLOW_API_H */
344
345