void (*wait)(struct dpif *dpif);
/* Retrieves statistics for 'dpif' into 'stats'. */
- int (*get_stats)(const struct dpif *dpif, struct ovs_dp_stats *stats);
-
- /* Retrieves 'dpif''s current treatment of IP fragments into '*drop_frags':
- * true indicates that fragments are dropped, false indicates that
- * fragments are treated in the same way as other IP packets (except that
- * the L4 header cannot be read). */
- int (*get_drop_frags)(const struct dpif *dpif, bool *drop_frags);
-
- /* Changes 'dpif''s treatment of IP fragments to 'drop_frags', whose
- * meaning is the same as for the get_drop_frags member function. */
- int (*set_drop_frags)(struct dpif *dpif, bool drop_frags);
+ int (*get_stats)(const struct dpif *dpif, struct dpif_dp_stats *stats);
/* Adds 'netdev' as a new port in 'dpif'. If successful, sets '*port_no'
* to the new port's port number. */
* actions. */
int (*get_max_ports)(const struct dpif *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'.
+ *
+ * The return value only needs to be meaningful when DPIF_UC_ACTION has
+ * been enabled in the 'dpif''s listen mask, and it is allowed to change
+ * when DPIF_UC_ACTION is disabled and then re-enabled.
+ *
+ * A dpif provider that doesn't have meaningful Netlink PIDs can use NULL
+ * for this function. This is equivalent to always returning 0. */
+ uint32_t (*port_get_pid)(const struct dpif *dpif, uint16_t port_no);
+
/* Attempts to begin dumping the ports in a dpif. On success, returns 0
* and initializes '*statep' with any data needed for iteration. On
* failure, returns a positive errno value. */
const struct nlattr *actions, size_t actions_len,
const struct ofpbuf *packet);
+ /* Executes each of the 'n_ops' operations in 'ops' on 'dpif', in the order
+ * in which they are specified, placing each operation's results in the
+ * "output" members documented in comments.
+ *
+ * This function is optional. It is only worthwhile to implement it if
+ * 'dpif' can perform operations in batch faster than individually. */
+ void (*operate)(struct dpif *dpif, union dpif_op **ops, size_t n_ops);
+
/* Retrieves 'dpif''s "listen mask" into '*listen_mask'. A 1-bit of value
* 2**X set in '*listen_mask' indicates that 'dpif' will receive messages
* of the type (from "enum dpif_upcall_type") with value X when its 'recv'
/* Sets 'dpif''s "listen mask" to 'listen_mask'. A 1-bit of value 2**X set
* in '*listen_mask' requests that 'dpif' will receive messages of the type
* (from "enum dpif_upcall_type") with value X when its 'recv' function is
- * called. */
+ * called.
+ *
+ * Turning DPIF_UC_ACTION off and then back on is allowed to change Netlink
+ * PID assignments (see ->port_get_pid()). The client is responsible for
+ * updating flows as necessary if it does this. */
int (*recv_set_mask)(struct dpif *dpif, int listen_mask);
/* Translates OpenFlow queue ID 'queue_id' (in host byte order) into a
- * priority value for use in the OVS_ACTION_ATTR_SET_PRIORITY action in
- * '*priority'. */
+ * priority value used for setting packet priority. */
int (*queue_to_priority)(const struct dpif *dpif, uint32_t queue_id,
uint32_t *priority);