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

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
...@@ -151,9 +151,6 @@ struct net { ...@@ -151,9 +151,6 @@ struct net {
#endif #endif
struct sock *nfnl; struct sock *nfnl;
struct sock *nfnl_stash; 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) #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
struct list_head nfct_timeout_list; struct list_head nfct_timeout_list;
#endif #endif
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <net/netlink.h> #include <net/netlink.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/netns/generic.h>
#include <linux/netfilter.h> #include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink.h> #include <linux/netfilter/nfnetlink.h>
...@@ -41,6 +42,17 @@ struct nfacct_filter { ...@@ -41,6 +42,17 @@ struct nfacct_filter {
u32 mask; 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_F_QUOTA (NFACCT_F_QUOTA_PKTS | NFACCT_F_QUOTA_BYTES)
#define NFACCT_OVERQUOTA_BIT 2 /* NFACCT_F_OVERQUOTA */ #define NFACCT_OVERQUOTA_BIT 2 /* NFACCT_F_OVERQUOTA */
...@@ -49,6 +61,7 @@ static int nfnl_acct_new(struct net *net, struct sock *nfnl, ...@@ -49,6 +61,7 @@ static int nfnl_acct_new(struct net *net, struct sock *nfnl,
const struct nlattr * const tb[], const struct nlattr * const tb[],
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct nfnl_acct_net *nfnl_acct_net = nfnl_acct_pernet(net);
struct nf_acct *nfacct, *matching = NULL; struct nf_acct *nfacct, *matching = NULL;
char *acct_name; char *acct_name;
unsigned int size = 0; unsigned int size = 0;
...@@ -61,7 +74,7 @@ static int nfnl_acct_new(struct net *net, struct sock *nfnl, ...@@ -61,7 +74,7 @@ static int nfnl_acct_new(struct net *net, struct sock *nfnl,
if (strlen(acct_name) == 0) if (strlen(acct_name) == 0)
return -EINVAL; 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) if (strncmp(nfacct->name, acct_name, NFACCT_NAME_MAX) != 0)
continue; continue;
...@@ -123,7 +136,7 @@ static int nfnl_acct_new(struct net *net, struct sock *nfnl, ...@@ -123,7 +136,7 @@ static int nfnl_acct_new(struct net *net, struct sock *nfnl,
be64_to_cpu(nla_get_be64(tb[NFACCT_PKTS]))); be64_to_cpu(nla_get_be64(tb[NFACCT_PKTS])));
} }
refcount_set(&nfacct->refcnt, 1); 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; return 0;
} }
...@@ -188,6 +201,7 @@ static int ...@@ -188,6 +201,7 @@ static int
nfnl_acct_dump(struct sk_buff *skb, struct netlink_callback *cb) nfnl_acct_dump(struct sk_buff *skb, struct netlink_callback *cb)
{ {
struct net *net = sock_net(skb->sk); struct net *net = sock_net(skb->sk);
struct nfnl_acct_net *nfnl_acct_net = nfnl_acct_pernet(net);
struct nf_acct *cur, *last; struct nf_acct *cur, *last;
const struct nfacct_filter *filter = cb->data; const struct nfacct_filter *filter = cb->data;
...@@ -199,7 +213,7 @@ nfnl_acct_dump(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -199,7 +213,7 @@ nfnl_acct_dump(struct sk_buff *skb, struct netlink_callback *cb)
cb->args[1] = 0; cb->args[1] = 0;
rcu_read_lock(); 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 (last) {
if (cur != last) if (cur != last)
continue; continue;
...@@ -269,6 +283,7 @@ static int nfnl_acct_get(struct net *net, struct sock *nfnl, ...@@ -269,6 +283,7 @@ static int nfnl_acct_get(struct net *net, struct sock *nfnl,
const struct nlattr * const tb[], const struct nlattr * const tb[],
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct nfnl_acct_net *nfnl_acct_net = nfnl_acct_pernet(net);
int ret = -ENOENT; int ret = -ENOENT;
struct nf_acct *cur; struct nf_acct *cur;
char *acct_name; char *acct_name;
...@@ -288,7 +303,7 @@ static int nfnl_acct_get(struct net *net, struct sock *nfnl, ...@@ -288,7 +303,7 @@ static int nfnl_acct_get(struct net *net, struct sock *nfnl,
return -EINVAL; return -EINVAL;
acct_name = nla_data(tb[NFACCT_NAME]); 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; struct sk_buff *skb2;
if (strncmp(cur->name, acct_name, NFACCT_NAME_MAX)!= 0) 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, ...@@ -342,19 +357,20 @@ static int nfnl_acct_del(struct net *net, struct sock *nfnl,
const struct nlattr * const tb[], const struct nlattr * const tb[],
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct nfnl_acct_net *nfnl_acct_net = nfnl_acct_pernet(net);
struct nf_acct *cur, *tmp; struct nf_acct *cur, *tmp;
int ret = -ENOENT; int ret = -ENOENT;
char *acct_name; char *acct_name;
if (!tb[NFACCT_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); nfnl_acct_try_del(cur);
return 0; return 0;
} }
acct_name = nla_data(tb[NFACCT_NAME]); 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) if (strncmp(cur->name, acct_name, NFACCT_NAME_MAX) != 0)
continue; continue;
...@@ -402,10 +418,11 @@ MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_ACCT); ...@@ -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 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; struct nf_acct *cur, *acct = NULL;
rcu_read_lock(); 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) if (strncmp(cur->name, acct_name, NFACCT_NAME_MAX)!= 0)
continue; continue;
...@@ -488,16 +505,17 @@ EXPORT_SYMBOL_GPL(nfnl_acct_overquota); ...@@ -488,16 +505,17 @@ EXPORT_SYMBOL_GPL(nfnl_acct_overquota);
static int __net_init nfnl_acct_net_init(struct net *net) 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; return 0;
} }
static void __net_exit nfnl_acct_net_exit(struct net *net) 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; 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); list_del_rcu(&cur->head);
if (refcount_dec_and_test(&cur->refcnt)) if (refcount_dec_and_test(&cur->refcnt))
...@@ -508,6 +526,8 @@ static void __net_exit nfnl_acct_net_exit(struct net *net) ...@@ -508,6 +526,8 @@ static void __net_exit nfnl_acct_net_exit(struct net *net)
static struct pernet_operations nfnl_acct_ops = { static struct pernet_operations nfnl_acct_ops = {
.init = nfnl_acct_net_init, .init = nfnl_acct_net_init,
.exit = nfnl_acct_net_exit, .exit = nfnl_acct_net_exit,
.id = &nfnl_acct_net_id,
.size = sizeof(struct nfnl_acct_net),
}; };
static int __init nfnl_acct_init(void) static int __init nfnl_acct_init(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment