return false;
}
+static void
+parse_output(struct ofpbuf *b, char *arg)
+{
+ if (strchr(arg, '[')) {
+ struct nx_action_output_reg *naor;
+ int ofs, n_bits;
+ uint32_t src;
+
+ nxm_parse_field_bits(arg, &src, &ofs, &n_bits);
+
+ naor = put_action(b, sizeof *naor, OFPAT_VENDOR);
+ naor->vendor = htonl(NX_VENDOR_ID);
+ naor->subtype = htons(NXAST_OUTPUT_REG);
+ naor->ofs_nbits = nxm_encode_ofs_nbits(ofs, n_bits);
+ naor->src = htonl(src);
+ naor->max_len = htons(UINT16_MAX);
+ } else {
+ put_output_action(b, str_to_u32(arg));
+ }
+}
+
static void
parse_resubmit(struct nx_action_resubmit *nar, char *arg)
{
} else if (!strcasecmp(act, "bundle_load")) {
bundle_parse_load(b, arg);
} else if (!strcasecmp(act, "output")) {
- put_output_action(b, str_to_u32(arg));
+ parse_output(b, arg);
} else if (!strcasecmp(act, "enqueue")) {
char *sp = NULL;
char *port_s = strtok_r(arg, ":q", &sp);
return false;
}
+BUILD_ASSERT_DECL(FLOW_WC_SEQ == 1);
#define FIELDS \
FIELD(F_TUN_ID, "tun_id", 0) \
FIELD(F_IN_PORT, "in_port", FWW_IN_PORT) \
static void
parse_reg_value(struct cls_rule *rule, int reg_idx, const char *value)
{
- uint32_t reg_value, reg_mask;
+ /* This uses an oversized destination field (64 bits when 32 bits would do)
+ * because some sscanf() implementations truncate the range of %i
+ * directives, so that e.g. "%"SCNi16 interprets input of "0xfedc" as a
+ * value of 0x7fff. The other alternatives are to allow only a single
+ * radix (e.g. decimal or hexadecimal) or to write more sophisticated
+ * parsers. */
+ unsigned long long int reg_value, reg_mask;
if (!strcmp(value, "ANY") || !strcmp(value, "*")) {
cls_rule_set_reg_masked(rule, reg_idx, 0, 0);
- } else if (sscanf(value, "%"SCNi32"/%"SCNi32,
+ } else if (sscanf(value, "%lli/%lli",
®_value, ®_mask) == 2) {
cls_rule_set_reg_masked(rule, reg_idx, reg_value, reg_mask);
- } else if (sscanf(value, "%"SCNi32, ®_value)) {
+ } else if (sscanf(value, "%lli", ®_value)) {
cls_rule_set_reg(rule, reg_idx, reg_value);
} else {
ovs_fatal(0, "register fields must take the form <value> "
* constant for 'command'. To parse syntax for an OFPST_FLOW or
* OFPST_AGGREGATE (or NXST_FLOW or NXST_AGGREGATE), use -1 for 'command'. */
void
-parse_ofp_str(struct flow_mod *fm, int command, const char *str_, bool verbose)
+parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_,
+ bool verbose)
{
enum {
F_OUT_PORT = 1 << 0,
struct cls_rule rule_copy;
struct ofpbuf actions;
struct ofpbuf *ofm;
- struct flow_mod fm;
+ struct ofputil_flow_mod fm;
ofpbuf_init(&actions, 64);
parse_ofp_str(&fm, command, string, verbose);
}
void
-parse_ofp_flow_stats_request_str(struct flow_stats_request *fsr,
+parse_ofp_flow_stats_request_str(struct ofputil_flow_stats_request *fsr,
bool aggregate, char *string)
{
- struct flow_mod fm;
+ struct ofputil_flow_mod fm;
parse_ofp_str(&fm, -1, string, false);
fsr->aggregate = aggregate;