lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20220915135150.1935656-1-michal.wilczynski@intel.com>
Date:   Thu, 15 Sep 2022 15:51:50 +0200
From:   Michal Wilczynski <michal.wilczynski@...el.com>
To:     netdev@...r.kernel.org
Cc:     alexandr.lobakin@...el.com, dchumak@...dia.com, maximmi@...dia.com,
        jiri@...nulli.us, simon.horman@...igine.com,
        jacob.e.keller@...el.com, jesse.brandeburg@...el.com,
        przemyslaw.kitszel@...el.com,
        Michal Wilczynski <michal.wilczynski@...el.com>
Subject: [RFC PATCH iproute2-next] iproute2: Support for queues and new parameters

New object type 'queue' is being added in the kernel, and new parameters
are being added: 'tx_weight' and 'tx_priority'.

Add support for configuration of these new elements.
Correspoding kernel changes:
https://lore.kernel.org/netdev/20220915134239.1935604-1-michal.wilczynski@intel.com/

Signed-off-by: Michal Wilczynski <michal.wilczynski@...el.com>
---
 devlink/devlink.c            | 137 ++++++++++++++++++++++++++++++-----
 include/uapi/linux/devlink.h |   8 +-
 2 files changed, 127 insertions(+), 18 deletions(-)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index 4f77e42f..abd9b823 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -297,6 +297,9 @@ static void ifname_map_free(struct ifname_map *ifname_map)
 #define DL_OPT_LINECARD		BIT(52)
 #define DL_OPT_LINECARD_TYPE	BIT(53)
 #define DL_OPT_SELFTESTS	BIT(54)
+#define DL_OPT_PORT_FN_RATE_QUEUE	BIT(55)
+#define DL_OPT_PORT_FN_RATE_TX_PRIORITY	BIT(56)
+#define DL_OPT_PORT_FN_RATE_TX_WEIGHT	BIT(57)
 
 struct dl_opts {
 	uint64_t present; /* flags of present items */
@@ -353,8 +356,11 @@ struct dl_opts {
 	uint16_t port_pfnumber;
 	uint8_t port_fn_state;
 	uint16_t rate_type;
+	uint16_t rate_queue;
 	uint64_t rate_tx_share;
 	uint64_t rate_tx_max;
+	uint16_t rate_tx_priority;
+	uint16_t rate_tx_weight;
 	char *rate_node_name;
 	const char *rate_parent_node;
 	uint32_t linecard_index;
@@ -1043,6 +1049,23 @@ static int dl_argv_handle_both(struct dl *dl, char **p_bus_name,
 	return 0;
 }
 
+static int __dl_argv_handle_queue_name(char *str, char **p_bus_name,
+				       char **p_dev_name, char **p_name)
+{
+	char *handlestr, *after, *before;
+	int err;
+
+	err = str_split_by_char(str, &handlestr, p_name, '/');
+	if (err)
+		return err;
+
+	err = str_split_by_char(handlestr, &before, &after, '/');
+	if (err)
+		return err;
+
+	return str_split_by_char(handlestr, p_bus_name, p_dev_name, '/');
+}
+
 static int __dl_argv_handle_name(char *str, char **p_bus_name,
 				 char **p_dev_name, char **p_name)
 {
@@ -1103,13 +1126,33 @@ static int dl_argv_handle_rate_node(struct dl *dl, char **p_bus_name,
 
 static int dl_argv_handle_rate(struct dl *dl, char **p_bus_name,
 			       char **p_dev_name, uint32_t *p_port_index,
-			       char **p_node_name, uint64_t *p_handle_bit)
+			       uint16_t *queue_id, char **p_node_name,
+			       uint64_t *p_handle_bit)
 {
 	char *str = dl_argv_next(dl);
 	char *identifier;
 	int err;
 
+	if (strstr(str, "queue")) {
+		err = __dl_argv_handle_queue_name(str, p_bus_name, p_dev_name, &identifier);
+		if (err) {
+			pr_err("Identification \"%s\" is invalid\n"
+			       "Expected \"bus_name/dev_name/queue/queue_id identification.",
+			       str);
+			return err;
+		}
+
+		if (!*identifier) {
+			pr_err("Identifier cannot be empty");
+			return -EINVAL;
+		}
+		err = get_u16(queue_id, identifier, 10);
+		*p_handle_bit = DL_OPT_PORT_FN_RATE_QUEUE;
+		return err;
+	}
+
 	err = ident_str_validate(str, 2);
+
 	if (err) {
 		pr_err("Expected \"bus_name/dev_name/node\" or "
 		       "\"bus_name/dev_name/port_index\" identification.\n");
@@ -1464,10 +1507,12 @@ static int port_fn_state_parse(const char *statestr, uint8_t *state)
 
 static int port_fn_rate_type_get(const char *typestr, uint16_t *type)
 {
-	if (!strcmp(typestr, "leaf"))
-		*type = DEVLINK_RATE_TYPE_LEAF;
+	if (!strcmp(typestr, "vport"))
+		*type = DEVLINK_RATE_TYPE_VPORT;
 	else if (!strcmp(typestr, "node"))
 		*type = DEVLINK_RATE_TYPE_NODE;
+	else if (!strcmp(typestr, "queue"))
+		*type = DEVLINK_RATE_TYPE_QUEUE;
 	else
 		return -EINVAL;
 	return 0;
@@ -1572,7 +1617,7 @@ static int dl_argv_parse(struct dl *dl, uint64_t o_required,
 		uint64_t handle_bit;
 
 		err = dl_argv_handle_rate(dl, &opts->bus_name, &opts->dev_name,
-					  &opts->port_index,
+					  &opts->port_index, &opts->rate_queue,
 					  &opts->rate_node_name,
 					  &handle_bit);
 		if (err)
@@ -2049,13 +2094,33 @@ static int dl_argv_parse(struct dl *dl, uint64_t o_required,
 			if (err)
 				return err;
 			o_found |= DL_OPT_PORT_FN_RATE_TX_MAX;
-		} else if (dl_argv_match(dl, "parent") &&
-			   (o_all & DL_OPT_PORT_FN_RATE_PARENT)) {
+		} else if (dl_argv_match(dl, "tx_priority") &&
+			   (o_all & DL_OPT_PORT_FN_RATE_TX_PRIORITY)) {
+			dl_arg_inc(dl);
+			err = dl_argv_uint16_t(dl, &opts->rate_tx_priority);
+			if (err)
+				return err;
+			o_found |= DL_OPT_PORT_FN_RATE_TX_PRIORITY;
+		} else if (dl_argv_match(dl, "tx_weight") &&
+			   (o_all & DL_OPT_PORT_FN_RATE_TX_WEIGHT)) {
+			dl_arg_inc(dl);
+			err = dl_argv_uint16_t(dl, &opts->rate_tx_weight);
+			if (err)
+				return err;
+			o_found |= DL_OPT_PORT_FN_RATE_TX_WEIGHT;
+		} else if (dl_argv_match(dl, "parent")
+			 /*  (o_all & DL_OPT_PORT_FN_RATE_PARENT)*/) {
 			dl_arg_inc(dl);
 			err = dl_argv_str(dl, &opts->rate_parent_node);
 			if (err)
 				return err;
 			o_found |= DL_OPT_PORT_FN_RATE_PARENT;
+		} else if (dl_argv_match(dl, "queue")) {
+			dl_arg_inc(dl);
+			err = dl_argv_uint16_t(dl, &opts->rate_queue);
+			if (err)
+				return err;
+			o_found |= DL_OPT_PORT_FN_RATE_QUEUE;
 		} else if (dl_argv_match(dl, "noparent") &&
 			   (o_all & DL_OPT_PORT_FN_RATE_PARENT)) {
 			dl_arg_inc(dl);
@@ -2185,6 +2250,10 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl)
 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, opts->dev_name);
 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_RATE_NODE_NAME,
 				  opts->rate_node_name);
+	} else if (opts->present & DL_OPT_PORT_FN_RATE_QUEUE) {
+		mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, opts->bus_name);
+		mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, opts->dev_name);
+		mnl_attr_put_u16(nlh, DEVLINK_ATTR_RATE_QUEUE, opts->rate_queue);
 	}
 	if (opts->present & DL_OPT_PORT_TYPE)
 		mnl_attr_put_u16(nlh, DEVLINK_ATTR_PORT_TYPE,
@@ -2317,12 +2386,21 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl)
 	if (opts->present & DL_OPT_PORT_FN_RATE_TX_SHARE)
 		mnl_attr_put_u64(nlh, DEVLINK_ATTR_RATE_TX_SHARE,
 				 opts->rate_tx_share);
+	if (opts->present & DL_OPT_PORT_FN_RATE_TX_PRIORITY)
+		mnl_attr_put_u16(nlh, DEVLINK_ATTR_RATE_TX_PRIORITY,
+				 opts->rate_tx_priority);
+	if (opts->present & DL_OPT_PORT_FN_RATE_TX_WEIGHT)
+		mnl_attr_put_u16(nlh, DEVLINK_ATTR_RATE_TX_WEIGHT,
+				 opts->rate_tx_weight);
 	if (opts->present & DL_OPT_PORT_FN_RATE_TX_MAX)
 		mnl_attr_put_u64(nlh, DEVLINK_ATTR_RATE_TX_MAX,
 				 opts->rate_tx_max);
 	if (opts->present & DL_OPT_PORT_FN_RATE_PARENT)
 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_RATE_PARENT_NODE_NAME,
 				  opts->rate_parent_node);
+	if (opts->present & DL_OPT_PORT_FN_RATE_QUEUE)
+		mnl_attr_put_u16(nlh, DEVLINK_ATTR_RATE_QUEUE,
+				 opts->rate_queue);
 	if (opts->present & DL_OPT_LINECARD)
 		mnl_attr_put_u32(nlh, DEVLINK_ATTR_LINECARD_INDEX,
 				 opts->linecard_index);
@@ -4881,12 +4959,19 @@ pr_out_port_rate_handle_start(struct dl *dl, struct nlattr **tb, bool try_nice)
 	const char *bus_name;
 	const char *dev_name;
 	const char *node_name;
-	static char buf[64];
+	static char buf[128];
+	uint32_t queue_id;
 
 	bus_name = mnl_attr_get_str(tb[DEVLINK_ATTR_BUS_NAME]);
 	dev_name = mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]);
-	node_name = mnl_attr_get_str(tb[DEVLINK_ATTR_RATE_NODE_NAME]);
-	sprintf(buf, "%s/%s/%s", bus_name, dev_name, node_name);
+
+	if (tb[DEVLINK_ATTR_RATE_QUEUE]) {
+		queue_id = mnl_attr_get_u16(tb[DEVLINK_ATTR_RATE_QUEUE]);
+		sprintf(buf, "%s/%s/queue/%u", bus_name, dev_name, queue_id);
+	} else if (tb[DEVLINK_ATTR_RATE_NODE_NAME]) {
+		node_name = mnl_attr_get_str(tb[DEVLINK_ATTR_RATE_NODE_NAME]);
+		sprintf(buf, "%s/%s/%s", bus_name, dev_name, node_name);
+	}
 	if (dl->json_output)
 		open_json_object(buf);
 	else
@@ -4896,10 +4981,12 @@ pr_out_port_rate_handle_start(struct dl *dl, struct nlattr **tb, bool try_nice)
 static char *port_rate_type_name(uint16_t type)
 {
 	switch (type) {
-	case DEVLINK_RATE_TYPE_LEAF:
-		return "leaf";
+	case DEVLINK_RATE_TYPE_VPORT:
+		return "vport";
 	case DEVLINK_RATE_TYPE_NODE:
 		return "node";
+	case DEVLINK_RATE_TYPE_QUEUE:
+		return "queue";
 	default:
 		return "<unknown type>";
 	}
@@ -4908,7 +4995,7 @@ static char *port_rate_type_name(uint16_t type)
 static void pr_out_port_fn_rate(struct dl *dl, struct nlattr **tb)
 {
 
-	if (!tb[DEVLINK_ATTR_RATE_NODE_NAME])
+	if (!tb[DEVLINK_ATTR_RATE_NODE_NAME] && !tb[DEVLINK_ATTR_RATE_QUEUE])
 		pr_out_port_handle_start(dl, tb, false);
 	else
 		pr_out_port_rate_handle_start(dl, tb, false);
@@ -4956,7 +5043,8 @@ static int cmd_port_fn_rate_show_cb(const struct nlmsghdr *nlh, void *data)
 	mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
 	if ((!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
 	     !tb[DEVLINK_ATTR_PORT_INDEX]) &&
-	    !tb[DEVLINK_ATTR_RATE_NODE_NAME]) {
+	     !tb[DEVLINK_ATTR_RATE_NODE_NAME] &&
+	     !tb[DEVLINK_ATTR_RATE_QUEUE]) {
 		return MNL_CB_ERROR;
 	}
 	pr_out_port_fn_rate(dl, tb);
@@ -4968,10 +5056,12 @@ static void cmd_port_fn_rate_help(void)
 	pr_err("Usage: devlink port function rate help\n");
 	pr_err("       devlink port function rate show [ DEV/{ PORT_INDEX | NODE_NAME } ]\n");
 	pr_err("       devlink port function rate add DEV/NODE_NAME\n");
-	pr_err("               [ tx_share VAL ][ tx_max VAL ][ { parent NODE_NAME | noparent } ]\n");
+	pr_err("               [ tx_share VAL ][ tx_max VAL ][ tx_priority ][ { parent NODE_NAME | noparent } ]\n");
 	pr_err("       devlink port function rate del DEV/NODE_NAME\n");
 	pr_err("       devlink port function rate set DEV/{ PORT_INDEX | NODE_NAME }\n");
-	pr_err("               [ tx_share VAL ][ tx_max VAL ][ { parent NODE_NAME | noparent } ]\n\n");
+	pr_err("               [ tx_share VAL ][ tx_max VAL ][ tx_priority ][ { parent NODE_NAME | noparent } ]\n\n");
+	pr_err("       devlink port function rate set DEV/queue/QUEUE_ID\n");
+	pr_err("               [ tx_share VAL ][ tx_max VAL ][ tx_priority ][ { parent NODE_NAME | noparent } ]\n\n");
 	pr_err("       VAL - float or integer value in units of bits or bytes per second (bit|bps)\n");
 	pr_err("       and SI (k-, m-, g-, t-) or IEC (ki-, mi-, gi-, ti-) case-insensitive prefix.\n");
 	pr_err("       Bare number, means bits per second, is possible.\n\n");
@@ -5031,7 +5121,11 @@ static int cmd_port_fn_rate_add(struct dl *dl)
 	int err;
 
 	err = dl_argv_parse(dl, DL_OPT_PORT_FN_RATE_NODE_NAME,
-			    DL_OPT_PORT_FN_RATE_TX_SHARE | DL_OPT_PORT_FN_RATE_TX_MAX);
+			    DL_OPT_PORT_FN_RATE_TX_SHARE | DL_OPT_PORT_FN_RATE_TX_MAX |
+			    DL_OPT_PORT_FN_RATE_TX_PRIORITY |
+			    DL_OPT_PORT_FN_RATE_TX_WEIGHT |
+			    DL_OPT_PORT_FN_RATE_PARENT);
+
 	if (err)
 		return err;
 
@@ -5085,6 +5179,12 @@ static int port_fn_get_rates_cb(const struct nlmsghdr *nlh, void *data)
 	if (tb[DEVLINK_ATTR_RATE_TX_MAX])
 		opts->rate_tx_max =
 			mnl_attr_get_u64(tb[DEVLINK_ATTR_RATE_TX_MAX]);
+	if (tb[DEVLINK_ATTR_RATE_TX_PRIORITY])
+		opts->rate_tx_priority =
+			mnl_attr_get_u16(tb[DEVLINK_ATTR_RATE_TX_PRIORITY]);
+	if (tb[DEVLINK_ATTR_RATE_TX_WEIGHT])
+		opts->rate_tx_weight =
+			mnl_attr_get_u16(tb[DEVLINK_ATTR_RATE_TX_WEIGHT]);
 	return MNL_CB_OK;
 }
 
@@ -5098,7 +5198,10 @@ static int cmd_port_fn_rate_set(struct dl *dl)
 				DL_OPT_PORT_FN_RATE_NODE_NAME,
 				DL_OPT_PORT_FN_RATE_TX_SHARE |
 				DL_OPT_PORT_FN_RATE_TX_MAX |
-				DL_OPT_PORT_FN_RATE_PARENT);
+				DL_OPT_PORT_FN_RATE_TX_PRIORITY |
+				DL_OPT_PORT_FN_RATE_TX_WEIGHT |
+				DL_OPT_PORT_FN_RATE_PARENT |
+				DL_OPT_PORT_FN_RATE_QUEUE);
 	if (err)
 		return err;
 
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 0224b8bd..7b6576f5 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -220,8 +220,10 @@ enum devlink_port_flavour {
 };
 
 enum devlink_rate_type {
-	DEVLINK_RATE_TYPE_LEAF,
+	DEVLINK_RATE_TYPE_LEAF, /* deprecated, leaving this for backward compatibility */
 	DEVLINK_RATE_TYPE_NODE,
+	DEVLINK_RATE_TYPE_QUEUE,
+	DEVLINK_RATE_TYPE_VPORT,
 };
 
 enum devlink_param_cmode {
@@ -607,6 +609,10 @@ enum devlink_attr {
 
 	DEVLINK_ATTR_SELFTESTS,			/* nested */
 
+	DEVLINK_ATTR_RATE_QUEUE,		/* u16 */
+	DEVLINK_ATTR_RATE_TX_PRIORITY,		/* u16 */
+	DEVLINK_ATTR_RATE_TX_WEIGHT,		/* u16 */
+
 	/* add new attributes above here, update the policy in devlink.c */
 
 	__DEVLINK_ATTR_MAX,
-- 
2.27.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ