treewide: Remove trailing whitespace
[sliver-openvswitch.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