lkml.org 
[lkml]   [2020]   [May]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 014/147] net_sched: fix tcm_parent in tc filter dump
    Date
    From: Cong Wang <xiyou.wangcong@gmail.com>

    [ Upstream commit a7df4870d79b00742da6cc93ca2f336a71db77f7 ]

    When we tell kernel to dump filters from root (ffff:ffff),
    those filters on ingress (ffff:0000) are matched, but their
    true parents must be dumped as they are. However, kernel
    dumps just whatever we tell it, that is either ffff:ffff
    or ffff:0000:

    $ nl-cls-list --dev=dummy0 --parent=root
    cls basic dev dummy0 id none parent root prio 49152 protocol ip match-all
    cls basic dev dummy0 id :1 parent root prio 49152 protocol ip match-all
    $ nl-cls-list --dev=dummy0 --parent=ffff:
    cls basic dev dummy0 id none parent ffff: prio 49152 protocol ip match-all
    cls basic dev dummy0 id :1 parent ffff: prio 49152 protocol ip match-all

    This is confusing and misleading, more importantly this is
    a regression since 4.15, so the old behavior must be restored.

    And, when tc filters are installed on a tc class, the parent
    should be the classid, rather than the qdisc handle. Commit
    edf6711c9840 ("net: sched: remove classid and q fields from tcf_proto")
    removed the classid we save for filters, we can just restore
    this classid in tcf_block.

    Steps to reproduce this:
    ip li set dev dummy0 up
    tc qd add dev dummy0 ingress
    tc filter add dev dummy0 parent ffff: protocol arp basic action pass
    tc filter show dev dummy0 root

    Before this patch:
    filter protocol arp pref 49152 basic
    filter protocol arp pref 49152 basic handle 0x1
    action order 1: gact action pass
    random type none pass val 0
    index 1 ref 1 bind 1

    After this patch:
    filter parent ffff: protocol arp pref 49152 basic
    filter parent ffff: protocol arp pref 49152 basic handle 0x1
    action order 1: gact action pass
    random type none pass val 0
    index 1 ref 1 bind 1

    Fixes: a10fa20101ae ("net: sched: propagate q and parent from caller down to tcf_fill_node")
    Fixes: edf6711c9840 ("net: sched: remove classid and q fields from tcf_proto")
    Cc: Jamal Hadi Salim <jhs@mojatatu.com>
    Cc: Jiri Pirko <jiri@resnulli.us>
    Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
    Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    include/net/sch_generic.h | 1 +
    net/sched/cls_api.c | 8 ++++----
    2 files changed, 5 insertions(+), 4 deletions(-)

    diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
    index 9fb7cf1cdf36c..3d03756e10699 100644
    --- a/include/net/sch_generic.h
    +++ b/include/net/sch_generic.h
    @@ -407,6 +407,7 @@ struct tcf_block {
    struct mutex lock;
    struct list_head chain_list;
    u32 index; /* block index for shared blocks */
    + u32 classid; /* which class this block belongs to */
    refcount_t refcnt;
    struct net *net;
    struct Qdisc *q;
    diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
    index c2cdd0fc2e709..68c8fc6f535c7 100644
    --- a/net/sched/cls_api.c
    +++ b/net/sched/cls_api.c
    @@ -2005,6 +2005,7 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
    err = PTR_ERR(block);
    goto errout;
    }
    + block->classid = parent;

    chain_index = tca[TCA_CHAIN] ? nla_get_u32(tca[TCA_CHAIN]) : 0;
    if (chain_index > TC_ACT_EXT_VAL_MASK) {
    @@ -2547,12 +2548,10 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
    return skb->len;

    parent = tcm->tcm_parent;
    - if (!parent) {
    + if (!parent)
    q = dev->qdisc;
    - parent = q->handle;
    - } else {
    + else
    q = qdisc_lookup(dev, TC_H_MAJ(tcm->tcm_parent));
    - }
    if (!q)
    goto out;
    cops = q->ops->cl_ops;
    @@ -2568,6 +2567,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
    block = cops->tcf_block(q, cl, NULL);
    if (!block)
    goto out;
    + parent = block->classid;
    if (tcf_block_shared(block))
    q = NULL;
    }
    --
    2.20.1


    \
     
     \ /
      Last update: 2020-05-18 19:55    [W:4.059 / U:0.764 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site