Skip to content

Commit 695176b

Browse files
Cong Wangdavem330
authored andcommitted
net_sched: refactor TC action init API
TC action ->init() API has 10 parameters, it becomes harder to read. Some of them are just boolean and can be replaced by flags. Similarly for the internal API tcf_action_init() and tcf_exts_validate(). This patch converts them to flags and fold them into the upper 16 bits of "flags", whose lower 16 bits are still reserved for user-space. More specifically, the following kernel flags are introduced: TCA_ACT_FLAGS_POLICE replace 'name' in a few contexts, to distinguish whether it is compatible with policer. TCA_ACT_FLAGS_BIND replaces 'bind', to indicate whether this action is bound to a filter. TCA_ACT_FLAGS_REPLACE replaces 'ovr' in most contexts, means we are replacing an existing action. TCA_ACT_FLAGS_NO_RTNL replaces 'rtnl_held' but has the opposite meaning, because we still hold RTNL in most cases. The only user-space flag TCA_ACT_FLAGS_NO_PERCPU_STATS is untouched and still stored as before. I have tested this patch with tdc and I do not see any failure related to this patch. Tested-by: Vlad Buslov <vladbu@nvidia.com> Acked-by: Jamal Hadi Salim<jhs@mojatatu.com> Cc: Jiri Pirko <jiri@resnulli.us> Signed-off-by: Cong Wang <cong.wang@bytedance.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 451395f commit 695176b

37 files changed

+185
-169
lines changed

include/net/act_api.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ struct tc_action {
5858
#define TCA_ACT_HW_STATS_ANY (TCA_ACT_HW_STATS_IMMEDIATE | \
5959
TCA_ACT_HW_STATS_DELAYED)
6060

61+
/* Reserve 16 bits for user-space. See TCA_ACT_FLAGS_NO_PERCPU_STATS. */
62+
#define TCA_ACT_FLAGS_USER_BITS 16
63+
#define TCA_ACT_FLAGS_USER_MASK 0xffff
64+
#define TCA_ACT_FLAGS_POLICE (1U << TCA_ACT_FLAGS_USER_BITS)
65+
#define TCA_ACT_FLAGS_BIND (1U << (TCA_ACT_FLAGS_USER_BITS + 1))
66+
#define TCA_ACT_FLAGS_REPLACE (1U << (TCA_ACT_FLAGS_USER_BITS + 2))
67+
#define TCA_ACT_FLAGS_NO_RTNL (1U << (TCA_ACT_FLAGS_USER_BITS + 3))
68+
6169
/* Update lastuse only if needed, to avoid dirtying a cache line.
6270
* We use a temp variable to avoid fetching jiffies twice.
6371
*/
@@ -99,8 +107,8 @@ struct tc_action_ops {
99107
void (*cleanup)(struct tc_action *);
100108
int (*lookup)(struct net *net, struct tc_action **a, u32 index);
101109
int (*init)(struct net *net, struct nlattr *nla,
102-
struct nlattr *est, struct tc_action **act, int ovr,
103-
int bind, bool rtnl_held, struct tcf_proto *tp,
110+
struct nlattr *est, struct tc_action **act,
111+
struct tcf_proto *tp,
104112
u32 flags, struct netlink_ext_ack *extack);
105113
int (*walk)(struct net *, struct sk_buff *,
106114
struct netlink_callback *, int,
@@ -179,18 +187,16 @@ int tcf_action_destroy(struct tc_action *actions[], int bind);
179187
int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
180188
int nr_actions, struct tcf_result *res);
181189
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
182-
struct nlattr *est, char *name, int ovr, int bind,
190+
struct nlattr *est,
183191
struct tc_action *actions[], int init_res[], size_t *attr_size,
184-
bool rtnl_held, struct netlink_ext_ack *extack);
185-
struct tc_action_ops *tc_action_load_ops(char *name, struct nlattr *nla,
192+
u32 flags, struct netlink_ext_ack *extack);
193+
struct tc_action_ops *tc_action_load_ops(struct nlattr *nla, bool police,
186194
bool rtnl_held,
187195
struct netlink_ext_ack *extack);
188196
struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
189197
struct nlattr *nla, struct nlattr *est,
190-
char *name, int ovr, int bind,
191198
struct tc_action_ops *a_o, int *init_res,
192-
bool rtnl_held,
193-
struct netlink_ext_ack *extack);
199+
u32 flags, struct netlink_ext_ack *extack);
194200
int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[], int bind,
195201
int ref, bool terse);
196202
int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);

include/net/pkt_cls.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
319319

320320
int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
321321
struct nlattr **tb, struct nlattr *rate_tlv,
322-
struct tcf_exts *exts, bool ovr, bool rtnl_held,
322+
struct tcf_exts *exts, u32 flags,
323323
struct netlink_ext_ack *extack);
324324
void tcf_exts_destroy(struct tcf_exts *exts);
325325
void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src);

include/net/sch_generic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ struct tcf_proto_ops {
357357
int (*change)(struct net *net, struct sk_buff *,
358358
struct tcf_proto*, unsigned long,
359359
u32 handle, struct nlattr **,
360-
void **, bool, bool,
360+
void **, u32,
361361
struct netlink_ext_ack *);
362362
int (*delete)(struct tcf_proto *tp, void *arg,
363363
bool *last, bool rtnl_held,

include/uapi/linux/pkt_cls.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ enum {
2222
__TCA_ACT_MAX
2323
};
2424

25+
/* See other TCA_ACT_FLAGS_ * flags in include/net/act_api.h. */
2526
#define TCA_ACT_FLAGS_NO_PERCPU_STATS 1 /* Don't use percpu allocator for
2627
* actions stats.
2728
*/

net/sched/act_api.c

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
495495
p->tcfa_tm.install = jiffies;
496496
p->tcfa_tm.lastuse = jiffies;
497497
p->tcfa_tm.firstuse = 0;
498-
p->tcfa_flags = flags;
498+
p->tcfa_flags = flags & TCA_ACT_FLAGS_USER_MASK;
499499
if (est) {
500500
err = gen_new_estimator(&p->tcfa_bstats, p->cpu_bstats,
501501
&p->tcfa_rate_est,
@@ -941,7 +941,7 @@ void tcf_idr_insert_many(struct tc_action *actions[])
941941
}
942942
}
943943

944-
struct tc_action_ops *tc_action_load_ops(char *name, struct nlattr *nla,
944+
struct tc_action_ops *tc_action_load_ops(struct nlattr *nla, bool police,
945945
bool rtnl_held,
946946
struct netlink_ext_ack *extack)
947947
{
@@ -951,7 +951,7 @@ struct tc_action_ops *tc_action_load_ops(char *name, struct nlattr *nla,
951951
struct nlattr *kind;
952952
int err;
953953

954-
if (name == NULL) {
954+
if (!police) {
955955
err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX, nla,
956956
tcf_action_policy, extack);
957957
if (err < 0)
@@ -967,7 +967,7 @@ struct tc_action_ops *tc_action_load_ops(char *name, struct nlattr *nla,
967967
return ERR_PTR(err);
968968
}
969969
} else {
970-
if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ) {
970+
if (strlcpy(act_name, "police", IFNAMSIZ) >= IFNAMSIZ) {
971971
NL_SET_ERR_MSG(extack, "TC action name too long");
972972
return ERR_PTR(-EINVAL);
973973
}
@@ -1004,20 +1004,19 @@ struct tc_action_ops *tc_action_load_ops(char *name, struct nlattr *nla,
10041004

10051005
struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
10061006
struct nlattr *nla, struct nlattr *est,
1007-
char *name, int ovr, int bind,
10081007
struct tc_action_ops *a_o, int *init_res,
1009-
bool rtnl_held,
1010-
struct netlink_ext_ack *extack)
1008+
u32 flags, struct netlink_ext_ack *extack)
10111009
{
1012-
struct nla_bitfield32 flags = { 0, 0 };
1010+
bool police = flags & TCA_ACT_FLAGS_POLICE;
1011+
struct nla_bitfield32 userflags = { 0, 0 };
10131012
u8 hw_stats = TCA_ACT_HW_STATS_ANY;
10141013
struct nlattr *tb[TCA_ACT_MAX + 1];
10151014
struct tc_cookie *cookie = NULL;
10161015
struct tc_action *a;
10171016
int err;
10181017

10191018
/* backward compatibility for policer */
1020-
if (name == NULL) {
1019+
if (!police) {
10211020
err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX, nla,
10221021
tcf_action_policy, extack);
10231022
if (err < 0)
@@ -1032,22 +1031,22 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
10321031
}
10331032
hw_stats = tcf_action_hw_stats_get(tb[TCA_ACT_HW_STATS]);
10341033
if (tb[TCA_ACT_FLAGS])
1035-
flags = nla_get_bitfield32(tb[TCA_ACT_FLAGS]);
1034+
userflags = nla_get_bitfield32(tb[TCA_ACT_FLAGS]);
10361035

1037-
err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, ovr, bind,
1038-
rtnl_held, tp, flags.value, extack);
1036+
err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, tp,
1037+
userflags.value | flags, extack);
10391038
} else {
1040-
err = a_o->init(net, nla, est, &a, ovr, bind, rtnl_held,
1041-
tp, flags.value, extack);
1039+
err = a_o->init(net, nla, est, &a, tp, userflags.value | flags,
1040+
extack);
10421041
}
10431042
if (err < 0)
10441043
goto err_out;
10451044
*init_res = err;
10461045

1047-
if (!name && tb[TCA_ACT_COOKIE])
1046+
if (!police && tb[TCA_ACT_COOKIE])
10481047
tcf_set_action_cookie(&a->act_cookie, cookie);
10491048

1050-
if (!name)
1049+
if (!police)
10511050
a->hw_stats = hw_stats;
10521051

10531052
return a;
@@ -1063,9 +1062,9 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
10631062
/* Returns numbers of initialized actions or negative error. */
10641063

10651064
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
1066-
struct nlattr *est, char *name, int ovr, int bind,
1067-
struct tc_action *actions[], int init_res[], size_t *attr_size,
1068-
bool rtnl_held, struct netlink_ext_ack *extack)
1065+
struct nlattr *est, struct tc_action *actions[],
1066+
int init_res[], size_t *attr_size, u32 flags,
1067+
struct netlink_ext_ack *extack)
10691068
{
10701069
struct tc_action_ops *ops[TCA_ACT_MAX_PRIO] = {};
10711070
struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
@@ -1082,7 +1081,9 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
10821081
for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
10831082
struct tc_action_ops *a_o;
10841083

1085-
a_o = tc_action_load_ops(name, tb[i], rtnl_held, extack);
1084+
a_o = tc_action_load_ops(tb[i], flags & TCA_ACT_FLAGS_POLICE,
1085+
!(flags & TCA_ACT_FLAGS_NO_RTNL),
1086+
extack);
10861087
if (IS_ERR(a_o)) {
10871088
err = PTR_ERR(a_o);
10881089
goto err_mod;
@@ -1091,9 +1092,8 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
10911092
}
10921093

10931094
for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
1094-
act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind,
1095-
ops[i - 1], &init_res[i - 1], rtnl_held,
1096-
extack);
1095+
act = tcf_action_init_1(net, tp, tb[i], est, ops[i - 1],
1096+
&init_res[i - 1], flags, extack);
10971097
if (IS_ERR(act)) {
10981098
err = PTR_ERR(act);
10991099
goto err;
@@ -1113,7 +1113,7 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
11131113
goto err_mod;
11141114

11151115
err:
1116-
tcf_action_destroy(actions, bind);
1116+
tcf_action_destroy(actions, flags & TCA_ACT_FLAGS_BIND);
11171117
err_mod:
11181118
for (i = 0; i < TCA_ACT_MAX_PRIO; i++) {
11191119
if (ops[i])
@@ -1495,7 +1495,7 @@ tcf_add_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
14951495
}
14961496

14971497
static int tcf_action_add(struct net *net, struct nlattr *nla,
1498-
struct nlmsghdr *n, u32 portid, int ovr,
1498+
struct nlmsghdr *n, u32 portid, u32 flags,
14991499
struct netlink_ext_ack *extack)
15001500
{
15011501
size_t attr_size = 0;
@@ -1504,8 +1504,8 @@ static int tcf_action_add(struct net *net, struct nlattr *nla,
15041504
int init_res[TCA_ACT_MAX_PRIO] = {};
15051505

15061506
for (loop = 0; loop < 10; loop++) {
1507-
ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0,
1508-
actions, init_res, &attr_size, true, extack);
1507+
ret = tcf_action_init(net, NULL, nla, NULL, actions, init_res,
1508+
&attr_size, flags, extack);
15091509
if (ret != -EAGAIN)
15101510
break;
15111511
}
@@ -1535,7 +1535,8 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
15351535
struct net *net = sock_net(skb->sk);
15361536
struct nlattr *tca[TCA_ROOT_MAX + 1];
15371537
u32 portid = NETLINK_CB(skb).portid;
1538-
int ret = 0, ovr = 0;
1538+
u32 flags = 0;
1539+
int ret = 0;
15391540

15401541
if ((n->nlmsg_type != RTM_GETACTION) &&
15411542
!netlink_capable(skb, CAP_NET_ADMIN))
@@ -1561,8 +1562,8 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
15611562
* is zero) then just set this
15621563
*/
15631564
if (n->nlmsg_flags & NLM_F_REPLACE)
1564-
ovr = 1;
1565-
ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, ovr,
1565+
flags = TCA_ACT_FLAGS_REPLACE;
1566+
ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, flags,
15661567
extack);
15671568
break;
15681569
case RTM_DELACTION:

net/sched/act_bpf.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,11 +275,11 @@ static void tcf_bpf_prog_fill_cfg(const struct tcf_bpf *prog,
275275

276276
static int tcf_bpf_init(struct net *net, struct nlattr *nla,
277277
struct nlattr *est, struct tc_action **act,
278-
int replace, int bind, bool rtnl_held,
279278
struct tcf_proto *tp, u32 flags,
280279
struct netlink_ext_ack *extack)
281280
{
282281
struct tc_action_net *tn = net_generic(net, bpf_net_id);
282+
bool bind = flags & TCA_ACT_FLAGS_BIND;
283283
struct nlattr *tb[TCA_ACT_BPF_MAX + 1];
284284
struct tcf_chain *goto_ch = NULL;
285285
struct tcf_bpf_cfg cfg, old;
@@ -317,7 +317,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
317317
if (bind)
318318
return 0;
319319

320-
if (!replace) {
320+
if (!(flags & TCA_ACT_FLAGS_REPLACE)) {
321321
tcf_idr_release(*act, bind);
322322
return -EEXIST;
323323
}

net/sched/act_connmark.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,12 @@ static const struct nla_policy connmark_policy[TCA_CONNMARK_MAX + 1] = {
9696

9797
static int tcf_connmark_init(struct net *net, struct nlattr *nla,
9898
struct nlattr *est, struct tc_action **a,
99-
int ovr, int bind, bool rtnl_held,
10099
struct tcf_proto *tp, u32 flags,
101100
struct netlink_ext_ack *extack)
102101
{
103102
struct tc_action_net *tn = net_generic(net, connmark_net_id);
104103
struct nlattr *tb[TCA_CONNMARK_MAX + 1];
104+
bool bind = flags & TCA_ACT_FLAGS_BIND;
105105
struct tcf_chain *goto_ch = NULL;
106106
struct tcf_connmark_info *ci;
107107
struct tc_connmark *parm;
@@ -144,7 +144,7 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
144144
ci = to_connmark(*a);
145145
if (bind)
146146
return 0;
147-
if (!ovr) {
147+
if (!(flags & TCA_ACT_FLAGS_REPLACE)) {
148148
tcf_idr_release(*a, bind);
149149
return -EEXIST;
150150
}

net/sched/act_csum.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,12 @@ static unsigned int csum_net_id;
4141
static struct tc_action_ops act_csum_ops;
4242

4343
static int tcf_csum_init(struct net *net, struct nlattr *nla,
44-
struct nlattr *est, struct tc_action **a, int ovr,
45-
int bind, bool rtnl_held, struct tcf_proto *tp,
44+
struct nlattr *est, struct tc_action **a,
45+
struct tcf_proto *tp,
4646
u32 flags, struct netlink_ext_ack *extack)
4747
{
4848
struct tc_action_net *tn = net_generic(net, csum_net_id);
49+
bool bind = flags & TCA_ACT_FLAGS_BIND;
4950
struct tcf_csum_params *params_new;
5051
struct nlattr *tb[TCA_CSUM_MAX + 1];
5152
struct tcf_chain *goto_ch = NULL;
@@ -78,7 +79,7 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla,
7879
} else if (err > 0) {
7980
if (bind)/* dont override defaults */
8081
return 0;
81-
if (!ovr) {
82+
if (!(flags & TCA_ACT_FLAGS_REPLACE)) {
8283
tcf_idr_release(*a, bind);
8384
return -EEXIST;
8485
}

net/sched/act_ct.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,11 +1235,11 @@ static int tcf_ct_fill_params(struct net *net,
12351235

12361236
static int tcf_ct_init(struct net *net, struct nlattr *nla,
12371237
struct nlattr *est, struct tc_action **a,
1238-
int replace, int bind, bool rtnl_held,
12391238
struct tcf_proto *tp, u32 flags,
12401239
struct netlink_ext_ack *extack)
12411240
{
12421241
struct tc_action_net *tn = net_generic(net, ct_net_id);
1242+
bool bind = flags & TCA_ACT_FLAGS_BIND;
12431243
struct tcf_ct_params *params = NULL;
12441244
struct nlattr *tb[TCA_CT_MAX + 1];
12451245
struct tcf_chain *goto_ch = NULL;
@@ -1279,7 +1279,7 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla,
12791279
if (bind)
12801280
return 0;
12811281

1282-
if (!replace) {
1282+
if (!(flags & TCA_ACT_FLAGS_REPLACE)) {
12831283
tcf_idr_release(*a, bind);
12841284
return -EEXIST;
12851285
}

net/sched/act_ctinfo.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,11 @@ static const struct nla_policy ctinfo_policy[TCA_CTINFO_MAX + 1] = {
154154

155155
static int tcf_ctinfo_init(struct net *net, struct nlattr *nla,
156156
struct nlattr *est, struct tc_action **a,
157-
int ovr, int bind, bool rtnl_held,
158157
struct tcf_proto *tp, u32 flags,
159158
struct netlink_ext_ack *extack)
160159
{
161160
struct tc_action_net *tn = net_generic(net, ctinfo_net_id);
161+
bool bind = flags & TCA_ACT_FLAGS_BIND;
162162
u32 dscpmask = 0, dscpstatemask, index;
163163
struct nlattr *tb[TCA_CTINFO_MAX + 1];
164164
struct tcf_ctinfo_params *cp_new;
@@ -221,7 +221,7 @@ static int tcf_ctinfo_init(struct net *net, struct nlattr *nla,
221221
} else if (err > 0) {
222222
if (bind) /* don't override defaults */
223223
return 0;
224-
if (!ovr) {
224+
if (!(flags & TCA_ACT_FLAGS_REPLACE)) {
225225
tcf_idr_release(*a, bind);
226226
return -EEXIST;
227227
}

0 commit comments

Comments
 (0)