net: dynamically allocate fqdir structures
Following patch will add rcu grace period before fqdir rhashtable destruction, so we need to dynamically allocate fqdir structures to not force expensive synchronize_rcu() calls in netns dismantle path. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a39aca678a
commit
4907abc605
|
@ -105,14 +105,25 @@ struct inet_frags {
|
||||||
int inet_frags_init(struct inet_frags *);
|
int inet_frags_init(struct inet_frags *);
|
||||||
void inet_frags_fini(struct inet_frags *);
|
void inet_frags_fini(struct inet_frags *);
|
||||||
|
|
||||||
static inline int fqdir_init(struct fqdir *fqdir, struct inet_frags *f,
|
static inline int fqdir_init(struct fqdir **fqdirp, struct inet_frags *f,
|
||||||
struct net *net)
|
struct net *net)
|
||||||
{
|
{
|
||||||
|
struct fqdir *fqdir = kzalloc(sizeof(*fqdir), GFP_KERNEL);
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (!fqdir)
|
||||||
|
return -ENOMEM;
|
||||||
fqdir->f = f;
|
fqdir->f = f;
|
||||||
fqdir->net = net;
|
fqdir->net = net;
|
||||||
atomic_long_set(&fqdir->mem, 0);
|
res = rhashtable_init(&fqdir->rhashtable, &fqdir->f->rhash_params);
|
||||||
return rhashtable_init(&fqdir->rhashtable, &fqdir->f->rhash_params);
|
if (res < 0) {
|
||||||
|
kfree(fqdir);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
*fqdirp = fqdir;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fqdir_exit(struct fqdir *fqdir);
|
void fqdir_exit(struct fqdir *fqdir);
|
||||||
|
|
||||||
void inet_frag_kill(struct inet_frag_queue *q);
|
void inet_frag_kill(struct inet_frag_queue *q);
|
||||||
|
|
|
@ -16,7 +16,7 @@ struct netns_sysctl_lowpan {
|
||||||
|
|
||||||
struct netns_ieee802154_lowpan {
|
struct netns_ieee802154_lowpan {
|
||||||
struct netns_sysctl_lowpan sysctl;
|
struct netns_sysctl_lowpan sysctl;
|
||||||
struct fqdir fqdir;
|
struct fqdir *fqdir;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -72,7 +72,7 @@ struct netns_ipv4 {
|
||||||
|
|
||||||
struct inet_peer_base *peers;
|
struct inet_peer_base *peers;
|
||||||
struct sock * __percpu *tcp_sk;
|
struct sock * __percpu *tcp_sk;
|
||||||
struct fqdir fqdir;
|
struct fqdir *fqdir;
|
||||||
#ifdef CONFIG_NETFILTER
|
#ifdef CONFIG_NETFILTER
|
||||||
struct xt_table *iptable_filter;
|
struct xt_table *iptable_filter;
|
||||||
struct xt_table *iptable_mangle;
|
struct xt_table *iptable_mangle;
|
||||||
|
|
|
@ -58,7 +58,7 @@ struct netns_ipv6 {
|
||||||
struct ipv6_devconf *devconf_all;
|
struct ipv6_devconf *devconf_all;
|
||||||
struct ipv6_devconf *devconf_dflt;
|
struct ipv6_devconf *devconf_dflt;
|
||||||
struct inet_peer_base *peers;
|
struct inet_peer_base *peers;
|
||||||
struct fqdir fqdir;
|
struct fqdir *fqdir;
|
||||||
#ifdef CONFIG_NETFILTER
|
#ifdef CONFIG_NETFILTER
|
||||||
struct xt_table *ip6table_filter;
|
struct xt_table *ip6table_filter;
|
||||||
struct xt_table *ip6table_mangle;
|
struct xt_table *ip6table_mangle;
|
||||||
|
@ -116,7 +116,7 @@ struct netns_ipv6 {
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
|
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
|
||||||
struct netns_nf_frag {
|
struct netns_nf_frag {
|
||||||
struct fqdir fqdir;
|
struct fqdir *fqdir;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ fq_find(struct net *net, const struct lowpan_802154_cb *cb,
|
||||||
key.src = *src;
|
key.src = *src;
|
||||||
key.dst = *dst;
|
key.dst = *dst;
|
||||||
|
|
||||||
q = inet_frag_find(&ieee802154_lowpan->fqdir, &key);
|
q = inet_frag_find(ieee802154_lowpan->fqdir, &key);
|
||||||
if (!q)
|
if (!q)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -377,11 +377,11 @@ static int __net_init lowpan_frags_ns_sysctl_register(struct net *net)
|
||||||
table[0].procname = NULL;
|
table[0].procname = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
table[0].data = &ieee802154_lowpan->fqdir.high_thresh;
|
table[0].data = &ieee802154_lowpan->fqdir->high_thresh;
|
||||||
table[0].extra1 = &ieee802154_lowpan->fqdir.low_thresh;
|
table[0].extra1 = &ieee802154_lowpan->fqdir->low_thresh;
|
||||||
table[1].data = &ieee802154_lowpan->fqdir.low_thresh;
|
table[1].data = &ieee802154_lowpan->fqdir->low_thresh;
|
||||||
table[1].extra2 = &ieee802154_lowpan->fqdir.high_thresh;
|
table[1].extra2 = &ieee802154_lowpan->fqdir->high_thresh;
|
||||||
table[2].data = &ieee802154_lowpan->fqdir.timeout;
|
table[2].data = &ieee802154_lowpan->fqdir->timeout;
|
||||||
|
|
||||||
hdr = register_net_sysctl(net, "net/ieee802154/6lowpan", table);
|
hdr = register_net_sysctl(net, "net/ieee802154/6lowpan", table);
|
||||||
if (hdr == NULL)
|
if (hdr == NULL)
|
||||||
|
@ -449,16 +449,18 @@ static int __net_init lowpan_frags_init_net(struct net *net)
|
||||||
net_ieee802154_lowpan(net);
|
net_ieee802154_lowpan(net);
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
ieee802154_lowpan->fqdir.high_thresh = IPV6_FRAG_HIGH_THRESH;
|
|
||||||
ieee802154_lowpan->fqdir.low_thresh = IPV6_FRAG_LOW_THRESH;
|
|
||||||
ieee802154_lowpan->fqdir.timeout = IPV6_FRAG_TIMEOUT;
|
|
||||||
|
|
||||||
res = fqdir_init(&ieee802154_lowpan->fqdir, &lowpan_frags, net);
|
res = fqdir_init(&ieee802154_lowpan->fqdir, &lowpan_frags, net);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
ieee802154_lowpan->fqdir->high_thresh = IPV6_FRAG_HIGH_THRESH;
|
||||||
|
ieee802154_lowpan->fqdir->low_thresh = IPV6_FRAG_LOW_THRESH;
|
||||||
|
ieee802154_lowpan->fqdir->timeout = IPV6_FRAG_TIMEOUT;
|
||||||
|
|
||||||
res = lowpan_frags_ns_sysctl_register(net);
|
res = lowpan_frags_ns_sysctl_register(net);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
fqdir_exit(&ieee802154_lowpan->fqdir);
|
fqdir_exit(ieee802154_lowpan->fqdir);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,7 +470,7 @@ static void __net_exit lowpan_frags_exit_net(struct net *net)
|
||||||
net_ieee802154_lowpan(net);
|
net_ieee802154_lowpan(net);
|
||||||
|
|
||||||
lowpan_frags_ns_sysctl_unregister(net);
|
lowpan_frags_ns_sysctl_unregister(net);
|
||||||
fqdir_exit(&ieee802154_lowpan->fqdir);
|
fqdir_exit(ieee802154_lowpan->fqdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pernet_operations lowpan_frags_ops = {
|
static struct pernet_operations lowpan_frags_ops = {
|
||||||
|
|
|
@ -150,6 +150,7 @@ void fqdir_exit(struct fqdir *fqdir)
|
||||||
fqdir->high_thresh = 0; /* prevent creation of new frags */
|
fqdir->high_thresh = 0; /* prevent creation of new frags */
|
||||||
|
|
||||||
rhashtable_free_and_destroy(&fqdir->rhashtable, inet_frags_free_cb, NULL);
|
rhashtable_free_and_destroy(&fqdir->rhashtable, inet_frags_free_cb, NULL);
|
||||||
|
kfree(fqdir);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(fqdir_exit);
|
EXPORT_SYMBOL(fqdir_exit);
|
||||||
|
|
||||||
|
|
|
@ -209,7 +209,7 @@ static struct ipq *ip_find(struct net *net, struct iphdr *iph,
|
||||||
};
|
};
|
||||||
struct inet_frag_queue *q;
|
struct inet_frag_queue *q;
|
||||||
|
|
||||||
q = inet_frag_find(&net->ipv4.fqdir, &key);
|
q = inet_frag_find(net->ipv4.fqdir, &key);
|
||||||
if (!q)
|
if (!q)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -589,12 +589,12 @@ static int __net_init ip4_frags_ns_ctl_register(struct net *net)
|
||||||
goto err_alloc;
|
goto err_alloc;
|
||||||
|
|
||||||
}
|
}
|
||||||
table[0].data = &net->ipv4.fqdir.high_thresh;
|
table[0].data = &net->ipv4.fqdir->high_thresh;
|
||||||
table[0].extra1 = &net->ipv4.fqdir.low_thresh;
|
table[0].extra1 = &net->ipv4.fqdir->low_thresh;
|
||||||
table[1].data = &net->ipv4.fqdir.low_thresh;
|
table[1].data = &net->ipv4.fqdir->low_thresh;
|
||||||
table[1].extra2 = &net->ipv4.fqdir.high_thresh;
|
table[1].extra2 = &net->ipv4.fqdir->high_thresh;
|
||||||
table[2].data = &net->ipv4.fqdir.timeout;
|
table[2].data = &net->ipv4.fqdir->timeout;
|
||||||
table[3].data = &net->ipv4.fqdir.max_dist;
|
table[3].data = &net->ipv4.fqdir->max_dist;
|
||||||
|
|
||||||
hdr = register_net_sysctl(net, "net/ipv4", table);
|
hdr = register_net_sysctl(net, "net/ipv4", table);
|
||||||
if (!hdr)
|
if (!hdr)
|
||||||
|
@ -642,6 +642,9 @@ static int __net_init ipv4_frags_init_net(struct net *net)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
res = fqdir_init(&net->ipv4.fqdir, &ip4_frags, net);
|
||||||
|
if (res < 0)
|
||||||
|
return res;
|
||||||
/* Fragment cache limits.
|
/* Fragment cache limits.
|
||||||
*
|
*
|
||||||
* The fragment memory accounting code, (tries to) account for
|
* The fragment memory accounting code, (tries to) account for
|
||||||
|
@ -656,30 +659,27 @@ static int __net_init ipv4_frags_init_net(struct net *net)
|
||||||
* we will prune down to 3MB, making room for approx 8 big 64K
|
* we will prune down to 3MB, making room for approx 8 big 64K
|
||||||
* fragments 8x128k.
|
* fragments 8x128k.
|
||||||
*/
|
*/
|
||||||
net->ipv4.fqdir.high_thresh = 4 * 1024 * 1024;
|
net->ipv4.fqdir->high_thresh = 4 * 1024 * 1024;
|
||||||
net->ipv4.fqdir.low_thresh = 3 * 1024 * 1024;
|
net->ipv4.fqdir->low_thresh = 3 * 1024 * 1024;
|
||||||
/*
|
/*
|
||||||
* Important NOTE! Fragment queue must be destroyed before MSL expires.
|
* Important NOTE! Fragment queue must be destroyed before MSL expires.
|
||||||
* RFC791 is wrong proposing to prolongate timer each fragment arrival
|
* RFC791 is wrong proposing to prolongate timer each fragment arrival
|
||||||
* by TTL.
|
* by TTL.
|
||||||
*/
|
*/
|
||||||
net->ipv4.fqdir.timeout = IP_FRAG_TIME;
|
net->ipv4.fqdir->timeout = IP_FRAG_TIME;
|
||||||
|
|
||||||
net->ipv4.fqdir.max_dist = 64;
|
net->ipv4.fqdir->max_dist = 64;
|
||||||
|
|
||||||
res = fqdir_init(&net->ipv4.fqdir, &ip4_frags, net);
|
|
||||||
if (res < 0)
|
|
||||||
return res;
|
|
||||||
res = ip4_frags_ns_ctl_register(net);
|
res = ip4_frags_ns_ctl_register(net);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
fqdir_exit(&net->ipv4.fqdir);
|
fqdir_exit(net->ipv4.fqdir);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __net_exit ipv4_frags_exit_net(struct net *net)
|
static void __net_exit ipv4_frags_exit_net(struct net *net)
|
||||||
{
|
{
|
||||||
ip4_frags_ns_ctl_unregister(net);
|
ip4_frags_ns_ctl_unregister(net);
|
||||||
fqdir_exit(&net->ipv4.fqdir);
|
fqdir_exit(net->ipv4.fqdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pernet_operations ip4_frags_ops = {
|
static struct pernet_operations ip4_frags_ops = {
|
||||||
|
|
|
@ -72,8 +72,8 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
|
||||||
seq_printf(seq, "RAW: inuse %d\n",
|
seq_printf(seq, "RAW: inuse %d\n",
|
||||||
sock_prot_inuse_get(net, &raw_prot));
|
sock_prot_inuse_get(net, &raw_prot));
|
||||||
seq_printf(seq, "FRAG: inuse %u memory %lu\n",
|
seq_printf(seq, "FRAG: inuse %u memory %lu\n",
|
||||||
atomic_read(&net->ipv4.fqdir.rhashtable.nelems),
|
atomic_read(&net->ipv4.fqdir->rhashtable.nelems),
|
||||||
frag_mem_limit(&net->ipv4.fqdir));
|
frag_mem_limit(net->ipv4.fqdir));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,12 +90,12 @@ static int nf_ct_frag6_sysctl_register(struct net *net)
|
||||||
goto err_alloc;
|
goto err_alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
table[0].data = &net->nf_frag.fqdir.timeout;
|
table[0].data = &net->nf_frag.fqdir->timeout;
|
||||||
table[1].data = &net->nf_frag.fqdir.low_thresh;
|
table[1].data = &net->nf_frag.fqdir->low_thresh;
|
||||||
table[1].extra2 = &net->nf_frag.fqdir.high_thresh;
|
table[1].extra2 = &net->nf_frag.fqdir->high_thresh;
|
||||||
table[2].data = &net->nf_frag.fqdir.high_thresh;
|
table[2].data = &net->nf_frag.fqdir->high_thresh;
|
||||||
table[2].extra1 = &net->nf_frag.fqdir.low_thresh;
|
table[2].extra1 = &net->nf_frag.fqdir->low_thresh;
|
||||||
table[2].extra2 = &init_net.nf_frag.fqdir.high_thresh;
|
table[2].extra2 = &init_net.nf_frag.fqdir->high_thresh;
|
||||||
|
|
||||||
hdr = register_net_sysctl(net, "net/netfilter", table);
|
hdr = register_net_sysctl(net, "net/netfilter", table);
|
||||||
if (hdr == NULL)
|
if (hdr == NULL)
|
||||||
|
@ -162,7 +162,7 @@ static struct frag_queue *fq_find(struct net *net, __be32 id, u32 user,
|
||||||
};
|
};
|
||||||
struct inet_frag_queue *q;
|
struct inet_frag_queue *q;
|
||||||
|
|
||||||
q = inet_frag_find(&net->nf_frag.fqdir, &key);
|
q = inet_frag_find(net->nf_frag.fqdir, &key);
|
||||||
if (!q)
|
if (!q)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -489,23 +489,24 @@ static int nf_ct_net_init(struct net *net)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
net->nf_frag.fqdir.high_thresh = IPV6_FRAG_HIGH_THRESH;
|
|
||||||
net->nf_frag.fqdir.low_thresh = IPV6_FRAG_LOW_THRESH;
|
|
||||||
net->nf_frag.fqdir.timeout = IPV6_FRAG_TIMEOUT;
|
|
||||||
|
|
||||||
res = fqdir_init(&net->nf_frag.fqdir, &nf_frags, net);
|
res = fqdir_init(&net->nf_frag.fqdir, &nf_frags, net);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
net->nf_frag.fqdir->high_thresh = IPV6_FRAG_HIGH_THRESH;
|
||||||
|
net->nf_frag.fqdir->low_thresh = IPV6_FRAG_LOW_THRESH;
|
||||||
|
net->nf_frag.fqdir->timeout = IPV6_FRAG_TIMEOUT;
|
||||||
|
|
||||||
res = nf_ct_frag6_sysctl_register(net);
|
res = nf_ct_frag6_sysctl_register(net);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
fqdir_exit(&net->nf_frag.fqdir);
|
fqdir_exit(net->nf_frag.fqdir);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nf_ct_net_exit(struct net *net)
|
static void nf_ct_net_exit(struct net *net)
|
||||||
{
|
{
|
||||||
nf_ct_frags6_sysctl_unregister(net);
|
nf_ct_frags6_sysctl_unregister(net);
|
||||||
fqdir_exit(&net->nf_frag.fqdir);
|
fqdir_exit(net->nf_frag.fqdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pernet_operations nf_ct_net_ops = {
|
static struct pernet_operations nf_ct_net_ops = {
|
||||||
|
|
|
@ -48,8 +48,8 @@ static int sockstat6_seq_show(struct seq_file *seq, void *v)
|
||||||
seq_printf(seq, "RAW6: inuse %d\n",
|
seq_printf(seq, "RAW6: inuse %d\n",
|
||||||
sock_prot_inuse_get(net, &rawv6_prot));
|
sock_prot_inuse_get(net, &rawv6_prot));
|
||||||
seq_printf(seq, "FRAG6: inuse %u memory %lu\n",
|
seq_printf(seq, "FRAG6: inuse %u memory %lu\n",
|
||||||
atomic_read(&net->ipv6.fqdir.rhashtable.nelems),
|
atomic_read(&net->ipv6.fqdir->rhashtable.nelems),
|
||||||
frag_mem_limit(&net->ipv6.fqdir));
|
frag_mem_limit(net->ipv6.fqdir));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ fq_find(struct net *net, __be32 id, const struct ipv6hdr *hdr, int iif)
|
||||||
IPV6_ADDR_LINKLOCAL)))
|
IPV6_ADDR_LINKLOCAL)))
|
||||||
key.iif = 0;
|
key.iif = 0;
|
||||||
|
|
||||||
q = inet_frag_find(&net->ipv6.fqdir, &key);
|
q = inet_frag_find(net->ipv6.fqdir, &key);
|
||||||
if (!q)
|
if (!q)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -443,11 +443,11 @@ static int __net_init ip6_frags_ns_sysctl_register(struct net *net)
|
||||||
goto err_alloc;
|
goto err_alloc;
|
||||||
|
|
||||||
}
|
}
|
||||||
table[0].data = &net->ipv6.fqdir.high_thresh;
|
table[0].data = &net->ipv6.fqdir->high_thresh;
|
||||||
table[0].extra1 = &net->ipv6.fqdir.low_thresh;
|
table[0].extra1 = &net->ipv6.fqdir->low_thresh;
|
||||||
table[1].data = &net->ipv6.fqdir.low_thresh;
|
table[1].data = &net->ipv6.fqdir->low_thresh;
|
||||||
table[1].extra2 = &net->ipv6.fqdir.high_thresh;
|
table[1].extra2 = &net->ipv6.fqdir->high_thresh;
|
||||||
table[2].data = &net->ipv6.fqdir.timeout;
|
table[2].data = &net->ipv6.fqdir->timeout;
|
||||||
|
|
||||||
hdr = register_net_sysctl(net, "net/ipv6", table);
|
hdr = register_net_sysctl(net, "net/ipv6", table);
|
||||||
if (!hdr)
|
if (!hdr)
|
||||||
|
@ -510,24 +510,24 @@ static int __net_init ipv6_frags_init_net(struct net *net)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
net->ipv6.fqdir.high_thresh = IPV6_FRAG_HIGH_THRESH;
|
|
||||||
net->ipv6.fqdir.low_thresh = IPV6_FRAG_LOW_THRESH;
|
|
||||||
net->ipv6.fqdir.timeout = IPV6_FRAG_TIMEOUT;
|
|
||||||
|
|
||||||
res = fqdir_init(&net->ipv6.fqdir, &ip6_frags, net);
|
res = fqdir_init(&net->ipv6.fqdir, &ip6_frags, net);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
net->ipv6.fqdir->high_thresh = IPV6_FRAG_HIGH_THRESH;
|
||||||
|
net->ipv6.fqdir->low_thresh = IPV6_FRAG_LOW_THRESH;
|
||||||
|
net->ipv6.fqdir->timeout = IPV6_FRAG_TIMEOUT;
|
||||||
|
|
||||||
res = ip6_frags_ns_sysctl_register(net);
|
res = ip6_frags_ns_sysctl_register(net);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
fqdir_exit(&net->ipv6.fqdir);
|
fqdir_exit(net->ipv6.fqdir);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __net_exit ipv6_frags_exit_net(struct net *net)
|
static void __net_exit ipv6_frags_exit_net(struct net *net)
|
||||||
{
|
{
|
||||||
ip6_frags_ns_sysctl_unregister(net);
|
ip6_frags_ns_sysctl_unregister(net);
|
||||||
fqdir_exit(&net->ipv6.fqdir);
|
fqdir_exit(net->ipv6.fqdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pernet_operations ip6_frags_ops = {
|
static struct pernet_operations ip6_frags_ops = {
|
||||||
|
|
Loading…
Reference in New Issue