cls_bpf: reset class and reuse major in da
commit 3a461da1d03e7a857edfa6a002040d07e118c639 upstream. There are two issues with the current code. First one is that we need to set res->class to 0 in case we use non-default classid matching. This is important for the case where cls_bpf was initially set up with an optional binding to a default class with tcf_bind_filter(), where the underlying qdisc implements bind_tcf() that fills res->class and tests for it later on when doing the classification. Convention for these cases is that after tc_classify() was called, such qdiscs (atm, drr, qfq, cbq, hfsc, htb) first test class, and if 0, then they lookup based on classid. Second, there's a bug with da mode, where res->classid is only assigned a 16 bit minor, but it needs to expand to the full 32 bit major/minor combination instead, therefore we need to expand with the bound major. This is fine as classes belonging to a classful qdisc must share the same major. Fixes: 045efa82ff56 ("cls_bpf: introduce integrated actions") Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
7ac882670f
commit
832b5b7237
@ -107,8 +107,9 @@ static int cls_bpf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
|
||||
}
|
||||
|
||||
if (prog->exts_integrated) {
|
||||
res->class = prog->res.class;
|
||||
res->classid = qdisc_skb_cb(skb)->tc_classid;
|
||||
res->class = 0;
|
||||
res->classid = TC_H_MAJ(prog->res.classid) |
|
||||
qdisc_skb_cb(skb)->tc_classid;
|
||||
|
||||
ret = cls_bpf_exec_opcode(filter_res);
|
||||
if (ret == TC_ACT_UNSPEC)
|
||||
@ -118,10 +119,12 @@ static int cls_bpf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
|
||||
|
||||
if (filter_res == 0)
|
||||
continue;
|
||||
|
||||
*res = prog->res;
|
||||
if (filter_res != -1)
|
||||
if (filter_res != -1) {
|
||||
res->class = 0;
|
||||
res->classid = filter_res;
|
||||
} else {
|
||||
*res = prog->res;
|
||||
}
|
||||
|
||||
ret = tcf_exts_exec(skb, &prog->exts, res);
|
||||
if (ret < 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user