public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH iproute2-next 0/4] dpll: add client-side filtering
@ 2026-02-24  9:12 Petr Oros
  2026-02-24  9:12 ` [PATCH iproute2-next 1/4] dpll: fix pin id-get type filter parsing Petr Oros
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Petr Oros @ 2026-02-24  9:12 UTC (permalink / raw)
  To: netdev; +Cc: dsahern, stephen, Petr Oros

This series fixes a parsing bug in dpll pin id-get and adds
client-side filtering support for dpll device show and pin show
commands.

Patch 1 fixes a bug where "dpll pin id-get type gnss" would read
the keyword "type" as the enum value instead of the actual type.

Patches 2-3 add client-side filtering for device show and pin show.
Users can filter output by various attributes (module-name, clock-id,
type, etc.) with AND semantics. Kernel-side dump filtering for dpll
is not yet available, so all filtering is done in userspace.

Patch 4 replaces the non-functional server-side "device" filter in
pin show (kernel ignores DPLL_A_ID in pin dump requests) with
client-side parent-device and parent-pin filtering that checks
nested multi-attrs. The argument is renamed from "device" to
"parent-device" to reflect the actual semantics.

Each patch includes corresponding man page and bash completion
updates.

Petr Oros (4):
  dpll: fix pin id-get type filter parsing
  dpll: add client-side filtering for device show
  dpll: add client-side filtering for pin show
  dpll: add pin filtering by parent-device and parent-pin

 bash-completion/dpll |  55 +++++-
 dpll/dpll.c          | 387 ++++++++++++++++++++++++++++++++++++++++---
 man/man8/dpll.8      |  80 ++++++++-
 3 files changed, 488 insertions(+), 34 deletions(-)

--
2.52.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH iproute2-next 1/4] dpll: fix pin id-get type filter parsing
  2026-02-24  9:12 [PATCH iproute2-next 0/4] dpll: add client-side filtering Petr Oros
@ 2026-02-24  9:12 ` Petr Oros
  2026-02-24  9:12 ` [PATCH iproute2-next 2/4] dpll: add client-side filtering for device show Petr Oros
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Petr Oros @ 2026-02-24  9:12 UTC (permalink / raw)
  To: netdev; +Cc: dsahern, stephen, Petr Oros

dpll_parse_attr_enum() expects the keyword to be already consumed,
but cmd_pin_id_get() used dpll_argv_match() which does not advance
the argument pointer. This caused the parser to read the keyword
"type" as the enum value instead of the actual type (e.g. "gnss").

Use dpll_argv_match_inc() to properly consume the keyword before
parsing the value.

Fixes: 656cfc3ce05b ("dpll: Add dpll command")
Signed-off-by: Petr Oros <poros@redhat.com>
---
 dpll/dpll.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dpll/dpll.c b/dpll/dpll.c
index 624567c2a826fd..0effa5a9c67e72 100644
--- a/dpll/dpll.c
+++ b/dpll/dpll.c
@@ -1768,7 +1768,7 @@ static int cmd_pin_id_get(struct dpll *dpll)
 			if (dpll_parse_attr_str(dpll, nlh, "package-label",
 						DPLL_A_PIN_PACKAGE_LABEL))
 				return -EINVAL;
-		} else if (dpll_argv_match(dpll, "type")) {
+		} else if (dpll_argv_match_inc(dpll, "type")) {
 			if (dpll_parse_attr_enum(dpll, nlh, "type",
 						 DPLL_A_PIN_TYPE,
 						 dpll_parse_pin_type))
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH iproute2-next 2/4] dpll: add client-side filtering for device show
  2026-02-24  9:12 [PATCH iproute2-next 0/4] dpll: add client-side filtering Petr Oros
  2026-02-24  9:12 ` [PATCH iproute2-next 1/4] dpll: fix pin id-get type filter parsing Petr Oros
@ 2026-02-24  9:12 ` Petr Oros
  2026-02-24  9:12 ` [PATCH iproute2-next 3/4] dpll: add client-side filtering for pin show Petr Oros
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Petr Oros @ 2026-02-24  9:12 UTC (permalink / raw)
  To: netdev; +Cc: dsahern, stephen, Petr Oros

Add client-side filtering support for dpll device show command.
Users can filter devices by module-name, clock-id, type, mode,
and lock-status. Multiple filters use AND semantics. Filters
work with both dump (all devices) and single GET (by id) operations.

Signed-off-by: Petr Oros <poros@redhat.com>
---
 bash-completion/dpll |  25 +++++-
 dpll/dpll.c          | 191 +++++++++++++++++++++++++++++++++++++++++--
 man/man8/dpll.8      |  35 +++++++-
 3 files changed, 243 insertions(+), 8 deletions(-)

diff --git a/bash-completion/dpll b/bash-completion/dpll
index caf86a36f2adf3..a614b3eb6ab355 100644
--- a/bash-completion/dpll
+++ b/bash-completion/dpll
@@ -60,8 +60,31 @@ _dpll_device()
                         "$(_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
+                    ;;
+                type)
+                    COMPREPLY=( $( compgen -W "pps eec" -- "$cur" ) )
+                    return 0
+                    ;;
+                mode)
+                    COMPREPLY=( $( compgen -W "manual automatic" -- "$cur" ) )
+                    return 0
+                    ;;
+                lock-status)
+                    COMPREPLY=( $( compgen -W \
+                        "unlocked locked locked-ho-acq holdover" -- "$cur" ) )
+                    return 0
+                    ;;
                 *)
-                    COMPREPLY=( $( compgen -W "id" -- "$cur" ) )
+                    COMPREPLY=( $( compgen -W "id module-name clock-id \
+                        type mode lock-status" -- "$cur" ) )
                     return 0
                     ;;
             esac
diff --git a/dpll/dpll.c b/dpll/dpll.c
index 0effa5a9c67e72..aea7b89c39d0b4 100644
--- a/dpll/dpll.c
+++ b/dpll/dpll.c
@@ -616,6 +616,9 @@ dpll_free:
 static void cmd_device_help(void)
 {
 	pr_err("Usage: dpll device show [ id DEVICE_ID ]\n");
+	pr_err("                        [ module-name NAME ] [ clock-id ID ]\n");
+	pr_err("                        [ type TYPE ] [ mode MODE ]\n");
+	pr_err("                        [ lock-status STATUS ]\n");
 	pr_err("       dpll device set id DEVICE_ID [ mode { automatic | manual } ]\n");
 	pr_err("                                    [ phase-offset-monitor { enable | disable } ]\n");
 	pr_err("                                    [ phase-offset-avg-factor NUM ]\n");
@@ -669,6 +672,21 @@ static int str_to_dpll_type(const char *s, __u32 *type)
 	return 0;
 }
 
+static int str_to_dpll_lock_status(const char *s, __u32 *status)
+{
+	if (!strcmp(s, "unlocked"))
+		*status = DPLL_LOCK_STATUS_UNLOCKED;
+	else if (!strcmp(s, "locked"))
+		*status = DPLL_LOCK_STATUS_LOCKED;
+	else if (!strcmp(s, "locked-ho-acq"))
+		*status = DPLL_LOCK_STATUS_LOCKED_HO_ACQ;
+	else if (!strcmp(s, "holdover"))
+		*status = DPLL_LOCK_STATUS_HOLDOVER;
+	else
+		return -EINVAL;
+	return 0;
+}
+
 static const char *dpll_lock_status_error_name(__u32 error)
 {
 	switch (error) {
@@ -735,6 +753,118 @@ static int attr_pin_cb(const struct nlattr *attr, void *data)
 	return MNL_CB_OK;
 }
 
+/*
+ * Dump filter helpers - client-side filtering of dump results.
+ * AND semantics: all specified filters must match.
+ */
+
+static inline bool filter_match_str(struct nlattr *attr, const char *expected)
+{
+	return attr && strcmp(mnl_attr_get_str(attr), expected) == 0;
+}
+
+static inline bool filter_match_u32(struct nlattr *attr, __u32 expected)
+{
+	return attr && mnl_attr_get_u32(attr) == expected;
+}
+
+static inline bool filter_match_u64(struct nlattr *attr, __u64 expected)
+{
+	return attr && mnl_attr_get_u64(attr) == expected;
+}
+
+static int dpll_filter_parse_str(struct dpll *dpll, const char *name,
+				 const char **dst, uint64_t *present,
+				 uint64_t flag)
+{
+	const char *str = dpll_argv_next(dpll);
+
+	if (!str) {
+		pr_err("%s requires an argument\n", name);
+		return -EINVAL;
+	}
+	*dst = str;
+	*present |= flag;
+	return 0;
+}
+
+static int dpll_filter_parse_u64(struct dpll *dpll, const char *name,
+				 __u64 *dst, uint64_t *present,
+				 uint64_t flag)
+{
+	const char *str = dpll_argv_next(dpll);
+
+	if (!str) {
+		pr_err("%s requires an argument\n", name);
+		return -EINVAL;
+	}
+	if (get_u64(dst, str, 0)) {
+		pr_err("invalid %s: %s\n", name, str);
+		return -EINVAL;
+	}
+	*present |= flag;
+	return 0;
+}
+
+static int dpll_filter_parse_enum(struct dpll *dpll, const char *name,
+				  __u32 *dst, uint64_t *present,
+				  uint64_t flag,
+				  int (*convert)(const char *, __u32 *),
+				  const char *valid_values)
+{
+	const char *str = dpll_argv_next(dpll);
+
+	if (!str) {
+		pr_err("%s requires an argument\n", name);
+		return -EINVAL;
+	}
+	if (convert(str, dst)) {
+		pr_err("invalid %s: %s (use %s)\n", name, str, valid_values);
+		return -EINVAL;
+	}
+	*present |= flag;
+	return 0;
+}
+
+#define DPLL_FILTER_DEV_MODULE_NAME	BIT(0)
+#define DPLL_FILTER_DEV_CLOCK_ID	BIT(1)
+#define DPLL_FILTER_DEV_TYPE		BIT(2)
+#define DPLL_FILTER_DEV_MODE		BIT(3)
+#define DPLL_FILTER_DEV_LOCK_STATUS	BIT(4)
+
+struct dpll_device_filter {
+	uint64_t present;
+	const char *module_name;
+	__u64 clock_id;
+	__u32 type;
+	__u32 mode;
+	__u32 lock_status;
+};
+
+static bool dpll_device_dump_filter(struct dpll_device_filter *filter,
+				    struct nlattr **tb)
+{
+	if (!filter || !filter->present)
+		return true;
+
+	if ((filter->present & DPLL_FILTER_DEV_MODULE_NAME) &&
+	    !filter_match_str(tb[DPLL_A_MODULE_NAME], filter->module_name))
+		return false;
+	if ((filter->present & DPLL_FILTER_DEV_CLOCK_ID) &&
+	    !filter_match_u64(tb[DPLL_A_CLOCK_ID], filter->clock_id))
+		return false;
+	if ((filter->present & DPLL_FILTER_DEV_TYPE) &&
+	    !filter_match_u32(tb[DPLL_A_TYPE], filter->type))
+		return false;
+	if ((filter->present & DPLL_FILTER_DEV_MODE) &&
+	    !filter_match_u32(tb[DPLL_A_MODE], filter->mode))
+		return false;
+	if ((filter->present & DPLL_FILTER_DEV_LOCK_STATUS) &&
+	    !filter_match_u32(tb[DPLL_A_LOCK_STATUS], filter->lock_status))
+		return false;
+	return true;
+}
+
 /* Print device attributes */
 static void dpll_device_print_attrs(const struct nlmsghdr *nlh,
 				    struct nlattr **tb)
@@ -765,9 +895,14 @@ static void dpll_device_print_attrs(const struct nlmsghdr *nlh,
 /* Netlink callback - device get (single device) */
 static int cmd_device_show_cb(const struct nlmsghdr *nlh, void *data)
 {
+	struct dpll_device_filter *filter = data;
 	struct nlattr *tb[DPLL_A_MAX + 1] = {};
 
 	mnl_attr_parse(nlh, sizeof(struct genlmsghdr), attr_cb, tb);
+
+	if (!dpll_device_dump_filter(filter, tb))
+		return MNL_CB_OK;
+
 	dpll_device_print_attrs(nlh, tb);
 
 	return MNL_CB_OK;
@@ -776,10 +911,14 @@ static int cmd_device_show_cb(const struct nlmsghdr *nlh, void *data)
 /* Netlink callback - device dump (multiple devices) */
 static int cmd_device_show_dump_cb(const struct nlmsghdr *nlh, void *data)
 {
+	struct dpll_device_filter *filter = data;
 	struct nlattr *tb[DPLL_A_MAX + 1] = {};
 
 	mnl_attr_parse(nlh, sizeof(struct genlmsghdr), attr_cb, tb);
 
+	if (!dpll_device_dump_filter(filter, tb))
+		return MNL_CB_OK;
+
 	open_json_object(NULL);
 	dpll_device_print_attrs(nlh, tb);
 	close_json_object();
@@ -787,7 +926,8 @@ static int cmd_device_show_dump_cb(const struct nlmsghdr *nlh, void *data)
 	return MNL_CB_OK;
 }
 
-static int cmd_device_show_id(struct dpll *dpll, __u32 id)
+static int cmd_device_show_id(struct dpll *dpll, __u32 id,
+			      struct dpll_device_filter *filter)
 {
 	struct nlmsghdr *nlh;
 	int err;
@@ -796,7 +936,8 @@ static int cmd_device_show_id(struct dpll *dpll, __u32 id)
 					  NLM_F_REQUEST | NLM_F_ACK);
 	mnl_attr_put_u32(nlh, DPLL_A_ID, id);
 
-	err = mnlu_gen_socket_sndrcv(&dpll->nlg, nlh, cmd_device_show_cb, NULL);
+	err = mnlu_gen_socket_sndrcv(&dpll->nlg, nlh, cmd_device_show_cb,
+				     filter);
 	if (err < 0) {
 		pr_err("Failed to get device %u\n", id);
 		return -1;
@@ -805,7 +946,8 @@ static int cmd_device_show_id(struct dpll *dpll, __u32 id)
 	return 0;
 }
 
-static int cmd_device_show_dump(struct dpll *dpll)
+static int cmd_device_show_dump(struct dpll *dpll,
+				struct dpll_device_filter *filter)
 {
 	struct nlmsghdr *nlh;
 	int err;
@@ -817,7 +959,7 @@ static int cmd_device_show_dump(struct dpll *dpll)
 	open_json_array(PRINT_JSON, "device");
 
 	err = mnlu_gen_socket_sndrcv(&dpll->nlg, nlh, cmd_device_show_dump_cb,
-				     NULL);
+				     filter);
 	if (err < 0) {
 		pr_err("Failed to dump devices\n");
 		close_json_array(PRINT_JSON, NULL);
@@ -831,6 +973,7 @@ static int cmd_device_show_dump(struct dpll *dpll)
 
 static int cmd_device_show(struct dpll *dpll)
 {
+	struct dpll_device_filter filter = {};
 	bool has_id = false;
 	__u32 id = 0;
 
@@ -839,6 +982,42 @@ static int cmd_device_show(struct dpll *dpll)
 			if (dpll_parse_u32(dpll, "id", &id))
 				return -EINVAL;
 			has_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_DEV_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_DEV_CLOCK_ID))
+				return -EINVAL;
+		} else if (dpll_argv_match(dpll, "type")) {
+			if (dpll_filter_parse_enum(dpll, "type",
+						   &filter.type,
+						   &filter.present,
+						   DPLL_FILTER_DEV_TYPE,
+						   str_to_dpll_type,
+						   "pps/eec"))
+				return -EINVAL;
+		} else if (dpll_argv_match(dpll, "mode")) {
+			if (dpll_filter_parse_enum(dpll, "mode",
+						   &filter.mode,
+						   &filter.present,
+						   DPLL_FILTER_DEV_MODE,
+						   str_to_dpll_mode,
+						   "manual/automatic"))
+				return -EINVAL;
+		} else if (dpll_argv_match(dpll, "lock-status")) {
+			if (dpll_filter_parse_enum(dpll, "lock-status",
+						   &filter.lock_status,
+						   &filter.present,
+						   DPLL_FILTER_DEV_LOCK_STATUS,
+						   str_to_dpll_lock_status,
+						   "unlocked/locked/locked-ho-acq/holdover"))
+				return -EINVAL;
 		} else {
 			pr_err("unknown option: %s\n", dpll_argv(dpll));
 			return -EINVAL;
@@ -846,9 +1025,9 @@ static int cmd_device_show(struct dpll *dpll)
 	}
 
 	if (has_id)
-		return cmd_device_show_id(dpll, id);
+		return cmd_device_show_id(dpll, id, &filter);
 
-	return cmd_device_show_dump(dpll);
+	return cmd_device_show_dump(dpll, &filter);
 }
 
 static int cmd_device_set(struct dpll *dpll)
diff --git a/man/man8/dpll.8 b/man/man8/dpll.8
index e82f083feac64b..1407ca9793c96c 100644
--- a/man/man8/dpll.8
+++ b/man/man8/dpll.8
@@ -60,7 +60,7 @@ and newlines for better human readability.
 
 .SH DEVICE COMMANDS
 
-.SS dpll device show [ id ID ]
+.SS dpll device show [ id ID ] [ module-name NAME ] [ clock-id ID ] [ type TYPE ] [ mode MODE ] [ lock-status STATUS ]
 
 Display information about DPLL devices. If no arguments are specified,
 shows all devices in the system.
@@ -69,6 +69,29 @@ shows all devices in the system.
 .BI id " ID"
 Show only the device with the specified numeric identifier.
 
+.TP
+.BI module-name " NAME"
+Show only devices provided by the specified kernel module.
+
+.TP
+.BI clock-id " ID"
+Show only devices with the specified 64-bit clock identifier.
+
+.TP
+.BI type " TYPE"
+Show only devices of the specified type:
+.BR pps " or " eec .
+
+.TP
+.BI mode " MODE"
+Show only devices in the specified operating mode:
+.BR manual " or " automatic .
+
+.TP
+.BI lock-status " STATUS"
+Show only devices with the specified lock status:
+.BR unlocked ", " locked ", " locked-ho-acq ", " holdover .
+
 .PP
 Output includes:
 .RS
@@ -304,6 +327,16 @@ Press Ctrl+C to stop monitoring.
 .B dpll device set id 0 phase-offset-monitor enable
 .fi
 
+.SS Show all EEC devices
+.nf
+.B dpll device show type eec
+.fi
+
+.SS Show devices from specific module in JSON
+.nf
+.B dpll -jp device show module-name ice
+.fi
+
 .SS Show all pins
 .nf
 .B dpll pin show
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH iproute2-next 3/4] dpll: add client-side filtering for pin show
  2026-02-24  9:12 [PATCH iproute2-next 0/4] dpll: add client-side filtering Petr Oros
  2026-02-24  9:12 ` [PATCH iproute2-next 1/4] dpll: fix pin id-get type filter parsing Petr Oros
  2026-02-24  9:12 ` [PATCH iproute2-next 2/4] dpll: add client-side filtering for device show Petr Oros
@ 2026-02-24  9:12 ` Petr Oros
  2026-02-24  9:12 ` [PATCH iproute2-next 4/4] dpll: add pin filtering by parent-device and parent-pin Petr Oros
  2026-03-02 16:20 ` [PATCH iproute2-next 0/4] dpll: add client-side filtering patchwork-bot+netdevbpf
  4 siblings, 0 replies; 6+ messages in thread
From: Petr Oros @ 2026-02-24  9:12 UTC (permalink / raw)
  To: netdev; +Cc: dsahern, stephen, Petr Oros

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>
---
 bash-completion/dpll |  22 +++++++-
 dpll/dpll.c          | 120 ++++++++++++++++++++++++++++++++++++++++---
 man/man8/dpll.8      |  37 ++++++++++++-
 3 files changed, 169 insertions(+), 10 deletions(-)

diff --git a/bash-completion/dpll b/bash-completion/dpll
index a614b3eb6ab355..f81a2d2caa1012 100644
--- a/bash-completion/dpll
+++ b/bash-completion/dpll
@@ -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
diff --git a/dpll/dpll.c b/dpll/dpll.c
index aea7b89c39d0b4..e39e56fc5632aa 100644
--- a/dpll/dpll.c
+++ b/dpll/dpll.c
@@ -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)
diff --git a/man/man8/dpll.8 b/man/man8/dpll.8
index 1407ca9793c96c..a4280153b4d67b 100644
--- a/man/man8/dpll.8
+++ b/man/man8/dpll.8
@@ -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
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH iproute2-next 4/4] dpll: add pin filtering by parent-device and parent-pin
  2026-02-24  9:12 [PATCH iproute2-next 0/4] dpll: add client-side filtering Petr Oros
                   ` (2 preceding siblings ...)
  2026-02-24  9:12 ` [PATCH iproute2-next 3/4] dpll: add client-side filtering for pin show Petr Oros
@ 2026-02-24  9:12 ` Petr Oros
  2026-03-02 16:20 ` [PATCH iproute2-next 0/4] dpll: add client-side filtering patchwork-bot+netdevbpf
  4 siblings, 0 replies; 6+ messages in thread
From: Petr Oros @ 2026-02-24  9:12 UTC (permalink / raw)
  To: netdev; +Cc: dsahern, stephen, Petr Oros

The existing "device" argument in "dpll pin show" sent DPLL_A_ID
in the pin dump request, but the kernel does not use this attribute
for pin dump filtering. Replace it with client-side parent-device
filtering that checks DPLL_A_PIN_PARENT_ID inside nested
DPLL_A_PIN_PARENT_DEVICE attributes.

Also add parent-pin filtering for mux pin hierarchies using the
same approach with DPLL_A_PIN_PARENT_PIN nested attributes.

Rename the "device" argument to "parent-device" to better reflect
the actual semantics.

Signed-off-by: Petr Oros <poros@redhat.com>
---
 bash-completion/dpll | 12 ++++--
 dpll/dpll.c          | 88 ++++++++++++++++++++++++++++++++++----------
 man/man8/dpll.8      | 10 +++--
 3 files changed, 85 insertions(+), 25 deletions(-)

diff --git a/bash-completion/dpll b/bash-completion/dpll
index f81a2d2caa1012..b3ba0d306183ac 100644
--- a/bash-completion/dpll
+++ b/bash-completion/dpll
@@ -153,11 +153,16 @@ _dpll_pin()
                         "$(_dpll_direct_complete pin_id)" -- "$cur" ) )
                     return 0
                     ;;
-                device)
+                parent-device)
                     COMPREPLY=( $( compgen -W \
                         "$(_dpll_direct_complete device_id)" -- "$cur" ) )
                     return 0
                     ;;
+                parent-pin)
+                    COMPREPLY=( $( compgen -W \
+                        "$(_dpll_direct_complete pin_id)" -- "$cur" ) )
+                    return 0
+                    ;;
                 module-name)
                     COMPREPLY=( $( compgen -W \
                         "$(_dpll_direct_complete module_name)" -- "$cur" ) )
@@ -177,8 +182,9 @@ _dpll_pin()
                     return 0
                     ;;
                 *)
-                    COMPREPLY=( $( compgen -W "id device module-name clock-id \
-                        board-label panel-label package-label type" \
+                    COMPREPLY=( $( compgen -W "id parent-device parent-pin \
+                        module-name clock-id board-label panel-label \
+                        package-label type" \
                         -- "$cur" ) )
                     return 0
                     ;;
diff --git a/dpll/dpll.c b/dpll/dpll.c
index e39e56fc5632aa..facf150f63d565 100644
--- a/dpll/dpll.c
+++ b/dpll/dpll.c
@@ -788,6 +788,24 @@ static int dpll_filter_parse_str(struct dpll *dpll, const char *name,
 	return 0;
 }
 
+static int dpll_filter_parse_u32(struct dpll *dpll, const char *name,
+				 __u32 *dst, uint64_t *present,
+				 uint64_t flag)
+{
+	const char *str = dpll_argv_next(dpll);
+
+	if (!str) {
+		pr_err("%s requires an argument\n", name);
+		return -EINVAL;
+	}
+	if (get_u32(dst, str, 0)) {
+		pr_err("invalid %s: %s\n", name, str);
+		return -EINVAL;
+	}
+	*present |= flag;
+	return 0;
+}
+
 static int dpll_filter_parse_u64(struct dpll *dpll, const char *name,
 				 __u64 *dst, uint64_t *present,
 				 uint64_t flag)
@@ -871,6 +889,8 @@ static bool dpll_device_dump_filter(struct dpll_device_filter *filter,
 #define DPLL_FILTER_PIN_PANEL_LABEL	BIT(3)
 #define DPLL_FILTER_PIN_PACKAGE_LABEL	BIT(4)
 #define DPLL_FILTER_PIN_TYPE		BIT(5)
+#define DPLL_FILTER_PIN_PARENT_DEVICE	BIT(6)
+#define DPLL_FILTER_PIN_PARENT_PIN	BIT(7)
 
 struct dpll_pin_filter {
 	uint64_t present;
@@ -880,9 +900,31 @@ struct dpll_pin_filter {
 	const char *panel_label;
 	const char *package_label;
 	__u32 type;
+	__u32 parent_device_id;
+	__u32 parent_pin_id;
 };
 
+static bool filter_match_nested_id(const struct nlmsghdr *nlh,
+				   uint16_t nest_type, __u32 expected_id)
+{
+	const struct nlattr *attr;
+
+	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
+		struct nlattr *tb_nest[DPLL_A_PIN_MAX + 1] = {};
+
+		if (mnl_attr_get_type(attr) != nest_type)
+			continue;
+
+		mnl_attr_parse_nested(attr, attr_pin_cb, tb_nest);
+		if (filter_match_u32(tb_nest[DPLL_A_PIN_PARENT_ID],
+				     expected_id))
+			return true;
+	}
+	return false;
+}
+
 static bool dpll_pin_dump_filter(struct dpll_pin_filter *filter,
+				 const struct nlmsghdr *nlh,
 				 struct nlattr **tb)
 {
 	if (!filter || !filter->present)
@@ -907,6 +949,14 @@ static bool dpll_pin_dump_filter(struct dpll_pin_filter *filter,
 	if ((filter->present & DPLL_FILTER_PIN_TYPE) &&
 	    !filter_match_u32(tb[DPLL_A_PIN_TYPE], filter->type))
 		return false;
+	if ((filter->present & DPLL_FILTER_PIN_PARENT_DEVICE) &&
+	    !filter_match_nested_id(nlh, DPLL_A_PIN_PARENT_DEVICE,
+				    filter->parent_device_id))
+		return false;
+	if ((filter->present & DPLL_FILTER_PIN_PARENT_PIN) &&
+	    !filter_match_nested_id(nlh, DPLL_A_PIN_PARENT_PIN,
+				    filter->parent_pin_id))
+		return false;
 	return true;
 }
 
@@ -1230,7 +1280,8 @@ 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("Usage: dpll pin show [ id PIN_ID ]\n");
+	pr_err("                     [ parent-device DEVICE_ID ] [ parent-pin PIN_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");
@@ -1607,7 +1658,7 @@ 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))
+	if (!dpll_pin_dump_filter(filter, nlh, tb))
 		return MNL_CB_OK;
 
 	/* Pass 1: Count multi-attr occurrences and allocate */
@@ -1691,12 +1742,9 @@ static int cmd_pin_show_dump_cb(const struct nlmsghdr *nlh, void *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))
+	if (!dpll_pin_dump_filter(filter, nlh, tb))
 		return MNL_CB_OK;
 
 	open_json_object(NULL);
@@ -1726,8 +1774,7 @@ static int cmd_pin_show_id(struct dpll *dpll, __u32 id,
 	return 0;
 }
 
-static int cmd_pin_show_dump(struct dpll *dpll, bool has_device_id,
-			     __u32 device_id,
+static int cmd_pin_show_dump(struct dpll *dpll,
 			     struct dpll_pin_filter *filter)
 {
 	struct nlmsghdr *nlh;
@@ -1737,11 +1784,6 @@ static int cmd_pin_show_dump(struct dpll *dpll, bool has_device_id,
 					  NLM_F_REQUEST | NLM_F_ACK |
 						  NLM_F_DUMP);
 
-	/* If device_id specified, filter pins by device */
-	if (has_device_id)
-		mnl_attr_put_u32(nlh, DPLL_A_ID, device_id);
-
-	/* Open JSON array for multiple pins */
 	open_json_array(PRINT_JSON, "pin");
 
 	err = mnlu_gen_socket_sndrcv(&dpll->nlg, nlh, cmd_pin_show_dump_cb,
@@ -1760,19 +1802,27 @@ 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;
+	bool has_pin_id = false;
+	__u32 pin_id = 0;
 
 	while (dpll_argc(dpll) > 0) {
 		if (dpll_argv_match(dpll, "id")) {
 			if (dpll_parse_u32(dpll, "id", &pin_id))
 				return -EINVAL;
 			has_pin_id = true;
-		} else if (dpll_argv_match(dpll, "device")) {
-			if (dpll_parse_u32(dpll, "device", &device_id))
+		} else if (dpll_argv_match(dpll, "parent-device")) {
+			if (dpll_filter_parse_u32(dpll, "parent-device",
+						  &filter.parent_device_id,
+						  &filter.present,
+						  DPLL_FILTER_PIN_PARENT_DEVICE))
+				return -EINVAL;
+		} else if (dpll_argv_match(dpll, "parent-pin")) {
+			if (dpll_filter_parse_u32(dpll, "parent-pin",
+						  &filter.parent_pin_id,
+						  &filter.present,
+						  DPLL_FILTER_PIN_PARENT_PIN))
 				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,
@@ -1820,7 +1870,7 @@ static int cmd_pin_show(struct dpll *dpll)
 	if (has_pin_id)
 		return cmd_pin_show_id(dpll, pin_id, &filter);
 
-	return cmd_pin_show_dump(dpll, has_device_id, device_id, &filter);
+	return cmd_pin_show_dump(dpll, &filter);
 }
 
 static int cmd_pin_parse_parent_device(struct dpll *dpll, struct nlmsghdr *nlh)
diff --git a/man/man8/dpll.8 b/man/man8/dpll.8
index a4280153b4d67b..86bc1a7e56d9f8 100644
--- a/man/man8/dpll.8
+++ b/man/man8/dpll.8
@@ -161,7 +161,7 @@ Device type:
 
 .SH PIN COMMANDS
 
-.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 ]
+.SS dpll pin show [ id ID ] [ parent-device DEVICE_ID ] [ parent-pin PIN_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.
@@ -171,8 +171,12 @@ shows all pins in the system.
 Show only the pin with the specified numeric identifier.
 
 .TP
-.BI device " ID"
-Show only pins associated with the specified device ID.
+.BI parent-device " DEVICE_ID"
+Show only pins that have the specified DPLL device as a parent.
+
+.TP
+.BI parent-pin " PIN_ID"
+Show only pins that have the specified pin as a parent (mux pins).
 
 .TP
 .BI module-name " NAME"
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH iproute2-next 0/4] dpll: add client-side filtering
  2026-02-24  9:12 [PATCH iproute2-next 0/4] dpll: add client-side filtering Petr Oros
                   ` (3 preceding siblings ...)
  2026-02-24  9:12 ` [PATCH iproute2-next 4/4] dpll: add pin filtering by parent-device and parent-pin Petr Oros
@ 2026-03-02 16:20 ` patchwork-bot+netdevbpf
  4 siblings, 0 replies; 6+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-03-02 16:20 UTC (permalink / raw)
  To: Petr Oros; +Cc: netdev, dsahern, stephen

Hello:

This series was applied to iproute2/iproute2-next.git (main)
by David Ahern <dsahern@kernel.org>:

On Tue, 24 Feb 2026 10:12:39 +0100 you wrote:
> This series fixes a parsing bug in dpll pin id-get and adds
> client-side filtering support for dpll device show and pin show
> commands.
> 
> Patch 1 fixes a bug where "dpll pin id-get type gnss" would read
> the keyword "type" as the enum value instead of the actual type.
> 
> [...]

Here is the summary with links:
  - [iproute2-next,1/4] dpll: fix pin id-get type filter parsing
    (no matching commit)
  - [iproute2-next,2/4] dpll: add client-side filtering for device show
    https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=4c4dfe5b4a38
  - [iproute2-next,3/4] dpll: add client-side filtering for pin show
    https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=0a0fe9c8390d
  - [iproute2-next,4/4] dpll: add pin filtering by parent-device and parent-pin
    https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=5d9d0ae4d7e5

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-03-02 16:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-24  9:12 [PATCH iproute2-next 0/4] dpll: add client-side filtering Petr Oros
2026-02-24  9:12 ` [PATCH iproute2-next 1/4] dpll: fix pin id-get type filter parsing Petr Oros
2026-02-24  9:12 ` [PATCH iproute2-next 2/4] dpll: add client-side filtering for device show Petr Oros
2026-02-24  9:12 ` [PATCH iproute2-next 3/4] dpll: add client-side filtering for pin show Petr Oros
2026-02-24  9:12 ` [PATCH iproute2-next 4/4] dpll: add pin filtering by parent-device and parent-pin Petr Oros
2026-03-02 16:20 ` [PATCH iproute2-next 0/4] dpll: add client-side filtering patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox