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. */
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 */
}
}
+/* 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)
{
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 */
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,
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);
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. */
*
* - 'metadata_match' and 'metadata_write' to OVS_BE64_MAX.
*
- * - 'instructions' to all instructions.
+ * - 'ovsinsts' to all instructions.
*
* - 'config' to OFPTC11_TABLE_MISS_MASK.
*
* - '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).
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);
(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