On 7 April 2017 at 06:12, Roi Dayan <r...@mellanox.com> wrote: > From: Paul Blakey <pa...@mellanox.com> > > Using the new netdev flow api operate will now try and > offload flows to the relevant netdev of the input port. > Other operate methods flows will come in later patches. > > Signed-off-by: Paul Blakey <pa...@mellanox.com> > Reviewed-by: Roi Dayan <r...@mellanox.com> > Reviewed-by: Simon Horman <simon.hor...@netronome.com> > ---
<snip> > static void > -dpif_netlink_operate(struct dpif *dpif_, struct dpif_op **ops, size_t n_ops) > +dbg_print_flow(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 ovs_u128 *ufid, > + const char *op) I wonder if we could refactor log_flow_message() into somewhere neutral and share the output format for these flows from here and there. > +{ > + struct ds s; > + > + ds_init(&s); > + ds_put_cstr(&s, op); > + ds_put_cstr(&s, " ("); > + odp_format_ufid(ufid, &s); > + ds_put_cstr(&s, ")"); > + if (key_len) { > + ds_put_cstr(&s, "\nflow (verbose): "); > + odp_flow_format(key, key_len, mask, mask_len, NULL, &s, true); > + ds_put_cstr(&s, "\nflow: "); > + odp_flow_format(key, key_len, mask, mask_len, NULL, &s, false); > + } > + ds_put_cstr(&s, "\nactions: "); > + format_odp_actions(&s, actions, actions_len); > + VLOG_DBG("\n%s", ds_cstr(&s)); > + ds_destroy(&s); > +} > + > +static int > +try_send_to_netdev(struct dpif_netlink *dpif, struct dpif_op *op) > { > - struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); > + switch (op->type) { > + case DPIF_OP_FLOW_PUT: { > + struct dpif_flow_put *put = &op->u.flow_put; > > + if (!put->ufid) { > + break; > + } > + dbg_print_flow(put->key, put->key_len, put->mask, put->mask_len, > + put->actions, put->actions_len, put->ufid, > + (put->flags & DPIF_FP_MODIFY ? "PUT(MODIFY)" : > "PUT")); > + return parse_flow_put(dpif, put); > + } > + case DPIF_OP_FLOW_DEL: > + case DPIF_OP_FLOW_GET: > + case DPIF_OP_EXECUTE: > + default: > + break; > + } > + return EOPNOTSUPP; > +} > + > +static void > +dpif_netlink_operate_chunks(struct dpif_netlink *dpif, struct dpif_op **ops, > + size_t n_ops) > +{ > while (n_ops > 0) { > size_t chunk = dpif_netlink_operate__(dpif, ops, n_ops); > + > ops += chunk; > n_ops -= chunk; > } > } > > +static void > +dpif_netlink_operate(struct dpif *dpif_, struct dpif_op **ops, size_t n_ops) > +{ > + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); > + struct dpif_op *new_ops[OPERATE_MAX_OPS]; > + int count = 0; > + int i = 0; > + int err = 0; > + > + if (netdev_flow_api_enabled) { > + while (n_ops > 0) { > + count = 0; > + > + while (n_ops > 0 && count < OPERATE_MAX_OPS) { > + struct dpif_op *op = ops[i++]; > + > + err = try_send_to_netdev(dpif, op); > + if (err && err != EEXIST) { > + new_ops[count++] = op; > + } else { > + op->error = err; > + } > + > + n_ops--; > + } > + > + dpif_netlink_operate_chunks(dpif, new_ops, count); > + } > + > + return; > + } > + > + dpif_netlink_operate_chunks(dpif, ops, n_ops); > +} > + > #if _WIN32 > static void > dpif_netlink_handler_uninit(struct dpif_handler *handler) > diff --git a/lib/odp-util.c b/lib/odp-util.c > index 8747778..349425e 100644 > --- a/lib/odp-util.c > +++ b/lib/odp-util.c > @@ -41,6 +41,7 @@ > #include "util.h" > #include "uuid.h" > #include "openvswitch/vlog.h" > +#include "openvswitch/match.h" > > VLOG_DEFINE_THIS_MODULE(odp_util); > > @@ -5497,6 +5498,58 @@ odp_flow_key_to_mask(const struct nlattr *mask_key, > size_t mask_key_len, > } > } > > +/* Converts the netlink formated key/mask to match. > + * Fails if odp_flow_key_from_key/mask and odp_flow_key_key/mask > + * disagree on the acceptable form of flow */ > +int > +parse_key_and_mask_to_match(const struct nlattr *key, size_t key_len, > + const struct nlattr *mask, size_t mask_len, > + struct match *match) > +{ > + enum odp_key_fitness fitness; > + > + fitness = odp_flow_key_to_flow(key, key_len, &match->flow); > + if (fitness) { > + /* This should not happen: it indicates that odp_flow_key_from_flow() > + * and odp_flow_key_to_flow() disagree on the acceptable form of a > + * flow. Log the problem as an error, with enough details to enable > + * debugging. */ > + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); > + > + if (!VLOG_DROP_ERR(&rl)) { > + struct ds s; > + > + ds_init(&s); > + odp_flow_format(key, key_len, NULL, 0, NULL, &s, true); > + VLOG_ERR("internal error parsing flow key %s", ds_cstr(&s)); > + ds_destroy(&s); > + } > + > + return EINVAL; > + } > + > + fitness = odp_flow_key_to_mask(mask, mask_len, &match->wc, &match->flow); > + if (fitness) { > + /* This should not happen: it indicates that > + * odp_flow_key_from_mask() and odp_flow_key_to_mask() > + * disagree on the acceptable form of a mask. Log the problem > + * as an error, with enough details to enable debugging. */ > + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); > + > + if (!VLOG_DROP_ERR(&rl)) { > + struct ds s; > + > + VLOG_ERR("internal error parsing flow mask %s (%s)", > + ds_cstr(&s), odp_key_fitness_to_string(fitness)); > + ds_destroy(&s); 's' is used uninitialized here? > + } > + > + return EINVAL; > + } > + > + return 0; > +} > + > /* Returns 'fitness' as a string, for use in debug messages. */ > const char * > odp_key_fitness_to_string(enum odp_key_fitness fitness) > diff --git a/lib/odp-util.h b/lib/odp-util.h > index 50fa1d1..8e5879d 100644 > --- a/lib/odp-util.h > +++ b/lib/odp-util.h > @@ -246,6 +246,9 @@ enum odp_key_fitness odp_flow_key_to_mask(const struct > nlattr *mask_key, > size_t mask_key_len, > struct flow_wildcards *mask, > const struct flow *flow); > +int parse_key_and_mask_to_match(const struct nlattr *key, size_t key_len, > + const struct nlattr *mask, size_t mask_len, > + struct match *match); > > const char *odp_key_fitness_to_string(enum odp_key_fitness); > > -- > 2.7.4 > _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev