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

Commit 103a9778 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso
Browse files

netfilter: ebtables: only call xt_compat_add_offset once per rule



The optimizations in commit 255d0dc3
(netfilter: x_table: speedup compat operations) assume that
xt_compat_add_offset is called once per rule.

ebtables however called it for each match/target found in a rule.

The match/watcher/target parser already returns the needed delta, so it
is sufficient to move the xt_compat_add_offset call to a more reasonable
location.

While at it, also get rid of the unused COMPAT iterator macros.

Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent 5a6351ee
Loading
Loading
Loading
Loading
+9 −52
Original line number Diff line number Diff line
@@ -1882,7 +1882,7 @@ static int compat_mtw_from_user(struct compat_ebt_entry_mwt *mwt,
	struct xt_match *match;
	struct xt_target *wt;
	void *dst = NULL;
	int off, pad = 0, ret = 0;
	int off, pad = 0;
	unsigned int size_kern, entry_offset, match_size = mwt->match_size;

	strlcpy(name, mwt->u.name, sizeof(name));
@@ -1935,13 +1935,6 @@ static int compat_mtw_from_user(struct compat_ebt_entry_mwt *mwt,
		break;
	}

	if (!dst) {
		ret = xt_compat_add_offset(NFPROTO_BRIDGE, entry_offset,
					off + ebt_compat_entry_padsize());
		if (ret < 0)
			return ret;
	}

	state->buf_kern_offset += match_size + off;
	state->buf_user_offset += match_size;
	pad = XT_ALIGN(size_kern) - size_kern;
@@ -2016,50 +2009,6 @@ static int ebt_size_mwt(struct compat_ebt_entry_mwt *match32,
	return growth;
}

#define EBT_COMPAT_WATCHER_ITERATE(e, fn, args...)          \
({                                                          \
	unsigned int __i;                                   \
	int __ret = 0;                                      \
	struct compat_ebt_entry_mwt *__watcher;             \
	                                                    \
	for (__i = e->watchers_offset;                      \
	     __i < (e)->target_offset;                      \
	     __i += __watcher->watcher_size +               \
	     sizeof(struct compat_ebt_entry_mwt)) {         \
		__watcher = (void *)(e) + __i;              \
		__ret = fn(__watcher , ## args);            \
		if (__ret != 0)                             \
			break;                              \
	}                                                   \
	if (__ret == 0) {                                   \
		if (__i != (e)->target_offset)              \
			__ret = -EINVAL;                    \
	}                                                   \
	__ret;                                              \
})

#define EBT_COMPAT_MATCH_ITERATE(e, fn, args...)            \
({                                                          \
	unsigned int __i;                                   \
	int __ret = 0;                                      \
	struct compat_ebt_entry_mwt *__match;               \
	                                                    \
	for (__i = sizeof(struct ebt_entry);                \
	     __i < (e)->watchers_offset;                    \
	     __i += __match->match_size +                   \
	     sizeof(struct compat_ebt_entry_mwt)) {         \
		__match = (void *)(e) + __i;                \
		__ret = fn(__match , ## args);              \
		if (__ret != 0)                             \
			break;                              \
	}                                                   \
	if (__ret == 0) {                                   \
		if (__i != (e)->watchers_offset)            \
			__ret = -EINVAL;                    \
	}                                                   \
	__ret;                                              \
})

/* called for all ebt_entry structures. */
static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base,
			  unsigned int *total,
@@ -2132,6 +2081,14 @@ static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base,
		}
	}

	if (state->buf_kern_start == NULL) {
		unsigned int offset = buf_start - (char *) base;

		ret = xt_compat_add_offset(NFPROTO_BRIDGE, offset, new_offset);
		if (ret < 0)
			return ret;
	}

	startoff = state->buf_user_offset - startoff;

	BUG_ON(*total < startoff);