diff mbox series

[ovs-dev,RFC,2/2] netdev-offload: Disallow offloading tounrelated vports.

Message ID 20190513143931.26598-3-i.maximets@samsung.com
State RFC
Headers show
Series netdev-offload: Prerequisites of vportoffloading via DPDK. | expand

Commit Message

Ilya Maximets May 13, 2019, 2:39 p.m. UTC
'linux_tc' flow API suitable only for vports with backing linux
interfaces. DPDK flow API is not suitable for such ports.

With this change we could drop vport restriction from dpif-netdev.

This is a prerequisite for enabling vport offloading in DPDK.

Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
---
 lib/dpif-netdev.c         |  2 +-
 lib/netdev-offload-dpdk.c |  8 ++++++++
 lib/netdev-offload-tc.c   |  8 ++++++++
 lib/netdev-vport.c        | 31 +++++++++++++++++++++++++++++++
 lib/netdev-vport.h        |  1 +
 5 files changed, 49 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 6165cd983..b17b19a2b 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -2382,7 +2382,7 @@  dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload)
 
     ovs_mutex_lock(&pmd->dp->port_mutex);
     port = dp_netdev_lookup_port(pmd->dp, in_port);
-    if (!port || netdev_vport_is_vport_class(port->netdev->netdev_class)) {
+    if (!port) {
         ovs_mutex_unlock(&pmd->dp->port_mutex);
         goto err_free;
     }
diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
index 01e900461..b7b0616ec 100644
--- a/lib/netdev-offload-dpdk.c
+++ b/lib/netdev-offload-dpdk.c
@@ -22,6 +22,7 @@ 
 #include "dpif-netdev.h"
 #include "netdev-offload-provider.h"
 #include "netdev-provider.h"
+#include "netdev-vport.h"
 #include "openvswitch/match.h"
 #include "openvswitch/vlog.h"
 #include "packets.h"
@@ -752,6 +753,13 @@  netdev_offload_dpdk_flow_del(struct netdev *netdev, const ovs_u128 *ufid,
 static int
 netdev_offload_dpdk_init_flow_api(struct netdev *netdev)
 {
+    if (netdev_vport_is_vport_class(netdev->netdev_class)
+        && netdev_vport_has_system_port(netdev)) {
+        VLOG_DBG("%s: vport has backing system interface. Skipping.",
+                 netdev_get_name(netdev));
+        return EOPNOTSUPP;
+    }
+
     return netdev_dpdk_flow_api_supported(netdev) ? 0 : EOPNOTSUPP;
 }
 
diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index 498aae369..e4d121ed7 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -31,6 +31,7 @@ 
 #include "netdev-linux.h"
 #include "netdev-offload-provider.h"
 #include "netdev-provider.h"
+#include "netdev-vport.h"
 #include "netlink.h"
 #include "netlink-socket.h"
 #include "odp-netlink.h"
@@ -1560,6 +1561,13 @@  netdev_tc_init_flow_api(struct netdev *netdev)
     int ifindex;
     int error;
 
+    if (netdev_vport_is_vport_class(netdev->netdev_class)
+        && !netdev_vport_has_system_port(netdev)) {
+        VLOG_DBG("%s: vport has no backing system interface. Skipping.",
+                 netdev_get_name(netdev));
+        return EOPNOTSUPP;
+    }
+
     ifindex = netdev_get_ifindex(netdev);
     if (ifindex < 0) {
         VLOG_INFO("init: failed to get ifindex for %s: %s",
diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
index 92a256af1..1c88a91ed 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -44,6 +44,7 @@ 
 #include "simap.h"
 #include "smap.h"
 #include "socket-util.h"
+#include "sset.h"
 #include "unaligned.h"
 #include "unixctl.h"
 #include "openvswitch/vlog.h"
@@ -120,6 +121,36 @@  netdev_vport_class_get_dpif_port(const struct netdev_class *class)
     return is_vport_class(class) ? vport_class_cast(class)->dpif_port : NULL;
 }
 
+bool
+netdev_vport_has_system_port(const struct netdev *netdev)
+{
+    bool found = false;
+    const char *name;
+    const char *type = "system";
+    struct sset names = SSET_INITIALIZER(&names);
+
+    ovs_assert(is_vport_class(netdev_get_class(netdev)));
+
+    dp_enumerate_names(type, &names);
+    SSET_FOR_EACH (name, &names) {
+        struct dpif *dpifp = NULL;
+
+        if (dpif_open(name, type, &dpifp)) {
+            continue;
+        }
+
+        found = dpif_port_exists(dpifp, netdev_get_name(netdev));
+
+        dpif_close(dpifp);
+        if (found) {
+            break;
+        }
+    }
+    sset_destroy(&names);
+
+    return found;
+}
+
 const char *
 netdev_vport_get_dpif_port(const struct netdev *netdev,
                            char namebuf[], size_t bufsize)
diff --git a/lib/netdev-vport.h b/lib/netdev-vport.h
index 9d756a265..4be1b92ec 100644
--- a/lib/netdev-vport.h
+++ b/lib/netdev-vport.h
@@ -40,6 +40,7 @@  void netdev_vport_inc_tx(const struct netdev *,
                          const struct dpif_flow_stats *);
 
 bool netdev_vport_is_vport_class(const struct netdev_class *);
+bool netdev_vport_has_system_port(const struct netdev *);
 const char *netdev_vport_class_get_dpif_port(const struct netdev_class *);
 
 #ifndef _WIN32