forked from Minki/linux
net_sched: fix tcm_parent in tc filter dump
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. Commitedf6711c98
("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:a10fa20101
("net: sched: propagate q and parent from caller down to tcf_fill_node") Fixes:edf6711c98
("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>
This commit is contained in:
parent
071a43e660
commit
a7df4870d7
@ -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;
|
||||
|
@ -2070,6 +2070,7 @@ replay:
|
||||
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) {
|
||||
@ -2612,12 +2613,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;
|
||||
@ -2633,6 +2632,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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user