linux/kernel/bpf/mprog.c

// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2023 Isovalent */

#include <linux/bpf.h>
#include <linux/bpf_mprog.h>

static int bpf_mprog_link(struct bpf_tuple *tuple,
			  u32 id_or_fd, u32 flags,
			  enum bpf_prog_type type)
{}

static int bpf_mprog_prog(struct bpf_tuple *tuple,
			  u32 id_or_fd, u32 flags,
			  enum bpf_prog_type type)
{}

static int bpf_mprog_tuple_relative(struct bpf_tuple *tuple,
				    u32 id_or_fd, u32 flags,
				    enum bpf_prog_type type)
{}

static void bpf_mprog_tuple_put(struct bpf_tuple *tuple)
{}

/* The bpf_mprog_{replace,delete}() operate on exact idx position with the
 * one exception that for deletion we support delete from front/back. In
 * case of front idx is -1, in case of back idx is bpf_mprog_total(entry).
 * Adjustment to first and last entry is trivial. The bpf_mprog_insert()
 * we have to deal with the following cases:
 *
 * idx + before:
 *
 * Insert P4 before P3: idx for old array is 1, idx for new array is 2,
 * hence we adjust target idx for the new array, so that memmove copies
 * P1 and P2 to the new entry, and we insert P4 into idx 2. Inserting
 * before P1 would have old idx -1 and new idx 0.
 *
 * +--+--+--+     +--+--+--+--+     +--+--+--+--+
 * |P1|P2|P3| ==> |P1|P2|  |P3| ==> |P1|P2|P4|P3|
 * +--+--+--+     +--+--+--+--+     +--+--+--+--+
 *
 * idx + after:
 *
 * Insert P4 after P2: idx for old array is 2, idx for new array is 2.
 * Again, memmove copies P1 and P2 to the new entry, and we insert P4
 * into idx 2. Inserting after P3 would have both old/new idx at 4 aka
 * bpf_mprog_total(entry).
 *
 * +--+--+--+     +--+--+--+--+     +--+--+--+--+
 * |P1|P2|P3| ==> |P1|P2|  |P3| ==> |P1|P2|P4|P3|
 * +--+--+--+     +--+--+--+--+     +--+--+--+--+
 */
static int bpf_mprog_replace(struct bpf_mprog_entry *entry,
			     struct bpf_mprog_entry **entry_new,
			     struct bpf_tuple *ntuple, int idx)
{}

static int bpf_mprog_insert(struct bpf_mprog_entry *entry,
			    struct bpf_mprog_entry **entry_new,
			    struct bpf_tuple *ntuple, int idx, u32 flags)
{}

static int bpf_mprog_delete(struct bpf_mprog_entry *entry,
			    struct bpf_mprog_entry **entry_new,
			    struct bpf_tuple *dtuple, int idx)
{}

/* In bpf_mprog_pos_*() we evaluate the target position for the BPF
 * program/link that needs to be replaced, inserted or deleted for
 * each "rule" independently. If all rules agree on that position
 * or existing element, then enact replacement, addition or deletion.
 * If this is not the case, then the request cannot be satisfied and
 * we bail out with an error.
 */
static int bpf_mprog_pos_exact(struct bpf_mprog_entry *entry,
			       struct bpf_tuple *tuple)
{}

static int bpf_mprog_pos_before(struct bpf_mprog_entry *entry,
				struct bpf_tuple *tuple)
{}

static int bpf_mprog_pos_after(struct bpf_mprog_entry *entry,
			       struct bpf_tuple *tuple)
{}

int bpf_mprog_attach(struct bpf_mprog_entry *entry,
		     struct bpf_mprog_entry **entry_new,
		     struct bpf_prog *prog_new, struct bpf_link *link,
		     struct bpf_prog *prog_old,
		     u32 flags, u32 id_or_fd, u64 revision)
{}

static int bpf_mprog_fetch(struct bpf_mprog_entry *entry,
			   struct bpf_tuple *tuple, int idx)
{}

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)
{}

int bpf_mprog_query(const union bpf_attr *attr, union bpf_attr __user *uattr,
		    struct bpf_mprog_entry *entry)
{}