From 103b4866f1d99c86e2cc345be95741759b135f75 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 12 Nov 2014 15:24:10 +0900 Subject: [PATCH] ofp-util: Provide bucket list helper functions This is in preparation for supporting the bucket commands of (draft) Open Flow 1.5 group mod messages. Also document ofputil_bucket_check_duplicate_id() for good measure. ONF-JIRA: EXT-350 Signed-off-by: Simon Horman Signed-off-by: Ben Pfaff --- lib/ofp-util.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/ofp-util.h | 6 ++++ 2 files changed, 88 insertions(+) diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 7655e3e40..0b6cee511 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -6874,6 +6874,64 @@ ofputil_bucket_list_destroy(struct list *buckets) } } +/* Clones 'bucket' and its ofpacts data */ +static struct ofputil_bucket * +ofputil_bucket_clone_data(const struct ofputil_bucket *bucket) +{ + struct ofputil_bucket *new; + + new = xmemdup(bucket, sizeof *bucket); + new->ofpacts = xmemdup(bucket->ofpacts, bucket->ofpacts_len); + + return new; +} + +/* Clones each of the buckets in the list 'src' appending them + * in turn to 'dest' which should be an initialised list. + * An exception is that if the pointer value of a bucket in 'src' + * matches 'skip' then it is not cloned or appended to 'dest'. + * This allows all of 'src' or 'all of 'src' except 'skip' to + * be cloned and appended to 'dest'. */ +void +ofputil_bucket_clone_list(struct list *dest, const struct list *src, + const struct ofputil_bucket *skip) +{ + struct ofputil_bucket *bucket; + + LIST_FOR_EACH (bucket, list_node, src) { + struct ofputil_bucket *new_bucket; + + if (bucket == skip) { + continue; + } + + new_bucket = ofputil_bucket_clone_data(bucket); + list_push_back(dest, &new_bucket->list_node); + } +} + +/* Find a bucket in the list 'buckets' whose bucket id is 'bucket_id' + * Returns the first bucket found or NULL if no buckets are found. */ +struct ofputil_bucket * +ofputil_bucket_find(const struct list *buckets, uint32_t bucket_id) +{ + struct ofputil_bucket *bucket; + + if (bucket_id > OFPG15_BUCKET_MAX) { + return NULL; + } + + LIST_FOR_EACH (bucket, list_node, buckets) { + if (bucket->bucket_id == bucket_id) { + return bucket; + } + } + + return NULL; +} + +/* Returns true if more than one bucket in the list 'buckets' + * have the same bucket id. Returns false otherwise. */ bool ofputil_bucket_check_duplicate_id(const struct list *buckets) { @@ -6893,6 +6951,30 @@ ofputil_bucket_check_duplicate_id(const struct list *buckets) return false; } +/* Returns the bucket at the front of the list 'buckets'. + * Undefined if 'buckets is empty. */ +struct ofputil_bucket * +ofputil_bucket_list_front(const struct list *buckets) +{ + static struct ofputil_bucket *bucket; + + ASSIGN_CONTAINER(bucket, list_front(buckets), list_node); + + return bucket; +} + +/* Returns the bucket at the back of the list 'buckets'. + * Undefined if 'buckets is empty. */ +struct ofputil_bucket * +ofputil_bucket_list_back(const struct list *buckets) +{ + static struct ofputil_bucket *bucket; + + ASSIGN_CONTAINER(bucket, list_back(buckets), list_node); + + return bucket; +} + /* Returns an OpenFlow group stats request for OpenFlow version 'ofp_version', * that requests stats for group 'group_id'. (Use OFPG_ALL to request stats * for all groups.) diff --git a/lib/ofp-util.h b/lib/ofp-util.h index d85a2552d..bc6f7d1b4 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -1035,7 +1035,13 @@ struct ofputil_group_desc { }; void ofputil_bucket_list_destroy(struct list *buckets); +void ofputil_bucket_clone_list(struct list *dest, const struct list *src, + const struct ofputil_bucket *); +struct ofputil_bucket *ofputil_bucket_find(const struct list *, + uint32_t bucket_id); bool ofputil_bucket_check_duplicate_id(const struct list *); +struct ofputil_bucket *ofputil_bucket_list_front(const struct list *); +struct ofputil_bucket *ofputil_bucket_list_back(const struct list *); static inline bool ofputil_bucket_has_liveness(const struct ofputil_bucket *bucket) -- 2.20.1