Remove hardware offload logic from the dpif-netlink implementation.
This is now handled by the dpif-offload provider as part of the
dpif_operate() function, i.e., it has been moved up one layer.

Signed-off-by: Eelco Chaudron <echau...@redhat.com>
---
 lib/dpif-netdev.c   |   3 +-
 lib/dpif-netlink.c  | 337 +-------------------------------------------
 lib/dpif-provider.h |   7 +-
 lib/dpif.c          |   5 +-
 4 files changed, 8 insertions(+), 344 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index b3127dae6..a7df5119f 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -4709,8 +4709,7 @@ dpif_netdev_execute(struct dpif *dpif, struct 
dpif_execute *execute)
 }
 
 static void
-dpif_netdev_operate(struct dpif *dpif, struct dpif_op **ops, size_t n_ops,
-                    enum dpif_offload_type offload_type OVS_UNUSED)
+dpif_netdev_operate(struct dpif *dpif, struct dpif_op **ops, size_t n_ops)
 {
     size_t i;
 
diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index e61fbc0c5..222dc8336 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -1722,66 +1722,6 @@ dpif_netlink_flow_to_dpif_flow(struct dpif_flow 
*dpif_flow,
     dpif_flow->attrs.dp_extra_info = NULL;
 }
 
-static int
-dpif_netlink_netdev_match_to_dpif_flow(struct match *match,
-                                       struct ofpbuf *key_buf,
-                                       struct ofpbuf *mask_buf,
-                                       struct nlattr *actions,
-                                       struct dpif_flow_stats *stats,
-                                       struct dpif_flow_attrs *attrs,
-                                       ovs_u128 *ufid,
-                                       struct dpif_flow *flow,
-                                       bool terse)
-{
-    memset(flow, 0, sizeof *flow);
-
-    if (!terse) {
-        struct odp_flow_key_parms odp_parms = {
-            .flow = &match->flow,
-            .mask = &match->wc.masks,
-            .support = {
-                .max_vlan_headers = 2,
-                .recirc = true,
-                .ct_state = true,
-                .ct_zone = true,
-                .ct_mark = true,
-                .ct_label = true,
-            },
-        };
-        size_t offset;
-
-        /* Key */
-        offset = key_buf->size;
-        flow->key = ofpbuf_tail(key_buf);
-        odp_flow_key_from_flow(&odp_parms, key_buf);
-        flow->key_len = key_buf->size - offset;
-
-        /* Mask */
-        offset = mask_buf->size;
-        flow->mask = ofpbuf_tail(mask_buf);
-        odp_parms.key_buf = key_buf;
-        odp_flow_key_from_mask(&odp_parms, mask_buf);
-        flow->mask_len = mask_buf->size - offset;
-
-        /* Actions */
-        flow->actions = nl_attr_get(actions);
-        flow->actions_len = nl_attr_get_size(actions);
-    }
-
-    /* Stats */
-    memcpy(&flow->stats, stats, sizeof *stats);
-
-    /* UFID */
-    flow->ufid_present = true;
-    flow->ufid = *ufid;
-
-    flow->pmd_id = PMD_ID_NULL;
-
-    memcpy(&flow->attrs, attrs, sizeof *attrs);
-
-    return 0;
-}
-
 static int
 dpif_netlink_flow_dump_next(struct dpif_flow_dump_thread *thread_,
                             struct dpif_flow *flows, int max_flows)
@@ -2062,224 +2002,11 @@ dpif_netlink_operate__(struct dpif_netlink *dpif,
     return n_ops;
 }
 
-static int
-parse_flow_get(struct dpif_netlink *dpif, struct dpif_flow_get *get)
-{
-    const char *dpif_type_str = dpif_normalize_type(dpif_type(&dpif->dpif));
-    struct dpif_flow *dpif_flow = get->flow;
-    struct match match;
-    struct nlattr *actions;
-    struct dpif_flow_stats stats;
-    struct dpif_flow_attrs attrs;
-    struct ofpbuf buf;
-    uint64_t act_buf[1024 / 8];
-    struct odputil_keybuf maskbuf;
-    struct odputil_keybuf keybuf;
-    struct odputil_keybuf actbuf;
-    struct ofpbuf key, mask, act;
-    int err;
-
-    ofpbuf_use_stack(&buf, &act_buf, sizeof act_buf);
-    err = netdev_ports_flow_get(dpif_type_str, &match, &actions, get->ufid,
-                                &stats, &attrs, &buf);
-    if (err) {
-        return err;
-    }
-
-    VLOG_DBG("found flow from netdev, translating to dpif flow");
-
-    ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
-    ofpbuf_use_stack(&act, &actbuf, sizeof actbuf);
-    ofpbuf_use_stack(&mask, &maskbuf, sizeof maskbuf);
-    dpif_netlink_netdev_match_to_dpif_flow(&match, &key, &mask, actions,
-                                           &stats, &attrs,
-                                           (ovs_u128 *) get->ufid,
-                                           dpif_flow,
-                                           false);
-    ofpbuf_put(get->buffer, nl_attr_get(actions), nl_attr_get_size(actions));
-    dpif_flow->actions = ofpbuf_at(get->buffer, 0, 0);
-    dpif_flow->actions_len = nl_attr_get_size(actions);
-
-    return 0;
-}
-
-static int
-parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
-{
-    const char *dpif_type_str = dpif_normalize_type(dpif_type(&dpif->dpif));
-    static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
-    struct match match;
-    odp_port_t in_port;
-    const struct nlattr *nla;
-    size_t left;
-    struct netdev *dev;
-    struct offload_info info;
-    int err;
-
-    info.tc_modify_flow_deleted = false;
-    if (put->flags & DPIF_FP_PROBE) {
-        return EOPNOTSUPP;
-    }
-
-    err = parse_key_and_mask_to_match(put->key, put->key_len, put->mask,
-                                      put->mask_len, &match);
-    if (err) {
-        return err;
-    }
-
-    in_port = match.flow.in_port.odp_port;
-    dev = netdev_ports_get(in_port, dpif_type_str);
-    if (!dev) {
-        return EOPNOTSUPP;
-    }
-
-    /* Check the output port for a tunnel. */
-    NL_ATTR_FOR_EACH(nla, left, put->actions, put->actions_len) {
-        if (nl_attr_type(nla) == OVS_ACTION_ATTR_OUTPUT) {
-            struct netdev *outdev;
-            odp_port_t out_port;
-
-            out_port = nl_attr_get_odp_port(nla);
-            outdev = netdev_ports_get(out_port, dpif_type_str);
-            if (!outdev) {
-                err = EOPNOTSUPP;
-                goto out;
-            }
-            netdev_close(outdev);
-        }
-    }
-
-    info.recirc_id_shared_with_tc = (dpif->user_features
-                                     & OVS_DP_F_TC_RECIRC_SHARING);
-    err = netdev_flow_put(dev, &match,
-                          CONST_CAST(struct nlattr *, put->actions),
-                          put->actions_len,
-                          CONST_CAST(ovs_u128 *, put->ufid),
-                          &info, put->stats);
-
-    if (!err) {
-        if (put->flags & DPIF_FP_MODIFY) {
-            struct dpif_op *opp;
-            struct dpif_op op;
-
-            op.type = DPIF_OP_FLOW_DEL;
-            op.flow_del.key = put->key;
-            op.flow_del.key_len = put->key_len;
-            op.flow_del.ufid = put->ufid;
-            op.flow_del.pmd_id = put->pmd_id;
-            op.flow_del.stats = NULL;
-            op.flow_del.terse = false;
-
-            opp = &op;
-            dpif_netlink_operate__(dpif, &opp, 1);
-        }
-
-        VLOG_DBG("added flow");
-    } else if (err != EEXIST) {
-        struct netdev *oor_netdev = NULL;
-        enum vlog_level level;
-        if (err == ENOSPC
-            && dpif_offload_is_offload_rebalance_policy_enabled()) {
-            /*
-             * We need to set OOR on the input netdev (i.e, 'dev') for the
-             * flow. But if the flow has a tunnel attribute (i.e, decap action,
-             * with a virtual device like a VxLAN interface as its in-port),
-             * then lookup and set OOR on the underlying tunnel (real) netdev.
-             */
-            oor_netdev = flow_get_tunnel_netdev(&match.flow.tunnel);
-            if (!oor_netdev) {
-                /* Not a 'tunnel' flow */
-                oor_netdev = dev;
-            }
-            netdev_set_hw_info(oor_netdev, HW_INFO_TYPE_OOR, true);
-        }
-        level = (err == ENOSPC || err == EOPNOTSUPP) ? VLL_DBG : VLL_ERR;
-        VLOG_RL(&rl, level, "failed to offload flow: %s: %s",
-                ovs_strerror(err),
-                (oor_netdev ? oor_netdev->name : dev->name));
-    }
-
-out:
-    if (err && err != EEXIST && (put->flags & DPIF_FP_MODIFY)) {
-        /* Modified rule can't be offloaded, try and delete from HW */
-        int del_err = 0;
-
-        if (!info.tc_modify_flow_deleted) {
-            del_err = netdev_flow_del(dev, put->ufid, put->stats);
-        }
-
-        if (!del_err) {
-            /* Delete from hw success, so old flow was offloaded.
-             * Change flags to create the flow in kernel */
-            put->flags &= ~DPIF_FP_MODIFY;
-            put->flags |= DPIF_FP_CREATE;
-        } else if (del_err != ENOENT && del_err != EOPNOTSUPP) {
-            VLOG_ERR_RL(&rl, "failed to delete offloaded flow: %s",
-                        ovs_strerror(del_err));
-            /* stop proccesing the flow in kernel */
-            err = 0;
-        }
-    }
-
-    netdev_close(dev);
-
-    return err;
-}
-
-static int
-try_send_to_netdev(struct dpif_netlink *dpif, struct dpif_op *op)
-{
-    int err = EOPNOTSUPP;
-
-    switch (op->type) {
-    case DPIF_OP_FLOW_PUT: {
-        struct dpif_flow_put *put = &op->flow_put;
-
-        if (!put->ufid) {
-            break;
-        }
-
-        err = parse_flow_put(dpif, put);
-        log_flow_put_message(&dpif->dpif, &this_module, put, 0);
-        break;
-    }
-    case DPIF_OP_FLOW_DEL: {
-        struct dpif_flow_del *del = &op->flow_del;
-
-        if (!del->ufid) {
-            break;
-        }
-
-        err = netdev_ports_flow_del(
-                                dpif_normalize_type(dpif_type(&dpif->dpif)),
-                                del->ufid,
-                                del->stats);
-        log_flow_del_message(&dpif->dpif, &this_module, del, 0);
-        break;
-    }
-    case DPIF_OP_FLOW_GET: {
-        struct dpif_flow_get *get = &op->flow_get;
-
-        if (!op->flow_get.ufid) {
-            break;
-        }
-
-        err = parse_flow_get(dpif, get);
-        log_flow_get_message(&dpif->dpif, &this_module, get, 0);
-        break;
-    }
-    case DPIF_OP_EXECUTE:
-    default:
-        break;
-    }
-
-    return err;
-}
-
 static void
-dpif_netlink_operate_chunks(struct dpif_netlink *dpif, struct dpif_op **ops,
-                            size_t n_ops)
+dpif_netlink_operate(struct dpif *dpif_, struct dpif_op **ops, size_t n_ops)
 {
+    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
+
     while (n_ops > 0) {
         size_t chunk = dpif_netlink_operate__(dpif, ops, n_ops);
 
@@ -2288,64 +2015,6 @@ dpif_netlink_operate_chunks(struct dpif_netlink *dpif, 
struct dpif_op **ops,
     }
 }
 
-static void
-dpif_netlink_operate(struct dpif *dpif_, struct dpif_op **ops, size_t n_ops,
-                     enum dpif_offload_type offload_type)
-{
-    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 (offload_type == DPIF_OFFLOAD_ALWAYS
-        && !dpif_offload_is_offload_enabled()) {
-        VLOG_DBG("Invalid offload_type: %d", offload_type);
-        return;
-    }
-
-    if (offload_type != DPIF_OFFLOAD_NEVER
-        && dpif_offload_is_offload_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) {
-                    if (offload_type == DPIF_OFFLOAD_ALWAYS) {
-                        /* We got an error while offloading an op. Since
-                         * OFFLOAD_ALWAYS is specified, we stop further
-                         * processing and return to the caller without
-                         * invoking kernel datapath as fallback. But the
-                         * interface requires us to process all n_ops; so
-                         * return the same error in the remaining ops too.
-                         */
-                        op->error = err;
-                        n_ops--;
-                        while (n_ops > 0) {
-                            op = ops[i++];
-                            op->error = err;
-                            n_ops--;
-                        }
-                        return;
-                    }
-                    new_ops[count++] = op;
-                } else {
-                    op->error = err;
-                }
-
-                n_ops--;
-            }
-
-            dpif_netlink_operate_chunks(dpif, new_ops, count);
-        }
-    } else if (offload_type != DPIF_OFFLOAD_ALWAYS) {
-        dpif_netlink_operate_chunks(dpif, ops, n_ops);
-    }
-}
-
 #if _WIN32
 static void
 dpif_netlink_handler_uninit(struct dpif_handler *handler)
diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h
index d27ad5165..e1c91caff 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -363,11 +363,8 @@ struct dpif_class {
     /* Executes each of the 'n_ops' operations in 'ops' on 'dpif', in the order
      * in which they are specified, placing each operation's results in the
      * "output" members documented in comments and the 'error' member of each
-     * dpif_op. The offload_type argument tells the provider if 'ops' should
-     * be submitted to to a netdev (only offload) or to the kernel datapath
-     * (never offload) or to both (offload if possible; software fallback). */
-    void (*operate)(struct dpif *dpif, struct dpif_op **ops, size_t n_ops,
-                    enum dpif_offload_type offload_type);
+     * dpif_op. */
+    void (*operate)(struct dpif *dpif, struct dpif_op **ops, size_t n_ops);
 
     /* Get hardware-offloads activity counters from a dataplane.
      * Those counters are not offload statistics (which are accessible through
diff --git a/lib/dpif.c b/lib/dpif.c
index c294b79ae..c8b73ca0e 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -1418,12 +1418,11 @@ dpif_operate(struct dpif *dpif, struct dpif_op **ops, 
size_t n_ops,
                 ops_left = dpif_offload_operate(dpif, ops_copy, chunk,
                                                 offload_type);
                 if (ops_left) {
-                    dpif->dpif_class->operate(dpif, ops_copy, ops_left,
-                                              offload_type);
+                    dpif->dpif_class->operate(dpif, ops_copy, ops_left);
                 }
                 free(ops_copy);
             } else {
-                dpif->dpif_class->operate(dpif, ops, chunk, offload_type);
+                dpif->dpif_class->operate(dpif, ops, chunk);
             }
 
             for (i = 0; i < chunk; i++) {
-- 
2.50.1

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to