On 14/04/2017 04:08, Joe Stringer wrote:
On 7 April 2017 at 06:12, Roi Dayan <[email protected]> wrote:
From: Paul Blakey <[email protected]>

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 <[email protected]>
Reviewed-by: Roi Dayan <[email protected]>
Reviewed-by: Simon Horman <[email protected]>
---

<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.

we'll check it. can also use maybe the other logging functions as well (put/del/get). Need to modify to use the actual current module for logging instead of the static this_module else everything will be logged as the dpif module.



+{
+        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?

fixed.


+        }
+
+        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
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to