2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 14:25:26 +00:00

ofp-actions: Implement writing to metadata field

In OpenFlow 1.1, we add support for OFPIT_WRITE_METADATA. This allows us to
write to the metadata field. Internally it is represented using ofpact_metadata.

We introduce NXAST_WRITE_METADATA to handle writing to the metadata field in
OpenFlow 1.0+. This structure reflects OFPIT_WRITE_METADATA.

When writing out the structure to OpenFlow 1.1, it uses the OFPIT_WRITE_METADATA
instruction only, and not the new NXAST action (which would be redundant).

Signed-off-by: Joe Stringer <joe@wand.net.nz>
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Joe Stringer
2012-10-19 02:37:37 +09:00
committed by Ben Pfaff
parent 9908606290
commit 4cceacb94c
10 changed files with 272 additions and 15 deletions

View File

@@ -360,6 +360,24 @@ set_field_parse(const char *arg, struct ofpbuf *ofpacts)
free(orig);
}
static void
parse_metadata(struct ofpbuf *b, char *arg)
{
struct ofpact_metadata *om;
char *mask = strchr(arg, '/');
om = ofpact_put_WRITE_METADATA(b);
if (mask) {
*mask = '\0';
om->mask = htonll(str_to_u64(mask + 1));
} else {
om->mask = htonll(UINT64_MAX);
}
om->metadata = htonll(str_to_u64(arg));
}
static void
parse_named_action(enum ofputil_action_code code, const struct flow *flow,
char *arg, struct ofpbuf *ofpacts)
@@ -465,6 +483,10 @@ parse_named_action(enum ofputil_action_code code, const struct flow *flow,
tunnel->tun_id = str_to_u64(arg);
break;
case OFPUTIL_NXAST_WRITE_METADATA:
parse_metadata(ofpacts, arg);
break;
case OFPUTIL_NXAST_SET_QUEUE:
ofpact_put_SET_QUEUE(ofpacts)->queue_id = str_to_u32(arg);
break;
@@ -560,6 +582,7 @@ static void
str_to_ofpacts(const struct flow *flow, char *str, struct ofpbuf *ofpacts)
{
char *pos, *act, *arg;
enum ofperr error;
int n_actions;
pos = str;
@@ -570,6 +593,12 @@ str_to_ofpacts(const struct flow *flow, char *str, struct ofpbuf *ofpacts)
}
n_actions++;
}
error = ofpacts_verify(ofpacts->data, ofpacts->size);
if (error) {
ovs_fatal(0, "Incorrect action ordering");
}
ofpact_pad(ofpacts);
}
@@ -577,6 +606,8 @@ static void
parse_named_instruction(enum ovs_instruction_type type,
char *arg, struct ofpbuf *ofpacts)
{
enum ofperr error;
switch (type) {
case OVSINST_OFPIT11_APPLY_ACTIONS:
NOT_REACHED(); /* This case is handled by str_to_inst_ofpacts() */
@@ -592,8 +623,7 @@ parse_named_instruction(enum ovs_instruction_type type,
break;
case OVSINST_OFPIT11_WRITE_METADATA:
/* TODO:XXX */
ovs_fatal(0, "instruction write-metadata is not supported yet");
parse_metadata(ofpacts, arg);
break;
case OVSINST_OFPIT11_GOTO_TABLE: {
@@ -606,6 +636,13 @@ parse_named_instruction(enum ovs_instruction_type type,
break;
}
}
/* If write_metadata is specified as an action AND an instruction, ofpacts
could be invalid. */
error = ofpacts_verify(ofpacts->data, ofpacts->size);
if (error) {
ovs_fatal(0, "Incorrect instruction ordering");
}
}
static void