From 36c80b2d4ce8adffb6259b0f915d7c66c8296601 Mon Sep 17 00:00:00 2001 From: Justin Pettit Date: Tue, 24 Jul 2018 21:07:04 -0700 Subject: [PATCH] dpif: Move common meter checks into the dpif layer. Another dpif provider will soon add support for meters, so move some of the common sanity checks up into the dpif layer so that each provider doesn't need to re-implement them. Signed-off-by: Justin Pettit Acked-by: Ben Pfaff --- lib/dpif-netdev.c | 15 +++------------ lib/dpif.c | 22 +++++++++++++++++++--- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 0a833dcd1..5ee8d0a4c 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -5172,21 +5172,12 @@ dpif_netdev_meter_set(struct dpif *dpif, ofproto_meter_id *meter_id, return EFBIG; /* Meter_id out of range. */ } - if (config->flags & ~DP_SUPPORTED_METER_FLAGS_MASK || - !(config->flags & (OFPMF13_KBPS | OFPMF13_PKTPS))) { + if (config->flags & ~DP_SUPPORTED_METER_FLAGS_MASK) { return EBADF; /* Unsupported flags set */ } - /* Validate bands */ - if (config->n_bands == 0 || config->n_bands > MAX_BANDS) { - return EINVAL; /* Too many bands */ - } - - /* Validate rates */ - for (i = 0; i < config->n_bands; i++) { - if (config->bands[i].rate == 0) { - return EDOM; /* rate must be non-zero */ - } + if (config->n_bands > MAX_BANDS) { + return EINVAL; } for (i = 0; i < config->n_bands; ++i) { diff --git a/lib/dpif.c b/lib/dpif.c index d78330bef..c267bcfb0 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -1895,11 +1895,27 @@ int dpif_meter_set(struct dpif *dpif, ofproto_meter_id *meter_id, struct ofputil_meter_config *config) { - int error; - COVERAGE_INC(dpif_meter_set); - error = dpif->dpif_class->meter_set(dpif, meter_id, config); + if (!(config->flags & (OFPMF13_KBPS | OFPMF13_PKTPS))) { + return EBADF; /* Rate unit type not set. */ + } + + if ((config->flags & OFPMF13_KBPS) && (config->flags & OFPMF13_PKTPS)) { + return EBADF; /* Both rate units may not be set. */ + } + + if (config->n_bands == 0) { + return EINVAL; + } + + for (size_t i = 0; i < config->n_bands; i++) { + if (config->bands[i].rate == 0) { + return EDOM; /* Rate must be non-zero */ + } + } + + int error = dpif->dpif_class->meter_set(dpif, meter_id, config); if (!error) { VLOG_DBG_RL(&dpmsg_rl, "%s: DPIF meter %"PRIu32" set", dpif_name(dpif), meter_id->uint32); -- 2.39.5