All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH iproute2-next v3 0/2] Add pcp-prio and new apptrust subcommand
@ 2022-12-02  9:22 Daniel Machon
  2022-12-02  9:22 ` [PATCH iproute2-next v3 1/2] dcb: add new pcp-prio parameter to dcb app Daniel Machon
  2022-12-02  9:22 ` [PATCH iproute2-next v3 2/2] dcb: add new subcommand for apptrust Daniel Machon
  0 siblings, 2 replies; 11+ messages in thread
From: Daniel Machon @ 2022-12-02  9:22 UTC (permalink / raw)
  To: netdev
  Cc: dsahern, stephen, petrm, maxime.chevallier, vladimir.oltean,
	UNGLinuxDriver, Daniel Machon

This patch series makes use of the newly introduced [1] DCB_APP_SEL_PCP
selector, for PCP/DEI prioritization, and DCB_ATTR_IEEE_APP_TRUST
attribute for configuring per-selector trust and trust-order.

========================================================================
New parameter "pcp-prio" to existing "app" subcommand:
========================================================================

A new pcp-prio parameter has been added to the app subcommand, which can
be used to classify traffic based on PCP and DEI from the VLAN header.
PCP and DEI is specified in a combination of numerical and symbolic
form, where 'de' (drop-eligible) means DEI=1 and 'nd' (not-drop-eligible)
means DEI=0.

Map PCP 1 and DEI 0 to priority 1
$ dcb app add dev eth0 pcp-prio 1nd:1

Map PCP 1 and DEI 1 to priority 1
$ dcb app add dev eth0 pcp-prio 1de:1

========================================================================
New apptrust subcommand for configuring per-selector trust and trust
order:
========================================================================

This new command currently has a single parameter, which lets you
specify an ordered list of trusted selectors. The microchip sparx5
driver is already enabled to offload said list of trusted selectors. The
new command has been given the name apptrust, to indicate that the trust
covers APP table selectors only. I found that 'apptrust' was better than
plain 'trust' as the latter does not indicate the scope of what is to be
trusted.

Example:

Trust selectors dscp and pcp, in that order:
$ dcb apptrust set dev eth0 order dscp pcp

Trust selectors ethtype, stream-port and pcp, in that order
$ dcb apptrust set dev eth0 order ethtype stream-port pcp

Show the trust order
$ dcb apptrust show dev eth0 order order: ethtype stream-port pcp

A concern was raised here [2], that 'apptrust' would not work well with
matches(), so instead strcmp() has been used to match for the new
subcommand, as suggested here [3]. Same goes with pcp-prio parameter for
dcb app.

The man page for dcb_app has been extended to cover the new pcp-prio
parameter, and a new man page for dcb_apptrust has been created.

[1] https://lore.kernel.org/netdev/20221101094834.2726202-1-daniel.machon@microchip.com/
[2] https://lore.kernel.org/netdev/20220909080631.6941a770@hermes.local/
[3] https://lore.kernel.org/netdev/Y0fP+9C0tE7P2xyK@shredder/

================================================================================

v2 -> v3:
  - Add macro for maximum pcp/dei value.

v1 -> v2:
  - Modified dcb_cmd_apptrust_set() to allow multiple consecutive parameters.
  - Added dcb_apptrust_print() to print everything in case of no argument.
  - Renamed pcp keys 0-7 to 0nd-7nd.
  - Renamed selector names in dcb-apptrust to reflect names used in dcb-app.
  - Updated dcb-app manpage to reflect new selector names, and removed part
    about hardware offload.
  - Updated dcb-apptrust manpage to reflect new selector names, and modified the
    description of the 'order' parameter.
  - Replaced uses of parse_one_of() with loops, for new 1nd:1 semantics to be
    parsed correctly, and not printing an error if selector was not found in
    list.

Daniel Machon (2):
  dcb: add new pcp-prio parameter to dcb app
  dcb: add new subcommand for apptrust

 dcb/Makefile            |   3 +-
 dcb/dcb.c               |   4 +-
 dcb/dcb.h               |   7 +
 dcb/dcb_app.c           | 142 ++++++++++++++++++-
 dcb/dcb_apptrust.c      | 307 ++++++++++++++++++++++++++++++++++++++++
 man/man8/dcb-app.8      |  32 +++++
 man/man8/dcb-apptrust.8 | 109 ++++++++++++++
 7 files changed, 595 insertions(+), 9 deletions(-)
 create mode 100644 dcb/dcb_apptrust.c
 create mode 100644 man/man8/dcb-apptrust.8

--
2.34.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH iproute2-next v3 1/2] dcb: add new pcp-prio parameter to dcb app
  2022-12-02  9:22 [PATCH iproute2-next v3 0/2] Add pcp-prio and new apptrust subcommand Daniel Machon
@ 2022-12-02  9:22 ` Daniel Machon
  2022-12-03 17:00   ` Stephen Hemminger
  2022-12-02  9:22 ` [PATCH iproute2-next v3 2/2] dcb: add new subcommand for apptrust Daniel Machon
  1 sibling, 1 reply; 11+ messages in thread
From: Daniel Machon @ 2022-12-02  9:22 UTC (permalink / raw)
  To: netdev
  Cc: dsahern, stephen, petrm, maxime.chevallier, vladimir.oltean,
	UNGLinuxDriver, Daniel Machon

Add new pcp-prio parameter to the app subcommand, which can be used to
classify traffic based on PCP and DEI from the VLAN header. PCP and DEI
is specified in a combination of numerical and symbolic form, where 'de'
(drop-eligible) means DEI=1 and 'nd' (not-drop-eligible) means DEI=0.

Map PCP 1 and DEI 0 to priority 1
$ dcb app add dev eth0 pcp-prio 1nd:1

Map PCP 1 and DEI 1 to priority 1
$ dcb app add dev eth0 pcp-prio 1de:1

Internally, PCP and DEI is encoded in the protocol field of the dcb_app
struct. Each combination of PCP and DEI maps to a priority, thus needing
a range of  0-15. A well formed dcb_app entry for PCP/DEI
prioritization, could look like:

    struct dcb_app pcp = {
        .selector = DCB_APP_SEL_PCP,
	.priority = 7,
        .protocol = 15
    }

For mapping PCP=7 and DEI=1 to Prio=7.

Also, three helper functions for translating between std and non-std APP
selectors, have been added to dcb_app.c and exposed through dcb.h.

Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
 dcb/dcb.h          |   3 +
 dcb/dcb_app.c      | 140 +++++++++++++++++++++++++++++++++++++++++++--
 man/man8/dcb-app.8 |  32 +++++++++++
 3 files changed, 169 insertions(+), 6 deletions(-)

diff --git a/dcb/dcb.h b/dcb/dcb.h
index 244c3d3c30e3..05eddcbbcfdf 100644
--- a/dcb/dcb.h
+++ b/dcb/dcb.h
@@ -57,6 +57,9 @@ void dcb_print_array_kw(const __u8 *array, size_t array_size,
 /* dcb_app.c */
 
 int dcb_cmd_app(struct dcb *dcb, int argc, char **argv);
+enum ieee_attrs_app dcb_app_attr_type_get(__u8 selector);
+bool dcb_app_attr_type_validate(enum ieee_attrs_app type);
+bool dcb_app_selector_validate(enum ieee_attrs_app type, __u8 selector);
 
 /* dcb_buffer.c */
 
diff --git a/dcb/dcb_app.c b/dcb/dcb_app.c
index dad34554017a..b2f1688bd31b 100644
--- a/dcb/dcb_app.c
+++ b/dcb/dcb_app.c
@@ -10,6 +10,18 @@
 #include "utils.h"
 #include "rt_names.h"
 
+#define DCB_APP_PCP_MAX 15
+
+static const char *const pcp_names[DCB_APP_PCP_MAX + 1] = {
+	"0nd", "1nd", "2nd", "3nd", "4nd", "5nd", "6nd", "7nd",
+	"0de", "1de", "2de", "3de", "4de", "5de", "6de", "7de"
+};
+
+static const char *const ieee_attrs_app_names[__DCB_ATTR_IEEE_APP_MAX] = {
+	[DCB_ATTR_IEEE_APP] = "DCB_ATTR_IEEE_APP",
+	[DCB_ATTR_DCB_APP] = "DCB_ATTR_DCB_APP"
+};
+
 static void dcb_app_help_add(void)
 {
 	fprintf(stderr,
@@ -20,11 +32,13 @@ static void dcb_app_help_add(void)
 		"           [ dgram-port-prio PORT:PRIO ]\n"
 		"           [ port-prio PORT:PRIO ]\n"
 		"           [ dscp-prio INTEGER:PRIO ]\n"
+		"           [ pcp-prio PCP:PRIO ]\n"
 		"\n"
 		" where PRIO := { 0 .. 7 }\n"
 		"       ET := { 0x600 .. 0xffff }\n"
 		"       PORT := { 1 .. 65535 }\n"
 		"       DSCP := { 0 .. 63 }\n"
+		"       PCP := { 0(nd/de) .. 7(nd/de) }\n"
 		"\n"
 	);
 }
@@ -39,6 +53,7 @@ static void dcb_app_help_show_flush(void)
 		"           [ dgram-port-prio ]\n"
 		"           [ port-prio ]\n"
 		"           [ dscp-prio ]\n"
+		"           [ pcp-prio ]\n"
 		"\n"
 	);
 }
@@ -58,6 +73,38 @@ struct dcb_app_table {
 	size_t n_apps;
 };
 
+enum ieee_attrs_app dcb_app_attr_type_get(__u8 selector)
+{
+	switch (selector) {
+	case IEEE_8021QAZ_APP_SEL_ETHERTYPE:
+	case IEEE_8021QAZ_APP_SEL_STREAM:
+	case IEEE_8021QAZ_APP_SEL_DGRAM:
+	case IEEE_8021QAZ_APP_SEL_ANY:
+	case IEEE_8021QAZ_APP_SEL_DSCP:
+		return DCB_ATTR_IEEE_APP;
+	case DCB_APP_SEL_PCP:
+		return DCB_ATTR_DCB_APP;
+	default:
+		return DCB_ATTR_IEEE_APP_UNSPEC;
+	}
+}
+
+bool dcb_app_attr_type_validate(enum ieee_attrs_app type)
+{
+	switch (type) {
+	case DCB_ATTR_IEEE_APP:
+	case DCB_ATTR_DCB_APP:
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool dcb_app_selector_validate(enum ieee_attrs_app type, __u8 selector)
+{
+	return dcb_app_attr_type_get(selector) == type;
+}
+
 static void dcb_app_table_fini(struct dcb_app_table *tab)
 {
 	free(tab->apps);
@@ -213,6 +260,32 @@ static int dcb_app_parse_mapping_ethtype_prio(__u32 key, char *value, void *data
 				 dcb_app_parse_mapping_cb, data);
 }
 
+static int dcb_app_parse_pcp(__u32 *key, const char *arg)
+{
+	int i;
+
+	for(i = 0; i < ARRAY_SIZE(pcp_names); i++) {
+		if (pcp_names[i] && strcmp(arg, pcp_names[i]) == 0) {
+			*key = i;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int dcb_app_parse_mapping_pcp_prio(__u32 key, char *value, void *data)
+{
+	__u8 prio;
+
+	if (get_u8(&prio, value, 0))
+		return -EINVAL;
+
+	return dcb_parse_mapping("PCP", key, DCB_APP_PCP_MAX,
+				 "PRIO", prio, IEEE_8021QAZ_MAX_TCS - 1,
+				 dcb_app_parse_mapping_cb, data);
+}
+
 static int dcb_app_parse_dscp(__u32 *key, const char *arg)
 {
 	if (parse_mapping_num_all(key, arg) == 0)
@@ -309,6 +382,11 @@ static bool dcb_app_is_dscp(const struct dcb_app *app)
 	return app->selector == IEEE_8021QAZ_APP_SEL_DSCP;
 }
 
+static bool dcb_app_is_pcp(const struct dcb_app *app)
+{
+	return app->selector == DCB_APP_SEL_PCP;
+}
+
 static bool dcb_app_is_stream_port(const struct dcb_app *app)
 {
 	return app->selector == IEEE_8021QAZ_APP_SEL_STREAM;
@@ -344,6 +422,17 @@ static int dcb_app_print_key_dscp(__u16 protocol)
 	return print_uint(PRINT_ANY, NULL, "%d:", protocol);
 }
 
+static int dcb_app_print_key_pcp(__u16 protocol)
+{
+	/* Print in numerical form, if protocol value is out-of-range */
+	if (protocol > DCB_APP_PCP_MAX) {
+		fprintf(stderr, "Unknown PCP key: %d\n", protocol);
+		return print_uint(PRINT_ANY, NULL, "%d:", protocol);
+	}
+
+	return print_string(PRINT_ANY, NULL, "%s:", pcp_names[protocol]);
+}
+
 static void dcb_app_print_filtered(const struct dcb_app_table *tab,
 				   bool (*filter)(const struct dcb_app *),
 				   int (*print_key)(__u16 protocol),
@@ -382,6 +471,15 @@ static void dcb_app_print_ethtype_prio(const struct dcb_app_table *tab)
 			       "ethtype_prio", "ethtype-prio");
 }
 
+static void dcb_app_print_pcp_prio(const struct dcb *dcb,
+				   const struct dcb_app_table *tab)
+{
+	dcb_app_print_filtered(tab, dcb_app_is_pcp,
+			       dcb->numeric ? dcb_app_print_key_dec
+					    : dcb_app_print_key_pcp,
+			       "pcp_prio", "pcp-prio");
+}
+
 static void dcb_app_print_dscp_prio(const struct dcb *dcb,
 				    const struct dcb_app_table *tab)
 {
@@ -439,26 +537,41 @@ static void dcb_app_print(const struct dcb *dcb, const struct dcb_app_table *tab
 	dcb_app_print_stream_port_prio(tab);
 	dcb_app_print_dgram_port_prio(tab);
 	dcb_app_print_port_prio(tab);
+	dcb_app_print_pcp_prio(dcb, tab);
 }
 
 static int dcb_app_get_table_attr_cb(const struct nlattr *attr, void *data)
 {
 	struct dcb_app_table *tab = data;
 	struct dcb_app *app;
+	uint16_t type;
 	int ret;
 
-	if (mnl_attr_get_type(attr) != DCB_ATTR_IEEE_APP) {
-		fprintf(stderr, "Unknown attribute in DCB_ATTR_IEEE_APP_TABLE: %d\n",
-			mnl_attr_get_type(attr));
+	type = mnl_attr_get_type(attr);
+
+	if (!dcb_app_attr_type_validate(type)) {
+		fprintf(stderr,
+			"Unknown attribute in DCB_ATTR_IEEE_APP_TABLE: %d\n",
+			type);
 		return MNL_CB_OK;
 	}
 	if (mnl_attr_get_payload_len(attr) < sizeof(struct dcb_app)) {
-		fprintf(stderr, "DCB_ATTR_IEEE_APP payload expected to have size %zd, not %d\n",
-			sizeof(struct dcb_app), mnl_attr_get_payload_len(attr));
+		fprintf(stderr,
+			"%s payload expected to have size %zd, not %d\n",
+			ieee_attrs_app_names[type], sizeof(struct dcb_app),
+			mnl_attr_get_payload_len(attr));
 		return MNL_CB_OK;
 	}
 
 	app = mnl_attr_get_payload(attr);
+
+	/* Check that selector is encapsulated in the right attribute */
+	if (!dcb_app_selector_validate(type, app->selector)) {
+		fprintf(stderr, "Wrong selector for type: %s\n",
+			ieee_attrs_app_names[type]);
+		return MNL_CB_OK;
+	}
+
 	ret = dcb_app_table_push(tab, app);
 	if (ret != 0)
 		return MNL_CB_ERROR;
@@ -491,6 +604,7 @@ struct dcb_app_add_del {
 static int dcb_app_add_del_cb(struct dcb *dcb, struct nlmsghdr *nlh, void *data)
 {
 	struct dcb_app_add_del *add_del = data;
+	enum ieee_attrs_app type;
 	struct nlattr *nest;
 	size_t i;
 
@@ -498,9 +612,10 @@ static int dcb_app_add_del_cb(struct dcb *dcb, struct nlmsghdr *nlh, void *data)
 
 	for (i = 0; i < add_del->tab->n_apps; i++) {
 		const struct dcb_app *app = &add_del->tab->apps[i];
+		type = dcb_app_attr_type_get(app->selector);
 
 		if (add_del->filter == NULL || add_del->filter(app))
-			mnl_attr_put(nlh, DCB_ATTR_IEEE_APP, sizeof(*app), app);
+			mnl_attr_put(nlh, type, sizeof(*app), app);
 	}
 
 	mnl_attr_nest_end(nlh, nest);
@@ -577,6 +692,12 @@ static int dcb_cmd_app_parse_add_del(struct dcb *dcb, const char *dev,
 			ret = parse_mapping(&argc, &argv, false,
 					    &dcb_app_parse_mapping_port_prio,
 					    &pm);
+		} else if (strcmp(*argv, "pcp-prio") == 0) {
+			NEXT_ARG();
+			pm.selector = DCB_APP_SEL_PCP;
+			ret = parse_mapping_gen(&argc, &argv, &dcb_app_parse_pcp,
+						&dcb_app_parse_mapping_pcp_prio,
+						&pm);
 		} else {
 			fprintf(stderr, "What is \"%s\"?\n", *argv);
 			dcb_app_help_add();
@@ -656,6 +777,8 @@ static int dcb_cmd_app_show(struct dcb *dcb, const char *dev, int argc, char **a
 			dcb_app_print_port_prio(&tab);
 		} else if (matches(*argv, "default-prio") == 0) {
 			dcb_app_print_default_prio(&tab);
+		} else if (strcmp(*argv, "pcp-prio") == 0) {
+			dcb_app_print_pcp_prio(dcb, &tab);
 		} else {
 			fprintf(stderr, "What is \"%s\"?\n", *argv);
 			dcb_app_help_show_flush();
@@ -705,6 +828,11 @@ static int dcb_cmd_app_flush(struct dcb *dcb, const char *dev, int argc, char **
 					      &dcb_app_is_dscp);
 			if (ret != 0)
 				goto out;
+		} else if (strcmp(*argv, "pcp-prio") == 0) {
+			ret = dcb_app_add_del(dcb, dev, DCB_CMD_IEEE_DEL, &tab,
+					      &dcb_app_is_pcp);
+			if (ret != 0)
+				goto out;
 		} else {
 			fprintf(stderr, "What is \"%s\"?\n", *argv);
 			dcb_app_help_show_flush();
diff --git a/man/man8/dcb-app.8 b/man/man8/dcb-app.8
index 9780fe4b60fa..ecb38591168e 100644
--- a/man/man8/dcb-app.8
+++ b/man/man8/dcb-app.8
@@ -23,6 +23,7 @@ the DCB (Data Center Bridging) subsystem
 .RB "[ " dgram-port-prio " ]"
 .RB "[ " port-prio " ]"
 .RB "[ " dscp-prio " ]"
+.RB "[ " pcp-prio " ]"
 
 .ti -8
 .B dcb ets " { " add " | " del " | " replace " } " dev
@@ -33,6 +34,7 @@ the DCB (Data Center Bridging) subsystem
 .RB "[ " dgram-port-prio " " \fIPORT-MAP\fB " ]"
 .RB "[ " port-prio " " \fIPORT-MAP\fB " ]"
 .RB "[ " dscp-prio " " \fIDSCP-MAP\fB " ]"
+.RB "[ " pcp-prio " " \fIPCP-MAP\fB " ]"
 
 .ti -8
 .IR PRIO-LIST " := [ " PRIO-LIST " ] " PRIO
@@ -55,6 +57,12 @@ the DCB (Data Center Bridging) subsystem
 .ti -8
 .IR DSCP-MAPPING " := { " DSCP " | " \fBall " }" \fB:\fIPRIO\fR
 
+.ti -8
+.IR PCP-MAP " := [ " PCP-MAP " ] " PCP-MAPPING
+
+.ti -8
+.IR PCP-MAPPING " := " PCP\fB:\fIPRIO\fR
+
 .ti -8
 .IR ET " := { " \fB0x600\fR " .. " \fB0xffff\fR " }"
 
@@ -64,6 +72,9 @@ the DCB (Data Center Bridging) subsystem
 .ti -8
 .IR DSCP " := { " \fB0\fR " .. " \fB63\fR " }"
 
+.ti -8
+.IR PCP " := { " \fB0(nd/de)\fR " .. " \fB7(nd/de)\fR " }"
+
 .ti -8
 .IR PRIO " := { " \fB0\fR " .. " \fB7\fR " }"
 
@@ -182,6 +193,17 @@ command line option
 .B -N
 turns the show translation off.
 
+.TP
+.B pcp-prio \fIPCP-MAP
+\fIPCP-MAP\fR uses the array parameter syntax, see
+.BR dcb (8)
+for details. Keys are PCP/DEI. Values are priorities assigned to traffic with
+matching PCP/DEI. PCP/DEI values are written as a combination of numeric- and
+symbolic values, to accommodate for both. PCP always in numerical form e.g
+0 .. 7 and DEI in symbolic form e.g 'de' (drop-eligible), indicating that the
+DEI bit is 1 or 'nd' (not-drop-eligible), indicating that the DEI bit is 0.
+In combination 2de:1 translates to a mapping of PCP=2 and DEI=1 to priority 1.
+
 .SH EXAMPLE & USAGE
 
 Prioritize traffic with DSCP 0 to priority 0, 24 to 3 and 48 to 6:
@@ -221,6 +243,16 @@ Flush all DSCP rules:
 .br
 (nothing)
 
+Add a rule to map traffic with PCP 1 and DEI 0 to priority 1 and PCP 2 and DEI 1
+to priority 2:
+
+.P
+# dcb app add dev eth0 pcp-prio 1nd:1 2de:2
+.br
+# dcb app show dev eth0 pcp-prio
+.br
+pcp-prio 1nd:1 2de:2
+
 .SH EXIT STATUS
 Exit status is 0 if command was successful or a positive integer upon failure.
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH iproute2-next v3 2/2] dcb: add new subcommand for apptrust
  2022-12-02  9:22 [PATCH iproute2-next v3 0/2] Add pcp-prio and new apptrust subcommand Daniel Machon
  2022-12-02  9:22 ` [PATCH iproute2-next v3 1/2] dcb: add new pcp-prio parameter to dcb app Daniel Machon
@ 2022-12-02  9:22 ` Daniel Machon
  1 sibling, 0 replies; 11+ messages in thread
From: Daniel Machon @ 2022-12-02  9:22 UTC (permalink / raw)
  To: netdev
  Cc: dsahern, stephen, petrm, maxime.chevallier, vladimir.oltean,
	UNGLinuxDriver, Daniel Machon

Add new apptrust subcommand for the dcbnl apptrust extension object.

The apptrust command lets you specify a consecutive ordered list of
trusted selectors, which can be used by drivers to determine which
selectors are eligible (trusted) for packet prioritization, and in which
order.

Selectors are sent in a new nested attribute:
DCB_ATTR_IEEE_APP_TRUST_TABLE.  The nest contains trusted selectors
encapsulated in either DCB_ATTR_IEEE_APP or DCB_ATTR_DCB_APP attributes,
for standard and non-standard selectors, respectively.

Example:

Trust selectors dscp and pcp, in that order
$ dcb apptrust set dev eth0 order dscp pcp

Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
 dcb/Makefile            |   3 +-
 dcb/dcb.c               |   4 +-
 dcb/dcb.h               |   4 +
 dcb/dcb_apptrust.c      | 307 ++++++++++++++++++++++++++++++++++++++++
 man/man8/dcb-apptrust.8 | 109 ++++++++++++++
 5 files changed, 425 insertions(+), 2 deletions(-)
 create mode 100644 dcb/dcb_apptrust.c
 create mode 100644 man/man8/dcb-apptrust.8

diff --git a/dcb/Makefile b/dcb/Makefile
index ca65d4670c80..dd41a559a0c8 100644
--- a/dcb/Makefile
+++ b/dcb/Makefile
@@ -7,7 +7,8 @@ DCBOBJ = dcb.o \
          dcb_dcbx.o \
          dcb_ets.o \
          dcb_maxrate.o \
-         dcb_pfc.o
+         dcb_pfc.o \
+         dcb_apptrust.o
 TARGETS += dcb
 LDLIBS += -lm
 
diff --git a/dcb/dcb.c b/dcb/dcb.c
index 391fd95455f4..3ffa91d64d0d 100644
--- a/dcb/dcb.c
+++ b/dcb/dcb.c
@@ -470,7 +470,7 @@ static void dcb_help(void)
 	fprintf(stderr,
 		"Usage: dcb [ OPTIONS ] OBJECT { COMMAND | help }\n"
 		"       dcb [ -f | --force ] { -b | --batch } filename [ -n | --netns ] netnsname\n"
-		"where  OBJECT := { app | buffer | dcbx | ets | maxrate | pfc }\n"
+		"where  OBJECT := { app | apptrust | buffer | dcbx | ets | maxrate | pfc }\n"
 		"       OPTIONS := [ -V | --Version | -i | --iec | -j | --json\n"
 		"                  | -N | --Numeric | -p | --pretty\n"
 		"                  | -s | --statistics | -v | --verbose]\n");
@@ -483,6 +483,8 @@ static int dcb_cmd(struct dcb *dcb, int argc, char **argv)
 		return 0;
 	} else if (matches(*argv, "app") == 0) {
 		return dcb_cmd_app(dcb, argc - 1, argv + 1);
+	} else if (strcmp(*argv, "apptrust") == 0) {
+		return dcb_cmd_apptrust(dcb, argc - 1, argv + 1);
 	} else if (matches(*argv, "buffer") == 0) {
 		return dcb_cmd_buffer(dcb, argc - 1, argv + 1);
 	} else if (matches(*argv, "dcbx") == 0) {
diff --git a/dcb/dcb.h b/dcb/dcb.h
index 05eddcbbcfdf..d40664f29dad 100644
--- a/dcb/dcb.h
+++ b/dcb/dcb.h
@@ -61,6 +61,10 @@ enum ieee_attrs_app dcb_app_attr_type_get(__u8 selector);
 bool dcb_app_attr_type_validate(enum ieee_attrs_app type);
 bool dcb_app_selector_validate(enum ieee_attrs_app type, __u8 selector);
 
+/* dcb_apptrust.c */
+
+int dcb_cmd_apptrust(struct dcb *dcb, int argc, char **argv);
+
 /* dcb_buffer.c */
 
 int dcb_cmd_buffer(struct dcb *dcb, int argc, char **argv);
diff --git a/dcb/dcb_apptrust.c b/dcb/dcb_apptrust.c
new file mode 100644
index 000000000000..ed1cba76929b
--- /dev/null
+++ b/dcb/dcb_apptrust.c
@@ -0,0 +1,307 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <errno.h>
+#include <linux/dcbnl.h>
+
+#include "dcb.h"
+#include "utils.h"
+
+static void dcb_apptrust_help_set(void)
+{
+	fprintf(stderr,
+		"Usage: dcb apptrust set dev STRING\n"
+		"       [ order [ ethtype | stream-port | dgram-port | port | dscp | pcp ] ]\n"
+		"\n");
+}
+
+static void dcb_apptrust_help_show(void)
+{
+	fprintf(stderr, "Usage: dcb apptrust show dev STRING\n"
+			"       [ order ]\n"
+			"\n");
+}
+
+static void dcb_apptrust_help(void)
+{
+	fprintf(stderr, "Usage: dcb apptrust help\n"
+			"\n");
+	dcb_apptrust_help_show();
+	dcb_apptrust_help_set();
+}
+
+static const char *const selector_names[] = {
+	[IEEE_8021QAZ_APP_SEL_ETHERTYPE] = "ethtype",
+	[IEEE_8021QAZ_APP_SEL_STREAM]    = "stream-port",
+	[IEEE_8021QAZ_APP_SEL_DGRAM]     = "dgram-port",
+	[IEEE_8021QAZ_APP_SEL_ANY]       = "port",
+	[IEEE_8021QAZ_APP_SEL_DSCP]      = "dscp",
+	[DCB_APP_SEL_PCP]                = "pcp",
+};
+
+struct dcb_apptrust_table {
+	__u8 selectors[IEEE_8021QAZ_APP_SEL_MAX + 1];
+	int nselectors;
+};
+
+static bool dcb_apptrust_contains(const struct dcb_apptrust_table *table,
+				  __u8 selector)
+{
+	int i;
+
+	for (i = 0; i < table->nselectors; i++)
+		if (table->selectors[i] == selector)
+			return true;
+
+	return false;
+}
+
+static void dcb_apptrust_print_order(const struct dcb_apptrust_table *table)
+{
+	const char *str;
+	__u8 selector;
+	int i;
+
+	open_json_array(PRINT_JSON, "order");
+	print_string(PRINT_FP, NULL, "order: ", NULL);
+
+	for (i = 0; i < table->nselectors; i++) {
+		selector = table->selectors[i];
+		str = selector_names[selector];
+		print_string(PRINT_ANY, NULL, "%s ", str);
+	}
+	print_nl();
+
+	close_json_array(PRINT_JSON, "order");
+}
+
+static void dcb_apptrust_print(const struct dcb_apptrust_table *table)
+{
+	dcb_apptrust_print_order(table);
+	print_nl();
+}
+
+static int dcb_apptrust_get_cb(const struct nlattr *attr, void *data)
+{
+	struct dcb_apptrust_table *table = data;
+	uint16_t type;
+	__u8 selector;
+
+	type = mnl_attr_get_type(attr);
+
+	if (!dcb_app_attr_type_validate(type)) {
+		fprintf(stderr,
+			"Unknown attribute in DCB_ATTR_IEEE_APP_TRUST_TABLE: %d\n",
+			type);
+		return MNL_CB_OK;
+	}
+
+	if (mnl_attr_get_payload_len(attr) < 1) {
+		fprintf(stderr,
+			"DCB_ATTR_IEEE_APP_TRUST payload expected to have size %zd, not %d\n",
+			sizeof(struct dcb_app), mnl_attr_get_payload_len(attr));
+		return MNL_CB_OK;
+	}
+
+	selector = mnl_attr_get_u8(attr);
+
+	/* Check that selector is encapsulated in the right attribute */
+	if (!dcb_app_selector_validate(type, selector)) {
+		fprintf(stderr, "Wrong type for selector: %s\n",
+			selector_names[selector]);
+		return MNL_CB_OK;
+	}
+
+	table->selectors[table->nselectors++] = selector;
+
+	return MNL_CB_OK;
+}
+
+static int dcb_apptrust_get(struct dcb *dcb, const char *dev,
+			    struct dcb_apptrust_table *table)
+{
+	uint16_t payload_len;
+	void *payload;
+	int ret;
+
+	ret = dcb_get_attribute_va(dcb, dev, DCB_ATTR_DCB_APP_TRUST_TABLE,
+				   &payload, &payload_len);
+	if (ret != 0)
+		return ret;
+
+	ret = mnl_attr_parse_payload(payload, payload_len, dcb_apptrust_get_cb,
+				     table);
+	if (ret != MNL_CB_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int dcb_apptrust_set_cb(struct dcb *dcb, struct nlmsghdr *nlh,
+			       void *data)
+{
+	const struct dcb_apptrust_table *table = data;
+	enum ieee_attrs_app type;
+	struct nlattr *nest;
+	int i;
+
+	nest = mnl_attr_nest_start(nlh, DCB_ATTR_DCB_APP_TRUST_TABLE);
+
+	for (i = 0; i < table->nselectors; i++) {
+		type = dcb_app_attr_type_get(table->selectors[i]);
+		mnl_attr_put_u8(nlh, type, table->selectors[i]);
+	}
+
+	mnl_attr_nest_end(nlh, nest);
+
+	return 0;
+}
+
+static int dcb_apptrust_set(struct dcb *dcb, const char *dev,
+			    const struct dcb_apptrust_table *table)
+{
+	return dcb_set_attribute_va(dcb, DCB_CMD_IEEE_SET, dev,
+				    &dcb_apptrust_set_cb, (void *)table);
+}
+
+static __u8 dcb_apptrust_parse_selector(const char *selector, int *err)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(selector_names); i++) {
+		if (selector_names[i] &&
+		    strcmp(selector, selector_names[i]) == 0) {
+			    *err = 0;
+			    return i;
+		    }
+	}
+
+	*err = -EINVAL;
+	return 0;
+}
+
+static int dcb_apptrust_parse_selector_list(int *argcp, char ***argvp,
+					    struct dcb_apptrust_table *table)
+{
+	int argc = *argcp, err;
+	char **argv = *argvp;
+	__u8 selector;
+
+	/* No trusted selectors ? */
+	if (argc == 0)
+		goto out;
+
+	while (argc > 0) {
+		selector = dcb_apptrust_parse_selector(*argv, &err);
+		if (err < 0)
+			goto out;
+
+		if (table->nselectors > IEEE_8021QAZ_APP_SEL_MAX)
+			return -ERANGE;
+
+		if (dcb_apptrust_contains(table, selector)) {
+			fprintf(stderr, "Duplicate selector: %s\n",
+				selector_names[selector]);
+			return -EINVAL;
+		}
+
+		table->selectors[table->nselectors++] = selector;
+
+		NEXT_ARG_FWD();
+	}
+
+out:
+	*argcp = argc;
+	*argvp = argv;
+
+	return 0;
+}
+
+static int dcb_cmd_apptrust_set(struct dcb *dcb, const char *dev, int argc,
+				char **argv)
+{
+	struct dcb_apptrust_table table = { 0 };
+	int ret;
+
+	if (!argc) {
+		dcb_apptrust_help_set();
+		return 0;
+	}
+
+	do {
+		if (strcmp(*argv, "help") == 0) {
+			dcb_apptrust_help_set();
+			return 0;
+		} else if (strcmp(*argv, "order") == 0) {
+			NEXT_ARG_FWD();
+			ret = dcb_apptrust_parse_selector_list(&argc, &argv,
+							       &table);
+			if (ret < 0) {
+				fprintf(stderr, "Invalid list of selectors\n");
+				return -EINVAL;
+			}
+		} else {
+			fprintf(stderr, "What is \"%s\"?\n", *argv);
+			dcb_apptrust_help_set();
+			return -EINVAL;
+		}
+	} while (argc > 0);
+
+	return dcb_apptrust_set(dcb, dev, &table);
+}
+
+static int dcb_cmd_apptrust_show(struct dcb *dcb, const char *dev, int argc,
+				 char **argv)
+{
+	struct dcb_apptrust_table table = { 0 };
+	int ret;
+
+	ret = dcb_apptrust_get(dcb, dev, &table);
+	if (ret)
+		return ret;
+
+	open_json_object(NULL);
+
+	if (!argc) {
+		dcb_apptrust_print(&table);
+		goto out;
+	}
+
+	do {
+		if (strcmp(*argv, "help") == 0) {
+			dcb_apptrust_help_show();
+			return 0;
+		} else if (strcmp(*argv, "order") == 0) {
+			dcb_apptrust_print_order(&table);
+		} else {
+			fprintf(stderr, "What is \"%s\"?\n", *argv);
+			dcb_apptrust_help_show();
+			return -EINVAL;
+		}
+
+		NEXT_ARG_FWD();
+	} while (argc > 0);
+
+out:
+	close_json_object();
+	return 0;
+}
+
+int dcb_cmd_apptrust(struct dcb *dcb, int argc, char **argv)
+{
+	if (!argc || strcmp(*argv, "help") == 0) {
+		dcb_apptrust_help();
+		return 0;
+	} else if (strcmp(*argv, "show") == 0) {
+		NEXT_ARG_FWD();
+		return dcb_cmd_parse_dev(dcb, argc, argv, dcb_cmd_apptrust_show,
+					 dcb_apptrust_help_show);
+	} else if (strcmp(*argv, "set") == 0) {
+		NEXT_ARG_FWD();
+		return dcb_cmd_parse_dev(dcb, argc, argv, dcb_cmd_apptrust_set,
+					 dcb_apptrust_help_set);
+	} else {
+		fprintf(stderr, "What is \"%s\"?\n", *argv);
+		dcb_apptrust_help();
+		return -EINVAL;
+	}
+}
diff --git a/man/man8/dcb-apptrust.8 b/man/man8/dcb-apptrust.8
new file mode 100644
index 000000000000..03da5edb3cfc
--- /dev/null
+++ b/man/man8/dcb-apptrust.8
@@ -0,0 +1,109 @@
+.TH DCB-APPTRUST 8 "22 November 2022" "iproute2" "Linux"
+.SH NAME
+dcb-apptrust \- show / configure per-selector trust and trust order of the 
+application priority table of the DCB (Data Center Bridging) subsystem.
+.SH SYNOPSIS
+.sp
+.ad l
+.in +8
+
+.ti -8
+.B dcb
+.RI "[ " OPTIONS " ] "
+.B apptrust
+.RI "{ " COMMAND " | " help " }"
+.sp
+
+.ti -8
+.B dcb apptrust show dev
+.RI DEV
+.RB "[ " order " ]"
+
+.ti -8
+.B dcb apptrust set dev
+.RI DEV
+.RB "[ " order " " \fiSEL-LIST\fB " ]"
+
+.ti -8
+.IR SEL-LIST " := [ " SEL-LIST " ] " SEL
+
+.ti -8
+.IR SEL " := { " ethtype " | " stream-port " | " dgram-port " | " port " | " dscp " | " pcp " } "
+
+.SH DESCRIPTION
+
+.B dcb apptrust
+is used to configure per-selector trust and trust order of the
+Application Priority Table, see
+.BR dcb-app (8)
+for details on how to configure app table entries.
+
+Selector trust can be used by the
+software stack, or drivers (most likely the latter), when querying the APP
+table, to determine if an APP entry should take effect, or not. Additionaly, the
+order of the trusted selectors will dictate which selector should take
+precedence, in the case of multiple different APP table selectors being present.
+
+.SH COMMANDS
+
+.TP
+.B show
+Display all trusted selectors.
+
+.TP
+.B set
+Set new list of trusted selectors. Empty list is effectively the same as
+removing trust entirely.
+
+.SH PARAMETERS
+
+The following describes only the write direction, i.e. as used with the
+\fBset\fR command. For the \fBshow\fR command, the parameter name is to be used
+as a simple keyword without further arguments. This instructs the tool to show
+the values of a given parameter.
+
+.TP
+.B order \fISEL-LIST
+\fISEL-LIST\fR is a space-separated list of selector names. Possible selector
+values are: 
+.B ethtype,
+.B stream-port,
+.B dgram-port,
+.B port,
+.B dscp,
+and
+.B pcp
+
+
+.SH EXAMPLE & USAGE
+
+Set trust order to: dscp, pcp for eth0:
+.P
+# dcb apptrust set dev eth0 order dscp pcp
+
+Set trust order to: port (stream or dgram), pcp, ethtype for eth1:
+.P
+# dcb apptrust set dev eth1 order port pcp ethtype
+
+Show what was set:
+
+.P
+# dcb apptrust show dev eth0
+.br
+order: port pcp ethtype
+
+.SH EXIT STATUS
+Exit status is 0 if command was successful or a positive integer upon failure.
+
+.SH SEE ALSO
+.BR dcb (8),
+.BR dcb-app (8)
+
+.SH REPORTING BUGS
+Report any bugs to the Network Developers mailing list
+.B <netdev@vger.kernel.org>
+where the development and maintenance is primarily done.
+You do not have to be subscribed to the list to send a message there.
+
+.SH AUTHOR
+Daniel Machon <daniel.machon@microchip.com>
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH iproute2-next v3 1/2] dcb: add new pcp-prio parameter to dcb app
  2022-12-02  9:22 ` [PATCH iproute2-next v3 1/2] dcb: add new pcp-prio parameter to dcb app Daniel Machon
@ 2022-12-03 17:00   ` Stephen Hemminger
  2022-12-04 22:27     ` Daniel.Machon
  0 siblings, 1 reply; 11+ messages in thread
From: Stephen Hemminger @ 2022-12-03 17:00 UTC (permalink / raw)
  To: Daniel Machon
  Cc: netdev, dsahern, petrm, maxime.chevallier, vladimir.oltean,
	UNGLinuxDriver

On Fri, 2 Dec 2022 10:22:34 +0100
Daniel Machon <daniel.machon@microchip.com> wrote:

> +static int dcb_app_print_key_pcp(__u16 protocol)
> +{
> +	/* Print in numerical form, if protocol value is out-of-range */
> +	if (protocol > DCB_APP_PCP_MAX) {
> +		fprintf(stderr, "Unknown PCP key: %d\n", protocol);
> +		return print_uint(PRINT_ANY, NULL, "%d:", protocol);
> +	}
> +
> +	return print_string(PRINT_ANY, NULL, "%s:", pcp_names[protocol]);
> +}

This is not an application friendly way to produce JSON output.
You need to put a key on each one, and value should not contain colon.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH iproute2-next v3 1/2] dcb: add new pcp-prio parameter to dcb app
  2022-12-03 17:00   ` Stephen Hemminger
@ 2022-12-04 22:27     ` Daniel.Machon
  2022-12-05  1:52       ` Stephen Hemminger
  0 siblings, 1 reply; 11+ messages in thread
From: Daniel.Machon @ 2022-12-04 22:27 UTC (permalink / raw)
  To: stephen
  Cc: netdev, dsahern, petrm, maxime.chevallier, vladimir.oltean,
	UNGLinuxDriver

> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Fri, 2 Dec 2022 10:22:34 +0100
> Daniel Machon <daniel.machon@microchip.com> wrote:
> 
> > +static int dcb_app_print_key_pcp(__u16 protocol)
> > +{
> > +     /* Print in numerical form, if protocol value is out-of-range */
> > +     if (protocol > DCB_APP_PCP_MAX) {
> > +             fprintf(stderr, "Unknown PCP key: %d\n", protocol);
> > +             return print_uint(PRINT_ANY, NULL, "%d:", protocol);
> > +     }
> > +
> > +     return print_string(PRINT_ANY, NULL, "%s:", pcp_names[protocol]);
> > +}
> 
> This is not an application friendly way to produce JSON output.
> You need to put a key on each one, and value should not contain colon.

Hi Stephen,

Trying to understand your comment.

Are you talking about not producing any JSON output with the symbolic
PCP values? eg. ["1de", 1] -> [8, 1]. So basically print with PRINT_FP
in case of printing in JSON context?

/Daniel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH iproute2-next v3 1/2] dcb: add new pcp-prio parameter to dcb app
  2022-12-04 22:27     ` Daniel.Machon
@ 2022-12-05  1:52       ` Stephen Hemminger
  2022-12-05  9:19         ` Daniel.Machon
  0 siblings, 1 reply; 11+ messages in thread
From: Stephen Hemminger @ 2022-12-05  1:52 UTC (permalink / raw)
  To: Daniel.Machon
  Cc: netdev, dsahern, petrm, maxime.chevallier, vladimir.oltean,
	UNGLinuxDriver

On Sun, 4 Dec 2022 22:27:40 +0000
<Daniel.Machon@microchip.com> wrote:

> > EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> > 
> > On Fri, 2 Dec 2022 10:22:34 +0100
> > Daniel Machon <daniel.machon@microchip.com> wrote:
> >   
> > > +static int dcb_app_print_key_pcp(__u16 protocol)
> > > +{
> > > +     /* Print in numerical form, if protocol value is out-of-range */
> > > +     if (protocol > DCB_APP_PCP_MAX) {
> > > +             fprintf(stderr, "Unknown PCP key: %d\n", protocol);
> > > +             return print_uint(PRINT_ANY, NULL, "%d:", protocol);
> > > +     }
> > > +
> > > +     return print_string(PRINT_ANY, NULL, "%s:", pcp_names[protocol]);
> > > +}  
> > 
> > This is not an application friendly way to produce JSON output.
> > You need to put a key on each one, and value should not contain colon.  
> 
> Hi Stephen,
> 
> Trying to understand your comment.
> 
> Are you talking about not producing any JSON output with the symbolic
> PCP values? eg. ["1de", 1] -> [8, 1]. So basically print with PRINT_FP
> in case of printing in JSON context?
> 
> /Daniel

What does output look like in json and non-json versions?
My concern that the json version would be awkward and have colons in it, but looks
like it won't.

For the unknown key type is printing error necessary? Maybe just show it in numeric form.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH iproute2-next v3 1/2] dcb: add new pcp-prio parameter to dcb app
  2022-12-05  1:52       ` Stephen Hemminger
@ 2022-12-05  9:19         ` Daniel.Machon
  2022-12-05 16:23           ` Stephen Hemminger
  0 siblings, 1 reply; 11+ messages in thread
From: Daniel.Machon @ 2022-12-05  9:19 UTC (permalink / raw)
  To: stephen
  Cc: netdev, dsahern, petrm, maxime.chevallier, vladimir.oltean,
	UNGLinuxDriver

> > > On Fri, 2 Dec 2022 10:22:34 +0100
> > > Daniel Machon <daniel.machon@microchip.com> wrote:
> > >
> > > > +static int dcb_app_print_key_pcp(__u16 protocol)
> > > > +{
> > > > +     /* Print in numerical form, if protocol value is out-of-range */
> > > > +     if (protocol > DCB_APP_PCP_MAX) {
> > > > +             fprintf(stderr, "Unknown PCP key: %d\n", protocol);
> > > > +             return print_uint(PRINT_ANY, NULL, "%d:", protocol);
> > > > +     }
> > > > +
> > > > +     return print_string(PRINT_ANY, NULL, "%s:", pcp_names[protocol]);
> > > > +}
> > >
> > > This is not an application friendly way to produce JSON output.
> > > You need to put a key on each one, and value should not contain colon.
> >
> > Hi Stephen,
> >
> > Trying to understand your comment.
> >
> > Are you talking about not producing any JSON output with the symbolic
> > PCP values? eg. ["1de", 1] -> [8, 1]. So basically print with PRINT_FP
> > in case of printing in JSON context?
> >
> > /Daniel
> 
> What does output look like in json and non-json versions?

non-JSON: pcp-prio 1de:1
JSON    : {"pcp_prio":[["1de",1]]}

> My concern that the json version would be awkward and have colons in it, but looks
> like it won't.

Yeah, the "%s:" format is only used in non-JSON context, so we are good
here.

> 
> For the unknown key type is printing error necessary? Maybe just show it in numeric form.

No not necessary, I'll get rid of it.

/ Daniel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH iproute2-next v3 1/2] dcb: add new pcp-prio parameter to dcb app
  2022-12-05  9:19         ` Daniel.Machon
@ 2022-12-05 16:23           ` Stephen Hemminger
  2022-12-05 19:19             ` Daniel.Machon
  0 siblings, 1 reply; 11+ messages in thread
From: Stephen Hemminger @ 2022-12-05 16:23 UTC (permalink / raw)
  To: Daniel.Machon
  Cc: netdev, dsahern, petrm, maxime.chevallier, vladimir.oltean,
	UNGLinuxDriver

On Mon, 5 Dec 2022 09:19:06 +0000
<Daniel.Machon@microchip.com> wrote:

> > > Trying to understand your comment.
> > >
> > > Are you talking about not producing any JSON output with the symbolic
> > > PCP values? eg. ["1de", 1] -> [8, 1]. So basically print with PRINT_FP
> > > in case of printing in JSON context?
> > >
> > > /Daniel  
> > 
> > What does output look like in json and non-json versions?  
> 
> non-JSON: pcp-prio 1de:1
> JSON    : {"pcp_prio":[["1de",1]]}

Would the JSON be better as:
	{ "pcp_prio" :[ { "1de":1 } ] }

It looks like the PCP values are both unique and used in a name/value manner.

> 
> > My concern that the json version would be awkward and have colons in it, but looks
> > like it won't.  
> 
> Yeah, the "%s:" format is only used in non-JSON context, so we are good
> here.
> 
> > 
> > For the unknown key type is printing error necessary? Maybe just show it in numeric form.  
> 
> No not necessary, I'll get rid of it.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH iproute2-next v3 1/2] dcb: add new pcp-prio parameter to dcb app
  2022-12-05 16:23           ` Stephen Hemminger
@ 2022-12-05 19:19             ` Daniel.Machon
  2022-12-05 21:05               ` Stephen Hemminger
  2022-12-06  8:55               ` Petr Machata
  0 siblings, 2 replies; 11+ messages in thread
From: Daniel.Machon @ 2022-12-05 19:19 UTC (permalink / raw)
  To: stephen
  Cc: netdev, dsahern, petrm, maxime.chevallier, vladimir.oltean,
	UNGLinuxDriver

> On Mon, 5 Dec 2022 09:19:06 +0000
> <Daniel.Machon@microchip.com> wrote:
> 
> > > > Trying to understand your comment.
> > > >
> > > > Are you talking about not producing any JSON output with the symbolic
> > > > PCP values? eg. ["1de", 1] -> [8, 1]. So basically print with PRINT_FP
> > > > in case of printing in JSON context?
> > > >
> > > > /Daniel
> > >
> > > What does output look like in json and non-json versions?
> >
> > non-JSON: pcp-prio 1de:1
> > JSON    : {"pcp_prio":[["1de",1]]}
> 
> Would the JSON be better as:
>         { "pcp_prio" :[ { "1de":1 } ] }
> 
> It looks like the PCP values are both unique and used in a name/value manner.

In this case I think it would be best to stay consistent with the rest
of the dcb app code. All priority mappings are printed using the
dcb_app_print_filtered() (now also the pcp-prio), which creates an
array, for whatever reason. 

If you are OK with this, I will go ahead and create v4, with the print
warning removed.

/Daniel

> 
> >
> > > My concern that the json version would be awkward and have colons in it, but looks
> > > like it won't.
> >
> > Yeah, the "%s:" format is only used in non-JSON context, so we are good
> > here.
> >
> > >
> > > For the unknown key type is printing error necessary? Maybe just show it in numeric form.
> >
> > No not necessary, I'll get rid of it.
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH iproute2-next v3 1/2] dcb: add new pcp-prio parameter to dcb app
  2022-12-05 19:19             ` Daniel.Machon
@ 2022-12-05 21:05               ` Stephen Hemminger
  2022-12-06  8:55               ` Petr Machata
  1 sibling, 0 replies; 11+ messages in thread
From: Stephen Hemminger @ 2022-12-05 21:05 UTC (permalink / raw)
  To: Daniel.Machon
  Cc: netdev, dsahern, petrm, maxime.chevallier, vladimir.oltean,
	UNGLinuxDriver

On Mon, 5 Dec 2022 19:19:35 +0000
<Daniel.Machon@microchip.com> wrote:

> > On Mon, 5 Dec 2022 09:19:06 +0000
> > <Daniel.Machon@microchip.com> wrote:
> >   
> > > > > Trying to understand your comment.
> > > > >
> > > > > Are you talking about not producing any JSON output with the symbolic
> > > > > PCP values? eg. ["1de", 1] -> [8, 1]. So basically print with PRINT_FP
> > > > > in case of printing in JSON context?
> > > > >
> > > > > /Daniel  
> > > >
> > > > What does output look like in json and non-json versions?  
> > >
> > > non-JSON: pcp-prio 1de:1
> > > JSON    : {"pcp_prio":[["1de",1]]}  
> > 
> > Would the JSON be better as:
> >         { "pcp_prio" :[ { "1de":1 } ] }
> > 
> > It looks like the PCP values are both unique and used in a name/value manner.  
> 
> In this case I think it would be best to stay consistent with the rest
> of the dcb app code. All priority mappings are printed using the
> dcb_app_print_filtered() (now also the pcp-prio), which creates an
> array, for whatever reason. 
> 
> If you are OK with this, I will go ahead and create v4, with the print
> warning removed.
> 
> /Daniel

I am ok with what ever you decide, just wanted to make sure you thought about it

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH iproute2-next v3 1/2] dcb: add new pcp-prio parameter to dcb app
  2022-12-05 19:19             ` Daniel.Machon
  2022-12-05 21:05               ` Stephen Hemminger
@ 2022-12-06  8:55               ` Petr Machata
  1 sibling, 0 replies; 11+ messages in thread
From: Petr Machata @ 2022-12-06  8:55 UTC (permalink / raw)
  To: Daniel.Machon
  Cc: stephen, netdev, dsahern, petrm, maxime.chevallier,
	vladimir.oltean, UNGLinuxDriver


<Daniel.Machon@microchip.com> writes:

>> On Mon, 5 Dec 2022 09:19:06 +0000
>> <Daniel.Machon@microchip.com> wrote:
>> 
>> > > > Trying to understand your comment.
>> > > >
>> > > > Are you talking about not producing any JSON output with the symbolic
>> > > > PCP values? eg. ["1de", 1] -> [8, 1]. So basically print with PRINT_FP
>> > > > in case of printing in JSON context?
>> > >
>> > > What does output look like in json and non-json versions?
>> >
>> > non-JSON: pcp-prio 1de:1
>> > JSON    : {"pcp_prio":[["1de",1]]}
>> 
>> Would the JSON be better as:
>>         { "pcp_prio" :[ { "1de":1 } ] }
>> 
>> It looks like the PCP values are both unique and used in a name/value manner.
>
> In this case I think it would be best to stay consistent with the rest
> of the dcb app code. All priority mappings are printed using the
> dcb_app_print_filtered() (now also the pcp-prio), which creates an
> array, for whatever reason.

The reason is that APP mappings are not unique. It is OK to have rules
for both 1de:1 and 1de:2. And 2de:1 and 2de:2 too, it's a full m:n
relationship. A JSON dictionary would not work well for this purpose.
(It's not technically forbidden to have duplicate keys in a JSON
dictionary, just discouraged, i.e. SHOULD NOT rather than SHALL NOT, but
e.g. jq then doesn't let you work with both entries.)

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2022-12-06  9:05 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-02  9:22 [PATCH iproute2-next v3 0/2] Add pcp-prio and new apptrust subcommand Daniel Machon
2022-12-02  9:22 ` [PATCH iproute2-next v3 1/2] dcb: add new pcp-prio parameter to dcb app Daniel Machon
2022-12-03 17:00   ` Stephen Hemminger
2022-12-04 22:27     ` Daniel.Machon
2022-12-05  1:52       ` Stephen Hemminger
2022-12-05  9:19         ` Daniel.Machon
2022-12-05 16:23           ` Stephen Hemminger
2022-12-05 19:19             ` Daniel.Machon
2022-12-05 21:05               ` Stephen Hemminger
2022-12-06  8:55               ` Petr Machata
2022-12-02  9:22 ` [PATCH iproute2-next v3 2/2] dcb: add new subcommand for apptrust Daniel Machon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.