| @@ -39,6 +39,7 @@ static const struct nla_policy rtm_nh_policy_new[] = { · 38 unmodified lines |
| 39 | [NHA_ENCAP] = { .type = NLA_NESTED }, | 39 | [NHA_ENCAP] = { .type = NLA_NESTED }, |
| 40 | [NHA_FDB] = { .type = NLA_FLAG }, | 40 | [NHA_FDB] = { .type = NLA_FLAG }, |
| 41 | [NHA_RES_GROUP] = { .type = NLA_NESTED }, | 41 | [NHA_RES_GROUP] = { .type = NLA_NESTED }, |
| | 42 | [NHA_HW_STATS_ENABLE] = NLA_POLICY_MAX(NLA_U32, true), |
| 42 | }; | 43 | }; |
| 43 | | 44 | |
| 44 | static const struct nla_policy rtm_nh_policy_get[] = { | 45 | static const struct nla_policy rtm_nh_policy_get[] = { |
| @@ -778,7 +779,8 @@ static int nla_put_nh_group(struct sk_buff *skb, struct nexthop *nh, · 733 unmodified lines |
| 778 | goto nla_put_failure; | 779 | goto nla_put_failure; |
| 779 | | 780 | |
| 780 | if (op_flags & NHA_OP_FLAG_DUMP_STATS && | 781 | if (op_flags & NHA_OP_FLAG_DUMP_STATS && |
| 781 | nla_put_nh_group_stats(skb, nh)) | 782 | (nla_put_u32(skb, NHA_HW_STATS_ENABLE, nhg->hw_stats) || |
| | 783 | nla_put_nh_group_stats(skb, nh))) |
| 782 | goto nla_put_failure; | 784 | goto nla_put_failure; |
| 783 | | 785 | |
| 784 | return 0; | 786 | return 0; |
| @@ -1202,6 +1204,7 @@ static int nh_check_attr_group(struct net *net, · 417 unmodified lines |
| 1202 | if (!tb[i]) | 1204 | if (!tb[i]) |
| 1203 | continue; | 1205 | continue; |
| 1204 | switch (i) { | 1206 | switch (i) { |
| | 1207 | case NHA_HW_STATS_ENABLE: |
| 1205 | case NHA_FDB: | 1208 | case NHA_FDB: |
| 1206 | continue; | 1209 | continue; |
| 1207 | case NHA_RES_GROUP: | 1210 | case NHA_RES_GROUP: |
| @@ -2622,6 +2625,9 @@ static struct nexthop *nexthop_create_group(struct net *net, · 1414 unmodified lines |
| 2622 | if (cfg->nh_fdb) | 2625 | if (cfg->nh_fdb) |
| 2623 | nhg->fdb_nh = 1; | 2626 | nhg->fdb_nh = 1; |
| 2624 | | 2627 | |
| | 2628 | if (cfg->nh_hw_stats) |
| | 2629 | nhg->hw_stats = true; |
| | 2630 | |
| 2625 | rcu_assign_pointer(nh->nh_grp, nhg); | 2631 | rcu_assign_pointer(nh->nh_grp, nhg); |
| 2626 | | 2632 | |
| 2627 | return nh; | 2633 | return nh; |
| @@ -2964,6 +2970,9 @@ static int rtm_to_nh_config(struct net *net, struct sk_buff *skb, · 336 unmodified lines |
| 2964 | err = rtm_to_nh_config_grp_res(tb[NHA_RES_GROUP], | 2970 | err = rtm_to_nh_config_grp_res(tb[NHA_RES_GROUP], |
| 2965 | cfg, extack); | 2971 | cfg, extack); |
| 2966 | | 2972 | |
| | 2973 | if (tb[NHA_HW_STATS_ENABLE]) |
| | 2974 | cfg->nh_hw_stats = nla_get_u32(tb[NHA_HW_STATS_ENABLE]); |
| | 2975 | |
| 2967 | /* no other attributes should be set */ | 2976 | /* no other attributes should be set */ |
| 2968 | goto out; | 2977 | goto out; |
| 2969 | } | 2978 | } |
| @@ -3055,6 +3064,10 @@ static int rtm_to_nh_config(struct net *net, struct sk_buff *skb, · 85 unmodified lines |
| 3055 | goto out; | 3064 | goto out; |
| 3056 | } | 3065 | } |
| 3057 | | 3066 | |
| | 3067 | if (tb[NHA_HW_STATS_ENABLE]) { |
| | 3068 | NL_SET_ERR_MSG(extack, "Cannot enable nexthop hardware statistics for non-group nexthops"); |
| | 3069 | goto out; |
| | 3070 | } |
| 3058 | | 3071 | |
| 3059 | err = 0; | 3072 | err = 0; |
| 3060 | out: | 3073 | out: |