[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1411005311-11752-7-git-send-email-simon.horman@netronome.com>
Date: Thu, 18 Sep 2014 10:55:09 +0900
From: Simon Horman <simon.horman@...ronome.com>
To: dev@...nvswitch.org, netdev@...r.kernel.org
Cc: Pravin Shelar <pshelar@...ira.com>, Jesse Gross <jesse@...ira.com>,
Thomas Graf <tgraf@...g.ch>,
Simon Horman <simon.horman@...ronome.com>
Subject: [PATCH/RFC repost 6/8] datapath: validation of select group action
Allow validation and copying of select group actions.
This completes the prototype select group action implementation
in the datapath. Subsequent patches will add support to ovs-vswtichd.
Signed-off-by: Simon Horman <simon.horman@...ronome.com>
---
datapath/flow_netlink.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 102 insertions(+)
diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c
index 6c74841..90eddba 100644
--- a/datapath/flow_netlink.c
+++ b/datapath/flow_netlink.c
@@ -1497,6 +1497,94 @@ static int validate_and_copy_sample(const struct nlattr *attr,
return 0;
}
+static int validate_and_copy_bucket(const struct nlattr *attr,
+ const struct sw_flow_key *key, int depth,
+ struct sw_flow_actions **sfa,
+ __be16 eth_type, __be16 vlan_tci)
+{
+ const struct nlattr *attrs[OVS_BUCKET_ATTR_MAX + 1];
+ const struct nlattr *weight, *actions;
+ const struct nlattr *a;
+ int rem, start, err, st_acts;
+
+ memset(attrs, 0, sizeof(attrs));
+ nla_for_each_nested(a, attr, rem) {
+ int type = nla_type(a);
+ if (!type || type > OVS_BUCKET_ATTR_MAX || attrs[type])
+ return -EINVAL;
+ attrs[type] = a;
+ }
+ if (rem)
+ return -EINVAL;
+
+ weight = attrs[OVS_BUCKET_ATTR_WEIGHT];
+ if (!weight || nla_len(weight) != sizeof(u16))
+ return -EINVAL;
+
+ actions = attrs[OVS_BUCKET_ATTR_ACTIONS];
+ if (!actions || (nla_len(actions) && nla_len(actions) < NLA_HDRLEN))
+ return -EINVAL;
+
+ /* validation done, copy sample action. */
+ start = add_nested_action_start(sfa, OVS_SELECT_GROUP_ATTR_BUCKET);
+ if (start < 0)
+ return start;
+ err = add_action(sfa, OVS_BUCKET_ATTR_WEIGHT,
+ nla_data(weight), sizeof(u16));
+ if (err)
+ return err;
+ st_acts = add_nested_action_start(sfa, OVS_SAMPLE_ATTR_ACTIONS);
+ if (st_acts < 0)
+ return st_acts;
+
+ err = __ovs_nla_copy_actions(actions, key, depth + 1, sfa,
+ eth_type, vlan_tci);
+ if (err)
+ return err;
+
+ add_nested_action_end(*sfa, st_acts);
+ add_nested_action_end(*sfa, start);
+
+ return 0;
+}
+
+static int validate_and_copy_select_group(const struct nlattr *attr,
+ const struct sw_flow_key *key,
+ int depth,
+ struct sw_flow_actions **sfa,
+ __be16 eth_type, __be16 vlan_tci)
+{
+ bool have_bucket = false;
+ const struct nlattr *a;
+ int rem, start, err;
+
+ start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SELECT_GROUP);
+ if (start < 0)
+ return start;
+
+ nla_for_each_nested(a, attr, rem) {
+ int type = nla_type(a);
+
+ if (!type || type > OVS_SAMPLE_ATTR_MAX)
+ return -EINVAL;
+
+ /* Only possible type is OVS_SELECT_GROUP_ATTR_BUCKET */
+ if ((nla_len(a) && nla_len(a) < NLA_HDRLEN))
+ return -EINVAL;
+ err = validate_and_copy_bucket(a, key, depth, sfa,
+ eth_type, vlan_tci);
+ if (err < 0)
+ return err;
+ have_bucket = true;
+ }
+ if (rem || !have_bucket)
+ return -EINVAL;
+
+ add_nested_action_end(*sfa, start);
+
+ return 0;
+}
+
static int validate_tp_port(const struct sw_flow_key *flow_key,
__be16 eth_type)
{
@@ -1750,6 +1838,7 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
[OVS_ACTION_ATTR_POP_VLAN] = 0,
[OVS_ACTION_ATTR_SET] = (u32)-1,
[OVS_ACTION_ATTR_SAMPLE] = (u32)-1,
+ [OVS_ACTION_ATTR_SELECT_GROUP] = (u32)-1,
[OVS_ACTION_ATTR_HASH] = sizeof(struct ovs_action_hash)
};
const struct ovs_action_push_vlan *vlan;
@@ -1856,6 +1945,19 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
skip_copy = true;
break;
+ case OVS_ACTION_ATTR_SELECT_GROUP:
+ /* Nothing may come after a select group */
+ if (!last_action(a, rem))
+ return -EINVAL;
+
+ err = validate_and_copy_select_group(a, key, depth,
+ sfa, eth_type,
+ vlan_tci);
+ if (err)
+ return err;
+ skip_copy = true;
+ break;
+
default:
return -EINVAL;
}
--
2.0.1
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists