Exemple #1
0
static int rst_restore_iptables(struct cpt_context * ctx)
{
	int err;
	int pfd[2];
	struct file *f;
	struct cpt_object_hdr v;
	int n;
	struct cpt_section_hdr h;
	loff_t sec = ctx->sections[CPT_SECT_NET_IPTABLES];
	loff_t end;
	int pid;
	int status;
	mm_segment_t oldfs;
	sigset_t ignore, blocked;

	if (sec == CPT_NULL)
		return 0;

	err = ctx->pread(&h, sizeof(h), ctx, sec);
	if (err)
		return err;
	if (h.cpt_section != CPT_SECT_NET_IPTABLES || h.cpt_hdrlen < sizeof(h))
		return -EINVAL;

	if (h.cpt_hdrlen == h.cpt_next)
		return 0;
	if (h.cpt_hdrlen > h.cpt_next)
		return -EINVAL;
	sec += h.cpt_hdrlen;
	err = rst_get_object(CPT_OBJ_NAME, sec, &v, ctx);
	if (err < 0)
		return err;

	err = sc_pipe(pfd);
	if (err < 0)
		return err;
	ignore.sig[0] = CPT_SIG_IGNORE_MASK;
	sigprocmask(SIG_BLOCK, &ignore, &blocked);
	pid = err = local_kernel_thread(dumpfn, (void*)pfd, SIGCHLD, 0);
	if (err < 0) {
		eprintk_ctx("iptables local_kernel_thread: %d\n", err);
		goto out;
	}
	f = fget(pfd[1]);
	sc_close(pfd[1]);
	sc_close(pfd[0]);

	ctx->file->f_pos = sec + v.cpt_hdrlen;
	end = sec + v.cpt_next;
	do {
		char *p;
		char buf[16];

		n = end - ctx->file->f_pos;
		if (n > sizeof(buf))
			n = sizeof(buf);

		if (ctx->read(buf, n, ctx))
			break;
		if ((p = memchr(buf, 0, n)) != NULL)
			n = p - buf;
		oldfs = get_fs(); set_fs(KERNEL_DS);
		f->f_op->write(f, buf, n, &f->f_pos);
		set_fs(oldfs);
	} while (ctx->file->f_pos < end);

	fput(f);

	oldfs = get_fs(); set_fs(KERNEL_DS);
	if ((err = sc_waitx(pid, 0, &status)) < 0)
		eprintk_ctx("wait4: %d\n", err);
	else if ((status & 0x7f) == 0) {
		err = (status & 0xff00) >> 8;
		if (err != 0) {
			eprintk_ctx("iptables-restore exited with %d\n", err);
			eprintk_ctx("Most probably some iptables modules are not loaded\n");
			err = -EINVAL;
		}
	} else {
Exemple #2
0
static int cpt_dump_iptables(struct cpt_context * ctx)
{
	int err = 0;
#ifdef CONFIG_VE_IPTABLES
	int pid;
	int pfd[2];
	struct file *f;
	struct cpt_object_hdr v;
	char buf[16];
	loff_t pos;
	int n;
	int status;
	mm_segment_t oldfs;
	sigset_t ignore, blocked;
	struct args_t args;
	struct ve_struct *oldenv;

	if (!(get_exec_env()->_iptables_modules & VE_IP_IPTABLES_MOD))
		return 0;

	err = sc_pipe(pfd);
	if (err < 0) {
		eprintk_ctx("sc_pipe: %d\n", err);
		return err;
	}
	args.pfd = pfd;
	args.veid = VEID(get_exec_env());
	ignore.sig[0] = CPT_SIG_IGNORE_MASK;
	sigprocmask(SIG_BLOCK, &ignore, &blocked);
	oldenv = set_exec_env(get_ve0());
	err = pid = local_kernel_thread(dumpfn, (void*)&args,
			SIGCHLD | CLONE_VFORK, 0);
	set_exec_env(oldenv);
	if (err < 0) {
		eprintk_ctx("local_kernel_thread: %d\n", err);
		goto out;
	}

	f = fget(pfd[0]);
	sc_close(pfd[1]);
	sc_close(pfd[0]);

	cpt_open_section(ctx, CPT_SECT_NET_IPTABLES);

	cpt_open_object(NULL, ctx);
	v.cpt_next = CPT_NULL;
	v.cpt_object = CPT_OBJ_NAME;
	v.cpt_hdrlen = sizeof(v);
	v.cpt_content = CPT_CONTENT_NAME;

	ctx->write(&v, sizeof(v), ctx);

	pos = ctx->file->f_pos;
	do {
		oldfs = get_fs(); set_fs(KERNEL_DS);
		n = f->f_op->read(f, buf, sizeof(buf), &f->f_pos);
		set_fs(oldfs);
		if (n > 0)
			ctx->write(buf, n, ctx);
	} while (n > 0);

	if (n < 0)
		eprintk_ctx("read: %d\n", n);

	fput(f);

	oldfs = get_fs(); set_fs(KERNEL_DS);
	if ((err = sc_waitx(pid, 0, &status)) < 0)
		eprintk_ctx("wait4: %d\n", err);
	else if ((status & 0x7f) == 0) {
		err = (status & 0xff00) >> 8;
		if (err != 0) {
			eprintk_ctx("iptables-save exited with %d\n", err);
			err = -EINVAL;
		}
	} else {