diff options
author | Pravin B Shelar <pshelar@nicira.com> | 2011-10-21 14:38:54 -0700 |
---|---|---|
committer | Pravin B Shelar <pshelar@nicira.com> | 2011-10-21 14:38:54 -0700 |
commit | 4edb9ae90e4092f5f56b9d914d2b88783c49860d (patch) | |
tree | b606f5a5eca862b62aa2f4458cb7f54b06c73c2d /lib/odp-util.c | |
parent | a0003c0c359bc3ffe8a6683dbd0121877a3ce700 (diff) |
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
Diffstat (limited to 'lib/odp-util.c')
-rw-r--r-- | lib/odp-util.c | 76 |
1 files changed, 27 insertions, 49 deletions
diff --git a/lib/odp-util.c b/lib/odp-util.c index a4710991..db3535db 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -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))); - 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))); - break; - case OVS_ACTION_ATTR_POP_VLAN: - ds_put_format(ds, "pop_vlan"); + 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_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)); + 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_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; |