- err = -EFAULT;
- if (copy_from_user(__skb_put(skb, len), uodp_flow, len))
- goto error_free_skb;
-
- odp_flow = (struct odp_flow *)skb->data;
- err = -EINVAL;
- if (odp_flow->len != len)
- goto error_free_skb;
-
- flowcmd->nlmsg_flags = odp_flow->nlmsg_flags;
- flowcmd->dp_idx = odp_flow->dp_idx;
- flowcmd->total_len = odp_flow->total_len;
-
- err = nla_parse(a, ODP_FLOW_ATTR_MAX,
- (struct nlattr *)(skb->data + sizeof(struct odp_flow)),
- skb->len - sizeof(struct odp_flow), flow_policy);
- if (err)
- goto error_free_skb;
-
- /* ODP_FLOW_ATTR_KEY. */
- if (a[ODP_FLOW_ATTR_KEY]) {
- err = flow_from_nlattrs(&flowcmd->key, a[ODP_FLOW_ATTR_KEY]);
- if (err)
- goto error_free_skb;
- } else
- memset(&flowcmd->key, 0, sizeof(struct sw_flow_key));
-
- /* ODP_FLOW_ATTR_ACTIONS. */
- if (a[ODP_FLOW_ATTR_ACTIONS]) {
- flowcmd->actions = nla_data(a[ODP_FLOW_ATTR_ACTIONS]);
- flowcmd->actions_len = nla_len(a[ODP_FLOW_ATTR_ACTIONS]);
- err = validate_actions(flowcmd->actions, flowcmd->actions_len);
- if (err)
- goto error_free_skb;
- } else {
- flowcmd->actions = NULL;
- flowcmd->actions_len = 0;
- }
-
- flowcmd->clear = a[ODP_FLOW_ATTR_CLEAR] != NULL;
-
- flowcmd->state = a[ODP_FLOW_ATTR_STATE] ? nla_get_u64(a[ODP_FLOW_ATTR_STATE]) : 0;
-