diff --git a/devlink/devlink.c b/devlink/devlink.c
index 6a46a4ecf648..066aab12c6f8 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -2302,6 +2302,88 @@ static int dl_argv_dry_parse(struct dl *dl, uint64_t o_required,
 	return err;
 }
 
+/* List of extented handles with two slashes. */
+static const uint64_t dl_opt_extended_handle[] = {
+	DL_OPT_HANDLEP,
+	DL_OPT_HANDLE_REGION,
+	DL_OPT_PORT_FN_RATE_NODE_NAME,
+};
+
+static int dl_argv_parse_with_selector(struct dl *dl, uint16_t *flags,
+				       uint8_t cmd,
+				       uint64_t o_required,
+				       uint64_t o_optional,
+				       uint64_t o_dump_required,
+				       uint64_t o_dump_optional)
+{
+	int err;
+	int i;
+
+	if (dl_no_arg(dl))
+		goto flag_set;
+
+	/* In case the handle suggests it, do dry parsing first
+	 * to see if all required options are there. Proceed with
+	 * dump selector in case there are missing options on the
+	 * command line. That means user provided partial
+	 * object identification.
+	 */
+
+	if ((o_required & (DL_OPT_HANDLE | DL_OPT_HANDLEP)) ==
+	    (DL_OPT_HANDLE | DL_OPT_HANDLEP)) {
+		/* Handle case when both devlink handle and port handle
+		 * are allowed. Try both alone, if parsing of either
+		 * is successful, we have a do parse case.
+		 */
+		err = dl_argv_dry_parse(dl, o_required & ~DL_OPT_HANDLEP,
+					o_optional);
+		if (err == -ENOENT)
+			goto dump_parse;
+		else if (!err)
+			goto do_parse;
+		err = dl_argv_dry_parse(dl, o_required & ~DL_OPT_HANDLE,
+					o_optional);
+		if (err == -ENOENT)
+			goto dump_parse;
+		goto do_parse;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(dl_opt_extended_handle); i++) {
+		uint64_t handle = dl_opt_extended_handle[i];
+
+		if ((o_required & handle) == handle) {
+			err = dl_argv_dry_parse(dl, (o_required & ~handle) |
+						DL_OPT_HANDLE,
+						o_optional);
+			if (err == -ENOENT || !err)
+				goto dump_parse;
+			goto do_parse;
+		}
+	}
+
+	err = dl_argv_dry_parse(dl, o_required, o_optional);
+	if (err == -ENOENT)
+		goto dump_parse;
+
+do_parse:
+	return dl_argv_parse(dl, o_required, o_optional);
+
+dump_parse:
+	err = mnlu_gen_cmd_dump_policy(&dl->nlg, cmd);
+	if (err) {
+		pr_err("Dump selectors are not supported by kernel for this command\n");
+		return -ENOTSUP;
+	}
+
+	err = dl_argv_parse(dl, o_dump_required, o_dump_optional);
+	if (err)
+		return err;
+
+flag_set:
+	*flags |= NLM_F_DUMP;
+	return 0;
+}
+
 static void
 dl_function_attr_put(struct nlmsghdr *nlh, const struct dl_opts *opts)
 {
@@ -3580,13 +3662,11 @@ static int cmd_dev_param_show(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	} else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_PARAM_NAME, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags, DEVLINK_CMD_PARAM_GET,
+					  DL_OPT_HANDLE | DL_OPT_PARAM_NAME, 0,
+					  DL_OPT_HANDLE, 0);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_PARAM_GET, flags);
 
@@ -4784,14 +4864,11 @@ static int cmd_port_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLEP, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags, DEVLINK_CMD_PORT_GET,
+					  DL_OPT_HANDLEP, 0,
+					  DL_OPT_HANDLE, 0);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_PORT_GET, flags);
 
@@ -4860,14 +4937,12 @@ static int cmd_port_param_show(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_PARAM_NAME, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags,
+					  DEVLINK_CMD_PORT_PARAM_GET,
+					  DL_OPT_HANDLE | DL_OPT_PARAM_NAME, 0,
+					  DL_OPT_HANDLE | DL_OPT_HANDLEP, 0);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_PORT_PARAM_GET,
 					  flags);
@@ -5234,16 +5309,9 @@ static int cmd_port_fn_rate_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl,
-				    DL_OPT_HANDLEP | DL_OPT_PORT_FN_RATE_NODE_NAME,
-				    0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags, DEVLINK_CMD_RATE_GET,
+					  DL_OPT_HANDLEP | DL_OPT_PORT_FN_RATE_NODE_NAME,
+					  0, DL_OPT_HANDLE, 0);
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_RATE_GET, flags);
 
@@ -5622,14 +5690,11 @@ static int cmd_linecard_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE, DL_OPT_LINECARD);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags, DEVLINK_CMD_LINECARD_GET,
+					  DL_OPT_HANDLE | DL_OPT_LINECARD, 0,
+					  DL_OPT_HANDLE, 0);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_LINECARD_GET,
 					  flags);
@@ -5740,14 +5805,11 @@ static int cmd_sb_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_SB, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags, DEVLINK_CMD_SB_GET,
+					  DL_OPT_HANDLE | DL_OPT_SB, 0,
+					  DL_OPT_HANDLE, DL_OPT_SB);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_SB_GET, flags);
 
@@ -5819,15 +5881,12 @@ static int cmd_sb_pool_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_SB |
-				    DL_OPT_SB_POOL, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags, DEVLINK_CMD_SB_POOL_GET,
+					  DL_OPT_HANDLE | DL_OPT_SB |
+					  DL_OPT_SB_POOL, 0,
+					  DL_OPT_HANDLE, DL_OPT_SB);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_SB_POOL_GET, flags);
 
@@ -5908,15 +5967,13 @@ static int cmd_sb_port_pool_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_SB |
-				    DL_OPT_SB_POOL, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags,
+					  DEVLINK_CMD_SB_PORT_POOL_GET,
+					  DL_OPT_HANDLEP | DL_OPT_SB |
+					  DL_OPT_SB_POOL, 0,
+					  DL_OPT_HANDLE | DL_OPT_HANDLEP, DL_OPT_SB);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_SB_PORT_POOL_GET, flags);
 
@@ -6015,15 +6072,14 @@ static int cmd_sb_tc_bind_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_SB | DL_OPT_SB_TC |
-				    DL_OPT_SB_TYPE, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags,
+					  DEVLINK_CMD_SB_TC_POOL_BIND_GET,
+					  DL_OPT_HANDLEP | DL_OPT_SB |
+					  DL_OPT_SB_TC | DL_OPT_SB_TYPE, 0,
+					  DL_OPT_HANDLE | DL_OPT_HANDLEP,
+					  DL_OPT_SB);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_SB_TC_POOL_BIND_GET, flags);
 
@@ -8697,14 +8753,11 @@ static int cmd_region_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE_REGION, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags, DEVLINK_CMD_REGION_GET,
+					  DL_OPT_HANDLE_REGION, 0,
+					  DL_OPT_HANDLE, 0);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_REGION_GET, flags);
 
@@ -9388,19 +9441,20 @@ static int __cmd_health_show(struct dl *dl, bool show_device, bool show_port)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	} else {
+	err = dl_argv_parse_with_selector(dl, &flags,
+					  DEVLINK_CMD_HEALTH_REPORTER_GET,
+					  DL_OPT_HANDLE | DL_OPT_HANDLEP |
+					  DL_OPT_HEALTH_REPORTER_NAME, 0,
+					  DL_OPT_HANDLE | DL_OPT_HANDLEP, 0);
+	if (err)
+		return err;
+
+	if (!(flags & NLM_F_DUMP))
 		ctx.show_port = true;
-		err = dl_argv_parse(dl,
-				    DL_OPT_HANDLE | DL_OPT_HANDLEP |
-				    DL_OPT_HEALTH_REPORTER_NAME, 0);
-		if (err)
-			return err;
-	}
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_HEALTH_REPORTER_GET,
 			       flags);
+
 	dl_opts_put(nlh, dl);
 
 	pr_out_section_start(dl, "health");
@@ -9582,14 +9636,11 @@ static int cmd_trap_show(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_TRAP_NAME, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags, DEVLINK_CMD_TRAP_GET,
+					  DL_OPT_HANDLE | DL_OPT_TRAP_NAME, 0,
+					  DL_OPT_HANDLE, 0);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_TRAP_GET, flags);
 
@@ -9660,15 +9711,12 @@ static int cmd_trap_group_show(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl,
-				    DL_OPT_HANDLE | DL_OPT_TRAP_GROUP_NAME, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags,
+					  DEVLINK_CMD_TRAP_GROUP_GET,
+					  DL_OPT_HANDLE | DL_OPT_TRAP_GROUP_NAME, 0,
+					  DL_OPT_HANDLE, 0);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_TRAP_GROUP_GET, flags);
 
@@ -9759,15 +9807,12 @@ static int cmd_trap_policer_show(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	if (dl_no_arg(dl)) {
-		flags |= NLM_F_DUMP;
-	}
-	else {
-		err = dl_argv_parse(dl,
-				    DL_OPT_HANDLE | DL_OPT_TRAP_POLICER_ID, 0);
-		if (err)
-			return err;
-	}
+	err = dl_argv_parse_with_selector(dl, &flags,
+					  DEVLINK_CMD_TRAP_POLICER_GET,
+					  DL_OPT_HANDLE | DL_OPT_TRAP_POLICER_ID, 0,
+					  DL_OPT_HANDLE, 0);
+	if (err)
+		return err;
 
 	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_TRAP_POLICER_GET, flags);
 
