ofp-actions: Add instructions bitmaps and fix related bug.
authorBen Pfaff <blp@nicira.com>
Mon, 11 Aug 2014 18:07:53 +0000 (11:07 -0700)
committerBen Pfaff <blp@nicira.com>
Mon, 11 Aug 2014 18:07:53 +0000 (11:07 -0700)
This will allow, later, to centralize all of the knowledge of instruction
encoding inside ofp-actions.

OFPIT11_ALL and OFPIT13_ALL are no longer used, so this commit removes
them.  Their definitions were wrong (they did not shift each bit into
position correctly), so this commit is also a small bug fix.

Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Jarno Rajahalme <jrajahalme@nicira.com>
include/openflow/openflow-1.1.h
include/openflow/openflow-1.3.h
lib/ofp-actions.c
lib/ofp-actions.h
lib/ofp-util.c
lib/ofp-util.h
ofproto/ofproto-provider.h
ofproto/ofproto.c
tests/ofproto.at

index bb6bcb0..5e618c9 100644 (file)
@@ -290,10 +290,6 @@ enum ofp11_instruction_type {
     OFPIT11_EXPERIMENTER = 0xFFFF  /* Experimenter instruction */
 };
 
-#define OFPIT11_ALL (OFPIT11_GOTO_TABLE | OFPIT11_WRITE_METADATA |      \
-                     OFPIT11_WRITE_ACTIONS | OFPIT11_APPLY_ACTIONS |    \
-                     OFPIT11_CLEAR_ACTIONS)
-
 #define OFP11_INSTRUCTION_ALIGN 8
 
 /* Generic ofp_instruction structure. */
index cc425f1..39de5b3 100644 (file)
@@ -91,10 +91,6 @@ enum ofp13_instruction_type {
     OFPIT13_METER = 6           /* Apply meter (rate limiter) */
 };
 
-#define OFPIT13_ALL (OFPIT11_GOTO_TABLE | OFPIT11_WRITE_METADATA |      \
-                     OFPIT11_WRITE_ACTIONS | OFPIT11_APPLY_ACTIONS |    \
-                     OFPIT11_CLEAR_ACTIONS | OFPIT13_METER)
-
 /* Instruction structure for OFPIT_METER */
 struct ofp13_instruction_meter {
     ovs_be16 type;              /* OFPIT13_METER */
index d6436c2..3eaf49c 100644 (file)
@@ -1646,6 +1646,75 @@ OVS_INSTRUCTIONS
     }
 }
 
+/* Two-way translation between OVS's internal "OVSINST_*" representation of
+ * instructions and the "OFPIT_*" representation used in OpenFlow. */
+struct ovsinst_map {
+    enum ovs_instruction_type ovsinst; /* Internal name for instruction. */
+    int ofpit;                         /* OFPIT_* number from OpenFlow spec. */
+};
+
+static const struct ovsinst_map *
+get_ovsinst_map(enum ofp_version version)
+{
+    /* OpenFlow 1.1 and 1.2 instructions. */
+    static const struct ovsinst_map of11[] = {
+        { OVSINST_OFPIT11_GOTO_TABLE, 1 },
+        { OVSINST_OFPIT11_WRITE_METADATA, 2 },
+        { OVSINST_OFPIT11_WRITE_ACTIONS, 3 },
+        { OVSINST_OFPIT11_APPLY_ACTIONS, 4 },
+        { OVSINST_OFPIT11_CLEAR_ACTIONS, 5 },
+        { 0, -1 },
+    };
+
+    /* OpenFlow 1.3+ instructions. */
+    static const struct ovsinst_map of13[] = {
+        { OVSINST_OFPIT11_GOTO_TABLE, 1 },
+        { OVSINST_OFPIT11_WRITE_METADATA, 2 },
+        { OVSINST_OFPIT11_WRITE_ACTIONS, 3 },
+        { OVSINST_OFPIT11_APPLY_ACTIONS, 4 },
+        { OVSINST_OFPIT11_CLEAR_ACTIONS, 5 },
+        { OVSINST_OFPIT13_METER, 6 },
+        { 0, -1 },
+    };
+
+    return version < OFP13_VERSION ? of11 : of13;
+}
+
+/* Converts 'ovsinst_bitmap', a bitmap whose bits correspond to OVSINST_*
+ * values, into a bitmap of instructions suitable for OpenFlow 'version'
+ * (OFP11_VERSION or later), and returns the result. */
+ovs_be32
+ovsinst_bitmap_to_openflow(uint32_t ovsinst_bitmap, enum ofp_version version)
+{
+    uint32_t ofpit_bitmap = 0;
+    const struct ovsinst_map *x;
+
+    for (x = get_ovsinst_map(version); x->ofpit >= 0; x++) {
+        if (ovsinst_bitmap & (1u << x->ovsinst)) {
+            ofpit_bitmap |= 1u << x->ofpit;
+        }
+    }
+    return htonl(ofpit_bitmap);
+}
+
+/* Converts 'ofpit_bitmap', a bitmap of instructions from an OpenFlow message
+ * with the given 'version' (OFP11_VERSION or later) into a bitmap whose bits
+ * correspond to OVSINST_* values, and returns the result. */
+uint32_t
+ovsinst_bitmap_from_openflow(ovs_be32 ofpit_bitmap_, enum ofp_version version)
+{
+    uint32_t ofpit_bitmap = ntohl(ofpit_bitmap_);
+    uint32_t ovsinst_bitmap = 0;
+    const struct ovsinst_map *x;
+
+    for (x = get_ovsinst_map(version); x->ofpit >= 0; x++) {
+        if (ofpit_bitmap & (1u << x->ofpit)) {
+            ovsinst_bitmap |= 1u << x->ovsinst;
+        }
+    }
+    return ovsinst_bitmap;
+}
+
 static inline struct ofp11_instruction *
 instruction_next(const struct ofp11_instruction *inst)
 {
index ce61f9d..ff7f3b7 100644 (file)
@@ -761,4 +761,8 @@ enum ovs_instruction_type ovs_instruction_type_from_ofpact_type(
 enum ofperr ovs_instruction_type_from_inst_type(
     enum ovs_instruction_type *instruction_type, const uint16_t inst_type);
 
+ovs_be32 ovsinst_bitmap_to_openflow(uint32_t ovsinst_bitmap, enum ofp_version);
+uint32_t ovsinst_bitmap_from_openflow(ovs_be32 ofpit_bitmap,
+                                      enum ofp_version);
+
 #endif /* ofp-actions.h */
index 9a8a868..86caafe 100644 (file)
@@ -5083,7 +5083,8 @@ ofputil_put_ofp11_table_stats(const struct ofputil_table_stats *in,
     ovs_strlcpy(out->name, in->name, sizeof out->name);
     out->wildcards = fields_to_ofp11_flow_match_fields(&in->wildcards);
     out->match = fields_to_ofp11_flow_match_fields(&in->match);
-    out->instructions = htonl(in->instructions);
+    out->instructions = ovsinst_bitmap_to_openflow(in->ovsinsts,
+                                                   OFP11_VERSION);
     out->write_actions = ofpact_bitmap_to_openflow(in->write_ofpacts,
                                                    OFP11_VERSION);
     out->apply_actions = ofpact_bitmap_to_openflow(in->apply_ofpacts,
@@ -5135,7 +5136,8 @@ ofputil_put_ofp12_table_stats(const struct ofputil_table_stats *in,
                                                    OFP12_VERSION);
     out->metadata_match = in->metadata_match;
     out->metadata_write = in->metadata_write;
-    out->instructions = htonl(in->instructions & OFPIT11_ALL);
+    out->instructions = ovsinst_bitmap_to_openflow(in->ovsinsts,
+                                                   OFP12_VERSION);
     out->config = htonl(in->config);
     out->max_entries = htonl(in->max_entries);
     out->active_count = htonl(in->active_count);
index 38e7006..6c7559a 100644 (file)
@@ -782,7 +782,7 @@ struct ofputil_table_stats {
     uint64_t apply_ofpacts;     /* OFPACT_* supported on Apply-Actions. */
     struct mf_bitmap write_setfields; /* Fields that can be set in W-A. */
     struct mf_bitmap apply_setfields; /* Fields that can be set in A-A. */
-    uint32_t instructions;      /* Bitmap of OFPIT_* values supported. */
+    uint32_t ovsinsts;          /* Bitmap of OVSINST_* values supported. */
 
     uint32_t active_count;      /* Number of active entries. */
     uint64_t lookup_count;      /* Number of packets looked up in table. */
index 9c0c94e..ca17319 100644 (file)
@@ -797,7 +797,7 @@ struct ofproto_class {
      *
      *   - 'metadata_match' and 'metadata_write' to OVS_BE64_MAX.
      *
-     *   - 'instructions' to all instructions.
+     *   - 'ovsinsts' to all instructions.
      *
      *   - 'config' to OFPTC11_TABLE_MISS_MASK.
      *
@@ -815,8 +815,8 @@ struct ofproto_class {
      *   - 'wildcards' to the set of wildcards actually supported by the table
      *     (if it doesn't support all OpenFlow wildcards).
      *
-     *   - 'instructions' to set the instructions actually supported by
-     *     the table.
+     *   - 'ovsinsts' to the set of instructions actually supported by the
+     *     table.
      *
      *   - 'write_actions' to set the write actions actually supported by
      *     the table (if it doesn't support all OpenFlow actions).
index 78b6773..ac7cb13 100644 (file)
@@ -3094,7 +3094,7 @@ handle_table_stats_request(struct ofconn *ofconn,
         stats[i].apply_setfields = rw_fields;
         stats[i].metadata_match = OVS_BE64_MAX;
         stats[i].metadata_write = OVS_BE64_MAX;
-        stats[i].instructions = OFPIT13_ALL;
+        stats[i].ovsinsts = (1u << N_OVS_INSTRUCTIONS) - 1;
         stats[i].config = OFPTC11_TABLE_MISS_MASK;
         stats[i].max_entries = 1000000; /* An arbitrary big number. */
         stats[i].active_count = classifier_count(&p->tables[i].cls);
index 06a7df4..5eef15b 100644 (file)
@@ -1067,7 +1067,7 @@ OVS_VSWITCHD_START
 (mid="wild=0x1ffffffffd, max=1000000,"
  tail="
                lookup=0, matched=0
-               match=0x1ffffffffd, instructions=0x00000007, config=0x00000003
+               match=0x1ffffffffd, instructions=0x0000003e, config=0x00000003
                write_actions=0x03ff8001, apply_actions=0x03ff8001
                write_setfields=0x0000000c0fe7fbdd
                apply_setfields=0x0000000c0fe7fbdd