diff options
-rw-r--r-- | include/uapi/linux/rtnetlink.h | 4 | ||||
-rw-r--r-- | net/sched/act_api.c | 69 |
2 files changed, 41 insertions, 32 deletions
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h index fdd408f6a5d2..d1325ffb0060 100644 --- a/include/uapi/linux/rtnetlink.h +++ b/include/uapi/linux/rtnetlink.h @@ -770,8 +770,12 @@ enum { * actions in a dump. All dump responses will contain the number of actions * being dumped stored in for user app's consumption in TCA_ROOT_COUNT * + * TCA_FLAG_TERSE_DUMP user->kernel to request terse (brief) dump that only + * includes essential action info (kind, index, etc.) + * */ #define TCA_FLAG_LARGE_DUMP_ON (1 << 0) +#define TCA_FLAG_TERSE_DUMP (1 << 1) /* New extended info filters for IFLA_EXT_MASK */ #define RTEXT_FILTER_VF (1 << 0) diff --git a/net/sched/act_api.c b/net/sched/act_api.c index f66417d5d2c3..1341c59c2f40 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -215,6 +215,36 @@ static size_t tcf_action_fill_size(const struct tc_action *act) return sz; } +static int +tcf_action_dump_terse(struct sk_buff *skb, struct tc_action *a, bool from_act) +{ + unsigned char *b = skb_tail_pointer(skb); + struct tc_cookie *cookie; + + if (nla_put_string(skb, TCA_KIND, a->ops->kind)) + goto nla_put_failure; + if (tcf_action_copy_stats(skb, a, 0)) + goto nla_put_failure; + if (from_act && nla_put_u32(skb, TCA_ACT_INDEX, a->tcfa_index)) + goto nla_put_failure; + + rcu_read_lock(); + cookie = rcu_dereference(a->act_cookie); + if (cookie) { + if (nla_put(skb, TCA_ACT_COOKIE, cookie->len, cookie->data)) { + rcu_read_unlock(); + goto nla_put_failure; + } + } + rcu_read_unlock(); + + return 0; + +nla_put_failure: + nlmsg_trim(skb, b); + return -1; +} + static int tcf_dump_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb, struct netlink_callback *cb) { @@ -248,7 +278,9 @@ static int tcf_dump_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb, index--; goto nla_put_failure; } - err = tcf_action_dump_1(skb, p, 0, 0); + err = (act_flags & TCA_FLAG_TERSE_DUMP) ? + tcf_action_dump_terse(skb, p, true) : + tcf_action_dump_1(skb, p, 0, 0); if (err < 0) { index--; nlmsg_trim(skb, nest); @@ -752,34 +784,6 @@ tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref) return a->ops->dump(skb, a, bind, ref); } -static int -tcf_action_dump_terse(struct sk_buff *skb, struct tc_action *a) -{ - unsigned char *b = skb_tail_pointer(skb); - struct tc_cookie *cookie; - - if (nla_put_string(skb, TCA_KIND, a->ops->kind)) - goto nla_put_failure; - if (tcf_action_copy_stats(skb, a, 0)) - goto nla_put_failure; - - rcu_read_lock(); - cookie = rcu_dereference(a->act_cookie); - if (cookie) { - if (nla_put(skb, TCA_ACT_COOKIE, cookie->len, cookie->data)) { - rcu_read_unlock(); - goto nla_put_failure; - } - } - rcu_read_unlock(); - - return 0; - -nla_put_failure: - nlmsg_trim(skb, b); - return -1; -} - int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref) { @@ -787,7 +791,7 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref) unsigned char *b = skb_tail_pointer(skb); struct nlattr *nest; - if (tcf_action_dump_terse(skb, a)) + if (tcf_action_dump_terse(skb, a, false)) goto nla_put_failure; if (a->hw_stats != TCA_ACT_HW_STATS_ANY && @@ -832,7 +836,7 @@ int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[], nest = nla_nest_start_noflag(skb, i + 1); if (nest == NULL) goto nla_put_failure; - err = terse ? tcf_action_dump_terse(skb, a) : + err = terse ? tcf_action_dump_terse(skb, a, false) : tcf_action_dump_1(skb, a, bind, ref); if (err < 0) goto errout; @@ -1469,7 +1473,8 @@ static int tcf_action_add(struct net *net, struct nlattr *nla, } static const struct nla_policy tcaa_policy[TCA_ROOT_MAX + 1] = { - [TCA_ROOT_FLAGS] = NLA_POLICY_BITFIELD32(TCA_FLAG_LARGE_DUMP_ON), + [TCA_ROOT_FLAGS] = NLA_POLICY_BITFIELD32(TCA_FLAG_LARGE_DUMP_ON | + TCA_FLAG_TERSE_DUMP), [TCA_ROOT_TIME_DELTA] = { .type = NLA_U32 }, }; |