diff --git a/devlink/devlink.c b/devlink/devlink.c
index 67a57e9ba550..ae017bb2a5bf 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -2083,6 +2083,206 @@ static int dl_argv_parse(struct dl *dl, uint64_t o_required,
 	return dl_args_finding_required_validate(o_required, o_found);
 }
 
+static int dl_opts_check(struct dl *dl, uint32_t cmd)
+{
+	struct dl_opts *opts = &dl->opts;
+	struct mnlu_attr_policy *policy;
+	int err;
+
+	policy = calloc(DEVLINK_ATTR_MAX + 1, sizeof(*policy));
+	if (!policy)
+		return -ENOMEM;
+
+	/* We only check the DO policy currently, since none of the commands
+	 * with NLM_F_DUMP send any attributes.
+	 */
+	err = mnlu_gen_get_op_policy(&dl->nlg, cmd, false, policy);
+	if (err)
+		return err;
+
+	if (opts->present & DL_OPT_HANDLE) {
+		if (!policy[DEVLINK_ATTR_BUS_NAME].valid ||
+		    !policy[DEVLINK_ATTR_DEV_NAME].valid)
+			return -EOPNOTSUPP;
+	} else if (opts->present & DL_OPT_HANDLEP) {
+		if (!policy[DEVLINK_ATTR_BUS_NAME].valid ||
+		    !policy[DEVLINK_ATTR_DEV_NAME].valid ||
+		    !policy[DEVLINK_ATTR_PORT_INDEX].valid)
+			return -EOPNOTSUPP;
+	} else if (opts->present & DL_OPT_HANDLE_REGION) {
+		if (!policy[DEVLINK_ATTR_BUS_NAME].valid ||
+		    !policy[DEVLINK_ATTR_DEV_NAME].valid ||
+		    !policy[DEVLINK_ATTR_REGION_NAME].valid)
+			return -EOPNOTSUPP;
+	} else if (opts->present & DL_OPT_PORT_FN_RATE_NODE_NAME) {
+		if (!policy[DEVLINK_ATTR_BUS_NAME].valid ||
+		    !policy[DEVLINK_ATTR_DEV_NAME].valid ||
+		    !policy[DEVLINK_ATTR_RATE_NODE_NAME].valid)
+			return -EOPNOTSUPP;
+	}
+	if (opts->present & DL_OPT_PORT_TYPE)
+		if (!policy[DEVLINK_ATTR_PORT_TYPE].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_PORT_COUNT)
+		if (!policy[DEVLINK_ATTR_PORT_SPLIT_COUNT].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_SB)
+		if (!policy[DEVLINK_ATTR_SB_INDEX].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_SB_POOL)
+		if (!policy[DEVLINK_ATTR_SB_POOL_INDEX].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_SB_SIZE)
+		if (!policy[DEVLINK_ATTR_SB_POOL_SIZE].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_SB_TYPE)
+		if (!policy[DEVLINK_ATTR_SB_POOL_TYPE].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_SB_THTYPE)
+		if (!policy[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_SB_TH)
+		if (!policy[DEVLINK_ATTR_SB_THRESHOLD].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_SB_TC)
+		if (!policy[DEVLINK_ATTR_SB_TC_INDEX].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_ESWITCH_MODE)
+		if (!policy[DEVLINK_ATTR_ESWITCH_MODE].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_ESWITCH_INLINE_MODE)
+		if (!policy[DEVLINK_ATTR_ESWITCH_INLINE_MODE].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_DPIPE_TABLE_NAME)
+		if (!policy[DEVLINK_ATTR_DPIPE_TABLE_NAME].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_DPIPE_TABLE_COUNTERS)
+		if (!policy[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_ESWITCH_ENCAP_MODE)
+		if (!policy[DEVLINK_ATTR_ESWITCH_ENCAP_MODE].valid)
+			return -EOPNOTSUPP;
+	if ((opts->present & DL_OPT_RESOURCE_PATH) && opts->resource_id_valid)
+		if (!policy[DEVLINK_ATTR_RESOURCE_ID].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_RESOURCE_SIZE)
+		if (!policy[DEVLINK_ATTR_RESOURCE_SIZE].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_PARAM_NAME)
+		if (!policy[DEVLINK_ATTR_PARAM_NAME].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_PARAM_CMODE)
+		if (!policy[DEVLINK_ATTR_PARAM_VALUE_CMODE].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_REGION_SNAPSHOT_ID)
+		if (!policy[DEVLINK_ATTR_REGION_SNAPSHOT_ID].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_REGION_ADDRESS)
+		if (!policy[DEVLINK_ATTR_REGION_CHUNK_ADDR].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_REGION_LENGTH)
+		if (!policy[DEVLINK_ATTR_REGION_CHUNK_LEN].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_FLASH_FILE_NAME)
+		if (!policy[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_FLASH_COMPONENT)
+		if (!policy[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_FLASH_OVERWRITE)
+		if (!policy[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_HEALTH_REPORTER_NAME)
+		if (!policy[DEVLINK_ATTR_HEALTH_REPORTER_NAME].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_HEALTH_REPORTER_GRACEFUL_PERIOD)
+		if (!policy[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_HEALTH_REPORTER_AUTO_RECOVER)
+		if (!policy[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_HEALTH_REPORTER_AUTO_DUMP)
+		if (!policy[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_TRAP_NAME)
+		if (!policy[DEVLINK_ATTR_TRAP_NAME].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_TRAP_GROUP_NAME)
+		if (!policy[DEVLINK_ATTR_TRAP_GROUP_NAME].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_TRAP_ACTION)
+		if (!policy[DEVLINK_ATTR_TRAP_ACTION].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_NETNS)
+		if (!policy[opts->netns_is_pid ? DEVLINK_ATTR_NETNS_PID :
+		    DEVLINK_ATTR_NETNS_FD].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_RELOAD_ACTION)
+		if (!policy[DEVLINK_ATTR_RELOAD_ACTION].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_RELOAD_LIMIT)
+		if (!policy[DEVLINK_ATTR_RELOAD_LIMITS].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_TRAP_POLICER_ID)
+		if (!policy[DEVLINK_ATTR_TRAP_POLICER_ID].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_TRAP_POLICER_RATE)
+		if (!policy[DEVLINK_ATTR_TRAP_POLICER_RATE].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_TRAP_POLICER_BURST)
+		if (!policy[DEVLINK_ATTR_TRAP_POLICER_BURST].valid)
+			return -EOPNOTSUPP;
+	/* TODO: figure how to properly handle nested attributes? */
+	if (opts->present & (DL_OPT_PORT_FUNCTION_HW_ADDR | DL_OPT_PORT_FUNCTION_STATE))
+		if (!policy[DEVLINK_ATTR_PORT_FUNCTION].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_PORT_FLAVOUR)
+		if (!policy[DEVLINK_ATTR_PORT_FLAVOUR].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_PORT_PFNUMBER)
+		if (!policy[DEVLINK_ATTR_PORT_PCI_PF_NUMBER].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_PORT_SFNUMBER)
+		if (!policy[DEVLINK_ATTR_PORT_PCI_SF_NUMBER].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_PORT_CONTROLLER)
+		if (!policy[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_PORT_FN_RATE_TYPE)
+		if (!policy[DEVLINK_ATTR_RATE_TYPE].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_PORT_FN_RATE_TX_SHARE)
+		if (!policy[DEVLINK_ATTR_RATE_TX_SHARE].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_PORT_FN_RATE_TX_MAX)
+		if (!policy[DEVLINK_ATTR_RATE_TX_MAX].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_PORT_FN_RATE_PARENT)
+		if (!policy[DEVLINK_ATTR_RATE_PARENT_NODE_NAME].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_LINECARD)
+		if (!policy[DEVLINK_ATTR_LINECARD_INDEX].valid)
+			return -EOPNOTSUPP;
+	if (opts->present & DL_OPT_LINECARD_TYPE)
+		if (!policy[DEVLINK_ATTR_LINECARD_TYPE].valid)
+			return -EOPNOTSUPP;
+
+	return 0;
+}
+
+static int dl_argv_parse_checked(struct dl *dl, uint32_t cmd,
+				 uint64_t o_required,
+				 uint64_t o_optional)
+{
+	int err;
+
+	err = dl_argv_parse(dl, o_required, o_optional);
+	if (err)
+		return err;
+
+	return dl_opts_check(dl, cmd);
+}
+
 static void
 dl_function_attr_put(struct nlmsghdr *nlh, const struct dl_opts *opts)
 {
@@ -2806,7 +3006,8 @@ static int cmd_dev_eswitch_show(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE, 0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_ESWITCH_GET,
+				    DL_OPT_HANDLE, 0);
 	if (err)
 		return err;
 
@@ -2826,10 +3027,9 @@ static int cmd_dev_eswitch_set(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE,
-			    DL_OPT_ESWITCH_MODE |
-			    DL_OPT_ESWITCH_INLINE_MODE |
-			    DL_OPT_ESWITCH_ENCAP_MODE);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_ESWITCH_SET,
+				    DL_OPT_HANDLE,
+				    DL_OPT_ESWITCH_MODE | DL_OPT_ESWITCH_INLINE_MODE | DL_OPT_ESWITCH_ENCAP_MODE);
 	if (err)
 		return err;
 
@@ -3201,10 +3401,9 @@ static int cmd_dev_param_set(struct dl *dl)
 	bool val_bool;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE |
-			    DL_OPT_PARAM_NAME |
-			    DL_OPT_PARAM_VALUE |
-			    DL_OPT_PARAM_CMODE, 0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_PARAM_GET,
+				    DL_OPT_HANDLE | DL_OPT_PARAM_NAME | DL_OPT_PARAM_VALUE | DL_OPT_PARAM_CMODE,
+				    0);
 	if (err)
 		return err;
 
@@ -3332,7 +3531,9 @@ static int cmd_dev_param_show(struct dl *dl)
 	if (dl_no_arg(dl)) {
 		flags |= NLM_F_DUMP;
 	} else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_PARAM_NAME, 0);
+		err = dl_argv_parse_checked(dl, DEVLINK_CMD_PARAM_GET,
+					    DL_OPT_HANDLE | DL_OPT_PARAM_NAME,
+					    0);
 		if (err)
 			return err;
 	}
@@ -3489,7 +3690,8 @@ static int cmd_dev_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE, 0);
+		err = dl_argv_parse_checked(dl, DEVLINK_CMD_GET,
+					    DL_OPT_HANDLE, 0);
 		if (err)
 			return err;
 	}
@@ -3565,9 +3767,8 @@ static int cmd_dev_reload(struct dl *dl)
 		return 0;
 	}
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE,
-			    DL_OPT_NETNS | DL_OPT_RELOAD_ACTION |
-			    DL_OPT_RELOAD_LIMIT);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_RELOAD, DL_OPT_HANDLE,
+				    DL_OPT_NETNS | DL_OPT_RELOAD_ACTION | DL_OPT_RELOAD_LIMIT);
 	if (err)
 		return err;
 
@@ -3713,7 +3914,8 @@ static int cmd_dev_info(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE, 0);
+		err = dl_argv_parse_checked(dl, DEVLINK_CMD_INFO_GET,
+					    DL_OPT_HANDLE, 0);
 		if (err)
 			return err;
 	}
@@ -3976,8 +4178,9 @@ static int cmd_dev_flash(struct dl *dl)
 		return 0;
 	}
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_FLASH_FILE_NAME,
-			    DL_OPT_FLASH_COMPONENT | DL_OPT_FLASH_OVERWRITE);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_FLASH_UPDATE,
+				    DL_OPT_HANDLE | DL_OPT_FLASH_FILE_NAME,
+				    DL_OPT_FLASH_COMPONENT | DL_OPT_FLASH_OVERWRITE);
 	if (err)
 		return err;
 
@@ -4520,7 +4723,8 @@ static int cmd_port_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLEP, 0);
+		err = dl_argv_parse_checked(dl, DEVLINK_CMD_PORT_GET,
+					    DL_OPT_HANDLEP, 0);
 		if (err)
 			return err;
 	}
@@ -4540,7 +4744,8 @@ static int cmd_port_set(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_PORT_TYPE, 0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_PORT_SET,
+				    DL_OPT_HANDLEP | DL_OPT_PORT_TYPE, 0);
 	if (err)
 		return err;
 
@@ -4557,7 +4762,8 @@ static int cmd_port_split(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_PORT_COUNT, 0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_PORT_SPLIT,
+				    DL_OPT_HANDLEP | DL_OPT_PORT_COUNT, 0);
 	if (err)
 		return err;
 
@@ -4574,7 +4780,8 @@ static int cmd_port_unsplit(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLEP, 0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_PORT_UNSPLIT,
+				    DL_OPT_HANDLEP, 0);
 	if (err)
 		return err;
 
@@ -4596,7 +4803,9 @@ static int cmd_port_param_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_PARAM_NAME, 0);
+		err = dl_argv_parse_checked(dl, DEVLINK_CMD_PORT_PARAM_GET,
+					    DL_OPT_HANDLEP | DL_OPT_PARAM_NAME,
+					    0);
 		if (err)
 			return err;
 	}
@@ -4628,8 +4837,8 @@ static int cmd_port_function_set(struct dl *dl)
 		cmd_port_function_help();
 		return 0;
 	}
-	err = dl_argv_parse(dl, DL_OPT_HANDLEP,
-			    DL_OPT_PORT_FUNCTION_HW_ADDR | DL_OPT_PORT_FUNCTION_STATE);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_PORT_SET, DL_OPT_HANDLEP,
+				    DL_OPT_PORT_FUNCTION_HW_ADDR | DL_OPT_PORT_FUNCTION_STATE);
 	if (err)
 		return err;
 
@@ -4720,10 +4929,9 @@ static int cmd_port_param_set(struct dl *dl)
 	bool val_bool;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLEP |
-			    DL_OPT_PARAM_NAME |
-			    DL_OPT_PARAM_VALUE |
-			    DL_OPT_PARAM_CMODE, 0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_PORT_PARAM_GET,
+				    DL_OPT_HANDLEP | DL_OPT_PARAM_NAME | DL_OPT_PARAM_VALUE | DL_OPT_PARAM_CMODE,
+				    0);
 	if (err)
 		return err;
 
@@ -4953,9 +5161,9 @@ static int cmd_port_fn_rate_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl,
-				    DL_OPT_HANDLEP | DL_OPT_PORT_FN_RATE_NODE_NAME,
-				    0);
+		err = dl_argv_parse_checked(dl, DEVLINK_CMD_RATE_GET,
+					    DL_OPT_HANDLEP | DL_OPT_PORT_FN_RATE_NODE_NAME,
+					    0);
 		if (err)
 			return err;
 	}
@@ -4995,8 +5203,9 @@ static int cmd_port_fn_rate_add(struct dl *dl)
 	struct nlmsghdr *nlh;
 	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);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_RATE_NEW,
+				    DL_OPT_PORT_FN_RATE_NODE_NAME,
+				    DL_OPT_PORT_FN_RATE_TX_SHARE | DL_OPT_PORT_FN_RATE_TX_MAX);
 	if (err)
 		return err;
 
@@ -5020,7 +5229,8 @@ static int cmd_port_fn_rate_del(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_PORT_FN_RATE_NODE_NAME, 0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_RATE_DEL,
+				    DL_OPT_PORT_FN_RATE_NODE_NAME, 0);
 	if (err)
 		return err;
 
@@ -5155,9 +5365,9 @@ static int cmd_port_add(struct dl *dl)
 		return 0;
 	}
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_HANDLEP |
-			    DL_OPT_PORT_FLAVOUR | DL_OPT_PORT_PFNUMBER,
-			    DL_OPT_PORT_SFNUMBER | DL_OPT_PORT_CONTROLLER);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_PORT_NEW,
+				    DL_OPT_HANDLE | DL_OPT_HANDLEP | DL_OPT_PORT_FLAVOUR | DL_OPT_PORT_PFNUMBER,
+				    DL_OPT_PORT_SFNUMBER | DL_OPT_PORT_CONTROLLER);
 	if (err)
 		return err;
 
@@ -5184,7 +5394,8 @@ static int cmd_port_del(struct dl *dl)
 		return 0;
 	}
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLEP, 0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_PORT_DEL, DL_OPT_HANDLEP,
+				    0);
 	if (err)
 		return err;
 
@@ -5327,7 +5538,8 @@ static int cmd_linecard_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE, DL_OPT_LINECARD);
+		err = dl_argv_parse_checked(dl, DEVLINK_CMD_LINECARD_GET,
+					    DL_OPT_HANDLE, DL_OPT_LINECARD);
 		if (err)
 			return err;
 	}
@@ -5348,8 +5560,9 @@ static int cmd_linecard_set(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_LINECARD |
-			    DL_OPT_LINECARD_TYPE, 0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_LINECARD_SET,
+				    DL_OPT_HANDLE | DL_OPT_LINECARD | DL_OPT_LINECARD_TYPE,
+				    0);
 	if (err)
 		return err;
 
@@ -5445,7 +5658,8 @@ static int cmd_sb_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE, DL_OPT_SB);
+		err = dl_argv_parse_checked(dl, DEVLINK_CMD_SB_GET,
+					    DL_OPT_HANDLE, DL_OPT_SB);
 		if (err)
 			return err;
 	}
@@ -5524,8 +5738,9 @@ static int cmd_sb_pool_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_SB_POOL,
-				    DL_OPT_SB);
+		err = dl_argv_parse_checked(dl, DEVLINK_CMD_SB_POOL_GET,
+					    DL_OPT_HANDLE | DL_OPT_SB_POOL,
+					    DL_OPT_SB);
 		if (err)
 			return err;
 	}
@@ -5545,8 +5760,9 @@ static int cmd_sb_pool_set(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_SB_POOL |
-			    DL_OPT_SB_SIZE | DL_OPT_SB_THTYPE, DL_OPT_SB);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_SB_POOL_SET,
+				    DL_OPT_HANDLE | DL_OPT_SB_POOL | DL_OPT_SB_SIZE | DL_OPT_SB_THTYPE,
+				    DL_OPT_SB);
 	if (err)
 		return err;
 
@@ -5613,8 +5829,9 @@ static int cmd_sb_port_pool_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_SB_POOL,
-				    DL_OPT_SB);
+		err = dl_argv_parse_checked(dl, DEVLINK_CMD_SB_PORT_POOL_GET,
+					    DL_OPT_HANDLEP | DL_OPT_SB_POOL,
+					    DL_OPT_SB);
 		if (err)
 			return err;
 	}
@@ -5634,8 +5851,9 @@ static int cmd_sb_port_pool_set(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_SB_POOL | DL_OPT_SB_TH,
-			    DL_OPT_SB);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_SB_PORT_POOL_SET,
+				    DL_OPT_HANDLEP | DL_OPT_SB_POOL | DL_OPT_SB_TH,
+				    DL_OPT_SB);
 	if (err)
 		return err;
 
@@ -5720,8 +5938,10 @@ static int cmd_sb_tc_bind_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_SB_TC |
-				    DL_OPT_SB_TYPE, DL_OPT_SB);
+		err = dl_argv_parse_checked(dl,
+					    DEVLINK_CMD_SB_TC_POOL_BIND_GET,
+					    DL_OPT_HANDLEP | DL_OPT_SB_TC | DL_OPT_SB_TYPE,
+					    DL_OPT_SB);
 		if (err)
 			return err;
 	}
@@ -5741,9 +5961,9 @@ static int cmd_sb_tc_bind_set(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLEP | DL_OPT_SB_TC |
-			    DL_OPT_SB_TYPE | DL_OPT_SB_POOL | DL_OPT_SB_TH,
-			    DL_OPT_SB);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_SB_TC_POOL_BIND_SET,
+				    DL_OPT_HANDLEP | DL_OPT_SB_TC | DL_OPT_SB_TYPE | DL_OPT_SB_POOL | DL_OPT_SB_TH,
+				    DL_OPT_SB);
 	if (err)
 		return err;
 
@@ -6097,7 +6317,8 @@ static int cmd_sb_occ_snapshot(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE, DL_OPT_SB);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_SB_OCC_SNAPSHOT,
+				    DL_OPT_HANDLE, DL_OPT_SB);
 	if (err)
 		return err;
 
@@ -6114,7 +6335,8 @@ static int cmd_sb_occ_clearmax(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE, DL_OPT_SB);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_SB_OCC_MAX_CLEAR,
+				    DL_OPT_HANDLE, DL_OPT_SB);
 	if (err)
 		return err;
 
@@ -7023,7 +7245,8 @@ static int cmd_dpipe_headers_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE, 0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_DPIPE_HEADERS_GET,
+				    DL_OPT_HANDLE, 0);
 	if (err)
 		return err;
 
@@ -7423,7 +7646,8 @@ static int cmd_dpipe_table_show(struct dl *dl)
 	uint16_t flags = NLM_F_REQUEST;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE, DL_OPT_DPIPE_TABLE_NAME);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_DPIPE_HEADERS_GET,
+				    DL_OPT_HANDLE, DL_OPT_DPIPE_TABLE_NAME);
 	if (err)
 		return err;
 
@@ -7478,8 +7702,9 @@ static int cmd_dpipe_table_set(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_DPIPE_TABLE_NAME |
-			    DL_OPT_DPIPE_TABLE_COUNTERS, 0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
+				    DL_OPT_HANDLE | DL_OPT_DPIPE_TABLE_NAME | DL_OPT_DPIPE_TABLE_COUNTERS,
+				    0);
 	if (err)
 		return err;
 
@@ -7852,7 +8077,9 @@ static int cmd_dpipe_table_dump(struct dl *dl)
 	if (err)
 		return err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_DPIPE_TABLE_NAME, 0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_DPIPE_HEADERS_GET,
+				    DL_OPT_HANDLE | DL_OPT_DPIPE_TABLE_NAME,
+				    0);
 	if (err)
 		goto out;
 
@@ -8129,7 +8356,8 @@ static int cmd_resource_show(struct dl *dl)
 	struct resource_ctx resource_ctx = {};
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE, 0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_DPIPE_TABLE_GET,
+				    DL_OPT_HANDLE, 0);
 	if (err)
 		return err;
 
@@ -8229,8 +8457,9 @@ static int cmd_resource_set(struct dl *dl)
 		return err;
 
 	ctx.print_resources = false;
-	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_RESOURCE_PATH |
-			    DL_OPT_RESOURCE_SIZE, 0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_RESOURCE_DUMP,
+				    DL_OPT_HANDLE | DL_OPT_RESOURCE_PATH |
+				    DL_OPT_RESOURCE_SIZE, 0);
 	if (err)
 		goto out;
 
@@ -8401,7 +8630,8 @@ static int cmd_region_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE_REGION, 0);
+		err = dl_argv_parse_checked(dl, DEVLINK_CMD_REGION_GET,
+					    DL_OPT_HANDLE_REGION, 0);
 		if (err)
 			return err;
 	}
@@ -8421,8 +8651,9 @@ static int cmd_region_snapshot_del(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE_REGION |
-			    DL_OPT_REGION_SNAPSHOT_ID, 0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_REGION_DEL,
+				    DL_OPT_HANDLE_REGION | DL_OPT_REGION_SNAPSHOT_ID,
+				    0);
 	if (err)
 		return err;
 
@@ -8473,9 +8704,9 @@ static int cmd_region_dump(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl,
-			    DL_OPT_HANDLE_REGION | DL_OPT_REGION_SNAPSHOT_ID,
-			    0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_REGION_READ,
+				    DL_OPT_HANDLE_REGION | DL_OPT_REGION_SNAPSHOT_ID,
+				    0);
 	if (err)
 		return err;
 
@@ -8497,9 +8728,9 @@ static int cmd_region_read(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE_REGION | DL_OPT_REGION_ADDRESS |
-			    DL_OPT_REGION_LENGTH | DL_OPT_REGION_SNAPSHOT_ID,
-			    0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_REGION_READ,
+				    DL_OPT_HANDLE_REGION | DL_OPT_REGION_ADDRESS | DL_OPT_REGION_LENGTH | DL_OPT_REGION_SNAPSHOT_ID,
+				    0);
 	if (err)
 		return err;
 
@@ -8538,8 +8769,9 @@ static int cmd_region_snapshot_new(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE_REGION,
-			    DL_OPT_REGION_SNAPSHOT_ID);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_REGION_NEW,
+				    DL_OPT_HANDLE_REGION,
+				    DL_OPT_REGION_SNAPSHOT_ID);
 	if (err)
 		return err;
 
@@ -8595,15 +8827,16 @@ static int cmd_health_set_params(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_HEALTH_REPORTER_SET,
-			       NLM_F_REQUEST | NLM_F_ACK);
-	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_HANDLEP | DL_OPT_HEALTH_REPORTER_NAME,
-			    DL_OPT_HEALTH_REPORTER_GRACEFUL_PERIOD |
-			    DL_OPT_HEALTH_REPORTER_AUTO_RECOVER |
-			    DL_OPT_HEALTH_REPORTER_AUTO_DUMP);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_HEALTH_REPORTER_SET,
+				    DL_OPT_HANDLE | DL_OPT_HANDLEP | DL_OPT_HEALTH_REPORTER_NAME,
+				    DL_OPT_HEALTH_REPORTER_GRACEFUL_PERIOD |
+				    DL_OPT_HEALTH_REPORTER_AUTO_RECOVER |
+				    DL_OPT_HEALTH_REPORTER_AUTO_DUMP);
 	if (err)
 		return err;
 
+	nlh = mnlu_gen_socket_cmd_prepare(&dl->nlg, DEVLINK_CMD_HEALTH_REPORTER_SET,
+			       NLM_F_REQUEST | NLM_F_ACK);
 	dl_opts_put(nlh, dl);
 	return mnlu_gen_socket_sndrcv(&dl->nlg, nlh, NULL, NULL);
 }
@@ -8613,9 +8846,10 @@ static int cmd_health_dump_clear(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_HANDLEP |
-			    DL_OPT_HEALTH_REPORTER_NAME,
-			    0);
+	err = dl_argv_parse_checked(dl,
+				    DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
+				    DL_OPT_HANDLE | DL_OPT_HANDLEP | DL_OPT_HEALTH_REPORTER_NAME,
+				    0);
 	if (err)
 		return err;
 
@@ -8866,9 +9100,9 @@ static int cmd_health_object_common(struct dl *dl, uint8_t cmd, uint16_t flags)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl,
-			    DL_OPT_HANDLE | DL_OPT_HANDLEP | DL_OPT_HEALTH_REPORTER_NAME,
-			    0);
+	err = dl_argv_parse_checked(dl, cmd,
+				    DL_OPT_HANDLE | DL_OPT_HANDLEP | DL_OPT_HEALTH_REPORTER_NAME,
+				    0);
 	if (err)
 		return err;
 
@@ -8908,9 +9142,9 @@ static int cmd_health_recover(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_HANDLEP |
-			    DL_OPT_HEALTH_REPORTER_NAME,
-			    0);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
+				    DL_OPT_HANDLE | DL_OPT_HANDLEP | DL_OPT_HEALTH_REPORTER_NAME,
+				    0);
 	if (err)
 		return err;
 
@@ -9088,9 +9322,10 @@ static int __cmd_health_show(struct dl *dl, bool show_device, bool show_port)
 		flags |= NLM_F_DUMP;
 	} else {
 		ctx.show_port = true;
-		err = dl_argv_parse(dl,
-				    DL_OPT_HANDLE | DL_OPT_HANDLEP |
-				    DL_OPT_HEALTH_REPORTER_NAME, 0);
+		err = dl_argv_parse_checked(dl,
+					    DEVLINK_CMD_HEALTH_REPORTER_GET,
+					    DL_OPT_HANDLE | DL_OPT_HANDLEP | DL_OPT_HEALTH_REPORTER_NAME,
+					    0);
 		if (err)
 			return err;
 	}
@@ -9282,7 +9517,9 @@ static int cmd_trap_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_TRAP_NAME, 0);
+		err = dl_argv_parse_checked(dl, DEVLINK_CMD_TRAP_GET,
+					    DL_OPT_HANDLE | DL_OPT_TRAP_NAME,
+					    0);
 		if (err)
 			return err;
 	}
@@ -9303,8 +9540,9 @@ static int cmd_trap_set(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_TRAP_NAME,
-			    DL_OPT_TRAP_ACTION);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_TRAP_SET,
+				    DL_OPT_HANDLE | DL_OPT_TRAP_NAME,
+				    DL_OPT_TRAP_ACTION);
 	if (err)
 		return err;
 
@@ -9360,8 +9598,9 @@ static int cmd_trap_group_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl,
-				    DL_OPT_HANDLE | DL_OPT_TRAP_GROUP_NAME, 0);
+		err = dl_argv_parse_checked(dl, DEVLINK_CMD_TRAP_GROUP_GET,
+					    DL_OPT_HANDLE | DL_OPT_TRAP_GROUP_NAME,
+					    0);
 		if (err)
 			return err;
 	}
@@ -9382,8 +9621,9 @@ static int cmd_trap_group_set(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_TRAP_GROUP_NAME,
-			    DL_OPT_TRAP_ACTION | DL_OPT_TRAP_POLICER_ID);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_TRAP_GROUP_SET,
+				    DL_OPT_HANDLE | DL_OPT_TRAP_GROUP_NAME,
+				    DL_OPT_TRAP_ACTION | DL_OPT_TRAP_POLICER_ID);
 	if (err)
 		return err;
 
@@ -9459,8 +9699,9 @@ static int cmd_trap_policer_show(struct dl *dl)
 		flags |= NLM_F_DUMP;
 	}
 	else {
-		err = dl_argv_parse(dl,
-				    DL_OPT_HANDLE | DL_OPT_TRAP_POLICER_ID, 0);
+		err = dl_argv_parse_checked(dl, DEVLINK_CMD_TRAP_POLICER_GET,
+					    DL_OPT_HANDLE | DL_OPT_TRAP_POLICER_ID,
+					    0);
 		if (err)
 			return err;
 	}
@@ -9481,8 +9722,9 @@ static int cmd_trap_policer_set(struct dl *dl)
 	struct nlmsghdr *nlh;
 	int err;
 
-	err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_TRAP_POLICER_ID,
-			    DL_OPT_TRAP_POLICER_RATE | DL_OPT_TRAP_POLICER_BURST);
+	err = dl_argv_parse_checked(dl, DEVLINK_CMD_TRAP_POLICER_SET,
+				    DL_OPT_HANDLE | DL_OPT_TRAP_POLICER_ID,
+				    DL_OPT_TRAP_POLICER_RATE | DL_OPT_TRAP_POLICER_BURST);
 	if (err)
 		return err;
 
