ofp-msgs: New approach to encoding and decoding OpenFlow headers.
[openvswitch] / lib / sflow_api.h
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  */
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
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <errno.h>
20 #include <string.h>
21 #include <sys/types.h>
22 #include <arpa/inet.h> /* for htonl */
23
24 #ifdef SFLOW_DO_SOCKET
25 #include <sys/socket.h>
26 #include <netinet/in_systm.h>
27 #include <netinet/in.h>
28 #include <netinet/ip.h>
29 #endif
30
31 #include "sflow.h"
32
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    ----------------------------------
49
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
59 typedef 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
86 typedef 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
94 struct _SFLAgent;  /* forward decl */
95
96 typedef 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
115 typedef 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 */
139 struct _SFLPoller;
140
141 typedef 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
145 typedef 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
163 typedef 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
167 typedef 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
171 typedef void (*errorFn_t)(void *magic,                /* callback to log error message */
172                           struct _SFLAgent *agent,    /* called with self */
173                           char *msg);                 /* error message */
174
175 typedef 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
185 typedef 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 */
206 void 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 */
218 SFLSampler *sfl_agent_addSampler(SFLAgent *agent, SFLDataSource_instance *pdsi);
219
220 /* call this to create pollers */
221 SFLPoller *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 */
227 SFLReceiver *sfl_agent_addReceiver(SFLAgent *agent);
228
229 /* call this to remove samplers */
230 int sfl_agent_removeSampler(SFLAgent *agent, SFLDataSource_instance *pdsi);
231
232 /* call this to remove pollers */
233 int 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) */
239 SFLSampler  *sfl_agent_getSampler(SFLAgent *agent, SFLDataSource_instance *pdsi);
240 SFLSampler  *sfl_agent_getNextSampler(SFLAgent *agent, SFLDataSource_instance *pdsi);
241 SFLPoller   *sfl_agent_getPoller(SFLAgent *agent, SFLDataSource_instance *pdsi);
242 SFLPoller   *sfl_agent_getNextPoller(SFLAgent *agent, SFLDataSource_instance *pdsi);
243 SFLReceiver *sfl_agent_getReceiver(SFLAgent *agent, u_int32_t receiverIndex);
244 SFLReceiver *sfl_agent_getNextReceiver(SFLAgent *agent, u_int32_t receiverIndex);
245
246 /* jump table access - for performance */
247 SFLSampler *sfl_agent_getSamplerByIfIndex(SFLAgent *agent, u_int32_t ifIndex);
248
249 /* call these functions to GET and SET MIB values */
250
251 /* receiver */
252 char *      sfl_receiver_get_sFlowRcvrOwner(SFLReceiver *receiver);
253 void        sfl_receiver_set_sFlowRcvrOwner(SFLReceiver *receiver, char *sFlowRcvrOwner);
254 time_t      sfl_receiver_get_sFlowRcvrTimeout(SFLReceiver *receiver);
255 void        sfl_receiver_set_sFlowRcvrTimeout(SFLReceiver *receiver, time_t sFlowRcvrTimeout);
256 u_int32_t   sfl_receiver_get_sFlowRcvrMaximumDatagramSize(SFLReceiver *receiver);
257 void        sfl_receiver_set_sFlowRcvrMaximumDatagramSize(SFLReceiver *receiver, u_int32_t sFlowRcvrMaximumDatagramSize);
258 SFLAddress *sfl_receiver_get_sFlowRcvrAddress(SFLReceiver *receiver);
259 void        sfl_receiver_set_sFlowRcvrAddress(SFLReceiver *receiver, SFLAddress *sFlowRcvrAddress);
260 u_int32_t   sfl_receiver_get_sFlowRcvrPort(SFLReceiver *receiver);
261 void        sfl_receiver_set_sFlowRcvrPort(SFLReceiver *receiver, u_int32_t sFlowRcvrPort);
262 /* sampler */
263 u_int32_t sfl_sampler_get_sFlowFsReceiver(SFLSampler *sampler);
264 void      sfl_sampler_set_sFlowFsReceiver(SFLSampler *sampler, u_int32_t sFlowFsReceiver);
265 u_int32_t sfl_sampler_get_sFlowFsPacketSamplingRate(SFLSampler *sampler);
266 void      sfl_sampler_set_sFlowFsPacketSamplingRate(SFLSampler *sampler, u_int32_t sFlowFsPacketSamplingRate);
267 u_int32_t sfl_sampler_get_sFlowFsMaximumHeaderSize(SFLSampler *sampler);
268 void      sfl_sampler_set_sFlowFsMaximumHeaderSize(SFLSampler *sampler, u_int32_t sFlowFsMaximumHeaderSize);
269 u_int32_t sfl_sampler_get_samplesLastTick(SFLSampler *sampler);
270 /* poller */
271 u_int32_t sfl_poller_get_sFlowCpReceiver(SFLPoller *poller);
272 void      sfl_poller_set_sFlowCpReceiver(SFLPoller *poller, u_int32_t sFlowCpReceiver);
273 u_int32_t sfl_poller_get_sFlowCpInterval(SFLPoller *poller);
274 void      sfl_poller_set_sFlowCpInterval(SFLPoller *poller, u_int32_t sFlowCpInterval);
275
276 /* fns to set the sflow agent address or sub-id */
277 void sfl_agent_set_agentAddress(SFLAgent *agent, SFLAddress *addr);
278 void 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 */
282 void sfl_poller_set_bridgePort(SFLPoller *poller, u_int32_t port_no);
283 u_int32_t sfl_poller_get_bridgePort(SFLPoller *poller);
284
285 /* call this to indicate a discontinuity with a counter like samplePool so that the
286    sflow collector will ignore the next delta */
287 void sfl_sampler_resetFlowSeqNo(SFLSampler *sampler);
288
289 /* call this to indicate a discontinuity with one or more of the counters so that the
290    sflow collector will ignore the next delta */
291 void sfl_poller_resetCountersSeqNo(SFLPoller *poller);
292
293 #ifdef SFLOW_SOFTWARE_SAMLING
294 /* software sampling: call this with every packet - returns non-zero if the packet
295    should be sampled (in which case you then call sfl_sampler_writeFlowSample()) */
296 int sfl_sampler_takeSample(SFLSampler *sampler);
297 #endif
298
299 /* call this to set a maximum samples-per-second threshold. If the sampler reaches this
300    threshold it will automatically back off the sampling rate. A value of 0 disables the
301    mechanism */
302 void sfl_sampler_set_backoffThreshold(SFLSampler *sampler, u_int32_t samplesPerSecond);
303 u_int32_t sfl_sampler_get_backoffThreshold(SFLSampler *sampler);
304
305 /* call this once per second (N.B. not on interrupt stack i.e. not hard real-time) */
306 void sfl_agent_tick(SFLAgent *agent, time_t now);
307
308 /* call this with each flow sample */
309 void sfl_sampler_writeFlowSample(SFLSampler *sampler, SFL_FLOW_SAMPLE_TYPE *fs);
310
311 /* call this to push counters samples (usually done in the getCountersFn callback) */
312 void sfl_poller_writeCountersSample(SFLPoller *poller, SFL_COUNTERS_SAMPLE_TYPE *cs);
313
314 /* call this to deallocate resources */
315 void sfl_agent_release(SFLAgent *agent);
316
317
318 /* internal fns */
319
320 void sfl_receiver_init(SFLReceiver *receiver, SFLAgent *agent);
321 void sfl_sampler_init(SFLSampler *sampler, SFLAgent *agent, SFLDataSource_instance *pdsi);
322 void sfl_poller_init(SFLPoller *poller, SFLAgent *agent, SFLDataSource_instance *pdsi, void *magic, getCountersFn_t getCountersFn);
323
324
325 void sfl_receiver_tick(SFLReceiver *receiver, time_t now);
326 void sfl_poller_tick(SFLPoller *poller, time_t now);
327 void sfl_sampler_tick(SFLSampler *sampler, time_t now);
328
329 int sfl_receiver_writeFlowSample(SFLReceiver *receiver, SFL_FLOW_SAMPLE_TYPE *fs);
330 int sfl_receiver_writeCountersSample(SFLReceiver *receiver, SFL_COUNTERS_SAMPLE_TYPE *cs);
331
332 void sfl_agent_resetReceiver(SFLAgent *agent, SFLReceiver *receiver);
333
334 void sfl_agent_error(SFLAgent *agent, char *modName, char *msg);
335 void sfl_agent_sysError(SFLAgent *agent, char *modName, char *msg);
336
337 u_int32_t sfl_receiver_samplePacketsSent(SFLReceiver *receiver);
338
339 #define SFL_ALLOC malloc
340 #define SFL_FREE free
341
342 #endif /* SFLOW_API_H */
343
344