sched, cls: check if we could overwrite actions when changing a filter
When actions are attached to a filter, they are a part of the filter itself, so when changing a filter we should allow to overwrite the actions inside as well. In my specific case, when I tried to _append_ a new action to an existing filter which already has an action, I got EEXIST since kernel refused to overwrite the existing one in kernel. This patch checks if we are changing the filter checking NLM_F_CREATE flag (Sigh, filters don't use NLM_F_REPLACE...) and then passes the boolean down to actions. This fixes the problem above. Cc: Jamal Hadi Salim <jhs@mojatatu.com> Cc: David S. Miller <davem@davemloft.net> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: Cong Wang <cwang@twopensource.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Šī revīzija ir iekļauta:

revīziju iesūtīja
David S. Miller

vecāks
4940b8cd1b
revīzija
2f7ef2f879
@@ -156,7 +156,7 @@ static void cls_bpf_put(struct tcf_proto *tp, unsigned long f)
|
||||
static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp,
|
||||
struct cls_bpf_prog *prog,
|
||||
unsigned long base, struct nlattr **tb,
|
||||
struct nlattr *est)
|
||||
struct nlattr *est, bool ovr)
|
||||
{
|
||||
struct sock_filter *bpf_ops, *bpf_old;
|
||||
struct tcf_exts exts;
|
||||
@@ -170,7 +170,7 @@ static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp,
|
||||
return -EINVAL;
|
||||
|
||||
tcf_exts_init(&exts, TCA_BPF_ACT, TCA_BPF_POLICE);
|
||||
ret = tcf_exts_validate(net, tp, tb, est, &exts);
|
||||
ret = tcf_exts_validate(net, tp, tb, est, &exts, ovr);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -242,7 +242,7 @@ static u32 cls_bpf_grab_new_handle(struct tcf_proto *tp,
|
||||
static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
|
||||
struct tcf_proto *tp, unsigned long base,
|
||||
u32 handle, struct nlattr **tca,
|
||||
unsigned long *arg)
|
||||
unsigned long *arg, bool ovr)
|
||||
{
|
||||
struct cls_bpf_head *head = tp->root;
|
||||
struct cls_bpf_prog *prog = (struct cls_bpf_prog *) *arg;
|
||||
@@ -260,7 +260,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
|
||||
if (handle && prog->handle != handle)
|
||||
return -EINVAL;
|
||||
return cls_bpf_modify_existing(net, tp, prog, base, tb,
|
||||
tca[TCA_RATE]);
|
||||
tca[TCA_RATE], ovr);
|
||||
}
|
||||
|
||||
prog = kzalloc(sizeof(*prog), GFP_KERNEL);
|
||||
@@ -277,7 +277,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
|
||||
goto errout;
|
||||
}
|
||||
|
||||
ret = cls_bpf_modify_existing(net, tp, prog, base, tb, tca[TCA_RATE]);
|
||||
ret = cls_bpf_modify_existing(net, tp, prog, base, tb, tca[TCA_RATE], ovr);
|
||||
if (ret < 0)
|
||||
goto errout;
|
||||
|
||||
|
Atsaukties uz šo jaunā problēmā
Block a user