diff options
| author | Ben Pfaff <blp@nicira.com> | 2010-12-28 10:39:52 -0800 |
|---|---|---|
| committer | Ben Pfaff <blp@nicira.com> | 2011-01-27 21:08:35 -0800 |
| commit | 704a1e09e9b31ea39ca41c028c7c6aaf2482283a (patch) | |
| tree | d270596243806665073b1773c2ee5f81ddc8abd0 /lib/dpif-provider.h | |
| parent | c662c789ed30a1e122967d5d183558e1bfe755a8 (diff) | |
| download | openvswitch-704a1e09e9b31ea39ca41c028c7c6aaf2482283a.tar.gz | |
datapath: Change listing flows to use an iterator concept.
One of the goals for Open vSwitch is to decouple kernel and userspace
software, so that either one can be upgraded or rolled back independent of
the other. To do this in full generality, it must be possible to change
the kernel's idea of the flow key separately from the userspace version.
In turn, that means that flow keys must become variable-length. This does
not, however, fit in well with the ODP_FLOW_LIST ioctl in its current form,
because that would require userspace to know how much space to allocate
for each flow's key in advance, or to allocate as much space as could
possibly be needed. Neither choice is very attractive.
This commit prepares for a different solution, by replacing ODP_FLOW_LIST
by a new ioctl ODP_FLOW_DUMP that retrieves a single flow from the datapath
on each call. It is much cleaner to allocate the maximum amount of space
for a single flow key than to do so for possibly a very large number of
flow keys.
As a side effect, this patch also fixes a race condition that sometimes
made "ovs-dpctl dump-flows" print an error: previously, flows were listed
and then their actions were retrieved, which left a window in which
ovs-vswitchd could delete the flow. Now dumping a flow and its actions is
a single step, closing that window.
Dumping all of the flows in a datapath is no longer an atomic step, so now
it is possible to miss some flows or see a single flow twice during
iteration, if the flow table is modified by another process. It doesn't
look like this should be a problem for ovs-vswitchd.
It would be faster to retrieve a number of flows in batch instead of just
one at a time, but that will naturally happen later when the kernel
datapath interface is changed to use Netlink, so this patch does not bother
with it.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
Diffstat (limited to 'lib/dpif-provider.h')
| -rw-r--r-- | lib/dpif-provider.h | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index deb3bf283..6b66a5dcd 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -240,12 +240,33 @@ struct dpif_class { * packets. */ int (*flow_flush)(struct dpif *dpif); - /* Stores up to 'n' flows in 'dpif' into 'flows', updating their statistics - * and actions as described under the flow_get member function. If - * successful, returns the number of flows actually present in 'dpif', - * which might be greater than the number stored (if 'dpif' has more than - * 'n' flows). On failure, returns a negative errno value. */ - int (*flow_list)(const struct dpif *dpif, struct odp_flow flows[], int n); + /* 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, stores a new odp_flow into 'flow' 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 once for a given iteration (but the 'flow_dump_done' + * function will be called afterward). + * + * Dumping flow actions is optional. If the caller does not want to dump + * actions it will initialize 'flow->actions' to NULL and + * 'flow->actions_len' to 0. Otherwise, 'flow->actions' points to an array + * of struct nlattr and 'flow->actions_len' contains the number of bytes of + * Netlink attributes. The implemention should fill in as many actions as + * will fit into the provided array and update 'flow->actions_len' with the + * number of bytes required (regardless of whether they fit in the provided + * space). */ + int (*flow_dump_next)(const struct dpif *dpif, void *state, + struct odp_flow *flow); + + /* 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'. */ |
