Skip to content

Commit f8ab180

Browse files
w1ldptrdavem330
authored andcommitted
net: sched: introduce terse dump flag
Add new TCA_DUMP_FLAGS attribute and use it in cls API to request terse filter output from classifiers with TCA_DUMP_FLAGS_TERSE flag. This option is intended to be used to improve performance of TC filter dump when userland only needs to obtain stats and not the whole classifier/action data. Extend struct tcf_proto_ops with new terse_dump() callback that must be defined by supporting classifier implementations. Support of the options in specific classifiers and actions is implemented in following patches in the series. Signed-off-by: Vlad Buslov <[email protected]> Reviewed-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2e186a2 commit f8ab180

File tree

3 files changed

+41
-8
lines changed

3 files changed

+41
-8
lines changed

include/net/sch_generic.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,10 @@ struct tcf_proto_ops {
330330
int (*dump)(struct net*, struct tcf_proto*, void *,
331331
struct sk_buff *skb, struct tcmsg*,
332332
bool);
333+
int (*terse_dump)(struct net *net,
334+
struct tcf_proto *tp, void *fh,
335+
struct sk_buff *skb,
336+
struct tcmsg *t, bool rtnl_held);
333337
int (*tmplt_dump)(struct sk_buff *skb,
334338
struct net *net,
335339
void *tmplt_priv);

include/uapi/linux/rtnetlink.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,11 +609,17 @@ enum {
609609
TCA_HW_OFFLOAD,
610610
TCA_INGRESS_BLOCK,
611611
TCA_EGRESS_BLOCK,
612+
TCA_DUMP_FLAGS,
612613
__TCA_MAX
613614
};
614615

615616
#define TCA_MAX (__TCA_MAX - 1)
616617

618+
#define TCA_DUMP_FLAGS_TERSE (1 << 0) /* Means that in dump user gets only basic
619+
* data necessary to identify the objects
620+
* (handle, cookie, etc.) and stats.
621+
*/
622+
617623
#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
618624
#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
619625

net/sched/cls_api.c

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1851,7 +1851,7 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb,
18511851
struct tcf_proto *tp, struct tcf_block *block,
18521852
struct Qdisc *q, u32 parent, void *fh,
18531853
u32 portid, u32 seq, u16 flags, int event,
1854-
bool rtnl_held)
1854+
bool terse_dump, bool rtnl_held)
18551855
{
18561856
struct tcmsg *tcm;
18571857
struct nlmsghdr *nlh;
@@ -1878,6 +1878,14 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb,
18781878
goto nla_put_failure;
18791879
if (!fh) {
18801880
tcm->tcm_handle = 0;
1881+
} else if (terse_dump) {
1882+
if (tp->ops->terse_dump) {
1883+
if (tp->ops->terse_dump(net, tp, fh, skb, tcm,
1884+
rtnl_held) < 0)
1885+
goto nla_put_failure;
1886+
} else {
1887+
goto cls_op_not_supp;
1888+
}
18811889
} else {
18821890
if (tp->ops->dump &&
18831891
tp->ops->dump(net, tp, fh, skb, tcm, rtnl_held) < 0)
@@ -1888,6 +1896,7 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb,
18881896

18891897
out_nlmsg_trim:
18901898
nla_put_failure:
1899+
cls_op_not_supp:
18911900
nlmsg_trim(skb, b);
18921901
return -1;
18931902
}
@@ -1908,7 +1917,7 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb,
19081917

19091918
if (tcf_fill_node(net, skb, tp, block, q, parent, fh, portid,
19101919
n->nlmsg_seq, n->nlmsg_flags, event,
1911-
rtnl_held) <= 0) {
1920+
false, rtnl_held) <= 0) {
19121921
kfree_skb(skb);
19131922
return -EINVAL;
19141923
}
@@ -1940,7 +1949,7 @@ static int tfilter_del_notify(struct net *net, struct sk_buff *oskb,
19401949

19411950
if (tcf_fill_node(net, skb, tp, block, q, parent, fh, portid,
19421951
n->nlmsg_seq, n->nlmsg_flags, RTM_DELTFILTER,
1943-
rtnl_held) <= 0) {
1952+
false, rtnl_held) <= 0) {
19441953
NL_SET_ERR_MSG(extack, "Failed to build del event notification");
19451954
kfree_skb(skb);
19461955
return -EINVAL;
@@ -2501,6 +2510,7 @@ struct tcf_dump_args {
25012510
struct tcf_block *block;
25022511
struct Qdisc *q;
25032512
u32 parent;
2513+
bool terse_dump;
25042514
};
25052515

25062516
static int tcf_node_dump(struct tcf_proto *tp, void *n, struct tcf_walker *arg)
@@ -2511,12 +2521,12 @@ static int tcf_node_dump(struct tcf_proto *tp, void *n, struct tcf_walker *arg)
25112521
return tcf_fill_node(net, a->skb, tp, a->block, a->q, a->parent,
25122522
n, NETLINK_CB(a->cb->skb).portid,
25132523
a->cb->nlh->nlmsg_seq, NLM_F_MULTI,
2514-
RTM_NEWTFILTER, true);
2524+
RTM_NEWTFILTER, a->terse_dump, true);
25152525
}
25162526

25172527
static bool tcf_chain_dump(struct tcf_chain *chain, struct Qdisc *q, u32 parent,
25182528
struct sk_buff *skb, struct netlink_callback *cb,
2519-
long index_start, long *p_index)
2529+
long index_start, long *p_index, bool terse)
25202530
{
25212531
struct net *net = sock_net(skb->sk);
25222532
struct tcf_block *block = chain->block;
@@ -2545,7 +2555,7 @@ static bool tcf_chain_dump(struct tcf_chain *chain, struct Qdisc *q, u32 parent,
25452555
if (tcf_fill_node(net, skb, tp, block, q, parent, NULL,
25462556
NETLINK_CB(cb->skb).portid,
25472557
cb->nlh->nlmsg_seq, NLM_F_MULTI,
2548-
RTM_NEWTFILTER, true) <= 0)
2558+
RTM_NEWTFILTER, false, true) <= 0)
25492559
goto errout;
25502560
cb->args[1] = 1;
25512561
}
@@ -2561,6 +2571,7 @@ static bool tcf_chain_dump(struct tcf_chain *chain, struct Qdisc *q, u32 parent,
25612571
arg.w.skip = cb->args[1] - 1;
25622572
arg.w.count = 0;
25632573
arg.w.cookie = cb->args[2];
2574+
arg.terse_dump = terse;
25642575
tp->ops->walk(tp, &arg.w, true);
25652576
cb->args[2] = arg.w.cookie;
25662577
cb->args[1] = arg.w.count + 1;
@@ -2574,6 +2585,10 @@ static bool tcf_chain_dump(struct tcf_chain *chain, struct Qdisc *q, u32 parent,
25742585
return false;
25752586
}
25762587

2588+
static const struct nla_policy tcf_tfilter_dump_policy[TCA_MAX + 1] = {
2589+
[TCA_DUMP_FLAGS] = NLA_POLICY_BITFIELD32(TCA_DUMP_FLAGS_TERSE),
2590+
};
2591+
25772592
/* called with RTNL */
25782593
static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
25792594
{
@@ -2583,6 +2598,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
25832598
struct Qdisc *q = NULL;
25842599
struct tcf_block *block;
25852600
struct tcmsg *tcm = nlmsg_data(cb->nlh);
2601+
bool terse_dump = false;
25862602
long index_start;
25872603
long index;
25882604
u32 parent;
@@ -2592,10 +2608,17 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
25922608
return skb->len;
25932609

25942610
err = nlmsg_parse_deprecated(cb->nlh, sizeof(*tcm), tca, TCA_MAX,
2595-
NULL, cb->extack);
2611+
tcf_tfilter_dump_policy, cb->extack);
25962612
if (err)
25972613
return err;
25982614

2615+
if (tca[TCA_DUMP_FLAGS]) {
2616+
struct nla_bitfield32 flags =
2617+
nla_get_bitfield32(tca[TCA_DUMP_FLAGS]);
2618+
2619+
terse_dump = flags.value & TCA_DUMP_FLAGS_TERSE;
2620+
}
2621+
25992622
if (tcm->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK) {
26002623
block = tcf_block_refcnt_get(net, tcm->tcm_block_index);
26012624
if (!block)
@@ -2653,7 +2676,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
26532676
nla_get_u32(tca[TCA_CHAIN]) != chain->index)
26542677
continue;
26552678
if (!tcf_chain_dump(chain, q, parent, skb, cb,
2656-
index_start, &index)) {
2679+
index_start, &index, terse_dump)) {
26572680
tcf_chain_put(chain);
26582681
err = -EMSGSIZE;
26592682
break;

0 commit comments

Comments
 (0)