eb4a825277334fbbe9426f6d54b1e6a020d719a1
[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
35 #ifndef __INCLUDE_RTE_METER_H__
36 #define __INCLUDE_RTE_METER_H__
37
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41
42 /**
43  * @file
44  * RTE Traffic Metering
45  *
46  * Traffic metering algorithms:
47  *    1. Single Rate Three Color Marker (srTCM): defined by IETF RFC 2697
48  *    2. Two Rate Three Color Marker (trTCM): defined by IETF RFC 2698
49  *
50  ***/
51
52 #include <stdint.h>
53
54 /*
55  * Application Programmer's Interface (API)
56  *
57  ***/
58
59 /** Packet Color Set */
60 enum rte_meter_color {
61         e_RTE_METER_GREEN = 0, /**< Green */
62         e_RTE_METER_YELLOW,    /**< Yellow */
63         e_RTE_METER_RED,       /**< Red */
64         e_RTE_METER_COLORS     /**< Number of available colors */
65 };
66
67 /** srTCM parameters per metered traffic flow. The CIR, CBS and EBS parameters only
68 count bytes of IP packets and do not include link specific headers. At least one of
69 the CBS or EBS parameters has to be greater than zero. */
70 struct rte_meter_srtcm_params {
71         uint64_t cir; /**< Committed Information Rate (CIR). Measured in bytes per second. */
72         uint64_t cbs; /**< Committed Burst Size (CBS).  Measured in bytes. */
73         uint64_t ebs; /**< Excess Burst Size (EBS).  Measured in bytes. */
74 };
75
76 /** trTCM parameters per metered traffic flow. The CIR, PIR, CBS and PBS parameters
77 only count bytes of IP packets and do not include link specific headers. PIR has to
78 be greater than or equal to CIR. Both CBS or EBS have to be greater than zero. */
79 struct rte_meter_trtcm_params {
80         uint64_t cir; /**< Committed Information Rate (CIR). Measured in bytes per second. */
81         uint64_t pir; /**< Peak Information Rate (PIR). Measured in bytes per second. */
82         uint64_t cbs; /**< Committed Burst Size (CBS). Measured in byes. */
83         uint64_t pbs; /**< Peak Burst Size (PBS). Measured in bytes. */
84 };
85
86 /** Internal data structure storing the srTCM run-time context per metered traffic flow. */
87 struct rte_meter_srtcm;
88
89 /** Internal data structure storing the trTCM run-time context per metered traffic flow. */
90 struct rte_meter_trtcm;
91
92 /**
93  * srTCM configuration per metered traffic flow
94  *
95  * @param m
96  *    Pointer to pre-allocated srTCM data structure
97  * @param params
98  *    User parameters per srTCM metered traffic flow
99  * @return
100  *    0 upon success, error code otherwise
101  */
102 int
103 rte_meter_srtcm_config(struct rte_meter_srtcm *m,
104         struct rte_meter_srtcm_params *params);
105
106 /**
107  * trTCM configuration per metered traffic flow
108  *
109  * @param m
110  *    Pointer to pre-allocated trTCM data structure
111  * @param params
112  *    User parameters per trTCM metered traffic flow
113  * @return
114  *    0 upon success, error code otherwise
115  */
116 int
117 rte_meter_trtcm_config(struct rte_meter_trtcm *m,
118         struct rte_meter_trtcm_params *params);
119
120 /**
121  * srTCM color blind traffic metering
122  *
123  * @param m
124  *    Handle to srTCM instance
125  * @param time
126  *    Current CPU time stamp (measured in CPU cycles)
127  * @param pkt_length
128  *    Length of the current IP packet (measured in bytes)
129  * @return
130  *    Color assigned to the current IP packet
131  */
132 static inline enum rte_meter_color
133 rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
134         uint64_t time,
135         uint32_t pkt_len);
136
137 /**
138  * srTCM color aware traffic metering
139  *
140  * @param m
141  *    Handle to srTCM instance
142  * @param time
143  *    Current CPU time stamp (measured in CPU cycles)
144  * @param pkt_length
145  *    Length of the current IP packet (measured in bytes)
146  * @param pkt_color
147  *    Input color of the current IP packet
148  * @return
149  *    Color assigned to the current IP packet
150  */
151 static inline enum rte_meter_color
152 rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
153         uint64_t time,
154         uint32_t pkt_len, 
155         enum rte_meter_color pkt_color);
156
157 /**
158  * trTCM color blind traffic metering
159  *
160  * @param m
161  *    Handle to trTCM instance
162  * @param time
163  *    Current CPU time stamp (measured in CPU cycles)
164  * @param pkt_length
165  *    Length of the current IP packet (measured in bytes)
166  * @return
167  *    Color assigned to the current IP packet
168  */
169 static inline enum rte_meter_color
170 rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
171         uint64_t time,
172         uint32_t pkt_len);
173
174 /**
175  * trTCM color aware traffic metering
176  *
177  * @param m
178  *    Handle to trTCM instance
179  * @param time
180  *    Current CPU time stamp (measured in CPU cycles)
181  * @param pkt_length
182  *    Length of the current IP packet (measured in bytes)
183  * @param pkt_color
184  *    Input color of the current IP packet
185  * @return
186  *    Color assigned to the current IP packet
187  */
188 static inline enum rte_meter_color
189 rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
190         uint64_t time,
191         uint32_t pkt_len,
192         enum rte_meter_color pkt_color);
193
194 /*
195  * Inline implementation of run-time methods
196  *
197  ***/
198  
199 /* Internal data structure storing the srTCM run-time context per metered traffic flow. */
200 struct rte_meter_srtcm {
201         uint64_t time; /* Time of latest update of C and E token buckets */
202         uint64_t tc;   /* Number of bytes currently available in the committed (C) token bucket */
203         uint64_t te;   /* Number of bytes currently available in the excess (E) token bucket */
204         uint64_t cbs;  /* Upper limit for C token bucket */
205         uint64_t ebs;  /* Upper limit for E token bucket */
206         uint64_t cir_period; /* Number of CPU cycles for one update of C and E token buckets */
207         uint64_t cir_bytes_per_period; /* Number of bytes to add to C and E token buckets on each update */
208 };
209
210 /* Internal data structure storing the trTCM run-time context per metered traffic flow. */
211 struct rte_meter_trtcm {
212         uint64_t time_tc; /* Time of latest update of C token bucket */
213         uint64_t time_tp; /* Time of latest update of E token bucket */
214         uint64_t tc;      /* Number of bytes currently available in the committed (C) token bucket */
215         uint64_t tp;      /* Number of bytes currently available in the peak (P) token bucket */
216         uint64_t cbs;     /* Upper limit for C token bucket */
217         uint64_t pbs;     /* Upper limit for P token bucket */
218         uint64_t cir_period; /* Number of CPU cycles for one update of C token bucket */
219         uint64_t cir_bytes_per_period; /* Number of bytes to add to C token bucket on each update */
220         uint64_t pir_period; /* Number of CPU cycles for one update of P token bucket */
221         uint64_t pir_bytes_per_period; /* Number of bytes to add to P token bucket on each update */
222 };
223
224 static inline enum rte_meter_color
225 rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m, 
226         uint64_t time,
227         uint32_t pkt_len)
228 {
229         uint64_t time_diff, n_periods, tc, te;
230         
231         /* Bucket update */
232         time_diff = time - m->time;
233         n_periods = time_diff / m->cir_period;
234         m->time += n_periods * m->cir_period;
235         
236         tc = m->tc + n_periods * m->cir_bytes_per_period;
237         if (tc > m->cbs)
238                 tc = m->cbs;
239         
240         te = m->te + n_periods * m->cir_bytes_per_period;
241         if (te > m->ebs)
242                 te = m->ebs;
243         
244         /* Color logic */
245         if (tc >= pkt_len) {
246                 m->tc = tc - pkt_len;
247                 m->te = te;
248                 return e_RTE_METER_GREEN;
249         }
250         
251         if (te >= pkt_len) {
252                 m->tc = tc;
253                 m->te = te - pkt_len;
254                 return e_RTE_METER_YELLOW;
255         }
256         
257         m->tc = tc;
258         m->te = te;
259         return e_RTE_METER_RED;
260 }
261
262 static inline enum rte_meter_color
263 rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
264         uint64_t time,
265         uint32_t pkt_len, 
266         enum rte_meter_color pkt_color)
267 {
268         uint64_t time_diff, n_periods, tc, te;
269         
270         /* Bucket update */
271         time_diff = time - m->time;
272         n_periods = time_diff / m->cir_period;
273         m->time += n_periods * m->cir_period;
274         
275         tc = m->tc + n_periods * m->cir_bytes_per_period;
276         if (tc > m->cbs)
277                 tc = m->cbs;
278         
279         te = m->te + n_periods * m->cir_bytes_per_period;
280         if (te > m->ebs)
281                 te = m->ebs;
282         
283         /* Color logic */
284         if ((pkt_color == e_RTE_METER_GREEN) && (tc >= pkt_len)) {
285                 m->tc = tc - pkt_len;
286                 m->te = te;
287                 return e_RTE_METER_GREEN;
288         }
289         
290         if ((pkt_color != e_RTE_METER_RED) && (te >= pkt_len)) {
291                 m->tc = tc;
292                 m->te = te - pkt_len;
293                 return e_RTE_METER_YELLOW;
294         }
295         
296         m->tc = tc;
297         m->te = te;
298         return e_RTE_METER_RED;
299 }
300
301 static inline enum rte_meter_color
302 rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
303         uint64_t time,
304         uint32_t pkt_len)
305 {
306         uint64_t time_diff_tc, time_diff_tp, n_periods_tc, n_periods_tp, tc, tp;
307         
308         /* Bucket update */
309         time_diff_tc = time - m->time_tc;
310         time_diff_tp = time - m->time_tp;
311         n_periods_tc = time_diff_tc / m->cir_period;
312         n_periods_tp = time_diff_tp / m->pir_period;
313         m->time_tc += n_periods_tc * m->cir_period;
314         m->time_tp += n_periods_tp * m->pir_period;
315         
316         tc = m->tc + n_periods_tc * m->cir_bytes_per_period;
317         if (tc > m->cbs)
318                 tc = m->cbs;
319                 
320         tp = m->tp + n_periods_tp * m->pir_bytes_per_period;
321         if (tp > m->pbs)
322                 tp = m->pbs;
323         
324         /* Color logic */
325         if (tp < pkt_len) {
326                 m->tc = tc;
327                 m->tp = tp;
328                 return e_RTE_METER_RED;
329         }
330         
331         if (tc < pkt_len) {
332                 m->tc = tc;
333                 m->tp = tp - pkt_len;
334                 return e_RTE_METER_YELLOW;
335         }
336         
337         m->tc = tc - pkt_len;
338         m->tp = tp - pkt_len;
339         return e_RTE_METER_GREEN;
340 }
341
342 static inline enum rte_meter_color
343 rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
344         uint64_t time,
345         uint32_t pkt_len, 
346         enum rte_meter_color pkt_color)
347 {
348         uint64_t time_diff_tc, time_diff_tp, n_periods_tc, n_periods_tp, tc, tp;
349         
350         /* Bucket update */
351         time_diff_tc = time - m->time_tc;
352         time_diff_tp = time - m->time_tp;
353         n_periods_tc = time_diff_tc / m->cir_period;
354         n_periods_tp = time_diff_tp / m->pir_period;
355         m->time_tc += n_periods_tc * m->cir_period;
356         m->time_tp += n_periods_tp * m->pir_period;
357         
358         tc = m->tc + n_periods_tc * m->cir_bytes_per_period;
359         if (tc > m->cbs)
360                 tc = m->cbs;
361                 
362         tp = m->tp + n_periods_tp * m->pir_bytes_per_period;
363         if (tp > m->pbs)
364                 tp = m->pbs;
365         
366         /* Color logic */
367         if ((pkt_color == e_RTE_METER_RED) || (tp < pkt_len)) {
368                 m->tc = tc;
369                 m->tp = tp;
370                 return e_RTE_METER_RED;
371         }
372         
373         if ((pkt_color == e_RTE_METER_YELLOW) || (tc < pkt_len)) {
374                 m->tc = tc;
375                 m->tp = tp - pkt_len;
376                 return e_RTE_METER_YELLOW;
377         }
378         
379         m->tc = tc - pkt_len;
380         m->tp = tp - pkt_len;
381         return e_RTE_METER_GREEN;
382 }
383
384 #ifdef __cplusplus
385 }
386 #endif
387
388 #endif /* __INCLUDE_RTE_METER_H__ */