* location.
*
* - Adding and removing ports to achieve a new configuration.
+ *
+ *
+ * Thread-safety
+ * =============
+ *
+ * Most of the dpif functions are fully thread-safe: they may be called from
+ * any number of threads on the same or different dpif objects. The exceptions
+ * are:
+ *
+ * - dpif_port_poll() and dpif_port_poll_wait() are conditionally
+ * thread-safe: they may be called from different threads only on
+ * different dpif objects.
+ *
+ * - Functions that operate on struct dpif_port_dump or struct
+ * dpif_flow_dump are conditionally thread-safe with respect to those
+ * objects. That is, one may dump ports or flows from any number of
+ * threads at once, but each thread must use its own struct dpif_port_dump
+ * or dpif_flow_dump.
*/
#ifndef DPIF_H
#define DPIF_H 1
const char *dpif_port_open_type(const char *datapath_type,
const char *port_type);
-int dpif_port_add(struct dpif *, struct netdev *, uint32_t *port_nop);
-int dpif_port_del(struct dpif *, uint32_t port_no);
+int dpif_port_add(struct dpif *, struct netdev *, odp_port_t *port_nop);
+int dpif_port_del(struct dpif *, odp_port_t port_no);
/* A port within a datapath.
*
struct dpif_port {
char *name; /* Network device name, e.g. "eth0". */
char *type; /* Network device type, e.g. "system". */
- uint32_t port_no; /* Port number within datapath. */
+ odp_port_t port_no; /* Port number within datapath. */
};
void dpif_port_clone(struct dpif_port *, const struct dpif_port *);
void dpif_port_destroy(struct dpif_port *);
bool dpif_port_exists(const struct dpif *dpif, const char *devname);
-int dpif_port_query_by_number(const struct dpif *, uint32_t port_no,
+int dpif_port_query_by_number(const struct dpif *, odp_port_t port_no,
struct dpif_port *);
int dpif_port_query_by_name(const struct dpif *, const char *devname,
struct dpif_port *);
-int dpif_port_get_name(struct dpif *, uint32_t port_no,
+int dpif_port_get_name(struct dpif *, odp_port_t port_no,
char *name, size_t name_size);
-int dpif_get_max_ports(const struct dpif *);
-uint32_t dpif_port_get_pid(const struct dpif *, uint32_t port_no);
+uint32_t dpif_get_max_ports(const struct dpif *);
+uint32_t dpif_port_get_pid(const struct dpif *, odp_port_t port_no);
struct dpif_port_dump {
const struct dpif *dpif;
int dpif_flow_flush(struct dpif *);
int dpif_flow_put(struct dpif *, enum dpif_flow_put_flags,
const struct nlattr *key, size_t key_len,
+ const struct nlattr *mask, size_t mask_len,
const struct nlattr *actions, size_t actions_len,
struct dpif_flow_stats *);
int dpif_flow_del(struct dpif *,
void dpif_flow_dump_start(struct dpif_flow_dump *, const struct dpif *);
bool dpif_flow_dump_next(struct dpif_flow_dump *,
const struct nlattr **key, size_t *key_len,
+ const struct nlattr **mask, size_t *mask_len,
const struct nlattr **actions, size_t *actions_len,
const struct dpif_flow_stats **);
int dpif_flow_dump_done(struct dpif_flow_dump *);
int dpif_execute(struct dpif *,
const struct nlattr *key, size_t key_len,
const struct nlattr *actions, size_t actions_len,
- const struct ofpbuf *);
+ const struct ofpbuf *,
+ bool needs_help);
\f
/* Operation batching interface.
*
enum dpif_flow_put_flags flags; /* DPIF_FP_*. */
const struct nlattr *key; /* Flow to put. */
size_t key_len; /* Length of 'key' in bytes. */
+ const struct nlattr *mask; /* Mask to put. */
+ size_t mask_len; /* Length of 'mask' in bytes. */
const struct nlattr *actions; /* Actions to perform on flow. */
size_t actions_len; /* Length of 'actions' in bytes. */
};
struct dpif_execute {
+ /* Raw support for execute passed along to the provider. */
const struct nlattr *key; /* Partial flow key (only for metadata). */
size_t key_len; /* Length of 'key' in bytes. */
const struct nlattr *actions; /* Actions to execute on packet. */
size_t actions_len; /* Length of 'actions' in bytes. */
const struct ofpbuf *packet; /* Packet to execute. */
+
+ /* Some dpif providers do not implement every action. The Linux kernel
+ * datapath, in particular, does not implement ARP field modification.
+ *
+ * If this member is set to true, the dpif layer executes in userspace all
+ * of the actions that it can, and for OVS_ACTION_ATTR_OUTPUT and
+ * OVS_ACTION_ATTR_USERSPACE actions it passes the packet through to the
+ * dpif implementation. */
+ bool needs_help;
};
struct dpif_op {