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:
@@ -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
|
||||
|
Reference in New Issue
Block a user