[ovs-dev] [ext-244 3/4] Remove assumption that there are 64 or fewer fields.
Ben Pfaff
blp at nicira.com
Sat Jul 26 05:25:31 UTC 2014
An upcoming commit will increase the number of fields beyond 64.
Signed-off-by: Ben Pfaff <blp at nicira.com>
---
lib/classifier.c | 9 +++------
lib/meta-flow.h | 12 +++++++++---
lib/ofp-print.c | 35 +++++++++++++++--------------------
lib/ofp-util.c | 22 +++++++++-------------
lib/ofp-util.h | 9 +++++----
5 files changed, 41 insertions(+), 46 deletions(-)
diff --git a/lib/classifier.c b/lib/classifier.c
index af28070..334d0da 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -501,9 +501,6 @@ classifier_destroy(struct classifier *cls)
}
}
-/* We use uint64_t as a set for the fields below. */
-BUILD_ASSERT_DECL(MFF_N_IDS <= 64);
-
/* Set the fields for which prefix lookup should be performed. */
bool
classifier_set_prefix_fields(struct classifier *cls,
@@ -511,8 +508,8 @@ classifier_set_prefix_fields(struct classifier *cls,
unsigned int n_fields)
OVS_EXCLUDED(cls->mutex)
{
- uint64_t fields = 0;
const struct mf_field * new_fields[CLS_MAX_TRIES];
+ struct mf_bitmap fields = MF_BITMAP_INITIALIZER;
int i, n_tries = 0;
bool changed = false;
@@ -527,12 +524,12 @@ classifier_set_prefix_fields(struct classifier *cls,
continue;
}
- if (fields & (UINT64_C(1) << trie_fields[i])) {
+ if (bitmap_is_set(fields.bm, trie_fields[i])) {
/* Duplicate field, there is no need to build more than
* one index for any one field. */
continue;
}
- fields |= UINT64_C(1) << trie_fields[i];
+ bitmap_set1(fields.bm, trie_fields[i]);
new_fields[n_tries] = NULL;
if (n_tries >= cls->n_tries || field != cls->tries[n_tries].field) {
diff --git a/lib/meta-flow.h b/lib/meta-flow.h
index 3208137..f65ed20 100644
--- a/lib/meta-flow.h
+++ b/lib/meta-flow.h
@@ -20,9 +20,9 @@
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip6.h>
+#include "bitmap.h"
#include "flow.h"
#include "ofp-errors.h"
-#include "ofp-util.h"
#include "packets.h"
#include "util.h"
@@ -134,6 +134,12 @@ enum OVS_PACKED_ENUM mf_field_id {
MFF_N_IDS
};
+/* A set of mf_field_ids. */
+struct mf_bitmap {
+ unsigned long bm[BITMAP_N_LONGS(MFF_N_IDS)];
+};
+#define MF_BITMAP_INITIALIZER { { [0] = 0 } }
+
/* Use this macro as CASE_MFF_REGS: in a switch statement to choose all of the
* MFF_REGx cases. */
#if FLOW_N_REGS == 8
@@ -270,9 +276,9 @@ struct mf_field {
* Also, some field types are tranparently mapped to each other via the
* struct flow (like vlan and dscp/tos fields), so each variant supports
* all protocols. */
- enum ofputil_protocol usable_protocols; /* If fully/cidr masked. */
+ uint32_t usable_protocols; /* If fully/cidr masked. */
/* If partially/non-cidr masked. */
- enum ofputil_protocol usable_protocols_bitwise;
+ uint32_t usable_protocols_bitwise;
int flow_be32ofs; /* Field's be32 offset in "struct flow", if prefix tree
* lookup is supported for the field, or -1. */
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index a2c2434..25e0478 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -2555,15 +2555,11 @@ print_table_action_features(struct ds *s,
ds_put_char(s, '\n');
ds_put_cstr(s, " supported on Set-Field: ");
- if (taf->set_fields) {
+ if (!bitmap_is_all_zeros(taf->set_fields.bm, MFF_N_IDS)) {
int i;
- for (i = 0; i < MFF_N_IDS; i++) {
- uint64_t bit = UINT64_C(1) << i;
-
- if (taf->set_fields & bit) {
- ds_put_format(s, "%s,", mf_from_id(i)->name);
- }
+ BITMAP_FOR_EACH_1 (i, MFF_N_IDS, taf->set_fields.bm) {
+ ds_put_format(s, "%s,", mf_from_id(i)->name);
}
ds_chomp(s, ',');
} else {
@@ -2576,7 +2572,8 @@ static bool
table_action_features_equal(const struct ofputil_table_action_features *a,
const struct ofputil_table_action_features *b)
{
- return a->actions == b->actions && a->set_fields == b->set_fields;
+ return (a->actions == b->actions
+ && bitmap_equal(a->set_fields.bm, b->set_fields.bm, MFF_N_IDS));
}
static void
@@ -2679,18 +2676,16 @@ ofp_print_table_features(struct ds *s, const struct ofp_header *oh)
}
ds_put_cstr(s, " matching:\n");
- for (i = 0; i < MFF_N_IDS; i++) {
- uint64_t bit = UINT64_C(1) << i;
-
- if (tf.match & bit) {
- const struct mf_field *f = mf_from_id(i);
-
- ds_put_format(s, " %s: %s\n",
- f->name,
- (tf.mask ? "arbitrary mask"
- : tf.wildcard ? "exact match or wildcard"
- : "must exact match"));
- }
+ BITMAP_FOR_EACH_1 (i, MFF_N_IDS, tf.match.bm) {
+ const struct mf_field *f = mf_from_id(i);
+ bool mask = bitmap_is_set(tf.mask.bm, i);
+ bool wildcard = bitmap_is_set(tf.wildcard.bm, i);
+
+ ds_put_format(s, " %s: %s\n",
+ f->name,
+ (mask ? "arbitrary mask"
+ : wildcard ? "exact match or wildcard"
+ : "must exact match"));
}
}
}
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 912def9..278349cb 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -4596,11 +4596,11 @@ parse_oxm(struct ofpbuf *b, bool loose,
static enum ofperr
parse_oxms(struct ofpbuf *payload, bool loose,
- uint64_t *exactp, uint64_t *maskedp)
+ struct mf_bitmap *exactp, struct mf_bitmap *maskedp)
{
- uint64_t exact, masked;
+ struct mf_bitmap exact = MF_BITMAP_INITIALIZER;
+ struct mf_bitmap masked = MF_BITMAP_INITIALIZER;
- exact = masked = 0;
while (ofpbuf_size(payload) > 0) {
const struct mf_field *field;
enum ofperr error;
@@ -4608,23 +4608,19 @@ parse_oxms(struct ofpbuf *payload, bool loose,
error = parse_oxm(payload, loose, &field, &hasmask);
if (!error) {
- if (hasmask) {
- masked |= UINT64_C(1) << field->id;
- } else {
- exact |= UINT64_C(1) << field->id;
- }
+ bitmap_set1(hasmask ? masked.bm : exact.bm, field->id);
} else if (error != OFPERR_OFPBMC_BAD_FIELD || !loose) {
return error;
}
}
if (exactp) {
*exactp = exact;
- } else if (exact) {
+ } else if (!bitmap_is_all_zeros(exact.bm, MFF_N_IDS)) {
return OFPERR_OFPBMC_BAD_MASK;
}
if (maskedp) {
*maskedp = masked;
- } else if (masked) {
+ } else if (!bitmap_is_all_zeros(masked.bm, MFF_N_IDS)) {
return OFPERR_OFPBMC_BAD_MASK;
}
return 0;
@@ -4769,10 +4765,10 @@ ofputil_decode_table_features(struct ofpbuf *msg,
*
* - Turn on 'wildcard' bits that are set in 'mask', because a field
* that is arbitrarily maskable can be wildcarded entirely. */
- tf->mask &= tf->match;
- tf->wildcard &= tf->match;
+ bitmap_and(tf->mask.bm, tf->match.bm, MFF_N_IDS);
+ bitmap_and(tf->wildcard.bm, tf->match.bm, MFF_N_IDS);
- tf->wildcard |= tf->mask;
+ bitmap_or(tf->wildcard.bm, tf->mask.bm, MFF_N_IDS);
return 0;
}
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index 878bcf8..23396bb 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -25,6 +25,7 @@
#include "flow.h"
#include "list.h"
#include "match.h"
+#include "meta-flow.h"
#include "netdev.h"
#include "openflow/nicira-ext.h"
#include "openvswitch/types.h"
@@ -650,7 +651,7 @@ struct ofputil_table_features {
* instruction. */
struct ofputil_table_action_features {
uint32_t actions; /* Bitmap of supported OFPAT*. */
- uint64_t set_fields; /* Bitmap of MFF_* "set-field" supports. */
+ struct mf_bitmap set_fields; /* Fields for "set-field". */
} write, apply;
} nonmiss, miss;
@@ -673,9 +674,9 @@ struct ofputil_table_features {
*
* Other combinations do not make sense.
*/
- uint64_t match; /* Fields that may be matched. */
- uint64_t mask; /* Subset of 'match' that may have masks. */
- uint64_t wildcard; /* Subset of 'match' that may be wildcarded. */
+ struct mf_bitmap match; /* Fields that may be matched. */
+ struct mf_bitmap mask; /* Subset of 'match' that may have masks. */
+ struct mf_bitmap wildcard; /* Subset of 'match' that may be wildcarded. */
};
int ofputil_decode_table_features(struct ofpbuf *,
--
1.9.1
More information about the dev
mailing list