doc: whitespace changes in licenses
[dpdk.git] / lib / librte_meter / rte_meter.h
1 /*-
2  *   BSD LICENSE
3  * 
4  *   Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  * 
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  * 
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  * 
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #ifndef __INCLUDE_RTE_METER_H__
35 #define __INCLUDE_RTE_METER_H__
36
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40
41 /**
42  * @file
43  * RTE Traffic Metering
44  *
45  * Traffic metering algorithms:
46  *    1. Single Rate Three Color Marker (srTCM): defined by IETF RFC 2697
47  *    2. Two Rate Three Color Marker (trTCM): defined by IETF RFC 2698
48  *
49  ***/
50
51 #include <stdint.h>
52
53 /*
54  * Application Programmer's Interface (API)
55  *
56  ***/
57
58 /** Packet Color Set */
59 enum rte_meter_color {
60         e_RTE_METER_GREEN = 0, /**< Green */
61         e_RTE_METER_YELLOW,    /**< Yellow */
62         e_RTE_METER_RED,       /**< Red */
63         e_RTE_METER_COLORS     /**< Number of available colors */
64 };
65
66 /** srTCM parameters per metered traffic flow. The CIR, CBS and EBS parameters only
67 count bytes of IP packets and do not include link specific headers. At least one of
68 the CBS or EBS parameters has to be greater than zero. */
69 struct rte_meter_srtcm_params {
70         uint64_t cir; /**< Committed Information Rate (CIR). Measured in bytes per second. */
71         uint64_t cbs; /**< Committed Burst Size (CBS).  Measured in bytes. */
72         uint64_t ebs; /**< Excess Burst Size (EBS).  Measured in bytes. */
73 };
74
75 /** trTCM parameters per metered traffic flow. The CIR, PIR, CBS and PBS parameters
76 only count bytes of IP packets and do not include link specific headers. PIR has to
77 be greater than or equal to CIR. Both CBS or EBS have to be greater than zero. */
78 struct rte_meter_trtcm_params {
79         uint64_t cir; /**< Committed Information Rate (CIR). Measured in bytes per second. */
80         uint64_t pir; /**< Peak Information Rate (PIR). Measured in bytes per second. */
81         uint64_t cbs; /**< Committed Burst Size (CBS). Measured in byes. */
82         uint64_t pbs; /**< Peak Burst Size (PBS). Measured in bytes. */
83 };
84
85 /** Internal data structure storing the srTCM run-time context per metered traffic flow. */
86 struct rte_meter_srtcm;
87
88 /** Internal data structure storing the trTCM run-time context per metered traffic flow. */
89 struct rte_meter_trtcm;
90
91 /**
92  * srTCM configuration per metered traffic flow
93  *
94  * @param m
95  *    Pointer to pre-allocated srTCM data structure
96  * @param params
97  *    User parameters per srTCM metered traffic flow
98  * @return
99  *    0 upon success, error code otherwise
100  */
101 int
102 rte_meter_srtcm_config(struct rte_meter_srtcm *m,
103         struct rte_meter_srtcm_params *params);
104
105 /**
106  * trTCM configuration per metered traffic flow
107  *
108  * @param m
109  *    Pointer to pre-allocated trTCM data structure
110  * @param params
111  *    User parameters per trTCM metered traffic flow
112  * @return
113  *    0 upon success, error code otherwise
114  */
115 int
116 rte_meter_trtcm_config(struct rte_meter_trtcm *m,
117         struct rte_meter_trtcm_params *params);
118
119 /**
120  * srTCM color blind traffic metering
121  *
122  * @param m
123  *    Handle to srTCM instance
124  * @param time
125  *    Current CPU time stamp (measured in CPU cycles)
126  * @param pkt_length
127  *    Length of the current IP packet (measured in bytes)
128  * @return
129  *    Color assigned to the current IP packet
130  */
131 static inline enum rte_meter_color
132 rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
133         uint64_t time,
134         uint32_t pkt_len);
135
136 /**
137  * srTCM color aware traffic metering
138  *
139  * @param m
140  *    Handle to srTCM instance
141  * @param time
142  *    Current CPU time stamp (measured in CPU cycles)
143  * @param pkt_length
144  *    Length of the current IP packet (measured in bytes)
145  * @param pkt_color
146  *    Input color of the current IP packet
147  * @return
148  *    Color assigned to the current IP packet
149  */
150 static inline enum rte_meter_color
151 rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
152         uint64_t time,
153         uint32_t pkt_len, 
154         enum rte_meter_color pkt_color);
155
156 /**
157  * trTCM color blind traffic metering
158  *
159  * @param m
160  *    Handle to trTCM instance
161  * @param time
162  *    Current CPU time stamp (measured in CPU cycles)
163  * @param pkt_length
164  *    Length of the current IP packet (measured in bytes)
165  * @return
166  *    Color assigned to the current IP packet
167  */
168 static inline enum rte_meter_color
169 rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
170         uint64_t time,
171         uint32_t pkt_len);
172
173 /**
174  * trTCM color aware traffic metering
175  *
176  * @param m
177  *    Handle to trTCM instance
178  * @param time
179  *    Current CPU time stamp (measured in CPU cycles)
180  * @param pkt_length
181  *    Length of the current IP packet (measured in bytes)
182  * @param pkt_color
183  *    Input color of the current IP packet
184  * @return
185  *    Color assigned to the current IP packet
186  */
187 static inline enum rte_meter_color
188 rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
189         uint64_t time,
190         uint32_t pkt_len,
191         enum rte_meter_color pkt_color);
192
193 /*
194  * Inline implementation of run-time methods
195  *
196  ***/
197  
198 /* Internal data structure storing the srTCM run-time context per metered traffic flow. */
199 struct rte_meter_srtcm {
200         uint64_t time; /* Time of latest update of C and E token buckets */
201         uint64_t tc;   /* Number of bytes currently available in the committed (C) token bucket */
202         uint64_t te;   /* Number of bytes currently available in the excess (E) token bucket */
203         uint64_t cbs;  /* Upper limit for C token bucket */
204         uint64_t ebs;  /* Upper limit for E token bucket */
205         uint64_t cir_period; /* Number of CPU cycles for one update of C and E token buckets */
206         uint64_t cir_bytes_per_period; /* Number of bytes to add to C and E token buckets on each update */
207 };
208
209 /* Internal data structure storing the trTCM run-time context per metered traffic flow. */
210 struct rte_meter_trtcm {
211         uint64_t time_tc; /* Time of latest update of C token bucket */
212         uint64_t time_tp; /* Time of latest update of E token bucket */
213         uint64_t tc;      /* Number of bytes currently available in the committed (C) token bucket */
214         uint64_t tp;      /* Number of bytes currently available in the peak (P) token bucket */
215         uint64_t cbs;     /* Upper limit for C token bucket */
216         uint64_t pbs;     /* Upper limit for P token bucket */
217         uint64_t cir_period; /* Number of CPU cycles for one update of C token bucket */
218         uint64_t cir_bytes_per_period; /* Number of bytes to add to C token bucket on each update */
219         uint64_t pir_period; /* Number of CPU cycles for one update of P token bucket */
220         uint64_t pir_bytes_per_period; /* Number of bytes to add to P token bucket on each update */
221 };
222
223 static inline enum rte_meter_color
224 rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m, 
225         uint64_t time,
226         uint32_t pkt_len)
227 {
228         uint64_t time_diff, n_periods, tc, te;
229         
230         /* Bucket update */
231         time_diff = time - m->time;
232         n_periods = time_diff / m->cir_period;
233         m->time += n_periods * m->cir_period;
234         
235         tc = m->tc + n_periods * m->cir_bytes_per_period;
236         if (tc > m->cbs)
237                 tc = m->cbs;
238         
239         te = m->te + n_periods * m->cir_bytes_per_period;
240         if (te > m->ebs)
241                 te = m->ebs;
242         
243         /* Color logic */
244         if (tc >= pkt_len) {
245                 m->tc = tc - pkt_len;
246                 m->te = te;
247                 return e_RTE_METER_GREEN;
248         }
249         
250         if (te >= pkt_len) {
251                 m->tc = tc;
252                 m->te = te - pkt_len;
253                 return e_RTE_METER_YELLOW;
254         }
255         
256         m->tc = tc;
257         m->te = te;
258         return e_RTE_METER_RED;
259 }
260
261 static inline enum rte_meter_color
262 rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
263         uint64_t time,
264         uint32_t pkt_len, 
265         enum rte_meter_color pkt_color)
266 {
267         uint64_t time_diff, n_periods, tc, te;
268         
269         /* Bucket update */
270         time_diff = time - m->time;
271         n_periods = time_diff / m->cir_period;
272         m->time += n_periods * m->cir_period;
273         
274         tc = m->tc + n_periods * m->cir_bytes_per_period;
275         if (tc > m->cbs)
276                 tc = m->cbs;
277         
278         te = m->te + n_periods * m->cir_bytes_per_period;
279         if (te > m->ebs)
280                 te = m->ebs;
281         
282         /* Color logic */
283         if ((pkt_color == e_RTE_METER_GREEN) && (tc >= pkt_len)) {
284                 m->tc = tc - pkt_len;
285                 m->te = te;
286                 return e_RTE_METER_GREEN;
287         }
288         
289         if ((pkt_color != e_RTE_METER_RED) && (te >= pkt_len)) {
290                 m->tc = tc;
291                 m->te = te - pkt_len;
292                 return e_RTE_METER_YELLOW;
293         }
294         
295         m->tc = tc;
296         m->te = te;
297         return e_RTE_METER_RED;
298 }
299
300 static inline enum rte_meter_color
301 rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
302         uint64_t time,
303         uint32_t pkt_len)
304 {
305         uint64_t time_diff_tc, time_diff_tp, n_periods_tc, n_periods_tp, tc, tp;
306         
307         /* Bucket update */
308         time_diff_tc = time - m->time_tc;
309         time_diff_tp = time - m->time_tp;
310         n_periods_tc = time_diff_tc / m->cir_period;
311         n_periods_tp = time_diff_tp / m->pir_period;
312         m->time_tc += n_periods_tc * m->cir_period;
313         m->time_tp += n_periods_tp * m->pir_period;
314         
315         tc = m->tc + n_periods_tc * m->cir_bytes_per_period;
316         if (tc > m->cbs)
317                 tc = m->cbs;
318                 
319         tp = m->tp + n_periods_tp * m->pir_bytes_per_period;
320         if (tp > m->pbs)
321                 tp = m->pbs;
322         
323         /* Color logic */
324         if (tp < pkt_len) {
325                 m->tc = tc;
326                 m->tp = tp;
327                 return e_RTE_METER_RED;
328         }
329         
330         if (tc < pkt_len) {
331                 m->tc = tc;
332                 m->tp = tp - pkt_len;
333                 return e_RTE_METER_YELLOW;
334         }
335         
336         m->tc = tc - pkt_len;
337         m->tp = tp - pkt_len;
338         return e_RTE_METER_GREEN;
339 }
340
341 static inline enum rte_meter_color
342 rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
343         uint64_t time,
344         uint32_t pkt_len, 
345         enum rte_meter_color pkt_color)
346 {
347         uint64_t time_diff_tc, time_diff_tp, n_periods_tc, n_periods_tp, tc, tp;
348         
349         /* Bucket update */
350         time_diff_tc = time - m->time_tc;
351         time_diff_tp = time - m->time_tp;
352         n_periods_tc = time_diff_tc / m->cir_period;
353         n_periods_tp = time_diff_tp / m->pir_period;
354         m->time_tc += n_periods_tc * m->cir_period;
355         m->time_tp += n_periods_tp * m->pir_period;
356         
357         tc = m->tc + n_periods_tc * m->cir_bytes_per_period;
358         if (tc > m->cbs)
359                 tc = m->cbs;
360                 
361         tp = m->tp + n_periods_tp * m->pir_bytes_per_period;
362         if (tp > m->pbs)
363                 tp = m->pbs;
364         
365         /* Color logic */
366         if ((pkt_color == e_RTE_METER_RED) || (tp < pkt_len)) {
367                 m->tc = tc;
368                 m->tp = tp;
369                 return e_RTE_METER_RED;
370         }
371         
372         if ((pkt_color == e_RTE_METER_YELLOW) || (tc < pkt_len)) {
373                 m->tc = tc;
374                 m->tp = tp - pkt_len;
375                 return e_RTE_METER_YELLOW;
376         }
377         
378         m->tc = tc - pkt_len;
379         m->tp = tp - pkt_len;
380         return e_RTE_METER_GREEN;
381 }
382
383 #ifdef __cplusplus
384 }
385 #endif
386
387 #endif /* __INCLUDE_RTE_METER_H__ */