Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fb5b6095 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[NETFILTER]: arp_tables: move entry and target checks to seperate functions



Resync with ip_tables.c as preparation for compat support.

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 70f0bfcf
Loading
Loading
Loading
Loading
+41 −17
Original line number Original line Diff line number Diff line
@@ -435,12 +435,9 @@ static int mark_source_chains(struct xt_table_info *newinfo,
	return 1;
	return 1;
}
}


static inline int check_entry(struct arpt_entry *e, const char *name, unsigned int size,
static inline int check_entry(struct arpt_entry *e, const char *name)
			      unsigned int *i)
{
{
	struct arpt_entry_target *t;
	struct arpt_entry_target *t;
	struct arpt_target *target;
	int ret;


	if (!arp_checkentry(&e->arp)) {
	if (!arp_checkentry(&e->arp)) {
		duprintf("arp_tables: arp check failed %p %s.\n", e, name);
		duprintf("arp_tables: arp check failed %p %s.\n", e, name);
@@ -454,30 +451,57 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i
	if (e->target_offset + t->u.target_size > e->next_offset)
	if (e->target_offset + t->u.target_size > e->next_offset)
		return -EINVAL;
		return -EINVAL;


	return 0;
}

static inline int check_target(struct arpt_entry *e, const char *name)
{
	struct arpt_entry_target *t;
	struct arpt_target *target;
	int ret;

	t = arpt_get_target(e);
	target = t->u.kernel.target;

	ret = xt_check_target(target, NF_ARP, t->u.target_size - sizeof(*t),
			      name, e->comefrom, 0, 0);
	if (!ret && t->u.kernel.target->checkentry
	    && !t->u.kernel.target->checkentry(name, e, target, t->data,
					       e->comefrom)) {
		duprintf("arp_tables: check failed for `%s'.\n",
			 t->u.kernel.target->name);
		ret = -EINVAL;
	}
	return ret;
}

static inline int
find_check_entry(struct arpt_entry *e, const char *name, unsigned int size,
		 unsigned int *i)
{
	struct arpt_entry_target *t;
	struct arpt_target *target;
	int ret;

	ret = check_entry(e, name);
	if (ret)
		return ret;

	t = arpt_get_target(e);
	target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name,
	target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name,
							t->u.user.revision),
							t->u.user.revision),
					 "arpt_%s", t->u.user.name);
					 "arpt_%s", t->u.user.name);
	if (IS_ERR(target) || !target) {
	if (IS_ERR(target) || !target) {
		duprintf("check_entry: `%s' not found\n", t->u.user.name);
		duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
		ret = target ? PTR_ERR(target) : -ENOENT;
		ret = target ? PTR_ERR(target) : -ENOENT;
		goto out;
		goto out;
	}
	}
	t->u.kernel.target = target;
	t->u.kernel.target = target;


	ret = xt_check_target(target, NF_ARP, t->u.target_size - sizeof(*t),
	ret = check_target(e, name);
			      name, e->comefrom, 0, 0);
	if (ret)
	if (ret)
		goto err;
		goto err;


	if (t->u.kernel.target->checkentry
	    && !t->u.kernel.target->checkentry(name, e, target, t->data,
					       e->comefrom)) {
		duprintf("arp_tables: check failed for `%s'.\n",
			 t->u.kernel.target->name);
		ret = -EINVAL;
		goto err;
	}

	(*i)++;
	(*i)++;
	return 0;
	return 0;
err:
err:
@@ -611,7 +635,7 @@ static int translate_table(const char *name,
	/* Finally, each sanity check must pass */
	/* Finally, each sanity check must pass */
	i = 0;
	i = 0;
	ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
	ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
				 check_entry, name, size, &i);
				 find_check_entry, name, size, &i);


	if (ret != 0) {
	if (ret != 0) {
		ARPT_ENTRY_ITERATE(entry0, newinfo->size,
		ARPT_ENTRY_ITERATE(entry0, newinfo->size,