mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 06:15:47 +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:
@@ -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. */
|
||||
static bool
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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>";
|
||||
}
|
||||
|
Reference in New Issue
Block a user