xref: /dpdk/lib/meter/rte_meter.h (revision daa02b5cddbb8e11b31d41e2bf7bb1ae64dcae2f)
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
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
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
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
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
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
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