Skip to content

Commit ad9294d

Browse files
borkmanndavem330
authored andcommitted
bpf: fix cls_bpf on filter replace
Running the following sequence is currently broken: # tc qdisc add dev foo clsact # tc filter replace dev foo ingress prio 1 handle 1 bpf da obj bar.o # tc filter replace dev foo ingress prio 1 handle 1 bpf da obj bar.o RTNETLINK answers: Invalid argument The normal expectation on kernel side is that the second command succeeds replacing the existing program. However, what happens is in cls_bpf_change(), we bail out with err in the second run in cls_bpf_offload(). The EINVAL comes directly in cls_bpf_offload() when comparing prog vs oldprog's gen_flags. In case of above replace the new prog's gen_flags are 0, but the old ones are 8, which means TCA_CLS_FLAGS_NOT_IN_HW is set (e.g. drivers not having cls_bpf offload). Fix 102740b ("cls_bpf: fix offload assumptions after callback conversion") in the following way: gen_flags from user space passed down via netlink cannot include status flags like TCA_CLS_FLAGS_IN_HW or TCA_CLS_FLAGS_NOT_IN_HW as opposed to oldprog that we previously loaded. Therefore, it doesn't make any sense to include them in the gen_flags comparison with the new prog before we even attempt to offload. Thus, lets fix this before 4.15 goes out. Fixes: 102740b ("cls_bpf: fix offload assumptions after callback conversion") Signed-off-by: Daniel Borkmann <[email protected]> Acked-by: Jakub Kicinski <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5a71784 commit ad9294d

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

net/sched/cls_bpf.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,17 @@ static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog,
183183
return 0;
184184
}
185185

186+
static u32 cls_bpf_flags(u32 flags)
187+
{
188+
return flags & CLS_BPF_SUPPORTED_GEN_FLAGS;
189+
}
190+
186191
static int cls_bpf_offload(struct tcf_proto *tp, struct cls_bpf_prog *prog,
187192
struct cls_bpf_prog *oldprog)
188193
{
189-
if (prog && oldprog && prog->gen_flags != oldprog->gen_flags)
194+
if (prog && oldprog &&
195+
cls_bpf_flags(prog->gen_flags) !=
196+
cls_bpf_flags(oldprog->gen_flags))
190197
return -EINVAL;
191198

192199
if (prog && tc_skip_hw(prog->gen_flags))

0 commit comments

Comments
 (0)