[PATCH 1/4] rtnl_mdb: decode br_port_msg netlink attributes

Dmitry V. Levin ldv at altlinux.org
Tue Sep 12 00:29:42 UTC 2017


On Sun, Sep 10, 2017 at 10:37:04AM +0800, JingPiao Chen wrote:
> * configure.ac (AC_CHECK_TYPES): Check for struct br_mdb_entry
> in <linux/if_bridge.h>.
> (AC_CHECK_MEMBERS): Check for state, flags and vid fields
> in struct br_mdb_entry.
> * rtnl_mdb.c: Include "xlat/mdb_flags.h", "xlat/mdb_states.h",
> "xlat/rtnl_mdba_mdb_attrs.h", "xlat/rtnl_mdba_mdb_eattr_attrs.h",
> "xlat/rtnl_mdba_mdb_entry_attrs.h" and "xlat/rtnl_mdba_router_attrs.h".
> (decode_mdba_mdb_entry_info, decode_mdba_mdb_entry,
> decode_mdba_mdb, decode_mdba_router_port,
> decode_mdba_router): New functions.
> (mdba_mdb_eattr_nla_decoders, mdba_mdb_entry_nla_decoders,
> mdba_mdb_nla_decoders, mdba_router_nla_decoders,
> br_port_msg_nla_decoders): New arrays.
> (decode_br_port_msg): Use br_port_msg_nla_decoders.
> * xlat/mdb_flags.in: New file.
> * xlat/mdb_states.in: Likewise.
> * xlat/rtnl_mdba_mdb_attrs.in: Likewise.
> * xlat/rtnl_mdba_mdb_eattr_attrs.in: Likewise.
> * xlat/rtnl_mdba_mdb_entry_attrs.in: Likewise.
> * xlat/rtnl_mdba_router_attrs.in: Likewise.
> ---
>  configure.ac                      |  11 ++-
>  rtnl_mdb.c                        | 151 +++++++++++++++++++++++++++++++++++++-
>  xlat/mdb_flags.in                 |   1 +
>  xlat/mdb_states.in                |   2 +
>  xlat/rtnl_mdba_mdb_attrs.in       |   2 +
>  xlat/rtnl_mdba_mdb_eattr_attrs.in |   2 +
>  xlat/rtnl_mdba_mdb_entry_attrs.in |   2 +
>  xlat/rtnl_mdba_router_attrs.in    |   2 +
>  8 files changed, 171 insertions(+), 2 deletions(-)
>  create mode 100644 xlat/mdb_flags.in
>  create mode 100644 xlat/mdb_states.in
>  create mode 100644 xlat/rtnl_mdba_mdb_attrs.in
>  create mode 100644 xlat/rtnl_mdba_mdb_eattr_attrs.in
>  create mode 100644 xlat/rtnl_mdba_mdb_entry_attrs.in
>  create mode 100644 xlat/rtnl_mdba_router_attrs.in
> 
> diff --git a/configure.ac b/configure.ac
> index cb6571a..2990a03 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -448,7 +448,16 @@ AC_CHECK_HEADERS([linux/bpf.h], [
>  	st_CHECK_UNION_BPF_ATTR([prog_flags])
>  ])
>  
> -AC_CHECK_TYPES([struct br_port_msg],,, [#include <linux/if_bridge.h>])
> +AC_CHECK_TYPES(m4_normalize([
> +	struct br_mdb_entry,
> +	struct br_port_msg
> +]),,, [#include <linux/if_bridge.h>])
> +AC_CHECK_MEMBERS(m4_normalize([
> +	struct br_mdb_entry.flags,
> +	struct br_mdb_entry.state,
> +	struct br_mdb_entry.vid
> +]),,, [#include <linux/if_bridge.h>])
> +
>  AC_CHECK_TYPES([struct dcbmsg],,, [#include <linux/dcbnl.h>])
>  AC_CHECK_TYPES([struct ifaddrlblmsg],,, [#include <linux/if_addrlabel.h>])
>  AC_CHECK_TYPES([struct netconfmsg],,, [#include <linux/netconf.h>])
> diff --git a/rtnl_mdb.c b/rtnl_mdb.c
> index ebe737d..7ec3c86 100644
> --- a/rtnl_mdb.c
> +++ b/rtnl_mdb.c
> @@ -39,7 +39,154 @@
>  # include <linux/if_bridge.h>
>  # include "netlink.h"
>  
> +# ifdef HAVE_STRUCT_BR_MDB_ENTRY_FLAGS
> +#  include "xlat/mdb_flags.h"
> +# endif
> +# ifdef HAVE_STRUCT_BR_MDB_ENTRY_STATE
> +#  include "xlat/mdb_states.h"
> +# endif
>  # include "xlat/rtnl_mdb_attrs.h"
> +# include "xlat/rtnl_mdba_mdb_attrs.h"
> +# include "xlat/rtnl_mdba_mdb_eattr_attrs.h"
> +# include "xlat/rtnl_mdba_mdb_entry_attrs.h"
> +# include "xlat/rtnl_mdba_router_attrs.h"
> +
> +static const nla_decoder_t mdba_mdb_eattr_nla_decoders[] = {
> +	[MDBA_MDB_EATTR_TIMER]	= decode_nla_u32
> +};
> +
> +static bool
> +decode_mdba_mdb_entry_info(struct tcb *const tcp,
> +			   const kernel_ulong_t addr,
> +			   const unsigned int len,
> +			   const void *const opaque_data)
> +{
> +# ifdef HAVE_STRUCT_BR_MDB_ENTRY
> +	struct br_mdb_entry entry;
> +
> +	if (len < sizeof(entry))
> +		return false;
> +	else if (!umove_or_printaddr(tcp, addr, &entry)) {
> +		PRINT_FIELD_IFINDEX("{", entry, ifindex);
> +#  ifdef HAVE_STRUCT_BR_MDB_ENTRY_STATE
> +		PRINT_FIELD_XVAL(", ", entry, state, mdb_states, "MDB_???");
> +#  endif

struct br_mdb_entry.state was introduced in linux kernel along with
the structure itself between v3.7 and v3.8-rc1, there is no need
to check for HAVE_STRUCT_BR_MDB_ENTRY_STATE.

> +#  ifdef HAVE_STRUCT_BR_MDB_ENTRY_FLAGS
> +		PRINT_FIELD_FLAGS(", ", entry, flags,
> +				  mdb_flags, "MDB_FLAGS_???");
> +#  endif
> +#  ifdef HAVE_STRUCT_BR_MDB_ENTRY_VID
> +		PRINT_FIELD_U(", ", entry, vid);
> +#  endif

Fortunately, struct br_mdb_entry has the same size and offsets regardless
of these fields, otherwise this code wouldn't be correct.

> +
> +		const int proto = ntohs(entry.addr.proto);
> +		const char *const str = proto == AF_INET || proto == AF_INET6
> +					? (proto == AF_INET ? "ip4" : "ip6")
> +					: "u";

If you want to print this prefix, then the correct output would be
"u={ip4=...}" and "u={ip6=...}".  I think this level of details is
redundant because the protocol name is printed anyway.
Let's just print "u=..." regardless of the protocol.

> +
> +		tprints(", addr={");
> +		print_inet_addr(proto, &entry.addr.u,
> +				sizeof(entry.addr.u), str);
> +		tprints(", proto=htons(");
> +		printxval(addrfams, proto, "AF_???");
> +		tprints(")}}");
> +	}
> +
> +	const size_t offset = NLMSG_ALIGN(sizeof(entry));
> +	if (len > offset) {
> +		tprints(", ");
> +		decode_nlattr(tcp, addr + offset, len - offset,
> +			      rtnl_mdba_mdb_eattr_attrs, "MDBA_MDB_EATTR_???",
> +			      mdba_mdb_eattr_nla_decoders,
> +			      ARRAY_SIZE(mdba_mdb_eattr_nla_decoders), NULL);
> +	}
> +
> +	return true;
> +# else
> +	return false;
> +# endif /* HAVE_STRUCT_BR_MDB_ENTRY */
> +}
> +
> +static const nla_decoder_t mdba_mdb_entry_nla_decoders[] = {
> +	[MDBA_MDB_ENTRY_INFO]	= decode_mdba_mdb_entry_info
> +};
> +
> +static bool
> +decode_mdba_mdb_entry(struct tcb *const tcp,
> +		      const kernel_ulong_t addr,
> +		      const unsigned int len,
> +		      const void *const opaque_data)
> +{
> +	decode_nlattr(tcp, addr, len, rtnl_mdba_mdb_entry_attrs,
> +		      "MDBA_MDB_ENTRY_???", mdba_mdb_entry_nla_decoders,
> +		      ARRAY_SIZE(mdba_mdb_entry_nla_decoders), NULL);
> +
> +	return true;
> +}
> +
> +static const nla_decoder_t mdba_mdb_nla_decoders[] = {
> +	[MDBA_MDB_ENTRY]	= decode_mdba_mdb_entry
> +};
> +
> +static bool
> +decode_mdba_mdb(struct tcb *const tcp,
> +		const kernel_ulong_t addr,
> +		const unsigned int len,
> +		const void *const opaque_data)
> +{
> +	decode_nlattr(tcp, addr, len, rtnl_mdba_mdb_attrs, "MDBA_MDB_???",
> +		      mdba_mdb_nla_decoders,
> +		      ARRAY_SIZE(mdba_mdb_nla_decoders), NULL);
> +
> +	return true;
> +}
> +
> +static bool
> +decode_mdba_router_port(struct tcb *const tcp,
> +			const kernel_ulong_t addr,
> +			const unsigned int len,
> +			const void *const opaque_data)
> +{
> +	uint32_t ifindex;
> +
> +	if (len < sizeof(ifindex))
> +		return false;
> +	else if (!umove_or_printaddr(tcp, addr, &ifindex))
> +		print_ifindex(ifindex);
> +
> +	const size_t offset = NLMSG_ALIGN(sizeof(ifindex));
> +	if (len > offset) {
> +		tprints(", ");
> +		decode_nlattr(tcp, addr + offset, len - offset,
> +			      rtnl_mdba_mdb_eattr_attrs, "MDBA_MDB_EATTR_???",
> +			      mdba_mdb_eattr_nla_decoders,
> +			      ARRAY_SIZE(mdba_mdb_eattr_nla_decoders), NULL);

MDBA_MDB_EATTR_* are attributes of MDBA_MDB_ENTRY_INFO.
Atrributes of MDBA_ROUTER_PORT are MDBA_ROUTER_PATTR_*, they differ
from MDBA_MDB_EATTR_* slightly: while MDBA_MDB_EATTR_TIMER equals
to MDBA_ROUTER_PATTR_TIMER, MDBA_ROUTER_PATTR_TYPE has no matching
MDBA_MDB_EATTR_*.


-- 
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/20170912/478ed1b7/attachment.bin>


More information about the Strace-devel mailing list