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)
{
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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");
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);
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);
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);