diff options
author | Eugene Syromyatnikov <evgsyr@gmail.com> | 2022-07-29 12:47:59 +0200 |
---|---|---|
committer | Dmitry V. Levin <ldv@strace.io> | 2022-07-31 21:03:01 +0000 |
commit | ca4e554480dfd99b7a3b5c905254376b8815682f (patch) | |
tree | 06c58b7314b010956ec76bb04a7b7ef8514c86fd | |
parent | 1e681af2c9951910917ddd673e839e7e774e2073 (diff) | |
download | strace-ca4e554480dfd99b7a3b5c905254376b8815682f.tar.gz |
rtnl_neigh: implement NDA_FDB_EXT_ATTRS decoding
* src/xlat/fdb_notify_flags.in: New file.
* src/xlat/rtnl_neigh_fdb_ext_attrs.in: Likewise.
* src/rtnl_neigh.c: Include "xlat/fdb_notify_flags.h",
"xlat/rtnl_neigh_fdb_ext_attrs.h".
(decode_fdb_notify_flags, decode_nda_fdb_ext_attrs): New functions.
(nda_fdb_ext_attrs_nla_decoders): New decoder array.
(ndmsg_nla_decoders) <[NDA_FDB_EXT_ATTRS]>: New entry, calls
decode_nda_fdb_ext_attrs.
* tests/nlattr_ndmsg.c: Add checks.
* NEWS: Mention it.
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | src/rtnl_neigh.c | 36 | ||||
-rw-r--r-- | src/xlat/fdb_notify_flags.in | 2 | ||||
-rw-r--r-- | src/xlat/rtnl_neigh_fdb_ext_attrs.in | 5 | ||||
-rw-r--r-- | tests/nlattr_ndmsg.c | 59 |
5 files changed, 103 insertions, 3 deletions
@@ -8,8 +8,8 @@ Noteworthy changes in release ?.?? (????-??-??) * Improvements * Implemented printing of Unix socket sun_path field's SELinux context. - * Implemented decoding of IFLA_TSO_MAX_SIZE and IFLA_TSO_MAX_SEGS netlink - attributes. + * Implemented decoding of IFLA_TSO_MAX_SIZE, IFLA_TSO_MAX_SEGS, + and NDA_FDB_EXT_ATTRS netlink attributes. * Improved decoding of INET_DIAG_LOCALS, INET_DIAG_MD5SIG, INET_DIAG_PEERS, INET_DIAG_PROTOCOL, INET_DIAG_REQ_PROTOCOL, INET_DIAG_SHUTDOWN, INET_DIAG_SK_BPF_STORAGES, INET_DIAG_SOCKOPT, and INET_DIAG_ULP_INFO diff --git a/src/rtnl_neigh.c b/src/rtnl_neigh.c index aea1240bf..28dd1d59b 100644 --- a/src/rtnl_neigh.c +++ b/src/rtnl_neigh.c @@ -14,9 +14,11 @@ #include "netlink.h" #include <linux/neighbour.h> +#include "xlat/fdb_notify_flags.h" #include "xlat/neighbor_cache_entry_flags.h" #include "xlat/neighbor_cache_entry_states.h" #include "xlat/rtnl_neigh_attrs.h" +#include "xlat/rtnl_neigh_fdb_ext_attrs.h" static bool decode_neigh_addr(struct tcb *const tcp, @@ -56,6 +58,39 @@ decode_nda_cacheinfo(struct tcb *const tcp, return true; } +static bool +decode_fdb_notify_flags(struct tcb *const tcp, + const kernel_ulong_t addr, + const unsigned int len, + const void *const opaque_data) +{ + static const struct decode_nla_xlat_opts opts = { + fdb_notify_flags, "FDB_NOTIFY_???", + .size = 1, + }; + + return decode_nla_flags(tcp, addr, len, &opts); +} + +static const nla_decoder_t nda_fdb_ext_attrs_nla_decoders[] = { + [NFEA_UNSPEC] = NULL, + [NFEA_ACTIVITY_NOTIFY] = decode_fdb_notify_flags, + [NFEA_DONT_REFRESH] = NULL, /* flag attr, no payload is expected */ +}; + +static bool +decode_nda_fdb_ext_attrs(struct tcb *const tcp, + const kernel_ulong_t addr, + const unsigned int len, + const void *const opaque_data) +{ + decode_nlattr(tcp, addr, len, rtnl_neigh_fdb_ext_attrs, + "NFEA_???", ARRSZ_PAIR(nda_fdb_ext_attrs_nla_decoders), + opaque_data); + + return true; +} + static const nla_decoder_t ndmsg_nla_decoders[] = { [NDA_DST] = decode_neigh_addr, [NDA_LLADDR] = decode_nla_hwaddr_nofamily, @@ -70,6 +105,7 @@ static const nla_decoder_t ndmsg_nla_decoders[] = { [NDA_SRC_VNI] = NULL, [NDA_PROTOCOL] = decode_nla_u8, [NDA_NH_ID] = decode_nla_u32, + [NDA_FDB_EXT_ATTRS] = decode_nda_fdb_ext_attrs, }; DECL_NETLINK_ROUTE_DECODER(decode_ndmsg) diff --git a/src/xlat/fdb_notify_flags.in b/src/xlat/fdb_notify_flags.in new file mode 100644 index 000000000..b9181496d --- /dev/null +++ b/src/xlat/fdb_notify_flags.in @@ -0,0 +1,2 @@ +FDB_NOTIFY_BIT (1 << 0) +FDB_NOTIFY_INACTIVE_BIT (1 << 1) diff --git a/src/xlat/rtnl_neigh_fdb_ext_attrs.in b/src/xlat/rtnl_neigh_fdb_ext_attrs.in new file mode 100644 index 000000000..24b52286e --- /dev/null +++ b/src/xlat/rtnl_neigh_fdb_ext_attrs.in @@ -0,0 +1,5 @@ +#enum +#value_indexed +NFEA_UNSPEC 0 +NFEA_ACTIVITY_NOTIFY 1 +NFEA_DONT_REFRESH 2 diff --git a/tests/nlattr_ndmsg.c b/tests/nlattr_ndmsg.c index 77694c22e..85ec7c746 100644 --- a/tests/nlattr_ndmsg.c +++ b/tests/nlattr_ndmsg.c @@ -15,6 +15,8 @@ #include <linux/neighbour.h> #include <linux/rtnetlink.h> +static const unsigned int hdrlen = sizeof(struct ndmsg); + static void init_ndmsg(struct nlmsghdr *const nlh, const unsigned int msg_len) { @@ -46,13 +48,32 @@ print_ndmsg(const unsigned int msg_len) msg_len); } +static void +init_ndmsg_nfea(struct nlmsghdr *const nlh, const unsigned int msg_len) +{ + init_ndmsg(nlh, msg_len); + + struct nlattr *nla = NLMSG_ATTR(nlh, hdrlen); + SET_STRUCT(struct nlattr, nla, + .nla_len = msg_len - NLMSG_SPACE(hdrlen), + .nla_type = NDA_FDB_EXT_ATTRS, + ); +} + +static void +print_ndmsg_nfea(const unsigned int msg_len) +{ + print_ndmsg(msg_len); + printf(", [{nla_len=%u, nla_type=NDA_FDB_EXT_ATTRS}", + msg_len - NLMSG_SPACE(hdrlen)); +} + int main(void) { skip_if_unavailable("/proc/self/fd/"); const int fd = create_nl_socket(NETLINK_ROUTE); - const unsigned int hdrlen = sizeof(struct ndmsg); void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen), NLA_HDRLEN + sizeof(struct nda_cacheinfo)); @@ -110,6 +131,42 @@ main(void) for (unsigned int i = 0; i < sizeof(mac); ++i) printf("%s%02x", i ? ":" : "", mac[i])); + /* NDA_FDB_EXT_ATTRS: unknown, undecoded */ + static const struct strval16 nfea_unk_attrs[] = { + { ENUM_KNOWN(0, NFEA_UNSPEC) }, + { ENUM_KNOWN(0x2, NFEA_DONT_REFRESH) }, + { ARG_XLAT_UNKNOWN(0x3, "NFEA_???") }, + { ARG_XLAT_UNKNOWN(0x1ace, "NFEA_???") }, + }; + static const uint32_t dummy = BE_LE(0xbadc0ded, 0xed0ddcba); + + for (size_t i = 0; i < ARRAY_SIZE(nfea_unk_attrs); i++) { + TEST_NESTED_NLATTR_(fd, nlh0, hdrlen, + init_ndmsg_nfea, print_ndmsg_nfea, + nfea_unk_attrs[i].val, + nfea_unk_attrs[i].str, + sizeof(dummy), &dummy, sizeof(dummy), 1, + printf("\"\\xba\\xdc\\x0d\\xed\"")); + } + + /* NDA_FDB_EXT_ATTRS: NFEA_ACTIVITY_NOTIFY */ + static const struct strval8 fan_flags[] = { + { ARG_STR(0) }, + { ARG_XLAT_KNOWN(0x1, "FDB_NOTIFY_BIT") }, + { ARG_XLAT_KNOWN(0xef, "FDB_NOTIFY_BIT" + "|FDB_NOTIFY_INACTIVE_BIT|0xec") }, + { ARG_XLAT_UNKNOWN(0xfc, "FDB_NOTIFY_???") }, + }; + + for (size_t i = 0; i < ARRAY_SIZE(fan_flags); i++) { + TEST_NESTED_NLATTR_(fd, nlh0, hdrlen, + init_ndmsg_nfea, print_ndmsg_nfea, + NFEA_ACTIVITY_NOTIFY, + "NFEA_ACTIVITY_NOTIFY", + 1, &fan_flags[i].val, 1, 1, + printf("%s", fan_flags[i].str)); + } + puts("+++ exited with 0 +++"); return 0; } |