diff options
Diffstat (limited to 'src/rtnl_tc_action.c')
-rw-r--r-- | src/rtnl_tc_action.c | 73 |
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); } |