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