>-----Original Message-----
>From: dev <[email protected]> On Behalf Of Eelco Chaudron
>Sent: Tuesday, 2 December 2025 16:05
>To: [email protected]
>Subject: [ovs-dev] [PATCH v2 12/41] dpif-offload: Introduce provider debug
>information API.
>
>This patch adds a new API that allows offload providers to expose free-form
>debug information. The information can be used for troubleshooting the offload
>providers state.
>
>The new API is integrated into the existing 'ovs-appctl dpif/offload/show'
>command, which now displays this debug output when available.
>
>Support for this API has been implemented for all currently supported offload
>providers.
>
>Signed-off-by: Eelco Chaudron <[email protected]>
>---
> include/openvswitch/json.h | 1 +
> lib/dpif-offload-dpdk.c | 53 ++++++++++++++++
> lib/dpif-offload-dummy.c | 55 ++++++++++++++++
> lib/dpif-offload-provider.h | 9 +++
> lib/dpif-offload-tc.c | 55 ++++++++++++++++
> lib/dpif-offload.c | 12 ++++
> lib/dpif-offload.h | 2 +
> lib/json.c | 7 +++
> ofproto/ofproto-dpif.c | 18 +++++-
> tests/ofproto-dpif.at | 104 +++++++++++++++++++++++++++++--
> tests/system-dpdk.at | 13 +++-
> tests/system-offloads-traffic.at | 33 ++++++++--
> 12 files changed, 347 insertions(+), 15 deletions(-)
>
>diff --git a/include/openvswitch/json.h b/include/openvswitch/json.h index
>134890553..ea2c4da04 100644
>--- a/include/openvswitch/json.h
>+++ b/include/openvswitch/json.h
>@@ -123,6 +123,7 @@ struct json *json_array_create_3(struct json *, struct
>json *, struct json *); bool json_array_contains_string(const struct json *,
>const
>char *);
>
> struct json *json_object_create(void);
>+bool json_object_is_empty(struct json *);
> void json_object_put(struct json *, const char *name, struct json *value);
> void
>json_object_put_nocopy(struct json *, char *name, struct json *value); void
>json_object_put_string(struct json *, diff --git a/lib/dpif-offload-dpdk.c
>b/lib/dpif-offload-dpdk.c index be33346a4..1f097bfc9 100644
>--- a/lib/dpif-offload-dpdk.c
>+++ b/lib/dpif-offload-dpdk.c
>@@ -23,6 +23,7 @@
> #include "netdev-vport.h"
> #include "util.h"
>
>+#include "openvswitch/json.h"
> #include "openvswitch/vlog.h"
>
> VLOG_DEFINE_THIS_MODULE(dpif_offload_dpdk);
>@@ -186,6 +187,57 @@ dpif_offload_dpdk_set_config(struct dpif_offload
>*offload_,
> }
> }
>
>+static bool
>+dpif_offload_dpdk_get_port_debug_ds(struct dpif_offload_port_mgr_port
>*port,
>+ void *aux) {
>+ struct ds *ds = aux;
>+
>+ ds_put_format(ds, " - %s: port_no: %u\n",
>+ netdev_get_name(port->netdev), port->port_no);
>+
>+ return false;
>+}
>+
>+static bool
>+dpif_offload_dpdk_get_port_debug_json(struct dpif_offload_port_mgr_port
>*port,
>+ void *aux) {
>+ struct json *json_port = json_object_create();
>+ struct json *json = aux;
>+
>+ json_object_put(json_port, "port_no",
>+ json_integer_create(odp_to_u32(port->port_no)));
>+
>+ json_object_put(json, netdev_get_name(port->netdev), json_port);
>+ return false;
>+}
>+
>+static void
>+dpif_offload_dpdk_get_debug(const struct dpif_offload *offload_, struct ds
>*ds,
>+ struct json *json) {
>+ struct dpif_offload_dpdk *offload =
>+dpif_offload_dpdk_cast(offload_);
>+
>+ if (json) {
>+ struct json *json_ports = json_object_create();
>+
>+ dpif_offload_port_mgr_traverse_ports(
>+ offload->port_mgr, dpif_offload_dpdk_get_port_debug_json,
>+ json_ports);
>+
>+ if (!json_object_is_empty(json_ports)) {
>+ json_object_put(json, "ports", json_ports);
>+ } else {
>+ json_destroy(json_ports);
>+ }
>+
Remove blank line. Also below occurrences.
>+ } else if (ds) {
>+ dpif_offload_port_mgr_traverse_ports(
>+ offload->port_mgr, dpif_offload_dpdk_get_port_debug_ds, ds);
>+ }
>+}
>+
> static bool
> dpif_offload_dpdk_can_offload(struct dpif_offload *offload OVS_UNUSED,
> struct netdev *netdev) @@ -208,6 +260,7 @@
> struct
>dpif_offload_class dpif_offload_dpdk_class = {
> .open = dpif_offload_dpdk_open,
> .close = dpif_offload_dpdk_close,
> .set_config = dpif_offload_dpdk_set_config,
>+ .get_debug = dpif_offload_dpdk_get_debug,
> .can_offload = dpif_offload_dpdk_can_offload,
> .port_add = dpif_offload_dpdk_port_add,
> .port_del = dpif_offload_dpdk_port_del, diff --git
> a/lib/dpif-offload-dummy.c
>b/lib/dpif-offload-dummy.c index 827165ba2..1a226a38f 100644
>--- a/lib/dpif-offload-dummy.c
>+++ b/lib/dpif-offload-dummy.c
>@@ -24,6 +24,7 @@
> #include "netdev-provider.h"
> #include "util.h"
>
>+#include "openvswitch/json.h"
>
> struct dpif_offload_dummy {
> struct dpif_offload offload;
>@@ -171,6 +172,59 @@ dpif_offload_dummy_set_config(struct dpif_offload
>*dpif_offload,
> }
> }
>
>+static bool
>+dpif_offload_dummy_get_port_debug_ds(struct dpif_offload_port_mgr_port
>*port,
>+ void *aux) {
>+ struct ds *ds = aux;
>+
>+ ds_put_format(ds, " - %s: port_no: %u\n", netdev_get_name(port-
>>netdev),
>+ port->port_no);
>+
>+ return false;
>+}
>+
>+static bool
>+dpif_offload_dummy_get_port_debug_json(struct
>dpif_offload_port_mgr_port *port,
>+ void *aux) {
>+ struct json *json_port = json_object_create();
>+ struct json *json = aux;
>+
>+ json_object_put(json_port, "port_no",
>+ json_integer_create(odp_to_u32(port->port_no)));
>+
>+ json_object_put(json, netdev_get_name(port->netdev), json_port);
>+ return false;
>+}
>+
>+static void
>+dpif_offload_dummy_get_debug(const struct dpif_offload *offload, struct ds
>*ds,
>+ struct json *json) {
>+ struct dpif_offload_dummy *offload_dummy;
>+
>+ offload_dummy = dpif_offload_dummy_cast(offload);
>+
>+ if (json) {
>+ struct json *json_ports = json_object_create();
>+
>+ dpif_offload_port_mgr_traverse_ports(
>+ offload_dummy->port_mgr,
>dpif_offload_dummy_get_port_debug_json,
>+ json_ports);
>+
>+ if (!json_object_is_empty(json_ports)) {
>+ json_object_put(json, "ports", json_ports);
>+ } else {
>+ json_destroy(json_ports);
>+ }
>+
>+ } else if (ds) {
>+ dpif_offload_port_mgr_traverse_ports(
>+ offload_dummy->port_mgr, dpif_offload_dummy_get_port_debug_ds,
>ds);
>+ }
>+}
>+
> static bool
> dpif_offload_dummy_can_offload(struct dpif_offload *dpif_offload
>OVS_UNUSED,
> struct netdev *netdev) @@ -187,6 +241,7 @@
>dpif_offload_dummy_can_offload(struct dpif_offload *dpif_offload
>OVS_UNUSED,
> .open = dpif_offload_dummy_open, \
> .close = dpif_offload_dummy_close, \
> .set_config = dpif_offload_dummy_set_config, \
>+ .get_debug = dpif_offload_dummy_get_debug, \
> .can_offload = dpif_offload_dummy_can_offload, \
> .port_add = dpif_offload_dummy_port_add, \
> .port_del = dpif_offload_dummy_port_del, \
>diff --git a/lib/dpif-offload-provider.h b/lib/dpif-offload-provider.h index
>496959ea3..50f9a53c2 100644
>--- a/lib/dpif-offload-provider.h
>+++ b/lib/dpif-offload-provider.h
>@@ -93,6 +93,15 @@ struct dpif_offload_class {
> void (*set_config)(struct dpif_offload *,
> const struct smap *other_config);
>
>+ /* Retrieve debug information from the offload provider in either string
>+ * (ds) or JSON format. If both formats are requested, the provider may
>+ * choose which one to return. Note that the actual format is
>unspecified,
>+ * it's up to the provider to decide what to return. If 'ds' is supplied,
>+ * it should be initialized, and might already contain data. The caller
>is
>+ * responsible for freeing any returned 'ds' or 'json' pointers. */
>+ void (*get_debug)(const struct dpif_offload *offload, struct ds *ds,
>+ struct json *json);
>+
> /* Verifies whether the offload provider supports offloading flows for the
> * given 'netdev'. Returns 'false' if the provider lacks the capabilities
> * to offload on this port, otherwise returns 'true'. */ diff --git
> a/lib/dpif-
>offload-tc.c b/lib/dpif-offload-tc.c index c3090829b..66d52851a 100644
>--- a/lib/dpif-offload-tc.c
>+++ b/lib/dpif-offload-tc.c
>@@ -24,6 +24,7 @@
> #include "util.h"
> #include "tc.h"
>
>+#include "openvswitch/json.h"
> #include "openvswitch/vlog.h"
>
> VLOG_DEFINE_THIS_MODULE(dpif_offload_tc);
>@@ -169,6 +170,59 @@ dpif_offload_tc_set_config(struct dpif_offload
>*offload,
> }
> }
>
>+static bool
>+dpif_offload_tc_get_port_debug_ds(struct dpif_offload_port_mgr_port *port,
>+ void *aux) {
>+ struct ds *ds = aux;
>+
>+ ds_put_format(ds, " - %s: port_no: %u, ifindex: %d\n",
>+ netdev_get_name(port->netdev), port->port_no,
>+ port->ifindex);
>+
>+ return false;
>+}
>+
>+static bool
>+dpif_offload_tc_get_port_debug_json(struct dpif_offload_port_mgr_port
>*port,
>+ void *aux) {
>+ struct json *json_port = json_object_create();
>+ struct json *json = aux;
>+
>+ json_object_put(json_port, "port_no",
>+ json_integer_create(odp_to_u32(port->port_no)));
>+ json_object_put(json_port, "ifindex",
>+ json_integer_create(port->ifindex));
>+
>+ json_object_put(json, netdev_get_name(port->netdev), json_port);
>+ return false;
>+}
>+
>+static void
>+dpif_offload_tc_get_debug(const struct dpif_offload *offload, struct ds *ds,
>+ struct json *json) {
>+ struct dpif_offload_tc *offload_tc = dpif_offload_tc_cast(offload);
>+
>+ if (json) {
>+ struct json *json_ports = json_object_create();
>+
>+ dpif_offload_port_mgr_traverse_ports(
>+ offload_tc->port_mgr, dpif_offload_tc_get_port_debug_json,
>+ json_ports);
>+
>+ if (!json_object_is_empty(json_ports)) {
>+ json_object_put(json, "ports", json_ports);
>+ } else {
>+ json_destroy(json_ports);
>+ }
>+
>+ } else if (ds) {
>+ dpif_offload_port_mgr_traverse_ports(offload_tc->port_mgr,
>+
>dpif_offload_tc_get_port_debug_ds,
>+ ds);
>+ }
>+}
>+
> static bool
> dpif_offload_tc_can_offload(struct dpif_offload *dpif_offload OVS_UNUSED,
> struct netdev *netdev) @@ -190,6 +244,7 @@ struct
>dpif_offload_class dpif_offload_tc_class = {
> .open = dpif_offload_tc_open,
> .close = dpif_offload_tc_close,
> .set_config = dpif_offload_tc_set_config,
>+ .get_debug = dpif_offload_tc_get_debug,
> .can_offload = dpif_offload_tc_can_offload,
> .port_add = dpif_offload_tc_port_add,
> .port_del = dpif_offload_tc_port_del, diff --git a/lib/dpif-offload.c
> b/lib/dpif-
>offload.c index 42055008e..bfaa953b5 100644
>--- a/lib/dpif-offload.c
>+++ b/lib/dpif-offload.c
>@@ -406,6 +406,18 @@ dpif_offload_class_type(const struct dpif_offload
>*offload)
> return offload->class->type;
> }
>
>+bool
>+dpif_offload_get_debug(const struct dpif_offload *offload, struct ds *ds,
>+ struct json *json) {
>+ if (!offload->class->get_debug) {
>+ return false;
>+ }
>+
>+ offload->class->get_debug(offload, ds, json);
>+ return true;
>+}
>+
> bool
> dpif_offload_is_offload_enabled(void)
> {
>diff --git a/lib/dpif-offload.h b/lib/dpif-offload.h index 9cee3a8f4..5b6c3038e
>100644
>--- a/lib/dpif-offload.h
>+++ b/lib/dpif-offload.h
>@@ -44,6 +44,8 @@ int dpif_offload_attach_providers(struct dpif *); void
>dpif_offload_detach_providers(struct dpif *); const char
>*dpif_offload_name(const struct dpif_offload *); const char
>*dpif_offload_class_type(const struct dpif_offload *);
>+bool dpif_offload_get_debug(const struct dpif_offload *, struct ds *,
>+ struct json *);
> void dpif_offload_dump_start(struct dpif_offload_dump *, const struct dpif *);
>bool dpif_offload_dump_next(struct dpif_offload_dump *,
> struct dpif_offload **); diff --git a/lib/json.c
> b/lib/json.c index
>23622ab36..23000f195 100644
>--- a/lib/json.c
>+++ b/lib/json.c
>@@ -397,6 +397,13 @@ json_object_create(void)
> return json;
> }
>
>+bool
>+json_object_is_empty(struct json *json) {
>+ return json && json->type == JSON_OBJECT
>+ && shash_is_empty(json->object); }
>+
> struct json *
> json_integer_create(long long int integer) { diff --git
> a/ofproto/ofproto-dpif.c
>b/ofproto/ofproto-dpif.c index 7f76c7864..de7657db3 100644
>--- a/ofproto/ofproto-dpif.c
>+++ b/ofproto/ofproto-dpif.c
>@@ -6719,6 +6719,7 @@ dpif_offload_show_backer_text(const struct
>dpif_backer *backer, struct ds *ds)
>
> DPIF_OFFLOAD_FOR_EACH (offload, &dump, backer->dpif) {
> ds_put_format(ds, " %s\n", dpif_offload_class_type(offload));
>+ dpif_offload_get_debug(offload, ds, NULL);
> }
> }
>
>@@ -6733,15 +6734,26 @@ dpif_offload_show_backer_json(struct json
>*backers,
> /* Add datapath as new JSON object using its name as key. */
> json_object_put(backers, dpif_name(backer->dpif), json_backer);
>
>- /* Add provider to "providers" array using its name as key. */
>- struct json *json_providers = json_array_create_empty();
>+ /* Add provider to "providers" object using its name as key. */
>+ struct json *json_providers = json_object_create();
>+
>+ /* Add provider to "priority" array using its name as key. */
>+ struct json *json_priority = json_array_create_empty();
>
> /* Add offload provides as new JSON objects using its type as key. */
> DPIF_OFFLOAD_FOR_EACH (offload, &dump, backer->dpif) {
>- json_array_add(json_providers,
>+ struct json *debug_data = json_object_create();
>+
>+ json_array_add(json_priority,
> json_string_create(dpif_offload_class_type(offload)));
>+
>+ dpif_offload_get_debug(offload, NULL, debug_data);
>+
>+ json_object_put(json_providers, dpif_offload_class_type(offload),
>+ debug_data);
> }
>
>+ json_object_put(json_backer, "priority", json_priority);
> json_object_put(json_backer, "providers", json_providers);
> return json_backer;
> }
>diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index
>0ed8334d5..10596a968 100644
>--- a/tests/ofproto-dpif.at
>+++ b/tests/ofproto-dpif.at
>@@ -20,6 +20,28 @@ check_dpflow_stats () {
> echo "n_flows=$flows n_buckets=$buckets"
> }
>
>+sort_dpif_offload_show () {
>+ awk '
>+ /^ -/ { dashlines[[++n]] = $0; next }
>+ { print }
>+ END {
>+ # asort(dashlines) is a GNU extension, so we need to do it
>+ # manually here as ofproto-dpif is also executed on FreeBSD.
>+ for (i = 1; i <= n; i++) {
>+ for (j = i + 1; j <= n; j++) {
>+ if (dashlines[[i]] > dashlines[[j]]) {
>+ tmp = dashlines[[i]]
>+ dashlines[[i]] = dashlines[[j]]
>+ dashlines[[j]] = tmp
>+ }
>+ }
>+ }
>+
>+ for (i=1; i<=n; i++) print dashlines[[i]]
>+ }
>+ '
>+}
>+
> m4_divert_pop([PREPARE_TESTS])
>
>
>@@ -10079,20 +10101,34 @@ AT_SETUP([ofproto-dpif - offload - ovs-appctl
>dpif/offload/])
> AT_KEYWORDS([dpif-offload])
> OVS_VSWITCHD_START([add-br br1 -- set bridge br1 datapath-type=dummy])
>
>-AT_CHECK([ovs-appctl dpif/offload/show], [0], [dnl
>+AT_CHECK([ovs-appctl dpif/offload/show | sort_dpif_offload_show], [0],
>+[dnl
> Globally enabled: false
> Datapaths:
> dummy@ovs-dummy:
> dummy
> dummy_x
>+ - br0: port_no: 100
>+ - br1: port_no: 101
>+ - ovs-dummy: port_no: 0
> ])
>
> AT_CHECK([ovs-appctl --format json --pretty dpif/offload/show], [0], [dnl {
> "dummy@ovs-dummy": {
>- "providers": [[
>+ "priority": [[
> "dummy",
>- "dummy_x"]]},
>+ "dummy_x"]],
>+ "providers": {
>+ "dummy": {
>+ "ports": {
>+ "br0": {
>+ "port_no": 100},
>+ "br1": {
>+ "port_no": 101},
>+ "ovs-dummy": {
>+ "port_no": 0}}},
>+ "dummy_x": {
>+ }}},
> "enabled": false}
> ])
>
>@@ -10117,26 +10153,82 @@ AT_KEYWORDS([dpif-offload])
>OVS_VSWITCHD_START([add-br br1 -- set bridge br1 datapath-type=dummy],
>[], [],
> [], [-- set Open_vSwitch . other_config:hw-offload-
>priority=dummy_x,dummy])
>
>-AT_CHECK([ovs-appctl dpif/offload/show], [0], [dnl
>+AT_CHECK([ovs-appctl dpif/offload/show | sort_dpif_offload_show], [0],
>+[dnl
> Globally enabled: false
> Datapaths:
> dummy@ovs-dummy:
> dummy_x
> dummy
>+ - br0: port_no: 100
>+ - br1: port_no: 101
>+ - ovs-dummy: port_no: 0
> ])
>
> AT_CHECK([ovs-appctl --format json --pretty dpif/offload/show], [0], [dnl {
> "dummy@ovs-dummy": {
>- "providers": [[
>+ "priority": [[
> "dummy_x",
>- "dummy"]]},
>+ "dummy"]],
>+ "providers": {
>+ "dummy": {
>+ },
>+ "dummy_x": {
>+ "ports": {
>+ "br0": {
>+ "port_no": 100},
>+ "br1": {
>+ "port_no": 101},
>+ "ovs-dummy": {
>+ "port_no": 0}}}}},
> "enabled": false}
> ])
>
> OVS_TRAFFIC_VSWITCHD_STOP
> AT_CLEANUP
>
>+AT_SETUP([ofproto-dpif - offload - port priority order])
>+AT_KEYWORDS([dpif-offload])
>+OVS_VSWITCHD_START([add-port br0 p1 -- \
>+ set Interface p1 type=dummy ofport_request=1 -- \
>+ set port p1 other_config:hw-offload-priority=dummy_x,dummy -- \
>+ add-port br0 p2 -- \
>+ set Interface p2 type=dummy ofport_request=2 -- \
>+ set port p2 other_config:hw-offload-priority=none -- \
>+ add-port br0 p3 -- \
>+ set Interface p3 type=dummy ofport_request=3 -- \
>+ set port p3 other_config:hw-offload-priority=dummy_x -- \
>+ add-port br0 p4 -- \
>+ set Interface p4 type=dummy ofport_request=4 -- \
>+ set port p4 other_config:hw-offload-priority=dummy])
>+
>+AT_CHECK([ovs-appctl --format json --pretty dpif/offload/show], [0],
>+[dnl {
>+ "dummy@ovs-dummy": {
>+ "priority": [[
>+ "dummy",
>+ "dummy_x"]],
>+ "providers": {
>+ "dummy": {
>+ "ports": {
>+ "br0": {
>+ "port_no": 100},
>+ "ovs-dummy": {
>+ "port_no": 0},
>+ "p4": {
>+ "port_no": 4}}},
>+ "dummy_x": {
>+ "ports": {
>+ "p1": {
>+ "port_no": 1},
>+ "p3": {
>+ "port_no": 3}}}}},
>+ "enabled": false}
>+])
>+
>+OVS_VSWITCHD_STOP
>+AT_CLEANUP
>+
> dnl ----------------------------------------------------------------------
> AT_BANNER([ofproto-dpif -- megaflows])
>
>diff --git a/tests/system-dpdk.at b/tests/system-dpdk.at index
>c1910b756..17d3d2595 100644
>--- a/tests/system-dpdk.at
>+++ b/tests/system-dpdk.at
>@@ -948,20 +948,29 @@ AT_KEYWORDS([dpdk dpif-offload])
> OVS_DPDK_PRE_CHECK()
> OVS_DPDK_START([--no-pci])
> AT_CHECK([ovs-vsctl add-br br0 -- set bridge br0 datapath_type=netdev])
>+AT_CHECK([ovs-vsctl add-port br0 p1 \
>+ -- set Interface p1 type=dpdk
>+options:dpdk-devargs=net_null0,no-rx=1],
>+ [], [stdout], [stderr])
>
> AT_CHECK([ovs-appctl dpif/offload/show], [0], [dnl Globally enabled: false
> Datapaths:
> netdev@ovs-netdev:
> dpdk
>+ - p1: port_no: 2
> ])
>
> AT_CHECK([ovs-appctl --format json --pretty dpif/offload/show], [0], [dnl {
> "enabled": false,
> "netdev@ovs-netdev": {
>- "providers": [[
>- "dpdk"]]}}
>+ "priority": [[
>+ "dpdk"]],
>+ "providers": {
>+ "dpdk": {
>+ "ports": {
>+ "p1": {
>+ "port_no": 2}}}}}}
> ])
>
> OVS_DPDK_STOP_VSWITCHD
>diff --git a/tests/system-offloads-traffic.at
>b/tests/system-offloads-traffic.at
>index 471c8fdb8..c58e89608 100644
>--- a/tests/system-offloads-traffic.at
>+++ b/tests/system-offloads-traffic.at
>@@ -1172,19 +1172,44 @@ AT_KEYWORDS([dpif-offload])
>OVS_TRAFFIC_VSWITCHD_START([], [],
> [-- set Open_vSwitch . other_config:hw-offload=true])
>
>-AT_CHECK([ovs-appctl dpif/offload/show], [0], [dnl
>+sort_dpif_offload_show () {
>+ dnl Note: We do not use an m4 macro as it does not like the $0, or escaped
>+ dnl variants and loops until it runs out of memory.
>+ awk '
>+ /^ -/ { dashlines[[++n]] = $0; next }
>+ { print }
>+ END {
>+ asort(dashlines)
>+ for (i=1; i<=n; i++) print dashlines[[i]]
>+ }
>+ ' | sed -E 's/ifindex: [[0-9]]+/ifindex: 0/g'
>+}
>+
>+AT_CHECK([ovs-appctl dpif/offload/show | sort_dpif_offload_show], [0],
>+[dnl
> Globally enabled: true
> Datapaths:
> system@ovs-system:
> tc
>+ - br0: port_no: 1, ifindex: 0
>+ - ovs-system: port_no: 0, ifindex: 0
> ])
>
>-AT_CHECK([ovs-appctl --format json --pretty dpif/offload/show], [0], [dnl
>+AT_CHECK([ovs-appctl --format json --pretty dpif/offload/show \
>+ | sed -E 's/"ifindex": [[0-9]]+/"ifindex": 0/g'], [0], [dnl
> {
> "enabled": true,
> "system@ovs-system": {
>- "providers": [[
>- "tc"]]}}
>+ "priority": [[
>+ "tc"]],
>+ "providers": {
>+ "tc": {
>+ "ports": {
>+ "br0": {
>+ "ifindex": 0,
>+ "port_no": 1},
>+ "ovs-system": {
>+ "ifindex": 0,
>+ "port_no": 0}}}}}}
> ])
>
> OVS_TRAFFIC_VSWITCHD_STOP
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev