1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Intel Corporation
10 #include <rte_mtr_driver.h>
12 #include "rte_eth_softnic_internals.h"
15 softnic_mtr_init(struct pmd_internals *p)
17 /* Initialize meter profiles list */
18 TAILQ_INIT(&p->mtr.meter_profiles);
20 /* Initialize meter policies list */
21 TAILQ_INIT(&p->mtr.meter_policies);
23 /* Initialize MTR objects list */
24 TAILQ_INIT(&p->mtr.mtrs);
30 softnic_mtr_free(struct pmd_internals *p)
32 /* Remove MTR objects */
34 struct softnic_mtr *m;
36 m = TAILQ_FIRST(&p->mtr.mtrs);
40 TAILQ_REMOVE(&p->mtr.mtrs, m, node);
44 /* Remove meter profiles */
46 struct softnic_mtr_meter_profile *mp;
48 mp = TAILQ_FIRST(&p->mtr.meter_profiles);
52 TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
56 /* Remove meter policies */
58 struct softnic_mtr_meter_policy *mp;
60 mp = TAILQ_FIRST(&p->mtr.meter_policies);
64 TAILQ_REMOVE(&p->mtr.meter_policies, mp, node);
69 struct softnic_mtr_meter_profile *
70 softnic_mtr_meter_profile_find(struct pmd_internals *p,
71 uint32_t meter_profile_id)
73 struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
74 struct softnic_mtr_meter_profile *mp;
76 TAILQ_FOREACH(mp, mpl, node)
77 if (meter_profile_id == mp->meter_profile_id)
84 meter_profile_check(struct rte_eth_dev *dev,
85 uint32_t meter_profile_id,
86 struct rte_mtr_meter_profile *profile,
87 struct rte_mtr_error *error)
89 struct pmd_internals *p = dev->data->dev_private;
90 struct softnic_mtr_meter_profile *mp;
92 /* Meter profile ID must be valid. */
93 if (meter_profile_id == UINT32_MAX)
94 return -rte_mtr_error_set(error,
96 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
98 "Meter profile id not valid");
100 /* Meter profile must not exist. */
101 mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
103 return -rte_mtr_error_set(error,
105 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
107 "Meter prfile already exists");
109 /* Profile must not be NULL. */
111 return -rte_mtr_error_set(error,
113 RTE_MTR_ERROR_TYPE_METER_PROFILE,
117 /* Traffic metering algorithm : TRTCM_RFC2698 */
118 if (profile->alg != RTE_MTR_TRTCM_RFC2698)
119 return -rte_mtr_error_set(error,
121 RTE_MTR_ERROR_TYPE_METER_PROFILE,
123 "Metering alg not supported");
125 /* Not support packet mode, just support byte mode. */
126 if (profile->packet_mode)
127 return -rte_mtr_error_set(error,
129 RTE_MTR_ERROR_TYPE_METER_PROFILE_PACKET_MODE,
131 "Meter packet mode not supported");
136 /* MTR meter profile add */
138 pmd_mtr_meter_profile_add(struct rte_eth_dev *dev,
139 uint32_t meter_profile_id,
140 struct rte_mtr_meter_profile *profile,
141 struct rte_mtr_error *error)
143 struct pmd_internals *p = dev->data->dev_private;
144 struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
145 struct softnic_mtr_meter_profile *mp;
148 /* Check input params */
149 status = meter_profile_check(dev, meter_profile_id, profile, error);
153 /* Memory allocation */
154 mp = calloc(1, sizeof(struct softnic_mtr_meter_profile));
156 return -rte_mtr_error_set(error,
158 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
160 "Memory alloc failed");
163 mp->meter_profile_id = meter_profile_id;
164 memcpy(&mp->params, profile, sizeof(mp->params));
167 TAILQ_INSERT_TAIL(mpl, mp, node);
172 /* MTR meter profile delete */
174 pmd_mtr_meter_profile_delete(struct rte_eth_dev *dev,
175 uint32_t meter_profile_id,
176 struct rte_mtr_error *error)
178 struct pmd_internals *p = dev->data->dev_private;
179 struct softnic_mtr_meter_profile *mp;
181 /* Meter profile must exist */
182 mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
184 return -rte_mtr_error_set(error,
186 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
188 "Meter profile id invalid");
192 return -rte_mtr_error_set(error,
194 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
196 "Meter profile in use");
198 /* Remove from list */
199 TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
205 struct softnic_mtr_meter_policy *
206 softnic_mtr_meter_policy_find(struct pmd_internals *p,
207 uint32_t meter_policy_id)
209 struct softnic_mtr_meter_policy_list *mpl = &p->mtr.meter_policies;
210 struct softnic_mtr_meter_policy *mp;
212 TAILQ_FOREACH(mp, mpl, node)
213 if (meter_policy_id == mp->meter_policy_id)
219 /* MTR meter policy add */
221 pmd_mtr_meter_policy_add(struct rte_eth_dev *dev,
222 uint32_t meter_policy_id,
223 struct rte_mtr_meter_policy_params *policy,
224 struct rte_mtr_error *error)
226 struct pmd_internals *p = dev->data->dev_private;
227 struct softnic_mtr_meter_policy_list *mpl = &p->mtr.meter_policies;
228 struct softnic_mtr_meter_policy *mp;
229 const struct rte_flow_action *act;
230 const struct rte_flow_action_meter_color *recolor;
232 bool valid_act_found;
235 return -rte_mtr_error_set(error,
237 RTE_MTR_ERROR_TYPE_METER_POLICY,
239 "Null meter policy invalid");
241 /* Meter policy must not exist. */
242 mp = softnic_mtr_meter_policy_find(p, meter_policy_id);
244 return -rte_mtr_error_set(error,
246 RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
248 "Meter policy already exists");
250 for (i = 0; i < RTE_COLORS; i++) {
251 if (policy->actions[i] == NULL)
252 return -rte_mtr_error_set(error,
254 RTE_MTR_ERROR_TYPE_METER_POLICY,
257 for (act = policy->actions[i], valid_act_found = false;
258 act->type != RTE_FLOW_ACTION_TYPE_END; act++) {
259 if (act->type == RTE_FLOW_ACTION_TYPE_VOID)
262 * Support one (and one only) of
263 * METER_COLOR or DROP action.
265 if ((act->type != RTE_FLOW_ACTION_TYPE_METER_COLOR &&
266 act->type != RTE_FLOW_ACTION_TYPE_DROP) ||
268 return -rte_mtr_error_set(error,
270 RTE_MTR_ERROR_TYPE_METER_POLICY,
273 valid_act_found = true;
275 if (!valid_act_found)
276 return -rte_mtr_error_set(error,
278 RTE_MTR_ERROR_TYPE_METER_POLICY,
280 "No valid action found");
283 /* Memory allocation */
284 mp = calloc(1, sizeof(struct softnic_mtr_meter_policy));
286 return -rte_mtr_error_set(error,
288 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
290 "Memory alloc failed");
293 mp->meter_policy_id = meter_policy_id;
294 for (i = 0; i < RTE_COLORS; i++) {
295 mp->policer[i] = RTE_TABLE_ACTION_POLICER_DROP;
296 act = policy->actions[i];
299 if (act->type == RTE_FLOW_ACTION_TYPE_METER_COLOR) {
301 switch (recolor->color) {
302 case RTE_COLOR_GREEN:
304 RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
306 case RTE_COLOR_YELLOW:
308 RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
312 RTE_TABLE_ACTION_POLICER_COLOR_RED;
321 TAILQ_INSERT_TAIL(mpl, mp, node);
326 /* MTR meter policy delete */
328 pmd_mtr_meter_policy_delete(struct rte_eth_dev *dev,
329 uint32_t meter_policy_id,
330 struct rte_mtr_error *error)
332 struct pmd_internals *p = dev->data->dev_private;
333 struct softnic_mtr_meter_policy *mp;
335 /* Meter policy must exist */
336 mp = softnic_mtr_meter_policy_find(p, meter_policy_id);
338 return -rte_mtr_error_set(error,
340 RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
342 "Meter policy id invalid");
346 return -rte_mtr_error_set(error,
348 RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
350 "Meter policy in use");
352 /* Remove from list */
353 TAILQ_REMOVE(&p->mtr.meter_policies, mp, node);
360 softnic_mtr_find(struct pmd_internals *p, uint32_t mtr_id)
362 struct softnic_mtr_list *ml = &p->mtr.mtrs;
363 struct softnic_mtr *m;
365 TAILQ_FOREACH(m, ml, node)
366 if (m->mtr_id == mtr_id)
374 mtr_check(struct pmd_internals *p,
376 struct rte_mtr_params *params,
378 struct rte_mtr_error *error)
381 if (softnic_mtr_find(p, mtr_id))
382 return -rte_mtr_error_set(error,
384 RTE_MTR_ERROR_TYPE_MTR_ID,
386 "MTR object already exists");
388 /* MTR params must not be NULL */
390 return -rte_mtr_error_set(error,
392 RTE_MTR_ERROR_TYPE_MTR_PARAMS,
394 "MTR object params null");
396 /* Previous meter color not supported */
397 if (params->use_prev_mtr_color)
398 return -rte_mtr_error_set(error,
400 RTE_MTR_ERROR_TYPE_MTR_PARAMS,
402 "Previous meter color not supported");
404 /* Shared MTR object not supported */
406 return -rte_mtr_error_set(error,
408 RTE_MTR_ERROR_TYPE_SHARED,
410 "Shared MTR object not supported");
415 /* MTR object create */
417 pmd_mtr_create(struct rte_eth_dev *dev,
419 struct rte_mtr_params *params,
421 struct rte_mtr_error *error)
423 struct pmd_internals *p = dev->data->dev_private;
424 struct softnic_mtr_list *ml = &p->mtr.mtrs;
425 struct softnic_mtr_meter_profile *mp;
426 struct softnic_mtr_meter_policy *policy;
427 struct softnic_mtr *m;
430 /* Check parameters */
431 status = mtr_check(p, mtr_id, params, shared, error);
435 /* Meter profile must exist */
436 mp = softnic_mtr_meter_profile_find(p, params->meter_profile_id);
438 return -rte_mtr_error_set(error,
440 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
442 "Meter profile id not valid");
444 /* Meter policy must exist */
445 policy = softnic_mtr_meter_policy_find(p, params->meter_policy_id);
446 if (policy == NULL) {
447 return -rte_mtr_error_set(error,
449 RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
451 "Meter policy id invalid");
454 /* Memory allocation */
455 m = calloc(1, sizeof(struct softnic_mtr));
457 return -rte_mtr_error_set(error,
459 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
461 "Memory alloc failed");
465 memcpy(&m->params, params, sizeof(m->params));
468 TAILQ_INSERT_TAIL(ml, m, node);
470 /* Update dependencies */
477 /* MTR object destroy */
479 pmd_mtr_destroy(struct rte_eth_dev *dev,
481 struct rte_mtr_error *error)
483 struct pmd_internals *p = dev->data->dev_private;
484 struct softnic_mtr_list *ml = &p->mtr.mtrs;
485 struct softnic_mtr_meter_profile *mp;
486 struct softnic_mtr *m;
487 struct softnic_mtr_meter_policy *policy;
489 /* MTR object must exist */
490 m = softnic_mtr_find(p, mtr_id);
492 return -rte_mtr_error_set(error,
494 RTE_MTR_ERROR_TYPE_MTR_ID,
496 "MTR object id not valid");
498 /* MTR object must not have any owner */
500 return -rte_mtr_error_set(error,
502 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
504 "MTR object is being used");
506 /* Get meter profile */
507 mp = softnic_mtr_meter_profile_find(p, m->params.meter_profile_id);
509 return -rte_mtr_error_set(error,
511 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
513 "MTR object meter profile invalid");
515 /* Meter policy must exist */
516 policy = softnic_mtr_meter_policy_find(p, m->params.meter_policy_id);
518 return -rte_mtr_error_set(error,
520 RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
522 "MTR object meter policy invalid");
524 /* Update dependencies */
528 /* Remove from list */
529 TAILQ_REMOVE(ml, m, node);
535 /* MTR object meter profile update */
537 pmd_mtr_meter_profile_update(struct rte_eth_dev *dev,
539 uint32_t meter_profile_id,
540 struct rte_mtr_error *error)
542 struct pmd_internals *p = dev->data->dev_private;
543 struct softnic_mtr_meter_profile *mp_new, *mp_old;
544 struct softnic_mtr *m;
547 /* MTR object id must be valid */
548 m = softnic_mtr_find(p, mtr_id);
550 return -rte_mtr_error_set(error,
552 RTE_MTR_ERROR_TYPE_MTR_ID,
554 "MTR object id not valid");
556 /* Meter profile id must be valid */
557 mp_new = softnic_mtr_meter_profile_find(p, meter_profile_id);
559 return -rte_mtr_error_set(error,
561 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
563 "Meter profile not valid");
565 /* MTR object already set to meter profile id */
566 if (m->params.meter_profile_id == meter_profile_id)
569 /* MTR object owner table update */
571 uint32_t table_id = m->flow->table_id;
572 struct softnic_table *table = &m->flow->pipeline->table[table_id];
573 struct softnic_table_rule_action action;
575 if (!softnic_pipeline_table_meter_profile_find(table,
577 struct rte_table_action_meter_profile profile;
579 memset(&profile, 0, sizeof(profile));
581 profile.alg = RTE_TABLE_ACTION_METER_TRTCM;
582 profile.trtcm.cir = mp_new->params.trtcm_rfc2698.cir;
583 profile.trtcm.pir = mp_new->params.trtcm_rfc2698.pir;
584 profile.trtcm.cbs = mp_new->params.trtcm_rfc2698.cbs;
585 profile.trtcm.pbs = mp_new->params.trtcm_rfc2698.pbs;
587 /* Add meter profile to pipeline table */
588 status = softnic_pipeline_table_mtr_profile_add(p,
589 m->flow->pipeline->name,
594 return -rte_mtr_error_set(error,
596 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
598 "Table meter profile add failed");
601 /* Set meter action */
602 memcpy(&action, &m->flow->action, sizeof(action));
604 action.mtr.mtr[0].meter_profile_id = meter_profile_id;
607 status = softnic_pipeline_table_rule_add(p,
608 m->flow->pipeline->name,
614 return -rte_mtr_error_set(error,
616 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
618 "Pipeline table rule add failed");
620 /* Flow: update meter action */
621 memcpy(&m->flow->action, &action, sizeof(m->flow->action));
624 mp_old = softnic_mtr_meter_profile_find(p, m->params.meter_profile_id);
626 /* Meter: Set meter profile */
627 m->params.meter_profile_id = meter_profile_id;
629 /* Update dependencies*/
636 /* MTR object meter DSCP table update */
638 pmd_mtr_meter_dscp_table_update(struct rte_eth_dev *dev,
640 enum rte_color *dscp_table,
641 struct rte_mtr_error *error)
643 struct pmd_internals *p = dev->data->dev_private;
644 struct rte_table_action_dscp_table dt;
645 struct pipeline *pipeline;
646 struct softnic_table *table;
647 struct softnic_mtr *m;
648 uint32_t table_id, i;
651 /* MTR object id must be valid */
652 m = softnic_mtr_find(p, mtr_id);
654 return -rte_mtr_error_set(error,
656 RTE_MTR_ERROR_TYPE_MTR_ID,
658 "MTR object id not valid");
660 /* MTR object owner valid? */
664 pipeline = m->flow->pipeline;
665 table_id = m->flow->table_id;
666 table = &pipeline->table[table_id];
668 memcpy(&dt, &table->dscp_table, sizeof(dt));
669 for (i = 0; i < RTE_DIM(dt.entry); i++)
670 dt.entry[i].color = (enum rte_color)dscp_table[i];
673 status = softnic_pipeline_table_dscp_table_update(p,
679 return -rte_mtr_error_set(error,
681 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
683 "Table action dscp table update failed");
688 /* MTR object policy update */
690 pmd_mtr_meter_policy_update(struct rte_eth_dev *dev,
692 uint32_t meter_policy_id,
693 struct rte_mtr_error *error)
695 struct pmd_internals *p = dev->data->dev_private;
696 struct softnic_mtr *m;
699 struct softnic_mtr_meter_policy *mp_new, *mp_old;
701 /* MTR object id must be valid */
702 m = softnic_mtr_find(p, mtr_id);
704 return -rte_mtr_error_set(error,
706 RTE_MTR_ERROR_TYPE_MTR_ID,
708 "MTR object id not valid");
710 if (m->params.meter_policy_id == meter_policy_id)
713 /* Meter policy must exist */
714 mp_new = softnic_mtr_meter_policy_find(p, meter_policy_id);
716 return -rte_mtr_error_set(error,
718 RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
720 "Meter policy id invalid");
722 /* MTR object owner valid? */
724 struct pipeline *pipeline = m->flow->pipeline;
725 struct softnic_table *table = &pipeline->table[m->flow->table_id];
726 struct softnic_table_rule_action action;
728 memcpy(&action, &m->flow->action, sizeof(action));
731 for (i = 0; i < RTE_COLORS; i++)
732 action.mtr.mtr[0].policer[i] = mp_new->policer[i];
734 /* Re-add the rule */
735 status = softnic_pipeline_table_rule_add(p,
742 return -rte_mtr_error_set(error,
744 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
746 "Pipeline table rule re-add failed");
748 /* Flow: Update meter action */
749 memcpy(&m->flow->action, &action, sizeof(m->flow->action));
751 /* Reset the meter stats */
752 rte_table_action_meter_read(table->a, m->flow->data,
756 mp_old = softnic_mtr_meter_policy_find(p, m->params.meter_policy_id);
758 return -rte_mtr_error_set(error,
760 RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
762 "Old meter policy id invalid");
764 /* Meter: Set meter profile */
765 m->params.meter_policy_id = meter_policy_id;
767 /* Update dependencies*/
774 #define MTR_STATS_PKTS_DEFAULT (RTE_MTR_STATS_N_PKTS_GREEN | \
775 RTE_MTR_STATS_N_PKTS_YELLOW | \
776 RTE_MTR_STATS_N_PKTS_RED | \
777 RTE_MTR_STATS_N_PKTS_DROPPED)
779 #define MTR_STATS_BYTES_DEFAULT (RTE_MTR_STATS_N_BYTES_GREEN | \
780 RTE_MTR_STATS_N_BYTES_YELLOW | \
781 RTE_MTR_STATS_N_BYTES_RED | \
782 RTE_MTR_STATS_N_BYTES_DROPPED)
784 /* MTR object stats read */
786 mtr_stats_convert(struct pmd_internals *p,
787 struct softnic_mtr *m,
788 struct rte_table_action_mtr_counters_tc *in,
789 struct rte_mtr_stats *out,
792 struct softnic_mtr_meter_policy *mp;
794 memset(&out, 0, sizeof(out));
797 /* Meter policy must exist */
798 mp = softnic_mtr_meter_policy_find(p, m->params.meter_policy_id);
802 if (in->n_packets_valid) {
805 for (i = 0; i < RTE_COLORS; i++) {
806 if (mp->policer[i] ==
807 RTE_TABLE_ACTION_POLICER_COLOR_GREEN)
808 out->n_pkts[RTE_COLOR_GREEN] += in->n_packets[i];
810 if (mp->policer[i] ==
811 RTE_TABLE_ACTION_POLICER_COLOR_YELLOW)
812 out->n_pkts[RTE_COLOR_YELLOW] += in->n_packets[i];
814 if (mp->policer[i] ==
815 RTE_TABLE_ACTION_POLICER_COLOR_RED)
816 out->n_pkts[RTE_COLOR_RED] += in->n_packets[i];
818 if (mp->policer[i] ==
819 RTE_TABLE_ACTION_POLICER_DROP)
820 out->n_pkts_dropped += in->n_packets[i];
823 *out_mask |= MTR_STATS_PKTS_DEFAULT;
826 if (in->n_bytes_valid) {
829 for (i = 0; i < RTE_COLORS; i++) {
830 if (mp->policer[i] ==
831 RTE_TABLE_ACTION_POLICER_COLOR_GREEN)
832 out->n_bytes[RTE_COLOR_GREEN] += in->n_bytes[i];
834 if (mp->policer[i] ==
835 RTE_TABLE_ACTION_POLICER_COLOR_YELLOW)
836 out->n_bytes[RTE_COLOR_YELLOW] += in->n_bytes[i];
838 if (mp->policer[i] ==
839 RTE_TABLE_ACTION_POLICER_COLOR_RED)
840 out->n_bytes[RTE_COLOR_RED] += in->n_bytes[i];
842 if (mp->policer[i] ==
843 RTE_TABLE_ACTION_POLICER_DROP)
844 out->n_bytes_dropped += in->n_bytes[i];
847 *out_mask |= MTR_STATS_BYTES_DEFAULT;
851 /* MTR object stats read */
853 pmd_mtr_stats_read(struct rte_eth_dev *dev,
855 struct rte_mtr_stats *stats,
856 uint64_t *stats_mask,
858 struct rte_mtr_error *error)
860 struct pmd_internals *p = dev->data->dev_private;
861 struct rte_table_action_mtr_counters counters;
862 struct pipeline *pipeline;
863 struct softnic_table *table;
864 struct softnic_mtr *m;
867 /* MTR object id must be valid */
868 m = softnic_mtr_find(p, mtr_id);
870 return -rte_mtr_error_set(error,
872 RTE_MTR_ERROR_TYPE_MTR_ID,
874 "MTR object id not valid");
876 /* MTR meter object owner valid? */
877 if (m->flow == NULL) {
879 memset(stats, 0, sizeof(*stats));
882 *stats_mask = MTR_STATS_PKTS_DEFAULT |
883 MTR_STATS_BYTES_DEFAULT;
888 pipeline = m->flow->pipeline;
889 table = &pipeline->table[m->flow->table_id];
891 /* Meter stats read. */
892 status = rte_table_action_meter_read(table->a,
898 return -rte_mtr_error_set(error,
900 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
902 "Meter stats read failed");
904 /* Stats format conversion. */
905 if (stats || stats_mask) {
906 struct rte_mtr_stats s;
916 memcpy(stats, &s, sizeof(*stats));
919 *stats_mask = s_mask;
925 const struct rte_mtr_ops pmd_mtr_ops = {
926 .capabilities_get = NULL,
928 .meter_profile_add = pmd_mtr_meter_profile_add,
929 .meter_profile_delete = pmd_mtr_meter_profile_delete,
931 .meter_policy_add = pmd_mtr_meter_policy_add,
932 .meter_policy_delete = pmd_mtr_meter_policy_delete,
934 .create = pmd_mtr_create,
935 .destroy = pmd_mtr_destroy,
936 .meter_enable = NULL,
937 .meter_disable = NULL,
939 .meter_profile_update = pmd_mtr_meter_profile_update,
940 .meter_dscp_table_update = pmd_mtr_meter_dscp_table_update,
941 .meter_policy_update = pmd_mtr_meter_policy_update,
942 .stats_update = NULL,
944 .stats_read = pmd_mtr_stats_read,