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

Reply via email to