in_port_s = strsep(&arg, ",");
if (in_port_s && in_port_s[0]) {
- if (!ofputil_port_from_string(in_port_s, &resubmit->in_port)) {
- resubmit->in_port = str_to_u32(in_port_s);
+ resubmit->in_port = ofputil_port_from_string(in_port_s);
+ if (!resubmit->in_port) {
+ ovs_fatal(0, "%s: resubmit to unknown port", in_port_s);
}
} else {
resubmit->in_port = OFPP_IN_PORT;
ofpact_update_len(b, &ids->ofpact);
}
+static void
+set_field_parse(const char *arg, struct ofpbuf *ofpacts)
+{
+ char *orig = xstrdup(arg);
+ struct ofpact_reg_load *load = ofpact_put_REG_LOAD(ofpacts);
+ char *value;
+ char *delim;
+ char *key;
+ const struct mf_field *mf;
+ const char *error;
+ union mf_value mf_value;
+
+ value = orig;
+ delim = strstr(orig, "->");
+ if (!delim) {
+ ovs_fatal(0, "%s: missing `->'", orig);
+ }
+ if (strlen(delim) <= strlen("->")) {
+ ovs_fatal(0, "%s: missing field name following `->'", orig);
+ }
+
+ key = delim + strlen("->");
+ mf = mf_from_name(key);
+ if (!mf) {
+ ovs_fatal(0, "%s is not valid oxm field name", key);
+ }
+ if (!mf->writable) {
+ ovs_fatal(0, "%s is not allowed to set", key);
+ }
+
+ delim[0] = '\0';
+ error = mf_parse_value(mf, value, &mf_value);
+ if (error) {
+ ovs_fatal(0, "%s", error);
+ }
+ if (!mf_is_value_valid(mf, &mf_value)) {
+ ovs_fatal(0, "%s is not valid valid for field %s", value, key);
+ }
+ ofpact_set_field_init(load, mf, &mf_value);
+ free(orig);
+}
+
static void
parse_named_action(enum ofputil_action_code code, const struct flow *flow,
char *arg, struct ofpbuf *ofpacts)
ofpact_put_SET_VLAN_PCP(ofpacts)->vlan_pcp = pcp;
break;
+ case OFPUTIL_OFPAT12_SET_FIELD:
+ set_field_parse(arg, ofpacts);
+ break;
+
case OFPUTIL_OFPAT10_STRIP_VLAN:
ofpact_put_STRIP_VLAN(ofpacts);
break;
pos = str;
n_actions = 0;
while (ofputil_parse_key_value(&pos, &act, &arg)) {
- uint16_t port;
- int code;
-
- code = ofputil_action_code_from_name(act);
+ int code = ofputil_action_code_from_name(act);
if (code >= 0) {
parse_named_action(code, flow, arg, ofpacts);
} else if (!strcasecmp(act, "drop")) {
"actions");
}
break;
- } else if (ofputil_port_from_string(act, &port)) {
- ofpact_put_OUTPUT(ofpacts)->port = port;
} else {
- ovs_fatal(0, "Unknown action: %s", act);
+ uint16_t port = ofputil_port_from_string(act);
+ if (port) {
+ ofpact_put_OUTPUT(ofpacts)->port = port;
+ } else {
+ ovs_fatal(0, "Unknown action: %s", act);
+ }
}
n_actions++;
}
if (!strcmp(name, "table")) {
fm->table_id = str_to_table_id(value);
} else if (!strcmp(name, "out_port")) {
- fm->out_port = atoi(value);
+ fm->out_port = ofputil_port_from_string(name);
+ if (!fm->out_port) {
+ ofp_fatal(str_, verbose, "%s is not a valid OpenFlow port",
+ name);
+ }
} else if (fields & F_PRIORITY && !strcmp(name, "priority")) {
fm->priority = str_to_u16(value, name);
} else if (fields & F_TIMEOUT && !strcmp(name, "idle_timeout")) {