@@ -185,6 +185,7 @@ static size_t tcf_action_shared_attrs_size(const struct tc_action *act)
185185 return nla_total_size (0 ) /* action number nested */
186186 + nla_total_size (IFNAMSIZ ) /* TCA_ACT_KIND */
187187 + cookie_len /* TCA_ACT_COOKIE */
188+ + nla_total_size (sizeof (struct nla_bitfield32 )) /* TCA_ACT_HW_STATS_TYPE */
188189 + nla_total_size (0 ) /* TCA_ACT_STATS nested */
189190 + nla_total_size (sizeof (struct nla_bitfield32 )) /* TCA_ACT_FLAGS */
190191 /* TCA_STATS_BASIC */
@@ -788,6 +789,17 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
788789 }
789790 rcu_read_unlock ();
790791
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+
791803 if (a -> tcfa_flags ) {
792804 struct nla_bitfield32 flags = { a -> tcfa_flags ,
793805 a -> tcfa_flags , };
@@ -854,7 +866,23 @@ static struct tc_cookie *nla_memdup_cookie(struct nlattr **tb)
854866 return c ;
855867}
856868
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+
857883static 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+
858886static const struct nla_policy tcf_action_policy [TCA_ACT_MAX + 1 ] = {
859887 [TCA_ACT_KIND ] = { .type = NLA_STRING },
860888 [TCA_ACT_INDEX ] = { .type = NLA_U32 },
@@ -863,6 +891,8 @@ static const struct nla_policy tcf_action_policy[TCA_ACT_MAX + 1] = {
863891 [TCA_ACT_OPTIONS ] = { .type = NLA_NESTED },
864892 [TCA_ACT_FLAGS ] = { .type = NLA_BITFIELD32 ,
865893 .validation_data = & tca_act_flags_allowed },
894+ [TCA_ACT_HW_STATS_TYPE ] = { .type = NLA_BITFIELD32 ,
895+ .validation_data = & tca_act_hw_stats_type_allowed },
866896};
867897
868898struct 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,
871901 bool rtnl_held ,
872902 struct netlink_ext_ack * extack )
873903{
904+ u8 hw_stats_type = TCA_ACT_HW_STATS_TYPE_ANY ;
874905 struct nla_bitfield32 flags = { 0 , 0 };
875906 struct tc_action * a ;
876907 struct tc_action_ops * a_o ;
@@ -903,6 +934,8 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
903934 goto err_out ;
904935 }
905936 }
937+ hw_stats_type =
938+ tcf_action_hw_stats_type_get (tb [TCA_ACT_HW_STATS_TYPE ]);
906939 if (tb [TCA_ACT_FLAGS ])
907940 flags = nla_get_bitfield32 (tb [TCA_ACT_FLAGS ]);
908941 } else {
@@ -953,6 +986,9 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
953986 if (!name && tb [TCA_ACT_COOKIE ])
954987 tcf_set_action_cookie (& a -> act_cookie , cookie );
955988
989+ if (!name )
990+ a -> hw_stats_type = hw_stats_type ;
991+
956992 /* module count goes up only when brand new policy is created
957993 * if it exists and is only bound to in a_o->init() then
958994 * ACT_P_CREATED is not returned (a zero is).
0 commit comments