@@ -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
18891897out_nlmsg_trim :
18901898nla_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
25062516static 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
25172527static 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 */
25782593static 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