]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
dpll: add client-side filtering for pin show
authorPetr Oros <poros@redhat.com>
Tue, 24 Feb 2026 09:12:42 +0000 (10:12 +0100)
committerDavid Ahern <dsahern@kernel.org>
Mon, 2 Mar 2026 15:44:15 +0000 (08:44 -0700)
Add client-side filtering support for dpll pin show command.
Users can filter pins by module-name, clock-id, board-label,
panel-label, package-label, and type. Multiple filters use AND
semantics. Filters work with both dump and single GET operations.

Signed-off-by: Petr Oros <poros@redhat.com>
Signed-off-by: David Ahern <dsahern@kernel.org>
bash-completion/dpll
dpll/dpll.c
man/man8/dpll.8

index a614b3eb6ab3551f7dac0d32a58809228a6e8fdb..f81a2d2caa1012652332fa9461a734871136c154 100644 (file)
@@ -158,8 +158,28 @@ _dpll_pin()
                         "$(_dpll_direct_complete device_id)" -- "$cur" ) )
                     return 0
                     ;;
+                module-name)
+                    COMPREPLY=( $( compgen -W \
+                        "$(_dpll_direct_complete module_name)" -- "$cur" ) )
+                    return 0
+                    ;;
+                clock-id)
+                    # numeric value, no completion
+                    return 0
+                    ;;
+                board-label|panel-label|package-label)
+                    # string value, no completion
+                    return 0
+                    ;;
+                type)
+                    COMPREPLY=( $( compgen -W "mux ext synce-eth-port \
+                        int-oscillator gnss" -- "$cur" ) )
+                    return 0
+                    ;;
                 *)
-                    COMPREPLY=( $( compgen -W "id device" -- "$cur" ) )
+                    COMPREPLY=( $( compgen -W "id device module-name clock-id \
+                        board-label panel-label package-label type" \
+                        -- "$cur" ) )
                     return 0
                     ;;
             esac
index d3c964e211319daf0f057bcbad00af58db65a55e..9909ee6d045b7eed34a690e70baa4b2b135e68b8 100644 (file)
@@ -865,6 +865,51 @@ static bool dpll_device_dump_filter(struct dpll_device_filter *filter,
        return true;
 }
 
+#define DPLL_FILTER_PIN_MODULE_NAME    BIT(0)
+#define DPLL_FILTER_PIN_CLOCK_ID       BIT(1)
+#define DPLL_FILTER_PIN_BOARD_LABEL    BIT(2)
+#define DPLL_FILTER_PIN_PANEL_LABEL    BIT(3)
+#define DPLL_FILTER_PIN_PACKAGE_LABEL  BIT(4)
+#define DPLL_FILTER_PIN_TYPE           BIT(5)
+
+struct dpll_pin_filter {
+       uint64_t present;
+       const char *module_name;
+       __u64 clock_id;
+       const char *board_label;
+       const char *panel_label;
+       const char *package_label;
+       __u32 type;
+};
+
+static bool dpll_pin_dump_filter(struct dpll_pin_filter *filter,
+                                struct nlattr **tb)
+{
+       if (!filter || !filter->present)
+               return true;
+
+       if ((filter->present & DPLL_FILTER_PIN_MODULE_NAME) &&
+           !filter_match_str(tb[DPLL_A_PIN_MODULE_NAME], filter->module_name))
+               return false;
+       if ((filter->present & DPLL_FILTER_PIN_CLOCK_ID) &&
+           !filter_match_u64(tb[DPLL_A_PIN_CLOCK_ID], filter->clock_id))
+               return false;
+       if ((filter->present & DPLL_FILTER_PIN_BOARD_LABEL) &&
+           !filter_match_str(tb[DPLL_A_PIN_BOARD_LABEL], filter->board_label))
+               return false;
+       if ((filter->present & DPLL_FILTER_PIN_PANEL_LABEL) &&
+           !filter_match_str(tb[DPLL_A_PIN_PANEL_LABEL], filter->panel_label))
+               return false;
+       if ((filter->present & DPLL_FILTER_PIN_PACKAGE_LABEL) &&
+           !filter_match_str(tb[DPLL_A_PIN_PACKAGE_LABEL],
+                             filter->package_label))
+               return false;
+       if ((filter->present & DPLL_FILTER_PIN_TYPE) &&
+           !filter_match_u32(tb[DPLL_A_PIN_TYPE], filter->type))
+               return false;
+       return true;
+}
+
 /* Print device attributes */
 static void dpll_device_print_attrs(const struct nlmsghdr *nlh,
                                    struct nlattr **tb)
@@ -1186,6 +1231,9 @@ static int cmd_device(struct dpll *dpll)
 static void cmd_pin_help(void)
 {
        pr_err("Usage: dpll pin show [ id PIN_ID ] [ device DEVICE_ID ]\n");
+       pr_err("                     [ module-name NAME ] [ clock-id ID ]\n");
+       pr_err("                     [ board-label LABEL ] [ panel-label LABEL ]\n");
+       pr_err("                     [ package-label LABEL ] [ type TYPE ]\n");
        pr_err("       dpll pin set id PIN_ID [ frequency FREQ ]\n");
        pr_err("                              [ phase-adjust ADJUST ]\n");
        pr_err("                              [ esync-frequency FREQ ]\n");
@@ -1546,6 +1594,7 @@ static void dpll_multi_attr_parse(const struct nlmsghdr *nlh, int attr_type,
 /* Callback for pin get (single) */
 static int cmd_pin_show_cb(const struct nlmsghdr *nlh, void *data)
 {
+       struct dpll_pin_filter *filter = data;
        struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
        struct multi_attr_ctx parent_dev_ctx = { 0 }, parent_pin_ctx = { 0 },
                              ref_sync_ctx = { 0 };
@@ -1558,6 +1607,9 @@ static int cmd_pin_show_cb(const struct nlmsghdr *nlh, void *data)
        /* First parse to get main attributes */
        mnl_attr_parse(nlh, sizeof(struct genlmsghdr), attr_pin_cb, tb);
 
+       if (!dpll_pin_dump_filter(filter, tb))
+               return MNL_CB_OK;
+
        /* Pass 1: Count multi-attr occurrences and allocate */
        count = multi_attr_count_get(nlh, genl, DPLL_A_PIN_PARENT_DEVICE);
        if (count > 0 && multi_attr_ctx_init(&parent_dev_ctx, count) < 0)
@@ -1635,16 +1687,27 @@ cleanup:
 /* Callback for pin dump (multiple) - wraps each pin in object */
 static int cmd_pin_show_dump_cb(const struct nlmsghdr *nlh, void *data)
 {
+       struct dpll_pin_filter *filter = data;
+       struct nlattr *tb[DPLL_A_PIN_MAX + 1] = {};
        int ret;
 
+       /* Lightweight pre-parse for filter check before expensive
+        * multi-attr processing in cmd_pin_show_cb.
+        */
+       mnl_attr_parse(nlh, sizeof(struct genlmsghdr), attr_pin_cb, tb);
+
+       if (!dpll_pin_dump_filter(filter, tb))
+               return MNL_CB_OK;
+
        open_json_object(NULL);
-       ret = cmd_pin_show_cb(nlh, data);
+       ret = cmd_pin_show_cb(nlh, NULL);
        close_json_object();
 
        return ret;
 }
 
-static int cmd_pin_show_id(struct dpll *dpll, __u32 id)
+static int cmd_pin_show_id(struct dpll *dpll, __u32 id,
+                          struct dpll_pin_filter *filter)
 {
        struct nlmsghdr *nlh;
        int err;
@@ -1653,7 +1716,8 @@ static int cmd_pin_show_id(struct dpll *dpll, __u32 id)
                                          NLM_F_REQUEST | NLM_F_ACK);
        mnl_attr_put_u32(nlh, DPLL_A_PIN_ID, id);
 
-       err = mnlu_gen_socket_sndrcv(&dpll->nlg, nlh, cmd_pin_show_cb, NULL);
+       err = mnlu_gen_socket_sndrcv(&dpll->nlg, nlh, cmd_pin_show_cb,
+                                    filter);
        if (err < 0) {
                pr_err("Failed to get pin %u\n", id);
                return -1;
@@ -1663,7 +1727,8 @@ static int cmd_pin_show_id(struct dpll *dpll, __u32 id)
 }
 
 static int cmd_pin_show_dump(struct dpll *dpll, bool has_device_id,
-                            __u32 device_id)
+                            __u32 device_id,
+                            struct dpll_pin_filter *filter)
 {
        struct nlmsghdr *nlh;
        int err;
@@ -1680,7 +1745,7 @@ static int cmd_pin_show_dump(struct dpll *dpll, bool has_device_id,
        open_json_array(PRINT_JSON, "pin");
 
        err = mnlu_gen_socket_sndrcv(&dpll->nlg, nlh, cmd_pin_show_dump_cb,
-                                    NULL);
+                                    filter);
        if (err < 0) {
                pr_err("Failed to dump pins\n");
                close_json_array(PRINT_JSON, NULL);
@@ -1696,6 +1761,7 @@ static int cmd_pin_show_dump(struct dpll *dpll, bool has_device_id,
 static int cmd_pin_show(struct dpll *dpll)
 {
        bool has_pin_id = false, has_device_id = false;
+       struct dpll_pin_filter filter = {};
        __u32 pin_id = 0, device_id = 0;
 
        while (dpll_argc(dpll) > 0) {
@@ -1707,6 +1773,44 @@ static int cmd_pin_show(struct dpll *dpll)
                        if (dpll_parse_u32(dpll, "device", &device_id))
                                return -EINVAL;
                        has_device_id = true;
+               } else if (dpll_argv_match(dpll, "module-name")) {
+                       if (dpll_filter_parse_str(dpll, "module-name",
+                                                 &filter.module_name,
+                                                 &filter.present,
+                                                 DPLL_FILTER_PIN_MODULE_NAME))
+                               return -EINVAL;
+               } else if (dpll_argv_match(dpll, "clock-id")) {
+                       if (dpll_filter_parse_u64(dpll, "clock-id",
+                                                 &filter.clock_id,
+                                                 &filter.present,
+                                                 DPLL_FILTER_PIN_CLOCK_ID))
+                               return -EINVAL;
+               } else if (dpll_argv_match(dpll, "board-label")) {
+                       if (dpll_filter_parse_str(dpll, "board-label",
+                                                 &filter.board_label,
+                                                 &filter.present,
+                                                 DPLL_FILTER_PIN_BOARD_LABEL))
+                               return -EINVAL;
+               } else if (dpll_argv_match(dpll, "panel-label")) {
+                       if (dpll_filter_parse_str(dpll, "panel-label",
+                                                 &filter.panel_label,
+                                                 &filter.present,
+                                                 DPLL_FILTER_PIN_PANEL_LABEL))
+                               return -EINVAL;
+               } else if (dpll_argv_match(dpll, "package-label")) {
+                       if (dpll_filter_parse_str(dpll, "package-label",
+                                                 &filter.package_label,
+                                                 &filter.present,
+                                                 DPLL_FILTER_PIN_PACKAGE_LABEL))
+                               return -EINVAL;
+               } else if (dpll_argv_match(dpll, "type")) {
+                       if (dpll_filter_parse_enum(dpll, "type",
+                                                  &filter.type,
+                                                  &filter.present,
+                                                  DPLL_FILTER_PIN_TYPE,
+                                                  str_to_dpll_pin_type,
+                                                  "mux/ext/synce-eth-port/int-oscillator/gnss"))
+                               return -EINVAL;
                } else {
                        pr_err("unknown option: %s\n", dpll_argv(dpll));
                        return -EINVAL;
@@ -1714,9 +1818,9 @@ static int cmd_pin_show(struct dpll *dpll)
        }
 
        if (has_pin_id)
-               return cmd_pin_show_id(dpll, pin_id);
-       else
-               return cmd_pin_show_dump(dpll, has_device_id, device_id);
+               return cmd_pin_show_id(dpll, pin_id, &filter);
+
+       return cmd_pin_show_dump(dpll, has_device_id, device_id, &filter);
 }
 
 static int cmd_pin_parse_parent_device(struct dpll *dpll, struct nlmsghdr *nlh)
index 1407ca9793c96ce209341f73167411b07cb0f4f1..a4280153b4d67b63de2f2763e39bfa3a9799570e 100644 (file)
@@ -161,7 +161,7 @@ Device type:
 
 .SH PIN COMMANDS
 
-.SS dpll pin show [ id ID ] [ device ID ]
+.SS dpll pin show [ id ID ] [ device ID ] [ module-name NAME ] [ clock-id ID ] [ board-label LABEL ] [ panel-label LABEL ] [ package-label LABEL ] [ type TYPE ]
 
 Display information about DPLL pins. If no arguments are specified,
 shows all pins in the system.
@@ -174,6 +174,31 @@ Show only the pin with the specified numeric identifier.
 .BI device " ID"
 Show only pins associated with the specified device ID.
 
+.TP
+.BI module-name " NAME"
+Show only pins provided by the specified kernel module.
+
+.TP
+.BI clock-id " ID"
+Show only pins with the specified 64-bit clock identifier.
+
+.TP
+.BI board-label " LABEL"
+Show only pins with the specified board label.
+
+.TP
+.BI panel-label " LABEL"
+Show only pins with the specified panel label.
+
+.TP
+.BI package-label " LABEL"
+Show only pins with the specified package label.
+
+.TP
+.BI type " TYPE"
+Show only pins of the specified type:
+.BR mux ", " ext ", " synce-eth-port ", " int-oscillator ", " gnss .
+
 .PP
 Output includes:
 .RS
@@ -342,6 +367,16 @@ Press Ctrl+C to stop monitoring.
 .B dpll pin show
 .fi
 
+.SS Show all GNSS pins
+.nf
+.B dpll pin show type gnss
+.fi
+
+.SS Show GNSS pins from specific module
+.nf
+.B dpll pin show type gnss module-name ice
+.fi
+
 .SS Show pin with pretty JSON output
 .nf
 .B dpll -jp pin show id 5