Strip down vport interface : iflink
[openvswitch] / lib / ofp-parse.c
index c171293c77e133c7fcf2461d10cb736992b51b06..e352bd436334b823fac85dfbe97efb3419ab4913 100644 (file)
@@ -316,6 +316,27 @@ parse_port_name(const char *name, uint16_t *port)
     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)
 {
@@ -541,7 +562,7 @@ str_to_action(char *str, struct ofpbuf *b)
         } 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);
@@ -613,6 +634,7 @@ parse_protocol(const char *name, const struct protocol **p_out)
     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)        \
@@ -812,14 +834,20 @@ parse_field_value(struct cls_rule *rule, enum field_index index,
 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",
                       &reg_value, &reg_mask) == 2) {
         cls_rule_set_reg_masked(rule, reg_idx, reg_value, reg_mask);
-    } else if (sscanf(value, "%"SCNi32, &reg_value)) {
+    } else if (sscanf(value, "%lli", &reg_value)) {
         cls_rule_set_reg(rule, reg_idx, reg_value);
     } else {
         ovs_fatal(0, "register fields must take the form <value> "
@@ -836,7 +864,8 @@ parse_reg_value(struct cls_rule *rule, int reg_idx, const char *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,
@@ -1007,7 +1036,7 @@ parse_ofp_flow_mod_str(struct list *packets, enum nx_flow_format *cur_format,
     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);
@@ -1061,10 +1090,10 @@ parse_ofp_flow_mod_file(struct list *packets,
 }
 
 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;