[PATCH 1/2] netlink: implement generic nlmsg_flags decoding

Dmitry V. Levin ldv at altlinux.org
Wed Jun 7 12:46:02 UTC 2017


On Wed, Jun 07, 2017 at 12:47:45PM +0800, JingPiao Chen wrote:
> * netlink.c: Include xlat/netlink_get_flags.h,
> xlat/netlink_new_flags.h, xlat/nl_route_get_types.h,
> xlat/nl_route_new_types.h, xlat/nl_xfrm_get_types.h,
> and xlat/nl_xfrm_new_types.h.
> (decode_nlmsg_flags): New function.
> (print_nlmsghdr): Use it.
> * xlat/netlink_get_flags.in: New file.
> * xlat/netlink_new_flags.in: Likewise.
> * xlat/nl_route_get_types.in: Likewise.
> * xlat/nl_route_new_types.in: Likewise.
> * xlat/nl_xfrm_get_types.in: Likewise.
> * xlat/nl_xfrm_new_types.in: Likewise.
> ---
> 
> This idea I have disscussed in irc, I do not have other idea, so I trying       
> to implement this idea.
> 
>  netlink.c                  | 48 +++++++++++++++++++++++++++++++++++++++++++++-
>  xlat/netlink_get_flags.in  | 11 +++++++++++
>  xlat/netlink_new_flags.in  | 11 +++++++++++
>  xlat/nl_route_get_types.in | 19 ++++++++++++++++++
>  xlat/nl_route_new_types.in | 17 ++++++++++++++++
>  xlat/nl_xfrm_get_types.in  |  5 +++++
>  xlat/nl_xfrm_new_types.in  |  5 +++++
>  7 files changed, 115 insertions(+), 1 deletion(-)
>  create mode 100644 xlat/netlink_get_flags.in
>  create mode 100644 xlat/netlink_new_flags.in
>  create mode 100644 xlat/nl_route_get_types.in
>  create mode 100644 xlat/nl_route_new_types.in
>  create mode 100644 xlat/nl_xfrm_get_types.in
>  create mode 100644 xlat/nl_xfrm_new_types.in
> 
> diff --git a/netlink.c b/netlink.c
> index f9ff465..3168d73 100644
> --- a/netlink.c
> +++ b/netlink.c
> @@ -34,14 +34,20 @@
>  #include <linux/rtnetlink.h>
>  #include <linux/xfrm.h>
>  #include "xlat/netlink_flags.h"
> +#include "xlat/netlink_get_flags.h"
> +#include "xlat/netlink_new_flags.h"
>  #include "xlat/netlink_protocols.h"
>  #include "xlat/netlink_types.h"
>  #include "xlat/nl_audit_types.h"
>  #include "xlat/nl_netfilter_msg_types.h"
>  #include "xlat/nl_netfilter_subsys_ids.h"
> +#include "xlat/nl_route_get_types.h"
> +#include "xlat/nl_route_new_types.h"
>  #include "xlat/nl_route_types.h"
>  #include "xlat/nl_selinux_types.h"
>  #include "xlat/nl_sock_diag_types.h"
> +#include "xlat/nl_xfrm_get_types.h"
> +#include "xlat/nl_xfrm_new_types.h"
>  #include "xlat/nl_xfrm_types.h"
>  
>  #undef NLMSG_HDRLEN
> @@ -152,6 +158,45 @@ decode_nlmsg_type(const uint16_t type, const unsigned int family)
>  	}
>  }
>  
> +static const struct {
> +	const struct xlat *gets;
> +	const struct xlat *news;
> +} type_class[] = {
> +	[NETLINK_ROUTE] = {
> +		.gets = nl_route_get_types,
> +		.news = nl_route_new_types,
> +	},
> +	[NETLINK_SOCK_DIAG] = {
> +		.gets = nl_sock_diag_types,
> +	},
> +	[NETLINK_XFRM] = {
> +		.gets = nl_xfrm_get_types,
> +		.news = nl_xfrm_new_types,
> +	},
> +};
> +
> +/*
> + * As all valid netlink families are positive integers, use unsigned int
> + * for family here to filter out NL_FAMILY_ERROR and NL_FAMILY_DEFAULT.
> + */
> +static void
> +decode_nlmsg_flags(const uint16_t flags, const uint16_t type,
> +		   const unsigned int family)
> +{
> +	if (family < ARRAY_SIZE(type_class)) {
> +		if (type_class[family].gets
> +		    && xlookup(type_class[family].gets, type))
> +			printflags(netlink_get_flags, flags, "NLMSG_F_???");
> +		else if (type_class[family].news
> +			 && xlookup(type_class[family].news, type))
> +			printflags(netlink_new_flags, flags, "NLMSG_F_???");
> +		else
> +			printflags(netlink_flags, flags, "NLMSG_F_???");
> +	} else {
> +		printflags(netlink_flags, flags, "NLMSG_F_???");
> +	}
> +}
> +

Using xlat tables just to list constants is an overkill.

For now this could be done with a switch statement, e.g.

	const struct xlat *table = netlink_flags;

	switch (family) {
		case NETLINK_SOCK_DIAG:
			table = netlink_get_flags;
			break;

		case NETLINK_ROUTE:
			switch (type & 3) {
				case  0:
					table = netlink_new_flags;
					break;
				case  2:
					table = netlink_get_flags;
					break;
			}
			break;

		case NETLINK_XFRM:
			switch (type) {
				case XFRM_MSG_NEWSA:
				case XFRM_MSG_NEWPOLICY:
				case XFRM_MSG_NEWAE:
				case XFRM_MSG_NEWSADINFO:
				case XFRM_MSG_NEWSPDINFO:
					table = netlink_new_flags;
					break;

				case XFRM_MSG_GETSA:
				case XFRM_MSG_GETPOLICY:
				case XFRM_MSG_GETAE:
				case XFRM_MSG_GETSADINFO:
				case XFRM_MSG_GETSPDINFO:
					table = netlink_get_flags;
					break;
			}
			break;
	}

	printflags(table, flags, "NLM_F_???");

With growing number of netfilter family decoders this could be delegated
further, e.g. by extending nlmsg_types table.


-- 
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20170607/8089530d/attachment.bin>


More information about the Strace-devel mailing list