This adds the bpf prog type for fuse-bpf, and the associated structures. Signed-off-by: Daniel Rosenberg <drosen@xxxxxxxxxx> Signed-off-by: Paul Lawrence <paullawrence@xxxxxxxxxx> --- include/linux/bpf_fuse.h | 50 +++++++++++++++++++++++++++++++++++++++ include/linux/bpf_types.h | 4 ++++ include/uapi/linux/bpf.h | 31 ++++++++++++++++++++++++ include/uapi/linux/fuse.h | 13 +++++++++- 4 files changed, 97 insertions(+), 1 deletion(-) diff --git a/include/linux/bpf_fuse.h b/include/linux/bpf_fuse.h index 18e2ec5bf453..9d22205c9ae0 100644 --- a/include/linux/bpf_fuse.h +++ b/include/linux/bpf_fuse.h @@ -6,6 +6,56 @@ #ifndef _BPF_FUSE_H #define _BPF_FUSE_H +/* + * Fuse BPF Args + * + * Used to communicate with bpf programs to allow checking or altering certain values. + * The end_offset allows the bpf verifier to check boundaries statically. This reflects + * the ends of the buffer. size shows the length that was actually used. + * + * In order to write to the output args, you must use the pointer returned by + * bpf_fuse_get_writeable. + * + */ + +#define FUSE_MAX_ARGS_IN 3 +#define FUSE_MAX_ARGS_OUT 2 + +struct bpf_fuse_arg { + void *value; // Start of the buffer + void *end_offset; // End of the buffer + uint32_t size; // Used size of the buffer + uint32_t max_size; // Max permitted size, if buffer is resizable. Otherwise 0 + uint32_t flags; // Flags indicating buffer status +}; + +#define FUSE_BPF_FORCE (1 << 0) +#define FUSE_BPF_OUT_ARGVAR (1 << 6) + +struct bpf_fuse_args { + uint64_t nodeid; + uint32_t opcode; + uint32_t error_in; + uint32_t in_numargs; + uint32_t out_numargs; + uint32_t flags; + struct bpf_fuse_arg in_args[FUSE_MAX_ARGS_IN]; + struct bpf_fuse_arg out_args[FUSE_MAX_ARGS_OUT]; +}; + +/* These flags are used internally to track information about the fuse buffers. + * Fuse sets some of the flags in init. The helper functions sets others, depending on what + * was requested by the bpf program. + */ +// Flags set by FUSE +#define BPF_FUSE_IMMUTABLE (1 << 0) // Buffer may not be written to +#define BPF_FUSE_VARIABLE_SIZE (1 << 1) // Buffer length may be changed (growth requires alloc) +#define BPF_FUSE_MUST_ALLOCATE (1 << 2) // Buffer must be re allocated before allowing writes + +// Flags set by helper function +#define BPF_FUSE_MODIFIED (1 << 3) // The helper function allowed writes to the buffer +#define BPF_FUSE_ALLOCATED (1 << 4) // The helper function allocated the buffer + bool bpf_helper_changes_one_pkt_data(void *func); #endif /* _BPF_FUSE_H */ diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h index 2b9112b80171..80c7f7d69794 100644 --- a/include/linux/bpf_types.h +++ b/include/linux/bpf_types.h @@ -79,6 +79,10 @@ BPF_PROG_TYPE(BPF_PROG_TYPE_LSM, lsm, #endif BPF_PROG_TYPE(BPF_PROG_TYPE_SYSCALL, bpf_syscall, void *, void *) +#ifdef CONFIG_FUSE_BPF +BPF_PROG_TYPE(BPF_PROG_TYPE_FUSE, fuse, + struct __bpf_fuse_args, struct bpf_fuse_args) +#endif BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY, array_map_ops) BPF_MAP_TYPE(BPF_MAP_TYPE_PERCPU_ARRAY, percpu_array_map_ops) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 59a217ca2dfd..ac81763f002b 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -952,6 +952,7 @@ enum bpf_prog_type { BPF_PROG_TYPE_LSM, BPF_PROG_TYPE_SK_LOOKUP, BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */ + BPF_PROG_TYPE_FUSE, }; enum bpf_attach_type { @@ -6848,4 +6849,34 @@ struct bpf_core_relo { enum bpf_core_relo_kind kind; }; +struct __bpf_fuse_arg { + __u64 value; + __u64 end_offset; + __u32 size; + __u32 max_size; +}; + +struct __bpf_fuse_args { + __u64 nodeid; + __u32 opcode; + __u32 error_in; + __u32 in_numargs; + __u32 out_numargs; + __u32 flags; + struct __bpf_fuse_arg in_args[3]; + struct __bpf_fuse_arg out_args[2]; +}; + +/* Return Codes for Fuse BPF programs */ +#define BPF_FUSE_CONTINUE 0 +#define BPF_FUSE_USER 1 +#define BPF_FUSE_USER_PREFILTER 2 +#define BPF_FUSE_POSTFILTER 3 +#define BPF_FUSE_USER_POSTFILTER 4 + +/* Op Code Filter values for BPF Programs */ +#define FUSE_OPCODE_FILTER 0x0ffff +#define FUSE_PREFILTER 0x10000 +#define FUSE_POSTFILTER 0x20000 + #endif /* _UAPI__LINUX_BPF_H__ */ diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h index d6ccee961891..8c80c146e69b 100644 --- a/include/uapi/linux/fuse.h +++ b/include/uapi/linux/fuse.h @@ -572,6 +572,17 @@ struct fuse_entry_out { struct fuse_attr attr; }; +#define FUSE_ACTION_KEEP 0 +#define FUSE_ACTION_REMOVE 1 +#define FUSE_ACTION_REPLACE 2 + +struct fuse_entry_bpf_out { + uint64_t backing_action; + uint64_t backing_fd; + uint64_t bpf_action; + uint64_t bpf_fd; +}; + struct fuse_forget_in { uint64_t nlookup; }; @@ -870,7 +881,7 @@ struct fuse_in_header { uint32_t uid; uint32_t gid; uint32_t pid; - uint32_t padding; + uint32_t error_in; }; struct fuse_out_header { -- 2.37.3.998.g577e59143f-goog