Skip to content

Commit c86e020

Browse files
zhengbaowendavem330
authored andcommitted
flow_offload: validate flags of filter and actions
Add process to validate flags of filter and actions when adding a tc filter. We need to prevent adding filter with flags conflicts with its actions. Signed-off-by: Baowen Zheng <[email protected]> Signed-off-by: Louis Peens <[email protected]> Signed-off-by: Simon Horman <[email protected]> Acked-by: Jamal Hadi Salim <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 13926d1 commit c86e020

File tree

7 files changed

+51
-20
lines changed

7 files changed

+51
-20
lines changed

include/net/act_api.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
203203
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
204204
struct nlattr *est,
205205
struct tc_action *actions[], int init_res[], size_t *attr_size,
206-
u32 flags, struct netlink_ext_ack *extack);
206+
u32 flags, u32 fl_flags, struct netlink_ext_ack *extack);
207207
struct tc_action_ops *tc_action_load_ops(struct nlattr *nla, bool police,
208208
bool rtnl_held,
209209
struct netlink_ext_ack *extack);

include/net/pkt_cls.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,9 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
330330
struct nlattr **tb, struct nlattr *rate_tlv,
331331
struct tcf_exts *exts, u32 flags,
332332
struct netlink_ext_ack *extack);
333+
int tcf_exts_validate_ex(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
334+
struct nlattr *rate_tlv, struct tcf_exts *exts,
335+
u32 flags, u32 fl_flags, struct netlink_ext_ack *extack);
333336
void tcf_exts_destroy(struct tcf_exts *exts);
334337
void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src);
335338
int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts);

net/sched/act_api.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,7 +1385,8 @@ static bool tc_act_bind(u32 flags)
13851385

13861386
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
13871387
struct nlattr *est, struct tc_action *actions[],
1388-
int init_res[], size_t *attr_size, u32 flags,
1388+
int init_res[], size_t *attr_size,
1389+
u32 flags, u32 fl_flags,
13891390
struct netlink_ext_ack *extack)
13901391
{
13911392
struct tc_action_ops *ops[TCA_ACT_MAX_PRIO] = {};
@@ -1423,7 +1424,18 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
14231424
sz += tcf_action_fill_size(act);
14241425
/* Start from index 0 */
14251426
actions[i - 1] = act;
1426-
if (!tc_act_bind(flags)) {
1427+
if (tc_act_bind(flags)) {
1428+
bool skip_sw = tc_skip_sw(fl_flags);
1429+
bool skip_hw = tc_skip_hw(fl_flags);
1430+
1431+
if (tc_act_bind(act->tcfa_flags))
1432+
continue;
1433+
if (skip_sw != tc_act_skip_sw(act->tcfa_flags) ||
1434+
skip_hw != tc_act_skip_hw(act->tcfa_flags)) {
1435+
err = -EINVAL;
1436+
goto err;
1437+
}
1438+
} else {
14271439
err = tcf_action_offload_add(act, extack);
14281440
if (tc_act_skip_sw(act->tcfa_flags) && err)
14291441
goto err;
@@ -1926,7 +1938,7 @@ static int tcf_action_add(struct net *net, struct nlattr *nla,
19261938

19271939
for (loop = 0; loop < 10; loop++) {
19281940
ret = tcf_action_init(net, NULL, nla, NULL, actions, init_res,
1929-
&attr_size, flags, extack);
1941+
&attr_size, flags, 0, extack);
19301942
if (ret != -EAGAIN)
19311943
break;
19321944
}

net/sched/cls_api.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3025,9 +3025,9 @@ void tcf_exts_destroy(struct tcf_exts *exts)
30253025
}
30263026
EXPORT_SYMBOL(tcf_exts_destroy);
30273027

3028-
int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
3029-
struct nlattr *rate_tlv, struct tcf_exts *exts,
3030-
u32 flags, struct netlink_ext_ack *extack)
3028+
int tcf_exts_validate_ex(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
3029+
struct nlattr *rate_tlv, struct tcf_exts *exts,
3030+
u32 flags, u32 fl_flags, struct netlink_ext_ack *extack)
30313031
{
30323032
#ifdef CONFIG_NET_CLS_ACT
30333033
{
@@ -3061,7 +3061,8 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
30613061
flags |= TCA_ACT_FLAGS_BIND;
30623062
err = tcf_action_init(net, tp, tb[exts->action],
30633063
rate_tlv, exts->actions, init_res,
3064-
&attr_size, flags, extack);
3064+
&attr_size, flags, fl_flags,
3065+
extack);
30653066
if (err < 0)
30663067
return err;
30673068
exts->nr_actions = err;
@@ -3077,6 +3078,15 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
30773078

30783079
return 0;
30793080
}
3081+
EXPORT_SYMBOL(tcf_exts_validate_ex);
3082+
3083+
int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
3084+
struct nlattr *rate_tlv, struct tcf_exts *exts,
3085+
u32 flags, struct netlink_ext_ack *extack)
3086+
{
3087+
return tcf_exts_validate_ex(net, tp, tb, rate_tlv, exts,
3088+
flags, 0, extack);
3089+
}
30803090
EXPORT_SYMBOL(tcf_exts_validate);
30813091

30823092
void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src)

net/sched/cls_flower.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,12 +1917,14 @@ static int fl_set_parms(struct net *net, struct tcf_proto *tp,
19171917
struct cls_fl_filter *f, struct fl_flow_mask *mask,
19181918
unsigned long base, struct nlattr **tb,
19191919
struct nlattr *est,
1920-
struct fl_flow_tmplt *tmplt, u32 flags,
1920+
struct fl_flow_tmplt *tmplt,
1921+
u32 flags, u32 fl_flags,
19211922
struct netlink_ext_ack *extack)
19221923
{
19231924
int err;
19241925

1925-
err = tcf_exts_validate(net, tp, tb, est, &f->exts, flags, extack);
1926+
err = tcf_exts_validate_ex(net, tp, tb, est, &f->exts, flags,
1927+
fl_flags, extack);
19261928
if (err < 0)
19271929
return err;
19281930

@@ -2036,7 +2038,8 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
20362038
}
20372039

20382040
err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE],
2039-
tp->chain->tmplt_priv, flags, extack);
2041+
tp->chain->tmplt_priv, flags, fnew->flags,
2042+
extack);
20402043
if (err)
20412044
goto errout;
20422045

net/sched/cls_matchall.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,13 @@ static const struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = {
163163
static int mall_set_parms(struct net *net, struct tcf_proto *tp,
164164
struct cls_mall_head *head,
165165
unsigned long base, struct nlattr **tb,
166-
struct nlattr *est, u32 flags,
166+
struct nlattr *est, u32 flags, u32 fl_flags,
167167
struct netlink_ext_ack *extack)
168168
{
169169
int err;
170170

171-
err = tcf_exts_validate(net, tp, tb, est, &head->exts, flags, extack);
171+
err = tcf_exts_validate_ex(net, tp, tb, est, &head->exts, flags,
172+
fl_flags, extack);
172173
if (err < 0)
173174
return err;
174175

@@ -226,8 +227,8 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
226227
goto err_alloc_percpu;
227228
}
228229

229-
err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE], flags,
230-
extack);
230+
err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE],
231+
flags, new->flags, extack);
231232
if (err)
232233
goto err_set_parms;
233234

net/sched/cls_u32.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -709,12 +709,13 @@ static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = {
709709
static int u32_set_parms(struct net *net, struct tcf_proto *tp,
710710
unsigned long base,
711711
struct tc_u_knode *n, struct nlattr **tb,
712-
struct nlattr *est, u32 flags,
712+
struct nlattr *est, u32 flags, u32 fl_flags,
713713
struct netlink_ext_ack *extack)
714714
{
715715
int err;
716716

717-
err = tcf_exts_validate(net, tp, tb, est, &n->exts, flags, extack);
717+
err = tcf_exts_validate_ex(net, tp, tb, est, &n->exts, flags,
718+
fl_flags, extack);
718719
if (err < 0)
719720
return err;
720721

@@ -895,7 +896,8 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
895896
return -ENOMEM;
896897

897898
err = u32_set_parms(net, tp, base, new, tb,
898-
tca[TCA_RATE], flags, extack);
899+
tca[TCA_RATE], flags, new->flags,
900+
extack);
899901

900902
if (err) {
901903
u32_destroy_key(new, false);
@@ -1060,8 +1062,8 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
10601062
}
10611063
#endif
10621064

1063-
err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], flags,
1064-
extack);
1065+
err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE],
1066+
flags, n->flags, extack);
10651067
if (err == 0) {
10661068
struct tc_u_knode __rcu **ins;
10671069
struct tc_u_knode *pins;

0 commit comments

Comments
 (0)