bpf: Handle bpf_mprog_query with NULL entry
Improve consistency for bpf_mprog_query() API and let the latter also handle a NULL entry as can be the case for tcx. Instead of returning -ENOENT, we copy a count of 0 and revision of 1 to user space, so that this can be fed into a subsequent bpf_mprog_attach() call as expected_revision. A BPF self- test as part of this series has been added to assert this case. Suggested-by: Lorenz Bauer <lmb@isovalent.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/r/20231006220655.1653-2-daniel@iogearbox.net Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
This commit is contained in:
parent
a4fe78386a
commit
edfa9af0a7
|
@ -401,14 +401,16 @@ int bpf_mprog_query(const union bpf_attr *attr, union bpf_attr __user *uattr,
|
||||||
struct bpf_mprog_cp *cp;
|
struct bpf_mprog_cp *cp;
|
||||||
struct bpf_prog *prog;
|
struct bpf_prog *prog;
|
||||||
const u32 flags = 0;
|
const u32 flags = 0;
|
||||||
|
u32 id, count = 0;
|
||||||
|
u64 revision = 1;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
u32 id, count;
|
|
||||||
u64 revision;
|
|
||||||
|
|
||||||
if (attr->query.query_flags || attr->query.attach_flags)
|
if (attr->query.query_flags || attr->query.attach_flags)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
revision = bpf_mprog_revision(entry);
|
if (entry) {
|
||||||
count = bpf_mprog_total(entry);
|
revision = bpf_mprog_revision(entry);
|
||||||
|
count = bpf_mprog_total(entry);
|
||||||
|
}
|
||||||
if (copy_to_user(&uattr->query.attach_flags, &flags, sizeof(flags)))
|
if (copy_to_user(&uattr->query.attach_flags, &flags, sizeof(flags)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (copy_to_user(&uattr->query.revision, &revision, sizeof(revision)))
|
if (copy_to_user(&uattr->query.revision, &revision, sizeof(revision)))
|
||||||
|
|
|
@ -123,7 +123,6 @@ int tcx_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr)
|
||||||
{
|
{
|
||||||
bool ingress = attr->query.attach_type == BPF_TCX_INGRESS;
|
bool ingress = attr->query.attach_type == BPF_TCX_INGRESS;
|
||||||
struct net *net = current->nsproxy->net_ns;
|
struct net *net = current->nsproxy->net_ns;
|
||||||
struct bpf_mprog_entry *entry;
|
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -133,12 +132,7 @@ int tcx_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr)
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
entry = tcx_entry_fetch(dev, ingress);
|
ret = bpf_mprog_query(attr, uattr, tcx_entry_fetch(dev, ingress));
|
||||||
if (!entry) {
|
|
||||||
ret = -ENOENT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
ret = bpf_mprog_query(attr, uattr, entry);
|
|
||||||
out:
|
out:
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in New Issue