return error;
}
-/* Returns one greater than the maximum port number accepted in flow
- * actions. */
-uint32_t
-dpif_get_max_ports(const struct dpif *dpif)
-{
- return dpif->dpif_class->get_max_ports(dpif);
-}
-
/* Returns the Netlink PID value to supply in OVS_ACTION_ATTR_USERSPACE actions
* as the OVS_USERSPACE_ATTR_PID attribute's value, for use in flows whose
* packets arrived on port 'port_no'.
/* Adds or modifies a flow in 'dpif'. The flow is specified by the Netlink
* attribute OVS_FLOW_ATTR_KEY with types OVS_KEY_ATTR_* in the 'key_len' bytes
- * starting at 'key', and OVS_FLOW_ATTR_MASK with types of OVS_KEY_ATTR_* in the
- * 'mask_len' bytes starting at 'mask'. The associated actions are specified by
- * the Netlink attributes with types OVS_ACTION_ATTR_* in the 'actions_len'
- * bytes starting at 'actions'.
+ * starting at 'key', and OVS_FLOW_ATTR_MASK with types of OVS_KEY_ATTR_* in
+ * the 'mask_len' bytes starting at 'mask'. The associated actions are
+ * specified by the Netlink attributes with types OVS_ACTION_ATTR_* in the
+ * 'actions_len' bytes starting at 'actions'.
*
* - If the flow's key does not exist in 'dpif', then the flow will be added if
* 'flags' includes DPIF_FP_CREATE. Otherwise the operation will fail with
* ENOENT.
*
+ * The datapath may reject attempts to insert overlapping flows with EINVAL
+ * or EEXIST, but clients should not rely on this: avoiding overlapping flows
+ * is primarily the client's responsibility.
+ *
* If the operation succeeds, then 'stats', if nonnull, will be zeroed.
*
* - If the flow's key does exist in 'dpif', then the flow's actions will be
static void
dpif_execute_helper_userspace_cb(void *aux, struct ofpbuf *packet,
const struct flow *flow,
- const struct nlattr *action)
+ const struct nlattr *action,
+ bool may_steal OVS_UNUSED)
{
dpif_execute_helper_execute__(aux, packet, flow,
action, NLA_ALIGN(action->nla_len));
{
struct dpif_execute_helper_aux aux;
enum odp_key_fitness fit;
- struct ofpbuf *packet;
struct flow flow;
COVERAGE_INC(dpif_execute_with_help);
aux.dpif = dpif;
aux.error = 0;
- packet = ofpbuf_clone_with_headroom(execute->packet, VLAN_HEADER_LEN);
- odp_execute_actions(&aux, packet, &flow,
+ odp_execute_actions(&aux, execute->packet, &flow,
execute->actions, execute->actions_len,
dpif_execute_helper_output_cb,
dpif_execute_helper_userspace_cb);
- ofpbuf_delete(packet);
-
return aux.error;
}
* OVS_ACTION_ATTR_USERSPACE actions it passes the packet through to the dpif
* implementation.
*
+ * This works even if 'actions_len' is too long for a Netlink attribute.
+ *
* Returns 0 if successful, otherwise a positive errno value. */
int
dpif_execute(struct dpif *dpif,
const struct nlattr *key, size_t key_len,
const struct nlattr *actions, size_t actions_len,
- const struct ofpbuf *buf,
- bool needs_help)
+ struct ofpbuf *buf, bool needs_help)
{
struct dpif_execute execute;
execute.actions = actions;
execute.actions_len = actions_len;
execute.packet = buf;
- execute.needs_help = needs_help;
+ execute.needs_help = needs_help || nl_attr_oversized(actions_len);
return dpif_execute__(dpif, &execute);
}
break;
default:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
}
}
* '*upcall', using 'buf' for storage. Should only be called if
* dpif_recv_set() has been used to enable receiving packets on 'dpif'.
*
- * 'upcall->packet' and 'upcall->key' point into data in the caller-provided
- * 'buf', so their memory cannot be freed separately from 'buf'. (This is
- * hardly a great way to do things but it works out OK for the dpif providers
- * and clients that exist so far.)
+ * 'upcall->key' and 'upcall->userdata' point into data in the caller-provided
+ * 'buf', so their memory cannot be freed separately from 'buf'.
+ *
+ * The caller owns the data of 'upcall->packet' and may modify it. If
+ * packet's headroom is exhausted as it is manipulated, 'upcall->packet'
+ * will be reallocated. This requires the data of 'upcall->packet' to be
+ * released with ofpbuf_uninit() before 'upcall' is destroyed. However,
+ * when an error is returned, the 'upcall->packet' may be uninitialized
+ * and should not be released.
*
* Returns 0 if successful, otherwise a positive errno value. Returns EAGAIN
* if no upcall is immediately available. */
struct ds flow;
char *packet;
- packet = ofp_packet_to_string(upcall->packet->data,
- upcall->packet->size);
+ packet = ofp_packet_to_string(upcall->packet.data,
+ upcall->packet.size);
ds_init(&flow);
odp_flow_key_format(upcall->key, upcall->key_len, &flow);