Message ID | 20180208151039.11231-1-ivecera@redhat.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
Series | [net] net/sched: cls_u32: fix cls_u32 on filter replace | expand |
From: Ivan Vecera <ivecera@redhat.com> Date: Thu, 8 Feb 2018 16:10:39 +0100 > The following sequence is currently broken: > > # tc qdisc add dev foo ingress > # tc filter replace dev foo protocol all ingress \ > u32 match u8 0 0 action mirred egress mirror dev bar1 > # tc filter replace dev foo protocol all ingress \ > handle 800::800 pref 49152 \ > u32 match u8 0 0 action mirred egress mirror dev bar2 > Error: cls_u32: Key node flags do not match passed flags. > We have an error talking to the kernel, -1 > > The error comes from u32_change() when comparing new and > existing flags. The existing ones always contains one of > TCA_CLS_FLAGS_{,NOT}_IN_HW flag depending on offloading state. > These flags cannot be passed from userspace so the condition > (n->flags != flags) in u32_change() always fails. > > Fix the condition so the flags TCA_CLS_FLAGS_NOT_IN_HW and > TCA_CLS_FLAGS_IN_HW are not taken into account. > > Fixes: 24d3dc6d27ea ("net/sched: cls_u32: Reflect HW offload status") > Signed-off-by: Ivan Vecera <ivecera@redhat.com> Ugh, private kernel flags are always troublesome for this reason. Applied and queued up for -stable.
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 6311a548046b..c75e68e839c7 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -955,7 +955,8 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, return -EINVAL; } - if (n->flags != flags) { + if ((n->flags ^ flags) & + ~(TCA_CLS_FLAGS_IN_HW | TCA_CLS_FLAGS_NOT_IN_HW)) { NL_SET_ERR_MSG_MOD(extack, "Key node flags do not match passed flags"); return -EINVAL; }
The following sequence is currently broken: # tc qdisc add dev foo ingress # tc filter replace dev foo protocol all ingress \ u32 match u8 0 0 action mirred egress mirror dev bar1 # tc filter replace dev foo protocol all ingress \ handle 800::800 pref 49152 \ u32 match u8 0 0 action mirred egress mirror dev bar2 Error: cls_u32: Key node flags do not match passed flags. We have an error talking to the kernel, -1 The error comes from u32_change() when comparing new and existing flags. The existing ones always contains one of TCA_CLS_FLAGS_{,NOT}_IN_HW flag depending on offloading state. These flags cannot be passed from userspace so the condition (n->flags != flags) in u32_change() always fails. Fix the condition so the flags TCA_CLS_FLAGS_NOT_IN_HW and TCA_CLS_FLAGS_IN_HW are not taken into account. Fixes: 24d3dc6d27ea ("net/sched: cls_u32: Reflect HW offload status") Signed-off-by: Ivan Vecera <ivecera@redhat.com> --- net/sched/cls_u32.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)