aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/openvswitch/datapath.c25
-rw-r--r--net/openvswitch/flow_netlink.c24
-rw-r--r--net/openvswitch/flow_netlink.h1
3 files changed, 21 insertions, 29 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 51017805b40b..014485ec4b0d 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -543,18 +543,12 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
543 if (err) 543 if (err)
544 goto err_flow_free; 544 goto err_flow_free;
545 545
546 acts = ovs_nla_alloc_flow_actions(nla_len(a[OVS_PACKET_ATTR_ACTIONS]));
547 err = PTR_ERR(acts);
548 if (IS_ERR(acts))
549 goto err_flow_free;
550
551 err = ovs_nla_copy_actions(a[OVS_PACKET_ATTR_ACTIONS], 546 err = ovs_nla_copy_actions(a[OVS_PACKET_ATTR_ACTIONS],
552 &flow->key, &acts); 547 &flow->key, &acts);
553 if (err) 548 if (err)
554 goto err_flow_free; 549 goto err_flow_free;
555 550
556 rcu_assign_pointer(flow->sf_acts, acts); 551 rcu_assign_pointer(flow->sf_acts, acts);
557
558 OVS_CB(packet)->egress_tun_info = NULL; 552 OVS_CB(packet)->egress_tun_info = NULL;
559 packet->priority = flow->key.phy.priority; 553 packet->priority = flow->key.phy.priority;
560 packet->mark = flow->key.phy.skb_mark; 554 packet->mark = flow->key.phy.skb_mark;
@@ -872,16 +866,11 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
872 ovs_flow_mask_key(&new_flow->key, &new_flow->unmasked_key, &mask); 866 ovs_flow_mask_key(&new_flow->key, &new_flow->unmasked_key, &mask);
873 867
874 /* Validate actions. */ 868 /* Validate actions. */
875 acts = ovs_nla_alloc_flow_actions(nla_len(a[OVS_FLOW_ATTR_ACTIONS]));
876 error = PTR_ERR(acts);
877 if (IS_ERR(acts))
878 goto err_kfree_flow;
879
880 error = ovs_nla_copy_actions(a[OVS_FLOW_ATTR_ACTIONS], &new_flow->key, 869 error = ovs_nla_copy_actions(a[OVS_FLOW_ATTR_ACTIONS], &new_flow->key,
881 &acts); 870 &acts);
882 if (error) { 871 if (error) {
883 OVS_NLERR("Flow actions may not be safe on all matching packets.\n"); 872 OVS_NLERR("Flow actions may not be safe on all matching packets.\n");
884 goto err_kfree_acts; 873 goto err_kfree_flow;
885 } 874 }
886 875
887 reply = ovs_flow_cmd_alloc_info(acts, info, false); 876 reply = ovs_flow_cmd_alloc_info(acts, info, false);
@@ -972,6 +961,7 @@ error:
972 return error; 961 return error;
973} 962}
974 963
964/* Factor out action copy to avoid "Wframe-larger-than=1024" warning. */
975static struct sw_flow_actions *get_flow_actions(const struct nlattr *a, 965static struct sw_flow_actions *get_flow_actions(const struct nlattr *a,
976 const struct sw_flow_key *key, 966 const struct sw_flow_key *key,
977 const struct sw_flow_mask *mask) 967 const struct sw_flow_mask *mask)
@@ -980,15 +970,10 @@ static struct sw_flow_actions *get_flow_actions(const struct nlattr *a,
980 struct sw_flow_key masked_key; 970 struct sw_flow_key masked_key;
981 int error; 971 int error;
982 972
983 acts = ovs_nla_alloc_flow_actions(nla_len(a));
984 if (IS_ERR(acts))
985 return acts;
986
987 ovs_flow_mask_key(&masked_key, key, mask); 973 ovs_flow_mask_key(&masked_key, key, mask);
988 error = ovs_nla_copy_actions(a, &masked_key, &acts); 974 error = ovs_nla_copy_actions(a, &masked_key, &acts);
989 if (error) { 975 if (error) {
990 OVS_NLERR("Flow actions may not be safe on all matching packets.\n"); 976 OVS_NLERR("Actions may not be safe on all matching packets.\n");
991 kfree(acts);
992 return ERR_PTR(error); 977 return ERR_PTR(error);
993 } 978 }
994 979
@@ -1028,10 +1013,8 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
1028 error = PTR_ERR(acts); 1013 error = PTR_ERR(acts);
1029 goto error; 1014 goto error;
1030 } 1015 }
1031 }
1032 1016
1033 /* Can allocate before locking if have acts. */ 1017 /* Can allocate before locking if have acts. */
1034 if (acts) {
1035 reply = ovs_flow_cmd_alloc_info(acts, info, false); 1018 reply = ovs_flow_cmd_alloc_info(acts, info, false);
1036 if (IS_ERR(reply)) { 1019 if (IS_ERR(reply)) {
1037 error = PTR_ERR(reply); 1020 error = PTR_ERR(reply);
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index 1050b2882b9e..482a0cbb22e8 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -1284,7 +1284,7 @@ nla_put_failure:
1284 1284
1285#define MAX_ACTIONS_BUFSIZE (32 * 1024) 1285#define MAX_ACTIONS_BUFSIZE (32 * 1024)
1286 1286
1287struct sw_flow_actions *ovs_nla_alloc_flow_actions(int size) 1287static struct sw_flow_actions *nla_alloc_flow_actions(int size)
1288{ 1288{
1289 struct sw_flow_actions *sfa; 1289 struct sw_flow_actions *sfa;
1290 1290
@@ -1329,7 +1329,7 @@ static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa,
1329 new_acts_size = MAX_ACTIONS_BUFSIZE; 1329 new_acts_size = MAX_ACTIONS_BUFSIZE;
1330 } 1330 }
1331 1331
1332 acts = ovs_nla_alloc_flow_actions(new_acts_size); 1332 acts = nla_alloc_flow_actions(new_acts_size);
1333 if (IS_ERR(acts)) 1333 if (IS_ERR(acts))
1334 return (void *)acts; 1334 return (void *)acts;
1335 1335
@@ -1396,7 +1396,7 @@ static inline void add_nested_action_end(struct sw_flow_actions *sfa,
1396 a->nla_len = sfa->actions_len - st_offset; 1396 a->nla_len = sfa->actions_len - st_offset;
1397} 1397}
1398 1398
1399static int ovs_nla_copy_actions__(const struct nlattr *attr, 1399static int __ovs_nla_copy_actions(const struct nlattr *attr,
1400 const struct sw_flow_key *key, 1400 const struct sw_flow_key *key,
1401 int depth, struct sw_flow_actions **sfa, 1401 int depth, struct sw_flow_actions **sfa,
1402 __be16 eth_type, __be16 vlan_tci); 1402 __be16 eth_type, __be16 vlan_tci);
@@ -1441,7 +1441,7 @@ static int validate_and_copy_sample(const struct nlattr *attr,
1441 if (st_acts < 0) 1441 if (st_acts < 0)
1442 return st_acts; 1442 return st_acts;
1443 1443
1444 err = ovs_nla_copy_actions__(actions, key, depth + 1, sfa, 1444 err = __ovs_nla_copy_actions(actions, key, depth + 1, sfa,
1445 eth_type, vlan_tci); 1445 eth_type, vlan_tci);
1446 if (err) 1446 if (err)
1447 return err; 1447 return err;
@@ -1684,7 +1684,7 @@ static int copy_action(const struct nlattr *from,
1684 return 0; 1684 return 0;
1685} 1685}
1686 1686
1687static int ovs_nla_copy_actions__(const struct nlattr *attr, 1687static int __ovs_nla_copy_actions(const struct nlattr *attr,
1688 const struct sw_flow_key *key, 1688 const struct sw_flow_key *key,
1689 int depth, struct sw_flow_actions **sfa, 1689 int depth, struct sw_flow_actions **sfa,
1690 __be16 eth_type, __be16 vlan_tci) 1690 __be16 eth_type, __be16 vlan_tci)
@@ -1846,8 +1846,18 @@ int ovs_nla_copy_actions(const struct nlattr *attr,
1846 const struct sw_flow_key *key, 1846 const struct sw_flow_key *key,
1847 struct sw_flow_actions **sfa) 1847 struct sw_flow_actions **sfa)
1848{ 1848{
1849 return ovs_nla_copy_actions__(attr, key, 0, sfa, key->eth.type, 1849 int err;
1850 key->eth.tci); 1850
1851 *sfa = nla_alloc_flow_actions(nla_len(attr));
1852 if (IS_ERR(*sfa))
1853 return PTR_ERR(*sfa);
1854
1855 err = __ovs_nla_copy_actions(attr, key, 0, sfa, key->eth.type,
1856 key->eth.tci);
1857 if (err)
1858 kfree(*sfa);
1859
1860 return err;
1851} 1861}
1852 1862
1853static int sample_action_to_attr(const struct nlattr *attr, struct sk_buff *skb) 1863static int sample_action_to_attr(const struct nlattr *attr, struct sk_buff *skb)
diff --git a/net/openvswitch/flow_netlink.h b/net/openvswitch/flow_netlink.h
index 4f0370646bc6..eb0b177300ad 100644
--- a/net/openvswitch/flow_netlink.h
+++ b/net/openvswitch/flow_netlink.h
@@ -56,7 +56,6 @@ int ovs_nla_copy_actions(const struct nlattr *attr,
56int ovs_nla_put_actions(const struct nlattr *attr, 56int ovs_nla_put_actions(const struct nlattr *attr,
57 int len, struct sk_buff *skb); 57 int len, struct sk_buff *skb);
58 58
59struct sw_flow_actions *ovs_nla_alloc_flow_actions(int actions_len);
60void ovs_nla_free_flow_actions(struct sw_flow_actions *); 59void ovs_nla_free_flow_actions(struct sw_flow_actions *);
61 60
62#endif /* flow_netlink.h */ 61#endif /* flow_netlink.h */