lkml.org 
[lkml]   [2021]   [Dec]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v7 net-next 11/12] flow_offload: validate flags of filter and actions
    Date
    From: Baowen Zheng <baowen.zheng@corigine.com>

    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 <baowen.zheng@corigine.com>
    Signed-off-by: Louis Peens <louis.peens@corigine.com>
    Signed-off-by: Simon Horman <simon.horman@corigine.com>
    Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
    ---
    include/net/act_api.h | 2 +-
    include/net/pkt_cls.h | 3 +++
    net/sched/act_api.c | 18 +++++++++++++++---
    net/sched/cls_api.c | 18 ++++++++++++++----
    net/sched/cls_flower.c | 9 ++++++---
    net/sched/cls_matchall.c | 9 +++++----
    net/sched/cls_u32.c | 12 +++++++-----
    7 files changed, 51 insertions(+), 20 deletions(-)

    diff --git a/include/net/act_api.h b/include/net/act_api.h
    index 0f5f69deb3ce..3049cb69c025 100644
    --- a/include/net/act_api.h
    +++ b/include/net/act_api.h
    @@ -203,7 +203,7 @@ int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
    int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
    struct nlattr *est,
    struct tc_action *actions[], int init_res[], size_t *attr_size,
    - u32 flags, struct netlink_ext_ack *extack);
    + u32 flags, u32 fl_flags, struct netlink_ext_ack *extack);
    struct tc_action_ops *tc_action_load_ops(struct nlattr *nla, bool police,
    bool rtnl_held,
    struct netlink_ext_ack *extack);
    diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
    index 9021e29694c9..8a2f4579081c 100644
    --- a/include/net/pkt_cls.h
    +++ b/include/net/pkt_cls.h
    @@ -330,6 +330,9 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
    struct nlattr **tb, struct nlattr *rate_tlv,
    struct tcf_exts *exts, u32 flags,
    struct netlink_ext_ack *extack);
    +int tcf_exts_validate_ex(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
    + struct nlattr *rate_tlv, struct tcf_exts *exts,
    + u32 flags, u32 fl_flags, struct netlink_ext_ack *extack);
    void tcf_exts_destroy(struct tcf_exts *exts);
    void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src);
    int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts);
    diff --git a/net/sched/act_api.c b/net/sched/act_api.c
    index 0103e44e241f..91967f6a6c03 100644
    --- a/net/sched/act_api.c
    +++ b/net/sched/act_api.c
    @@ -1385,7 +1385,8 @@ static bool tc_act_bind(u32 flags)

    int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
    struct nlattr *est, struct tc_action *actions[],
    - int init_res[], size_t *attr_size, u32 flags,
    + int init_res[], size_t *attr_size,
    + u32 flags, u32 fl_flags,
    struct netlink_ext_ack *extack)
    {
    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,
    sz += tcf_action_fill_size(act);
    /* Start from index 0 */
    actions[i - 1] = act;
    - if (!tc_act_bind(flags)) {
    + if (tc_act_bind(flags)) {
    + bool skip_sw = tc_skip_sw(fl_flags);
    + bool skip_hw = tc_skip_hw(fl_flags);
    +
    + if (tc_act_bind(act->tcfa_flags))
    + continue;
    + if (skip_sw != tc_act_skip_sw(act->tcfa_flags) ||
    + skip_hw != tc_act_skip_hw(act->tcfa_flags)) {
    + err = -EINVAL;
    + goto err;
    + }
    + } else {
    err = tcf_action_offload_add(act, extack);
    if (tc_act_skip_sw(act->tcfa_flags) && err)
    goto err;
    @@ -1926,7 +1938,7 @@ static int tcf_action_add(struct net *net, struct nlattr *nla,

    for (loop = 0; loop < 10; loop++) {
    ret = tcf_action_init(net, NULL, nla, NULL, actions, init_res,
    - &attr_size, flags, extack);
    + &attr_size, flags, 0, extack);
    if (ret != -EAGAIN)
    break;
    }
    diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
    index 353e1eed48be..e3e26d358c7f 100644
    --- a/net/sched/cls_api.c
    +++ b/net/sched/cls_api.c
    @@ -3025,9 +3025,9 @@ void tcf_exts_destroy(struct tcf_exts *exts)
    }
    EXPORT_SYMBOL(tcf_exts_destroy);

    -int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
    - struct nlattr *rate_tlv, struct tcf_exts *exts,
    - u32 flags, struct netlink_ext_ack *extack)
    +int tcf_exts_validate_ex(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
    + struct nlattr *rate_tlv, struct tcf_exts *exts,
    + u32 flags, u32 fl_flags, struct netlink_ext_ack *extack)
    {
    #ifdef CONFIG_NET_CLS_ACT
    {
    @@ -3061,7 +3061,8 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
    flags |= TCA_ACT_FLAGS_BIND;
    err = tcf_action_init(net, tp, tb[exts->action],
    rate_tlv, exts->actions, init_res,
    - &attr_size, flags, extack);
    + &attr_size, flags, fl_flags,
    + extack);
    if (err < 0)
    return err;
    exts->nr_actions = err;
    @@ -3077,6 +3078,15 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,

    return 0;
    }
    +EXPORT_SYMBOL(tcf_exts_validate_ex);
    +
    +int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
    + struct nlattr *rate_tlv, struct tcf_exts *exts,
    + u32 flags, struct netlink_ext_ack *extack)
    +{
    + return tcf_exts_validate_ex(net, tp, tb, rate_tlv, exts,
    + flags, 0, extack);
    +}
    EXPORT_SYMBOL(tcf_exts_validate);

    void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src)
    diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
    index f4dad3be31c9..1e5caad4f7c8 100644
    --- a/net/sched/cls_flower.c
    +++ b/net/sched/cls_flower.c
    @@ -1917,12 +1917,14 @@ static int fl_set_parms(struct net *net, struct tcf_proto *tp,
    struct cls_fl_filter *f, struct fl_flow_mask *mask,
    unsigned long base, struct nlattr **tb,
    struct nlattr *est,
    - struct fl_flow_tmplt *tmplt, u32 flags,
    + struct fl_flow_tmplt *tmplt,
    + u32 flags, u32 fl_flags,
    struct netlink_ext_ack *extack)
    {
    int err;

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

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

    err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE],
    - tp->chain->tmplt_priv, flags, extack);
    + tp->chain->tmplt_priv, flags, fnew->flags,
    + extack);
    if (err)
    goto errout;

    diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c
    index 2d2702915cfa..13f7a9ecd89a 100644
    --- a/net/sched/cls_matchall.c
    +++ b/net/sched/cls_matchall.c
    @@ -163,12 +163,13 @@ static const struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = {
    static int mall_set_parms(struct net *net, struct tcf_proto *tp,
    struct cls_mall_head *head,
    unsigned long base, struct nlattr **tb,
    - struct nlattr *est, u32 flags,
    + struct nlattr *est, u32 flags, u32 fl_flags,
    struct netlink_ext_ack *extack)
    {
    int err;

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

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

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

    diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
    index 4272814487f0..cf5649292ee0 100644
    --- a/net/sched/cls_u32.c
    +++ b/net/sched/cls_u32.c
    @@ -709,12 +709,13 @@ static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = {
    static int u32_set_parms(struct net *net, struct tcf_proto *tp,
    unsigned long base,
    struct tc_u_knode *n, struct nlattr **tb,
    - struct nlattr *est, u32 flags,
    + struct nlattr *est, u32 flags, u32 fl_flags,
    struct netlink_ext_ack *extack)
    {
    int err;

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

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

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

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

    - err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], flags,
    - extack);
    + err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE],
    + flags, n->flags, extack);
    if (err == 0) {
    struct tc_u_knode __rcu **ins;
    struct tc_u_knode *pins;
    --
    2.20.1
    \
     
     \ /
      Last update: 2021-12-17 15:39    [W:2.917 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site