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