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