ofproto: Verify compatibility of liveness of groups with their type
authorSimon Horman <horms@verge.net.au>
Wed, 30 Oct 2013 09:17:10 +0000 (18:17 +0900)
committerBen Pfaff <blp@nicira.com>
Sat, 2 Nov 2013 06:02:20 +0000 (23:02 -0700)
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 <horms@verge.net.au>
Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/ofp-util.c
lib/ofp-util.h

index 63c2347..4109e1b 100644 (file)
@@ -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'.
index f62aa02..c66e65d 100644 (file)
@@ -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(