naccyde / rpms / iproute

Forked from rpms/iproute 9 months ago
Clone
Blob Blame History Raw
From 01194858b0ee630c56b7988b3e911ccf008b89ff Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Sat, 9 Jul 2016 11:33:14 +0200
Subject: [PATCH] devlink: allow to parse both devlink and port handle in the
 same time

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1342515
Upstream Status: iproute2.git commit 2f85a9c535874

commit 2f85a9c535874e721cfc8b8743325afc93a8b1fa
Author: Jiri Pirko <jiri@mellanox.com>
Date:   Fri Apr 15 09:51:50 2016 +0200

    devlink: allow to parse both devlink and port handle in the same time

    For filtering purposes, it makes sense for used to either specify
    devlink handle of port handle.

    Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 devlink/devlink.c | 109 ++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 90 insertions(+), 19 deletions(-)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index d436bbf..e2e0413 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -363,6 +363,12 @@ static int strtouint32_t(const char *str, uint32_t *p_val)
 	return 0;
 }
 
+static int __dl_argv_handle(char *str, char **p_bus_name, char **p_dev_name)
+{
+	strslashrsplit(str, p_bus_name, p_dev_name);
+	return 0;
+}
+
 static int dl_argv_handle(struct dl *dl, char **p_bus_name, char **p_dev_name)
 {
 	char *str = dl_argv_next(dl);
@@ -376,8 +382,40 @@ static int dl_argv_handle(struct dl *dl, char **p_bus_name, char **p_dev_name)
 		pr_err("Expected \"bus_name/dev_name\".\n");
 		return -EINVAL;
 	}
+	return __dl_argv_handle(str, p_bus_name, p_dev_name);
+}
 
-	strslashrsplit(str, p_bus_name, p_dev_name);
+static int __dl_argv_handle_port(char *str,
+				 char **p_bus_name, char **p_dev_name,
+				 uint32_t *p_port_index)
+{
+	char *handlestr = handlestr;
+	char *portstr = portstr;
+	int err;
+
+	strslashrsplit(str, &handlestr, &portstr);
+	err = strtouint32_t(portstr, p_port_index);
+	if (err) {
+		pr_err("Port index \"%s\" is not a number or not within range\n",
+		       portstr);
+		return err;
+	}
+	strslashrsplit(handlestr, p_bus_name, p_dev_name);
+	return 0;
+}
+
+static int __dl_argv_handle_port_ifname(struct dl *dl, char *str,
+					char **p_bus_name, char **p_dev_name,
+					uint32_t *p_port_index)
+{
+	int err;
+
+	err = ifname_map_lookup(dl, str, p_bus_name, p_dev_name,
+				p_port_index);
+	if (err) {
+		pr_err("Netdevice \"%s\" not found\n", str);
+		return err;
+	}
 	return 0;
 }
 
@@ -386,7 +424,6 @@ static int dl_argv_handle_port(struct dl *dl, char **p_bus_name,
 {
 	char *str = dl_argv_next(dl);
 	unsigned int slash_count;
-	int err;
 
 	if (!str) {
 		pr_err("Port identification (\"bus_name/dev_name/port_index\" or \"netdev ifname\") expected.\n");
@@ -398,26 +435,52 @@ static int dl_argv_handle_port(struct dl *dl, char **p_bus_name,
 		pr_err("Expected \"bus_name/dev_name/port_index\" or \"netdev_ifname\".\n");
 		return -EINVAL;
 	}
-
 	if (slash_count == 2) {
-		char *handlestr = handlestr;
-		char *portstr = portstr;
-
-		err = strslashrsplit(str, &handlestr, &portstr);
-		err = strtouint32_t(portstr, p_port_index);
-		if (err) {
-			pr_err("Port index \"%s\" is not a number or not within range\n",
-			       portstr);
+		return __dl_argv_handle_port(str, p_bus_name,
+					     p_dev_name, p_port_index);
+	} else if (slash_count == 0) {
+		return __dl_argv_handle_port_ifname(dl, str, p_bus_name,
+						    p_dev_name, p_port_index);
+	}
+	return 0;
+}
+
+static int dl_argv_handle_both(struct dl *dl, char **p_bus_name,
+			       char **p_dev_name, uint32_t *p_port_index,
+			       uint32_t *p_handle_bit)
+{
+	char *str = dl_argv_next(dl);
+	unsigned int slash_count;
+	int err;
+
+	if (!str) {
+		pr_err("One of following identifications expected:\n"
+		       "Devlink identification (\"bus_name/dev_name\")\n"
+		       "Port identification (\"bus_name/dev_name/port_index\" or \"netdev ifname\")\n");
+		return -EINVAL;
+	}
+	slash_count = strslashcount(str);
+	if (slash_count == 1) {
+		err = __dl_argv_handle(str, p_bus_name, p_dev_name);
+		if (err)
 			return err;
-		}
-		strslashrsplit(handlestr, p_bus_name, p_dev_name);
+		*p_handle_bit = DL_OPT_HANDLE;
+	} else if (slash_count == 2) {
+		err = __dl_argv_handle_port(str, p_bus_name,
+					    p_dev_name, p_port_index);
+		if (err)
+			return err;
+		*p_handle_bit = DL_OPT_HANDLEP;
 	} else if (slash_count == 0) {
-		err = ifname_map_lookup(dl, str, p_bus_name, p_dev_name,
-					p_port_index);
-		if (err) {
-			pr_err("Netdevice \"%s\" not found\n", str);
+		err = __dl_argv_handle_port_ifname(dl, str, p_bus_name,
+						   p_dev_name, p_port_index);
+		if (err)
 			return err;
-		}
+		*p_handle_bit = DL_OPT_HANDLEP;
+	} else {
+		pr_err("Wrong port identification string format.\n");
+		pr_err("Expected \"bus_name/dev_name\" or \"bus_name/dev_name/port_index\" or \"netdev_ifname\".\n");
+		return -EINVAL;
 	}
 	return 0;
 }
@@ -475,7 +538,15 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required,
 	uint32_t o_found = 0;
 	int err;
 
-	if (o_required & DL_OPT_HANDLE) {
+	if (o_required & DL_OPT_HANDLE && o_required & DL_OPT_HANDLEP) {
+		uint32_t handle_bit = handle_bit;
+
+		err = dl_argv_handle_both(dl, &opts->bus_name, &opts->dev_name,
+					  &opts->port_index, &handle_bit);
+		if (err)
+			return err;
+		o_found |= handle_bit;
+	} else if (o_required & DL_OPT_HANDLE) {
 		err = dl_argv_handle(dl, &opts->bus_name, &opts->dev_name);
 		if (err)
 			return err;
-- 
1.8.3.1