- /* Attempts to begin dumping the flows in a dpif. On success, returns 0
- * and initializes '*statep' with any data needed for iteration. On
- * failure, returns a positive errno value. */
- int (*flow_dump_start)(const struct dpif *dpif, void **statep);
-
- /* Attempts to retrieve another flow from 'dpif' for 'state', which was
- * initialized by a successful call to the 'flow_dump_start' function for
- * 'dpif'. On success, updates the output parameters as described below
- * and returns 0. Returns EOF if the end of the flow table has been
- * reached, or a positive errno value on error. This function will not be
- * called again once it returns nonzero within a given iteration (but the
- * 'flow_dump_done' function will be called afterward).
- *
- * On success, if 'key' and 'key_len' are nonnull then '*key' and
- * '*key_len' must be set to Netlink attributes with types ODP_KEY_ATTR_*
- * representing the dumped flow's key. If 'actions' and 'actions_len' are
- * nonnull then they should be set to Netlink attributes with types ODPAT_*
- * representing the dumped flow's actions. If 'stats' is nonnull then it
- * should be set to the dumped flow's statistics.
- *
- * All of the returned data is owned by 'dpif', not by the caller, and the
- * caller must not modify or free it. 'dpif' must guarantee that it
- * remains accessible and unchanging until at least the next call to
- * 'flow_dump_next' or 'flow_dump_done' for 'state'. */
- int (*flow_dump_next)(const struct dpif *dpif, void *state,
- const struct nlattr **key, size_t *key_len,
- const struct nlattr **actions, size_t *actions_len,
- const struct dpif_flow_stats **stats);
-
- /* Releases resources from 'dpif' for 'state', which was initialized by a
- * successful call to the 'flow_dump_start' function for 'dpif'. */
- int (*flow_dump_done)(const struct dpif *dpif, void *state);
-
- /* Performs the 'actions_len' bytes of actions in 'actions' on the Ethernet
- * frame specified in 'packet'. */
- int (*execute)(struct dpif *dpif, const struct nlattr *actions,
- size_t actions_len, const struct ofpbuf *packet);
-
- /* 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'
- * function is called. */
- int (*recv_get_mask)(const struct dpif *dpif, int *listen_mask);
-
- /* 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. */
- int (*recv_set_mask)(struct dpif *dpif, int listen_mask);
-
- /* Retrieves 'dpif''s sFlow sampling probability into '*probability'.
- * Return value is 0 or a positive errno value. EOPNOTSUPP indicates that
- * the datapath does not support sFlow, as does a null pointer.
- *
- * '*probability' is expressed as the number of packets out of UINT_MAX to
- * sample, e.g. probability/UINT_MAX is the probability of sampling a given
- * packet. */
- int (*get_sflow_probability)(const struct dpif *dpif,
- uint32_t *probability);
-
- /* Sets 'dpif''s sFlow sampling probability to 'probability'. Return value
- * is 0 or a positive errno value. EOPNOTSUPP indicates that the datapath
- * does not support sFlow, as does a null pointer.
- *
- * 'probability' is expressed as the number of packets out of UINT_MAX to
- * sample, e.g. probability/UINT_MAX is the probability of sampling a given
- * packet. */
- int (*set_sflow_probability)(struct dpif *dpif, uint32_t probability);
+ /* Flow dumping interface.
+ *
+ * This is the back-end for the flow dumping interface described in
+ * dpif.h. Please read the comments there first, because this code
+ * closely follows it.
+ *
+ * 'flow_dump_create' and 'flow_dump_thread_create' must always return an
+ * initialized and usable data structure and defer error return until
+ * flow_dump_destroy(). This hasn't been a problem for the dpifs that
+ * exist so far.
+ *
+ * 'flow_dump_create' and 'flow_dump_thread_create' must initialize the
+ * structures that they return with dpif_flow_dump_init() and
+ * dpif_flow_dump_thread_init(), respectively.
+ *
+ * If 'terse' is true, then only UID and statistics will
+ * be returned in the dump. Otherwise, all fields will be returned. */
+ struct dpif_flow_dump *(*flow_dump_create)(const struct dpif *dpif,
+ bool terse);
+ int (*flow_dump_destroy)(struct dpif_flow_dump *dump);
+
+ struct dpif_flow_dump_thread *(*flow_dump_thread_create)(
+ struct dpif_flow_dump *dump);
+ void (*flow_dump_thread_destroy)(struct dpif_flow_dump_thread *thread);
+
+ int (*flow_dump_next)(struct dpif_flow_dump_thread *thread,
+ struct dpif_flow *flows, int max_flows);
+
+ /* 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 and the 'error' member of each
+ * dpif_op. */
+ void (*operate)(struct dpif *dpif, struct dpif_op **ops, size_t n_ops);
+
+ /* Enables or disables receiving packets with dpif_recv() for 'dpif'.
+ * Turning packet receive 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)(struct dpif *dpif, bool enable);
+
+ /* Refreshes the poll loops and Netlink sockets associated to each port,
+ * when the number of upcall handlers (upcall receiving thread) is changed
+ * to 'n_handlers' and receiving packets for 'dpif' is enabled by
+ * recv_set().
+ *
+ * Since multiple upcall handlers can read upcalls simultaneously from
+ * 'dpif', each port can have multiple Netlink sockets, one per upcall
+ * handler. So, handlers_set() is responsible for the following tasks:
+ *
+ * When receiving upcall is enabled, extends or creates the
+ * configuration to support:
+ *
+ * - 'n_handlers' Netlink sockets for each port.
+ *
+ * - 'n_handlers' poll loops, one for each upcall handler.
+ *
+ * - registering the Netlink sockets for the same upcall handler to
+ * the corresponding poll loop.
+ * */
+ int (*handlers_set)(struct dpif *dpif, uint32_t n_handlers);
+
+ /* If 'dpif' creates its own I/O polling threads, refreshes poll threads
+ * configuration. 'n_rxqs' configures the number of rx_queues, which
+ * are distributed among threads. 'cmask' configures the cpu mask
+ * for setting the polling threads' cpu affinity. */
+ int (*poll_threads_set)(struct dpif *dpif, unsigned int n_rxqs,
+ const char *cmask);