kernel/bpf/mprog.c

Source file repositories/reference/linux-study-clean/kernel/bpf/mprog.c

File Facts

System
Linux kernel
Corpus path
kernel/bpf/mprog.c
Extension
.c
Size
11921 bytes
Lines
453
Domain
Core OS
Bucket
Scheduler, Processes, Timers, Sync, And Syscalls
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (tidx < 0) {
			ret = tidx;
			goto out;
		}
		idx = tidx;
	} else if (bpf_mprog_total(entry) == bpf_mprog_max()) {
		ret = -ERANGE;
		goto out;
	}
	if (flags & BPF_F_BEFORE) {
		tidx = bpf_mprog_pos_before(entry, &rtuple);
		if (tidx < -1 || (idx >= -1 && tidx != idx)) {
			ret = tidx < -1 ? tidx : -ERANGE;
			goto out;
		}
		idx = tidx;
	}
	if (flags & BPF_F_AFTER) {
		tidx = bpf_mprog_pos_after(entry, &rtuple);
		if (tidx < -1 || (idx >= -1 && tidx != idx)) {
			ret = tidx < 0 ? tidx : -ERANGE;
			goto out;
		}
		idx = tidx;
	}
	if (idx < -1) {
		if (rtuple.prog || flags) {
			ret = -EINVAL;
			goto out;
		}
		idx = bpf_mprog_total(entry);
		flags = BPF_F_AFTER;
	}
	if (idx >= bpf_mprog_max()) {
		ret = -ERANGE;
		goto out;
	}
	if (flags & BPF_F_REPLACE)
		ret = bpf_mprog_replace(entry, entry_new, &ntuple, idx);
	else
		ret = bpf_mprog_insert(entry, entry_new, &ntuple, idx, flags);
out:
	bpf_mprog_tuple_put(&rtuple);
	return ret;
}

static int bpf_mprog_fetch(struct bpf_mprog_entry *entry,
			   struct bpf_tuple *tuple, int idx)
{
	int total = bpf_mprog_total(entry);
	struct bpf_mprog_cp *cp;
	struct bpf_mprog_fp *fp;
	struct bpf_prog *prog;
	struct bpf_link *link;

	if (idx == -1)
		idx = 0;
	else if (idx == total)
		idx = total - 1;
	bpf_mprog_read(entry, idx, &fp, &cp);
	prog = READ_ONCE(fp->prog);
	link = cp->link;
	/* The deletion request can either be without filled tuple in which
	 * case it gets populated here based on idx, or with filled tuple
	 * where the only thing we end up doing is the WARN_ON_ONCE() assert.
	 * If we hit a BPF link at the given index, it must not be removed
	 * from opts path.
	 */
	if (link && !tuple->link)
		return -EBUSY;
	WARN_ON_ONCE(tuple->prog && tuple->prog != prog);
	WARN_ON_ONCE(tuple->link && tuple->link != link);
	tuple->prog = prog;
	tuple->link = link;
	return 0;
}

int bpf_mprog_detach(struct bpf_mprog_entry *entry,
		     struct bpf_mprog_entry **entry_new,
		     struct bpf_prog *prog, struct bpf_link *link,
		     u32 flags, u32 id_or_fd, u64 revision)
{
	struct bpf_tuple rtuple, dtuple = {
		.prog = prog,
		.link = link,
	};
	int ret, idx = -ERANGE, tidx;

	if (flags & BPF_F_REPLACE)
		return -EINVAL;

Annotation

Implementation Notes