@@ -185,6 +185,7 @@ static size_t tcf_action_shared_attrs_size(const struct tc_action *act)
185
185
return nla_total_size (0 ) /* action number nested */
186
186
+ nla_total_size (IFNAMSIZ ) /* TCA_ACT_KIND */
187
187
+ cookie_len /* TCA_ACT_COOKIE */
188
+ + nla_total_size (sizeof (struct nla_bitfield32 )) /* TCA_ACT_HW_STATS_TYPE */
188
189
+ nla_total_size (0 ) /* TCA_ACT_STATS nested */
189
190
+ nla_total_size (sizeof (struct nla_bitfield32 )) /* TCA_ACT_FLAGS */
190
191
/* TCA_STATS_BASIC */
@@ -788,6 +789,17 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
788
789
}
789
790
rcu_read_unlock ();
790
791
792
+ if (a -> hw_stats_type != TCA_ACT_HW_STATS_TYPE_ANY ) {
793
+ struct nla_bitfield32 hw_stats_type = {
794
+ a -> hw_stats_type ,
795
+ TCA_ACT_HW_STATS_TYPE_ANY ,
796
+ };
797
+
798
+ if (nla_put (skb , TCA_ACT_HW_STATS_TYPE , sizeof (hw_stats_type ),
799
+ & hw_stats_type ))
800
+ goto nla_put_failure ;
801
+ }
802
+
791
803
if (a -> tcfa_flags ) {
792
804
struct nla_bitfield32 flags = { a -> tcfa_flags ,
793
805
a -> tcfa_flags , };
@@ -854,7 +866,23 @@ static struct tc_cookie *nla_memdup_cookie(struct nlattr **tb)
854
866
return c ;
855
867
}
856
868
869
+ static u8 tcf_action_hw_stats_type_get (struct nlattr * hw_stats_type_attr )
870
+ {
871
+ struct nla_bitfield32 hw_stats_type_bf ;
872
+
873
+ /* If the user did not pass the attr, that means he does
874
+ * not care about the type. Return "any" in that case
875
+ * which is setting on all supported types.
876
+ */
877
+ if (!hw_stats_type_attr )
878
+ return TCA_ACT_HW_STATS_TYPE_ANY ;
879
+ hw_stats_type_bf = nla_get_bitfield32 (hw_stats_type_attr );
880
+ return hw_stats_type_bf .value ;
881
+ }
882
+
857
883
static const u32 tca_act_flags_allowed = TCA_ACT_FLAGS_NO_PERCPU_STATS ;
884
+ static const u32 tca_act_hw_stats_type_allowed = TCA_ACT_HW_STATS_TYPE_ANY ;
885
+
858
886
static const struct nla_policy tcf_action_policy [TCA_ACT_MAX + 1 ] = {
859
887
[TCA_ACT_KIND ] = { .type = NLA_STRING },
860
888
[TCA_ACT_INDEX ] = { .type = NLA_U32 },
@@ -863,6 +891,8 @@ static const struct nla_policy tcf_action_policy[TCA_ACT_MAX + 1] = {
863
891
[TCA_ACT_OPTIONS ] = { .type = NLA_NESTED },
864
892
[TCA_ACT_FLAGS ] = { .type = NLA_BITFIELD32 ,
865
893
.validation_data = & tca_act_flags_allowed },
894
+ [TCA_ACT_HW_STATS_TYPE ] = { .type = NLA_BITFIELD32 ,
895
+ .validation_data = & tca_act_hw_stats_type_allowed },
866
896
};
867
897
868
898
struct tc_action * tcf_action_init_1 (struct net * net , struct tcf_proto * tp ,
@@ -871,6 +901,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
871
901
bool rtnl_held ,
872
902
struct netlink_ext_ack * extack )
873
903
{
904
+ u8 hw_stats_type = TCA_ACT_HW_STATS_TYPE_ANY ;
874
905
struct nla_bitfield32 flags = { 0 , 0 };
875
906
struct tc_action * a ;
876
907
struct tc_action_ops * a_o ;
@@ -903,6 +934,8 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
903
934
goto err_out ;
904
935
}
905
936
}
937
+ hw_stats_type =
938
+ tcf_action_hw_stats_type_get (tb [TCA_ACT_HW_STATS_TYPE ]);
906
939
if (tb [TCA_ACT_FLAGS ])
907
940
flags = nla_get_bitfield32 (tb [TCA_ACT_FLAGS ]);
908
941
} else {
@@ -953,6 +986,9 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
953
986
if (!name && tb [TCA_ACT_COOKIE ])
954
987
tcf_set_action_cookie (& a -> act_cookie , cookie );
955
988
989
+ if (!name )
990
+ a -> hw_stats_type = hw_stats_type ;
991
+
956
992
/* module count goes up only when brand new policy is created
957
993
* if it exists and is only bound to in a_o->init() then
958
994
* ACT_P_CREATED is not returned (a zero is).
0 commit comments