[ovs-dev] [PATCH 3/4] ofp-parse: New function parse_ofp_exact_flow().
Ben Pfaff
blp at nicira.com
Fri Apr 27 16:49:51 UTC 2012
This function parses a flow rather than a cls_rule. It will be useful
for "ofproto/trace", which currently requires an odp_flow and thus can't
accept values for registers and other concepts that don't exist in the
kernel.
Signed-off-by: Ben Pfaff <blp at nicira.com>
---
lib/meta-flow.c | 13 +++++++++
lib/meta-flow.h | 1 +
lib/ofp-parse.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/ofp-parse.h | 3 ++
4 files changed, 94 insertions(+), 0 deletions(-)
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index 82e9e9b..a5942ad 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -1452,6 +1452,19 @@ mf_set_flow_value(const struct mf_field *mf,
}
}
+/* Returns true if 'mf' has a nonzero value in 'flow'.
+ *
+ * The caller is responsible for ensuring that 'flow' meets 'mf''s
+ * prerequisites. */
+bool
+mf_is_zero(const struct mf_field *mf, const struct flow *flow)
+{
+ union mf_value value;
+
+ mf_get_value(mf, flow, &value);
+ return is_all_zeros((const uint8_t *) &value, mf->n_bytes);
+}
+
/* Makes 'rule' wildcard field 'mf'.
*
* The caller is responsible for ensuring that 'rule' meets 'mf''s
diff --git a/lib/meta-flow.h b/lib/meta-flow.h
index 6340b3e..a34bd34 100644
--- a/lib/meta-flow.h
+++ b/lib/meta-flow.h
@@ -264,6 +264,7 @@ void mf_set_value(const struct mf_field *, const union mf_value *value,
struct cls_rule *);
void mf_set_flow_value(const struct mf_field *, const union mf_value *value,
struct flow *);
+bool mf_is_zero(const struct mf_field *, const struct flow *);
void mf_get(const struct mf_field *, const struct cls_rule *,
union mf_value *value, union mf_value *mask);
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index 3f7a021..fd8541c 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -755,3 +755,80 @@ parse_ofp_flow_stats_request_str(struct ofputil_flow_stats_request *fsr,
fsr->out_port = fm.out_port;
fsr->table_id = fm.table_id;
}
+
+/* Parses a specification of a flow from S into FLOW. S must take the form
+ * FIELD=VALUE[,FIELD=VALUE]... where each FIELD is the name of a mf_field.
+ * Fields must be specified in a natural order for satisfying prerequisites.
+ *
+ * Returns NULL on success, otherwise a malloc()'d string that explains the
+ * problem. */
+char *
+parse_ofp_exact_flow(struct flow *flow, const char *s)
+{
+ char *pos, *key, *value_s;
+ char *error = NULL;
+ char *copy;
+
+ memset(flow, 0, sizeof *flow);
+
+ pos = copy = xstrdup(s);
+ while (ofputil_parse_key_value(&pos, &key, &value_s)) {
+ const struct protocol *p;
+ if (parse_protocol(key, &p)) {
+ if (flow->dl_type) {
+ error = xasprintf("%s: Ethernet type set multiple times", s);
+ goto exit;
+ }
+ flow->dl_type = htons(p->dl_type);
+
+ if (p->nw_proto) {
+ if (flow->nw_proto) {
+ error = xasprintf("%s: network protocol set "
+ "multiple times", s);
+ goto exit;
+ }
+ flow->nw_proto = p->nw_proto;
+ }
+ } else {
+ const struct mf_field *mf;
+ union mf_value value;
+ char *field_error;
+
+ mf = mf_from_name(key);
+ if (!mf) {
+ error = xasprintf("%s: unknown field %s", s, key);
+ goto exit;
+ }
+
+ if (!mf_are_prereqs_ok(mf, flow)) {
+ error = xasprintf("%s: prerequisites not met for setting %s",
+ s, key);
+ goto exit;
+ }
+
+ if (!mf_is_zero(mf, flow)) {
+ error = xasprintf("%s: field %s set multiple times", s, key);
+ goto exit;
+ }
+
+ field_error = mf_parse_value(mf, value_s, &value);
+ if (field_error) {
+ error = xasprintf("%s: bad value for %s (%s)",
+ s, key, field_error);
+ free(field_error);
+ goto exit;
+ }
+
+ mf_set_flow_value(mf, &value, flow);
+ }
+ }
+
+exit:
+ free(copy);
+
+ if (error) {
+ memset(flow, 0, sizeof *flow);
+ }
+ return error;
+}
+
diff --git a/lib/ofp-parse.h b/lib/ofp-parse.h
index c552caa..69ee44a 100644
--- a/lib/ofp-parse.h
+++ b/lib/ofp-parse.h
@@ -23,6 +23,7 @@
#include <stdint.h>
#include <stdio.h>
+struct flow;
struct ofpbuf;
struct ofputil_flow_mod;
struct ofputil_flow_stats_request;
@@ -41,4 +42,6 @@ void parse_ofp_flow_stats_request_str(struct ofputil_flow_stats_request *,
void parse_ofp_actions(const char *, struct ofpbuf *actions);
+char *parse_ofp_exact_flow(struct flow *, const char *);
+
#endif /* ofp-parse.h */
--
1.7.2.5
More information about the dev
mailing list