2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-25 15:07:05 +00:00

datapath: Refactor actions in terms of match fields.

Almost all current actions can be expressed in the form of
push/pop/set <field>, where field is one of the match fields. We can
create three base actions and take a field. This has both a nice
symmetry and avoids inconsistencies where we can match on the vlan
TPID but not set it.
Following patch converts all actions to this new format.

Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>

Bug #7115
This commit is contained in:
Pravin B Shelar
2011-10-21 14:38:54 -07:00
parent a0003c0c35
commit 4edb9ae90e
10 changed files with 615 additions and 422 deletions

View File

@@ -33,6 +33,9 @@
#include "timeval.h"
#include "util.h"
static void
format_odp_key_attr(const struct nlattr *a, struct ds *ds);
/* The interface between userspace and kernel uses an "OVS_*" prefix.
* Since this is fairly non-specific for the OVS userspace components,
* "ODP_*" (Open vSwitch Datapath) is used as the prefix for
@@ -48,7 +51,7 @@
* - For an action with a variable-length argument, returns -2.
*
* - For an invalid 'type', returns -1. */
int
static int
odp_action_len(uint16_t type)
{
if (type > OVS_ACTION_ATTR_MAX) {
@@ -58,16 +61,9 @@ odp_action_len(uint16_t type)
switch ((enum ovs_action_attr) type) {
case OVS_ACTION_ATTR_OUTPUT: return 4;
case OVS_ACTION_ATTR_USERSPACE: return -2;
case OVS_ACTION_ATTR_PUSH_VLAN: return 2;
case OVS_ACTION_ATTR_POP_VLAN: return 0;
case OVS_ACTION_ATTR_SET_DL_SRC: return ETH_ADDR_LEN;
case OVS_ACTION_ATTR_SET_DL_DST: return ETH_ADDR_LEN;
case OVS_ACTION_ATTR_SET_NW_SRC: return 4;
case OVS_ACTION_ATTR_SET_NW_DST: return 4;
case OVS_ACTION_ATTR_SET_NW_TOS: return 1;
case OVS_ACTION_ATTR_SET_TP_SRC: return 2;
case OVS_ACTION_ATTR_SET_TP_DST: return 2;
case OVS_ACTION_ATTR_SET_TUNNEL: return 8;
case OVS_ACTION_ATTR_PUSH: return -2;
case OVS_ACTION_ATTR_POP: return 2;
case OVS_ACTION_ATTR_SET: return -2;
case OVS_ACTION_ATTR_SET_PRIORITY: return 4;
case OVS_ACTION_ATTR_POP_PRIORITY: return 0;
case OVS_ACTION_ATTR_SAMPLE: return -2;
@@ -170,12 +166,11 @@ format_odp_userspace_action(struct ds *ds, const struct nlattr *attr)
}
void
static void
format_odp_action(struct ds *ds, const struct nlattr *a)
{
const uint8_t *eth;
int expected_len;
ovs_be32 ip;
enum ovs_action_attr type = nl_attr_type(a);
expected_len = odp_action_len(nl_attr_type(a));
if (expected_len != -2 && nl_attr_get_size(a) != expected_len) {
@@ -185,49 +180,30 @@ format_odp_action(struct ds *ds, const struct nlattr *a)
return;
}
switch (nl_attr_type(a)) {
switch (type) {
case OVS_ACTION_ATTR_OUTPUT:
ds_put_format(ds, "%"PRIu16, nl_attr_get_u32(a));
break;
case OVS_ACTION_ATTR_USERSPACE:
format_odp_userspace_action(ds, a);
break;
case OVS_ACTION_ATTR_SET_TUNNEL:
ds_put_format(ds, "set_tunnel(%#"PRIx64")",
ntohll(nl_attr_get_be64(a)));
case OVS_ACTION_ATTR_SET:
ds_put_cstr(ds, "set(");
format_odp_key_attr(nl_attr_get(a), ds);
ds_put_cstr(ds, ")");
break;
case OVS_ACTION_ATTR_PUSH_VLAN:
ds_put_format(ds, "push_vlan(vid=%"PRIu16",pcp=%d)",
vlan_tci_to_vid(nl_attr_get_be16(a)),
vlan_tci_to_pcp(nl_attr_get_be16(a)));
case OVS_ACTION_ATTR_PUSH:
ds_put_cstr(ds, "push(");
format_odp_key_attr(nl_attr_get(a), ds);
ds_put_cstr(ds, ")");
break;
case OVS_ACTION_ATTR_POP_VLAN:
ds_put_format(ds, "pop_vlan");
break;
case OVS_ACTION_ATTR_SET_DL_SRC:
eth = nl_attr_get_unspec(a, ETH_ADDR_LEN);
ds_put_format(ds, "set_dl_src("ETH_ADDR_FMT")", ETH_ADDR_ARGS(eth));
break;
case OVS_ACTION_ATTR_SET_DL_DST:
eth = nl_attr_get_unspec(a, ETH_ADDR_LEN);
ds_put_format(ds, "set_dl_dst("ETH_ADDR_FMT")", ETH_ADDR_ARGS(eth));
break;
case OVS_ACTION_ATTR_SET_NW_SRC:
ip = nl_attr_get_be32(a);
ds_put_format(ds, "set_nw_src("IP_FMT")", IP_ARGS(&ip));
break;
case OVS_ACTION_ATTR_SET_NW_DST:
ip = nl_attr_get_be32(a);
ds_put_format(ds, "set_nw_dst("IP_FMT")", IP_ARGS(&ip));
break;
case OVS_ACTION_ATTR_SET_NW_TOS:
ds_put_format(ds, "set_nw_tos(%"PRIu8")", nl_attr_get_u8(a));
break;
case OVS_ACTION_ATTR_SET_TP_SRC:
ds_put_format(ds, "set_tp_src(%"PRIu16")", ntohs(nl_attr_get_be16(a)));
break;
case OVS_ACTION_ATTR_SET_TP_DST:
ds_put_format(ds, "set_tp_dst(%"PRIu16")", ntohs(nl_attr_get_be16(a)));
case OVS_ACTION_ATTR_POP:
if (nl_attr_get_u16(a) == OVS_KEY_ATTR_8021Q) {
ds_put_cstr(ds, "pop(vlan)");
} else {
ds_put_format(ds, "pop(key%"PRIu16")", nl_attr_get_u16(a));
}
break;
case OVS_ACTION_ATTR_SET_PRIORITY:
ds_put_format(ds, "set_priority(%#"PRIx32")", nl_attr_get_u32(a));
@@ -238,6 +214,8 @@ format_odp_action(struct ds *ds, const struct nlattr *a)
case OVS_ACTION_ATTR_SAMPLE:
format_odp_sample_action(ds, a);
break;
case OVS_ACTION_ATTR_UNSPEC:
case __OVS_ACTION_ATTR_MAX:
default:
format_generic_odp_action(ds, a);
break;