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