From e57681e5300e4d1181a52d4bde05edc4fb000e88 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 30 Oct 2013 18:17:10 +0900 Subject: [PATCH 1/1] ofproto: Verify compatibility of liveness of groups with their type Require liveness for fast-failover groups as it is mandated by OpenFlow1.3. Allow livness for select groups which is in keeping with OpenFlow1.3. Disallow liveness it for other group types. Signed-off-by: Simon Horman Signed-off-by: Ben Pfaff --- lib/ofp-util.c | 29 ++++++++++++++++++++++++++++- lib/ofp-util.h | 7 +++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 63c2347c8..4109e1b3e 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -6202,6 +6202,8 @@ ofputil_decode_group_mod(const struct ofp_header *oh, { const struct ofp11_group_mod *ogm; struct ofpbuf msg; + struct ofputil_bucket *bucket; + enum ofperr err; ofpbuf_use_const(&msg, oh, ntohs(oh->length)); ofpraw_pull_assert(&msg); @@ -6211,7 +6213,32 @@ ofputil_decode_group_mod(const struct ofp_header *oh, gm->type = ogm->type; gm->group_id = ntohl(ogm->group_id); - return ofputil_pull_buckets(&msg, msg.size, oh->version, &gm->buckets); + err = ofputil_pull_buckets(&msg, msg.size, oh->version, &gm->buckets); + if (err) { + return err; + } + + LIST_FOR_EACH (bucket, list_node, &gm->buckets) { + switch (gm->type) { + case OFPGT11_ALL: + case OFPGT11_INDIRECT: + if (ofputil_bucket_has_liveness(bucket)) { + return OFPERR_OFPGMFC_WATCH_UNSUPPORTED; + } + break; + case OFPGT11_SELECT: + break; + case OFPGT11_FF: + if (!ofputil_bucket_has_liveness(bucket)) { + return OFPERR_OFPGMFC_INVALID_GROUP; + } + break; + default: + NOT_REACHED(); + } + } + + return 0; } /* Parse a queue status request message into 'oqsr'. diff --git a/lib/ofp-util.h b/lib/ofp-util.h index f62aa0206..c66e65dba 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -1008,6 +1008,13 @@ struct ofputil_group_desc { void ofputil_bucket_list_destroy(struct list *buckets); +static inline bool +ofputil_bucket_has_liveness(const struct ofputil_bucket *bucket) +{ + return (bucket->watch_port != OFPP_ANY || + bucket->watch_group != OFPG_ANY); +} + struct ofpbuf *ofputil_encode_group_stats_request(enum ofp_version, uint32_t group_id); enum ofperr ofputil_decode_group_stats_request( -- 2.43.0