summaryrefslogtreecommitdiff
path: root/src/rtnl_tc_action.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rtnl_tc_action.c')
-rw-r--r--src/rtnl_tc_action.c73
1 files changed, 71 insertions, 2 deletions
diff --git a/src/rtnl_tc_action.c b/src/rtnl_tc_action.c
index 33e22d426..55f40f29d 100644
--- a/src/rtnl_tc_action.c
+++ b/src/rtnl_tc_action.c
@@ -18,6 +18,8 @@
#include "xlat/rtnl_tc_action_attrs.h"
#include "xlat/rtnl_tca_act_flags.h"
#include "xlat/rtnl_tca_act_hw_stats.h"
+#include "xlat/rtnl_tca_root_flags.h"
+#include "xlat/rtnl_tca_root_attrs.h"
static bool
@@ -48,7 +50,7 @@ decode_tca_act_hw_stats(struct tcb *const tcp,
return decode_nla_flags(tcp, addr, len, &opts);
}
-static const nla_decoder_t tcamsg_nla_decoders[] = {
+static const nla_decoder_t tca_act_nla_decoders[] = {
[TCA_ACT_KIND] = decode_nla_str,
[TCA_ACT_OPTIONS] = NULL, /* unimplemented */
[TCA_ACT_INDEX] = decode_nla_u32,
@@ -61,6 +63,73 @@ static const nla_decoder_t tcamsg_nla_decoders[] = {
[TCA_ACT_IN_HW_COUNT] = decode_nla_u32,
};
+static bool
+decode_tca_action(struct tcb *const tcp,
+ const kernel_ulong_t addr,
+ const unsigned int len,
+ const void *const opaque_data)
+{
+ decode_nlattr(tcp, addr, len, rtnl_tc_action_attrs, "TCA_ACT_???",
+ ARRSZ_PAIR(tca_act_nla_decoders), NULL);
+
+ return true;
+}
+
+static bool
+decode_tca_root_act_tab(struct tcb *const tcp,
+ const kernel_ulong_t addr,
+ const unsigned int len,
+ const void *const opaque_data)
+{
+ nla_decoder_t tca_action_decoder = &decode_tca_action;
+
+ /* TCA_ROOT_TAB (nee TCA_ACT_TAB) misuses nesting for array */
+ decode_nlattr(tcp, addr, len, NULL, NULL,
+ &tca_action_decoder, 0, NULL);
+
+ return true;
+}
+
+static bool
+decode_tca_root_act_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 = {
+ rtnl_tca_root_flags, "TCA_ACT_FLAG_???",
+ .size = 4,
+ };
+
+ return decode_nla_flags(tcp, addr, len, &opts);
+}
+
+static bool
+decode_tca_msecs(struct tcb *const tcp,
+ const kernel_ulong_t addr,
+ const unsigned int len,
+ const void *const opaque_data)
+{
+ uint64_t val;
+
+ if (len > sizeof(val))
+ return false;
+
+ if (!umoven_to_uint64_or_printaddr(tcp, addr, len, &val))
+ print_ticks(val, 1000, 3);
+
+ return true;
+}
+
+static const nla_decoder_t tcamsg_nla_decoders[] = {
+ [TCA_ROOT_UNSPEC] = NULL,
+ [TCA_ROOT_TAB] = decode_tca_root_act_tab,
+ [TCA_ROOT_FLAGS] = decode_tca_root_act_flags,
+ [TCA_ROOT_COUNT] = decode_nla_u32,
+ [TCA_ROOT_TIME_DELTA] = decode_tca_msecs,
+ [TCA_ROOT_EXT_WARN_MSG] = decode_nla_str,
+};
+
DECL_NETLINK_ROUTE_DECODER(decode_tcamsg)
{
struct tcamsg tca = { .tca_family = family };
@@ -73,7 +142,7 @@ DECL_NETLINK_ROUTE_DECODER(decode_tcamsg)
if (len > offset) {
tprint_array_next();
decode_nlattr(tcp, addr + offset, len - offset,
- rtnl_tc_action_attrs, "TCA_ACT_???",
+ rtnl_tca_root_attrs, "TCA_ROOT_???",
tcamsg_nla_decoders,
ARRAY_SIZE(tcamsg_nla_decoders), NULL);
}