コード例 #1
0
ファイル: act_bpf.c プロジェクト: RealJohnGalt/linux
static int tcf_bpf_init_from_efd(struct nlattr **tb, struct tcf_bpf_cfg *cfg)
{
	struct bpf_prog *fp;
	char *name = NULL;
	u32 bpf_fd;

	bpf_fd = nla_get_u32(tb[TCA_ACT_BPF_FD]);

	fp = bpf_prog_get(bpf_fd);
	if (IS_ERR(fp))
		return PTR_ERR(fp);

	if (fp->type != BPF_PROG_TYPE_SCHED_ACT) {
		bpf_prog_put(fp);
		return -EINVAL;
	}

	if (tb[TCA_ACT_BPF_NAME]) {
		name = kmemdup(nla_data(tb[TCA_ACT_BPF_NAME]),
			       nla_len(tb[TCA_ACT_BPF_NAME]),
			       GFP_KERNEL);
		if (!name) {
			bpf_prog_put(fp);
			return -ENOMEM;
		}
	}

	cfg->bpf_fd = bpf_fd;
	cfg->bpf_name = name;
	cfg->filter = fp;

	return 0;
}
コード例 #2
0
ファイル: act_bpf.c プロジェクト: ReneNyffenegger/linux
static int tcf_bpf_init_from_efd(struct nlattr **tb, struct tcf_bpf_cfg *cfg)
{
	struct bpf_prog *fp;
	char *name = NULL;
	u32 bpf_fd;

	bpf_fd = nla_get_u32(tb[TCA_ACT_BPF_FD]);

	fp = bpf_prog_get_type(bpf_fd, BPF_PROG_TYPE_SCHED_ACT);
	if (IS_ERR(fp))
		return PTR_ERR(fp);

	if (tb[TCA_ACT_BPF_NAME]) {
		name = nla_memdup(tb[TCA_ACT_BPF_NAME], GFP_KERNEL);
		if (!name) {
			bpf_prog_put(fp);
			return -ENOMEM;
		}
	}

	cfg->bpf_name = name;
	cfg->filter = fp;
	cfg->is_ebpf = true;

	return 0;
}
コード例 #3
0
ファイル: arraymap.c プロジェクト: ammubhave/bargud
/* only called from syscall */
static int prog_array_map_update_elem(struct bpf_map *map, void *key,
				      void *value, u64 map_flags)
{
	struct bpf_array *array = container_of(map, struct bpf_array, map);
	struct bpf_prog *prog, *old_prog;
	u32 index = *(u32 *)key, ufd;

	if (map_flags != BPF_ANY)
		return -EINVAL;

	if (index >= array->map.max_entries)
		return -E2BIG;

	ufd = *(u32 *)value;
	prog = bpf_prog_get(ufd);
	if (IS_ERR(prog))
		return PTR_ERR(prog);

	if (!bpf_prog_array_compatible(array, prog)) {
		bpf_prog_put(prog);
		return -EINVAL;
	}

	old_prog = xchg(array->prog + index, prog);
	if (old_prog)
		bpf_prog_put_rcu(old_prog);

	return 0;
}
コード例 #4
0
ファイル: act_bpf.c プロジェクト: RealJohnGalt/linux
static void tcf_bpf_cleanup(struct tc_action *act, int bind)
{
	const struct tcf_bpf *prog = act->priv;

	if (tcf_bpf_is_ebpf(prog))
		bpf_prog_put(prog->filter);
	else
		bpf_prog_destroy(prog->filter);
}
コード例 #5
0
ファイル: act_bpf.c プロジェクト: acton393/linux
static void tcf_bpf_cfg_cleanup(const struct tcf_bpf_cfg *cfg)
{
	if (cfg->is_ebpf)
		bpf_prog_put(cfg->filter);
	else
		bpf_prog_destroy(cfg->filter);

	kfree(cfg->bpf_ops);
	kfree(cfg->bpf_name);
}
コード例 #6
0
static void *prog_fd_array_get_ptr(struct bpf_map *map, int fd)
{
    struct bpf_array *array = container_of(map, struct bpf_array, map);
    struct bpf_prog *prog = bpf_prog_get(fd);
    if (IS_ERR(prog))
        return prog;

    if (!bpf_prog_array_compatible(array, prog)) {
        bpf_prog_put(prog);
        return ERR_PTR(-EINVAL);
    }
    return prog;
}
コード例 #7
0
ファイル: inode.c プロジェクト: AK101111/linux
static void bpf_any_put(void *raw, enum bpf_type type)
{
	switch (type) {
	case BPF_TYPE_PROG:
		bpf_prog_put(raw);
		break;
	case BPF_TYPE_MAP:
		bpf_map_put_with_uref(raw);
		break;
	default:
		WARN_ON_ONCE(1);
		break;
	}
}
コード例 #8
0
ファイル: cgroup.c プロジェクト: krzk/linux
/**
 * cgroup_bpf_put() - put references of all bpf programs
 * @cgrp: the cgroup to modify
 */
void cgroup_bpf_put(struct cgroup *cgrp)
{
	unsigned int type;

	for (type = 0; type < ARRAY_SIZE(cgrp->bpf.progs); type++) {
		struct list_head *progs = &cgrp->bpf.progs[type];
		struct bpf_prog_list *pl, *tmp;

		list_for_each_entry_safe(pl, tmp, progs, node) {
			list_del(&pl->node);
			bpf_prog_put(pl->prog);
			kfree(pl);
			static_branch_dec(&cgroup_bpf_enabled_key);
		}
		bpf_prog_array_free(cgrp->bpf.effective[type]);
	}
コード例 #9
0
ファイル: act_bpf.c プロジェクト: RealJohnGalt/linux
static int tcf_bpf_init(struct net *net, struct nlattr *nla,
			struct nlattr *est, struct tc_action *act,
			int replace, int bind)
{
	struct nlattr *tb[TCA_ACT_BPF_MAX + 1];
	struct tc_act_bpf *parm;
	struct tcf_bpf *prog;
	struct tcf_bpf_cfg cfg;
	bool is_bpf, is_ebpf;
	int ret;

	if (!nla)
		return -EINVAL;

	ret = nla_parse_nested(tb, TCA_ACT_BPF_MAX, nla, act_bpf_policy);
	if (ret < 0)
		return ret;

	is_bpf = tb[TCA_ACT_BPF_OPS_LEN] && tb[TCA_ACT_BPF_OPS];
	is_ebpf = tb[TCA_ACT_BPF_FD];

	if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf) ||
	    !tb[TCA_ACT_BPF_PARMS])
		return -EINVAL;

	parm = nla_data(tb[TCA_ACT_BPF_PARMS]);

	memset(&cfg, 0, sizeof(cfg));

	ret = is_bpf ? tcf_bpf_init_from_ops(tb, &cfg) :
		       tcf_bpf_init_from_efd(tb, &cfg);
	if (ret < 0)
		return ret;

	if (!tcf_hash_check(parm->index, act, bind)) {
		ret = tcf_hash_create(parm->index, est, act,
				      sizeof(*prog), bind);
		if (ret < 0)
			goto destroy_fp;

		ret = ACT_P_CREATED;
	} else {
		/* Don't override defaults. */
		if (bind)
			goto destroy_fp;

		tcf_hash_release(act, bind);
		if (!replace) {
			ret = -EEXIST;
			goto destroy_fp;
		}
	}

	prog = to_bpf(act);
	spin_lock_bh(&prog->tcf_lock);

	prog->bpf_ops = cfg.bpf_ops;
	prog->bpf_name = cfg.bpf_name;

	if (cfg.bpf_num_ops)
		prog->bpf_num_ops = cfg.bpf_num_ops;
	if (cfg.bpf_fd)
		prog->bpf_fd = cfg.bpf_fd;

	prog->tcf_action = parm->action;
	prog->filter = cfg.filter;

	spin_unlock_bh(&prog->tcf_lock);

	if (ret == ACT_P_CREATED)
		tcf_hash_insert(act);

	return ret;

destroy_fp:
	if (is_ebpf)
		bpf_prog_put(cfg.filter);
	else
		bpf_prog_destroy(cfg.filter);

	kfree(cfg.bpf_ops);
	kfree(cfg.bpf_name);

	return ret;
}
コード例 #10
0
ファイル: arraymap.c プロジェクト: robeat101/linux
static void prog_fd_array_put_ptr(void *ptr)
{
    bpf_prog_put(ptr);
}