There are two separate API to allocate and copy actions list. Anytime
OVS needs to copy action list, it needs to call both functions.
Following patch moves action allocation to copy function to avoid
code duplication.
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Acked-by: Jarno Rajahalme <jrajahalme@nicira.com>
if (err)
goto err_flow_free;
if (err)
goto err_flow_free;
- acts = ovs_nla_alloc_flow_actions(nla_len(a[OVS_PACKET_ATTR_ACTIONS]));
- err = PTR_ERR(acts);
- if (IS_ERR(acts))
- goto err_flow_free;
-
err = ovs_nla_copy_actions(a[OVS_PACKET_ATTR_ACTIONS],
&flow->key, &acts);
err = ovs_nla_copy_actions(a[OVS_PACKET_ATTR_ACTIONS],
&flow->key, &acts);
- rcu_assign_pointer(flow->sf_acts, acts);
if (err)
goto err_flow_free;
if (err)
goto err_flow_free;
+ rcu_assign_pointer(flow->sf_acts, acts);
OVS_CB(packet)->flow = flow;
OVS_CB(packet)->pkt_key = &flow->key;
OVS_CB(skb)->egress_tun_info = NULL;
OVS_CB(packet)->flow = flow;
OVS_CB(packet)->pkt_key = &flow->key;
OVS_CB(skb)->egress_tun_info = NULL;
ovs_flow_mask_key(&new_flow->key, &new_flow->unmasked_key, &mask);
/* Validate actions. */
ovs_flow_mask_key(&new_flow->key, &new_flow->unmasked_key, &mask);
/* Validate actions. */
- acts = ovs_nla_alloc_flow_actions(nla_len(a[OVS_FLOW_ATTR_ACTIONS]));
- error = PTR_ERR(acts);
- if (IS_ERR(acts))
- goto err_kfree_flow;
-
error = ovs_nla_copy_actions(a[OVS_FLOW_ATTR_ACTIONS], &new_flow->key,
&acts);
if (error) {
error = ovs_nla_copy_actions(a[OVS_FLOW_ATTR_ACTIONS], &new_flow->key,
&acts);
if (error) {
-static struct sw_flow_actions *get_flow_actions(const struct nlattr *a,
- const struct sw_flow_key *key,
- const struct sw_flow_mask *mask)
-{
- struct sw_flow_actions *acts;
- struct sw_flow_key masked_key;
- int error;
-
- acts = ovs_nla_alloc_flow_actions(nla_len(a));
- if (IS_ERR(acts))
- return acts;
-
- ovs_flow_mask_key(&masked_key, key, mask);
- error = ovs_nla_copy_actions(a, &masked_key, &acts);
- if (error) {
- OVS_NLERR("Flow actions may not be safe on all matching packets.\n");
- kfree(acts);
- return ERR_PTR(error);
- }
-
- return acts;
-}
-
static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
{
struct nlattr **a = info->attrs;
static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
{
struct nlattr **a = info->attrs;
/* Validate actions. */
if (a[OVS_FLOW_ATTR_ACTIONS]) {
/* Validate actions. */
if (a[OVS_FLOW_ATTR_ACTIONS]) {
- acts = get_flow_actions(a[OVS_FLOW_ATTR_ACTIONS], &key, &mask);
- if (IS_ERR(acts)) {
- error = PTR_ERR(acts);
+ struct sw_flow_key masked_key;
+
+ ovs_flow_mask_key(&masked_key, &key, &mask);
+ error = ovs_nla_copy_actions(a[OVS_FLOW_ATTR_ACTIONS],
+ &masked_key, &acts);
+ if (error) {
+ OVS_NLERR("Flow actions may not be safe on all matching packets.\n");
- /* Can allocate before locking if have acts. */
- if (acts) {
+ /* Can allocate before locking if have acts. */
reply = ovs_flow_cmd_alloc_info(acts, info, false);
if (IS_ERR(reply)) {
error = PTR_ERR(reply);
reply = ovs_flow_cmd_alloc_info(acts, info, false);
if (IS_ERR(reply)) {
error = PTR_ERR(reply);
#define MAX_ACTIONS_BUFSIZE (32 * 1024)
#define MAX_ACTIONS_BUFSIZE (32 * 1024)
-struct sw_flow_actions *ovs_nla_alloc_flow_actions(int size)
+static struct sw_flow_actions *nla_alloc_flow_actions(int size)
{
struct sw_flow_actions *sfa;
{
struct sw_flow_actions *sfa;
new_acts_size = MAX_ACTIONS_BUFSIZE;
}
new_acts_size = MAX_ACTIONS_BUFSIZE;
}
- acts = ovs_nla_alloc_flow_actions(new_acts_size);
+ acts = nla_alloc_flow_actions(new_acts_size);
if (IS_ERR(acts))
return (void *)acts;
if (IS_ERR(acts))
return (void *)acts;
a->nla_len = sfa->actions_len - st_offset;
}
a->nla_len = sfa->actions_len - st_offset;
}
-static int ovs_nla_copy_actions__(const struct nlattr *attr,
+static int __ovs_nla_copy_actions(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 sw_flow_key *key,
int depth, struct sw_flow_actions **sfa,
__be16 eth_type, __be16 vlan_tci);
if (st_acts < 0)
return st_acts;
if (st_acts < 0)
return st_acts;
- err = ovs_nla_copy_actions__(actions, key, depth + 1, sfa,
+ err = __ovs_nla_copy_actions(actions, key, depth + 1, sfa,
eth_type, vlan_tci);
if (err)
return err;
eth_type, vlan_tci);
if (err)
return err;
-static int ovs_nla_copy_actions__(const struct nlattr *attr,
+static int __ovs_nla_copy_actions(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 sw_flow_key *key,
int depth, struct sw_flow_actions **sfa,
__be16 eth_type, __be16 vlan_tci)
const struct sw_flow_key *key,
struct sw_flow_actions **sfa)
{
const struct sw_flow_key *key,
struct sw_flow_actions **sfa)
{
- return ovs_nla_copy_actions__(attr, key, 0, sfa, key->eth.type,
- key->eth.tci);
+ int err;
+
+ *sfa = nla_alloc_flow_actions(nla_len(attr));
+ if (IS_ERR(*sfa))
+ return PTR_ERR(*sfa);
+
+ err = __ovs_nla_copy_actions(attr, key, 0, sfa, key->eth.type,
+ key->eth.tci);
+ if (err)
+ kfree(*sfa);
+
+ return err;
}
static int sample_action_to_attr(const struct nlattr *attr, struct sk_buff *skb)
}
static int sample_action_to_attr(const struct nlattr *attr, struct sk_buff *skb)
int ovs_nla_put_actions(const struct nlattr *attr,
int len, struct sk_buff *skb);
int ovs_nla_put_actions(const struct nlattr *attr,
int len, struct sk_buff *skb);
-struct sw_flow_actions *ovs_nla_alloc_flow_actions(int actions_len);
void ovs_nla_free_flow_actions(struct sw_flow_actions *);
#endif /* flow_netlink.h */
void ovs_nla_free_flow_actions(struct sw_flow_actions *);
#endif /* flow_netlink.h */