diff options
-rw-r--r-- | net/openvswitch/datapath.c | 25 | ||||
-rw-r--r-- | net/openvswitch/flow_netlink.c | 24 | ||||
-rw-r--r-- | net/openvswitch/flow_netlink.h | 1 |
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. */ | ||
975 | static struct sw_flow_actions *get_flow_actions(const struct nlattr *a, | 965 | static 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 | ||
1287 | struct sw_flow_actions *ovs_nla_alloc_flow_actions(int size) | 1287 | static 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 | ||
1399 | static int ovs_nla_copy_actions__(const struct nlattr *attr, | 1399 | static 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 | ||
1687 | static int ovs_nla_copy_actions__(const struct nlattr *attr, | 1687 | static 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 | ||
1853 | static int sample_action_to_attr(const struct nlattr *attr, struct sk_buff *skb) | 1863 | static 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, | |||
56 | int ovs_nla_put_actions(const struct nlattr *attr, | 56 | int ovs_nla_put_actions(const struct nlattr *attr, |
57 | int len, struct sk_buff *skb); | 57 | int len, struct sk_buff *skb); |
58 | 58 | ||
59 | struct sw_flow_actions *ovs_nla_alloc_flow_actions(int actions_len); | ||
60 | void ovs_nla_free_flow_actions(struct sw_flow_actions *); | 59 | void ovs_nla_free_flow_actions(struct sw_flow_actions *); |
61 | 60 | ||
62 | #endif /* flow_netlink.h */ | 61 | #endif /* flow_netlink.h */ |