Woops, I forgot to indicate that this series is for branch-2.3.
On 3 July 2014 12:29, Joe Stringer <joestrin...@nicira.com> wrote: > Change the interface to allow implementations to pass back a buffer, and > allow callers to specify which of actions, mask, and stats they wish to > receive. This will be used in the next commit. > > Signed-off-by: Joe Stringer <joestrin...@nicira.com> > --- > lib/dpif-linux.c | 23 +++++++++++++---------- > lib/dpif-netdev.c | 30 +++++++++++++++++++++++++----- > lib/dpif-provider.h | 21 ++++++++++++++++----- > lib/dpif.c | 43 +++++++++++++++++++++++++++++++------------ > lib/dpif.h | 5 ++++- > 5 files changed, 89 insertions(+), 33 deletions(-) > > diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c > index 6a8564a..93154a3 100644 > --- a/lib/dpif-linux.c > +++ b/lib/dpif-linux.c > @@ -1041,24 +1041,27 @@ dpif_linux_flow_get__(const struct dpif_linux > *dpif, > static int > dpif_linux_flow_get(const struct dpif *dpif_, > const struct nlattr *key, size_t key_len, > - struct ofpbuf **actionsp, struct dpif_flow_stats > *stats) > + struct ofpbuf **bufp, > + struct nlattr **maskp, size_t *mask_len, > + struct nlattr **actionsp, size_t *actions_len, > + struct dpif_flow_stats *stats) > { > const struct dpif_linux *dpif = dpif_linux_cast(dpif_); > struct dpif_linux_flow reply; > - struct ofpbuf *buf; > int error; > > - error = dpif_linux_flow_get__(dpif, key, key_len, &reply, &buf); > + error = dpif_linux_flow_get__(dpif, key, key_len, &reply, bufp); > if (!error) { > - if (stats) { > - dpif_linux_flow_get_stats(&reply, stats); > + if (maskp) { > + *maskp = CONST_CAST(struct nlattr *, reply.mask); > + *mask_len = reply.mask_len; > } > if (actionsp) { > - ofpbuf_set_data(buf, CONST_CAST(struct nlattr *, > reply.actions)); > - ofpbuf_set_size(buf, reply.actions_len); > - *actionsp = buf; > - } else { > - ofpbuf_delete(buf); > + *actionsp = CONST_CAST(struct nlattr *, reply.actions); > + *actions_len = reply.actions_len; > + } > + if (stats) { > + dpif_linux_flow_get_stats(&reply, stats); > } > } > return error; > diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c > index fdf1af4..2a078f3 100644 > --- a/lib/dpif-netdev.c > +++ b/lib/dpif-netdev.c > @@ -1191,7 +1191,10 @@ dpif_netdev_flow_from_nlattrs(const struct nlattr > *key, uint32_t key_len, > static int > dpif_netdev_flow_get(const struct dpif *dpif, > const struct nlattr *nl_key, size_t nl_key_len, > - struct ofpbuf **actionsp, struct dpif_flow_stats > *stats) > + struct ofpbuf **bufp, > + struct nlattr **maskp, size_t *mask_len, > + struct nlattr **actionsp, size_t *actions_len, > + struct dpif_flow_stats *stats) > { > struct dp_netdev *dp = get_dp_netdev(dpif); > struct dp_netdev_flow *netdev_flow; > @@ -1212,14 +1215,31 @@ dpif_netdev_flow_get(const struct dpif *dpif, > get_dpif_flow_stats(netdev_flow, stats); > } > > - if (actionsp) { > - struct dp_netdev_actions *actions; > + if (maskp || actionsp) { > + *bufp = ofpbuf_new(1024); > + if (maskp) { > + struct flow_wildcards wc; > + > + minimask_expand(&netdev_flow->cr.match.mask, &wc); > + odp_flow_key_from_mask(*bufp, &wc.masks, > &netdev_flow->flow, > + > odp_to_u32(wc.masks.in_port.odp_port), > + SIZE_MAX); > + *maskp = ofpbuf_data(*bufp); > + *mask_len = ofpbuf_size(*bufp); > + } > + if (actionsp) { > + struct dp_netdev_actions *actions; > > - actions = dp_netdev_flow_get_actions(netdev_flow); > - *actionsp = ofpbuf_clone_data(actions->actions, > actions->size); > + actions = dp_netdev_flow_get_actions(netdev_flow); > + *actionsp = ofpbuf_push(*bufp, actions->actions, > actions->size); > + *actions_len = actions->size; > + } > + } else { > + *bufp = NULL; > } > } else { > error = ENOENT; > + *bufp = NULL; > } > > return error; > diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h > index 615f2c6..389e84e 100644 > --- a/lib/dpif-provider.h > +++ b/lib/dpif-provider.h > @@ -224,16 +224,27 @@ struct dpif_class { > * Returns 0 if successful. If no flow matches, returns ENOENT. On > other > * failure, returns a positive errno value. > * > - * If 'actionsp' is nonnull, then on success '*actionsp' must be set > to an > - * ofpbuf owned by the caller that contains the Netlink attributes > for the > - * flow's actions. The caller must free the ofpbuf (with > ofpbuf_delete()) > - * when it is no longer needed. > + * On success, '*bufp' will be set to an ofpbuf owned by the caller > that > + * contains the response for 'maskp' and 'actionsp'. The caller must > supply > + * a valid pointer, and must free the ofpbuf (with ofpbuf_delete()) > when it > + * is no longer needed. > + * > + * If 'maskp' is nonnull, then on success '*maskp' will point to the > + * Netlink attributes for the flow's mask, stored in '*bufp'. > '*mask_len' > + * will be set to the length of the mask attributes. > + * > + * If 'actionsp' is nonnull, then on success '*actionsp' will point > to the > + * Netlink attributes for the flow's actions, stored in '*bufp'. > + * '*actions_len' will be set to the length of the actions attributes. > * > * If 'stats' is nonnull, then on success it must be updated with the > * flow's statistics. */ > int (*flow_get)(const struct dpif *dpif, > const struct nlattr *key, size_t key_len, > - struct ofpbuf **actionsp, struct dpif_flow_stats > *stats); > + struct ofpbuf **bufp, > + struct nlattr **maskp, size_t *mask_len, > + struct nlattr **actionsp, size_t *acts_len, > + struct dpif_flow_stats *stats); > > /* Adds or modifies a flow in 'dpif'. The flow is specified by the > Netlink > * attributes with types OVS_KEY_ATTR_* in the 'put->key_len' bytes > diff --git a/lib/dpif.c b/lib/dpif.c > index 8ec8200..9a81765 100644 > --- a/lib/dpif.c > +++ b/lib/dpif.c > @@ -831,44 +831,63 @@ dpif_flow_flush(struct dpif *dpif) > * Returns 0 if successful. If no flow matches, returns ENOENT. On other > * failure, returns a positive errno value. > * > - * If 'actionsp' is nonnull, then on success '*actionsp' will be set to an > - * ofpbuf owned by the caller that contains the Netlink attributes for the > - * flow's actions. The caller must free the ofpbuf (with > ofpbuf_delete()) when > - * it is no longer needed. > + * On success, '*bufp' will be set to an ofpbuf owned by the caller that > + * contains the response for 'maskp' and 'actionsp'. The caller must > supply > + * a valid pointer, and must free the ofpbuf (with ofpbuf_delete()) when > it > + * is no longer needed. > + * > + * If 'maskp' is nonnull, then on success '*maskp' will point to the > + * Netlink attributes for the flow's mask, stored in '*bufp'. '*mask_len' > + * will be set to the length of the mask attributes. > + * > + * If 'actionsp' is nonnull, then on success '*actionsp' will point to the > + * Netlink attributes for the flow's actions, stored in '*bufp'. > + * '*actions_len' will be set to the length of the actions attributes. > * > * If 'stats' is nonnull, then on success it will be updated with the > flow's > * statistics. */ > int > dpif_flow_get(const struct dpif *dpif, > - const struct nlattr *key, size_t key_len, > - struct ofpbuf **actionsp, struct dpif_flow_stats *stats) > + const struct nlattr *key, size_t key_len, struct ofpbuf > **bufp, > + struct nlattr **maskp, size_t *mask_len, > + struct nlattr **actionsp, size_t *actions_len, > + struct dpif_flow_stats *stats) > { > int error; > > COVERAGE_INC(dpif_flow_get); > > - error = dpif->dpif_class->flow_get(dpif, key, key_len, actionsp, > stats); > + error = dpif->dpif_class->flow_get(dpif, key, key_len, bufp, > + maskp, mask_len, > + actionsp, actions_len, > + stats); > if (error) { > if (actionsp) { > *actionsp = NULL; > + *actions_len = 0; > + } > + if (maskp) { > + *maskp = NULL; > + *mask_len = 0; > } > if (stats) { > memset(stats, 0, sizeof *stats); > } > + ofpbuf_delete(*bufp); > } > if (should_log_flow_message(error)) { > const struct nlattr *actions; > - size_t actions_len; > + size_t acts_len; > > if (!error && actionsp) { > - actions = ofpbuf_data(*actionsp); > - actions_len = ofpbuf_size(*actionsp); > + actions = *actionsp; > + acts_len = *actions_len; > } else { > actions = NULL; > - actions_len = 0; > + acts_len = 0; > } > log_flow_message(dpif, error, "flow_get", key, key_len, > - NULL, 0, stats, actions, actions_len); > + NULL, 0, stats, actions, acts_len); > } > return error; > } > diff --git a/lib/dpif.h b/lib/dpif.h > index e7aca8e..f13cc36 100644 > --- a/lib/dpif.h > +++ b/lib/dpif.h > @@ -524,7 +524,10 @@ int dpif_flow_del(struct dpif *, > struct dpif_flow_stats *); > int dpif_flow_get(const struct dpif *, > const struct nlattr *key, size_t key_len, > - struct ofpbuf **actionsp, struct dpif_flow_stats *); > + struct ofpbuf **bufp, > + struct nlattr **maskp, size_t *mask_len, > + struct nlattr **actionsp, size_t *acts_len, > + struct dpif_flow_stats *stats); > > struct dpif_flow_dump { > const struct dpif *dpif; > -- > 1.7.10.4 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev