Commit f7583f02 authored by Wang Shanker's avatar Wang Shanker Committed by Pablo Neira Ayuso
Browse files

netfilter: nfnl_acct: remove data from struct net



This patch removes nfnl_acct_list from struct net to reduce the default
memory footprint for the netns structure.

Signed-off-by: default avatarMiao Wang <shankerwangmiao@gmail.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 0ef083d5
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -151,9 +151,6 @@ struct net {
#endif
	struct sock		*nfnl;
	struct sock		*nfnl_stash;
#if IS_ENABLED(CONFIG_NETFILTER_NETLINK_ACCT)
	struct list_head        nfnl_acct_list;
#endif
#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
	struct list_head	nfct_timeout_list;
#endif
+29 −9
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/errno.h>
#include <net/netlink.h>
#include <net/sock.h>
#include <net/netns/generic.h>

#include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink.h>
@@ -41,6 +42,17 @@ struct nfacct_filter {
	u32 mask;
};

struct nfnl_acct_net {
	struct list_head        nfnl_acct_list;
};

static unsigned int nfnl_acct_net_id __read_mostly;

static inline struct nfnl_acct_net *nfnl_acct_pernet(struct net *net)
{
	return net_generic(net, nfnl_acct_net_id);
}

#define NFACCT_F_QUOTA (NFACCT_F_QUOTA_PKTS | NFACCT_F_QUOTA_BYTES)
#define NFACCT_OVERQUOTA_BIT	2	/* NFACCT_F_OVERQUOTA */

@@ -49,6 +61,7 @@ static int nfnl_acct_new(struct net *net, struct sock *nfnl,
			 const struct nlattr * const tb[],
			 struct netlink_ext_ack *extack)
{
	struct nfnl_acct_net *nfnl_acct_net = nfnl_acct_pernet(net);
	struct nf_acct *nfacct, *matching = NULL;
	char *acct_name;
	unsigned int size = 0;
@@ -61,7 +74,7 @@ static int nfnl_acct_new(struct net *net, struct sock *nfnl,
	if (strlen(acct_name) == 0)
		return -EINVAL;

	list_for_each_entry(nfacct, &net->nfnl_acct_list, head) {
	list_for_each_entry(nfacct, &nfnl_acct_net->nfnl_acct_list, head) {
		if (strncmp(nfacct->name, acct_name, NFACCT_NAME_MAX) != 0)
			continue;

@@ -123,7 +136,7 @@ static int nfnl_acct_new(struct net *net, struct sock *nfnl,
			     be64_to_cpu(nla_get_be64(tb[NFACCT_PKTS])));
	}
	refcount_set(&nfacct->refcnt, 1);
	list_add_tail_rcu(&nfacct->head, &net->nfnl_acct_list);
	list_add_tail_rcu(&nfacct->head, &nfnl_acct_net->nfnl_acct_list);
	return 0;
}

@@ -188,6 +201,7 @@ static int
nfnl_acct_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct net *net = sock_net(skb->sk);
	struct nfnl_acct_net *nfnl_acct_net = nfnl_acct_pernet(net);
	struct nf_acct *cur, *last;
	const struct nfacct_filter *filter = cb->data;

@@ -199,7 +213,7 @@ nfnl_acct_dump(struct sk_buff *skb, struct netlink_callback *cb)
		cb->args[1] = 0;

	rcu_read_lock();
	list_for_each_entry_rcu(cur, &net->nfnl_acct_list, head) {
	list_for_each_entry_rcu(cur, &nfnl_acct_net->nfnl_acct_list, head) {
		if (last) {
			if (cur != last)
				continue;
@@ -269,6 +283,7 @@ static int nfnl_acct_get(struct net *net, struct sock *nfnl,
			 const struct nlattr * const tb[],
			 struct netlink_ext_ack *extack)
{
	struct nfnl_acct_net *nfnl_acct_net = nfnl_acct_pernet(net);
	int ret = -ENOENT;
	struct nf_acct *cur;
	char *acct_name;
@@ -288,7 +303,7 @@ static int nfnl_acct_get(struct net *net, struct sock *nfnl,
		return -EINVAL;
	acct_name = nla_data(tb[NFACCT_NAME]);

	list_for_each_entry(cur, &net->nfnl_acct_list, head) {
	list_for_each_entry(cur, &nfnl_acct_net->nfnl_acct_list, head) {
		struct sk_buff *skb2;

		if (strncmp(cur->name, acct_name, NFACCT_NAME_MAX)!= 0)
@@ -342,19 +357,20 @@ static int nfnl_acct_del(struct net *net, struct sock *nfnl,
			 const struct nlattr * const tb[],
			 struct netlink_ext_ack *extack)
{
	struct nfnl_acct_net *nfnl_acct_net = nfnl_acct_pernet(net);
	struct nf_acct *cur, *tmp;
	int ret = -ENOENT;
	char *acct_name;

	if (!tb[NFACCT_NAME]) {
		list_for_each_entry_safe(cur, tmp, &net->nfnl_acct_list, head)
		list_for_each_entry_safe(cur, tmp, &nfnl_acct_net->nfnl_acct_list, head)
			nfnl_acct_try_del(cur);

		return 0;
	}
	acct_name = nla_data(tb[NFACCT_NAME]);

	list_for_each_entry(cur, &net->nfnl_acct_list, head) {
	list_for_each_entry(cur, &nfnl_acct_net->nfnl_acct_list, head) {
		if (strncmp(cur->name, acct_name, NFACCT_NAME_MAX) != 0)
			continue;

@@ -402,10 +418,11 @@ MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_ACCT);

struct nf_acct *nfnl_acct_find_get(struct net *net, const char *acct_name)
{
	struct nfnl_acct_net *nfnl_acct_net = nfnl_acct_pernet(net);
	struct nf_acct *cur, *acct = NULL;

	rcu_read_lock();
	list_for_each_entry_rcu(cur, &net->nfnl_acct_list, head) {
	list_for_each_entry_rcu(cur, &nfnl_acct_net->nfnl_acct_list, head) {
		if (strncmp(cur->name, acct_name, NFACCT_NAME_MAX)!= 0)
			continue;

@@ -488,16 +505,17 @@ EXPORT_SYMBOL_GPL(nfnl_acct_overquota);

static int __net_init nfnl_acct_net_init(struct net *net)
{
	INIT_LIST_HEAD(&net->nfnl_acct_list);
	INIT_LIST_HEAD(&nfnl_acct_pernet(net)->nfnl_acct_list);

	return 0;
}

static void __net_exit nfnl_acct_net_exit(struct net *net)
{
	struct nfnl_acct_net *nfnl_acct_net = nfnl_acct_pernet(net);
	struct nf_acct *cur, *tmp;

	list_for_each_entry_safe(cur, tmp, &net->nfnl_acct_list, head) {
	list_for_each_entry_safe(cur, tmp, &nfnl_acct_net->nfnl_acct_list, head) {
		list_del_rcu(&cur->head);

		if (refcount_dec_and_test(&cur->refcnt))
@@ -508,6 +526,8 @@ static void __net_exit nfnl_acct_net_exit(struct net *net)
static struct pernet_operations nfnl_acct_ops = {
        .init   = nfnl_acct_net_init,
        .exit   = nfnl_acct_net_exit,
        .id     = &nfnl_acct_net_id,
        .size   = sizeof(struct nfnl_acct_net),
};

static int __init nfnl_acct_init(void)