summaryrefslogtreecommitdiff
path: root/src/rtnl_neightbl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rtnl_neightbl.c')
-rw-r--r--src/rtnl_neightbl.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/src/rtnl_neightbl.c b/src/rtnl_neightbl.c
new file mode 100644
index 000000000..46a279f58
--- /dev/null
+++ b/src/rtnl_neightbl.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
+ * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
+ * Copyright (c) 2016-2020 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "defs.h"
+#include "netlink_route.h"
+#include "nlattr.h"
+
+#include "types/rtnl_neightbl.h"
+
+#include "xlat/rtnl_neightbl_attrs.h"
+#include "xlat/rtnl_neightbl_parms_attrs.h"
+
+static bool
+decode_ndt_config(struct tcb *const tcp,
+ const kernel_ulong_t addr,
+ const unsigned int len,
+ const void *const opaque_data)
+{
+ struct_ndt_config ndtc;
+
+ if (len < sizeof(ndtc))
+ return false;
+ else if (!umove_or_printaddr(tcp, addr, &ndtc)) {
+ tprint_struct_begin();
+ PRINT_FIELD_U(ndtc, ndtc_key_len);
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtc, ndtc_entry_size);
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtc, ndtc_entries);
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtc, ndtc_last_flush);
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtc, ndtc_last_rand);
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtc, ndtc_hash_rnd);
+ tprint_struct_next();
+ PRINT_FIELD_0X(ndtc, ndtc_hash_mask);
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtc, ndtc_hash_chain_gc);
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtc, ndtc_proxy_qlen);
+ tprint_struct_end();
+ }
+
+ return true;
+}
+
+static const nla_decoder_t ndt_parms_nla_decoders[] = {
+ [NDTPA_IFINDEX] = decode_nla_ifindex,
+ [NDTPA_REFCNT] = decode_nla_u32,
+ [NDTPA_REACHABLE_TIME] = decode_nla_u64,
+ [NDTPA_BASE_REACHABLE_TIME] = decode_nla_u64,
+ [NDTPA_RETRANS_TIME] = decode_nla_u64,
+ [NDTPA_GC_STALETIME] = decode_nla_u64,
+ [NDTPA_DELAY_PROBE_TIME] = decode_nla_u64,
+ [NDTPA_QUEUE_LEN] = decode_nla_u32,
+ [NDTPA_APP_PROBES] = decode_nla_u32,
+ [NDTPA_UCAST_PROBES] = decode_nla_u32,
+ [NDTPA_MCAST_PROBES] = decode_nla_u32,
+ [NDTPA_ANYCAST_DELAY] = decode_nla_u64,
+ [NDTPA_PROXY_DELAY] = decode_nla_u64,
+ [NDTPA_PROXY_QLEN] = decode_nla_u32,
+ [NDTPA_LOCKTIME] = decode_nla_u64,
+ [NDTPA_QUEUE_LENBYTES] = decode_nla_u32,
+ [NDTPA_MCAST_REPROBES] = decode_nla_u32,
+ [NDTPA_PAD] = NULL
+};
+
+static bool
+decode_ndta_parms(struct tcb *const tcp,
+ const kernel_ulong_t addr,
+ const unsigned int len,
+ const void *const opaque_data)
+{
+ decode_nlattr(tcp, addr, len, rtnl_neightbl_parms_attrs, "NDTPA_???",
+ ndt_parms_nla_decoders,
+ ARRAY_SIZE(ndt_parms_nla_decoders), opaque_data);
+
+ return true;
+}
+
+static bool
+decode_ndt_stats(struct tcb *const tcp,
+ const kernel_ulong_t addr,
+ const unsigned int len,
+ const void *const opaque_data)
+{
+ struct_ndt_stats ndtst;
+ const unsigned int min_size =
+ offsetofend(struct ndt_stats, ndts_forced_gc_runs);
+ const unsigned int def_size = sizeof(ndtst);
+ const unsigned int size =
+ (len >= def_size) ? def_size :
+ ((len == min_size) ? min_size : 0);
+
+ if (!size)
+ return false;
+
+ if (!umoven_or_printaddr(tcp, addr, size, &ndtst)) {
+ tprint_struct_begin();
+ PRINT_FIELD_U(ndtst, ndts_allocs);
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtst, ndts_destroys);
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtst, ndts_hash_grows);
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtst, ndts_res_failed);
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtst, ndts_lookups);
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtst, ndts_hits);
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtst, ndts_rcv_probes_mcast);
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtst, ndts_rcv_probes_ucast);
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtst, ndts_periodic_gc_runs);
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtst, ndts_forced_gc_runs);
+ if (len >= def_size) {
+ tprint_struct_next();
+ PRINT_FIELD_U(ndtst, ndts_table_fulls);
+ }
+ tprint_struct_end();
+ }
+
+ return true;
+}
+
+static const nla_decoder_t ndtmsg_nla_decoders[] = {
+ [NDTA_NAME] = decode_nla_str,
+ [NDTA_THRESH1] = decode_nla_u32,
+ [NDTA_THRESH2] = decode_nla_u32,
+ [NDTA_THRESH3] = decode_nla_u32,
+ [NDTA_CONFIG] = decode_ndt_config,
+ [NDTA_PARMS] = decode_ndta_parms,
+ [NDTA_STATS] = decode_ndt_stats,
+ [NDTA_GC_INTERVAL] = decode_nla_u64,
+ [NDTA_PAD] = NULL,
+};
+
+DECL_NETLINK_ROUTE_DECODER(decode_ndtmsg)
+{
+ struct ndtmsg ndtmsg = { .ndtm_family = family };
+
+ tprint_struct_begin();
+ PRINT_FIELD_XVAL(ndtmsg, ndtm_family, addrfams, "AF_???");
+ tprint_struct_end();
+
+ const size_t offset = NLMSG_ALIGN(sizeof(ndtmsg));
+ if (len > offset) {
+ tprints(", ");
+ decode_nlattr(tcp, addr + offset, len - offset,
+ rtnl_neightbl_attrs, "NDTA_???",
+ ndtmsg_nla_decoders,
+ ARRAY_SIZE(ndtmsg_nla_decoders), NULL);
+ }
+}