summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Syromyatnikov <evgsyr@gmail.com>2022-07-29 12:47:59 +0200
committerDmitry V. Levin <ldv@strace.io>2022-07-31 21:03:01 +0000
commitca4e554480dfd99b7a3b5c905254376b8815682f (patch)
tree06c58b7314b010956ec76bb04a7b7ef8514c86fd
parent1e681af2c9951910917ddd673e839e7e774e2073 (diff)
downloadstrace-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--NEWS4
-rw-r--r--src/rtnl_neigh.c36
-rw-r--r--src/xlat/fdb_notify_flags.in2
-rw-r--r--src/xlat/rtnl_neigh_fdb_ext_attrs.in5
-rw-r--r--tests/nlattr_ndmsg.c59
5 files changed, 103 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index 58597e451..c4ecb52c2 100644
--- a/NEWS
+++ b/NEWS
@@ -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;
}