Imported Upstream version 16.11
[deb_dpdk.git] / lib / librte_meter / rte_meter.h
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 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_len
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_len
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_len
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_len
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         /* Put the tokens overflowing from tc into te bucket */
236         tc = m->tc + n_periods * m->cir_bytes_per_period;
237         te = m->te;
238         if (tc > m->cbs) {
239                 te += (tc - m->cbs);
240                 if (te > m->ebs)
241                         te = m->ebs;
242                 tc = m->cbs;
243         }
244
245         /* Color logic */
246         if (tc >= pkt_len) {
247                 m->tc = tc - pkt_len;
248                 m->te = te;
249                 return e_RTE_METER_GREEN;
250         }
251
252         if (te >= pkt_len) {
253                 m->tc = tc;
254                 m->te = te - pkt_len;
255                 return e_RTE_METER_YELLOW;
256         }
257
258         m->tc = tc;
259         m->te = te;
260         return e_RTE_METER_RED;
261 }
262
263 static inline enum rte_meter_color
264 rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
265         uint64_t time,
266         uint32_t pkt_len,
267         enum rte_meter_color pkt_color)
268 {
269         uint64_t time_diff, n_periods, tc, te;
270
271         /* Bucket update */
272         time_diff = time - m->time;
273         n_periods = time_diff / m->cir_period;
274         m->time += n_periods * m->cir_period;
275
276         /* Put the tokens overflowing from tc into te bucket */
277         tc = m->tc + n_periods * m->cir_bytes_per_period;
278         te = m->te;
279         if (tc > m->cbs) {
280                 te += (tc - m->cbs);
281                 if (te > m->ebs)
282                         te = m->ebs;
283                 tc = m->cbs;
284         }
285
286         /* Color logic */
287         if ((pkt_color == e_RTE_METER_GREEN) && (tc >= pkt_len)) {
288                 m->tc = tc - pkt_len;
289                 m->te = te;
290                 return e_RTE_METER_GREEN;
291         }
292
293         if ((pkt_color != e_RTE_METER_RED) && (te >= pkt_len)) {
294                 m->tc = tc;
295                 m->te = te - pkt_len;
296                 return e_RTE_METER_YELLOW;
297         }
298
299         m->tc = tc;
300         m->te = te;
301         return e_RTE_METER_RED;
302 }
303
304 static inline enum rte_meter_color
305 rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
306         uint64_t time,
307         uint32_t pkt_len)
308 {
309         uint64_t time_diff_tc, time_diff_tp, n_periods_tc, n_periods_tp, tc, tp;
310
311         /* Bucket update */
312         time_diff_tc = time - m->time_tc;
313         time_diff_tp = time - m->time_tp;
314         n_periods_tc = time_diff_tc / m->cir_period;
315         n_periods_tp = time_diff_tp / m->pir_period;
316         m->time_tc += n_periods_tc * m->cir_period;
317         m->time_tp += n_periods_tp * m->pir_period;
318
319         tc = m->tc + n_periods_tc * m->cir_bytes_per_period;
320         if (tc > m->cbs)
321                 tc = m->cbs;
322
323         tp = m->tp + n_periods_tp * m->pir_bytes_per_period;
324         if (tp > m->pbs)
325                 tp = m->pbs;
326
327         /* Color logic */
328         if (tp < pkt_len) {
329                 m->tc = tc;
330                 m->tp = tp;
331                 return e_RTE_METER_RED;
332         }
333
334         if (tc < pkt_len) {
335                 m->tc = tc;
336                 m->tp = tp - pkt_len;
337                 return e_RTE_METER_YELLOW;
338         }
339
340         m->tc = tc - pkt_len;
341         m->tp = tp - pkt_len;
342         return e_RTE_METER_GREEN;
343 }
344
345 static inline enum rte_meter_color
346 rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
347         uint64_t time,
348         uint32_t pkt_len,
349         enum rte_meter_color pkt_color)
350 {
351         uint64_t time_diff_tc, time_diff_tp, n_periods_tc, n_periods_tp, tc, tp;
352
353         /* Bucket update */
354         time_diff_tc = time - m->time_tc;
355         time_diff_tp = time - m->time_tp;
356         n_periods_tc = time_diff_tc / m->cir_period;
357         n_periods_tp = time_diff_tp / m->pir_period;
358         m->time_tc += n_periods_tc * m->cir_period;
359         m->time_tp += n_periods_tp * m->pir_period;
360
361         tc = m->tc + n_periods_tc * m->cir_bytes_per_period;
362         if (tc > m->cbs)
363                 tc = m->cbs;
364
365         tp = m->tp + n_periods_tp * m->pir_bytes_per_period;
366         if (tp > m->pbs)
367                 tp = m->pbs;
368
369         /* Color logic */
370         if ((pkt_color == e_RTE_METER_RED) || (tp < pkt_len)) {
371                 m->tc = tc;
372                 m->tp = tp;
373                 return e_RTE_METER_RED;
374         }
375
376         if ((pkt_color == e_RTE_METER_YELLOW) || (tc < pkt_len)) {
377                 m->tc = tc;
378                 m->tp = tp - pkt_len;
379                 return e_RTE_METER_YELLOW;
380         }
381
382         m->tc = tc - pkt_len;
383         m->tp = tp - pkt_len;
384         return e_RTE_METER_GREEN;
385 }
386
387 #ifdef __cplusplus
388 }
389 #endif
390
391 #endif /* __INCLUDE_RTE_METER_H__ */