DPDK  18.05.1
rte_meter.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4 
5 #ifndef __INCLUDE_RTE_METER_H__
6 #define __INCLUDE_RTE_METER_H__
7 
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11 
22 #include <stdint.h>
23 #include <rte_compat.h>
24 
25 /*
26  * Application Programmer's Interface (API)
27  *
28  ***/
29 
36 };
37 
42  uint64_t cir;
43  uint64_t cbs;
44  uint64_t ebs;
45 };
46 
51  uint64_t cir;
52  uint64_t pir;
53  uint64_t cbs;
54  uint64_t pbs;
55 };
56 
61 struct rte_meter_srtcm_profile;
62 
67 struct rte_meter_trtcm_profile;
68 
70 struct rte_meter_srtcm;
71 
73 struct rte_meter_trtcm;
74 
85 int __rte_experimental
86 rte_meter_srtcm_profile_config(struct rte_meter_srtcm_profile *p,
87  struct rte_meter_srtcm_params *params);
88 
99 int __rte_experimental
100 rte_meter_trtcm_profile_config(struct rte_meter_trtcm_profile *p,
101  struct rte_meter_trtcm_params *params);
102 
113 int
114 rte_meter_srtcm_config(struct rte_meter_srtcm *m,
115  struct rte_meter_srtcm_profile *p);
116 
127 int
129  struct rte_meter_trtcm_profile *p);
130 
145 static inline enum rte_meter_color
146 rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
147  struct rte_meter_srtcm_profile *p,
148  uint64_t time,
149  uint32_t pkt_len);
150 
167 static inline enum rte_meter_color
168 rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
169  struct rte_meter_srtcm_profile *p,
170  uint64_t time,
171  uint32_t pkt_len,
172  enum rte_meter_color pkt_color);
173 
188 static inline enum rte_meter_color
190  struct rte_meter_trtcm_profile *p,
191  uint64_t time,
192  uint32_t pkt_len);
193 
210 static inline enum rte_meter_color
212  struct rte_meter_trtcm_profile *p,
213  uint64_t time,
214  uint32_t pkt_len,
215  enum rte_meter_color pkt_color);
216 
217 /*
218  * Inline implementation of run-time methods
219  *
220  ***/
221 
222 struct rte_meter_srtcm_profile {
223  uint64_t cbs;
225  uint64_t ebs;
227  uint64_t cir_period;
229  uint64_t cir_bytes_per_period;
231 };
232 
233 /* Internal data structure storing the srTCM run-time context per metered traffic flow. */
234 struct rte_meter_srtcm {
235  uint64_t time; /* Time of latest update of C and E token buckets */
236  uint64_t tc; /* Number of bytes currently available in the committed (C) token bucket */
237  uint64_t te; /* Number of bytes currently available in the excess (E) token bucket */
238 };
239 
240 struct rte_meter_trtcm_profile {
241  uint64_t cbs;
243  uint64_t pbs;
245  uint64_t cir_period;
247  uint64_t cir_bytes_per_period;
249  uint64_t pir_period;
251  uint64_t pir_bytes_per_period;
253 };
254 
260  uint64_t time_tc;
262  uint64_t time_tp;
264  uint64_t tc;
266  uint64_t tp;
268 };
269 
270 static inline enum rte_meter_color
271 rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
272  struct rte_meter_srtcm_profile *p,
273  uint64_t time,
274  uint32_t pkt_len)
275 {
276  uint64_t time_diff, n_periods, tc, te;
277 
278  /* Bucket update */
279  time_diff = time - m->time;
280  n_periods = time_diff / p->cir_period;
281  m->time += n_periods * p->cir_period;
282 
283  /* Put the tokens overflowing from tc into te bucket */
284  tc = m->tc + n_periods * p->cir_bytes_per_period;
285  te = m->te;
286  if (tc > p->cbs) {
287  te += (tc - p->cbs);
288  if (te > p->ebs)
289  te = p->ebs;
290  tc = p->cbs;
291  }
292 
293  /* Color logic */
294  if (tc >= pkt_len) {
295  m->tc = tc - pkt_len;
296  m->te = te;
297  return e_RTE_METER_GREEN;
298  }
299 
300  if (te >= pkt_len) {
301  m->tc = tc;
302  m->te = te - pkt_len;
303  return e_RTE_METER_YELLOW;
304  }
305 
306  m->tc = tc;
307  m->te = te;
308  return e_RTE_METER_RED;
309 }
310 
311 static inline enum rte_meter_color
312 rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
313  struct rte_meter_srtcm_profile *p,
314  uint64_t time,
315  uint32_t pkt_len,
316  enum rte_meter_color pkt_color)
317 {
318  uint64_t time_diff, n_periods, tc, te;
319 
320  /* Bucket update */
321  time_diff = time - m->time;
322  n_periods = time_diff / p->cir_period;
323  m->time += n_periods * p->cir_period;
324 
325  /* Put the tokens overflowing from tc into te bucket */
326  tc = m->tc + n_periods * p->cir_bytes_per_period;
327  te = m->te;
328  if (tc > p->cbs) {
329  te += (tc - p->cbs);
330  if (te > p->ebs)
331  te = p->ebs;
332  tc = p->cbs;
333  }
334 
335  /* Color logic */
336  if ((pkt_color == e_RTE_METER_GREEN) && (tc >= pkt_len)) {
337  m->tc = tc - pkt_len;
338  m->te = te;
339  return e_RTE_METER_GREEN;
340  }
341 
342  if ((pkt_color != e_RTE_METER_RED) && (te >= pkt_len)) {
343  m->tc = tc;
344  m->te = te - pkt_len;
345  return e_RTE_METER_YELLOW;
346  }
347 
348  m->tc = tc;
349  m->te = te;
350  return e_RTE_METER_RED;
351 }
352 
353 static inline enum rte_meter_color
355  struct rte_meter_trtcm_profile *p,
356  uint64_t time,
357  uint32_t pkt_len)
358 {
359  uint64_t time_diff_tc, time_diff_tp, n_periods_tc, n_periods_tp, tc, tp;
360 
361  /* Bucket update */
362  time_diff_tc = time - m->time_tc;
363  time_diff_tp = time - m->time_tp;
364  n_periods_tc = time_diff_tc / p->cir_period;
365  n_periods_tp = time_diff_tp / p->pir_period;
366  m->time_tc += n_periods_tc * p->cir_period;
367  m->time_tp += n_periods_tp * p->pir_period;
368 
369  tc = m->tc + n_periods_tc * p->cir_bytes_per_period;
370  if (tc > p->cbs)
371  tc = p->cbs;
372 
373  tp = m->tp + n_periods_tp * p->pir_bytes_per_period;
374  if (tp > p->pbs)
375  tp = p->pbs;
376 
377  /* Color logic */
378  if (tp < pkt_len) {
379  m->tc = tc;
380  m->tp = tp;
381  return e_RTE_METER_RED;
382  }
383 
384  if (tc < pkt_len) {
385  m->tc = tc;
386  m->tp = tp - pkt_len;
387  return e_RTE_METER_YELLOW;
388  }
389 
390  m->tc = tc - pkt_len;
391  m->tp = tp - pkt_len;
392  return e_RTE_METER_GREEN;
393 }
394 
395 static inline enum rte_meter_color
397  struct rte_meter_trtcm_profile *p,
398  uint64_t time,
399  uint32_t pkt_len,
400  enum rte_meter_color pkt_color)
401 {
402  uint64_t time_diff_tc, time_diff_tp, n_periods_tc, n_periods_tp, tc, tp;
403 
404  /* Bucket update */
405  time_diff_tc = time - m->time_tc;
406  time_diff_tp = time - m->time_tp;
407  n_periods_tc = time_diff_tc / p->cir_period;
408  n_periods_tp = time_diff_tp / p->pir_period;
409  m->time_tc += n_periods_tc * p->cir_period;
410  m->time_tp += n_periods_tp * p->pir_period;
411 
412  tc = m->tc + n_periods_tc * p->cir_bytes_per_period;
413  if (tc > p->cbs)
414  tc = p->cbs;
415 
416  tp = m->tp + n_periods_tp * p->pir_bytes_per_period;
417  if (tp > p->pbs)
418  tp = p->pbs;
419 
420  /* Color logic */
421  if ((pkt_color == e_RTE_METER_RED) || (tp < pkt_len)) {
422  m->tc = tc;
423  m->tp = tp;
424  return e_RTE_METER_RED;
425  }
426 
427  if ((pkt_color == e_RTE_METER_YELLOW) || (tc < pkt_len)) {
428  m->tc = tc;
429  m->tp = tp - pkt_len;
430  return e_RTE_METER_YELLOW;
431  }
432 
433  m->tc = tc - pkt_len;
434  m->tp = tp - pkt_len;
435  return e_RTE_METER_GREEN;
436 }
437 
438 #ifdef __cplusplus
439 }
440 #endif
441 
442 #endif /* __INCLUDE_RTE_METER_H__ */