[ovs-dev] [PATCH v2 02/16] ofp-actions: Add action bitmap abstraction.
Ben Pfaff
blp at nicira.com
Thu Aug 7 23:13:48 UTC 2014
Until now, sets of actions have been abstracted separately outside
ofp-actions, as enum ofputil_action_bitmap. Drawing sets of actions into
ofp-actions, as done in this commit, makes for a better overall
abstraction of actions, with better consistency.
A big part of this commit is shifting from using ofp12_table_stats as if
it were an abstraction for OpenFlow table stats, toward using a new
struct ofputil_table_stats, which is what we generally do with other
OpenFlow structures and fits better with the rest of the code.
Signed-off-by: Ben Pfaff <blp at nicira.com>
---
lib/ofp-actions.c | 156 ++++++++++++++++++++++++
lib/ofp-actions.h | 145 ++++++++++++-----------
lib/ofp-print.c | 105 ++++-------------
lib/ofp-util.c | 280 +++++++++++++++++++++-----------------------
lib/ofp-util.h | 66 ++++-------
ofproto/ofproto-dpif.c | 23 +---
ofproto/ofproto-provider.h | 22 ++--
ofproto/ofproto.c | 85 ++++++--------
tests/ofp-print.at | 26 ++--
tests/ofproto.at | 20 ++--
10 files changed, 495 insertions(+), 433 deletions(-)
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index e8fd922..3818b2d 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -3091,6 +3091,151 @@ ofpacts_put_openflow_instructions(const struct ofpact ofpacts[],
}
}
+/* Sets of supported actions. */
+
+struct ofpact_xlate {
+ enum ofpact_type ofpact;
+ int ofpat;
+};
+
+static const struct ofpact_xlate *
+get_ofpact_xlate(enum ofp_version version)
+{
+ /* OpenFlow 1.0 actions. */
+ static const struct ofpact_xlate of10[] = {
+ { OFPACT_OUTPUT, 0 },
+ { OFPACT_SET_VLAN_VID, 1 },
+ { OFPACT_SET_VLAN_PCP, 2 },
+ { OFPACT_STRIP_VLAN, 3 },
+ { OFPACT_SET_ETH_SRC, 4 },
+ { OFPACT_SET_ETH_DST, 5 },
+ { OFPACT_SET_IPV4_SRC, 6 },
+ { OFPACT_SET_IPV4_DST, 7 },
+ { OFPACT_SET_IP_DSCP, 8 },
+ { OFPACT_SET_L4_SRC_PORT, 9 },
+ { OFPACT_SET_L4_DST_PORT, 10 },
+ { OFPACT_ENQUEUE, 11 },
+ { 0, -1 },
+ };
+
+ /* OpenFlow 1.1 actions. */
+ static const struct ofpact_xlate of11[] = {
+ { OFPACT_OUTPUT, 0 },
+ { OFPACT_SET_VLAN_VID, 1 },
+ { OFPACT_SET_VLAN_PCP, 2 },
+ { OFPACT_SET_ETH_SRC, 3 },
+ { OFPACT_SET_ETH_DST, 4 },
+ { OFPACT_SET_IPV4_SRC, 5 },
+ { OFPACT_SET_IPV4_DST, 6 },
+ { OFPACT_SET_IP_DSCP, 7 },
+ { OFPACT_SET_IP_ECN, 8 },
+ { OFPACT_SET_L4_SRC_PORT, 9 },
+ { OFPACT_SET_L4_DST_PORT, 10 },
+ /* OFPAT_COPY_TTL_OUT (11) not supported. */
+ /* OFPAT_COPY_TTL_IN (12) not supported. */
+ { OFPACT_SET_MPLS_LABEL, 13 },
+ { OFPACT_SET_MPLS_TC, 14 },
+ { OFPACT_SET_MPLS_TTL, 15 },
+ { OFPACT_DEC_MPLS_TTL, 16 },
+ { OFPACT_PUSH_VLAN, 17 },
+ { OFPACT_STRIP_VLAN, 18 },
+ { OFPACT_PUSH_MPLS, 19 },
+ { OFPACT_POP_MPLS, 20 },
+ { OFPACT_SET_QUEUE, 21 },
+ { OFPACT_GROUP, 22 },
+ { OFPACT_SET_IP_TTL, 23 },
+ { OFPACT_DEC_TTL, 24 },
+ { 0, -1 },
+ };
+
+ /* OpenFlow 1.2, 1.3, and 1.4 actions. */
+ static const struct ofpact_xlate of12[] = {
+ { OFPACT_OUTPUT, 0 },
+ /* OFPAT_COPY_TTL_OUT (11) not supported. */
+ /* OFPAT_COPY_TTL_IN (12) not supported. */
+ { OFPACT_SET_MPLS_TTL, 15 },
+ { OFPACT_DEC_MPLS_TTL, 16 },
+ { OFPACT_PUSH_VLAN, 17 },
+ { OFPACT_STRIP_VLAN, 18 },
+ { OFPACT_PUSH_MPLS, 19 },
+ { OFPACT_POP_MPLS, 20 },
+ { OFPACT_SET_QUEUE, 21 },
+ { OFPACT_GROUP, 22 },
+ { OFPACT_SET_IP_TTL, 23 },
+ { OFPACT_DEC_TTL, 24 },
+ { OFPACT_SET_FIELD, 25 },
+ /* OF1.3+ OFPAT_PUSH_PBB (26) not supported. */
+ /* OF1.3+ OFPAT_POP_PBB (27) not supported. */
+ { 0, -1 },
+ };
+
+ switch (version) {
+ case OFP10_VERSION:
+ return of10;
+
+ case OFP11_VERSION:
+ return of11;
+
+ case OFP12_VERSION:
+ case OFP13_VERSION:
+ case OFP14_VERSION:
+ case OFP15_VERSION:
+ default:
+ return of12;
+ }
+}
+
+/* Converts 'ofpacts_bitmap', a bitmap whose bits correspond to OFPACT_*
+ * values, into a bitmap of actions suitable for OpenFlow 'version', and
+ * returns the result. */
+ovs_be32
+ofpact_bitmap_to_openflow(uint64_t ofpacts_bitmap, enum ofp_version version)
+{
+ uint32_t openflow_bitmap = 0;
+ const struct ofpact_xlate *x;
+
+ for (x = get_ofpact_xlate(version); x->ofpat >= 0; x++) {
+ if (ofpacts_bitmap & (UINT64_C(1) << x->ofpact)) {
+ openflow_bitmap |= 1u << x->ofpat;
+ }
+ }
+ return htonl(openflow_bitmap);
+}
+
+/* Converts 'ofpat_bitmap', a bitmap of actions from an OpenFlow message with
+ * the given 'version' into a bitmap whose bits correspond to OFPACT_* values,
+ * and returns the result. */
+uint64_t
+ofpact_bitmap_from_openflow(ovs_be32 ofpat_bitmap, enum ofp_version version)
+{
+ uint64_t ofpact_bitmap = 0;
+ const struct ofpact_xlate *x;
+
+ for (x = get_ofpact_xlate(version); x->ofpat >= 0; x++) {
+ if (ofpat_bitmap & htonl(1u << x->ofpat)) {
+ ofpact_bitmap |= UINT64_C(1) << x->ofpact;
+ }
+ }
+ return ofpact_bitmap;
+}
+
+/* Appends to 's' a string representation of the set of OFPACT_* represented
+ * by 'ofpacts_bitmap'. */
+void
+ofpact_bitmap_format(uint64_t ofpacts_bitmap, struct ds *s)
+{
+ if (!ofpacts_bitmap) {
+ ds_put_cstr(s, "<none>");
+ } else {
+ while (ofpacts_bitmap) {
+ ds_put_format(s, "%s ",
+ ofpact_name(rightmost_1bit_idx(ofpacts_bitmap)));
+ ofpacts_bitmap = zero_rightmost_1bit(ofpacts_bitmap);
+ }
+ ds_chomp(s, ' ');
+ }
+}
+
/* Returns true if 'action' outputs to 'port', false otherwise. */
static bool
ofpact_outputs_to_port(const struct ofpact *ofpact, ofp_port_t port)
@@ -3648,3 +3793,14 @@ ofpact_pad(struct ofpbuf *ofpacts)
ofpbuf_put_zeros(ofpacts, pad);
}
}
+
+const char *
+ofpact_name(enum ofpact_type type)
+{
+ switch (type) {
+#define OFPACT(ENUM, STRUCT, MEMBER, NAME) case OFPACT_##ENUM: return NAME;
+ OFPACTS
+#undef OFPACT
+ }
+ return "<unknown>";
+}
diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h
index 8cb8862..5877151 100644
--- a/lib/ofp-actions.h
+++ b/lib/ofp-actions.h
@@ -31,7 +31,7 @@
* This macro is used directly only internally by this header, but the list is
* still of interest to developers.
*
- * Each DEFINE_OFPACT invocation has the following parameters:
+ * Each OFPACT invocation has the following parameters:
*
* 1. <ENUM>, used below in the enum definition of OFPACT_<ENUM>, and
* elsewhere.
@@ -49,80 +49,79 @@
* - If "struct <STRUCT>" is variable-length, it must be the name of the
* flexible array member.
*/
-#define OFPACTS \
- /* Output. */ \
- DEFINE_OFPACT(OUTPUT, ofpact_output, ofpact) \
- DEFINE_OFPACT(GROUP, ofpact_group, ofpact) \
- DEFINE_OFPACT(CONTROLLER, ofpact_controller, ofpact) \
- DEFINE_OFPACT(ENQUEUE, ofpact_enqueue, ofpact) \
- DEFINE_OFPACT(OUTPUT_REG, ofpact_output_reg, ofpact) \
- DEFINE_OFPACT(BUNDLE, ofpact_bundle, slaves) \
- \
- /* Header changes. */ \
- DEFINE_OFPACT(SET_FIELD, ofpact_set_field, ofpact) \
- DEFINE_OFPACT(SET_VLAN_VID, ofpact_vlan_vid, ofpact) \
- DEFINE_OFPACT(SET_VLAN_PCP, ofpact_vlan_pcp, ofpact) \
- DEFINE_OFPACT(STRIP_VLAN, ofpact_null, ofpact) \
- DEFINE_OFPACT(PUSH_VLAN, ofpact_null, ofpact) \
- DEFINE_OFPACT(SET_ETH_SRC, ofpact_mac, ofpact) \
- DEFINE_OFPACT(SET_ETH_DST, ofpact_mac, ofpact) \
- DEFINE_OFPACT(SET_IPV4_SRC, ofpact_ipv4, ofpact) \
- DEFINE_OFPACT(SET_IPV4_DST, ofpact_ipv4, ofpact) \
- DEFINE_OFPACT(SET_IP_DSCP, ofpact_dscp, ofpact) \
- DEFINE_OFPACT(SET_IP_ECN, ofpact_ecn, ofpact) \
- DEFINE_OFPACT(SET_IP_TTL, ofpact_ip_ttl, ofpact) \
- DEFINE_OFPACT(SET_L4_SRC_PORT, ofpact_l4_port, ofpact) \
- DEFINE_OFPACT(SET_L4_DST_PORT, ofpact_l4_port, ofpact) \
- DEFINE_OFPACT(REG_MOVE, ofpact_reg_move, ofpact) \
- DEFINE_OFPACT(REG_LOAD, ofpact_reg_load, ofpact) \
- DEFINE_OFPACT(STACK_PUSH, ofpact_stack, ofpact) \
- DEFINE_OFPACT(STACK_POP, ofpact_stack, ofpact) \
- DEFINE_OFPACT(DEC_TTL, ofpact_cnt_ids, cnt_ids) \
- DEFINE_OFPACT(SET_MPLS_LABEL, ofpact_mpls_label, ofpact) \
- DEFINE_OFPACT(SET_MPLS_TC, ofpact_mpls_tc, ofpact) \
- DEFINE_OFPACT(SET_MPLS_TTL, ofpact_mpls_ttl, ofpact) \
- DEFINE_OFPACT(DEC_MPLS_TTL, ofpact_null, ofpact) \
- DEFINE_OFPACT(PUSH_MPLS, ofpact_push_mpls, ofpact) \
- DEFINE_OFPACT(POP_MPLS, ofpact_pop_mpls, ofpact) \
- \
- /* Metadata. */ \
- DEFINE_OFPACT(SET_TUNNEL, ofpact_tunnel, ofpact) \
- DEFINE_OFPACT(SET_QUEUE, ofpact_queue, ofpact) \
- DEFINE_OFPACT(POP_QUEUE, ofpact_null, ofpact) \
- DEFINE_OFPACT(FIN_TIMEOUT, ofpact_fin_timeout, ofpact) \
- \
- /* Flow table interaction. */ \
- DEFINE_OFPACT(RESUBMIT, ofpact_resubmit, ofpact) \
- DEFINE_OFPACT(LEARN, ofpact_learn, specs) \
- \
- /* Arithmetic. */ \
- DEFINE_OFPACT(MULTIPATH, ofpact_multipath, ofpact) \
- \
- /* Other. */ \
- DEFINE_OFPACT(NOTE, ofpact_note, data) \
- DEFINE_OFPACT(EXIT, ofpact_null, ofpact) \
- DEFINE_OFPACT(SAMPLE, ofpact_sample, ofpact) \
- \
- /* Instructions */ \
- DEFINE_OFPACT(METER, ofpact_meter, ofpact) \
- DEFINE_OFPACT(CLEAR_ACTIONS, ofpact_null, ofpact) \
- DEFINE_OFPACT(WRITE_ACTIONS, ofpact_nest, ofpact) \
- DEFINE_OFPACT(WRITE_METADATA, ofpact_metadata, ofpact) \
- DEFINE_OFPACT(GOTO_TABLE, ofpact_goto_table, ofpact)
+#define OFPACTS \
+ /* Output. */ \
+ OFPACT(OUTPUT, ofpact_output, ofpact, "output") \
+ OFPACT(GROUP, ofpact_group, ofpact, "group") \
+ OFPACT(CONTROLLER, ofpact_controller, ofpact, "controller") \
+ OFPACT(ENQUEUE, ofpact_enqueue, ofpact, "enqueue") \
+ OFPACT(OUTPUT_REG, ofpact_output_reg, ofpact, "output_reg") \
+ OFPACT(BUNDLE, ofpact_bundle, slaves, "bundle") \
+ \
+ /* Header changes. */ \
+ OFPACT(SET_FIELD, ofpact_set_field, ofpact, "set_field") \
+ OFPACT(SET_VLAN_VID, ofpact_vlan_vid, ofpact, "set_vlan_vid") \
+ OFPACT(SET_VLAN_PCP, ofpact_vlan_pcp, ofpact, "set_vlan_pcp") \
+ OFPACT(STRIP_VLAN, ofpact_null, ofpact, "strip_vlan") \
+ OFPACT(PUSH_VLAN, ofpact_null, ofpact, "push_vlan") \
+ OFPACT(SET_ETH_SRC, ofpact_mac, ofpact, "mod_dl_src") \
+ OFPACT(SET_ETH_DST, ofpact_mac, ofpact, "mod_dl_dst") \
+ OFPACT(SET_IPV4_SRC, ofpact_ipv4, ofpact, "mod_nw_src") \
+ OFPACT(SET_IPV4_DST, ofpact_ipv4, ofpact, "mod_nw_dst") \
+ OFPACT(SET_IP_DSCP, ofpact_dscp, ofpact, "mod_nw_tos") \
+ OFPACT(SET_IP_ECN, ofpact_ecn, ofpact, "mod_nw_ecn") \
+ OFPACT(SET_IP_TTL, ofpact_ip_ttl, ofpact, "mod_nw_ttl") \
+ OFPACT(SET_L4_SRC_PORT, ofpact_l4_port, ofpact, "mod_tp_src") \
+ OFPACT(SET_L4_DST_PORT, ofpact_l4_port, ofpact, "mod_tp_dst") \
+ OFPACT(REG_MOVE, ofpact_reg_move, ofpact, "move") \
+ OFPACT(REG_LOAD, ofpact_reg_load, ofpact, "load") \
+ OFPACT(STACK_PUSH, ofpact_stack, ofpact, "push") \
+ OFPACT(STACK_POP, ofpact_stack, ofpact, "pop") \
+ OFPACT(DEC_TTL, ofpact_cnt_ids, cnt_ids, "dec_ttl") \
+ OFPACT(SET_MPLS_LABEL, ofpact_mpls_label, ofpact, "set_mpls_label") \
+ OFPACT(SET_MPLS_TC, ofpact_mpls_tc, ofpact, "set_mpls_tc") \
+ OFPACT(SET_MPLS_TTL, ofpact_mpls_ttl, ofpact, "set_mpls_ttl") \
+ OFPACT(DEC_MPLS_TTL, ofpact_null, ofpact, "dec_mpls_ttl") \
+ OFPACT(PUSH_MPLS, ofpact_push_mpls, ofpact, "push_mpls") \
+ OFPACT(POP_MPLS, ofpact_pop_mpls, ofpact, "pop_mpls") \
+ \
+ /* Metadata. */ \
+ OFPACT(SET_TUNNEL, ofpact_tunnel, ofpact, "set_tunnel") \
+ OFPACT(SET_QUEUE, ofpact_queue, ofpact, "set_queue") \
+ OFPACT(POP_QUEUE, ofpact_null, ofpact, "pop_queue") \
+ OFPACT(FIN_TIMEOUT, ofpact_fin_timeout, ofpact, "fin_timeout") \
+ \
+ /* Flow table interaction. */ \
+ OFPACT(RESUBMIT, ofpact_resubmit, ofpact, "resubmit") \
+ OFPACT(LEARN, ofpact_learn, specs, "learn") \
+ \
+ /* Arithmetic. */ \
+ OFPACT(MULTIPATH, ofpact_multipath, ofpact, "multipath") \
+ \
+ /* Other. */ \
+ OFPACT(NOTE, ofpact_note, data, "note") \
+ OFPACT(EXIT, ofpact_null, ofpact, "exit") \
+ OFPACT(SAMPLE, ofpact_sample, ofpact, "sample") \
+ \
+ /* Instructions. */ \
+ OFPACT(METER, ofpact_meter, ofpact, "meter") \
+ OFPACT(CLEAR_ACTIONS, ofpact_null, ofpact, "clear_actions") \
+ OFPACT(WRITE_ACTIONS, ofpact_nest, ofpact, "write_actions") \
+ OFPACT(WRITE_METADATA, ofpact_metadata, ofpact, "write_metadata") \
+ OFPACT(GOTO_TABLE, ofpact_goto_table, ofpact, "goto_table")
/* enum ofpact_type, with a member OFPACT_<ENUM> for each action. */
enum OVS_PACKED_ENUM ofpact_type {
-#define DEFINE_OFPACT(ENUM, STRUCT, MEMBER) OFPACT_##ENUM,
+#define OFPACT(ENUM, STRUCT, MEMBER, NAME) OFPACT_##ENUM,
OFPACTS
-#undef DEFINE_OFPACT
+#undef OFPACT
};
-/* N_OFPACTS, the number of values of "enum ofpact_type". */
+/* Define N_OFPACTS to the number of types of ofpacts. */
enum {
- N_OFPACTS =
-#define DEFINE_OFPACT(ENUM, STRUCT, MEMBER) + 1
- OFPACTS
-#undef DEFINE_OFPACT
+#define OFPACT(ENUM, STRUCT, MEMBER, NAME) + 1
+ N_OFPACTS = OFPACTS
+#undef OFPACT
};
/* Header for an action.
@@ -611,6 +610,11 @@ void ofpacts_put_openflow_instructions(const struct ofpact[],
struct ofpbuf *openflow,
enum ofp_version ofp_version);
+/* Sets of supported actions. */
+ovs_be32 ofpact_bitmap_to_openflow(uint64_t ofpacts_bitmap, enum ofp_version);
+uint64_t ofpact_bitmap_from_openflow(ovs_be32 ofpat_bitmap, enum ofp_version);
+void ofpact_bitmap_format(uint64_t ofpacts_bitmap, struct ds *);
+
/* Working with ofpacts. */
bool ofpacts_output_to_port(const struct ofpact[], size_t ofpacts_len,
ofp_port_t port);
@@ -624,6 +628,7 @@ uint32_t ofpacts_get_meter(const struct ofpact[], size_t ofpacts_len);
*
* (For parsing ofpacts, see ofp-parse.h.) */
void ofpacts_format(const struct ofpact[], size_t ofpacts_len, struct ds *);
+const char *ofpact_name(enum ofpact_type);
/* Internal use by the helpers below. */
void ofpact_init(struct ofpact *, enum ofpact_type, size_t len);
@@ -667,7 +672,7 @@ void *ofpact_put(struct ofpbuf *, enum ofpact_type, size_t len);
* An integer constant, the value of OFPACT_<ENUM>_RAW_SIZE rounded up to a
* multiple of OFPACT_ALIGNTO.
*/
-#define DEFINE_OFPACT(ENUM, STRUCT, MEMBER) \
+#define OFPACT(ENUM, STRUCT, MEMBER, NAME) \
BUILD_ASSERT_DECL(offsetof(struct STRUCT, ofpact) == 0); \
\
enum { OFPACT_##ENUM##_RAW_SIZE \
@@ -699,7 +704,7 @@ void *ofpact_put(struct ofpbuf *, enum ofpact_type, size_t len);
OFPACT_##ENUM##_RAW_SIZE); \
}
OFPACTS
-#undef DEFINE_OFPACT
+#undef OFPACT
/* Functions to use after adding ofpacts to a buffer. */
void ofpact_update_len(struct ofpbuf *, struct ofpact *);
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 25e0478..2b0b20f 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -467,45 +467,6 @@ ofputil_capabilities_to_name(uint32_t bit)
return NULL;
}
-static const char *
-ofputil_action_bitmap_to_name(uint32_t bit)
-{
- enum ofputil_action_bitmap action = bit;
-
- switch (action) {
- case OFPUTIL_A_OUTPUT: return "OUTPUT";
- case OFPUTIL_A_SET_VLAN_VID: return "SET_VLAN_VID";
- case OFPUTIL_A_SET_VLAN_PCP: return "SET_VLAN_PCP";
- case OFPUTIL_A_STRIP_VLAN: return "STRIP_VLAN";
- case OFPUTIL_A_SET_DL_SRC: return "SET_DL_SRC";
- case OFPUTIL_A_SET_DL_DST: return "SET_DL_DST";
- case OFPUTIL_A_SET_NW_SRC: return "SET_NW_SRC";
- case OFPUTIL_A_SET_NW_DST: return "SET_NW_DST";
- case OFPUTIL_A_SET_NW_ECN: return "SET_NW_ECN";
- case OFPUTIL_A_SET_NW_TOS: return "SET_NW_TOS";
- case OFPUTIL_A_SET_TP_SRC: return "SET_TP_SRC";
- case OFPUTIL_A_SET_TP_DST: return "SET_TP_DST";
- case OFPUTIL_A_SET_FIELD: return "SET_FIELD";
- case OFPUTIL_A_ENQUEUE: return "ENQUEUE";
- case OFPUTIL_A_COPY_TTL_OUT: return "COPY_TTL_OUT";
- case OFPUTIL_A_COPY_TTL_IN: return "COPY_TTL_IN";
- case OFPUTIL_A_SET_MPLS_LABEL: return "SET_MPLS_LABEL";
- case OFPUTIL_A_SET_MPLS_TC: return "SET_MPLS_TC";
- case OFPUTIL_A_SET_MPLS_TTL: return "SET_MPLS_TTL";
- case OFPUTIL_A_DEC_MPLS_TTL: return "DEC_MPLS_TTL";
- case OFPUTIL_A_PUSH_VLAN: return "PUSH_VLAN";
- case OFPUTIL_A_POP_VLAN: return "POP_VLAN";
- case OFPUTIL_A_PUSH_MPLS: return "PUSH_MPLS";
- case OFPUTIL_A_POP_MPLS: return "POP_MPLS";
- case OFPUTIL_A_SET_QUEUE: return "SET_QUEUE";
- case OFPUTIL_A_GROUP: return "GROUP";
- case OFPUTIL_A_SET_NW_TTL: return "SET_NW_TTL";
- case OFPUTIL_A_DEC_NW_TTL: return "DEC_NW_TTL";
- }
-
- return NULL;
-}
-
static void
ofp_print_switch_features(struct ds *string, const struct ofp_header *oh)
{
@@ -536,8 +497,7 @@ ofp_print_switch_features(struct ds *string, const struct ofp_header *oh)
switch ((enum ofp_version)oh->version) {
case OFP10_VERSION:
ds_put_cstr(string, "actions: ");
- ofp_print_bit_names(string, features.actions,
- ofputil_action_bitmap_to_name, ' ');
+ ofpact_bitmap_format(features.ofpacts, string);
ds_put_char(string, '\n');
break;
case OFP11_VERSION:
@@ -2458,10 +2418,23 @@ ofp_print_group_stats(struct ds *s, const struct ofp_header *oh)
}
}
+static const char *
+group_type_to_string(enum ofp11_group_type type)
+{
+ switch (type) {
+ case OFPGT11_ALL: return "all";
+ case OFPGT11_SELECT: return "select";
+ case OFPGT11_INDIRECT: return "indirect";
+ case OFPGT11_FF: return "fast failover";
+ default: OVS_NOT_REACHED();
+ }
+}
+
static void
ofp_print_group_features(struct ds *string, const struct ofp_header *oh)
{
struct ofputil_group_features features;
+ int i;
ofputil_decode_group_features_reply(oh, &features);
@@ -2470,32 +2443,15 @@ ofp_print_group_features(struct ds *string, const struct ofp_header *oh)
ds_put_format(string, " Capabilities: 0x%"PRIx32"\n",
features.capabilities);
- if (features.types & (1u << OFPGT11_ALL)) {
- ds_put_format(string, " All group :\n");
- ds_put_format(string,
- " max_groups = %#"PRIx32" actions=0x%08"PRIx32"\n",
- features.max_groups[0], features.actions[0]);
- }
-
- if (features.types & (1u << OFPGT11_SELECT)) {
- ds_put_format(string, " Select group :\n");
- ds_put_format(string, " max_groups = %#"PRIx32" "
- "actions=0x%08"PRIx32"\n",
- features.max_groups[1], features.actions[1]);
- }
-
- if (features.types & (1u << OFPGT11_INDIRECT)) {
- ds_put_format(string, " Indirect group :\n");
- ds_put_format(string, " max_groups = %#"PRIx32" "
- "actions=0x%08"PRIx32"\n",
- features.max_groups[2], features.actions[2]);
- }
-
- if (features.types & (1u << OFPGT11_FF)) {
- ds_put_format(string, " Fast Failover group :\n");
- ds_put_format(string, " max_groups = %#"PRIx32" "
- "actions=0x%08"PRIx32"\n",
- features.max_groups[3], features.actions[3]);
+ for (i = 0; i < 4; i++) {
+ if (features.types & (1u << i)) {
+ ds_put_format(string, " %s group:\n", group_type_to_string(i));
+ ds_put_format(string, " max_groups=%#"PRIx32"\n",
+ features.max_groups[i]);
+ ds_put_format(string, " actions: ");
+ ofpact_bitmap_format(features.ofpacts[i], string);
+ ds_put_char(string, '\n');
+ }
}
}
@@ -2535,23 +2491,12 @@ ofp_print_group_mod(struct ds *s, const struct ofp_header *oh)
ofp_print_group(s, gm.group_id, gm.type, &gm.buckets);
}
-static const char *
-ofp13_action_to_string(uint32_t bit)
-{
- switch (bit) {
-#define OFPAT13_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
- case 1u << ENUM: return NAME;
-#include "ofp-util.def"
- }
- return NULL;
-}
-
static void
print_table_action_features(struct ds *s,
const struct ofputil_table_action_features *taf)
{
ds_put_cstr(s, " actions: ");
- ofp_print_bit_names(s, taf->actions, ofp13_action_to_string, ',');
+ ofpact_bitmap_format(taf->ofpacts, s);
ds_put_char(s, '\n');
ds_put_cstr(s, " supported on Set-Field: ");
@@ -2572,7 +2517,7 @@ static bool
table_action_features_equal(const struct ofputil_table_action_features *a,
const struct ofputil_table_action_features *b)
{
- return (a->actions == b->actions
+ return (a->ofpacts == b->ofpacts
&& bitmap_equal(a->set_fields.bm, b->set_fields.bm, MFF_N_IDS));
}
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index a065169..0ef4070 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -4012,42 +4012,6 @@ BUILD_ASSERT_DECL((int) OFPUTIL_C_IP_REASM == OFPC_IP_REASM);
BUILD_ASSERT_DECL((int) OFPUTIL_C_QUEUE_STATS == OFPC_QUEUE_STATS);
BUILD_ASSERT_DECL((int) OFPUTIL_C_ARP_MATCH_IP == OFPC_ARP_MATCH_IP);
-struct ofputil_action_bit_translation {
- enum ofputil_action_bitmap ofputil_bit;
- int of_bit;
-};
-
-static const struct ofputil_action_bit_translation of10_action_bits[] = {
- { OFPUTIL_A_OUTPUT, OFPAT10_OUTPUT },
- { OFPUTIL_A_SET_VLAN_VID, OFPAT10_SET_VLAN_VID },
- { OFPUTIL_A_SET_VLAN_PCP, OFPAT10_SET_VLAN_PCP },
- { OFPUTIL_A_STRIP_VLAN, OFPAT10_STRIP_VLAN },
- { OFPUTIL_A_SET_DL_SRC, OFPAT10_SET_DL_SRC },
- { OFPUTIL_A_SET_DL_DST, OFPAT10_SET_DL_DST },
- { OFPUTIL_A_SET_NW_SRC, OFPAT10_SET_NW_SRC },
- { OFPUTIL_A_SET_NW_DST, OFPAT10_SET_NW_DST },
- { OFPUTIL_A_SET_NW_TOS, OFPAT10_SET_NW_TOS },
- { OFPUTIL_A_SET_TP_SRC, OFPAT10_SET_TP_SRC },
- { OFPUTIL_A_SET_TP_DST, OFPAT10_SET_TP_DST },
- { OFPUTIL_A_ENQUEUE, OFPAT10_ENQUEUE },
- { 0, 0 },
-};
-
-static enum ofputil_action_bitmap
-decode_action_bits(ovs_be32 of_actions,
- const struct ofputil_action_bit_translation *x)
-{
- enum ofputil_action_bitmap ofputil_actions;
-
- ofputil_actions = 0;
- for (; x->ofputil_bit; x++) {
- if (of_actions & htonl(1u << x->of_bit)) {
- ofputil_actions |= x->ofputil_bit;
- }
- }
- return ofputil_actions;
-}
-
static uint32_t
ofputil_capabilities_mask(enum ofp_version ofp_version)
{
@@ -4096,13 +4060,14 @@ ofputil_decode_switch_features(const struct ofp_header *oh,
if (osf->capabilities & htonl(OFPC10_STP)) {
features->capabilities |= OFPUTIL_C_STP;
}
- features->actions = decode_action_bits(osf->actions, of10_action_bits);
+ features->ofpacts = ofpact_bitmap_from_openflow(osf->actions,
+ OFP10_VERSION);
} else if (raw == OFPRAW_OFPT11_FEATURES_REPLY
|| raw == OFPRAW_OFPT13_FEATURES_REPLY) {
if (osf->capabilities & htonl(OFPC11_GROUP_STATS)) {
features->capabilities |= OFPUTIL_C_GROUP_STATS;
}
- features->actions = 0;
+ features->ofpacts = 0;
if (raw == OFPRAW_OFPT13_FEATURES_REPLY) {
features->auxiliary_id = osf->auxiliary_id;
}
@@ -4153,21 +4118,6 @@ ofputil_switch_features_has_ports(struct ofpbuf *b)
return false;
}
-static ovs_be32
-encode_action_bits(enum ofputil_action_bitmap ofputil_actions,
- const struct ofputil_action_bit_translation *x)
-{
- uint32_t of_actions;
-
- of_actions = 0;
- for (; x->ofputil_bit; x++) {
- if (ofputil_actions & x->ofputil_bit) {
- of_actions |= 1 << x->of_bit;
- }
- }
- return htonl(of_actions);
-}
-
/* Returns a buffer owned by the caller that encodes 'features' in the format
* required by 'protocol' with the given 'xid'. The caller should append port
* information to the buffer with subsequent calls to
@@ -4212,7 +4162,8 @@ ofputil_encode_switch_features(const struct ofputil_switch_features *features,
if (features->capabilities & OFPUTIL_C_STP) {
osf->capabilities |= htonl(OFPC10_STP);
}
- osf->actions = encode_action_bits(features->actions, of10_action_bits);
+ osf->actions = ofpact_bitmap_to_openflow(features->ofpacts,
+ OFP10_VERSION);
break;
case OFP13_VERSION:
case OFP14_VERSION:
@@ -4504,20 +4455,25 @@ pull_table_feature_property(struct ofpbuf *msg, struct ofpbuf *payload,
}
static enum ofperr
-parse_table_ids(struct ofpbuf *payload, uint32_t *ids)
+parse_action_bitmap(struct ofpbuf *payload, enum ofp_version ofp_version,
+ uint64_t *ofpacts)
{
- uint16_t type;
+ uint32_t types = 0;
- *ids = 0;
while (ofpbuf_size(payload) > 0) {
- enum ofperr error = pull_table_feature_property(payload, NULL, &type);
+ uint16_t type;
+ enum ofperr error;
+
+ error = pull_table_feature_property(payload, NULL, &type);
if (error) {
return error;
}
- if (type < CHAR_BIT * sizeof *ids) {
- *ids |= 1u << type;
+ if (type < CHAR_BIT * sizeof types) {
+ types |= 1u << type;
}
}
+
+ *ofpacts = ofpact_bitmap_from_openflow(htonl(types), ofp_version);
return 0;
}
@@ -4646,12 +4602,14 @@ int
ofputil_decode_table_features(struct ofpbuf *msg,
struct ofputil_table_features *tf, bool loose)
{
+ const struct ofp_header *oh;
struct ofp13_table_features *otf;
unsigned int len;
if (!msg->frame) {
ofpraw_pull_assert(msg);
}
+ oh = ofpbuf_l2(msg);
if (!ofpbuf_size(msg)) {
return EOF;
@@ -4708,17 +4666,21 @@ ofputil_decode_table_features(struct ofpbuf *msg,
break;
case OFPTFPT13_WRITE_ACTIONS:
- error = parse_table_ids(&payload, &tf->nonmiss.write.actions);
+ error = parse_action_bitmap(&payload, oh->version,
+ &tf->nonmiss.write.ofpacts);
break;
case OFPTFPT13_WRITE_ACTIONS_MISS:
- error = parse_table_ids(&payload, &tf->miss.write.actions);
+ error = parse_action_bitmap(&payload, oh->version,
+ &tf->miss.write.ofpacts);
break;
case OFPTFPT13_APPLY_ACTIONS:
- error = parse_table_ids(&payload, &tf->nonmiss.apply.actions);
+ error = parse_action_bitmap(&payload, oh->version,
+ &tf->nonmiss.apply.ofpacts);
break;
case OFPTFPT13_APPLY_ACTIONS_MISS:
- error = parse_table_ids(&payload, &tf->miss.apply.actions);
+ error = parse_action_bitmap(&payload, oh->version,
+ &tf->miss.apply.ofpacts);
break;
case OFPTFPT13_MATCH:
@@ -5030,27 +4992,27 @@ ofputil_decode_role_status(const struct ofp_header *oh,
/* Table stats. */
static void
-ofputil_put_ofp10_table_stats(const struct ofp12_table_stats *in,
+ofputil_put_ofp10_table_stats(const struct ofputil_table_stats *in,
struct ofpbuf *buf)
{
struct wc_map {
enum ofp10_flow_wildcards wc10;
- enum oxm12_ofb_match_fields mf12;
+ enum mf_field_id mf;
};
static const struct wc_map wc_map[] = {
- { OFPFW10_IN_PORT, OFPXMT12_OFB_IN_PORT },
- { OFPFW10_DL_VLAN, OFPXMT12_OFB_VLAN_VID },
- { OFPFW10_DL_SRC, OFPXMT12_OFB_ETH_SRC },
- { OFPFW10_DL_DST, OFPXMT12_OFB_ETH_DST},
- { OFPFW10_DL_TYPE, OFPXMT12_OFB_ETH_TYPE },
- { OFPFW10_NW_PROTO, OFPXMT12_OFB_IP_PROTO },
- { OFPFW10_TP_SRC, OFPXMT12_OFB_TCP_SRC },
- { OFPFW10_TP_DST, OFPXMT12_OFB_TCP_DST },
- { OFPFW10_NW_SRC_MASK, OFPXMT12_OFB_IPV4_SRC },
- { OFPFW10_NW_DST_MASK, OFPXMT12_OFB_IPV4_DST },
- { OFPFW10_DL_VLAN_PCP, OFPXMT12_OFB_VLAN_PCP },
- { OFPFW10_NW_TOS, OFPXMT12_OFB_IP_DSCP },
+ { OFPFW10_IN_PORT, MFF_IN_PORT },
+ { OFPFW10_DL_VLAN, MFF_VLAN_VID },
+ { OFPFW10_DL_SRC, MFF_ETH_SRC },
+ { OFPFW10_DL_DST, MFF_ETH_DST},
+ { OFPFW10_DL_TYPE, MFF_ETH_TYPE },
+ { OFPFW10_NW_PROTO, MFF_IP_PROTO },
+ { OFPFW10_TP_SRC, MFF_TCP_SRC },
+ { OFPFW10_TP_DST, MFF_TCP_DST },
+ { OFPFW10_NW_SRC_MASK, MFF_IPV4_SRC },
+ { OFPFW10_NW_DST_MASK, MFF_IPV4_DST },
+ { OFPFW10_DL_VLAN_PCP, MFF_VLAN_PCP },
+ { OFPFW10_NW_TOS, MFF_IP_DSCP },
};
struct ofp10_table_stats *out;
@@ -5061,41 +5023,41 @@ ofputil_put_ofp10_table_stats(const struct ofp12_table_stats *in,
ovs_strlcpy(out->name, in->name, sizeof out->name);
out->wildcards = 0;
for (p = wc_map; p < &wc_map[ARRAY_SIZE(wc_map)]; p++) {
- if (in->wildcards & htonll(1ULL << p->mf12)) {
+ if (bitmap_is_set(in->wildcards.bm, p->mf)) {
out->wildcards |= htonl(p->wc10);
}
}
- out->max_entries = in->max_entries;
- out->active_count = in->active_count;
- put_32aligned_be64(&out->lookup_count, in->lookup_count);
- put_32aligned_be64(&out->matched_count, in->matched_count);
+ out->max_entries = htonl(in->max_entries);
+ out->active_count = htonl(in->active_count);
+ put_32aligned_be64(&out->lookup_count, htonll(in->lookup_count));
+ put_32aligned_be64(&out->matched_count, htonll(in->matched_count));
}
static ovs_be32
-oxm12_to_ofp11_flow_match_fields(ovs_be64 oxm12)
+fields_to_ofp11_flow_match_fields(const struct mf_bitmap *fields)
{
struct map {
enum ofp11_flow_match_fields fmf11;
- enum oxm12_ofb_match_fields mf12;
+ enum mf_field_id mf;
};
static const struct map map[] = {
- { OFPFMF11_IN_PORT, OFPXMT12_OFB_IN_PORT },
- { OFPFMF11_DL_VLAN, OFPXMT12_OFB_VLAN_VID },
- { OFPFMF11_DL_VLAN_PCP, OFPXMT12_OFB_VLAN_PCP },
- { OFPFMF11_DL_TYPE, OFPXMT12_OFB_ETH_TYPE },
- { OFPFMF11_NW_TOS, OFPXMT12_OFB_IP_DSCP },
- { OFPFMF11_NW_PROTO, OFPXMT12_OFB_IP_PROTO },
- { OFPFMF11_TP_SRC, OFPXMT12_OFB_TCP_SRC },
- { OFPFMF11_TP_DST, OFPXMT12_OFB_TCP_DST },
- { OFPFMF11_MPLS_LABEL, OFPXMT12_OFB_MPLS_LABEL },
- { OFPFMF11_MPLS_TC, OFPXMT12_OFB_MPLS_TC },
+ { OFPFMF11_IN_PORT, MFF_IN_PORT },
+ { OFPFMF11_DL_VLAN, MFF_VLAN_VID },
+ { OFPFMF11_DL_VLAN_PCP, MFF_VLAN_PCP },
+ { OFPFMF11_DL_TYPE, MFF_ETH_TYPE },
+ { OFPFMF11_NW_TOS, MFF_IP_DSCP },
+ { OFPFMF11_NW_PROTO, MFF_IP_PROTO },
+ { OFPFMF11_TP_SRC, MFF_TCP_SRC },
+ { OFPFMF11_TP_DST, MFF_TCP_DST },
+ { OFPFMF11_MPLS_LABEL, MFF_MPLS_LABEL },
+ { OFPFMF11_MPLS_TC, MFF_MPLS_TC },
/* I don't know what OFPFMF11_TYPE means. */
- { OFPFMF11_DL_SRC, OFPXMT12_OFB_ETH_SRC },
- { OFPFMF11_DL_DST, OFPXMT12_OFB_ETH_DST },
- { OFPFMF11_NW_SRC, OFPXMT12_OFB_IPV4_SRC },
- { OFPFMF11_NW_DST, OFPXMT12_OFB_IPV4_DST },
- { OFPFMF11_METADATA, OFPXMT12_OFB_METADATA },
+ { OFPFMF11_DL_SRC, MFF_ETH_SRC },
+ { OFPFMF11_DL_DST, MFF_ETH_DST },
+ { OFPFMF11_NW_SRC, MFF_IPV4_SRC },
+ { OFPFMF11_NW_DST, MFF_IPV4_DST },
+ { OFPFMF11_METADATA, MFF_METADATA },
};
const struct map *p;
@@ -5103,7 +5065,7 @@ oxm12_to_ofp11_flow_match_fields(ovs_be64 oxm12)
fmf11 = 0;
for (p = map; p < &map[ARRAY_SIZE(map)]; p++) {
- if (oxm12 & htonll(1ULL << p->mf12)) {
+ if (bitmap_is_set(fields->bm, p->mf)) {
fmf11 |= p->fmf11;
}
}
@@ -5111,7 +5073,7 @@ oxm12_to_ofp11_flow_match_fields(ovs_be64 oxm12)
}
static void
-ofputil_put_ofp11_table_stats(const struct ofp12_table_stats *in,
+ofputil_put_ofp11_table_stats(const struct ofputil_table_stats *in,
struct ofpbuf *buf)
{
struct ofp11_table_stats *out;
@@ -5119,50 +5081,84 @@ ofputil_put_ofp11_table_stats(const struct ofp12_table_stats *in,
out = ofpbuf_put_zeros(buf, sizeof *out);
out->table_id = in->table_id;
ovs_strlcpy(out->name, in->name, sizeof out->name);
- out->wildcards = oxm12_to_ofp11_flow_match_fields(in->wildcards);
- out->match = oxm12_to_ofp11_flow_match_fields(in->match);
- out->instructions = in->instructions;
- out->write_actions = in->write_actions;
- out->apply_actions = in->apply_actions;
- out->config = in->config;
- out->max_entries = in->max_entries;
- out->active_count = in->active_count;
- out->lookup_count = in->lookup_count;
- out->matched_count = in->matched_count;
+ 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->write_actions = ofpact_bitmap_to_openflow(in->write_ofpacts,
+ OFP11_VERSION);
+ out->apply_actions = ofpact_bitmap_to_openflow(in->apply_ofpacts,
+ OFP11_VERSION);
+ out->config = htonl(in->config);
+ out->max_entries = htonl(in->max_entries);
+ out->active_count = htonl(in->active_count);
+ out->lookup_count = htonll(in->lookup_count);
+ out->matched_count = htonll(in->matched_count);
+}
+
+static ovs_be64
+mf_bitmap_to_oxm_bitmap(const struct mf_bitmap *fields,
+ enum ofp_version version)
+{
+ uint64_t oxm_bitmap = 0;
+ int i;
+
+ BITMAP_FOR_EACH_1 (i, MFF_N_IDS, fields->bm) {
+ uint32_t oxm = mf_oxm_header(i, version);
+ uint32_t vendor = NXM_VENDOR(oxm);
+ int field = NXM_FIELD(oxm);
+
+ if (vendor == OFPXMC12_OPENFLOW_BASIC && field < 64) {
+ oxm_bitmap |= UINT64_C(1) << field;
+ }
+ }
+ return htonll(oxm_bitmap);
}
static void
-ofputil_put_ofp12_table_stats(const struct ofp12_table_stats *in,
+ofputil_put_ofp12_table_stats(const struct ofputil_table_stats *in,
struct ofpbuf *buf)
{
- struct ofp12_table_stats *out = ofpbuf_put(buf, in, sizeof *in);
+ struct ofp12_table_stats *out;
- /* Trim off OF1.3-only capabilities. */
- out->match &= htonll(OFPXMT12_MASK);
- out->wildcards &= htonll(OFPXMT12_MASK);
- out->write_setfields &= htonll(OFPXMT12_MASK);
- out->apply_setfields &= htonll(OFPXMT12_MASK);
+ out = ofpbuf_put_zeros(buf, sizeof *out);
+ out->table_id = in->table_id;
+ ovs_strlcpy(out->name, in->name, sizeof out->name);
+ out->match = mf_bitmap_to_oxm_bitmap(&in->match, OFP12_VERSION);
+ out->wildcards = mf_bitmap_to_oxm_bitmap(&in->wildcards, OFP12_VERSION);
+ out->write_actions = ofpact_bitmap_to_openflow(in->write_ofpacts,
+ OFP12_VERSION);
+ out->apply_actions = ofpact_bitmap_to_openflow(in->apply_ofpacts,
+ OFP12_VERSION);
+ out->write_setfields = mf_bitmap_to_oxm_bitmap(&in->write_setfields,
+ OFP12_VERSION);
+ out->apply_setfields = mf_bitmap_to_oxm_bitmap(&in->apply_setfields,
+ OFP12_VERSION);
+ out->metadata_match = in->metadata_match;
+ out->metadata_write = in->metadata_write;
+ out->instructions = htonl(in->instructions & OFPIT11_ALL);
+ out->config = htonl(in->config);
+ out->max_entries = htonl(in->max_entries);
+ out->active_count = htonl(in->active_count);
+ out->lookup_count = htonll(in->lookup_count);
+ out->matched_count = htonll(in->matched_count);
}
static void
-ofputil_put_ofp13_table_stats(const struct ofp12_table_stats *in,
+ofputil_put_ofp13_table_stats(const struct ofputil_table_stats *in,
struct ofpbuf *buf)
{
struct ofp13_table_stats *out;
- /* OF 1.3 splits table features off the ofp_table_stats,
- * so there is not much here. */
-
out = ofpbuf_put_uninit(buf, sizeof *out);
out->table_id = in->table_id;
- out->active_count = in->active_count;
- out->lookup_count = in->lookup_count;
- out->matched_count = in->matched_count;
+ out->active_count = htonl(in->active_count);
+ out->lookup_count = htonll(in->lookup_count);
+ out->matched_count = htonll(in->matched_count);
}
struct ofpbuf *
-ofputil_encode_table_stats_reply(const struct ofp12_table_stats stats[], int n,
- const struct ofp_header *request)
+ofputil_encode_table_stats_reply(const struct ofputil_table_stats stats[],
+ int n, const struct ofp_header *request)
{
struct ofpbuf *reply;
int i;
@@ -6796,20 +6792,18 @@ ofputil_encode_group_features_reply(
{
struct ofp12_group_features_stats *ogf;
struct ofpbuf *reply;
+ int i;
reply = ofpraw_alloc_xid(OFPRAW_OFPST12_GROUP_FEATURES_REPLY,
request->version, request->xid, 0);
ogf = ofpbuf_put_zeros(reply, sizeof *ogf);
ogf->types = htonl(features->types);
ogf->capabilities = htonl(features->capabilities);
- ogf->max_groups[0] = htonl(features->max_groups[0]);
- ogf->max_groups[1] = htonl(features->max_groups[1]);
- ogf->max_groups[2] = htonl(features->max_groups[2]);
- ogf->max_groups[3] = htonl(features->max_groups[3]);
- ogf->actions[0] = htonl(features->actions[0]);
- ogf->actions[1] = htonl(features->actions[1]);
- ogf->actions[2] = htonl(features->actions[2]);
- ogf->actions[3] = htonl(features->actions[3]);
+ for (i = 0; i < 4; i++) {
+ ogf->max_groups[i] = htonl(features->max_groups[i]);
+ ogf->actions[i] = ofpact_bitmap_to_openflow(features->ofpacts[i],
+ request->version);
+ }
return reply;
}
@@ -6820,17 +6814,15 @@ ofputil_decode_group_features_reply(const struct ofp_header *oh,
struct ofputil_group_features *features)
{
const struct ofp12_group_features_stats *ogf = ofpmsg_body(oh);
+ int i;
features->types = ntohl(ogf->types);
features->capabilities = ntohl(ogf->capabilities);
- features->max_groups[0] = ntohl(ogf->max_groups[0]);
- features->max_groups[1] = ntohl(ogf->max_groups[1]);
- features->max_groups[2] = ntohl(ogf->max_groups[2]);
- features->max_groups[3] = ntohl(ogf->max_groups[3]);
- features->actions[0] = ntohl(ogf->actions[0]);
- features->actions[1] = ntohl(ogf->actions[1]);
- features->actions[2] = ntohl(ogf->actions[2]);
- features->actions[3] = ntohl(ogf->actions[3]);
+ for (i = 0; i < 4; i++) {
+ features->max_groups[i] = ntohl(ogf->max_groups[i]);
+ features->ofpacts[i] = ofpact_bitmap_from_openflow(
+ ogf->actions[i], oh->version);
+ }
}
/* Parse a group status request message into a 32 bit OpenFlow 1.1
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index 39e50ed..38e7006 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -528,37 +528,6 @@ enum ofputil_capabilities {
OFPUTIL_C_PORT_BLOCKED = 1 << 8, /* Switch will block looping ports */
};
-enum ofputil_action_bitmap {
- OFPUTIL_A_OUTPUT = 1 << 0,
- OFPUTIL_A_SET_VLAN_VID = 1 << 1,
- OFPUTIL_A_SET_VLAN_PCP = 1 << 2,
- OFPUTIL_A_STRIP_VLAN = 1 << 3,
- OFPUTIL_A_SET_DL_SRC = 1 << 4,
- OFPUTIL_A_SET_DL_DST = 1 << 5,
- OFPUTIL_A_SET_NW_SRC = 1 << 6,
- OFPUTIL_A_SET_NW_DST = 1 << 7,
- OFPUTIL_A_SET_NW_ECN = 1 << 8,
- OFPUTIL_A_SET_NW_TOS = 1 << 9,
- OFPUTIL_A_SET_TP_SRC = 1 << 10,
- OFPUTIL_A_SET_TP_DST = 1 << 11,
- OFPUTIL_A_ENQUEUE = 1 << 12,
- OFPUTIL_A_COPY_TTL_OUT = 1 << 13,
- OFPUTIL_A_COPY_TTL_IN = 1 << 14,
- OFPUTIL_A_SET_MPLS_LABEL = 1 << 15,
- OFPUTIL_A_SET_MPLS_TC = 1 << 16,
- OFPUTIL_A_SET_MPLS_TTL = 1 << 17,
- OFPUTIL_A_DEC_MPLS_TTL = 1 << 18,
- OFPUTIL_A_PUSH_VLAN = 1 << 19,
- OFPUTIL_A_POP_VLAN = 1 << 20,
- OFPUTIL_A_PUSH_MPLS = 1 << 21,
- OFPUTIL_A_POP_MPLS = 1 << 22,
- OFPUTIL_A_SET_QUEUE = 1 << 23,
- OFPUTIL_A_GROUP = 1 << 24,
- OFPUTIL_A_SET_NW_TTL = 1 << 25,
- OFPUTIL_A_DEC_NW_TTL = 1 << 26,
- OFPUTIL_A_SET_FIELD = 1 << 27,
-};
-
/* Abstract ofp_switch_features. */
struct ofputil_switch_features {
uint64_t datapath_id; /* Datapath unique ID. */
@@ -566,7 +535,7 @@ struct ofputil_switch_features {
uint8_t n_tables; /* Number of tables supported by datapath. */
uint8_t auxiliary_id; /* Identify auxiliary connections */
enum ofputil_capabilities capabilities;
- enum ofputil_action_bitmap actions;
+ uint64_t ofpacts; /* Bitmap of OFPACT_* bits. */
};
enum ofperr ofputil_decode_switch_features(const struct ofp_header *,
@@ -650,7 +619,7 @@ struct ofputil_table_features {
* - 'apply' reports features available in an "apply_actions"
* instruction. */
struct ofputil_table_action_features {
- uint32_t actions; /* Bitmap of supported OFPAT*. */
+ uint64_t ofpacts; /* Bitmap of supported OFPACT_*. */
struct mf_bitmap set_fields; /* Fields for "set-field". */
} write, apply;
} nonmiss, miss;
@@ -798,13 +767,30 @@ struct ofpbuf *ofputil_encode_role_status(
enum ofperr ofputil_decode_role_status(const struct ofp_header *oh,
struct ofputil_role_status *rs);
-/* Abstract table stats.
- *
- * For now we use ofp12_table_stats as a superset of the other protocol
- * versions' table stats. */
+/* Abstract table stats. */
+struct ofputil_table_stats {
+ uint8_t table_id;
+ char name[OFP_MAX_TABLE_NAME_LEN];
+ ovs_be64 metadata_match; /* Bits of metadata table can match. */
+ ovs_be64 metadata_write; /* Bits of metadata table can write. */
+ uint32_t config; /* Bitmap of OFPTC_* values */
+ uint32_t max_entries; /* Max number of entries supported. */
+
+ struct mf_bitmap match; /* Fields table can match. */
+ struct mf_bitmap wildcards; /* Fields table can wildcard. */
+ uint64_t write_ofpacts; /* OFPACT_* supported on Write-Actions. */
+ 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 active_count; /* Number of active entries. */
+ uint64_t lookup_count; /* Number of packets looked up in table. */
+ uint64_t matched_count; /* Number of packets that hit table. */
+};
struct ofpbuf *ofputil_encode_table_stats_reply(
- const struct ofp12_table_stats[], int n,
+ const struct ofputil_table_stats[], int n,
const struct ofp_header *request);
/* Queue configuration request. */
@@ -1099,9 +1085,7 @@ struct ofputil_group_features {
uint32_t types; /* Bitmap of OFPGT_* values supported. */
uint32_t capabilities; /* Bitmap of OFPGFC12_* capability supported. */
uint32_t max_groups[4]; /* Maximum number of groups for each type. */
-
- /* Bitmaps of OFPAT_* that are supported. OF1.2+ actions only. */
- uint32_t actions[4];
+ uint64_t ofpacts[4]; /* Bitmaps of supported OFPACT_* */
};
/* Group desc reply, independent of protocol. */
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 48d0b82..92d5718 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -1500,37 +1500,26 @@ flush(struct ofproto *ofproto_)
static void
get_features(struct ofproto *ofproto_ OVS_UNUSED,
- bool *arp_match_ip, enum ofputil_action_bitmap *actions)
+ bool *arp_match_ip, uint64_t *ofpacts)
{
*arp_match_ip = true;
- *actions = (OFPUTIL_A_OUTPUT |
- OFPUTIL_A_SET_VLAN_VID |
- OFPUTIL_A_SET_VLAN_PCP |
- OFPUTIL_A_STRIP_VLAN |
- OFPUTIL_A_SET_DL_SRC |
- OFPUTIL_A_SET_DL_DST |
- OFPUTIL_A_SET_NW_SRC |
- OFPUTIL_A_SET_NW_DST |
- OFPUTIL_A_SET_NW_TOS |
- OFPUTIL_A_SET_TP_SRC |
- OFPUTIL_A_SET_TP_DST |
- OFPUTIL_A_ENQUEUE);
+ *ofpacts = (UINT64_C(1) << N_OFPACTS) - 1;
}
static void
-get_tables(struct ofproto *ofproto, struct ofp12_table_stats *ots)
+get_tables(struct ofproto *ofproto, struct ofputil_table_stats *stats)
{
int i;
- strcpy(ots->name, "classifier");
+ strcpy(stats->name, "classifier");
for (i = 0; i < ofproto->n_tables; i++) {
unsigned long missed, matched;
atomic_read(&ofproto->tables[i].n_matched, &matched);
- ots[i].matched_count = htonll(matched);
+ stats[i].matched_count = matched;
atomic_read(&ofproto->tables[i].n_missed, &missed);
- ots[i].lookup_count = htonll(matched + missed);
+ stats[i].lookup_count = matched + missed;
}
}
diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
index 7e6e99b..9c0c94e 100644
--- a/ofproto/ofproto-provider.h
+++ b/ofproto/ofproto-provider.h
@@ -774,30 +774,30 @@ struct ofproto_class {
* supports matching IP addresses inside ARP requests and replies, false
* otherwise.
*
- * The implementation should store in '*actions' a bitmap of the supported
- * OpenFlow actions. Vendor actions are not included in '*actions'. */
+ * The implementation should store in '*ofpacts' a bitmap of the supported
+ * OFPACT_* actions. */
void (*get_features)(struct ofproto *ofproto,
bool *arp_match_ip,
- enum ofputil_action_bitmap *actions);
+ uint64_t *ofpacts);
/* Helper for the OpenFlow OFPST_TABLE statistics request.
*
- * The 'ots' array contains 'ofproto->n_tables' elements. Each element is
+ * The 'stats' array contains 'ofproto->n_tables' elements. Each element is
* initialized as:
*
* - 'table_id' to the array index.
*
* - 'name' to "table#" where # is the table ID.
*
- * - 'match' and 'wildcards' to OFPXMT12_MASK.
+ * - 'match' and 'wildcards' to all fields.
*
- * - 'write_actions' and 'apply_actions' to OFPAT12_OUTPUT.
+ * - 'write_actions' and 'apply_actions' to all actions.
*
- * - 'write_setfields' and 'apply_setfields' to OFPXMT12_MASK.
+ * - 'write_setfields' and 'apply_setfields' to all writable fields.
*
* - 'metadata_match' and 'metadata_write' to OVS_BE64_MAX.
*
- * - 'instructions' to OFPIT11_ALL.
+ * - 'instructions' to all instructions.
*
* - 'config' to OFPTC11_TABLE_MISS_MASK.
*
@@ -838,11 +838,9 @@ struct ofproto_class {
*
* - 'matched_count' to the number of packets looked up in this flow
* table so far that matched one of the flow entries.
- *
- * All of the members of struct ofp12_table_stats are in network byte
- * order.
*/
- void (*get_tables)(struct ofproto *ofproto, struct ofp12_table_stats *ots);
+ void (*get_tables)(struct ofproto *ofproto,
+ struct ofputil_table_stats *stats);
/* ## ---------------- ## */
/* ## ofport Functions ## */
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index fca7d09..78b6773 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -524,28 +524,10 @@ ofproto_create(const char *datapath_name, const char *datapath_type,
ovs_mutex_unlock(&ofproto_mutex);
ofproto->ogf.capabilities = OFPGFC_CHAINING | OFPGFC_SELECT_LIVENESS |
OFPGFC_SELECT_WEIGHT;
- ofproto->ogf.max_groups[OFPGT11_ALL] = OFPG_MAX;
- ofproto->ogf.max_groups[OFPGT11_SELECT] = OFPG_MAX;
- ofproto->ogf.max_groups[OFPGT11_INDIRECT] = OFPG_MAX;
- ofproto->ogf.max_groups[OFPGT11_FF] = OFPG_MAX;
- ofproto->ogf.actions[0] =
- (1 << OFPAT11_OUTPUT) |
- (1 << OFPAT11_COPY_TTL_OUT) |
- (1 << OFPAT11_COPY_TTL_IN) |
- (1 << OFPAT11_SET_MPLS_TTL) |
- (1 << OFPAT11_DEC_MPLS_TTL) |
- (1 << OFPAT11_PUSH_VLAN) |
- (1 << OFPAT11_POP_VLAN) |
- (1 << OFPAT11_PUSH_MPLS) |
- (1 << OFPAT11_POP_MPLS) |
- (1 << OFPAT11_SET_QUEUE) |
- (1 << OFPAT11_GROUP) |
- (1 << OFPAT11_SET_NW_TTL) |
- (1 << OFPAT11_DEC_NW_TTL) |
- (1 << OFPAT12_SET_FIELD);
-/* not supported:
- * (1 << OFPAT13_PUSH_PBB) |
- * (1 << OFPAT13_POP_PBB) */
+ for (i = 0; i < 4; i++) {
+ ofproto->ogf.max_groups[i] = OFPG_MAX;
+ ofproto->ogf.ofpacts[i] = (UINT64_C(1) << N_OFPACTS) - 1;
+ }
error = ofproto->ofproto_class->construct(ofproto);
if (error) {
@@ -2805,8 +2787,8 @@ handle_features_request(struct ofconn *ofconn, const struct ofp_header *oh)
struct ofpbuf *b;
ofproto->ofproto_class->get_features(ofproto, &arp_match_ip,
- &features.actions);
- ovs_assert(features.actions & OFPUTIL_A_OUTPUT); /* sanity check */
+ &features.ofpacts);
+ ovs_assert(features.ofpacts & (UINT64_C(1) << OFPACT_OUTPUT));
features.datapath_id = ofproto->datapath_id;
features.n_buffers = pktbuf_capacity();
@@ -3081,37 +3063,44 @@ static enum ofperr
handle_table_stats_request(struct ofconn *ofconn,
const struct ofp_header *request)
{
+ struct mf_bitmap rw_fields = MF_BITMAP_INITIALIZER;
struct ofproto *p = ofconn_get_ofproto(ofconn);
- struct ofp12_table_stats *ots;
+ struct ofputil_table_stats *stats;
struct ofpbuf *msg;
int n_tables;
size_t i;
+ for (i = 0; i < MFF_N_IDS; i++) {
+ if (mf_from_id(i)->writable) {
+ bitmap_set1(rw_fields.bm, i);
+ }
+ }
+
/* Set up default values.
*
* ofp12_table_stats is used as a generic structure as
* it is able to hold all the fields for ofp10_table_stats
* and ofp11_table_stats (and of course itself).
*/
- ots = xcalloc(p->n_tables, sizeof *ots);
+ stats = xcalloc(p->n_tables, sizeof *stats);
for (i = 0; i < p->n_tables; i++) {
- ots[i].table_id = i;
- sprintf(ots[i].name, "table%"PRIuSIZE, i);
- ots[i].match = htonll(OFPXMT13_MASK);
- ots[i].wildcards = htonll(OFPXMT13_MASK);
- ots[i].write_actions = htonl(OFPAT11_OUTPUT);
- ots[i].apply_actions = htonl(OFPAT11_OUTPUT);
- ots[i].write_setfields = htonll(OFPXMT13_MASK);
- ots[i].apply_setfields = htonll(OFPXMT13_MASK);
- ots[i].metadata_match = OVS_BE64_MAX;
- ots[i].metadata_write = OVS_BE64_MAX;
- ots[i].instructions = htonl(OFPIT11_ALL);
- ots[i].config = htonl(OFPTC11_TABLE_MISS_MASK);
- ots[i].max_entries = htonl(1000000); /* An arbitrary big number. */
- ots[i].active_count = htonl(classifier_count(&p->tables[i].cls));
- }
-
- p->ofproto_class->get_tables(p, ots);
+ stats[i].table_id = i;
+ sprintf(stats[i].name, "table%"PRIuSIZE, i);
+ bitmap_set_multiple(stats[i].match.bm, 0, MFF_N_IDS, 1);
+ bitmap_set_multiple(stats[i].wildcards.bm, 0, MFF_N_IDS, 1);
+ stats[i].write_ofpacts = (UINT64_C(1) << N_OFPACTS) - 1;
+ stats[i].apply_ofpacts = (UINT64_C(1) << N_OFPACTS) - 1;
+ stats[i].write_setfields = rw_fields;
+ 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].config = OFPTC11_TABLE_MISS_MASK;
+ stats[i].max_entries = 1000000; /* An arbitrary big number. */
+ stats[i].active_count = classifier_count(&p->tables[i].cls);
+ }
+
+ p->ofproto_class->get_tables(p, stats);
/* Post-process the tables, dropping hidden tables. */
n_tables = p->n_tables;
@@ -3124,18 +3113,18 @@ handle_table_stats_request(struct ofconn *ofconn,
}
if (table->name) {
- ovs_strzcpy(ots[i].name, table->name, sizeof ots[i].name);
+ ovs_strzcpy(stats[i].name, table->name, sizeof stats[i].name);
}
- if (table->max_flows < ntohl(ots[i].max_entries)) {
- ots[i].max_entries = htonl(table->max_flows);
+ if (table->max_flows < stats[i].max_entries) {
+ stats[i].max_entries = table->max_flows;
}
}
- msg = ofputil_encode_table_stats_reply(ots, n_tables, request);
+ msg = ofputil_encode_table_stats_reply(stats, n_tables, request);
ofconn_send_reply(ofconn, msg);
- free(ots);
+ free(stats);
return 0;
}
diff --git a/tests/ofp-print.at b/tests/ofp-print.at
index 5871930..3e35baa 100644
--- a/tests/ofp-print.at
+++ b/tests/ofp-print.at
@@ -203,7 +203,7 @@ ff fe 50 54 00 00 00 01 62 72 30 00 00 00 00 00 \
OFPT_FEATURES_REPLY (xid=0x1): dpid:0000505400000001
n_tables:2, n_buffers:256
capabilities: FLOW_STATS TABLE_STATS PORT_STATS ARP_MATCH_IP
-actions: OUTPUT SET_VLAN_VID SET_VLAN_PCP STRIP_VLAN SET_DL_SRC SET_DL_DST SET_NW_SRC SET_NW_DST SET_NW_TOS SET_TP_SRC SET_TP_DST ENQUEUE
+actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
1(eth1): addr:50:54:00:00:00:02
config: 0
state: 0
@@ -1923,20 +1923,24 @@ AT_CHECK([ovs-ofctl ofp-print "\
03 13 00 38 00 00 00 02 00 08 00 00 00 00 00 00 \
00 00 00 0f 00 00 00 0f \
00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 04 \
-00 00 00 01 00 00 00 03 00 00 00 07 00 00 00 0f \
+00 00 00 01 00 02 00 01 00 06 00 01 00 0e 00 01 \
"], [0], [dnl
OFPST_GROUP_FEATURES reply (OF1.2) (xid=0x2):
Group table:
Types: 0xf
Capabilities: 0xf
- All group :
- max_groups = 0x1 actions=0x00000001
- Select group :
- max_groups = 0x2 actions=0x00000003
- Indirect group :
- max_groups = 0x3 actions=0x00000007
- Fast Failover group :
- max_groups = 0x4 actions=0x0000000f
+ all group:
+ max_groups=0x1
+ actions: output
+ select group:
+ max_groups=0x2
+ actions: output push_vlan
+ indirect group:
+ max_groups=0x3
+ actions: output strip_vlan push_vlan
+ fast failover group:
+ max_groups=0x4
+ actions: output strip_vlan push_vlan push_mpls
])
AT_CLEANUP
@@ -2275,7 +2279,7 @@ f5 f6 f7 f8 f9 fa fb fc fd 00 00 00 00 00 00 00 \
next tables: 1-253
instructions: apply_actions,clear_actions,write_actions,write_metadata,goto_table
Write-Actions and Apply-Actions features:
- actions: output,copy_ttl_out,copy_ttl_in,set_mpls_ttl,dec_mpls_ttl,push_vlan,pop_vlan,push_mpls,pop_mpls,set_queue,group,set_nw_ttl,dec_nw_ttl,set_field,push_pbb,pop_pbb
+ actions: output group set_field strip_vlan push_vlan mod_nw_ttl dec_ttl set_mpls_ttl dec_mpls_ttl push_mpls pop_mpls set_queue
supported on Set-Field: tun_id,tun_src,tun_dst,metadata,in_port,in_port_oxm,pkt_mark,reg0,reg1,reg2,reg3,reg4,reg5,reg6,reg7,eth_src,eth_dst,vlan_tci,vlan_vid,vlan_pcp,mpls_label,mpls_tc,ip_src,ip_dst,ipv6_src,ipv6_dst,nw_tos,ip_dscp,nw_ecn,nw_ttl,arp_op,arp_spa,arp_tpa,arp_sha,arp_tha,tcp_src,tcp_dst,udp_src,udp_dst,sctp_src,sctp_dst
matching:
tun_id: exact match or wildcard
diff --git a/tests/ofproto.at b/tests/ofproto.at
index 3a55ce3..06a7df4 100644
--- a/tests/ofproto.at
+++ b/tests/ofproto.at
@@ -36,7 +36,7 @@ AT_CHECK([STRIP_XIDS stdout], [0], [dnl
OFPT_FEATURES_REPLY: dpid:fedcba9876543210
n_tables:254, n_buffers:256
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
-actions: OUTPUT SET_VLAN_VID SET_VLAN_PCP STRIP_VLAN SET_DL_SRC SET_DL_DST SET_NW_SRC SET_NW_DST SET_NW_TOS SET_TP_SRC SET_TP_DST ENQUEUE
+actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
LOCAL(br0): addr:aa:55:aa:55:00:00
config: PORT_DOWN
state: LINK_DOWN
@@ -58,7 +58,7 @@ s/00:0.$/00:0x/' < stdout]],
OFPT_FEATURES_REPLY: dpid:fedcba9876543210
n_tables:254, n_buffers:256
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
-actions: OUTPUT SET_VLAN_VID SET_VLAN_PCP STRIP_VLAN SET_DL_SRC SET_DL_DST SET_NW_SRC SET_NW_DST SET_NW_TOS SET_TP_SRC SET_TP_DST ENQUEUE
+actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
1(p1): addr:aa:55:aa:55:00:0x
config: PORT_DOWN
state: LINK_DOWN
@@ -451,7 +451,7 @@ do
OFPT_FEATURES_REPLY: dpid:fedcba9876543210
n_tables:254, n_buffers:256
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
-actions: OUTPUT SET_VLAN_VID SET_VLAN_PCP STRIP_VLAN SET_DL_SRC SET_DL_DST SET_NW_SRC SET_NW_DST SET_NW_TOS SET_TP_SRC SET_TP_DST ENQUEUE
+actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
LOCAL(br0): addr:aa:55:aa:55:00:00
config: $config
state: $state
@@ -1064,13 +1064,13 @@ AT_CLEANUP
AT_SETUP([ofproto - flow table configuration (OpenFlow 1.2)])
OVS_VSWITCHD_START
# Check the default configuration.
-(mid="wild=0xfffffffff, max=1000000,"
+(mid="wild=0x1ffffffffd, max=1000000,"
tail="
lookup=0, matched=0
- match=0xfffffffff, instructions=0x00000007, config=0x00000003
- write_actions=0x00000000, apply_actions=0x00000000
- write_setfields=0x0000000fffffffff
- apply_setfields=0x0000000fffffffff
+ match=0x1ffffffffd, instructions=0x00000007, config=0x00000003
+ write_actions=0x03ff8001, apply_actions=0x03ff8001
+ write_setfields=0x0000000c0fe7fbdd
+ apply_setfields=0x0000000c0fe7fbdd
metadata_match=0xffffffffffffffff
metadata_write=0xffffffffffffffff"
echo "OFPST_TABLE reply (OF1.2) (xid=0x2): 254 tables
@@ -1095,9 +1095,9 @@ AT_CHECK(
# Check that the configuration was updated.
mv expout orig-expout
(echo "OFPST_TABLE reply (OF1.2) (xid=0x2): 254 tables
- 0: main : wild=0xfffffffff, max=1000000, active=0"
+ 0: main : wild=0x1ffffffffd, max=1000000, active=0"
tail -n +3 orig-expout | head -7
- echo " 1: table1 : wild=0xfffffffff, max= 1024, active=0"
+ echo " 1: table1 : wild=0x1ffffffffd, max= 1024, active=0"
tail -n +11 orig-expout) > expout
AT_CHECK([ovs-ofctl -O OpenFlow12 dump-tables br0], [0], [expout])
OVS_VSWITCHD_STOP
--
1.7.10.4
More information about the dev
mailing list