コード例 #1
0
ファイル: bpf_jitter.c プロジェクト: BillTheBest/libuinet
bpf_jit_filter *
bpf_jitter(struct bpf_insn *fp, int nins)
{
	bpf_jit_filter *filter;

	/* Allocate the filter structure. */
#ifdef _KERNEL
	filter = (struct bpf_jit_filter *)malloc(sizeof(*filter),
	    M_BPFJIT, M_NOWAIT);
#else
	filter = (struct bpf_jit_filter *)malloc(sizeof(*filter));
#endif
	if (filter == NULL)
		return (NULL);

	/* No filter means accept all. */
	if (fp == NULL || nins == 0) {
		filter->func = bpf_jit_accept_all;
		return (filter);
	}

	/* Create the binary. */
	if ((filter->func = bpf_jit_compile(fp, nins, &filter->size)) == NULL) {
#ifdef _KERNEL
		free(filter, M_BPFJIT);
#else
		free(filter);
#endif
		return (NULL);
	}

	return (filter);
}
コード例 #2
0
/**
 *	sk_attach_filter - attach a socket filter
 *	@fprog: the filter program
 *	@sk: the socket to use
 *
 * Attach the user's filter code. We first run some sanity checks on
 * it to make sure it does not explode on us later. If an error
 * occurs or there is insufficient memory for the filter a negative
 * errno code is returned. On success the return is zero.
 */
int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
{
	struct sk_filter *fp, *old_fp;
	unsigned int fsize = sizeof(struct sock_filter) * fprog->len;
	int err;

	/* Make sure new filter is there and in the right amounts. */
	if (fprog->filter == NULL)
		return -EINVAL;

	fp = sock_kmalloc(sk, fsize+sizeof(*fp), GFP_KERNEL);
	if (!fp)
		return -ENOMEM;
	if (copy_from_user(fp->insns, fprog->filter, fsize)) {
		sock_kfree_s(sk, fp, fsize+sizeof(*fp));
		return -EFAULT;
	}

	atomic_set(&fp->refcnt, 1);
	fp->len = fprog->len;
	fp->bpf_func = sk_run_filter;

	err = sk_chk_filter(fp->insns, fp->len);
	if (err) {
		sk_filter_uncharge(sk, fp);
		return err;
	}

	bpf_jit_compile(fp);

	rcu_read_lock_bh();
	old_fp = rcu_dereference_bh(sk->sk_filter);
	rcu_assign_pointer(sk->sk_filter, fp);
	rcu_read_unlock_bh();

	if (old_fp)
		sk_filter_delayed_uncharge(sk, old_fp);
	return 0;
}