2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-29 13:27:59 +00:00

ofp-parse: New function parse_ofp_exact_flow().

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@nicira.com>
This commit is contained in:
Ben Pfaff 2012-05-04 09:52:37 -07:00
parent 33cadc5034
commit ccbe50f8f6
4 changed files with 94 additions and 0 deletions

View File

@ -1457,6 +1457,19 @@ mf_set_flow_value(const struct mf_field *mf,
} }
} }
/* Returns true if 'mf' has a zero value in 'flow', false if it is nonzero.
*
* 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'. /* Makes 'rule' wildcard field 'mf'.
* *
* The caller is responsible for ensuring that 'rule' meets 'mf''s * The caller is responsible for ensuring that 'rule' meets 'mf''s

View File

@ -264,6 +264,7 @@ void mf_set_value(const struct mf_field *, const union mf_value *value,
struct cls_rule *); struct cls_rule *);
void mf_set_flow_value(const struct mf_field *, const union mf_value *value, void mf_set_flow_value(const struct mf_field *, const union mf_value *value,
struct flow *); struct flow *);
bool mf_is_zero(const struct mf_field *, const struct flow *);
void mf_get(const struct mf_field *, const struct cls_rule *, void mf_get(const struct mf_field *, const struct cls_rule *,
union mf_value *value, union mf_value *mask); union mf_value *value, union mf_value *mask);

View File

@ -755,3 +755,80 @@ parse_ofp_flow_stats_request_str(struct ofputil_flow_stats_request *fsr,
fsr->out_port = fm.out_port; fsr->out_port = fm.out_port;
fsr->table_id = fm.table_id; 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;
}

View File

@ -23,6 +23,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
struct flow;
struct ofpbuf; struct ofpbuf;
struct ofputil_flow_mod; struct ofputil_flow_mod;
struct ofputil_flow_stats_request; 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); void parse_ofp_actions(const char *, struct ofpbuf *actions);
char *parse_ofp_exact_flow(struct flow *, const char *);
#endif /* ofp-parse.h */ #endif /* ofp-parse.h */