|
@@ -241,7 +241,7 @@ static int cls_bpf_init(struct tcf_proto *tp)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static void cls_bpf_delete_prog(struct tcf_proto *tp, struct cls_bpf_prog *prog)
|
|
|
|
|
|
+static void __cls_bpf_delete_prog(struct cls_bpf_prog *prog)
|
|
{
|
|
{
|
|
tcf_exts_destroy(&prog->exts);
|
|
tcf_exts_destroy(&prog->exts);
|
|
|
|
|
|
@@ -255,22 +255,22 @@ static void cls_bpf_delete_prog(struct tcf_proto *tp, struct cls_bpf_prog *prog)
|
|
kfree(prog);
|
|
kfree(prog);
|
|
}
|
|
}
|
|
|
|
|
|
-static void __cls_bpf_delete_prog(struct rcu_head *rcu)
|
|
|
|
|
|
+static void cls_bpf_delete_prog_rcu(struct rcu_head *rcu)
|
|
{
|
|
{
|
|
- struct cls_bpf_prog *prog = container_of(rcu, struct cls_bpf_prog, rcu);
|
|
|
|
-
|
|
|
|
- cls_bpf_delete_prog(prog->tp, prog);
|
|
|
|
|
|
+ __cls_bpf_delete_prog(container_of(rcu, struct cls_bpf_prog, rcu));
|
|
}
|
|
}
|
|
|
|
|
|
-static int cls_bpf_delete(struct tcf_proto *tp, unsigned long arg)
|
|
|
|
|
|
+static void __cls_bpf_delete(struct tcf_proto *tp, struct cls_bpf_prog *prog)
|
|
{
|
|
{
|
|
- struct cls_bpf_prog *prog = (struct cls_bpf_prog *) arg;
|
|
|
|
-
|
|
|
|
cls_bpf_stop_offload(tp, prog);
|
|
cls_bpf_stop_offload(tp, prog);
|
|
list_del_rcu(&prog->link);
|
|
list_del_rcu(&prog->link);
|
|
tcf_unbind_filter(tp, &prog->res);
|
|
tcf_unbind_filter(tp, &prog->res);
|
|
- call_rcu(&prog->rcu, __cls_bpf_delete_prog);
|
|
|
|
|
|
+ call_rcu(&prog->rcu, cls_bpf_delete_prog_rcu);
|
|
|
|
+}
|
|
|
|
|
|
|
|
+static int cls_bpf_delete(struct tcf_proto *tp, unsigned long arg)
|
|
|
|
+{
|
|
|
|
+ __cls_bpf_delete(tp, (struct cls_bpf_prog *) arg);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -282,12 +282,8 @@ static bool cls_bpf_destroy(struct tcf_proto *tp, bool force)
|
|
if (!force && !list_empty(&head->plist))
|
|
if (!force && !list_empty(&head->plist))
|
|
return false;
|
|
return false;
|
|
|
|
|
|
- list_for_each_entry_safe(prog, tmp, &head->plist, link) {
|
|
|
|
- cls_bpf_stop_offload(tp, prog);
|
|
|
|
- list_del_rcu(&prog->link);
|
|
|
|
- tcf_unbind_filter(tp, &prog->res);
|
|
|
|
- call_rcu(&prog->rcu, __cls_bpf_delete_prog);
|
|
|
|
- }
|
|
|
|
|
|
+ list_for_each_entry_safe(prog, tmp, &head->plist, link)
|
|
|
|
+ __cls_bpf_delete(tp, prog);
|
|
|
|
|
|
kfree_rcu(head, rcu);
|
|
kfree_rcu(head, rcu);
|
|
return true;
|
|
return true;
|
|
@@ -511,14 +507,14 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
|
|
|
|
|
|
ret = cls_bpf_offload(tp, prog, oldprog);
|
|
ret = cls_bpf_offload(tp, prog, oldprog);
|
|
if (ret) {
|
|
if (ret) {
|
|
- cls_bpf_delete_prog(tp, prog);
|
|
|
|
|
|
+ __cls_bpf_delete_prog(prog);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
if (oldprog) {
|
|
if (oldprog) {
|
|
list_replace_rcu(&oldprog->link, &prog->link);
|
|
list_replace_rcu(&oldprog->link, &prog->link);
|
|
tcf_unbind_filter(tp, &oldprog->res);
|
|
tcf_unbind_filter(tp, &oldprog->res);
|
|
- call_rcu(&oldprog->rcu, __cls_bpf_delete_prog);
|
|
|
|
|
|
+ call_rcu(&oldprog->rcu, cls_bpf_delete_prog_rcu);
|
|
} else {
|
|
} else {
|
|
list_add_rcu(&prog->link, &head->plist);
|
|
list_add_rcu(&prog->link, &head->plist);
|
|
}
|
|
}
|
|
@@ -553,10 +549,18 @@ static int cls_bpf_dump_bpf_info(const struct cls_bpf_prog *prog,
|
|
static int cls_bpf_dump_ebpf_info(const struct cls_bpf_prog *prog,
|
|
static int cls_bpf_dump_ebpf_info(const struct cls_bpf_prog *prog,
|
|
struct sk_buff *skb)
|
|
struct sk_buff *skb)
|
|
{
|
|
{
|
|
|
|
+ struct nlattr *nla;
|
|
|
|
+
|
|
if (prog->bpf_name &&
|
|
if (prog->bpf_name &&
|
|
nla_put_string(skb, TCA_BPF_NAME, prog->bpf_name))
|
|
nla_put_string(skb, TCA_BPF_NAME, prog->bpf_name))
|
|
return -EMSGSIZE;
|
|
return -EMSGSIZE;
|
|
|
|
|
|
|
|
+ nla = nla_reserve(skb, TCA_BPF_DIGEST, sizeof(prog->filter->digest));
|
|
|
|
+ if (nla == NULL)
|
|
|
|
+ return -EMSGSIZE;
|
|
|
|
+
|
|
|
|
+ memcpy(nla_data(nla), prog->filter->digest, nla_len(nla));
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|