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