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