@@ -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;
}
@@ -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;
}
@@ -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",
@@ -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)
@@ -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
'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(-)