Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6

This commit is contained in:
David S. Miller 2010-02-16 11:15:13 -08:00
commit 749f621e20
111 changed files with 2313 additions and 1836 deletions

View file

@ -29,6 +29,7 @@
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter/x_tables.h>
#include <net/netfilter/nf_log.h>
#include "../../netfilter/xt_repldata.h"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Netfilter Core Team <[email protected]>");
@ -67,6 +68,12 @@ do { \
#define inline
#endif
void *ip6t_alloc_initial_table(const struct xt_table *info)
{
return xt_alloc_initial_table(ip6t, IP6T);
}
EXPORT_SYMBOL_GPL(ip6t_alloc_initial_table);
/*
We keep a set of rules for each CPU, so we can avoid write-locking
them in the softirq when updating the counters and therefore
@ -201,7 +208,7 @@ ip6t_error(struct sk_buff *skb, const struct xt_target_param *par)
/* Performance critical - called for every packet */
static inline bool
do_match(struct ip6t_entry_match *m, const struct sk_buff *skb,
do_match(const struct ip6t_entry_match *m, const struct sk_buff *skb,
struct xt_match_param *par)
{
par->match = m->u.kernel.match;
@ -215,7 +222,7 @@ do_match(struct ip6t_entry_match *m, const struct sk_buff *skb,
}
static inline struct ip6t_entry *
get_entry(void *base, unsigned int offset)
get_entry(const void *base, unsigned int offset)
{
return (struct ip6t_entry *)(base + offset);
}
@ -229,6 +236,12 @@ static inline bool unconditional(const struct ip6t_ip6 *ipv6)
return memcmp(ipv6, &uncond, sizeof(uncond)) == 0;
}
static inline const struct ip6t_entry_target *
ip6t_get_target_c(const struct ip6t_entry *e)
{
return ip6t_get_target((struct ip6t_entry *)e);
}
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
/* This cries for unification! */
@ -264,11 +277,11 @@ static struct nf_loginfo trace_loginfo = {
/* Mildly perf critical (only if packet tracing is on) */
static inline int
get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e,
get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e,
const char *hookname, const char **chainname,
const char **comment, unsigned int *rulenum)
{
struct ip6t_standard_target *t = (void *)ip6t_get_target(s);
const struct ip6t_standard_target *t = (void *)ip6t_get_target_c(s);
if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) {
/* Head of user chain: ERROR target with chainname */
@ -294,15 +307,15 @@ get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e,
return 0;
}
static void trace_packet(struct sk_buff *skb,
static void trace_packet(const struct sk_buff *skb,
unsigned int hook,
const struct net_device *in,
const struct net_device *out,
const char *tablename,
struct xt_table_info *private,
struct ip6t_entry *e)
const struct xt_table_info *private,
const struct ip6t_entry *e)
{
void *table_base;
const void *table_base;
const struct ip6t_entry *root;
const char *hookname, *chainname, *comment;
unsigned int rulenum = 0;
@ -345,9 +358,9 @@ ip6t_do_table(struct sk_buff *skb,
/* Initializing verdict to NF_DROP keeps gcc happy. */
unsigned int verdict = NF_DROP;
const char *indev, *outdev;
void *table_base;
const void *table_base;
struct ip6t_entry *e, *back;
struct xt_table_info *private;
const struct xt_table_info *private;
struct xt_match_param mtpar;
struct xt_target_param tgpar;
@ -378,7 +391,7 @@ ip6t_do_table(struct sk_buff *skb,
back = get_entry(table_base, private->underflow[hook]);
do {
struct ip6t_entry_target *t;
const struct ip6t_entry_target *t;
IP_NF_ASSERT(e);
IP_NF_ASSERT(back);
@ -393,7 +406,7 @@ ip6t_do_table(struct sk_buff *skb,
ntohs(ipv6_hdr(skb)->payload_len) +
sizeof(struct ipv6hdr), 1);
t = ip6t_get_target(e);
t = ip6t_get_target_c(e);
IP_NF_ASSERT(t->u.kernel.target);
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
@ -475,7 +488,7 @@ ip6t_do_table(struct sk_buff *skb,
/* Figures out from what hook each rule can be called: returns 0 if
there are loops. Puts hook bitmask in comefrom. */
static int
mark_source_chains(struct xt_table_info *newinfo,
mark_source_chains(const struct xt_table_info *newinfo,
unsigned int valid_hooks, void *entry0)
{
unsigned int hook;
@ -493,8 +506,8 @@ mark_source_chains(struct xt_table_info *newinfo,
e->counters.pcnt = pos;
for (;;) {
struct ip6t_standard_target *t
= (void *)ip6t_get_target(e);
const struct ip6t_standard_target *t
= (void *)ip6t_get_target_c(e);
int visited = e->comefrom & (1 << hook);
if (e->comefrom & (1 << NF_INET_NUMHOOKS)) {
@ -585,13 +598,14 @@ mark_source_chains(struct xt_table_info *newinfo,
}
static int
cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
cleanup_match(struct ip6t_entry_match *m, struct net *net, unsigned int *i)
{
struct xt_mtdtor_param par;
if (i && (*i)-- == 0)
return 1;
par.net = net;
par.match = m->u.kernel.match;
par.matchinfo = m->data;
par.family = NFPROTO_IPV6;
@ -602,9 +616,9 @@ cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
}
static int
check_entry(struct ip6t_entry *e, const char *name)
check_entry(const struct ip6t_entry *e, const char *name)
{
struct ip6t_entry_target *t;
const struct ip6t_entry_target *t;
if (!ip6_checkentry(&e->ipv6)) {
duprintf("ip_tables: ip check failed %p %s.\n", e, name);
@ -615,7 +629,7 @@ check_entry(struct ip6t_entry *e, const char *name)
e->next_offset)
return -EINVAL;
t = ip6t_get_target(e);
t = ip6t_get_target_c(e);
if (e->target_offset + t->u.target_size > e->next_offset)
return -EINVAL;
@ -668,10 +682,11 @@ err:
return ret;
}
static int check_target(struct ip6t_entry *e, const char *name)
static int check_target(struct ip6t_entry *e, struct net *net, const char *name)
{
struct ip6t_entry_target *t = ip6t_get_target(e);
struct xt_tgchk_param par = {
.net = net,
.table = name,
.entryinfo = e,
.target = t->u.kernel.target,
@ -693,8 +708,8 @@ static int check_target(struct ip6t_entry *e, const char *name)
}
static int
find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
unsigned int *i)
find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
unsigned int size, unsigned int *i)
{
struct ip6t_entry_target *t;
struct xt_target *target;
@ -707,6 +722,7 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
return ret;
j = 0;
mtpar.net = net;
mtpar.table = name;
mtpar.entryinfo = &e->ipv6;
mtpar.hook_mask = e->comefrom;
@ -727,7 +743,7 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
}
t->u.kernel.target = target;
ret = check_target(e, name);
ret = check_target(e, net, name);
if (ret)
goto err;
@ -736,18 +752,18 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
err:
module_put(t->u.kernel.target->me);
cleanup_matches:
IP6T_MATCH_ITERATE(e, cleanup_match, &j);
IP6T_MATCH_ITERATE(e, cleanup_match, net, &j);
return ret;
}
static bool check_underflow(struct ip6t_entry *e)
static bool check_underflow(const struct ip6t_entry *e)
{
const struct ip6t_entry_target *t;
unsigned int verdict;
if (!unconditional(&e->ipv6))
return false;
t = ip6t_get_target(e);
t = ip6t_get_target_c(e);
if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
return false;
verdict = ((struct ip6t_standard_target *)t)->verdict;
@ -758,8 +774,8 @@ static bool check_underflow(struct ip6t_entry *e)
static int
check_entry_size_and_hooks(struct ip6t_entry *e,
struct xt_table_info *newinfo,
unsigned char *base,
unsigned char *limit,
const unsigned char *base,
const unsigned char *limit,
const unsigned int *hook_entries,
const unsigned int *underflows,
unsigned int valid_hooks,
@ -806,7 +822,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
}
static int
cleanup_entry(struct ip6t_entry *e, unsigned int *i)
cleanup_entry(struct ip6t_entry *e, struct net *net, unsigned int *i)
{
struct xt_tgdtor_param par;
struct ip6t_entry_target *t;
@ -815,9 +831,10 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i)
return 1;
/* Cleanup all matches */
IP6T_MATCH_ITERATE(e, cleanup_match, NULL);
IP6T_MATCH_ITERATE(e, cleanup_match, net, NULL);
t = ip6t_get_target(e);
par.net = net;
par.target = t->u.kernel.target;
par.targinfo = t->data;
par.family = NFPROTO_IPV6;
@ -830,7 +847,8 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i)
/* Checks and translates the user-supplied table segment (held in
newinfo) */
static int
translate_table(const char *name,
translate_table(struct net *net,
const char *name,
unsigned int valid_hooks,
struct xt_table_info *newinfo,
void *entry0,
@ -892,11 +910,11 @@ translate_table(const char *name,
/* Finally, each sanity check must pass */
i = 0;
ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
find_check_entry, name, size, &i);
find_check_entry, net, name, size, &i);
if (ret != 0) {
IP6T_ENTRY_ITERATE(entry0, newinfo->size,
cleanup_entry, &i);
cleanup_entry, net, &i);
return ret;
}
@ -972,11 +990,11 @@ get_counters(const struct xt_table_info *t,
local_bh_enable();
}
static struct xt_counters *alloc_counters(struct xt_table *table)
static struct xt_counters *alloc_counters(const struct xt_table *table)
{
unsigned int countersize;
struct xt_counters *counters;
struct xt_table_info *private = table->private;
const struct xt_table_info *private = table->private;
/* We need atomic snapshot of counters: rest doesn't change
(other than comefrom, which userspace doesn't care
@ -994,11 +1012,11 @@ static struct xt_counters *alloc_counters(struct xt_table *table)
static int
copy_entries_to_user(unsigned int total_size,
struct xt_table *table,
const struct xt_table *table,
void __user *userptr)
{
unsigned int off, num;
struct ip6t_entry *e;
const struct ip6t_entry *e;
struct xt_counters *counters;
const struct xt_table_info *private = table->private;
int ret = 0;
@ -1050,7 +1068,7 @@ copy_entries_to_user(unsigned int total_size,
}
}
t = ip6t_get_target(e);
t = ip6t_get_target_c(e);
if (copy_to_user(userptr + off + e->target_offset
+ offsetof(struct ip6t_entry_target,
u.user.name),
@ -1067,7 +1085,7 @@ copy_entries_to_user(unsigned int total_size,
}
#ifdef CONFIG_COMPAT
static void compat_standard_from_user(void *dst, void *src)
static void compat_standard_from_user(void *dst, const void *src)
{
int v = *(compat_int_t *)src;
@ -1076,7 +1094,7 @@ static void compat_standard_from_user(void *dst, void *src)
memcpy(dst, &v, sizeof(v));
}
static int compat_standard_to_user(void __user *dst, void *src)
static int compat_standard_to_user(void __user *dst, const void *src)
{
compat_int_t cv = *(int *)src;
@ -1086,24 +1104,24 @@ static int compat_standard_to_user(void __user *dst, void *src)
}
static inline int
compat_calc_match(struct ip6t_entry_match *m, int *size)
compat_calc_match(const struct ip6t_entry_match *m, int *size)
{
*size += xt_compat_match_offset(m->u.kernel.match);
return 0;
}
static int compat_calc_entry(struct ip6t_entry *e,
static int compat_calc_entry(const struct ip6t_entry *e,
const struct xt_table_info *info,
void *base, struct xt_table_info *newinfo)
const void *base, struct xt_table_info *newinfo)
{
struct ip6t_entry_target *t;
const struct ip6t_entry_target *t;
unsigned int entry_offset;
int off, i, ret;
off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
entry_offset = (void *)e - base;
IP6T_MATCH_ITERATE(e, compat_calc_match, &off);
t = ip6t_get_target(e);
t = ip6t_get_target_c(e);
off += xt_compat_target_offset(t->u.kernel.target);
newinfo->size -= off;
ret = xt_compat_add_offset(AF_INET6, entry_offset, off);
@ -1139,7 +1157,8 @@ static int compat_table_info(const struct xt_table_info *info,
}
#endif
static int get_info(struct net *net, void __user *user, int *len, int compat)
static int get_info(struct net *net, void __user *user,
const int *len, int compat)
{
char name[IP6T_TABLE_MAXNAMELEN];
struct xt_table *t;
@ -1199,7 +1218,8 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
}
static int
get_entries(struct net *net, struct ip6t_get_entries __user *uptr, int *len)
get_entries(struct net *net, struct ip6t_get_entries __user *uptr,
const int *len)
{
int ret;
struct ip6t_get_entries get;
@ -1291,7 +1311,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
/* Decrease module usage counts and free resource */
loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,
NULL);
net, NULL);
xt_free_table_info(oldinfo);
if (copy_to_user(counters_ptr, counters,
sizeof(struct xt_counters) * num_counters) != 0)
@ -1310,7 +1330,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
}
static int
do_replace(struct net *net, void __user *user, unsigned int len)
do_replace(struct net *net, const void __user *user, unsigned int len)
{
int ret;
struct ip6t_replace tmp;
@ -1336,7 +1356,7 @@ do_replace(struct net *net, void __user *user, unsigned int len)
goto free_newinfo;
}
ret = translate_table(tmp.name, tmp.valid_hooks,
ret = translate_table(net, tmp.name, tmp.valid_hooks,
newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
tmp.hook_entry, tmp.underflow);
if (ret != 0)
@ -1351,7 +1371,7 @@ do_replace(struct net *net, void __user *user, unsigned int len)
return 0;
free_newinfo_untrans:
IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL);
IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, net, NULL);
free_newinfo:
xt_free_table_info(newinfo);
return ret;
@ -1371,7 +1391,7 @@ add_counter_to_entry(struct ip6t_entry *e,
}
static int
do_add_counters(struct net *net, void __user *user, unsigned int len,
do_add_counters(struct net *net, const void __user *user, unsigned int len,
int compat)
{
unsigned int i, curcpu;
@ -1570,10 +1590,10 @@ static int
check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
struct xt_table_info *newinfo,
unsigned int *size,
unsigned char *base,
unsigned char *limit,
unsigned int *hook_entries,
unsigned int *underflows,
const unsigned char *base,
const unsigned char *limit,
const unsigned int *hook_entries,
const unsigned int *underflows,
unsigned int *i,
const char *name)
{
@ -1690,14 +1710,15 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
return ret;
}
static int compat_check_entry(struct ip6t_entry *e, const char *name,
unsigned int *i)
static int compat_check_entry(struct ip6t_entry *e, struct net *net,
const char *name, unsigned int *i)
{
unsigned int j;
int ret;
struct xt_mtchk_param mtpar;
j = 0;
mtpar.net = net;
mtpar.table = name;
mtpar.entryinfo = &e->ipv6;
mtpar.hook_mask = e->comefrom;
@ -1706,7 +1727,7 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name,
if (ret)
goto cleanup_matches;
ret = check_target(e, name);
ret = check_target(e, net, name);
if (ret)
goto cleanup_matches;
@ -1714,12 +1735,13 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name,
return 0;
cleanup_matches:
IP6T_MATCH_ITERATE(e, cleanup_match, &j);
IP6T_MATCH_ITERATE(e, cleanup_match, net, &j);
return ret;
}
static int
translate_compat_table(const char *name,
translate_compat_table(struct net *net,
const char *name,
unsigned int valid_hooks,
struct xt_table_info **pinfo,
void **pentry0,
@ -1808,12 +1830,12 @@ translate_compat_table(const char *name,
i = 0;
ret = IP6T_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry,
name, &i);
net, name, &i);
if (ret) {
j -= i;
COMPAT_IP6T_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i,
compat_release_entry, &j);
IP6T_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i);
IP6T_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, net, &i);
xt_free_table_info(newinfo);
return ret;
}
@ -1868,7 +1890,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
goto free_newinfo;
}
ret = translate_compat_table(tmp.name, tmp.valid_hooks,
ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
&newinfo, &loc_cpu_entry, tmp.size,
tmp.num_entries, tmp.hook_entry,
tmp.underflow);
@ -1884,7 +1906,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
return 0;
free_newinfo_untrans:
IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL);
IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, net, NULL);
free_newinfo:
xt_free_table_info(newinfo);
return ret;
@ -2121,7 +2143,7 @@ struct xt_table *ip6t_register_table(struct net *net,
loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
memcpy(loc_cpu_entry, repl->entries, repl->size);
ret = translate_table(table->name, table->valid_hooks,
ret = translate_table(net, table->name, table->valid_hooks,
newinfo, loc_cpu_entry, repl->size,
repl->num_entries,
repl->hook_entry,
@ -2142,7 +2164,7 @@ out:
return ERR_PTR(ret);
}
void ip6t_unregister_table(struct xt_table *table)
void ip6t_unregister_table(struct net *net, struct xt_table *table)
{
struct xt_table_info *private;
void *loc_cpu_entry;
@ -2152,7 +2174,7 @@ void ip6t_unregister_table(struct xt_table *table)
/* Decrease module usage counts and free resources */
loc_cpu_entry = private->entries[raw_smp_processor_id()];
IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL);
IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, net, NULL);
if (private->number > private->initial_entries)
module_put(table_owner);
xt_free_table_info(private);

View file

@ -21,99 +21,26 @@ MODULE_DESCRIPTION("ip6tables filter table");
(1 << NF_INET_FORWARD) | \
(1 << NF_INET_LOCAL_OUT))
static struct
{
struct ip6t_replace repl;
struct ip6t_standard entries[3];
struct ip6t_error term;
} initial_table __net_initdata = {
.repl = {
.name = "filter",
.valid_hooks = FILTER_VALID_HOOKS,
.num_entries = 4,
.size = sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error),
.hook_entry = {
[NF_INET_LOCAL_IN] = 0,
[NF_INET_FORWARD] = sizeof(struct ip6t_standard),
[NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2
},
.underflow = {
[NF_INET_LOCAL_IN] = 0,
[NF_INET_FORWARD] = sizeof(struct ip6t_standard),
[NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2
},
},
.entries = {
IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */
IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */
IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
},
.term = IP6T_ERROR_INIT, /* ERROR */
};
static const struct xt_table packet_filter = {
.name = "filter",
.valid_hooks = FILTER_VALID_HOOKS,
.me = THIS_MODULE,
.af = NFPROTO_IPV6,
.priority = NF_IP6_PRI_FILTER,
};
/* The work comes in here from netfilter.c. */
static unsigned int
ip6t_in_hook(unsigned int hook,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
ip6table_filter_hook(unsigned int hook, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
return ip6t_do_table(skb, hook, in, out,
dev_net(in)->ipv6.ip6table_filter);
const struct net *net = dev_net((in != NULL) ? in : out);
return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_filter);
}
static unsigned int
ip6t_local_out_hook(unsigned int hook,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
#if 0
/* root is playing with raw sockets. */
if (skb->len < sizeof(struct iphdr) ||
ip_hdrlen(skb) < sizeof(struct iphdr)) {
if (net_ratelimit())
printk("ip6t_hook: happy cracking.\n");
return NF_ACCEPT;
}
#endif
return ip6t_do_table(skb, hook, in, out,
dev_net(out)->ipv6.ip6table_filter);
}
static struct nf_hook_ops ip6t_ops[] __read_mostly = {
{
.hook = ip6t_in_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP6_PRI_FILTER,
},
{
.hook = ip6t_in_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_FORWARD,
.priority = NF_IP6_PRI_FILTER,
},
{
.hook = ip6t_local_out_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_FILTER,
},
};
static struct nf_hook_ops *filter_ops __read_mostly;
/* Default to forward because I got too much mail already. */
static int forward = NF_ACCEPT;
@ -121,9 +48,18 @@ module_param(forward, bool, 0000);
static int __net_init ip6table_filter_net_init(struct net *net)
{
/* Register table */
struct ip6t_replace *repl;
repl = ip6t_alloc_initial_table(&packet_filter);
if (repl == NULL)
return -ENOMEM;
/* Entry 1 is the FORWARD hook */
((struct ip6t_standard *)repl->entries)[1].target.verdict =
-forward - 1;
net->ipv6.ip6table_filter =
ip6t_register_table(net, &packet_filter, &initial_table.repl);
ip6t_register_table(net, &packet_filter, repl);
kfree(repl);
if (IS_ERR(net->ipv6.ip6table_filter))
return PTR_ERR(net->ipv6.ip6table_filter);
return 0;
@ -131,7 +67,7 @@ static int __net_init ip6table_filter_net_init(struct net *net)
static void __net_exit ip6table_filter_net_exit(struct net *net)
{
ip6t_unregister_table(net->ipv6.ip6table_filter);
ip6t_unregister_table(net, net->ipv6.ip6table_filter);
}
static struct pernet_operations ip6table_filter_net_ops = {
@ -148,17 +84,16 @@ static int __init ip6table_filter_init(void)
return -EINVAL;
}
/* Entry 1 is the FORWARD hook */
initial_table.entries[1].target.verdict = -forward - 1;
ret = register_pernet_subsys(&ip6table_filter_net_ops);
if (ret < 0)
return ret;
/* Register hooks */
ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
if (ret < 0)
filter_ops = xt_hook_link(&packet_filter, ip6table_filter_hook);
if (IS_ERR(filter_ops)) {
ret = PTR_ERR(filter_ops);
goto cleanup_table;
}
return ret;
@ -169,7 +104,7 @@ static int __init ip6table_filter_init(void)
static void __exit ip6table_filter_fini(void)
{
nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
xt_hook_unlink(&packet_filter, filter_ops);
unregister_pernet_subsys(&ip6table_filter_net_ops);
}

View file

@ -21,80 +21,17 @@ MODULE_DESCRIPTION("ip6tables mangle table");
(1 << NF_INET_LOCAL_OUT) | \
(1 << NF_INET_POST_ROUTING))
static const struct
{
struct ip6t_replace repl;
struct ip6t_standard entries[5];
struct ip6t_error term;
} initial_table __net_initdata = {
.repl = {
.name = "mangle",
.valid_hooks = MANGLE_VALID_HOOKS,
.num_entries = 6,
.size = sizeof(struct ip6t_standard) * 5 + sizeof(struct ip6t_error),
.hook_entry = {
[NF_INET_PRE_ROUTING] = 0,
[NF_INET_LOCAL_IN] = sizeof(struct ip6t_standard),
[NF_INET_FORWARD] = sizeof(struct ip6t_standard) * 2,
[NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3,
[NF_INET_POST_ROUTING] = sizeof(struct ip6t_standard) * 4,
},
.underflow = {
[NF_INET_PRE_ROUTING] = 0,
[NF_INET_LOCAL_IN] = sizeof(struct ip6t_standard),
[NF_INET_FORWARD] = sizeof(struct ip6t_standard) * 2,
[NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3,
[NF_INET_POST_ROUTING] = sizeof(struct ip6t_standard) * 4,
},
},
.entries = {
IP6T_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */
IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */
IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */
IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
IP6T_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */
},
.term = IP6T_ERROR_INIT, /* ERROR */
};
static const struct xt_table packet_mangler = {
.name = "mangle",
.valid_hooks = MANGLE_VALID_HOOKS,
.me = THIS_MODULE,
.af = NFPROTO_IPV6,
.priority = NF_IP6_PRI_MANGLE,
};
/* The work comes in here from netfilter.c. */
static unsigned int
ip6t_in_hook(unsigned int hook,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
ip6t_mangle_out(struct sk_buff *skb, const struct net_device *out)
{
return ip6t_do_table(skb, hook, in, out,
dev_net(in)->ipv6.ip6table_mangle);
}
static unsigned int
ip6t_post_routing_hook(unsigned int hook,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
return ip6t_do_table(skb, hook, in, out,
dev_net(out)->ipv6.ip6table_mangle);
}
static unsigned int
ip6t_local_out_hook(unsigned int hook,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
unsigned int ret;
struct in6_addr saddr, daddr;
u_int8_t hop_limit;
@ -119,7 +56,7 @@ ip6t_local_out_hook(unsigned int hook,
/* flowlabel and prio (includes version, which shouldn't change either */
flowlabel = *((u_int32_t *)ipv6_hdr(skb));
ret = ip6t_do_table(skb, hook, in, out,
ret = ip6t_do_table(skb, NF_INET_LOCAL_OUT, NULL, out,
dev_net(out)->ipv6.ip6table_mangle);
if (ret != NF_DROP && ret != NF_STOLEN &&
@ -132,49 +69,33 @@ ip6t_local_out_hook(unsigned int hook,
return ret;
}
static struct nf_hook_ops ip6t_ops[] __read_mostly = {
{
.hook = ip6t_in_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP6_PRI_MANGLE,
},
{
.hook = ip6t_in_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP6_PRI_MANGLE,
},
{
.hook = ip6t_in_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_FORWARD,
.priority = NF_IP6_PRI_MANGLE,
},
{
.hook = ip6t_local_out_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_MANGLE,
},
{
.hook = ip6t_post_routing_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP6_PRI_MANGLE,
},
};
/* The work comes in here from netfilter.c. */
static unsigned int
ip6table_mangle_hook(unsigned int hook, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
if (hook == NF_INET_LOCAL_OUT)
return ip6t_mangle_out(skb, out);
if (hook == NF_INET_POST_ROUTING)
return ip6t_do_table(skb, hook, in, out,
dev_net(out)->ipv6.ip6table_mangle);
/* INPUT/FORWARD */
return ip6t_do_table(skb, hook, in, out,
dev_net(in)->ipv6.ip6table_mangle);
}
static struct nf_hook_ops *mangle_ops __read_mostly;
static int __net_init ip6table_mangle_net_init(struct net *net)
{
/* Register table */
struct ip6t_replace *repl;
repl = ip6t_alloc_initial_table(&packet_mangler);
if (repl == NULL)
return -ENOMEM;
net->ipv6.ip6table_mangle =
ip6t_register_table(net, &packet_mangler, &initial_table.repl);
ip6t_register_table(net, &packet_mangler, repl);
kfree(repl);
if (IS_ERR(net->ipv6.ip6table_mangle))
return PTR_ERR(net->ipv6.ip6table_mangle);
return 0;
@ -182,7 +103,7 @@ static int __net_init ip6table_mangle_net_init(struct net *net)
static void __net_exit ip6table_mangle_net_exit(struct net *net)
{
ip6t_unregister_table(net->ipv6.ip6table_mangle);
ip6t_unregister_table(net, net->ipv6.ip6table_mangle);
}
static struct pernet_operations ip6table_mangle_net_ops = {
@ -199,9 +120,11 @@ static int __init ip6table_mangle_init(void)
return ret;
/* Register hooks */
ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
if (ret < 0)
mangle_ops = xt_hook_link(&packet_mangler, ip6table_mangle_hook);
if (IS_ERR(mangle_ops)) {
ret = PTR_ERR(mangle_ops);
goto cleanup_table;
}
return ret;
@ -212,7 +135,7 @@ static int __init ip6table_mangle_init(void)
static void __exit ip6table_mangle_fini(void)
{
nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
xt_hook_unlink(&packet_mangler, mangle_ops);
unregister_pernet_subsys(&ip6table_mangle_net_ops);
}

View file

@ -8,85 +8,37 @@
#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
static const struct
{
struct ip6t_replace repl;
struct ip6t_standard entries[2];
struct ip6t_error term;
} initial_table __net_initdata = {
.repl = {
.name = "raw",
.valid_hooks = RAW_VALID_HOOKS,
.num_entries = 3,
.size = sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error),
.hook_entry = {
[NF_INET_PRE_ROUTING] = 0,
[NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard)
},
.underflow = {
[NF_INET_PRE_ROUTING] = 0,
[NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard)
},
},
.entries = {
IP6T_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */
IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
},
.term = IP6T_ERROR_INIT, /* ERROR */
};
static const struct xt_table packet_raw = {
.name = "raw",
.valid_hooks = RAW_VALID_HOOKS,
.me = THIS_MODULE,
.af = NFPROTO_IPV6,
.priority = NF_IP6_PRI_FIRST,
};
/* The work comes in here from netfilter.c. */
static unsigned int
ip6t_pre_routing_hook(unsigned int hook,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
ip6table_raw_hook(unsigned int hook, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
return ip6t_do_table(skb, hook, in, out,
dev_net(in)->ipv6.ip6table_raw);
const struct net *net = dev_net((in != NULL) ? in : out);
return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_raw);
}
static unsigned int
ip6t_local_out_hook(unsigned int hook,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
return ip6t_do_table(skb, hook, in, out,
dev_net(out)->ipv6.ip6table_raw);
}
static struct nf_hook_ops ip6t_ops[] __read_mostly = {
{
.hook = ip6t_pre_routing_hook,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP6_PRI_FIRST,
.owner = THIS_MODULE,
},
{
.hook = ip6t_local_out_hook,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_FIRST,
.owner = THIS_MODULE,
},
};
static struct nf_hook_ops *rawtable_ops __read_mostly;
static int __net_init ip6table_raw_net_init(struct net *net)
{
/* Register table */
struct ip6t_replace *repl;
repl = ip6t_alloc_initial_table(&packet_raw);
if (repl == NULL)
return -ENOMEM;
net->ipv6.ip6table_raw =
ip6t_register_table(net, &packet_raw, &initial_table.repl);
ip6t_register_table(net, &packet_raw, repl);
kfree(repl);
if (IS_ERR(net->ipv6.ip6table_raw))
return PTR_ERR(net->ipv6.ip6table_raw);
return 0;
@ -94,7 +46,7 @@ static int __net_init ip6table_raw_net_init(struct net *net)
static void __net_exit ip6table_raw_net_exit(struct net *net)
{
ip6t_unregister_table(net->ipv6.ip6table_raw);
ip6t_unregister_table(net, net->ipv6.ip6table_raw);
}
static struct pernet_operations ip6table_raw_net_ops = {
@ -111,9 +63,11 @@ static int __init ip6table_raw_init(void)
return ret;
/* Register hooks */
ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
if (ret < 0)
rawtable_ops = xt_hook_link(&packet_raw, ip6table_raw_hook);
if (IS_ERR(rawtable_ops)) {
ret = PTR_ERR(rawtable_ops);
goto cleanup_table;
}
return ret;
@ -124,7 +78,7 @@ static int __init ip6table_raw_init(void)
static void __exit ip6table_raw_fini(void)
{
nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
xt_hook_unlink(&packet_raw, rawtable_ops);
unregister_pernet_subsys(&ip6table_raw_net_ops);
}

View file

@ -26,106 +26,37 @@ MODULE_DESCRIPTION("ip6tables security table, for MAC rules");
(1 << NF_INET_FORWARD) | \
(1 << NF_INET_LOCAL_OUT)
static const struct
{
struct ip6t_replace repl;
struct ip6t_standard entries[3];
struct ip6t_error term;
} initial_table __net_initdata = {
.repl = {
.name = "security",
.valid_hooks = SECURITY_VALID_HOOKS,
.num_entries = 4,
.size = sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error),
.hook_entry = {
[NF_INET_LOCAL_IN] = 0,
[NF_INET_FORWARD] = sizeof(struct ip6t_standard),
[NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2,
},
.underflow = {
[NF_INET_LOCAL_IN] = 0,
[NF_INET_FORWARD] = sizeof(struct ip6t_standard),
[NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2,
},
},
.entries = {
IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */
IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */
IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
},
.term = IP6T_ERROR_INIT, /* ERROR */
};
static const struct xt_table security_table = {
.name = "security",
.valid_hooks = SECURITY_VALID_HOOKS,
.me = THIS_MODULE,
.af = NFPROTO_IPV6,
.priority = NF_IP6_PRI_SECURITY,
};
static unsigned int
ip6t_local_in_hook(unsigned int hook,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
ip6table_security_hook(unsigned int hook, struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
return ip6t_do_table(skb, hook, in, out,
dev_net(in)->ipv6.ip6table_security);
const struct net *net = dev_net((in != NULL) ? in : out);
return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_security);
}
static unsigned int
ip6t_forward_hook(unsigned int hook,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
return ip6t_do_table(skb, hook, in, out,
dev_net(in)->ipv6.ip6table_security);
}
static unsigned int
ip6t_local_out_hook(unsigned int hook,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
/* TBD: handle short packets via raw socket */
return ip6t_do_table(skb, hook, in, out,
dev_net(out)->ipv6.ip6table_security);
}
static struct nf_hook_ops ip6t_ops[] __read_mostly = {
{
.hook = ip6t_local_in_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP6_PRI_SECURITY,
},
{
.hook = ip6t_forward_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_FORWARD,
.priority = NF_IP6_PRI_SECURITY,
},
{
.hook = ip6t_local_out_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_SECURITY,
},
};
static struct nf_hook_ops *sectbl_ops __read_mostly;
static int __net_init ip6table_security_net_init(struct net *net)
{
net->ipv6.ip6table_security =
ip6t_register_table(net, &security_table, &initial_table.repl);
struct ip6t_replace *repl;
repl = ip6t_alloc_initial_table(&security_table);
if (repl == NULL)
return -ENOMEM;
net->ipv6.ip6table_security =
ip6t_register_table(net, &security_table, repl);
kfree(repl);
if (IS_ERR(net->ipv6.ip6table_security))
return PTR_ERR(net->ipv6.ip6table_security);
@ -134,7 +65,7 @@ static int __net_init ip6table_security_net_init(struct net *net)
static void __net_exit ip6table_security_net_exit(struct net *net)
{
ip6t_unregister_table(net->ipv6.ip6table_security);
ip6t_unregister_table(net, net->ipv6.ip6table_security);
}
static struct pernet_operations ip6table_security_net_ops = {
@ -150,9 +81,11 @@ static int __init ip6table_security_init(void)
if (ret < 0)
return ret;
ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
if (ret < 0)
sectbl_ops = xt_hook_link(&security_table, ip6table_security_hook);
if (IS_ERR(sectbl_ops)) {
ret = PTR_ERR(sectbl_ops);
goto cleanup_table;
}
return ret;
@ -163,7 +96,7 @@ cleanup_table:
static void __exit ip6table_security_fini(void)
{
nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
xt_hook_unlink(&security_table, sectbl_ops);
unregister_pernet_subsys(&ip6table_security_net_ops);
}

View file

@ -27,6 +27,7 @@
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_l3proto.h>
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_zones.h>
#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
#include <net/netfilter/nf_log.h>
@ -191,15 +192,20 @@ out:
static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
struct sk_buff *skb)
{
u16 zone = NF_CT_DEFAULT_ZONE;
if (skb->nfct)
zone = nf_ct_zone((struct nf_conn *)skb->nfct);
#ifdef CONFIG_BRIDGE_NETFILTER
if (skb->nf_bridge &&
skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
return IP6_DEFRAG_CONNTRACK_BRIDGE_IN;
return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
#endif
if (hooknum == NF_INET_PRE_ROUTING)
return IP6_DEFRAG_CONNTRACK_IN;
return IP6_DEFRAG_CONNTRACK_IN + zone;
else
return IP6_DEFRAG_CONNTRACK_OUT;
return IP6_DEFRAG_CONNTRACK_OUT + zone;
}
@ -212,7 +218,7 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
struct sk_buff *reasm;
/* Previously seen (loopback)? */
if (skb->nfct)
if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct))
return NF_ACCEPT;
reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));

View file

@ -23,6 +23,7 @@
#include <net/netfilter/nf_conntrack_tuple.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_zones.h>
#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
#include <net/netfilter/nf_log.h>
@ -128,7 +129,7 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,
}
static int
icmpv6_error_message(struct net *net,
icmpv6_error_message(struct net *net, struct nf_conn *tmpl,
struct sk_buff *skb,
unsigned int icmp6off,
enum ip_conntrack_info *ctinfo,
@ -137,6 +138,7 @@ icmpv6_error_message(struct net *net,
struct nf_conntrack_tuple intuple, origtuple;
const struct nf_conntrack_tuple_hash *h;
const struct nf_conntrack_l4proto *inproto;
u16 zone = tmpl ? nf_ct_zone(tmpl) : NF_CT_DEFAULT_ZONE;
NF_CT_ASSERT(skb->nfct == NULL);
@ -163,7 +165,7 @@ icmpv6_error_message(struct net *net,
*ctinfo = IP_CT_RELATED;
h = nf_conntrack_find_get(net, &intuple);
h = nf_conntrack_find_get(net, zone, &intuple);
if (!h) {
pr_debug("icmpv6_error: no match\n");
return -NF_ACCEPT;
@ -179,7 +181,8 @@ icmpv6_error_message(struct net *net,
}
static int
icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
icmpv6_error(struct net *net, struct nf_conn *tmpl,
struct sk_buff *skb, unsigned int dataoff,
enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum)
{
const struct icmp6hdr *icmp6h;
@ -215,7 +218,7 @@ icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
if (icmp6h->icmp6_type >= 128)
return NF_ACCEPT;
return icmpv6_error_message(net, skb, dataoff, ctinfo, hooknum);
return icmpv6_error_message(net, tmpl, skb, dataoff, ctinfo, hooknum);
}
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)

View file

@ -45,9 +45,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#define NF_CT_FRAG6_HIGH_THRESH 262144 /* == 256*1024 */
#define NF_CT_FRAG6_LOW_THRESH 196608 /* == 192*1024 */
#define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT
struct nf_ct_frag6_skb_cb
{
@ -670,8 +667,8 @@ int nf_ct_frag6_init(void)
nf_frags.frag_expire = nf_ct_frag6_expire;
nf_frags.secret_interval = 10 * 60 * HZ;
nf_init_frags.timeout = IPV6_FRAG_TIMEOUT;
nf_init_frags.high_thresh = 256 * 1024;
nf_init_frags.low_thresh = 192 * 1024;
nf_init_frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
nf_init_frags.low_thresh = IPV6_FRAG_LOW_THRESH;
inet_frags_init_net(&nf_init_frags);
inet_frags_init(&nf_frags);

View file

@ -742,8 +742,8 @@ static inline void ip6_frags_sysctl_unregister(void)
static int __net_init ipv6_frags_init_net(struct net *net)
{
net->ipv6.frags.high_thresh = 256 * 1024;
net->ipv6.frags.low_thresh = 192 * 1024;
net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT;
inet_frags_init_net(&net->ipv6.frags);