diff options
Diffstat (limited to 'include/linux/bpf.h')
| -rw-r--r-- | include/linux/bpf.h | 163 | 
1 files changed, 129 insertions, 34 deletions
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 8827e797ff97..33014ae73103 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -23,7 +23,7 @@ struct bpf_prog;  struct bpf_map;  struct sock;  struct seq_file; -struct btf; +struct btf_type;  /* map is generic key/value storage optionally accesible by eBPF programs */  struct bpf_map_ops { @@ -39,6 +39,9 @@ struct bpf_map_ops {  	void *(*map_lookup_elem)(struct bpf_map *map, void *key);  	int (*map_update_elem)(struct bpf_map *map, void *key, void *value, u64 flags);  	int (*map_delete_elem)(struct bpf_map *map, void *key); +	int (*map_push_elem)(struct bpf_map *map, void *value, u64 flags); +	int (*map_pop_elem)(struct bpf_map *map, void *value); +	int (*map_peek_elem)(struct bpf_map *map, void *value);  	/* funcs called by prog_array and perf_event_array map */  	void *(*map_fd_get_ptr)(struct bpf_map *map, struct file *map_file, @@ -48,8 +51,9 @@ struct bpf_map_ops {  	u32 (*map_fd_sys_lookup_elem)(void *ptr);  	void (*map_seq_show_elem)(struct bpf_map *map, void *key,  				  struct seq_file *m); -	int (*map_check_btf)(const struct bpf_map *map, const struct btf *btf, -			     u32 key_type_id, u32 value_type_id); +	int (*map_check_btf)(const struct bpf_map *map, +			     const struct btf_type *key_type, +			     const struct btf_type *value_type);  };  struct bpf_map { @@ -85,6 +89,7 @@ struct bpf_map {  	char name[BPF_OBJ_NAME_LEN];  }; +struct bpf_offload_dev;  struct bpf_offloaded_map;  struct bpf_map_dev_ops { @@ -117,9 +122,13 @@ static inline bool bpf_map_offload_neutral(const struct bpf_map *map)  static inline bool bpf_map_support_seq_show(const struct bpf_map *map)  { -	return map->ops->map_seq_show_elem && map->ops->map_check_btf; +	return map->btf && map->ops->map_seq_show_elem;  } +int map_check_no_btf(const struct bpf_map *map, +		     const struct btf_type *key_type, +		     const struct btf_type *value_type); +  extern const struct bpf_map_ops bpf_map_offload_ops;  /* function argument constraints */ @@ -132,6 +141,7 @@ enum bpf_arg_type {  	ARG_CONST_MAP_PTR,	/* const argument used as pointer to bpf_map */  	ARG_PTR_TO_MAP_KEY,	/* pointer to stack used as map key */  	ARG_PTR_TO_MAP_VALUE,	/* pointer to stack used as map value */ +	ARG_PTR_TO_UNINIT_MAP_VALUE,	/* pointer to valid memory used to store a map value */  	/* the following constraints used to prototype bpf_memcmp() and other  	 * functions that access data on eBPF program stack @@ -148,13 +158,16 @@ enum bpf_arg_type {  	ARG_PTR_TO_CTX,		/* pointer to context */  	ARG_ANYTHING,		/* any (initialized) argument is ok */ +	ARG_PTR_TO_SOCKET,	/* pointer to bpf_sock */  };  /* type of values returned from helper functions */  enum bpf_return_type {  	RET_INTEGER,			/* function returns integer */  	RET_VOID,			/* function doesn't return anything */ +	RET_PTR_TO_MAP_VALUE,		/* returns a pointer to map elem value */  	RET_PTR_TO_MAP_VALUE_OR_NULL,	/* returns a pointer to map elem value or NULL */ +	RET_PTR_TO_SOCKET_OR_NULL,	/* returns a pointer to a socket or NULL */  };  /* eBPF function prototype used by verifier to allow BPF_CALLs from eBPF programs @@ -205,6 +218,9 @@ enum bpf_reg_type {  	PTR_TO_PACKET_META,	 /* skb->data - meta_len */  	PTR_TO_PACKET,		 /* reg points to skb->data */  	PTR_TO_PACKET_END,	 /* skb->data + headlen */ +	PTR_TO_FLOW_KEYS,	 /* reg points to bpf_flow_keys */ +	PTR_TO_SOCKET,		 /* reg points to struct bpf_sock */ +	PTR_TO_SOCKET_OR_NULL,	 /* reg points to struct bpf_sock or NULL */  };  /* The information passed from prog-specific *_is_valid_access @@ -251,6 +267,7 @@ struct bpf_verifier_ops {  struct bpf_prog_offload_ops {  	int (*insn_hook)(struct bpf_verifier_env *env,  			 int insn_idx, int prev_insn_idx); +	int (*finalize)(struct bpf_verifier_env *env);  };  struct bpf_prog_offload { @@ -264,6 +281,14 @@ struct bpf_prog_offload {  	u32			jited_len;  }; +enum bpf_cgroup_storage_type { +	BPF_CGROUP_STORAGE_SHARED, +	BPF_CGROUP_STORAGE_PERCPU, +	__BPF_CGROUP_STORAGE_MAX +}; + +#define MAX_BPF_CGROUP_STORAGE_TYPE __BPF_CGROUP_STORAGE_MAX +  struct bpf_prog_aux {  	atomic_t refcnt;  	u32 used_map_cnt; @@ -281,6 +306,7 @@ struct bpf_prog_aux {  	struct bpf_prog *prog;  	struct user_struct *user;  	u64 load_time; /* ns since boottime */ +	struct bpf_map *cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE];  	char name[BPF_OBJ_NAME_LEN];  #ifdef CONFIG_SECURITY  	void *security; @@ -326,6 +352,11 @@ const struct bpf_func_proto *bpf_get_trace_printk_proto(void);  typedef unsigned long (*bpf_ctx_copy_t)(void *dst, const void *src,  					unsigned long off, unsigned long len); +typedef u32 (*bpf_convert_ctx_access_t)(enum bpf_access_type type, +					const struct bpf_insn *src, +					struct bpf_insn *dst, +					struct bpf_prog *prog, +					u32 *target_size);  u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size,  		     void *ctx, u64 ctx_size, bpf_ctx_copy_t ctx_copy); @@ -347,12 +378,17 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,   * The 'struct bpf_prog_array *' should only be replaced with xchg()   * since other cpus are walking the array of pointers in parallel.   */ +struct bpf_prog_array_item { +	struct bpf_prog *prog; +	struct bpf_cgroup_storage *cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE]; +}; +  struct bpf_prog_array {  	struct rcu_head rcu; -	struct bpf_prog *progs[0]; +	struct bpf_prog_array_item items[0];  }; -struct bpf_prog_array __rcu *bpf_prog_array_alloc(u32 prog_cnt, gfp_t flags); +struct bpf_prog_array *bpf_prog_array_alloc(u32 prog_cnt, gfp_t flags);  void bpf_prog_array_free(struct bpf_prog_array __rcu *progs);  int bpf_prog_array_length(struct bpf_prog_array __rcu *progs);  int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs, @@ -370,7 +406,8 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,  #define __BPF_PROG_RUN_ARRAY(array, ctx, func, check_non_null)	\  	({						\ -		struct bpf_prog **_prog, *__prog;	\ +		struct bpf_prog_array_item *_item;	\ +		struct bpf_prog *_prog;			\  		struct bpf_prog_array *_array;		\  		u32 _ret = 1;				\  		preempt_disable();			\ @@ -378,10 +415,11 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,  		_array = rcu_dereference(array);	\  		if (unlikely(check_non_null && !_array))\  			goto _out;			\ -		_prog = _array->progs;			\ -		while ((__prog = READ_ONCE(*_prog))) {	\ -			_ret &= func(__prog, ctx);	\ -			_prog++;			\ +		_item = &_array->items[0];		\ +		while ((_prog = READ_ONCE(_item->prog))) {		\ +			bpf_cgroup_storage_set(_item->cgroup_storage);	\ +			_ret &= func(_prog, ctx);	\ +			_item++;			\  		}					\  _out:							\  		rcu_read_unlock();			\ @@ -434,6 +472,8 @@ struct bpf_map * __must_check bpf_map_inc(struct bpf_map *map, bool uref);  void bpf_map_put_with_uref(struct bpf_map *map);  void bpf_map_put(struct bpf_map *map);  int bpf_map_precharge_memlock(u32 pages); +int bpf_map_charge_memlock(struct bpf_map *map, u32 pages); +void bpf_map_uncharge_memlock(struct bpf_map *map, u32 pages);  void *bpf_map_area_alloc(size_t size, int numa_node);  void bpf_map_area_free(void *base);  void bpf_map_init_from_attr(struct bpf_map *map, union bpf_attr *attr); @@ -512,6 +552,7 @@ static inline int bpf_map_attr_numa_node(const union bpf_attr *attr)  }  struct bpf_prog *bpf_prog_get_type_path(const char *name, enum bpf_prog_type type); +int array_map_alloc_check(union bpf_attr *attr);  #else /* !CONFIG_BPF_SYSCALL */  static inline struct bpf_prog *bpf_prog_get(u32 ufd) @@ -648,7 +689,15 @@ int bpf_map_offload_delete_elem(struct bpf_map *map, void *key);  int bpf_map_offload_get_next_key(struct bpf_map *map,  				 void *key, void *next_key); -bool bpf_offload_dev_match(struct bpf_prog *prog, struct bpf_map *map); +bool bpf_offload_prog_map_match(struct bpf_prog *prog, struct bpf_map *map); + +struct bpf_offload_dev *bpf_offload_dev_create(void); +void bpf_offload_dev_destroy(struct bpf_offload_dev *offdev); +int bpf_offload_dev_netdev_register(struct bpf_offload_dev *offdev, +				    struct net_device *netdev); +void bpf_offload_dev_netdev_unregister(struct bpf_offload_dev *offdev, +				       struct net_device *netdev); +bool bpf_offload_dev_match(struct bpf_prog *prog, struct net_device *netdev);  #if defined(CONFIG_NET) && defined(CONFIG_BPF_SYSCALL)  int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr); @@ -692,33 +741,18 @@ static inline void bpf_map_offload_map_free(struct bpf_map *map)  }  #endif /* CONFIG_NET && CONFIG_BPF_SYSCALL */ -#if defined(CONFIG_STREAM_PARSER) && defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_INET) -struct sock  *__sock_map_lookup_elem(struct bpf_map *map, u32 key); -struct sock  *__sock_hash_lookup_elem(struct bpf_map *map, void *key); -int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type); -int sockmap_get_from_fd(const union bpf_attr *attr, int type, -			struct bpf_prog *prog); +#if defined(CONFIG_BPF_STREAM_PARSER) +int sock_map_prog_update(struct bpf_map *map, struct bpf_prog *prog, u32 which); +int sock_map_get_from_fd(const union bpf_attr *attr, struct bpf_prog *prog);  #else -static inline struct sock  *__sock_map_lookup_elem(struct bpf_map *map, u32 key) -{ -	return NULL; -} - -static inline struct sock  *__sock_hash_lookup_elem(struct bpf_map *map, -						    void *key) -{ -	return NULL; -} - -static inline int sock_map_prog(struct bpf_map *map, -				struct bpf_prog *prog, -				u32 type) +static inline int sock_map_prog_update(struct bpf_map *map, +				       struct bpf_prog *prog, u32 which)  {  	return -EOPNOTSUPP;  } -static inline int sockmap_get_from_fd(const union bpf_attr *attr, int type, -				      struct bpf_prog *prog) +static inline int sock_map_get_from_fd(const union bpf_attr *attr, +				       struct bpf_prog *prog)  {  	return -EINVAL;  } @@ -749,10 +783,40 @@ static inline void __xsk_map_flush(struct bpf_map *map)  }  #endif +#if defined(CONFIG_INET) && defined(CONFIG_BPF_SYSCALL) +void bpf_sk_reuseport_detach(struct sock *sk); +int bpf_fd_reuseport_array_lookup_elem(struct bpf_map *map, void *key, +				       void *value); +int bpf_fd_reuseport_array_update_elem(struct bpf_map *map, void *key, +				       void *value, u64 map_flags); +#else +static inline void bpf_sk_reuseport_detach(struct sock *sk) +{ +} + +#ifdef CONFIG_BPF_SYSCALL +static inline int bpf_fd_reuseport_array_lookup_elem(struct bpf_map *map, +						     void *key, void *value) +{ +	return -EOPNOTSUPP; +} + +static inline int bpf_fd_reuseport_array_update_elem(struct bpf_map *map, +						     void *key, void *value, +						     u64 map_flags) +{ +	return -EOPNOTSUPP; +} +#endif /* CONFIG_BPF_SYSCALL */ +#endif /* defined(CONFIG_INET) && defined(CONFIG_BPF_SYSCALL) */ +  /* verifier prototypes for helper functions called from eBPF programs */  extern const struct bpf_func_proto bpf_map_lookup_elem_proto;  extern const struct bpf_func_proto bpf_map_update_elem_proto;  extern const struct bpf_func_proto bpf_map_delete_elem_proto; +extern const struct bpf_func_proto bpf_map_push_elem_proto; +extern const struct bpf_func_proto bpf_map_pop_elem_proto; +extern const struct bpf_func_proto bpf_map_peek_elem_proto;  extern const struct bpf_func_proto bpf_get_prandom_u32_proto;  extern const struct bpf_func_proto bpf_get_smp_processor_id_proto; @@ -767,9 +831,40 @@ extern const struct bpf_func_proto bpf_get_stack_proto;  extern const struct bpf_func_proto bpf_sock_map_update_proto;  extern const struct bpf_func_proto bpf_sock_hash_update_proto;  extern const struct bpf_func_proto bpf_get_current_cgroup_id_proto; +extern const struct bpf_func_proto bpf_msg_redirect_hash_proto; +extern const struct bpf_func_proto bpf_msg_redirect_map_proto; +extern const struct bpf_func_proto bpf_sk_redirect_hash_proto; +extern const struct bpf_func_proto bpf_sk_redirect_map_proto; + +extern const struct bpf_func_proto bpf_get_local_storage_proto;  /* Shared helpers among cBPF and eBPF. */  void bpf_user_rnd_init_once(void);  u64 bpf_user_rnd_u32(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5); +#if defined(CONFIG_NET) +bool bpf_sock_is_valid_access(int off, int size, enum bpf_access_type type, +			      struct bpf_insn_access_aux *info); +u32 bpf_sock_convert_ctx_access(enum bpf_access_type type, +				const struct bpf_insn *si, +				struct bpf_insn *insn_buf, +				struct bpf_prog *prog, +				u32 *target_size); +#else +static inline bool bpf_sock_is_valid_access(int off, int size, +					    enum bpf_access_type type, +					    struct bpf_insn_access_aux *info) +{ +	return false; +} +static inline u32 bpf_sock_convert_ctx_access(enum bpf_access_type type, +					      const struct bpf_insn *si, +					      struct bpf_insn *insn_buf, +					      struct bpf_prog *prog, +					      u32 *target_size) +{ +	return 0; +} +#endif +  #endif /* _LINUX_BPF_H */  | 
