Calling dpif_probe_feature() should return if supported or not
without relation to the dpif name.

Signed-off-by: Roi Dayan <r...@nvidia.com>
Reviewed-by: Eli Britstein <el...@nvidia.com>
---

Notes:
    v2
    - Add back recheck support as generic to dpif.
      This required a new dpif-provider callback.
      This will allow to recheck the drop support for tc when
      hw-offload changes false->true.
      This can be removed if changing hw-offload false->true is also assumed to 
require restart.

 lib/dpif-netdev.c      |  1 +
 lib/dpif-netlink.c     | 48 +++++++++++++++++++++++++++++++++++++++++-
 lib/dpif-provider.h    |  3 +++
 lib/dpif.c             |  6 +++---
 lib/dpif.h             |  2 +-
 ofproto/ofproto-dpif.c | 14 ++++++------
 6 files changed, 62 insertions(+), 12 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 5bb48f2e5c0c..53b0c07fefc1 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -10136,6 +10136,7 @@ const struct dpif_class dpif_netdev_class = {
     NULL,                       /* cache_get_name */
     NULL,                       /* cache_get_size */
     NULL,                       /* cache_set_size */
+    NULL,                       /* recheck_support_needed */
 };
 
 static void
diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index f8850181d8b3..9e52636871df 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -756,6 +756,21 @@ dpif_netlink_run(struct dpif *dpif_)
     return false;
 }
 
+static bool
+dpif_netlink_recheck_support_needed(const struct dpif *dpif_ OVS_UNUSED)
+{
+    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
+    bool reconfigure = false;
+
+    if (netdev_is_flow_api_enabled()) {
+        if (ovsthread_once_start(&once)) {
+            reconfigure = true;
+            ovsthread_once_done(&once);
+        }
+    }
+    return reconfigure;
+}
+
 static int
 dpif_netlink_get_stats(const struct dpif *dpif_, struct dpif_dp_stats *stats)
 {
@@ -2425,6 +2440,28 @@ dpif_netlink_operate_chunks(struct dpif_netlink *dpif, 
struct dpif_op **ops,
     }
 }
 
+static bool
+dpif_netlink_is_explicit_drop_probe(struct dpif_op *op)
+{
+    struct dpif_flow_put *put = &op->flow_put;
+    const struct nlattr *nla;
+    size_t left;
+
+    if (!(op->type == DPIF_OP_FLOW_PUT &&
+        (op->flow_put.flags & DPIF_FP_PROBE))) {
+        return false;
+    }
+
+    NL_ATTR_FOR_EACH (nla, left, put->actions, put->actions_len) {
+        if (nl_attr_type(nla) == OVS_ACTION_ATTR_DROP) {
+            return true;
+        }
+        break;
+    }
+
+    return false;
+}
+
 static void
 dpif_netlink_operate(struct dpif *dpif_, struct dpif_op **ops, size_t n_ops,
                      enum dpif_offload_type offload_type)
@@ -2448,7 +2485,15 @@ dpif_netlink_operate(struct dpif *dpif_, struct dpif_op 
**ops, size_t n_ops,
                 struct dpif_op *op = ops[i++];
 
                 err = try_send_to_netdev(dpif, op);
-                if (err && err != EEXIST) {
+                /* TC does not support probing, always returns EOPNOTSUPP and
+                 * falls back to kernel openvswitch.
+                 * Explicit drop is supported in kernel openvswitch but not
+                 * in TC so fail it here because flow api is enabled.
+                 */
+                if (err == EOPNOTSUPP &&
+                    dpif_netlink_is_explicit_drop_probe(op)) {
+                    op->error = EINVAL;
+                } else 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
@@ -4579,6 +4624,7 @@ const struct dpif_class dpif_netlink_class = {
     dpif_netlink_cache_get_name,
     dpif_netlink_cache_get_size,
     dpif_netlink_cache_set_size,
+    dpif_netlink_recheck_support_needed,
 };
 
 static int
diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h
index 520e21e68db2..aa4a29418b20 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -683,6 +683,9 @@ struct dpif_class {
 
     /* Set cache size. */
     int (*cache_set_size)(struct dpif *dpif, uint32_t level, uint32_t size);
+
+    /* If 'true' recheck support of actions and attributes. */
+    bool (*recheck_support_needed)(const struct dpif *dpif);
 };
 
 extern const struct dpif_class dpif_netlink_class;
diff --git a/lib/dpif.c b/lib/dpif.c
index c22a47c3c15e..f7b8ffe0fcaa 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -1937,10 +1937,10 @@ dpif_supports_tnl_push_pop(const struct dpif *dpif)
 }
 
 bool
-dpif_may_support_explicit_drop_action(const struct dpif *dpif)
+dpif_is_recheck_support_needed(const struct dpif *dpif)
 {
-    /* TC does not support offloading this action. */
-    return dpif_is_netdev(dpif) || !netdev_is_flow_api_enabled();
+    return dpif->dpif_class->recheck_support_needed ?
+           dpif->dpif_class->recheck_support_needed(dpif) : false;
 }
 
 bool
diff --git a/lib/dpif.h b/lib/dpif.h
index a764e8a592bd..d40342914f5b 100644
--- a/lib/dpif.h
+++ b/lib/dpif.h
@@ -940,7 +940,7 @@ int dpif_get_pmds_for_port(const struct dpif * dpif, 
odp_port_t port_no,
 
 char *dpif_get_dp_version(const struct dpif *);
 bool dpif_supports_tnl_push_pop(const struct dpif *);
-bool dpif_may_support_explicit_drop_action(const struct dpif *);
+bool dpif_is_recheck_support_needed(const struct dpif *);
 bool dpif_synced_dp_layers(struct dpif *);
 
 /* Log functions. */
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 91f8f4deebd0..15cb53c115da 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -394,7 +394,8 @@ type_run(const char *type)
         udpif_set_threads(backer->udpif, n_handlers, n_revalidators);
     }
 
-    if (recheck_support_explicit_drop_action(backer)) {
+    if (dpif_is_recheck_support_needed(backer->dpif) &&
+        recheck_support_explicit_drop_action(backer)) {
         backer->need_revalidate = REV_RECONFIGURE;
     }
 
@@ -1420,8 +1421,8 @@ check_drop_action(struct dpif_backer *backer)
     ofpbuf_use_stack(&actions, &actbuf, sizeof actbuf);
     nl_msg_put_u32(&actions, OVS_ACTION_ATTR_DROP, XLATE_OK);
 
-    supported = dpif_may_support_explicit_drop_action(backer->dpif) &&
-                dpif_probe_feature(backer->dpif, "drop", &key, &actions, NULL);
+    supported = dpif_probe_feature(backer->dpif, "drop", &key, &actions,
+                                   NULL);
 
     VLOG_INFO("%s: Datapath %s explicit drop action",
               dpif_name(backer->dpif),
@@ -1769,10 +1770,9 @@ recheck_support_explicit_drop_action(struct dpif_backer 
*backer)
     atomic_read_relaxed(&backer->rt_support.explicit_drop_action,
                         &explicit_drop_action);
 
-    if (explicit_drop_action
-        && !dpif_may_support_explicit_drop_action(backer->dpif)) {
-        ovs_assert(!check_drop_action(backer));
-        atomic_store_relaxed(&backer->rt_support.explicit_drop_action, false);
+    if (explicit_drop_action && !check_drop_action(backer)) {
+        atomic_store_relaxed(&backer->rt_support.explicit_drop_action,
+                             false);
         return true;
     }
 
-- 
2.21.0

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

Reply via email to