netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] libnetlink: add rtattr_for_each_nested() iteration macro
@ 2020-08-24 17:51 Johannes Berg
  2020-08-24 17:51 ` [PATCH 2/3] libnetlink: add nl_print_policy() helper Johannes Berg
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Johannes Berg @ 2020-08-24 17:51 UTC (permalink / raw)
  To: linux-wireless, Stephen Hemminger, netdev; +Cc: David Ahern

This is useful for iterating elements in a nested attribute,
if they're not parsed with a strict length limit or such.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/libnetlink.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/libnetlink.h b/include/libnetlink.h
index e27516f7648f..0d4a9f29afbd 100644
--- a/include/libnetlink.h
+++ b/include/libnetlink.h
@@ -284,4 +284,9 @@ int rtnl_from_file(FILE *, rtnl_listen_filter_t handler,
  * messages from dump file */
 #define NLMSG_TSTAMP	15
 
+#define rtattr_for_each_nested(attr, nest) \
+	for ((attr) = (void *)RTA_DATA(nest); \
+	     RTA_OK(attr, RTA_PAYLOAD(nest) - ((char *)(attr) - (char *)RTA_DATA((nest)))); \
+	     (attr) = RTA_TAIL((attr)))
+
 #endif /* __LIBNETLINK_H__ */
-- 
2.26.2


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

* [PATCH 2/3] libnetlink: add nl_print_policy() helper
  2020-08-24 17:51 [PATCH 1/3] libnetlink: add rtattr_for_each_nested() iteration macro Johannes Berg
@ 2020-08-24 17:51 ` Johannes Berg
  2020-10-25 21:23   ` Stephen Hemminger
  2020-08-24 17:51 ` [PATCH 3/3] genl: ctrl: support dumping netlink policy Johannes Berg
  2020-08-25  3:36 ` [PATCH 1/3] libnetlink: add rtattr_for_each_nested() iteration macro David Ahern
  2 siblings, 1 reply; 5+ messages in thread
From: Johannes Berg @ 2020-08-24 17:51 UTC (permalink / raw)
  To: linux-wireless, Stephen Hemminger, netdev; +Cc: David Ahern

This prints out the data from the given nested attribute
to the given FILE pointer, interpreting the firmware that
the kernel has for showing netlink policies.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/libnetlink.h |  2 ++
 lib/libnetlink.c     | 73 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)

diff --git a/include/libnetlink.h b/include/libnetlink.h
index 0d4a9f29afbd..b9073a6a13ad 100644
--- a/include/libnetlink.h
+++ b/include/libnetlink.h
@@ -289,4 +289,6 @@ int rtnl_from_file(FILE *, rtnl_listen_filter_t handler,
 	     RTA_OK(attr, RTA_PAYLOAD(nest) - ((char *)(attr) - (char *)RTA_DATA((nest)))); \
 	     (attr) = RTA_TAIL((attr)))
 
+void nl_print_policy(const struct rtattr *attr, FILE *fp);
+
 #endif /* __LIBNETLINK_H__ */
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index e02d6294b02e..a7b60d873afb 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -28,6 +28,7 @@
 #include <linux/nexthop.h>
 
 #include "libnetlink.h"
+#include "utils.h"
 
 #define __aligned(x)		__attribute__((aligned(x)))
 
@@ -1440,3 +1441,75 @@ int __parse_rtattr_nested_compat(struct rtattr *tb[], int max,
 	memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
 	return 0;
 }
+
+static const char *get_nla_type_str(unsigned int attr)
+{
+	switch (attr) {
+#define C(x) case NL_ATTR_TYPE_ ## x: return #x
+	C(U8);
+	C(U16);
+	C(U32);
+	C(U64);
+	C(STRING);
+	C(FLAG);
+	C(NESTED);
+	C(NESTED_ARRAY);
+	C(NUL_STRING);
+	C(BINARY);
+	C(S8);
+	C(S16);
+	C(S32);
+	C(S64);
+	C(BITFIELD32);
+	default:
+		return "unknown";
+	}
+}
+
+void nl_print_policy(const struct rtattr *attr, FILE *fp)
+{
+	const struct rtattr *pos;
+
+	rtattr_for_each_nested(pos, attr) {
+		const struct rtattr *attr;
+
+		fprintf(fp, " policy[%u]:", pos->rta_type & ~NLA_F_NESTED);
+
+		rtattr_for_each_nested(attr, pos) {
+			struct rtattr *tp[NL_POLICY_TYPE_ATTR_MAX + 1];
+
+			parse_rtattr_nested(tp, ARRAY_SIZE(tp) - 1, attr);
+
+			if (tp[NL_POLICY_TYPE_ATTR_TYPE])
+				fprintf(fp, "attr[%u]: type=%s",
+					attr->rta_type & ~NLA_F_NESTED,
+					get_nla_type_str(rta_getattr_u32(tp[NL_POLICY_TYPE_ATTR_TYPE])));
+
+			if (tp[NL_POLICY_TYPE_ATTR_POLICY_IDX])
+				fprintf(fp, " policy:%u",
+					rta_getattr_u32(tp[NL_POLICY_TYPE_ATTR_POLICY_IDX]));
+
+			if (tp[NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE])
+				fprintf(fp, " maxattr:%u",
+					rta_getattr_u32(tp[NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE]));
+
+			if (tp[NL_POLICY_TYPE_ATTR_MIN_VALUE_S] && tp[NL_POLICY_TYPE_ATTR_MAX_VALUE_S])
+				fprintf(fp, " range:[%lld,%lld]",
+					(signed long long)rta_getattr_u64(tp[NL_POLICY_TYPE_ATTR_MIN_VALUE_S]),
+					(signed long long)rta_getattr_u64(tp[NL_POLICY_TYPE_ATTR_MAX_VALUE_S]));
+
+			if (tp[NL_POLICY_TYPE_ATTR_MIN_VALUE_U] && tp[NL_POLICY_TYPE_ATTR_MAX_VALUE_U])
+				fprintf(fp, " range:[%llu,%llu]",
+					(unsigned long long)rta_getattr_u64(tp[NL_POLICY_TYPE_ATTR_MIN_VALUE_U]),
+					(unsigned long long)rta_getattr_u64(tp[NL_POLICY_TYPE_ATTR_MAX_VALUE_U]));
+
+			if (tp[NL_POLICY_TYPE_ATTR_MIN_LENGTH])
+				fprintf(fp, " min len:%u",
+					rta_getattr_u32(tp[NL_POLICY_TYPE_ATTR_MIN_LENGTH]));
+
+			if (tp[NL_POLICY_TYPE_ATTR_MAX_LENGTH])
+				fprintf(fp, " max len:%u",
+					rta_getattr_u32(tp[NL_POLICY_TYPE_ATTR_MAX_LENGTH]));
+		}
+	}
+}
-- 
2.26.2


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

* [PATCH 3/3] genl: ctrl: support dumping netlink policy
  2020-08-24 17:51 [PATCH 1/3] libnetlink: add rtattr_for_each_nested() iteration macro Johannes Berg
  2020-08-24 17:51 ` [PATCH 2/3] libnetlink: add nl_print_policy() helper Johannes Berg
@ 2020-08-24 17:51 ` Johannes Berg
  2020-08-25  3:36 ` [PATCH 1/3] libnetlink: add rtattr_for_each_nested() iteration macro David Ahern
  2 siblings, 0 replies; 5+ messages in thread
From: Johannes Berg @ 2020-08-24 17:51 UTC (permalink / raw)
  To: linux-wireless, Stephen Hemminger, netdev; +Cc: David Ahern

Support dumping the netlink policy of a given generic netlink
family, the policy (with any sub-policies if appropriate) is
exported by the kernel in a general fashion.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 genl/ctrl.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/genl/ctrl.c b/genl/ctrl.c
index 0fb464b01cfb..68099fe97f1a 100644
--- a/genl/ctrl.c
+++ b/genl/ctrl.c
@@ -28,13 +28,15 @@
 static int usage(void)
 {
 	fprintf(stderr,"Usage: ctrl <CMD>\n" \
-		       "CMD   := get <PARMS> | list | monitor\n" \
+		       "CMD   := get <PARMS> | list | monitor | policy <PARMS>\n" \
 		       "PARMS := name <name> | id <id>\n" \
 		       "Examples:\n" \
 		       "\tctrl ls\n" \
 		       "\tctrl monitor\n" \
 		       "\tctrl get name foobar\n" \
-		       "\tctrl get id 0xF\n");
+		       "\tctrl get id 0xF\n"
+		       "\tctrl policy name foobar\n"
+		       "\tctrl policy id 0xF\n");
 	return -1;
 }
 
@@ -123,7 +125,8 @@ static int print_ctrl(struct rtnl_ctrl_data *ctrl,
 	    ghdr->cmd != CTRL_CMD_DELFAMILY &&
 	    ghdr->cmd != CTRL_CMD_NEWFAMILY &&
 	    ghdr->cmd != CTRL_CMD_NEWMCAST_GRP &&
-	    ghdr->cmd != CTRL_CMD_DELMCAST_GRP) {
+	    ghdr->cmd != CTRL_CMD_DELMCAST_GRP &&
+	    ghdr->cmd != CTRL_CMD_GETPOLICY) {
 		fprintf(stderr, "Unknown controller command %d\n", ghdr->cmd);
 		return 0;
 	}
@@ -136,7 +139,7 @@ static int print_ctrl(struct rtnl_ctrl_data *ctrl,
 	}
 
 	attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN);
-	parse_rtattr(tb, CTRL_ATTR_MAX, attrs, len);
+	parse_rtattr_flags(tb, CTRL_ATTR_MAX, attrs, len, NLA_F_NESTED);
 
 	if (tb[CTRL_ATTR_FAMILY_NAME]) {
 		char *name = RTA_DATA(tb[CTRL_ATTR_FAMILY_NAME]);
@@ -159,6 +162,9 @@ static int print_ctrl(struct rtnl_ctrl_data *ctrl,
 		__u32 *ma = RTA_DATA(tb[CTRL_ATTR_MAXATTR]);
 		fprintf(fp, " max attribs: %d ",*ma);
 	}
+	if (tb[CTRL_ATTR_POLICY])
+		nl_print_policy(tb[CTRL_ATTR_POLICY], fp);
+
 	/* end of family definitions .. */
 	fprintf(fp,"\n");
 	if (tb[CTRL_ATTR_OPS]) {
@@ -235,7 +241,9 @@ static int ctrl_list(int cmd, int argc, char **argv)
 		exit(1);
 	}
 
-	if (cmd == CTRL_CMD_GETFAMILY) {
+	if (cmd == CTRL_CMD_GETFAMILY || cmd == CTRL_CMD_GETPOLICY) {
+		req.g.cmd = cmd;
+
 		if (argc != 2) {
 			fprintf(stderr, "Wrong number of params\n");
 			return -1;
@@ -260,7 +268,9 @@ static int ctrl_list(int cmd, int argc, char **argv)
 			fprintf(stderr, "Wrong params\n");
 			goto ctrl_done;
 		}
+	}
 
+	if (cmd == CTRL_CMD_GETFAMILY) {
 		if (rtnl_talk(&rth, nlh, &answer) < 0) {
 			fprintf(stderr, "Error talking to the kernel\n");
 			goto ctrl_done;
@@ -273,7 +283,7 @@ static int ctrl_list(int cmd, int argc, char **argv)
 
 	}
 
-	if (cmd == CTRL_CMD_UNSPEC) {
+	if (cmd == CTRL_CMD_UNSPEC || cmd == CTRL_CMD_GETPOLICY) {
 		nlh->nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
 		nlh->nlmsg_seq = rth.dump = ++rth.seq;
 
@@ -324,6 +334,8 @@ static int parse_ctrl(struct genl_util *a, int argc, char **argv)
 	    matches(*argv, "show") == 0 ||
 	    matches(*argv, "lst") == 0)
 		return ctrl_list(CTRL_CMD_UNSPEC, argc-1, argv+1);
+	if (matches(*argv, "policy") == 0)
+		return ctrl_list(CTRL_CMD_GETPOLICY, argc-1, argv+1);
 	if (matches(*argv, "help") == 0)
 		return usage();
 
-- 
2.26.2


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

* Re: [PATCH 1/3] libnetlink: add rtattr_for_each_nested() iteration macro
  2020-08-24 17:51 [PATCH 1/3] libnetlink: add rtattr_for_each_nested() iteration macro Johannes Berg
  2020-08-24 17:51 ` [PATCH 2/3] libnetlink: add nl_print_policy() helper Johannes Berg
  2020-08-24 17:51 ` [PATCH 3/3] genl: ctrl: support dumping netlink policy Johannes Berg
@ 2020-08-25  3:36 ` David Ahern
  2 siblings, 0 replies; 5+ messages in thread
From: David Ahern @ 2020-08-25  3:36 UTC (permalink / raw)
  To: Johannes Berg, linux-wireless, Stephen Hemminger, netdev

On 8/24/20 11:51 AM, Johannes Berg wrote:
> This is useful for iterating elements in a nested attribute,
> if they're not parsed with a strict length limit or such.
> 
> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
> ---
>  include/libnetlink.h | 5 +++++
>  1 file changed, 5 insertions(+)
> 

applied to iproute2-next. Thanks, Johannes.


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

* Re: [PATCH 2/3] libnetlink: add nl_print_policy() helper
  2020-08-24 17:51 ` [PATCH 2/3] libnetlink: add nl_print_policy() helper Johannes Berg
@ 2020-10-25 21:23   ` Stephen Hemminger
  0 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2020-10-25 21:23 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, netdev, David Ahern

On Mon, 24 Aug 2020 19:51:07 +0200
Johannes Berg <johannes@sipsolutions.net> wrote:

> This prints out the data from the given nested attribute
> to the given FILE pointer, interpreting the firmware that
> the kernel has for showing netlink policies.
> 
> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

This patch causes warnings from iproute2 build on Debian stable.
Please fix.

    CC       libnetlink.o
libnetlink.c:33: warning: "__aligned" redefined
 #define __aligned(x)  __attribute__((aligned(x)))
 
In file included from /usr/include/bsd/string.h:39,
                 from ../include/utils.h:13,
                 from libnetlink.c:31:
/usr/include/bsd/sys/cdefs.h:128: note: this is the location of the previous definition
 #  define __aligned(x) __attribute__((__aligned__(x)))
 

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

end of thread, other threads:[~2020-10-25 21:23 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-24 17:51 [PATCH 1/3] libnetlink: add rtattr_for_each_nested() iteration macro Johannes Berg
2020-08-24 17:51 ` [PATCH 2/3] libnetlink: add nl_print_policy() helper Johannes Berg
2020-10-25 21:23   ` Stephen Hemminger
2020-08-24 17:51 ` [PATCH 3/3] genl: ctrl: support dumping netlink policy Johannes Berg
2020-08-25  3:36 ` [PATCH 1/3] libnetlink: add rtattr_for_each_nested() iteration macro David Ahern

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).