mirror of
https://github.com/openvswitch/ovs
synced 2025-09-02 15:25:22 +00:00
ofp-actions: Add action bitmap abstraction.
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@nicira.com> Acked-by: Jarno Rajahalme <jrajahalme@nicira.com>
This commit is contained in:
@@ -306,12 +306,20 @@ struct ofp12_table_stats {
|
|||||||
};
|
};
|
||||||
OFP_ASSERT(sizeof(struct ofp12_table_stats) == 128);
|
OFP_ASSERT(sizeof(struct ofp12_table_stats) == 128);
|
||||||
|
|
||||||
|
/* Number of types of groups supported by ofp12_group_features_stats. */
|
||||||
|
#define OFPGT12_N_TYPES 4
|
||||||
|
|
||||||
/* Body of reply to OFPST12_GROUP_FEATURES request. Group features. */
|
/* Body of reply to OFPST12_GROUP_FEATURES request. Group features. */
|
||||||
struct ofp12_group_features_stats {
|
struct ofp12_group_features_stats {
|
||||||
ovs_be32 types; /* Bitmap of OFPGT11_* values supported. */
|
ovs_be32 types; /* Bitmap of OFPGT11_* values supported. */
|
||||||
ovs_be32 capabilities; /* Bitmap of OFPGFC12_* capability supported. */
|
ovs_be32 capabilities; /* Bitmap of OFPGFC12_* capability supported. */
|
||||||
ovs_be32 max_groups[4]; /* Maximum number of groups for each type. */
|
|
||||||
ovs_be32 actions[4]; /* Bitmaps of OFPAT_* that are supported. */
|
/* Each element in the following arrays corresponds to the group type with
|
||||||
|
* the same number, e.g. max_groups[0] is the maximum number of OFPGT11_ALL
|
||||||
|
* groups, actions[2] is the actions supported by OFPGT11_INDIRECT
|
||||||
|
* groups. */
|
||||||
|
ovs_be32 max_groups[OFPGT12_N_TYPES]; /* Max number of groups. */
|
||||||
|
ovs_be32 actions[OFPGT12_N_TYPES]; /* Bitmaps of supported OFPAT_*. */
|
||||||
};
|
};
|
||||||
OFP_ASSERT(sizeof(struct ofp12_group_features_stats) == 40);
|
OFP_ASSERT(sizeof(struct ofp12_group_features_stats) == 40);
|
||||||
|
|
||||||
|
@@ -3091,6 +3091,155 @@ ofpacts_put_openflow_instructions(const struct ofpact ofpacts[],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sets of supported actions. */
|
||||||
|
|
||||||
|
/* Two-way translation between OVS's internal "OFPACT_*" representation of
|
||||||
|
* actions and the "OFPAT_*" representation used in some OpenFlow version.
|
||||||
|
* (OFPAT_* numbering varies from one OpenFlow version to another, so a given
|
||||||
|
* instance is specific to one OpenFlow version.) */
|
||||||
|
struct ofpact_map {
|
||||||
|
enum ofpact_type ofpact; /* Internal name for action type. */
|
||||||
|
int ofpat; /* OFPAT_* number from OpenFlow spec. */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct ofpact_map *
|
||||||
|
get_ofpact_map(enum ofp_version version)
|
||||||
|
{
|
||||||
|
/* OpenFlow 1.0 actions. */
|
||||||
|
static const struct ofpact_map 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_map 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_map 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_map *x;
|
||||||
|
|
||||||
|
for (x = get_ofpact_map(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_map *x;
|
||||||
|
|
||||||
|
for (x = get_ofpact_map(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. */
|
/* Returns true if 'action' outputs to 'port', false otherwise. */
|
||||||
static bool
|
static bool
|
||||||
ofpact_outputs_to_port(const struct ofpact *ofpact, ofp_port_t port)
|
ofpact_outputs_to_port(const struct ofpact *ofpact, ofp_port_t port)
|
||||||
@@ -3648,3 +3797,14 @@ ofpact_pad(struct ofpbuf *ofpacts)
|
|||||||
ofpbuf_put_zeros(ofpacts, pad);
|
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>";
|
||||||
|
}
|
||||||
|
@@ -31,7 +31,7 @@
|
|||||||
* This macro is used directly only internally by this header, but the list is
|
* This macro is used directly only internally by this header, but the list is
|
||||||
* still of interest to developers.
|
* 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
|
* 1. <ENUM>, used below in the enum definition of OFPACT_<ENUM>, and
|
||||||
* elsewhere.
|
* elsewhere.
|
||||||
@@ -48,81 +48,83 @@
|
|||||||
*
|
*
|
||||||
* - If "struct <STRUCT>" is variable-length, it must be the name of the
|
* - If "struct <STRUCT>" is variable-length, it must be the name of the
|
||||||
* flexible array member.
|
* flexible array member.
|
||||||
|
*
|
||||||
|
* 4. <NAME>, a quoted string that gives the name of the action, for use in
|
||||||
|
* parsing actions from text.
|
||||||
*/
|
*/
|
||||||
#define OFPACTS \
|
#define OFPACTS \
|
||||||
/* Output. */ \
|
/* Output. */ \
|
||||||
DEFINE_OFPACT(OUTPUT, ofpact_output, ofpact) \
|
OFPACT(OUTPUT, ofpact_output, ofpact, "output") \
|
||||||
DEFINE_OFPACT(GROUP, ofpact_group, ofpact) \
|
OFPACT(GROUP, ofpact_group, ofpact, "group") \
|
||||||
DEFINE_OFPACT(CONTROLLER, ofpact_controller, ofpact) \
|
OFPACT(CONTROLLER, ofpact_controller, ofpact, "controller") \
|
||||||
DEFINE_OFPACT(ENQUEUE, ofpact_enqueue, ofpact) \
|
OFPACT(ENQUEUE, ofpact_enqueue, ofpact, "enqueue") \
|
||||||
DEFINE_OFPACT(OUTPUT_REG, ofpact_output_reg, ofpact) \
|
OFPACT(OUTPUT_REG, ofpact_output_reg, ofpact, "output_reg") \
|
||||||
DEFINE_OFPACT(BUNDLE, ofpact_bundle, slaves) \
|
OFPACT(BUNDLE, ofpact_bundle, slaves, "bundle") \
|
||||||
\
|
\
|
||||||
/* Header changes. */ \
|
/* Header changes. */ \
|
||||||
DEFINE_OFPACT(SET_FIELD, ofpact_set_field, ofpact) \
|
OFPACT(SET_FIELD, ofpact_set_field, ofpact, "set_field") \
|
||||||
DEFINE_OFPACT(SET_VLAN_VID, ofpact_vlan_vid, ofpact) \
|
OFPACT(SET_VLAN_VID, ofpact_vlan_vid, ofpact, "set_vlan_vid") \
|
||||||
DEFINE_OFPACT(SET_VLAN_PCP, ofpact_vlan_pcp, ofpact) \
|
OFPACT(SET_VLAN_PCP, ofpact_vlan_pcp, ofpact, "set_vlan_pcp") \
|
||||||
DEFINE_OFPACT(STRIP_VLAN, ofpact_null, ofpact) \
|
OFPACT(STRIP_VLAN, ofpact_null, ofpact, "strip_vlan") \
|
||||||
DEFINE_OFPACT(PUSH_VLAN, ofpact_null, ofpact) \
|
OFPACT(PUSH_VLAN, ofpact_null, ofpact, "push_vlan") \
|
||||||
DEFINE_OFPACT(SET_ETH_SRC, ofpact_mac, ofpact) \
|
OFPACT(SET_ETH_SRC, ofpact_mac, ofpact, "mod_dl_src") \
|
||||||
DEFINE_OFPACT(SET_ETH_DST, ofpact_mac, ofpact) \
|
OFPACT(SET_ETH_DST, ofpact_mac, ofpact, "mod_dl_dst") \
|
||||||
DEFINE_OFPACT(SET_IPV4_SRC, ofpact_ipv4, ofpact) \
|
OFPACT(SET_IPV4_SRC, ofpact_ipv4, ofpact, "mod_nw_src") \
|
||||||
DEFINE_OFPACT(SET_IPV4_DST, ofpact_ipv4, ofpact) \
|
OFPACT(SET_IPV4_DST, ofpact_ipv4, ofpact, "mod_nw_dst") \
|
||||||
DEFINE_OFPACT(SET_IP_DSCP, ofpact_dscp, ofpact) \
|
OFPACT(SET_IP_DSCP, ofpact_dscp, ofpact, "mod_nw_tos") \
|
||||||
DEFINE_OFPACT(SET_IP_ECN, ofpact_ecn, ofpact) \
|
OFPACT(SET_IP_ECN, ofpact_ecn, ofpact, "mod_nw_ecn") \
|
||||||
DEFINE_OFPACT(SET_IP_TTL, ofpact_ip_ttl, ofpact) \
|
OFPACT(SET_IP_TTL, ofpact_ip_ttl, ofpact, "mod_nw_ttl") \
|
||||||
DEFINE_OFPACT(SET_L4_SRC_PORT, ofpact_l4_port, ofpact) \
|
OFPACT(SET_L4_SRC_PORT, ofpact_l4_port, ofpact, "mod_tp_src") \
|
||||||
DEFINE_OFPACT(SET_L4_DST_PORT, ofpact_l4_port, ofpact) \
|
OFPACT(SET_L4_DST_PORT, ofpact_l4_port, ofpact, "mod_tp_dst") \
|
||||||
DEFINE_OFPACT(REG_MOVE, ofpact_reg_move, ofpact) \
|
OFPACT(REG_MOVE, ofpact_reg_move, ofpact, "move") \
|
||||||
DEFINE_OFPACT(REG_LOAD, ofpact_reg_load, ofpact) \
|
OFPACT(REG_LOAD, ofpact_reg_load, ofpact, "load") \
|
||||||
DEFINE_OFPACT(STACK_PUSH, ofpact_stack, ofpact) \
|
OFPACT(STACK_PUSH, ofpact_stack, ofpact, "push") \
|
||||||
DEFINE_OFPACT(STACK_POP, ofpact_stack, ofpact) \
|
OFPACT(STACK_POP, ofpact_stack, ofpact, "pop") \
|
||||||
DEFINE_OFPACT(DEC_TTL, ofpact_cnt_ids, cnt_ids) \
|
OFPACT(DEC_TTL, ofpact_cnt_ids, cnt_ids, "dec_ttl") \
|
||||||
DEFINE_OFPACT(SET_MPLS_LABEL, ofpact_mpls_label, ofpact) \
|
OFPACT(SET_MPLS_LABEL, ofpact_mpls_label, ofpact, "set_mpls_label") \
|
||||||
DEFINE_OFPACT(SET_MPLS_TC, ofpact_mpls_tc, ofpact) \
|
OFPACT(SET_MPLS_TC, ofpact_mpls_tc, ofpact, "set_mpls_tc") \
|
||||||
DEFINE_OFPACT(SET_MPLS_TTL, ofpact_mpls_ttl, ofpact) \
|
OFPACT(SET_MPLS_TTL, ofpact_mpls_ttl, ofpact, "set_mpls_ttl") \
|
||||||
DEFINE_OFPACT(DEC_MPLS_TTL, ofpact_null, ofpact) \
|
OFPACT(DEC_MPLS_TTL, ofpact_null, ofpact, "dec_mpls_ttl") \
|
||||||
DEFINE_OFPACT(PUSH_MPLS, ofpact_push_mpls, ofpact) \
|
OFPACT(PUSH_MPLS, ofpact_push_mpls, ofpact, "push_mpls") \
|
||||||
DEFINE_OFPACT(POP_MPLS, ofpact_pop_mpls, ofpact) \
|
OFPACT(POP_MPLS, ofpact_pop_mpls, ofpact, "pop_mpls") \
|
||||||
\
|
\
|
||||||
/* Metadata. */ \
|
/* Metadata. */ \
|
||||||
DEFINE_OFPACT(SET_TUNNEL, ofpact_tunnel, ofpact) \
|
OFPACT(SET_TUNNEL, ofpact_tunnel, ofpact, "set_tunnel") \
|
||||||
DEFINE_OFPACT(SET_QUEUE, ofpact_queue, ofpact) \
|
OFPACT(SET_QUEUE, ofpact_queue, ofpact, "set_queue") \
|
||||||
DEFINE_OFPACT(POP_QUEUE, ofpact_null, ofpact) \
|
OFPACT(POP_QUEUE, ofpact_null, ofpact, "pop_queue") \
|
||||||
DEFINE_OFPACT(FIN_TIMEOUT, ofpact_fin_timeout, ofpact) \
|
OFPACT(FIN_TIMEOUT, ofpact_fin_timeout, ofpact, "fin_timeout") \
|
||||||
\
|
\
|
||||||
/* Flow table interaction. */ \
|
/* Flow table interaction. */ \
|
||||||
DEFINE_OFPACT(RESUBMIT, ofpact_resubmit, ofpact) \
|
OFPACT(RESUBMIT, ofpact_resubmit, ofpact, "resubmit") \
|
||||||
DEFINE_OFPACT(LEARN, ofpact_learn, specs) \
|
OFPACT(LEARN, ofpact_learn, specs, "learn") \
|
||||||
\
|
\
|
||||||
/* Arithmetic. */ \
|
/* Arithmetic. */ \
|
||||||
DEFINE_OFPACT(MULTIPATH, ofpact_multipath, ofpact) \
|
OFPACT(MULTIPATH, ofpact_multipath, ofpact, "multipath") \
|
||||||
\
|
\
|
||||||
/* Other. */ \
|
/* Other. */ \
|
||||||
DEFINE_OFPACT(NOTE, ofpact_note, data) \
|
OFPACT(NOTE, ofpact_note, data, "note") \
|
||||||
DEFINE_OFPACT(EXIT, ofpact_null, ofpact) \
|
OFPACT(EXIT, ofpact_null, ofpact, "exit") \
|
||||||
DEFINE_OFPACT(SAMPLE, ofpact_sample, ofpact) \
|
OFPACT(SAMPLE, ofpact_sample, ofpact, "sample") \
|
||||||
\
|
\
|
||||||
/* Instructions */ \
|
/* Instructions. */ \
|
||||||
DEFINE_OFPACT(METER, ofpact_meter, ofpact) \
|
OFPACT(METER, ofpact_meter, ofpact, "meter") \
|
||||||
DEFINE_OFPACT(CLEAR_ACTIONS, ofpact_null, ofpact) \
|
OFPACT(CLEAR_ACTIONS, ofpact_null, ofpact, "clear_actions") \
|
||||||
DEFINE_OFPACT(WRITE_ACTIONS, ofpact_nest, ofpact) \
|
OFPACT(WRITE_ACTIONS, ofpact_nest, ofpact, "write_actions") \
|
||||||
DEFINE_OFPACT(WRITE_METADATA, ofpact_metadata, ofpact) \
|
OFPACT(WRITE_METADATA, ofpact_metadata, ofpact, "write_metadata") \
|
||||||
DEFINE_OFPACT(GOTO_TABLE, ofpact_goto_table, ofpact)
|
OFPACT(GOTO_TABLE, ofpact_goto_table, ofpact, "goto_table")
|
||||||
|
|
||||||
/* enum ofpact_type, with a member OFPACT_<ENUM> for each action. */
|
/* enum ofpact_type, with a member OFPACT_<ENUM> for each action. */
|
||||||
enum OVS_PACKED_ENUM ofpact_type {
|
enum OVS_PACKED_ENUM ofpact_type {
|
||||||
#define DEFINE_OFPACT(ENUM, STRUCT, MEMBER) OFPACT_##ENUM,
|
#define OFPACT(ENUM, STRUCT, MEMBER, NAME) OFPACT_##ENUM,
|
||||||
OFPACTS
|
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 {
|
enum {
|
||||||
N_OFPACTS =
|
#define OFPACT(ENUM, STRUCT, MEMBER, NAME) + 1
|
||||||
#define DEFINE_OFPACT(ENUM, STRUCT, MEMBER) + 1
|
N_OFPACTS = OFPACTS
|
||||||
OFPACTS
|
#undef OFPACT
|
||||||
#undef DEFINE_OFPACT
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Header for an action.
|
/* Header for an action.
|
||||||
@@ -611,6 +613,11 @@ void ofpacts_put_openflow_instructions(const struct ofpact[],
|
|||||||
struct ofpbuf *openflow,
|
struct ofpbuf *openflow,
|
||||||
enum ofp_version ofp_version);
|
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. */
|
/* Working with ofpacts. */
|
||||||
bool ofpacts_output_to_port(const struct ofpact[], size_t ofpacts_len,
|
bool ofpacts_output_to_port(const struct ofpact[], size_t ofpacts_len,
|
||||||
ofp_port_t port);
|
ofp_port_t port);
|
||||||
@@ -624,6 +631,7 @@ uint32_t ofpacts_get_meter(const struct ofpact[], size_t ofpacts_len);
|
|||||||
*
|
*
|
||||||
* (For parsing ofpacts, see ofp-parse.h.) */
|
* (For parsing ofpacts, see ofp-parse.h.) */
|
||||||
void ofpacts_format(const struct ofpact[], size_t ofpacts_len, struct ds *);
|
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. */
|
/* Internal use by the helpers below. */
|
||||||
void ofpact_init(struct ofpact *, enum ofpact_type, size_t len);
|
void ofpact_init(struct ofpact *, enum ofpact_type, size_t len);
|
||||||
@@ -667,7 +675,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
|
* An integer constant, the value of OFPACT_<ENUM>_RAW_SIZE rounded up to a
|
||||||
* multiple of OFPACT_ALIGNTO.
|
* multiple of OFPACT_ALIGNTO.
|
||||||
*/
|
*/
|
||||||
#define DEFINE_OFPACT(ENUM, STRUCT, MEMBER) \
|
#define OFPACT(ENUM, STRUCT, MEMBER, NAME) \
|
||||||
BUILD_ASSERT_DECL(offsetof(struct STRUCT, ofpact) == 0); \
|
BUILD_ASSERT_DECL(offsetof(struct STRUCT, ofpact) == 0); \
|
||||||
\
|
\
|
||||||
enum { OFPACT_##ENUM##_RAW_SIZE \
|
enum { OFPACT_##ENUM##_RAW_SIZE \
|
||||||
@@ -699,7 +707,7 @@ void *ofpact_put(struct ofpbuf *, enum ofpact_type, size_t len);
|
|||||||
OFPACT_##ENUM##_RAW_SIZE); \
|
OFPACT_##ENUM##_RAW_SIZE); \
|
||||||
}
|
}
|
||||||
OFPACTS
|
OFPACTS
|
||||||
#undef DEFINE_OFPACT
|
#undef OFPACT
|
||||||
|
|
||||||
/* Functions to use after adding ofpacts to a buffer. */
|
/* Functions to use after adding ofpacts to a buffer. */
|
||||||
void ofpact_update_len(struct ofpbuf *, struct ofpact *);
|
void ofpact_update_len(struct ofpbuf *, struct ofpact *);
|
||||||
|
105
lib/ofp-print.c
105
lib/ofp-print.c
@@ -467,45 +467,6 @@ ofputil_capabilities_to_name(uint32_t bit)
|
|||||||
return NULL;
|
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
|
static void
|
||||||
ofp_print_switch_features(struct ds *string, const struct ofp_header *oh)
|
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) {
|
switch ((enum ofp_version)oh->version) {
|
||||||
case OFP10_VERSION:
|
case OFP10_VERSION:
|
||||||
ds_put_cstr(string, "actions: ");
|
ds_put_cstr(string, "actions: ");
|
||||||
ofp_print_bit_names(string, features.actions,
|
ofpact_bitmap_format(features.ofpacts, string);
|
||||||
ofputil_action_bitmap_to_name, ' ');
|
|
||||||
ds_put_char(string, '\n');
|
ds_put_char(string, '\n');
|
||||||
break;
|
break;
|
||||||
case OFP11_VERSION:
|
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
|
static void
|
||||||
ofp_print_group_features(struct ds *string, const struct ofp_header *oh)
|
ofp_print_group_features(struct ds *string, const struct ofp_header *oh)
|
||||||
{
|
{
|
||||||
struct ofputil_group_features features;
|
struct ofputil_group_features features;
|
||||||
|
int i;
|
||||||
|
|
||||||
ofputil_decode_group_features_reply(oh, &features);
|
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",
|
ds_put_format(string, " Capabilities: 0x%"PRIx32"\n",
|
||||||
features.capabilities);
|
features.capabilities);
|
||||||
|
|
||||||
if (features.types & (1u << OFPGT11_ALL)) {
|
for (i = 0; i < OFPGT12_N_TYPES; i++) {
|
||||||
ds_put_format(string, " All group :\n");
|
if (features.types & (1u << i)) {
|
||||||
ds_put_format(string,
|
ds_put_format(string, " %s group:\n", group_type_to_string(i));
|
||||||
" max_groups = %#"PRIx32" actions=0x%08"PRIx32"\n",
|
ds_put_format(string, " max_groups=%#"PRIx32"\n",
|
||||||
features.max_groups[0], features.actions[0]);
|
features.max_groups[i]);
|
||||||
}
|
ds_put_format(string, " actions: ");
|
||||||
|
ofpact_bitmap_format(features.ofpacts[i], string);
|
||||||
if (features.types & (1u << OFPGT11_SELECT)) {
|
ds_put_char(string, '\n');
|
||||||
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]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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);
|
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
|
static void
|
||||||
print_table_action_features(struct ds *s,
|
print_table_action_features(struct ds *s,
|
||||||
const struct ofputil_table_action_features *taf)
|
const struct ofputil_table_action_features *taf)
|
||||||
{
|
{
|
||||||
ds_put_cstr(s, " actions: ");
|
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_char(s, '\n');
|
||||||
|
|
||||||
ds_put_cstr(s, " supported on Set-Field: ");
|
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,
|
table_action_features_equal(const struct ofputil_table_action_features *a,
|
||||||
const struct ofputil_table_action_features *b)
|
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));
|
&& bitmap_equal(a->set_fields.bm, b->set_fields.bm, MFF_N_IDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
280
lib/ofp-util.c
280
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_QUEUE_STATS == OFPC_QUEUE_STATS);
|
||||||
BUILD_ASSERT_DECL((int) OFPUTIL_C_ARP_MATCH_IP == OFPC_ARP_MATCH_IP);
|
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
|
static uint32_t
|
||||||
ofputil_capabilities_mask(enum ofp_version ofp_version)
|
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)) {
|
if (osf->capabilities & htonl(OFPC10_STP)) {
|
||||||
features->capabilities |= OFPUTIL_C_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
|
} else if (raw == OFPRAW_OFPT11_FEATURES_REPLY
|
||||||
|| raw == OFPRAW_OFPT13_FEATURES_REPLY) {
|
|| raw == OFPRAW_OFPT13_FEATURES_REPLY) {
|
||||||
if (osf->capabilities & htonl(OFPC11_GROUP_STATS)) {
|
if (osf->capabilities & htonl(OFPC11_GROUP_STATS)) {
|
||||||
features->capabilities |= OFPUTIL_C_GROUP_STATS;
|
features->capabilities |= OFPUTIL_C_GROUP_STATS;
|
||||||
}
|
}
|
||||||
features->actions = 0;
|
features->ofpacts = 0;
|
||||||
if (raw == OFPRAW_OFPT13_FEATURES_REPLY) {
|
if (raw == OFPRAW_OFPT13_FEATURES_REPLY) {
|
||||||
features->auxiliary_id = osf->auxiliary_id;
|
features->auxiliary_id = osf->auxiliary_id;
|
||||||
}
|
}
|
||||||
@@ -4153,21 +4118,6 @@ ofputil_switch_features_has_ports(struct ofpbuf *b)
|
|||||||
return false;
|
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
|
/* 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
|
* required by 'protocol' with the given 'xid'. The caller should append port
|
||||||
* information to the buffer with subsequent calls to
|
* 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) {
|
if (features->capabilities & OFPUTIL_C_STP) {
|
||||||
osf->capabilities |= htonl(OFPC10_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;
|
break;
|
||||||
case OFP13_VERSION:
|
case OFP13_VERSION:
|
||||||
case OFP14_VERSION:
|
case OFP14_VERSION:
|
||||||
@@ -4504,20 +4455,25 @@ pull_table_feature_property(struct ofpbuf *msg, struct ofpbuf *payload,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static enum ofperr
|
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) {
|
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) {
|
if (error) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
if (type < CHAR_BIT * sizeof *ids) {
|
if (type < CHAR_BIT * sizeof types) {
|
||||||
*ids |= 1u << type;
|
types |= 1u << type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*ofpacts = ofpact_bitmap_from_openflow(htonl(types), ofp_version);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4646,12 +4602,14 @@ int
|
|||||||
ofputil_decode_table_features(struct ofpbuf *msg,
|
ofputil_decode_table_features(struct ofpbuf *msg,
|
||||||
struct ofputil_table_features *tf, bool loose)
|
struct ofputil_table_features *tf, bool loose)
|
||||||
{
|
{
|
||||||
|
const struct ofp_header *oh;
|
||||||
struct ofp13_table_features *otf;
|
struct ofp13_table_features *otf;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
|
||||||
if (!msg->frame) {
|
if (!msg->frame) {
|
||||||
ofpraw_pull_assert(msg);
|
ofpraw_pull_assert(msg);
|
||||||
}
|
}
|
||||||
|
oh = ofpbuf_l2(msg);
|
||||||
|
|
||||||
if (!ofpbuf_size(msg)) {
|
if (!ofpbuf_size(msg)) {
|
||||||
return EOF;
|
return EOF;
|
||||||
@@ -4708,17 +4666,21 @@ ofputil_decode_table_features(struct ofpbuf *msg,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OFPTFPT13_WRITE_ACTIONS:
|
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;
|
break;
|
||||||
case OFPTFPT13_WRITE_ACTIONS_MISS:
|
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;
|
break;
|
||||||
|
|
||||||
case OFPTFPT13_APPLY_ACTIONS:
|
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;
|
break;
|
||||||
case OFPTFPT13_APPLY_ACTIONS_MISS:
|
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;
|
break;
|
||||||
|
|
||||||
case OFPTFPT13_MATCH:
|
case OFPTFPT13_MATCH:
|
||||||
@@ -5030,27 +4992,27 @@ ofputil_decode_role_status(const struct ofp_header *oh,
|
|||||||
/* Table stats. */
|
/* Table stats. */
|
||||||
|
|
||||||
static void
|
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 ofpbuf *buf)
|
||||||
{
|
{
|
||||||
struct wc_map {
|
struct wc_map {
|
||||||
enum ofp10_flow_wildcards wc10;
|
enum ofp10_flow_wildcards wc10;
|
||||||
enum oxm12_ofb_match_fields mf12;
|
enum mf_field_id mf;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct wc_map wc_map[] = {
|
static const struct wc_map wc_map[] = {
|
||||||
{ OFPFW10_IN_PORT, OFPXMT12_OFB_IN_PORT },
|
{ OFPFW10_IN_PORT, MFF_IN_PORT },
|
||||||
{ OFPFW10_DL_VLAN, OFPXMT12_OFB_VLAN_VID },
|
{ OFPFW10_DL_VLAN, MFF_VLAN_VID },
|
||||||
{ OFPFW10_DL_SRC, OFPXMT12_OFB_ETH_SRC },
|
{ OFPFW10_DL_SRC, MFF_ETH_SRC },
|
||||||
{ OFPFW10_DL_DST, OFPXMT12_OFB_ETH_DST},
|
{ OFPFW10_DL_DST, MFF_ETH_DST},
|
||||||
{ OFPFW10_DL_TYPE, OFPXMT12_OFB_ETH_TYPE },
|
{ OFPFW10_DL_TYPE, MFF_ETH_TYPE },
|
||||||
{ OFPFW10_NW_PROTO, OFPXMT12_OFB_IP_PROTO },
|
{ OFPFW10_NW_PROTO, MFF_IP_PROTO },
|
||||||
{ OFPFW10_TP_SRC, OFPXMT12_OFB_TCP_SRC },
|
{ OFPFW10_TP_SRC, MFF_TCP_SRC },
|
||||||
{ OFPFW10_TP_DST, OFPXMT12_OFB_TCP_DST },
|
{ OFPFW10_TP_DST, MFF_TCP_DST },
|
||||||
{ OFPFW10_NW_SRC_MASK, OFPXMT12_OFB_IPV4_SRC },
|
{ OFPFW10_NW_SRC_MASK, MFF_IPV4_SRC },
|
||||||
{ OFPFW10_NW_DST_MASK, OFPXMT12_OFB_IPV4_DST },
|
{ OFPFW10_NW_DST_MASK, MFF_IPV4_DST },
|
||||||
{ OFPFW10_DL_VLAN_PCP, OFPXMT12_OFB_VLAN_PCP },
|
{ OFPFW10_DL_VLAN_PCP, MFF_VLAN_PCP },
|
||||||
{ OFPFW10_NW_TOS, OFPXMT12_OFB_IP_DSCP },
|
{ OFPFW10_NW_TOS, MFF_IP_DSCP },
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ofp10_table_stats *out;
|
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);
|
ovs_strlcpy(out->name, in->name, sizeof out->name);
|
||||||
out->wildcards = 0;
|
out->wildcards = 0;
|
||||||
for (p = wc_map; p < &wc_map[ARRAY_SIZE(wc_map)]; p++) {
|
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->wildcards |= htonl(p->wc10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out->max_entries = in->max_entries;
|
out->max_entries = htonl(in->max_entries);
|
||||||
out->active_count = in->active_count;
|
out->active_count = htonl(in->active_count);
|
||||||
put_32aligned_be64(&out->lookup_count, in->lookup_count);
|
put_32aligned_be64(&out->lookup_count, htonll(in->lookup_count));
|
||||||
put_32aligned_be64(&out->matched_count, in->matched_count);
|
put_32aligned_be64(&out->matched_count, htonll(in->matched_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ovs_be32
|
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 {
|
struct map {
|
||||||
enum ofp11_flow_match_fields fmf11;
|
enum ofp11_flow_match_fields fmf11;
|
||||||
enum oxm12_ofb_match_fields mf12;
|
enum mf_field_id mf;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct map map[] = {
|
static const struct map map[] = {
|
||||||
{ OFPFMF11_IN_PORT, OFPXMT12_OFB_IN_PORT },
|
{ OFPFMF11_IN_PORT, MFF_IN_PORT },
|
||||||
{ OFPFMF11_DL_VLAN, OFPXMT12_OFB_VLAN_VID },
|
{ OFPFMF11_DL_VLAN, MFF_VLAN_VID },
|
||||||
{ OFPFMF11_DL_VLAN_PCP, OFPXMT12_OFB_VLAN_PCP },
|
{ OFPFMF11_DL_VLAN_PCP, MFF_VLAN_PCP },
|
||||||
{ OFPFMF11_DL_TYPE, OFPXMT12_OFB_ETH_TYPE },
|
{ OFPFMF11_DL_TYPE, MFF_ETH_TYPE },
|
||||||
{ OFPFMF11_NW_TOS, OFPXMT12_OFB_IP_DSCP },
|
{ OFPFMF11_NW_TOS, MFF_IP_DSCP },
|
||||||
{ OFPFMF11_NW_PROTO, OFPXMT12_OFB_IP_PROTO },
|
{ OFPFMF11_NW_PROTO, MFF_IP_PROTO },
|
||||||
{ OFPFMF11_TP_SRC, OFPXMT12_OFB_TCP_SRC },
|
{ OFPFMF11_TP_SRC, MFF_TCP_SRC },
|
||||||
{ OFPFMF11_TP_DST, OFPXMT12_OFB_TCP_DST },
|
{ OFPFMF11_TP_DST, MFF_TCP_DST },
|
||||||
{ OFPFMF11_MPLS_LABEL, OFPXMT12_OFB_MPLS_LABEL },
|
{ OFPFMF11_MPLS_LABEL, MFF_MPLS_LABEL },
|
||||||
{ OFPFMF11_MPLS_TC, OFPXMT12_OFB_MPLS_TC },
|
{ OFPFMF11_MPLS_TC, MFF_MPLS_TC },
|
||||||
/* I don't know what OFPFMF11_TYPE means. */
|
/* I don't know what OFPFMF11_TYPE means. */
|
||||||
{ OFPFMF11_DL_SRC, OFPXMT12_OFB_ETH_SRC },
|
{ OFPFMF11_DL_SRC, MFF_ETH_SRC },
|
||||||
{ OFPFMF11_DL_DST, OFPXMT12_OFB_ETH_DST },
|
{ OFPFMF11_DL_DST, MFF_ETH_DST },
|
||||||
{ OFPFMF11_NW_SRC, OFPXMT12_OFB_IPV4_SRC },
|
{ OFPFMF11_NW_SRC, MFF_IPV4_SRC },
|
||||||
{ OFPFMF11_NW_DST, OFPXMT12_OFB_IPV4_DST },
|
{ OFPFMF11_NW_DST, MFF_IPV4_DST },
|
||||||
{ OFPFMF11_METADATA, OFPXMT12_OFB_METADATA },
|
{ OFPFMF11_METADATA, MFF_METADATA },
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct map *p;
|
const struct map *p;
|
||||||
@@ -5103,7 +5065,7 @@ oxm12_to_ofp11_flow_match_fields(ovs_be64 oxm12)
|
|||||||
|
|
||||||
fmf11 = 0;
|
fmf11 = 0;
|
||||||
for (p = map; p < &map[ARRAY_SIZE(map)]; p++) {
|
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;
|
fmf11 |= p->fmf11;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5111,7 +5073,7 @@ oxm12_to_ofp11_flow_match_fields(ovs_be64 oxm12)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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 ofpbuf *buf)
|
||||||
{
|
{
|
||||||
struct ofp11_table_stats *out;
|
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 = ofpbuf_put_zeros(buf, sizeof *out);
|
||||||
out->table_id = in->table_id;
|
out->table_id = in->table_id;
|
||||||
ovs_strlcpy(out->name, in->name, sizeof out->name);
|
ovs_strlcpy(out->name, in->name, sizeof out->name);
|
||||||
out->wildcards = oxm12_to_ofp11_flow_match_fields(in->wildcards);
|
out->wildcards = fields_to_ofp11_flow_match_fields(&in->wildcards);
|
||||||
out->match = oxm12_to_ofp11_flow_match_fields(in->match);
|
out->match = fields_to_ofp11_flow_match_fields(&in->match);
|
||||||
out->instructions = in->instructions;
|
out->instructions = htonl(in->instructions);
|
||||||
out->write_actions = in->write_actions;
|
out->write_actions = ofpact_bitmap_to_openflow(in->write_ofpacts,
|
||||||
out->apply_actions = in->apply_actions;
|
OFP11_VERSION);
|
||||||
out->config = in->config;
|
out->apply_actions = ofpact_bitmap_to_openflow(in->apply_ofpacts,
|
||||||
out->max_entries = in->max_entries;
|
OFP11_VERSION);
|
||||||
out->active_count = in->active_count;
|
out->config = htonl(in->config);
|
||||||
out->lookup_count = in->lookup_count;
|
out->max_entries = htonl(in->max_entries);
|
||||||
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
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 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 = ofpbuf_put_zeros(buf, sizeof *out);
|
||||||
out->match &= htonll(OFPXMT12_MASK);
|
out->table_id = in->table_id;
|
||||||
out->wildcards &= htonll(OFPXMT12_MASK);
|
ovs_strlcpy(out->name, in->name, sizeof out->name);
|
||||||
out->write_setfields &= htonll(OFPXMT12_MASK);
|
out->match = mf_bitmap_to_oxm_bitmap(&in->match, OFP12_VERSION);
|
||||||
out->apply_setfields &= htonll(OFPXMT12_MASK);
|
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
|
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 ofpbuf *buf)
|
||||||
{
|
{
|
||||||
struct ofp13_table_stats *out;
|
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 = ofpbuf_put_uninit(buf, sizeof *out);
|
||||||
out->table_id = in->table_id;
|
out->table_id = in->table_id;
|
||||||
out->active_count = in->active_count;
|
out->active_count = htonl(in->active_count);
|
||||||
out->lookup_count = in->lookup_count;
|
out->lookup_count = htonll(in->lookup_count);
|
||||||
out->matched_count = in->matched_count;
|
out->matched_count = htonll(in->matched_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ofpbuf *
|
struct ofpbuf *
|
||||||
ofputil_encode_table_stats_reply(const struct ofp12_table_stats stats[], int n,
|
ofputil_encode_table_stats_reply(const struct ofputil_table_stats stats[],
|
||||||
const struct ofp_header *request)
|
int n, const struct ofp_header *request)
|
||||||
{
|
{
|
||||||
struct ofpbuf *reply;
|
struct ofpbuf *reply;
|
||||||
int i;
|
int i;
|
||||||
@@ -6796,20 +6792,18 @@ ofputil_encode_group_features_reply(
|
|||||||
{
|
{
|
||||||
struct ofp12_group_features_stats *ogf;
|
struct ofp12_group_features_stats *ogf;
|
||||||
struct ofpbuf *reply;
|
struct ofpbuf *reply;
|
||||||
|
int i;
|
||||||
|
|
||||||
reply = ofpraw_alloc_xid(OFPRAW_OFPST12_GROUP_FEATURES_REPLY,
|
reply = ofpraw_alloc_xid(OFPRAW_OFPST12_GROUP_FEATURES_REPLY,
|
||||||
request->version, request->xid, 0);
|
request->version, request->xid, 0);
|
||||||
ogf = ofpbuf_put_zeros(reply, sizeof *ogf);
|
ogf = ofpbuf_put_zeros(reply, sizeof *ogf);
|
||||||
ogf->types = htonl(features->types);
|
ogf->types = htonl(features->types);
|
||||||
ogf->capabilities = htonl(features->capabilities);
|
ogf->capabilities = htonl(features->capabilities);
|
||||||
ogf->max_groups[0] = htonl(features->max_groups[0]);
|
for (i = 0; i < OFPGT12_N_TYPES; i++) {
|
||||||
ogf->max_groups[1] = htonl(features->max_groups[1]);
|
ogf->max_groups[i] = htonl(features->max_groups[i]);
|
||||||
ogf->max_groups[2] = htonl(features->max_groups[2]);
|
ogf->actions[i] = ofpact_bitmap_to_openflow(features->ofpacts[i],
|
||||||
ogf->max_groups[3] = htonl(features->max_groups[3]);
|
request->version);
|
||||||
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]);
|
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
@@ -6820,17 +6814,15 @@ ofputil_decode_group_features_reply(const struct ofp_header *oh,
|
|||||||
struct ofputil_group_features *features)
|
struct ofputil_group_features *features)
|
||||||
{
|
{
|
||||||
const struct ofp12_group_features_stats *ogf = ofpmsg_body(oh);
|
const struct ofp12_group_features_stats *ogf = ofpmsg_body(oh);
|
||||||
|
int i;
|
||||||
|
|
||||||
features->types = ntohl(ogf->types);
|
features->types = ntohl(ogf->types);
|
||||||
features->capabilities = ntohl(ogf->capabilities);
|
features->capabilities = ntohl(ogf->capabilities);
|
||||||
features->max_groups[0] = ntohl(ogf->max_groups[0]);
|
for (i = 0; i < OFPGT12_N_TYPES; i++) {
|
||||||
features->max_groups[1] = ntohl(ogf->max_groups[1]);
|
features->max_groups[i] = ntohl(ogf->max_groups[i]);
|
||||||
features->max_groups[2] = ntohl(ogf->max_groups[2]);
|
features->ofpacts[i] = ofpact_bitmap_from_openflow(
|
||||||
features->max_groups[3] = ntohl(ogf->max_groups[3]);
|
ogf->actions[i], oh->version);
|
||||||
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]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse a group status request message into a 32 bit OpenFlow 1.1
|
/* Parse a group status request message into a 32 bit OpenFlow 1.1
|
||||||
|
@@ -528,37 +528,6 @@ enum ofputil_capabilities {
|
|||||||
OFPUTIL_C_PORT_BLOCKED = 1 << 8, /* Switch will block looping ports */
|
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. */
|
/* Abstract ofp_switch_features. */
|
||||||
struct ofputil_switch_features {
|
struct ofputil_switch_features {
|
||||||
uint64_t datapath_id; /* Datapath unique ID. */
|
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 n_tables; /* Number of tables supported by datapath. */
|
||||||
uint8_t auxiliary_id; /* Identify auxiliary connections */
|
uint8_t auxiliary_id; /* Identify auxiliary connections */
|
||||||
enum ofputil_capabilities capabilities;
|
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 *,
|
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"
|
* - 'apply' reports features available in an "apply_actions"
|
||||||
* instruction. */
|
* instruction. */
|
||||||
struct ofputil_table_action_features {
|
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". */
|
struct mf_bitmap set_fields; /* Fields for "set-field". */
|
||||||
} write, apply;
|
} write, apply;
|
||||||
} nonmiss, miss;
|
} nonmiss, miss;
|
||||||
@@ -798,13 +767,30 @@ struct ofpbuf *ofputil_encode_role_status(
|
|||||||
|
|
||||||
enum ofperr ofputil_decode_role_status(const struct ofp_header *oh,
|
enum ofperr ofputil_decode_role_status(const struct ofp_header *oh,
|
||||||
struct ofputil_role_status *rs);
|
struct ofputil_role_status *rs);
|
||||||
/* Abstract table stats.
|
/* Abstract table stats. */
|
||||||
*
|
struct ofputil_table_stats {
|
||||||
* For now we use ofp12_table_stats as a superset of the other protocol
|
uint8_t table_id;
|
||||||
* versions' table stats. */
|
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(
|
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);
|
const struct ofp_header *request);
|
||||||
|
|
||||||
/* Queue configuration request. */
|
/* Queue configuration request. */
|
||||||
@@ -1099,9 +1085,7 @@ struct ofputil_group_features {
|
|||||||
uint32_t types; /* Bitmap of OFPGT_* values supported. */
|
uint32_t types; /* Bitmap of OFPGT_* values supported. */
|
||||||
uint32_t capabilities; /* Bitmap of OFPGFC12_* capability supported. */
|
uint32_t capabilities; /* Bitmap of OFPGFC12_* capability supported. */
|
||||||
uint32_t max_groups[4]; /* Maximum number of groups for each type. */
|
uint32_t max_groups[4]; /* Maximum number of groups for each type. */
|
||||||
|
uint64_t ofpacts[4]; /* Bitmaps of supported OFPACT_* */
|
||||||
/* Bitmaps of OFPAT_* that are supported. OF1.2+ actions only. */
|
|
||||||
uint32_t actions[4];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Group desc reply, independent of protocol. */
|
/* Group desc reply, independent of protocol. */
|
||||||
|
@@ -1500,37 +1500,26 @@ flush(struct ofproto *ofproto_)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
get_features(struct ofproto *ofproto_ OVS_UNUSED,
|
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;
|
*arp_match_ip = true;
|
||||||
*actions = (OFPUTIL_A_OUTPUT |
|
*ofpacts = (UINT64_C(1) << N_OFPACTS) - 1;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_tables(struct ofproto *ofproto, struct ofp12_table_stats *ots)
|
get_tables(struct ofproto *ofproto, struct ofputil_table_stats *stats)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
strcpy(ots->name, "classifier");
|
strcpy(stats->name, "classifier");
|
||||||
|
|
||||||
for (i = 0; i < ofproto->n_tables; i++) {
|
for (i = 0; i < ofproto->n_tables; i++) {
|
||||||
unsigned long missed, matched;
|
unsigned long missed, matched;
|
||||||
|
|
||||||
atomic_read(&ofproto->tables[i].n_matched, &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);
|
atomic_read(&ofproto->tables[i].n_missed, &missed);
|
||||||
ots[i].lookup_count = htonll(matched + missed);
|
stats[i].lookup_count = matched + missed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -774,30 +774,30 @@ struct ofproto_class {
|
|||||||
* supports matching IP addresses inside ARP requests and replies, false
|
* supports matching IP addresses inside ARP requests and replies, false
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*
|
*
|
||||||
* The implementation should store in '*actions' a bitmap of the supported
|
* The implementation should store in '*ofpacts' a bitmap of the supported
|
||||||
* OpenFlow actions. Vendor actions are not included in '*actions'. */
|
* OFPACT_* actions. */
|
||||||
void (*get_features)(struct ofproto *ofproto,
|
void (*get_features)(struct ofproto *ofproto,
|
||||||
bool *arp_match_ip,
|
bool *arp_match_ip,
|
||||||
enum ofputil_action_bitmap *actions);
|
uint64_t *ofpacts);
|
||||||
|
|
||||||
/* Helper for the OpenFlow OFPST_TABLE statistics request.
|
/* 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:
|
* initialized as:
|
||||||
*
|
*
|
||||||
* - 'table_id' to the array index.
|
* - 'table_id' to the array index.
|
||||||
*
|
*
|
||||||
* - 'name' to "table#" where # is the table ID.
|
* - '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.
|
* - 'metadata_match' and 'metadata_write' to OVS_BE64_MAX.
|
||||||
*
|
*
|
||||||
* - 'instructions' to OFPIT11_ALL.
|
* - 'instructions' to all instructions.
|
||||||
*
|
*
|
||||||
* - 'config' to OFPTC11_TABLE_MISS_MASK.
|
* - '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
|
* - 'matched_count' to the number of packets looked up in this flow
|
||||||
* table so far that matched one of the flow entries.
|
* 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 ## */
|
/* ## ofport Functions ## */
|
||||||
|
@@ -524,28 +524,10 @@ ofproto_create(const char *datapath_name, const char *datapath_type,
|
|||||||
ovs_mutex_unlock(&ofproto_mutex);
|
ovs_mutex_unlock(&ofproto_mutex);
|
||||||
ofproto->ogf.capabilities = OFPGFC_CHAINING | OFPGFC_SELECT_LIVENESS |
|
ofproto->ogf.capabilities = OFPGFC_CHAINING | OFPGFC_SELECT_LIVENESS |
|
||||||
OFPGFC_SELECT_WEIGHT;
|
OFPGFC_SELECT_WEIGHT;
|
||||||
ofproto->ogf.max_groups[OFPGT11_ALL] = OFPG_MAX;
|
for (i = 0; i < 4; i++) {
|
||||||
ofproto->ogf.max_groups[OFPGT11_SELECT] = OFPG_MAX;
|
ofproto->ogf.max_groups[i] = OFPG_MAX;
|
||||||
ofproto->ogf.max_groups[OFPGT11_INDIRECT] = OFPG_MAX;
|
ofproto->ogf.ofpacts[i] = (UINT64_C(1) << N_OFPACTS) - 1;
|
||||||
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) */
|
|
||||||
|
|
||||||
error = ofproto->ofproto_class->construct(ofproto);
|
error = ofproto->ofproto_class->construct(ofproto);
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -2805,8 +2787,8 @@ handle_features_request(struct ofconn *ofconn, const struct ofp_header *oh)
|
|||||||
struct ofpbuf *b;
|
struct ofpbuf *b;
|
||||||
|
|
||||||
ofproto->ofproto_class->get_features(ofproto, &arp_match_ip,
|
ofproto->ofproto_class->get_features(ofproto, &arp_match_ip,
|
||||||
&features.actions);
|
&features.ofpacts);
|
||||||
ovs_assert(features.actions & OFPUTIL_A_OUTPUT); /* sanity check */
|
ovs_assert(features.ofpacts & (UINT64_C(1) << OFPACT_OUTPUT));
|
||||||
|
|
||||||
features.datapath_id = ofproto->datapath_id;
|
features.datapath_id = ofproto->datapath_id;
|
||||||
features.n_buffers = pktbuf_capacity();
|
features.n_buffers = pktbuf_capacity();
|
||||||
@@ -3081,37 +3063,44 @@ static enum ofperr
|
|||||||
handle_table_stats_request(struct ofconn *ofconn,
|
handle_table_stats_request(struct ofconn *ofconn,
|
||||||
const struct ofp_header *request)
|
const struct ofp_header *request)
|
||||||
{
|
{
|
||||||
|
struct mf_bitmap rw_fields = MF_BITMAP_INITIALIZER;
|
||||||
struct ofproto *p = ofconn_get_ofproto(ofconn);
|
struct ofproto *p = ofconn_get_ofproto(ofconn);
|
||||||
struct ofp12_table_stats *ots;
|
struct ofputil_table_stats *stats;
|
||||||
struct ofpbuf *msg;
|
struct ofpbuf *msg;
|
||||||
int n_tables;
|
int n_tables;
|
||||||
size_t i;
|
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.
|
/* Set up default values.
|
||||||
*
|
*
|
||||||
* ofp12_table_stats is used as a generic structure as
|
* ofp12_table_stats is used as a generic structure as
|
||||||
* it is able to hold all the fields for ofp10_table_stats
|
* it is able to hold all the fields for ofp10_table_stats
|
||||||
* and ofp11_table_stats (and of course itself).
|
* 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++) {
|
for (i = 0; i < p->n_tables; i++) {
|
||||||
ots[i].table_id = i;
|
stats[i].table_id = i;
|
||||||
sprintf(ots[i].name, "table%"PRIuSIZE, i);
|
sprintf(stats[i].name, "table%"PRIuSIZE, i);
|
||||||
ots[i].match = htonll(OFPXMT13_MASK);
|
bitmap_set_multiple(stats[i].match.bm, 0, MFF_N_IDS, 1);
|
||||||
ots[i].wildcards = htonll(OFPXMT13_MASK);
|
bitmap_set_multiple(stats[i].wildcards.bm, 0, MFF_N_IDS, 1);
|
||||||
ots[i].write_actions = htonl(OFPAT11_OUTPUT);
|
stats[i].write_ofpacts = (UINT64_C(1) << N_OFPACTS) - 1;
|
||||||
ots[i].apply_actions = htonl(OFPAT11_OUTPUT);
|
stats[i].apply_ofpacts = (UINT64_C(1) << N_OFPACTS) - 1;
|
||||||
ots[i].write_setfields = htonll(OFPXMT13_MASK);
|
stats[i].write_setfields = rw_fields;
|
||||||
ots[i].apply_setfields = htonll(OFPXMT13_MASK);
|
stats[i].apply_setfields = rw_fields;
|
||||||
ots[i].metadata_match = OVS_BE64_MAX;
|
stats[i].metadata_match = OVS_BE64_MAX;
|
||||||
ots[i].metadata_write = OVS_BE64_MAX;
|
stats[i].metadata_write = OVS_BE64_MAX;
|
||||||
ots[i].instructions = htonl(OFPIT11_ALL);
|
stats[i].instructions = OFPIT13_ALL;
|
||||||
ots[i].config = htonl(OFPTC11_TABLE_MISS_MASK);
|
stats[i].config = OFPTC11_TABLE_MISS_MASK;
|
||||||
ots[i].max_entries = htonl(1000000); /* An arbitrary big number. */
|
stats[i].max_entries = 1000000; /* An arbitrary big number. */
|
||||||
ots[i].active_count = htonl(classifier_count(&p->tables[i].cls));
|
stats[i].active_count = classifier_count(&p->tables[i].cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
p->ofproto_class->get_tables(p, ots);
|
p->ofproto_class->get_tables(p, stats);
|
||||||
|
|
||||||
/* Post-process the tables, dropping hidden tables. */
|
/* Post-process the tables, dropping hidden tables. */
|
||||||
n_tables = p->n_tables;
|
n_tables = p->n_tables;
|
||||||
@@ -3124,18 +3113,18 @@ handle_table_stats_request(struct ofconn *ofconn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (table->name) {
|
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)) {
|
if (table->max_flows < stats[i].max_entries) {
|
||||||
ots[i].max_entries = htonl(table->max_flows);
|
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);
|
ofconn_send_reply(ofconn, msg);
|
||||||
|
|
||||||
free(ots);
|
free(stats);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -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
|
OFPT_FEATURES_REPLY (xid=0x1): dpid:0000505400000001
|
||||||
n_tables:2, n_buffers:256
|
n_tables:2, n_buffers:256
|
||||||
capabilities: FLOW_STATS TABLE_STATS PORT_STATS ARP_MATCH_IP
|
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
|
1(eth1): addr:50:54:00:00:00:02
|
||||||
config: 0
|
config: 0
|
||||||
state: 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 \
|
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 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 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
|
"], [0], [dnl
|
||||||
OFPST_GROUP_FEATURES reply (OF1.2) (xid=0x2):
|
OFPST_GROUP_FEATURES reply (OF1.2) (xid=0x2):
|
||||||
Group table:
|
Group table:
|
||||||
Types: 0xf
|
Types: 0xf
|
||||||
Capabilities: 0xf
|
Capabilities: 0xf
|
||||||
All group :
|
all group:
|
||||||
max_groups = 0x1 actions=0x00000001
|
max_groups=0x1
|
||||||
Select group :
|
actions: output
|
||||||
max_groups = 0x2 actions=0x00000003
|
select group:
|
||||||
Indirect group :
|
max_groups=0x2
|
||||||
max_groups = 0x3 actions=0x00000007
|
actions: output push_vlan
|
||||||
Fast Failover group :
|
indirect group:
|
||||||
max_groups = 0x4 actions=0x0000000f
|
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
|
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
|
next tables: 1-253
|
||||||
instructions: apply_actions,clear_actions,write_actions,write_metadata,goto_table
|
instructions: apply_actions,clear_actions,write_actions,write_metadata,goto_table
|
||||||
Write-Actions and Apply-Actions features:
|
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
|
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:
|
matching:
|
||||||
tun_id: exact match or wildcard
|
tun_id: exact match or wildcard
|
||||||
|
@@ -36,7 +36,7 @@ AT_CHECK([STRIP_XIDS stdout], [0], [dnl
|
|||||||
OFPT_FEATURES_REPLY: dpid:fedcba9876543210
|
OFPT_FEATURES_REPLY: dpid:fedcba9876543210
|
||||||
n_tables:254, n_buffers:256
|
n_tables:254, n_buffers:256
|
||||||
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
|
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
|
LOCAL(br0): addr:aa:55:aa:55:00:00
|
||||||
config: PORT_DOWN
|
config: PORT_DOWN
|
||||||
state: LINK_DOWN
|
state: LINK_DOWN
|
||||||
@@ -58,7 +58,7 @@ s/00:0.$/00:0x/' < stdout]],
|
|||||||
OFPT_FEATURES_REPLY: dpid:fedcba9876543210
|
OFPT_FEATURES_REPLY: dpid:fedcba9876543210
|
||||||
n_tables:254, n_buffers:256
|
n_tables:254, n_buffers:256
|
||||||
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
|
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
|
1(p1): addr:aa:55:aa:55:00:0x
|
||||||
config: PORT_DOWN
|
config: PORT_DOWN
|
||||||
state: LINK_DOWN
|
state: LINK_DOWN
|
||||||
@@ -451,7 +451,7 @@ do
|
|||||||
OFPT_FEATURES_REPLY: dpid:fedcba9876543210
|
OFPT_FEATURES_REPLY: dpid:fedcba9876543210
|
||||||
n_tables:254, n_buffers:256
|
n_tables:254, n_buffers:256
|
||||||
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
|
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
|
LOCAL(br0): addr:aa:55:aa:55:00:00
|
||||||
config: $config
|
config: $config
|
||||||
state: $state
|
state: $state
|
||||||
@@ -1064,13 +1064,13 @@ AT_CLEANUP
|
|||||||
AT_SETUP([ofproto - flow table configuration (OpenFlow 1.2)])
|
AT_SETUP([ofproto - flow table configuration (OpenFlow 1.2)])
|
||||||
OVS_VSWITCHD_START
|
OVS_VSWITCHD_START
|
||||||
# Check the default configuration.
|
# Check the default configuration.
|
||||||
(mid="wild=0xfffffffff, max=1000000,"
|
(mid="wild=0x1ffffffffd, max=1000000,"
|
||||||
tail="
|
tail="
|
||||||
lookup=0, matched=0
|
lookup=0, matched=0
|
||||||
match=0xfffffffff, instructions=0x00000007, config=0x00000003
|
match=0x1ffffffffd, instructions=0x00000007, config=0x00000003
|
||||||
write_actions=0x00000000, apply_actions=0x00000000
|
write_actions=0x03ff8001, apply_actions=0x03ff8001
|
||||||
write_setfields=0x0000000fffffffff
|
write_setfields=0x0000000c0fe7fbdd
|
||||||
apply_setfields=0x0000000fffffffff
|
apply_setfields=0x0000000c0fe7fbdd
|
||||||
metadata_match=0xffffffffffffffff
|
metadata_match=0xffffffffffffffff
|
||||||
metadata_write=0xffffffffffffffff"
|
metadata_write=0xffffffffffffffff"
|
||||||
echo "OFPST_TABLE reply (OF1.2) (xid=0x2): 254 tables
|
echo "OFPST_TABLE reply (OF1.2) (xid=0x2): 254 tables
|
||||||
@@ -1095,9 +1095,9 @@ AT_CHECK(
|
|||||||
# Check that the configuration was updated.
|
# Check that the configuration was updated.
|
||||||
mv expout orig-expout
|
mv expout orig-expout
|
||||||
(echo "OFPST_TABLE reply (OF1.2) (xid=0x2): 254 tables
|
(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
|
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
|
tail -n +11 orig-expout) > expout
|
||||||
AT_CHECK([ovs-ofctl -O OpenFlow12 dump-tables br0], [0], [expout])
|
AT_CHECK([ovs-ofctl -O OpenFlow12 dump-tables br0], [0], [expout])
|
||||||
OVS_VSWITCHD_STOP
|
OVS_VSWITCHD_STOP
|
||||||
|
Reference in New Issue
Block a user