aboutsummaryrefslogtreecommitdiff
path: root/lib/odp-util.c
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2011-11-17 10:24:05 -0800
committerBen Pfaff <blp@nicira.com>2011-11-17 10:24:05 -0800
commitbecffb862616fa1a5c76c948b4f39cd61f6efca8 (patch)
tree3f528deb7c041ccc81328e77ba5a4f10ec4ddbb7 /lib/odp-util.c
parent7202cbe5521ed327ea0c9c959493a08ad2bf8d01 (diff)
tests: Rewrite code for comparing sets of ODP actions.
The compare-odp-actions.pl utility isn't fully general, even for its intended purpose of allowing sets of ODP actions to be compared ignoring unimportant differences in ordering of output actions and VLAN set actions. I decided that the proper way to do it was to have a utility that can actually parse the actions, instead of just doing textual transformations on them. So, this commit replaces compare-odp-actions.pl by "ovs-dpctl normalize-actions", which is sufficiently general for the intended purpose. The new ovs-dpctl functionality can be easily extended to handle differences in fields other than VLAN, but only VLAN is needed so far. This will be needed in an upcoming commit that in some cases introduces redundant "set vlan" actions into the ODP actions, which compare-odp-actions.pl doesn't tolerate.
Diffstat (limited to 'lib/odp-util.c')
-rw-r--r--lib/odp-util.c65
1 files changed, 26 insertions, 39 deletions
diff --git a/lib/odp-util.c b/lib/odp-util.c
index 935633f3..28dd537f 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -116,21 +116,6 @@ ovs_key_attr_to_string(enum ovs_key_attr attr)
}
}
-static enum ovs_key_attr
-ovs_key_attr_from_string(const char *s, size_t len)
-{
- enum ovs_key_attr attr;
-
- for (attr = 0; attr <= OVS_KEY_ATTR_MAX; attr++) {
- const char *attr_name = ovs_key_attr_to_string(attr);
- if (strlen(attr_name) == len && !memcmp(s, attr_name, len)) {
- return attr;
- }
- }
-
- return OVS_KEY_ATTR_UNSPEC;
-}
-
static void
format_generic_odp_action(struct ds *ds, const struct nlattr *a)
{
@@ -409,33 +394,35 @@ parse_odp_action(const char *s, const struct shash *port_names,
return retval + 5;
}
- if (!strncmp(s, "push(", 5)) {
- size_t start_ofs;
- int retval;
+ {
+ struct ovs_action_push_vlan push;
+ int tpid = ETH_TYPE_VLAN;
+ int vid, pcp;
+ int cfi = 1;
+ int n = -1;
- start_ofs = nl_msg_start_nested(actions, OVS_ACTION_ATTR_PUSH);
- retval = parse_odp_key_attr(s + 5, port_names, actions);
- if (retval < 0) {
- return retval;
- }
- if (s[retval + 5] != ')') {
- return -EINVAL;
+ if ((sscanf(s, "push_vlan(vid=%i,pcp=%i)%n", &vid, &pcp, &n) > 0
+ && n > 0)
+ || (sscanf(s, "push_vlan(vid=%i,pcp=%i,cfi=%i)%n",
+ &vid, &pcp, &cfi, &n) > 0 && n > 0)
+ || (sscanf(s, "push_vlan(tpid=%i,vid=%i,pcp=%i)%n",
+ &tpid, &vid, &pcp, &n) > 0 && n > 0)
+ || (sscanf(s, "push_vlan(tpid=%i,vid=%i,pcp=%i,cfi=%i)%n",
+ &tpid, &vid, &pcp, &cfi, &n) > 0 && n > 0)) {
+ push.vlan_tpid = htons(tpid);
+ push.vlan_tci = htons((vid << VLAN_VID_SHIFT)
+ | (pcp << VLAN_PCP_SHIFT)
+ | (cfi ? VLAN_CFI : 0));
+ nl_msg_put_unspec(actions, OVS_ACTION_ATTR_PUSH_VLAN,
+ &push, sizeof push);
+
+ return n;
}
- nl_msg_end_nested(actions, start_ofs);
- return retval + 6;
}
- if (!strncmp(s, "pop(", 4)) {
- enum ovs_key_attr key;
- size_t len;
-
- len = strcspn(s + 4, ")");
- key = ovs_key_attr_from_string(s + 4, len);
- if (key == OVS_KEY_ATTR_UNSPEC || s[4 + len] != ')') {
- return -EINVAL;
- }
- nl_msg_put_u16(actions, OVS_ACTION_ATTR_POP, key);
- return len + 5;
+ if (!strncmp(s, "pop_vlan", 8)) {
+ nl_msg_put_flag(actions, OVS_ACTION_ATTR_POP_VLAN);
+ return 8;
}
{
@@ -1107,7 +1094,7 @@ parse_odp_key_attr(const char *s, const struct shash *port_names,
break;
}
- retval = parse_odp_key_attr(s, key);
+ retval = parse_odp_key_attr(s, port_names, key);
if (retval < 0) {
return retval;
}