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