diff options
-rw-r--r-- | net/openvswitch/datapath.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index f6bd93d5f435..010125c48244 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -933,11 +933,34 @@ error: | |||
933 | return error; | 933 | return error; |
934 | } | 934 | } |
935 | 935 | ||
936 | static struct sw_flow_actions *get_flow_actions(const struct nlattr *a, | ||
937 | const struct sw_flow_key *key, | ||
938 | const struct sw_flow_mask *mask) | ||
939 | { | ||
940 | struct sw_flow_actions *acts; | ||
941 | struct sw_flow_key masked_key; | ||
942 | int error; | ||
943 | |||
944 | acts = ovs_nla_alloc_flow_actions(nla_len(a)); | ||
945 | if (IS_ERR(acts)) | ||
946 | return acts; | ||
947 | |||
948 | ovs_flow_mask_key(&masked_key, key, mask); | ||
949 | error = ovs_nla_copy_actions(a, &masked_key, 0, &acts); | ||
950 | if (error) { | ||
951 | OVS_NLERR("Flow actions may not be safe on all matching packets.\n"); | ||
952 | kfree(acts); | ||
953 | return ERR_PTR(error); | ||
954 | } | ||
955 | |||
956 | return acts; | ||
957 | } | ||
958 | |||
936 | static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info) | 959 | static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info) |
937 | { | 960 | { |
938 | struct nlattr **a = info->attrs; | 961 | struct nlattr **a = info->attrs; |
939 | struct ovs_header *ovs_header = info->userhdr; | 962 | struct ovs_header *ovs_header = info->userhdr; |
940 | struct sw_flow_key key, masked_key; | 963 | struct sw_flow_key key; |
941 | struct sw_flow *flow; | 964 | struct sw_flow *flow; |
942 | struct sw_flow_mask mask; | 965 | struct sw_flow_mask mask; |
943 | struct sk_buff *reply = NULL; | 966 | struct sk_buff *reply = NULL; |
@@ -959,17 +982,10 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info) | |||
959 | 982 | ||
960 | /* Validate actions. */ | 983 | /* Validate actions. */ |
961 | if (a[OVS_FLOW_ATTR_ACTIONS]) { | 984 | if (a[OVS_FLOW_ATTR_ACTIONS]) { |
962 | acts = ovs_nla_alloc_flow_actions(nla_len(a[OVS_FLOW_ATTR_ACTIONS])); | 985 | acts = get_flow_actions(a[OVS_FLOW_ATTR_ACTIONS], &key, &mask); |
963 | error = PTR_ERR(acts); | 986 | if (IS_ERR(acts)) { |
964 | if (IS_ERR(acts)) | 987 | error = PTR_ERR(acts); |
965 | goto error; | 988 | goto error; |
966 | |||
967 | ovs_flow_mask_key(&masked_key, &key, &mask); | ||
968 | error = ovs_nla_copy_actions(a[OVS_FLOW_ATTR_ACTIONS], | ||
969 | &masked_key, 0, &acts); | ||
970 | if (error) { | ||
971 | OVS_NLERR("Flow actions may not be safe on all matching packets.\n"); | ||
972 | goto err_kfree_acts; | ||
973 | } | 989 | } |
974 | } | 990 | } |
975 | 991 | ||