meter: support RFC4115 trTCM
[dpdk.git] / lib / librte_meter / rte_meter.h
1
2 /* SPDX-License-Identifier: BSD-3-Clause
3  * Copyright(c) 2010-2014 Intel Corporation
4  */
5
6 #ifndef __INCLUDE_RTE_METER_H__
7 #define __INCLUDE_RTE_METER_H__
8
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12
13 /**
14  * @file
15  * RTE Traffic Metering
16  *
17  * Traffic metering algorithms:
18  *    1. Single Rate Three Color Marker (srTCM): defined by IETF RFC 2697
19  *    2. Two Rate Three Color Marker (trTCM): defined by IETF RFC 2698
20  *    3. Two Rate Three Color Marker (trTCM): defined by IETF RFC 4115
21  *
22  ***/
23
24 #include <stdint.h>
25
26 #include "rte_compat.h"
27
28 /*
29  * Application Programmer's Interface (API)
30  *
31  ***/
32
33 /**
34  * Color
35  */
36 enum rte_color {
37         RTE_COLOR_GREEN = 0, /**< Green */
38         RTE_COLOR_YELLOW, /**< Yellow */
39         RTE_COLOR_RED, /**< Red */
40         RTE_COLORS /**< Number of colors */
41 };
42
43 /* New rte_color is defined and used to deprecate rte_meter_color soon. */
44 #define rte_meter_color rte_color
45 #define e_RTE_METER_GREEN RTE_COLOR_GREEN
46 #define e_RTE_METER_YELLOW RTE_COLOR_YELLOW
47 #define e_RTE_METER_RED RTE_COLOR_RED
48 #define e_RTE_METER_COLORS RTE_COLORS
49
50 /** srTCM parameters per metered traffic flow. The CIR, CBS and EBS parameters only
51 count bytes of IP packets and do not include link specific headers. At least one of
52 the CBS or EBS parameters has to be greater than zero. */
53 struct rte_meter_srtcm_params {
54         uint64_t cir; /**< Committed Information Rate (CIR). Measured in bytes per second. */
55         uint64_t cbs; /**< Committed Burst Size (CBS).  Measured in bytes. */
56         uint64_t ebs; /**< Excess Burst Size (EBS).  Measured in bytes. */
57 };
58
59 /** trTCM parameters per metered traffic flow. The CIR, PIR, CBS and PBS parameters
60 only count bytes of IP packets and do not include link specific headers. PIR has to
61 be greater than or equal to CIR. Both CBS or EBS have to be greater than zero. */
62 struct rte_meter_trtcm_params {
63         uint64_t cir; /**< Committed Information Rate (CIR). Measured in bytes per second. */
64         uint64_t pir; /**< Peak Information Rate (PIR). Measured in bytes per second. */
65         uint64_t cbs; /**< Committed Burst Size (CBS). Measured in bytes. */
66         uint64_t pbs; /**< Peak Burst Size (PBS). Measured in bytes. */
67 };
68
69 /** trTCM parameters per metered traffic flow. The CIR, EIR, CBS and EBS
70 parameters only count bytes of IP packets and do not include link specific
71 headers. The CBS and EBS need to be greater than zero if CIR and EIR are
72 none-zero respectively.*/
73 struct rte_meter_trtcm_rfc4115_params {
74         uint64_t cir; /**< Committed Information Rate (CIR). Measured in bytes per second. */
75         uint64_t eir; /**< Excess Information Rate (EIR). Measured in bytes per second. */
76         uint64_t cbs; /**< Committed Burst Size (CBS). Measured in bytes. */
77         uint64_t ebs; /**< Excess Burst Size (EBS). Measured in bytes. */
78 };
79
80 /**
81  * Internal data structure storing the srTCM configuration profile. Typically
82  * shared by multiple srTCM objects.
83  */
84 struct rte_meter_srtcm_profile;
85
86 /**
87  * Internal data structure storing the trTCM configuration profile. Typically
88  * shared by multiple trTCM objects.
89  */
90 struct rte_meter_trtcm_profile;
91
92 /**
93  * Internal data structure storing the trTCM RFC4115 configuration profile.
94  * Typically shared by multiple trTCM objects.
95  */
96 struct rte_meter_trtcm_rfc4115_profile;
97
98 /** Internal data structure storing the srTCM run-time context per metered traffic flow. */
99 struct rte_meter_srtcm;
100
101 /** Internal data structure storing the trTCM run-time context per metered traffic flow. */
102 struct rte_meter_trtcm;
103
104 /**
105  * Internal data structure storing the trTCM RFC4115 run-time context per
106  * metered traffic flow.
107  */
108 struct rte_meter_trtcm_rfc4115;
109
110 /**
111  * srTCM profile configuration
112  *
113  * @param p
114  *    Pointer to pre-allocated srTCM profile data structure
115  * @param params
116  *    srTCM profile parameters
117  * @return
118  *    0 upon success, error code otherwise
119  */
120 int
121 rte_meter_srtcm_profile_config(struct rte_meter_srtcm_profile *p,
122         struct rte_meter_srtcm_params *params);
123
124 /**
125  * trTCM profile configuration
126  *
127  * @param p
128  *    Pointer to pre-allocated trTCM profile data structure
129  * @param params
130  *    trTCM profile parameters
131  * @return
132  *    0 upon success, error code otherwise
133  */
134 int
135 rte_meter_trtcm_profile_config(struct rte_meter_trtcm_profile *p,
136         struct rte_meter_trtcm_params *params);
137 /**
138  * @warning
139  * @b EXPERIMENTAL: this API may change without prior notice
140  *
141  * trTCM RFC 4115 profile configuration
142  *
143  * @param p
144  *    Pointer to pre-allocated trTCM profile data structure
145  * @param params
146  *    trTCM profile parameters
147  * @return
148  *    0 upon success, error code otherwise
149  */
150 int __rte_experimental
151 rte_meter_trtcm_rfc4115_profile_config(
152         struct rte_meter_trtcm_rfc4115_profile *p,
153         struct rte_meter_trtcm_rfc4115_params *params);
154
155 /**
156  * srTCM configuration per metered traffic flow
157  *
158  * @param m
159  *    Pointer to pre-allocated srTCM data structure
160  * @param p
161  *    srTCM profile. Needs to be valid.
162  * @return
163  *    0 upon success, error code otherwise
164  */
165 int
166 rte_meter_srtcm_config(struct rte_meter_srtcm *m,
167         struct rte_meter_srtcm_profile *p);
168
169 /**
170  * trTCM configuration per metered traffic flow
171  *
172  * @param m
173  *    Pointer to pre-allocated trTCM data structure
174  * @param p
175  *    trTCM profile. Needs to be valid.
176  * @return
177  *    0 upon success, error code otherwise
178  */
179 int
180 rte_meter_trtcm_config(struct rte_meter_trtcm *m,
181         struct rte_meter_trtcm_profile *p);
182
183 /**
184  * @warning
185  * @b EXPERIMENTAL: this API may change without prior notice
186  *
187  * trTCM RFC 4115 configuration per metered traffic flow
188  *
189  * @param m
190  *    Pointer to pre-allocated trTCM data structure
191  * @param p
192  *    trTCM profile. Needs to be valid.
193  * @return
194  *    0 upon success, error code otherwise
195  */
196 int __rte_experimental
197 rte_meter_trtcm_rfc4115_config(struct rte_meter_trtcm_rfc4115 *m,
198         struct rte_meter_trtcm_rfc4115_profile *p);
199
200 /**
201  * srTCM color blind traffic metering
202  *
203  * @param m
204  *    Handle to srTCM instance
205  * @param p
206  *    srTCM profile specified at srTCM object creation time
207  * @param time
208  *    Current CPU time stamp (measured in CPU cycles)
209  * @param pkt_len
210  *    Length of the current IP packet (measured in bytes)
211  * @return
212  *    Color assigned to the current IP packet
213  */
214 static inline enum rte_meter_color
215 rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
216         struct rte_meter_srtcm_profile *p,
217         uint64_t time,
218         uint32_t pkt_len);
219
220 /**
221  * srTCM color aware traffic metering
222  *
223  * @param m
224  *    Handle to srTCM instance
225  * @param p
226  *    srTCM profile specified at srTCM object creation time
227  * @param time
228  *    Current CPU time stamp (measured in CPU cycles)
229  * @param pkt_len
230  *    Length of the current IP packet (measured in bytes)
231  * @param pkt_color
232  *    Input color of the current IP packet
233  * @return
234  *    Color assigned to the current IP packet
235  */
236 static inline enum rte_meter_color
237 rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
238         struct rte_meter_srtcm_profile *p,
239         uint64_t time,
240         uint32_t pkt_len,
241         enum rte_meter_color pkt_color);
242
243 /**
244  * trTCM color blind traffic metering
245  *
246  * @param m
247  *    Handle to trTCM instance
248  * @param p
249  *    trTCM profile specified at trTCM object creation time
250  * @param time
251  *    Current CPU time stamp (measured in CPU cycles)
252  * @param pkt_len
253  *    Length of the current IP packet (measured in bytes)
254  * @return
255  *    Color assigned to the current IP packet
256  */
257 static inline enum rte_meter_color
258 rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
259         struct rte_meter_trtcm_profile *p,
260         uint64_t time,
261         uint32_t pkt_len);
262
263 /**
264  * trTCM color aware traffic metering
265  *
266  * @param m
267  *    Handle to trTCM instance
268  * @param p
269  *    trTCM profile specified at trTCM object creation time
270  * @param time
271  *    Current CPU time stamp (measured in CPU cycles)
272  * @param pkt_len
273  *    Length of the current IP packet (measured in bytes)
274  * @param pkt_color
275  *    Input color of the current IP packet
276  * @return
277  *    Color assigned to the current IP packet
278  */
279 static inline enum rte_meter_color
280 rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
281         struct rte_meter_trtcm_profile *p,
282         uint64_t time,
283         uint32_t pkt_len,
284         enum rte_meter_color pkt_color);
285
286 /**
287  * @warning
288  * @b EXPERIMENTAL: this API may change without prior notice
289  *
290  * trTCM RFC4115 color blind traffic metering
291  *
292  * @param m
293  *    Handle to trTCM instance
294  * @param p
295  *    trTCM profile specified at trTCM object creation time
296  * @param time
297  *    Current CPU time stamp (measured in CPU cycles)
298  * @param pkt_len
299  *    Length of the current IP packet (measured in bytes)
300  * @return
301  *    Color assigned to the current IP packet
302  */
303 static inline enum rte_meter_color __rte_experimental
304 rte_meter_trtcm_rfc4115_color_blind_check(
305         struct rte_meter_trtcm_rfc4115 *m,
306         struct rte_meter_trtcm_rfc4115_profile *p,
307         uint64_t time,
308         uint32_t pkt_len);
309
310 /**
311  * @warning
312  * @b EXPERIMENTAL: this API may change without prior notice
313  *
314  * trTCM RFC4115 color aware traffic metering
315  *
316  * @param m
317  *    Handle to trTCM instance
318  * @param p
319  *    trTCM profile specified at trTCM object creation time
320  * @param time
321  *    Current CPU time stamp (measured in CPU cycles)
322  * @param pkt_len
323  *    Length of the current IP packet (measured in bytes)
324  * @param pkt_color
325  *    Input color of the current IP packet
326  * @return
327  *    Color assigned to the current IP packet
328  */
329 static inline enum rte_meter_color __rte_experimental
330 rte_meter_trtcm_rfc4115_color_aware_check(
331         struct rte_meter_trtcm_rfc4115 *m,
332         struct rte_meter_trtcm_rfc4115_profile *p,
333         uint64_t time,
334         uint32_t pkt_len,
335         enum rte_meter_color pkt_color);
336
337 /*
338  * Inline implementation of run-time methods
339  *
340  ***/
341
342 struct rte_meter_srtcm_profile {
343         uint64_t cbs;
344         /**< Upper limit for C token bucket */
345         uint64_t ebs;
346         /**< Upper limit for E token bucket */
347         uint64_t cir_period;
348         /**< Number of CPU cycles for each update of C and E token buckets */
349         uint64_t cir_bytes_per_period;
350         /**< Number of bytes to add to C and E token buckets on each update */
351 };
352
353 /* Internal data structure storing the srTCM run-time context per metered traffic flow. */
354 struct rte_meter_srtcm {
355         uint64_t time; /* Time of latest update of C and E token buckets */
356         uint64_t tc;   /* Number of bytes currently available in the committed (C) token bucket */
357         uint64_t te;   /* Number of bytes currently available in the excess (E) token bucket */
358 };
359
360 struct rte_meter_trtcm_profile {
361         uint64_t cbs;
362         /**< Upper limit for C token bucket */
363         uint64_t pbs;
364         /**< Upper limit for P token bucket */
365         uint64_t cir_period;
366         /**< Number of CPU cycles for one update of C token bucket */
367         uint64_t cir_bytes_per_period;
368         /**< Number of bytes to add to C token bucket on each update */
369         uint64_t pir_period;
370         /**< Number of CPU cycles for one update of P token bucket */
371         uint64_t pir_bytes_per_period;
372         /**< Number of bytes to add to P token bucket on each update */
373 };
374
375 /**
376  * Internal data structure storing the trTCM run-time context per metered
377  * traffic flow.
378  */
379 struct rte_meter_trtcm {
380         uint64_t time_tc;
381         /**< Time of latest update of C token bucket */
382         uint64_t time_tp;
383         /**< Time of latest update of P token bucket */
384         uint64_t tc;
385         /**< Number of bytes currently available in committed(C) token bucket */
386         uint64_t tp;
387         /**< Number of bytes currently available in the peak(P) token bucket */
388 };
389
390 struct rte_meter_trtcm_rfc4115_profile {
391         uint64_t cbs;
392         /**< Upper limit for C token bucket */
393         uint64_t ebs;
394         /**< Upper limit for E token bucket */
395         uint64_t cir_period;
396         /**< Number of CPU cycles for one update of C token bucket */
397         uint64_t cir_bytes_per_period;
398         /**< Number of bytes to add to C token bucket on each update */
399         uint64_t eir_period;
400         /**< Number of CPU cycles for one update of E token bucket */
401         uint64_t eir_bytes_per_period;
402         /**< Number of bytes to add to E token bucket on each update */
403 };
404
405 /**
406  * Internal data structure storing the trTCM RFC4115 run-time context per
407  * metered traffic flow.
408  */
409 struct rte_meter_trtcm_rfc4115 {
410         uint64_t time_tc;
411         /**< Time of latest update of C token bucket */
412         uint64_t time_te;
413         /**< Time of latest update of E token bucket */
414         uint64_t tc;
415         /**< Number of bytes currently available in committed(C) token bucket */
416         uint64_t te;
417         /**< Number of bytes currently available in the excess(E) token bucket */
418 };
419
420 static inline enum rte_meter_color
421 rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
422         struct rte_meter_srtcm_profile *p,
423         uint64_t time,
424         uint32_t pkt_len)
425 {
426         uint64_t time_diff, n_periods, tc, te;
427
428         /* Bucket update */
429         time_diff = time - m->time;
430         n_periods = time_diff / p->cir_period;
431         m->time += n_periods * p->cir_period;
432
433         /* Put the tokens overflowing from tc into te bucket */
434         tc = m->tc + n_periods * p->cir_bytes_per_period;
435         te = m->te;
436         if (tc > p->cbs) {
437                 te += (tc - p->cbs);
438                 if (te > p->ebs)
439                         te = p->ebs;
440                 tc = p->cbs;
441         }
442
443         /* Color logic */
444         if (tc >= pkt_len) {
445                 m->tc = tc - pkt_len;
446                 m->te = te;
447                 return e_RTE_METER_GREEN;
448         }
449
450         if (te >= pkt_len) {
451                 m->tc = tc;
452                 m->te = te - pkt_len;
453                 return e_RTE_METER_YELLOW;
454         }
455
456         m->tc = tc;
457         m->te = te;
458         return e_RTE_METER_RED;
459 }
460
461 static inline enum rte_meter_color
462 rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
463         struct rte_meter_srtcm_profile *p,
464         uint64_t time,
465         uint32_t pkt_len,
466         enum rte_meter_color pkt_color)
467 {
468         uint64_t time_diff, n_periods, tc, te;
469
470         /* Bucket update */
471         time_diff = time - m->time;
472         n_periods = time_diff / p->cir_period;
473         m->time += n_periods * p->cir_period;
474
475         /* Put the tokens overflowing from tc into te bucket */
476         tc = m->tc + n_periods * p->cir_bytes_per_period;
477         te = m->te;
478         if (tc > p->cbs) {
479                 te += (tc - p->cbs);
480                 if (te > p->ebs)
481                         te = p->ebs;
482                 tc = p->cbs;
483         }
484
485         /* Color logic */
486         if ((pkt_color == e_RTE_METER_GREEN) && (tc >= pkt_len)) {
487                 m->tc = tc - pkt_len;
488                 m->te = te;
489                 return e_RTE_METER_GREEN;
490         }
491
492         if ((pkt_color != e_RTE_METER_RED) && (te >= pkt_len)) {
493                 m->tc = tc;
494                 m->te = te - pkt_len;
495                 return e_RTE_METER_YELLOW;
496         }
497
498         m->tc = tc;
499         m->te = te;
500         return e_RTE_METER_RED;
501 }
502
503 static inline enum rte_meter_color
504 rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
505         struct rte_meter_trtcm_profile *p,
506         uint64_t time,
507         uint32_t pkt_len)
508 {
509         uint64_t time_diff_tc, time_diff_tp, n_periods_tc, n_periods_tp, tc, tp;
510
511         /* Bucket update */
512         time_diff_tc = time - m->time_tc;
513         time_diff_tp = time - m->time_tp;
514         n_periods_tc = time_diff_tc / p->cir_period;
515         n_periods_tp = time_diff_tp / p->pir_period;
516         m->time_tc += n_periods_tc * p->cir_period;
517         m->time_tp += n_periods_tp * p->pir_period;
518
519         tc = m->tc + n_periods_tc * p->cir_bytes_per_period;
520         if (tc > p->cbs)
521                 tc = p->cbs;
522
523         tp = m->tp + n_periods_tp * p->pir_bytes_per_period;
524         if (tp > p->pbs)
525                 tp = p->pbs;
526
527         /* Color logic */
528         if (tp < pkt_len) {
529                 m->tc = tc;
530                 m->tp = tp;
531                 return e_RTE_METER_RED;
532         }
533
534         if (tc < pkt_len) {
535                 m->tc = tc;
536                 m->tp = tp - pkt_len;
537                 return e_RTE_METER_YELLOW;
538         }
539
540         m->tc = tc - pkt_len;
541         m->tp = tp - pkt_len;
542         return e_RTE_METER_GREEN;
543 }
544
545 static inline enum rte_meter_color
546 rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
547         struct rte_meter_trtcm_profile *p,
548         uint64_t time,
549         uint32_t pkt_len,
550         enum rte_meter_color pkt_color)
551 {
552         uint64_t time_diff_tc, time_diff_tp, n_periods_tc, n_periods_tp, tc, tp;
553
554         /* Bucket update */
555         time_diff_tc = time - m->time_tc;
556         time_diff_tp = time - m->time_tp;
557         n_periods_tc = time_diff_tc / p->cir_period;
558         n_periods_tp = time_diff_tp / p->pir_period;
559         m->time_tc += n_periods_tc * p->cir_period;
560         m->time_tp += n_periods_tp * p->pir_period;
561
562         tc = m->tc + n_periods_tc * p->cir_bytes_per_period;
563         if (tc > p->cbs)
564                 tc = p->cbs;
565
566         tp = m->tp + n_periods_tp * p->pir_bytes_per_period;
567         if (tp > p->pbs)
568                 tp = p->pbs;
569
570         /* Color logic */
571         if ((pkt_color == e_RTE_METER_RED) || (tp < pkt_len)) {
572                 m->tc = tc;
573                 m->tp = tp;
574                 return e_RTE_METER_RED;
575         }
576
577         if ((pkt_color == e_RTE_METER_YELLOW) || (tc < pkt_len)) {
578                 m->tc = tc;
579                 m->tp = tp - pkt_len;
580                 return e_RTE_METER_YELLOW;
581         }
582
583         m->tc = tc - pkt_len;
584         m->tp = tp - pkt_len;
585         return e_RTE_METER_GREEN;
586 }
587
588 static inline enum rte_meter_color __rte_experimental
589 rte_meter_trtcm_rfc4115_color_blind_check(
590         struct rte_meter_trtcm_rfc4115 *m,
591         struct rte_meter_trtcm_rfc4115_profile *p,
592         uint64_t time,
593         uint32_t pkt_len)
594 {
595         uint64_t time_diff_tc, time_diff_te, n_periods_tc, n_periods_te, tc, te;
596
597         /* Bucket update */
598         time_diff_tc = time - m->time_tc;
599         time_diff_te = time - m->time_te;
600         n_periods_tc = time_diff_tc / p->cir_period;
601         n_periods_te = time_diff_te / p->eir_period;
602         m->time_tc += n_periods_tc * p->cir_period;
603         m->time_te += n_periods_te * p->eir_period;
604
605         tc = m->tc + n_periods_tc * p->cir_bytes_per_period;
606         if (tc > p->cbs)
607                 tc = p->cbs;
608
609         te = m->te + n_periods_te * p->eir_bytes_per_period;
610         if (te > p->ebs)
611                 te = p->ebs;
612
613         /* Color logic */
614         if (tc >= pkt_len) {
615                 m->tc = tc - pkt_len;
616                 m->te = te;
617                 return e_RTE_METER_GREEN;
618         }
619         if (te >= pkt_len) {
620                 m->tc = tc;
621                 m->te = te - pkt_len;
622                 return e_RTE_METER_YELLOW;
623         }
624
625         /* If we end up here the color is RED */
626         m->tc = tc;
627         m->te = te;
628         return e_RTE_METER_RED;
629 }
630
631 static inline enum rte_meter_color __rte_experimental
632 rte_meter_trtcm_rfc4115_color_aware_check(
633         struct rte_meter_trtcm_rfc4115 *m,
634         struct rte_meter_trtcm_rfc4115_profile *p,
635         uint64_t time,
636         uint32_t pkt_len,
637         enum rte_meter_color pkt_color)
638 {
639         uint64_t time_diff_tc, time_diff_te, n_periods_tc, n_periods_te, tc, te;
640
641         /* Bucket update */
642         time_diff_tc = time - m->time_tc;
643         time_diff_te = time - m->time_te;
644         n_periods_tc = time_diff_tc / p->cir_period;
645         n_periods_te = time_diff_te / p->eir_period;
646         m->time_tc += n_periods_tc * p->cir_period;
647         m->time_te += n_periods_te * p->eir_period;
648
649         tc = m->tc + n_periods_tc * p->cir_bytes_per_period;
650         if (tc > p->cbs)
651                 tc = p->cbs;
652
653         te = m->te + n_periods_te * p->eir_bytes_per_period;
654         if (te > p->ebs)
655                 te = p->ebs;
656
657         /* Color logic */
658         if ((pkt_color == e_RTE_METER_GREEN) && (tc >= pkt_len)) {
659                 m->tc = tc - pkt_len;
660                 m->te = te;
661                 return e_RTE_METER_GREEN;
662         }
663
664         if ((pkt_color != e_RTE_METER_RED) && (te >= pkt_len)) {
665                 m->tc = tc;
666                 m->te = te - pkt_len;
667                 return e_RTE_METER_YELLOW;
668         }
669
670         /* If we end up here the color is RED */
671         m->tc = tc;
672         m->te = te;
673         return e_RTE_METER_RED;
674 }
675
676
677 #ifdef __cplusplus
678 }
679 #endif
680
681 #endif /* __INCLUDE_RTE_METER_H__ */