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