mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	bpf: Refactor bpf_link update handling
Make bpf_link update support more generic by making it into another bpf_link_ops methods. This allows generic syscall handling code to be agnostic to various conditionally compiled features (e.g., the case of CONFIG_CGROUP_BPF). This also allows to keep link type-specific code to remain static within respective code base. Refactor existing bpf_cgroup_link code and take advantage of this. Signed-off-by: Andrii Nakryiko <andriin@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20200429001614.1544-2-andriin@fb.com
This commit is contained in:
		
							parent
							
								
									9b329d0dbe
								
							
						
					
					
						commit
						f9d041271c
					
				
					 5 changed files with 34 additions and 49 deletions
				
			
		| 
						 | 
				
			
			@ -100,8 +100,6 @@ int __cgroup_bpf_attach(struct cgroup *cgrp,
 | 
			
		|||
int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
 | 
			
		||||
			struct bpf_cgroup_link *link,
 | 
			
		||||
			enum bpf_attach_type type);
 | 
			
		||||
int __cgroup_bpf_replace(struct cgroup *cgrp, struct bpf_cgroup_link *link,
 | 
			
		||||
			 struct bpf_prog *new_prog);
 | 
			
		||||
int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
 | 
			
		||||
		       union bpf_attr __user *uattr);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -112,8 +110,6 @@ int cgroup_bpf_attach(struct cgroup *cgrp,
 | 
			
		|||
		      u32 flags);
 | 
			
		||||
int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
 | 
			
		||||
		      enum bpf_attach_type type);
 | 
			
		||||
int cgroup_bpf_replace(struct bpf_link *link, struct bpf_prog *old_prog,
 | 
			
		||||
		       struct bpf_prog *new_prog);
 | 
			
		||||
int cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
 | 
			
		||||
		     union bpf_attr __user *uattr);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -353,7 +349,6 @@ int cgroup_bpf_prog_query(const union bpf_attr *attr,
 | 
			
		|||
#else
 | 
			
		||||
 | 
			
		||||
struct bpf_prog;
 | 
			
		||||
struct bpf_link;
 | 
			
		||||
struct cgroup_bpf {};
 | 
			
		||||
static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; }
 | 
			
		||||
static inline void cgroup_bpf_offline(struct cgroup *cgrp) {}
 | 
			
		||||
| 
						 | 
				
			
			@ -377,13 +372,6 @@ static inline int cgroup_bpf_link_attach(const union bpf_attr *attr,
 | 
			
		|||
	return -EINVAL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int cgroup_bpf_replace(struct bpf_link *link,
 | 
			
		||||
				     struct bpf_prog *old_prog,
 | 
			
		||||
				     struct bpf_prog *new_prog)
 | 
			
		||||
{
 | 
			
		||||
	return -EINVAL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int cgroup_bpf_prog_query(const union bpf_attr *attr,
 | 
			
		||||
					union bpf_attr __user *uattr)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1093,7 +1093,8 @@ struct bpf_link {
 | 
			
		|||
struct bpf_link_ops {
 | 
			
		||||
	void (*release)(struct bpf_link *link);
 | 
			
		||||
	void (*dealloc)(struct bpf_link *link);
 | 
			
		||||
 | 
			
		||||
	int (*update_prog)(struct bpf_link *link, struct bpf_prog *new_prog,
 | 
			
		||||
			   struct bpf_prog *old_prog);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void bpf_link_init(struct bpf_link *link, const struct bpf_link_ops *ops,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -557,8 +557,9 @@ static void replace_effective_prog(struct cgroup *cgrp,
 | 
			
		|||
 *
 | 
			
		||||
 * Must be called with cgroup_mutex held.
 | 
			
		||||
 */
 | 
			
		||||
int __cgroup_bpf_replace(struct cgroup *cgrp, struct bpf_cgroup_link *link,
 | 
			
		||||
			 struct bpf_prog *new_prog)
 | 
			
		||||
static int __cgroup_bpf_replace(struct cgroup *cgrp,
 | 
			
		||||
				struct bpf_cgroup_link *link,
 | 
			
		||||
				struct bpf_prog *new_prog)
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *progs = &cgrp->bpf.progs[link->type];
 | 
			
		||||
	struct bpf_prog *old_prog;
 | 
			
		||||
| 
						 | 
				
			
			@ -583,6 +584,30 @@ int __cgroup_bpf_replace(struct cgroup *cgrp, struct bpf_cgroup_link *link,
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int cgroup_bpf_replace(struct bpf_link *link, struct bpf_prog *new_prog,
 | 
			
		||||
			      struct bpf_prog *old_prog)
 | 
			
		||||
{
 | 
			
		||||
	struct bpf_cgroup_link *cg_link;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	cg_link = container_of(link, struct bpf_cgroup_link, link);
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&cgroup_mutex);
 | 
			
		||||
	/* link might have been auto-released by dying cgroup, so fail */
 | 
			
		||||
	if (!cg_link->cgroup) {
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
		goto out_unlock;
 | 
			
		||||
	}
 | 
			
		||||
	if (old_prog && link->prog != old_prog) {
 | 
			
		||||
		ret = -EPERM;
 | 
			
		||||
		goto out_unlock;
 | 
			
		||||
	}
 | 
			
		||||
	ret = __cgroup_bpf_replace(cg_link->cgroup, cg_link, new_prog);
 | 
			
		||||
out_unlock:
 | 
			
		||||
	mutex_unlock(&cgroup_mutex);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct bpf_prog_list *find_detach_entry(struct list_head *progs,
 | 
			
		||||
					       struct bpf_prog *prog,
 | 
			
		||||
					       struct bpf_cgroup_link *link,
 | 
			
		||||
| 
						 | 
				
			
			@ -811,6 +836,7 @@ static void bpf_cgroup_link_dealloc(struct bpf_link *link)
 | 
			
		|||
const struct bpf_link_ops bpf_cgroup_link_lops = {
 | 
			
		||||
	.release = bpf_cgroup_link_release,
 | 
			
		||||
	.dealloc = bpf_cgroup_link_dealloc,
 | 
			
		||||
	.update_prog = cgroup_bpf_replace,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int cgroup_bpf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3645,13 +3645,10 @@ static int link_update(union bpf_attr *attr)
 | 
			
		|||
		goto out_put_progs;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_CGROUP_BPF
 | 
			
		||||
	if (link->ops == &bpf_cgroup_link_lops) {
 | 
			
		||||
		ret = cgroup_bpf_replace(link, old_prog, new_prog);
 | 
			
		||||
		goto out_put_progs;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	ret = -EINVAL;
 | 
			
		||||
	if (link->ops->update_prog)
 | 
			
		||||
		ret = link->ops->update_prog(link, new_prog, old_prog);
 | 
			
		||||
	else
 | 
			
		||||
		ret = EINVAL;
 | 
			
		||||
 | 
			
		||||
out_put_progs:
 | 
			
		||||
	if (old_prog)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6508,33 +6508,6 @@ int cgroup_bpf_attach(struct cgroup *cgrp,
 | 
			
		|||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cgroup_bpf_replace(struct bpf_link *link, struct bpf_prog *old_prog,
 | 
			
		||||
		       struct bpf_prog *new_prog)
 | 
			
		||||
{
 | 
			
		||||
	struct bpf_cgroup_link *cg_link;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	if (link->ops != &bpf_cgroup_link_lops)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	cg_link = container_of(link, struct bpf_cgroup_link, link);
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&cgroup_mutex);
 | 
			
		||||
	/* link might have been auto-released by dying cgroup, so fail */
 | 
			
		||||
	if (!cg_link->cgroup) {
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
		goto out_unlock;
 | 
			
		||||
	}
 | 
			
		||||
	if (old_prog && link->prog != old_prog) {
 | 
			
		||||
		ret = -EPERM;
 | 
			
		||||
		goto out_unlock;
 | 
			
		||||
	}
 | 
			
		||||
	ret = __cgroup_bpf_replace(cg_link->cgroup, cg_link, new_prog);
 | 
			
		||||
out_unlock:
 | 
			
		||||
	mutex_unlock(&cgroup_mutex);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
 | 
			
		||||
		      enum bpf_attach_type type)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue