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

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

netfilter: x_tables: pass xt_counters struct to counter allocator



Keeps some noise away from a followup patch.

Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Acked-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 4d31eef5
Loading
Loading
Loading
Loading
+1 −26
Original line number Diff line number Diff line
@@ -404,32 +404,7 @@ static inline unsigned long ifname_compare_aligned(const char *_a,
}


/* On SMP, ip(6)t_entry->counters.pcnt holds address of the
 * real (percpu) counter.  On !SMP, its just the packet count,
 * so nothing needs to be done there.
 *
 * xt_percpu_counter_alloc returns the address of the percpu
 * counter, or 0 on !SMP. We force an alignment of 16 bytes
 * so that bytes/packets share a common cache line.
 *
 * Hence caller must use IS_ERR_VALUE to check for error, this
 * allows us to return 0 for single core systems without forcing
 * callers to deal with SMP vs. NONSMP issues.
 */
static inline unsigned long xt_percpu_counter_alloc(void)
{
	if (nr_cpu_ids > 1) {
		void __percpu *res = __alloc_percpu(sizeof(struct xt_counters),
						    sizeof(struct xt_counters));

		if (res == NULL)
			return -ENOMEM;

		return (__force unsigned long) res;
	}

	return 0;
}
bool xt_percpu_counter_alloc(struct xt_counters *counters);
void xt_percpu_counter_free(struct xt_counters *cnt);

static inline struct xt_counters *
+1 −4
Original line number Diff line number Diff line
@@ -415,13 +415,10 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size)
{
	struct xt_entry_target *t;
	struct xt_target *target;
	unsigned long pcnt;
	int ret;

	pcnt = xt_percpu_counter_alloc();
	if (IS_ERR_VALUE(pcnt))
	if (!xt_percpu_counter_alloc(&e->counters))
		return -ENOMEM;
	e->counters.pcnt = pcnt;

	t = arpt_get_target(e);
	target = xt_request_find_target(NFPROTO_ARP, t->u.user.name,
+1 −4
Original line number Diff line number Diff line
@@ -539,12 +539,9 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
	unsigned int j;
	struct xt_mtchk_param mtpar;
	struct xt_entry_match *ematch;
	unsigned long pcnt;

	pcnt = xt_percpu_counter_alloc();
	if (IS_ERR_VALUE(pcnt))
	if (!xt_percpu_counter_alloc(&e->counters))
		return -ENOMEM;
	e->counters.pcnt = pcnt;

	j = 0;
	mtpar.net	= net;
+1 −4
Original line number Diff line number Diff line
@@ -570,12 +570,9 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
	unsigned int j;
	struct xt_mtchk_param mtpar;
	struct xt_entry_match *ematch;
	unsigned long pcnt;

	pcnt = xt_percpu_counter_alloc();
	if (IS_ERR_VALUE(pcnt))
	if (!xt_percpu_counter_alloc(&e->counters))
		return -ENOMEM;
	e->counters.pcnt = pcnt;

	j = 0;
	mtpar.net	= net;
+30 −0
Original line number Diff line number Diff line
@@ -1615,6 +1615,36 @@ void xt_proto_fini(struct net *net, u_int8_t af)
}
EXPORT_SYMBOL_GPL(xt_proto_fini);

/**
 * xt_percpu_counter_alloc - allocate x_tables rule counter
 *
 * @counter: pointer to counter struct inside the ip(6)/arpt_entry struct
 *
 * On SMP, the packet counter [ ip(6)t_entry->counters.pcnt ] will then
 * contain the address of the real (percpu) counter.
 *
 * Rule evaluation needs to use xt_get_this_cpu_counter() helper
 * to fetch the real percpu counter.
 *
 * returns false on error.
 */
bool xt_percpu_counter_alloc(struct xt_counters *counter)
{
	void __percpu *res;

	if (nr_cpu_ids <= 1)
		return true;

	res = __alloc_percpu(sizeof(struct xt_counters),
			     sizeof(struct xt_counters));
	if (!res)
		return false;

	counter->pcnt = (__force unsigned long)res;
	return true;
}
EXPORT_SYMBOL_GPL(xt_percpu_counter_alloc);

void xt_percpu_counter_free(struct xt_counters *counters)
{
	unsigned long pcnt = counters->pcnt;