forked from Minki/linux
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Pablo Neira Ayuso says: ==================== Netfilter updates for net-next The following patchset contains Netfilter updates for net-next: 1) Use nfnetlink_unicast() instead of netlink_unicast() in nft_compat. 2) Remove call to nf_ct_l4proto_find() in flowtable offload timeout fixup. 3) CLUSTERIP registers ARP hook on demand, from Florian. 4) Use clusterip_net to store pernet warning, also from Florian. 5) Remove struct netns_xt, from Florian Westphal. 6) Enable ebtables hooks in initns on demand, from Florian. 7) Allow to filter conntrack netlink dump per status bits, from Florian Westphal. 8) Register x_tables hooks in initns on demand, from Florian. 9) Remove queue_handler from per-netns structure, again from Florian. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
6f45933dfe
@ -238,9 +238,6 @@ struct xt_table {
|
||||
u_int8_t af; /* address/protocol family */
|
||||
int priority; /* hook order */
|
||||
|
||||
/* called when table is needed in the given netns */
|
||||
int (*table_init)(struct net *net);
|
||||
|
||||
/* A unique name... */
|
||||
const char name[XT_TABLE_MAXNAMELEN];
|
||||
};
|
||||
@ -452,6 +449,9 @@ xt_get_per_cpu_counter(struct xt_counters *cnt, unsigned int cpu)
|
||||
|
||||
struct nf_hook_ops *xt_hook_ops_alloc(const struct xt_table *, nf_hookfn *);
|
||||
|
||||
int xt_register_template(const struct xt_table *t, int(*table_init)(struct net *net));
|
||||
void xt_unregister_template(const struct xt_table *t);
|
||||
|
||||
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||
#include <net/compat.h>
|
||||
|
||||
|
@ -127,4 +127,6 @@ static inline bool ebt_invalid_target(int target)
|
||||
return (target < -NUM_STANDARD_TARGETS || target >= 0);
|
||||
}
|
||||
|
||||
int ebt_register_template(const struct ebt_table *t, int(*table_init)(struct net *net));
|
||||
void ebt_unregister_template(const struct ebt_table *t);
|
||||
#endif
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include <net/netns/ieee802154_6lowpan.h>
|
||||
#include <net/netns/sctp.h>
|
||||
#include <net/netns/netfilter.h>
|
||||
#include <net/netns/x_tables.h>
|
||||
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
||||
#include <net/netns/conntrack.h>
|
||||
#endif
|
||||
@ -133,7 +132,6 @@ struct net {
|
||||
#endif
|
||||
#ifdef CONFIG_NETFILTER
|
||||
struct netns_nf nf;
|
||||
struct netns_xt xt;
|
||||
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
||||
struct netns_ct ct;
|
||||
#endif
|
||||
|
@ -33,8 +33,8 @@ struct nf_queue_handler {
|
||||
void (*nf_hook_drop)(struct net *net);
|
||||
};
|
||||
|
||||
void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh);
|
||||
void nf_unregister_queue_handler(struct net *net);
|
||||
void nf_register_queue_handler(const struct nf_queue_handler *qh);
|
||||
void nf_unregister_queue_handler(void);
|
||||
void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
|
||||
|
||||
void nf_queue_entry_get_refs(struct nf_queue_entry *entry);
|
||||
|
@ -12,7 +12,6 @@ struct netns_nf {
|
||||
#if defined CONFIG_PROC_FS
|
||||
struct proc_dir_entry *proc_netfilter;
|
||||
#endif
|
||||
const struct nf_queue_handler __rcu *queue_handler;
|
||||
const struct nf_logger __rcu *nf_loggers[NFPROTO_NUMPROTO];
|
||||
#ifdef CONFIG_SYSCTL
|
||||
struct ctl_table_header *nf_log_dir_header;
|
||||
|
@ -1,12 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __NETNS_X_TABLES_H
|
||||
#define __NETNS_X_TABLES_H
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/netfilter_defs.h>
|
||||
|
||||
struct netns_xt {
|
||||
bool notrack_deprecated_warning;
|
||||
bool clusterip_deprecated_warning;
|
||||
};
|
||||
#endif
|
@ -56,6 +56,7 @@ enum ctattr_type {
|
||||
CTA_LABELS_MASK,
|
||||
CTA_SYNPROXY,
|
||||
CTA_FILTER,
|
||||
CTA_STATUS_MASK,
|
||||
__CTA_MAX
|
||||
};
|
||||
#define CTA_MAX (__CTA_MAX - 1)
|
||||
|
@ -98,7 +98,7 @@ static const struct nf_hook_ops ebt_ops_broute = {
|
||||
.priority = NF_BR_PRI_FIRST,
|
||||
};
|
||||
|
||||
static int __net_init broute_net_init(struct net *net)
|
||||
static int broute_table_init(struct net *net)
|
||||
{
|
||||
return ebt_register_table(net, &broute_table, &ebt_ops_broute);
|
||||
}
|
||||
@ -114,19 +114,30 @@ static void __net_exit broute_net_exit(struct net *net)
|
||||
}
|
||||
|
||||
static struct pernet_operations broute_net_ops = {
|
||||
.init = broute_net_init,
|
||||
.exit = broute_net_exit,
|
||||
.pre_exit = broute_net_pre_exit,
|
||||
};
|
||||
|
||||
static int __init ebtable_broute_init(void)
|
||||
{
|
||||
return register_pernet_subsys(&broute_net_ops);
|
||||
int ret = ebt_register_template(&broute_table, broute_table_init);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = register_pernet_subsys(&broute_net_ops);
|
||||
if (ret) {
|
||||
ebt_unregister_template(&broute_table);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit ebtable_broute_fini(void)
|
||||
{
|
||||
unregister_pernet_subsys(&broute_net_ops);
|
||||
ebt_unregister_template(&broute_table);
|
||||
}
|
||||
|
||||
module_init(ebtable_broute_init);
|
||||
|
@ -86,7 +86,7 @@ static const struct nf_hook_ops ebt_ops_filter[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __net_init frame_filter_net_init(struct net *net)
|
||||
static int frame_filter_table_init(struct net *net)
|
||||
{
|
||||
return ebt_register_table(net, &frame_filter, ebt_ops_filter);
|
||||
}
|
||||
@ -102,19 +102,30 @@ static void __net_exit frame_filter_net_exit(struct net *net)
|
||||
}
|
||||
|
||||
static struct pernet_operations frame_filter_net_ops = {
|
||||
.init = frame_filter_net_init,
|
||||
.exit = frame_filter_net_exit,
|
||||
.pre_exit = frame_filter_net_pre_exit,
|
||||
};
|
||||
|
||||
static int __init ebtable_filter_init(void)
|
||||
{
|
||||
return register_pernet_subsys(&frame_filter_net_ops);
|
||||
int ret = ebt_register_template(&frame_filter, frame_filter_table_init);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = register_pernet_subsys(&frame_filter_net_ops);
|
||||
if (ret) {
|
||||
ebt_unregister_template(&frame_filter);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit ebtable_filter_fini(void)
|
||||
{
|
||||
unregister_pernet_subsys(&frame_filter_net_ops);
|
||||
ebt_unregister_template(&frame_filter);
|
||||
}
|
||||
|
||||
module_init(ebtable_filter_init);
|
||||
|
@ -85,7 +85,7 @@ static const struct nf_hook_ops ebt_ops_nat[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __net_init frame_nat_net_init(struct net *net)
|
||||
static int frame_nat_table_init(struct net *net)
|
||||
{
|
||||
return ebt_register_table(net, &frame_nat, ebt_ops_nat);
|
||||
}
|
||||
@ -101,19 +101,30 @@ static void __net_exit frame_nat_net_exit(struct net *net)
|
||||
}
|
||||
|
||||
static struct pernet_operations frame_nat_net_ops = {
|
||||
.init = frame_nat_net_init,
|
||||
.exit = frame_nat_net_exit,
|
||||
.pre_exit = frame_nat_net_pre_exit,
|
||||
};
|
||||
|
||||
static int __init ebtable_nat_init(void)
|
||||
{
|
||||
return register_pernet_subsys(&frame_nat_net_ops);
|
||||
int ret = ebt_register_template(&frame_nat, frame_nat_table_init);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = register_pernet_subsys(&frame_nat_net_ops);
|
||||
if (ret) {
|
||||
ebt_unregister_template(&frame_nat);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit ebtable_nat_fini(void)
|
||||
{
|
||||
unregister_pernet_subsys(&frame_nat_net_ops);
|
||||
ebt_unregister_template(&frame_nat);
|
||||
}
|
||||
|
||||
module_init(ebtable_nat_init);
|
||||
|
@ -44,7 +44,16 @@ struct ebt_pernet {
|
||||
struct list_head tables;
|
||||
};
|
||||
|
||||
struct ebt_template {
|
||||
struct list_head list;
|
||||
char name[EBT_TABLE_MAXNAMELEN];
|
||||
struct module *owner;
|
||||
/* called when table is needed in the given netns */
|
||||
int (*table_init)(struct net *net);
|
||||
};
|
||||
|
||||
static unsigned int ebt_pernet_id __read_mostly;
|
||||
static LIST_HEAD(template_tables);
|
||||
static DEFINE_MUTEX(ebt_mutex);
|
||||
|
||||
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||
@ -309,30 +318,57 @@ letscontinue:
|
||||
|
||||
/* If it succeeds, returns element and locks mutex */
|
||||
static inline void *
|
||||
find_inlist_lock_noload(struct list_head *head, const char *name, int *error,
|
||||
find_inlist_lock_noload(struct net *net, const char *name, int *error,
|
||||
struct mutex *mutex)
|
||||
{
|
||||
struct {
|
||||
struct list_head list;
|
||||
char name[EBT_FUNCTION_MAXNAMELEN];
|
||||
} *e;
|
||||
struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
|
||||
struct ebt_template *tmpl;
|
||||
struct ebt_table *table;
|
||||
|
||||
mutex_lock(mutex);
|
||||
list_for_each_entry(e, head, list) {
|
||||
if (strcmp(e->name, name) == 0)
|
||||
return e;
|
||||
list_for_each_entry(table, &ebt_net->tables, list) {
|
||||
if (strcmp(table->name, name) == 0)
|
||||
return table;
|
||||
}
|
||||
|
||||
list_for_each_entry(tmpl, &template_tables, list) {
|
||||
if (strcmp(name, tmpl->name) == 0) {
|
||||
struct module *owner = tmpl->owner;
|
||||
|
||||
if (!try_module_get(owner))
|
||||
goto out;
|
||||
|
||||
mutex_unlock(mutex);
|
||||
|
||||
*error = tmpl->table_init(net);
|
||||
if (*error) {
|
||||
module_put(owner);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mutex_lock(mutex);
|
||||
module_put(owner);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry(table, &ebt_net->tables, list) {
|
||||
if (strcmp(table->name, name) == 0)
|
||||
return table;
|
||||
}
|
||||
|
||||
out:
|
||||
*error = -ENOENT;
|
||||
mutex_unlock(mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
find_inlist_lock(struct list_head *head, const char *name, const char *prefix,
|
||||
find_inlist_lock(struct net *net, const char *name, const char *prefix,
|
||||
int *error, struct mutex *mutex)
|
||||
{
|
||||
return try_then_request_module(
|
||||
find_inlist_lock_noload(head, name, error, mutex),
|
||||
find_inlist_lock_noload(net, name, error, mutex),
|
||||
"%s%s", prefix, name);
|
||||
}
|
||||
|
||||
@ -340,10 +376,7 @@ static inline struct ebt_table *
|
||||
find_table_lock(struct net *net, const char *name, int *error,
|
||||
struct mutex *mutex)
|
||||
{
|
||||
struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
|
||||
|
||||
return find_inlist_lock(&ebt_net->tables, name,
|
||||
"ebtable_", error, mutex);
|
||||
return find_inlist_lock(net, name, "ebtable_", error, mutex);
|
||||
}
|
||||
|
||||
static inline void ebt_free_table_info(struct ebt_table_info *info)
|
||||
@ -1258,6 +1291,54 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ebt_register_template(const struct ebt_table *t, int (*table_init)(struct net *net))
|
||||
{
|
||||
struct ebt_template *tmpl;
|
||||
|
||||
mutex_lock(&ebt_mutex);
|
||||
list_for_each_entry(tmpl, &template_tables, list) {
|
||||
if (WARN_ON_ONCE(strcmp(t->name, tmpl->name) == 0)) {
|
||||
mutex_unlock(&ebt_mutex);
|
||||
return -EEXIST;
|
||||
}
|
||||
}
|
||||
|
||||
tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL);
|
||||
if (!tmpl) {
|
||||
mutex_unlock(&ebt_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
tmpl->table_init = table_init;
|
||||
strscpy(tmpl->name, t->name, sizeof(tmpl->name));
|
||||
tmpl->owner = t->me;
|
||||
list_add(&tmpl->list, &template_tables);
|
||||
|
||||
mutex_unlock(&ebt_mutex);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ebt_register_template);
|
||||
|
||||
void ebt_unregister_template(const struct ebt_table *t)
|
||||
{
|
||||
struct ebt_template *tmpl;
|
||||
|
||||
mutex_lock(&ebt_mutex);
|
||||
list_for_each_entry(tmpl, &template_tables, list) {
|
||||
if (strcmp(t->name, tmpl->name))
|
||||
continue;
|
||||
|
||||
list_del(&tmpl->list);
|
||||
mutex_unlock(&ebt_mutex);
|
||||
kfree(tmpl);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_unlock(&ebt_mutex);
|
||||
WARN_ON_ONCE(1);
|
||||
}
|
||||
EXPORT_SYMBOL(ebt_unregister_template);
|
||||
|
||||
static struct ebt_table *__ebt_find_table(struct net *net, const char *name)
|
||||
{
|
||||
struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
|
||||
|
@ -18,15 +18,12 @@ MODULE_DESCRIPTION("arptables filter table");
|
||||
#define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT) | \
|
||||
(1 << NF_ARP_FORWARD))
|
||||
|
||||
static int __net_init arptable_filter_table_init(struct net *net);
|
||||
|
||||
static const struct xt_table packet_filter = {
|
||||
.name = "filter",
|
||||
.valid_hooks = FILTER_VALID_HOOKS,
|
||||
.me = THIS_MODULE,
|
||||
.af = NFPROTO_ARP,
|
||||
.priority = NF_IP_PRI_FILTER,
|
||||
.table_init = arptable_filter_table_init,
|
||||
};
|
||||
|
||||
/* The work comes in here from netfilter.c */
|
||||
@ -39,7 +36,7 @@ arptable_filter_hook(void *priv, struct sk_buff *skb,
|
||||
|
||||
static struct nf_hook_ops *arpfilter_ops __read_mostly;
|
||||
|
||||
static int __net_init arptable_filter_table_init(struct net *net)
|
||||
static int arptable_filter_table_init(struct net *net)
|
||||
{
|
||||
struct arpt_replace *repl;
|
||||
int err;
|
||||
@ -69,30 +66,32 @@ static struct pernet_operations arptable_filter_net_ops = {
|
||||
|
||||
static int __init arptable_filter_init(void)
|
||||
{
|
||||
int ret;
|
||||
int ret = xt_register_template(&packet_filter,
|
||||
arptable_filter_table_init);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
arpfilter_ops = xt_hook_ops_alloc(&packet_filter, arptable_filter_hook);
|
||||
if (IS_ERR(arpfilter_ops))
|
||||
if (IS_ERR(arpfilter_ops)) {
|
||||
xt_unregister_template(&packet_filter);
|
||||
return PTR_ERR(arpfilter_ops);
|
||||
}
|
||||
|
||||
ret = register_pernet_subsys(&arptable_filter_net_ops);
|
||||
if (ret < 0) {
|
||||
xt_unregister_template(&packet_filter);
|
||||
kfree(arpfilter_ops);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = arptable_filter_table_init(&init_net);
|
||||
if (ret) {
|
||||
unregister_pernet_subsys(&arptable_filter_net_ops);
|
||||
kfree(arpfilter_ops);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit arptable_filter_fini(void)
|
||||
{
|
||||
unregister_pernet_subsys(&arptable_filter_net_ops);
|
||||
xt_unregister_template(&packet_filter);
|
||||
kfree(arpfilter_ops);
|
||||
}
|
||||
|
||||
|
@ -66,11 +66,22 @@ struct clusterip_net {
|
||||
/* lock protects the configs list */
|
||||
spinlock_t lock;
|
||||
|
||||
bool clusterip_deprecated_warning;
|
||||
#ifdef CONFIG_PROC_FS
|
||||
struct proc_dir_entry *procdir;
|
||||
/* mutex protects the config->pde*/
|
||||
struct mutex mutex;
|
||||
#endif
|
||||
unsigned int hook_users;
|
||||
};
|
||||
|
||||
static unsigned int clusterip_arp_mangle(void *priv, struct sk_buff *skb, const struct nf_hook_state *state);
|
||||
|
||||
static const struct nf_hook_ops cip_arp_ops = {
|
||||
.hook = clusterip_arp_mangle,
|
||||
.pf = NFPROTO_ARP,
|
||||
.hooknum = NF_ARP_OUT,
|
||||
.priority = -1
|
||||
};
|
||||
|
||||
static unsigned int clusterip_net_id __read_mostly;
|
||||
@ -458,6 +469,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
static int clusterip_tg_check(const struct xt_tgchk_param *par)
|
||||
{
|
||||
struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
|
||||
struct clusterip_net *cn = clusterip_pernet(par->net);
|
||||
const struct ipt_entry *e = par->entryinfo;
|
||||
struct clusterip_config *config;
|
||||
int ret, i;
|
||||
@ -467,6 +479,9 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (cn->hook_users == UINT_MAX)
|
||||
return -EOVERFLOW;
|
||||
|
||||
if (cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP &&
|
||||
cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT &&
|
||||
cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT_DPT) {
|
||||
@ -517,10 +532,23 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!par->net->xt.clusterip_deprecated_warning) {
|
||||
if (cn->hook_users == 0) {
|
||||
ret = nf_register_net_hook(par->net, &cip_arp_ops);
|
||||
|
||||
if (ret < 0) {
|
||||
clusterip_config_entry_put(config);
|
||||
clusterip_config_put(config);
|
||||
nf_ct_netns_put(par->net, par->family);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
cn->hook_users++;
|
||||
|
||||
if (!cn->clusterip_deprecated_warning) {
|
||||
pr_info("ipt_CLUSTERIP is deprecated and it will removed soon, "
|
||||
"use xt_cluster instead\n");
|
||||
par->net->xt.clusterip_deprecated_warning = true;
|
||||
cn->clusterip_deprecated_warning = true;
|
||||
}
|
||||
|
||||
cipinfo->config = config;
|
||||
@ -531,6 +559,7 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
|
||||
static void clusterip_tg_destroy(const struct xt_tgdtor_param *par)
|
||||
{
|
||||
const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
|
||||
struct clusterip_net *cn = clusterip_pernet(par->net);
|
||||
|
||||
/* if no more entries are referencing the config, remove it
|
||||
* from the list and destroy the proc entry */
|
||||
@ -539,6 +568,10 @@ static void clusterip_tg_destroy(const struct xt_tgdtor_param *par)
|
||||
clusterip_config_put(cipinfo->config);
|
||||
|
||||
nf_ct_netns_put(par->net, par->family);
|
||||
cn->hook_users--;
|
||||
|
||||
if (cn->hook_users == 0)
|
||||
nf_unregister_net_hook(par->net, &cip_arp_ops);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||
@ -602,9 +635,8 @@ static void arp_print(struct arp_payload *payload)
|
||||
#endif
|
||||
|
||||
static unsigned int
|
||||
arp_mangle(void *priv,
|
||||
struct sk_buff *skb,
|
||||
const struct nf_hook_state *state)
|
||||
clusterip_arp_mangle(void *priv, struct sk_buff *skb,
|
||||
const struct nf_hook_state *state)
|
||||
{
|
||||
struct arphdr *arp = arp_hdr(skb);
|
||||
struct arp_payload *payload;
|
||||
@ -654,13 +686,6 @@ arp_mangle(void *priv,
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
static const struct nf_hook_ops cip_arp_ops = {
|
||||
.hook = arp_mangle,
|
||||
.pf = NFPROTO_ARP,
|
||||
.hooknum = NF_ARP_OUT,
|
||||
.priority = -1
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* PROC DIR HANDLING
|
||||
***********************************************************************/
|
||||
@ -817,20 +842,14 @@ static const struct proc_ops clusterip_proc_ops = {
|
||||
static int clusterip_net_init(struct net *net)
|
||||
{
|
||||
struct clusterip_net *cn = clusterip_pernet(net);
|
||||
int ret;
|
||||
|
||||
INIT_LIST_HEAD(&cn->configs);
|
||||
|
||||
spin_lock_init(&cn->lock);
|
||||
|
||||
ret = nf_register_net_hook(net, &cip_arp_ops);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
cn->procdir = proc_mkdir("ipt_CLUSTERIP", net->proc_net);
|
||||
if (!cn->procdir) {
|
||||
nf_unregister_net_hook(net, &cip_arp_ops);
|
||||
pr_err("Unable to proc dir entry\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -850,7 +869,6 @@ static void clusterip_net_exit(struct net *net)
|
||||
cn->procdir = NULL;
|
||||
mutex_unlock(&cn->mutex);
|
||||
#endif
|
||||
nf_unregister_net_hook(net, &cip_arp_ops);
|
||||
}
|
||||
|
||||
static struct pernet_operations clusterip_net_ops = {
|
||||
|
@ -19,7 +19,6 @@ MODULE_DESCRIPTION("iptables filter table");
|
||||
#define FILTER_VALID_HOOKS ((1 << NF_INET_LOCAL_IN) | \
|
||||
(1 << NF_INET_FORWARD) | \
|
||||
(1 << NF_INET_LOCAL_OUT))
|
||||
static int __net_init iptable_filter_table_init(struct net *net);
|
||||
|
||||
static const struct xt_table packet_filter = {
|
||||
.name = "filter",
|
||||
@ -27,7 +26,6 @@ static const struct xt_table packet_filter = {
|
||||
.me = THIS_MODULE,
|
||||
.af = NFPROTO_IPV4,
|
||||
.priority = NF_IP_PRI_FILTER,
|
||||
.table_init = iptable_filter_table_init,
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
@ -43,7 +41,7 @@ static struct nf_hook_ops *filter_ops __read_mostly;
|
||||
static bool forward __read_mostly = true;
|
||||
module_param(forward, bool, 0000);
|
||||
|
||||
static int __net_init iptable_filter_table_init(struct net *net)
|
||||
static int iptable_filter_table_init(struct net *net)
|
||||
{
|
||||
struct ipt_replace *repl;
|
||||
int err;
|
||||
@ -62,7 +60,7 @@ static int __net_init iptable_filter_table_init(struct net *net)
|
||||
|
||||
static int __net_init iptable_filter_net_init(struct net *net)
|
||||
{
|
||||
if (net == &init_net || !forward)
|
||||
if (!forward)
|
||||
return iptable_filter_table_init(net);
|
||||
|
||||
return 0;
|
||||
@ -86,22 +84,32 @@ static struct pernet_operations iptable_filter_net_ops = {
|
||||
|
||||
static int __init iptable_filter_init(void)
|
||||
{
|
||||
int ret;
|
||||
int ret = xt_register_template(&packet_filter,
|
||||
iptable_filter_table_init);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
filter_ops = xt_hook_ops_alloc(&packet_filter, iptable_filter_hook);
|
||||
if (IS_ERR(filter_ops))
|
||||
if (IS_ERR(filter_ops)) {
|
||||
xt_unregister_template(&packet_filter);
|
||||
return PTR_ERR(filter_ops);
|
||||
}
|
||||
|
||||
ret = register_pernet_subsys(&iptable_filter_net_ops);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
xt_unregister_template(&packet_filter);
|
||||
kfree(filter_ops);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit iptable_filter_fini(void)
|
||||
{
|
||||
unregister_pernet_subsys(&iptable_filter_net_ops);
|
||||
xt_unregister_template(&packet_filter);
|
||||
kfree(filter_ops);
|
||||
}
|
||||
|
||||
|
@ -25,15 +25,12 @@ MODULE_DESCRIPTION("iptables mangle table");
|
||||
(1 << NF_INET_LOCAL_OUT) | \
|
||||
(1 << NF_INET_POST_ROUTING))
|
||||
|
||||
static int __net_init iptable_mangle_table_init(struct net *net);
|
||||
|
||||
static const struct xt_table packet_mangler = {
|
||||
.name = "mangle",
|
||||
.valid_hooks = MANGLE_VALID_HOOKS,
|
||||
.me = THIS_MODULE,
|
||||
.af = NFPROTO_IPV4,
|
||||
.priority = NF_IP_PRI_MANGLE,
|
||||
.table_init = iptable_mangle_table_init,
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
@ -83,7 +80,7 @@ iptable_mangle_hook(void *priv,
|
||||
}
|
||||
|
||||
static struct nf_hook_ops *mangle_ops __read_mostly;
|
||||
static int __net_init iptable_mangle_table_init(struct net *net)
|
||||
static int iptable_mangle_table_init(struct net *net)
|
||||
{
|
||||
struct ipt_replace *repl;
|
||||
int ret;
|
||||
@ -113,32 +110,30 @@ static struct pernet_operations iptable_mangle_net_ops = {
|
||||
|
||||
static int __init iptable_mangle_init(void)
|
||||
{
|
||||
int ret;
|
||||
int ret = xt_register_template(&packet_mangler,
|
||||
iptable_mangle_table_init);
|
||||
|
||||
mangle_ops = xt_hook_ops_alloc(&packet_mangler, iptable_mangle_hook);
|
||||
if (IS_ERR(mangle_ops)) {
|
||||
xt_unregister_template(&packet_mangler);
|
||||
ret = PTR_ERR(mangle_ops);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = register_pernet_subsys(&iptable_mangle_net_ops);
|
||||
if (ret < 0) {
|
||||
xt_unregister_template(&packet_mangler);
|
||||
kfree(mangle_ops);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = iptable_mangle_table_init(&init_net);
|
||||
if (ret) {
|
||||
unregister_pernet_subsys(&iptable_mangle_net_ops);
|
||||
kfree(mangle_ops);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit iptable_mangle_fini(void)
|
||||
{
|
||||
unregister_pernet_subsys(&iptable_mangle_net_ops);
|
||||
xt_unregister_template(&packet_mangler);
|
||||
kfree(mangle_ops);
|
||||
}
|
||||
|
||||
|
@ -17,8 +17,6 @@ struct iptable_nat_pernet {
|
||||
struct nf_hook_ops *nf_nat_ops;
|
||||
};
|
||||
|
||||
static int __net_init iptable_nat_table_init(struct net *net);
|
||||
|
||||
static unsigned int iptable_nat_net_id __read_mostly;
|
||||
|
||||
static const struct xt_table nf_nat_ipv4_table = {
|
||||
@ -29,7 +27,6 @@ static const struct xt_table nf_nat_ipv4_table = {
|
||||
(1 << NF_INET_LOCAL_IN),
|
||||
.me = THIS_MODULE,
|
||||
.af = NFPROTO_IPV4,
|
||||
.table_init = iptable_nat_table_init,
|
||||
};
|
||||
|
||||
static unsigned int iptable_nat_do_chain(void *priv,
|
||||
@ -113,7 +110,7 @@ static void ipt_nat_unregister_lookups(struct net *net)
|
||||
kfree(ops);
|
||||
}
|
||||
|
||||
static int __net_init iptable_nat_table_init(struct net *net)
|
||||
static int iptable_nat_table_init(struct net *net)
|
||||
{
|
||||
struct ipt_replace *repl;
|
||||
int ret;
|
||||
@ -155,20 +152,25 @@ static struct pernet_operations iptable_nat_net_ops = {
|
||||
|
||||
static int __init iptable_nat_init(void)
|
||||
{
|
||||
int ret = register_pernet_subsys(&iptable_nat_net_ops);
|
||||
int ret = xt_register_template(&nf_nat_ipv4_table,
|
||||
iptable_nat_table_init);
|
||||
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = iptable_nat_table_init(&init_net);
|
||||
if (ret)
|
||||
unregister_pernet_subsys(&iptable_nat_net_ops);
|
||||
ret = register_pernet_subsys(&iptable_nat_net_ops);
|
||||
if (ret < 0) {
|
||||
xt_unregister_template(&nf_nat_ipv4_table);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit iptable_nat_exit(void)
|
||||
{
|
||||
unregister_pernet_subsys(&iptable_nat_net_ops);
|
||||
xt_unregister_template(&nf_nat_ipv4_table);
|
||||
}
|
||||
|
||||
module_init(iptable_nat_init);
|
||||
|
@ -12,8 +12,6 @@
|
||||
|
||||
#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
|
||||
|
||||
static int __net_init iptable_raw_table_init(struct net *net);
|
||||
|
||||
static bool raw_before_defrag __read_mostly;
|
||||
MODULE_PARM_DESC(raw_before_defrag, "Enable raw table before defrag");
|
||||
module_param(raw_before_defrag, bool, 0000);
|
||||
@ -24,7 +22,6 @@ static const struct xt_table packet_raw = {
|
||||
.me = THIS_MODULE,
|
||||
.af = NFPROTO_IPV4,
|
||||
.priority = NF_IP_PRI_RAW,
|
||||
.table_init = iptable_raw_table_init,
|
||||
};
|
||||
|
||||
static const struct xt_table packet_raw_before_defrag = {
|
||||
@ -33,7 +30,6 @@ static const struct xt_table packet_raw_before_defrag = {
|
||||
.me = THIS_MODULE,
|
||||
.af = NFPROTO_IPV4,
|
||||
.priority = NF_IP_PRI_RAW_BEFORE_DEFRAG,
|
||||
.table_init = iptable_raw_table_init,
|
||||
};
|
||||
|
||||
/* The work comes in here from netfilter.c. */
|
||||
@ -89,22 +85,24 @@ static int __init iptable_raw_init(void)
|
||||
pr_info("Enabling raw table before defrag\n");
|
||||
}
|
||||
|
||||
ret = xt_register_template(table,
|
||||
iptable_raw_table_init);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
rawtable_ops = xt_hook_ops_alloc(table, iptable_raw_hook);
|
||||
if (IS_ERR(rawtable_ops))
|
||||
if (IS_ERR(rawtable_ops)) {
|
||||
xt_unregister_template(table);
|
||||
return PTR_ERR(rawtable_ops);
|
||||
}
|
||||
|
||||
ret = register_pernet_subsys(&iptable_raw_net_ops);
|
||||
if (ret < 0) {
|
||||
xt_unregister_template(table);
|
||||
kfree(rawtable_ops);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = iptable_raw_table_init(&init_net);
|
||||
if (ret) {
|
||||
unregister_pernet_subsys(&iptable_raw_net_ops);
|
||||
kfree(rawtable_ops);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -112,6 +110,7 @@ static void __exit iptable_raw_fini(void)
|
||||
{
|
||||
unregister_pernet_subsys(&iptable_raw_net_ops);
|
||||
kfree(rawtable_ops);
|
||||
xt_unregister_template(&packet_raw);
|
||||
}
|
||||
|
||||
module_init(iptable_raw_init);
|
||||
|
@ -25,15 +25,12 @@ MODULE_DESCRIPTION("iptables security table, for MAC rules");
|
||||
(1 << NF_INET_FORWARD) | \
|
||||
(1 << NF_INET_LOCAL_OUT)
|
||||
|
||||
static int __net_init iptable_security_table_init(struct net *net);
|
||||
|
||||
static const struct xt_table security_table = {
|
||||
.name = "security",
|
||||
.valid_hooks = SECURITY_VALID_HOOKS,
|
||||
.me = THIS_MODULE,
|
||||
.af = NFPROTO_IPV4,
|
||||
.priority = NF_IP_PRI_SECURITY,
|
||||
.table_init = iptable_security_table_init,
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
@ -45,7 +42,7 @@ iptable_security_hook(void *priv, struct sk_buff *skb,
|
||||
|
||||
static struct nf_hook_ops *sectbl_ops __read_mostly;
|
||||
|
||||
static int __net_init iptable_security_table_init(struct net *net)
|
||||
static int iptable_security_table_init(struct net *net)
|
||||
{
|
||||
struct ipt_replace *repl;
|
||||
int ret;
|
||||
@ -75,24 +72,25 @@ static struct pernet_operations iptable_security_net_ops = {
|
||||
|
||||
static int __init iptable_security_init(void)
|
||||
{
|
||||
int ret;
|
||||
int ret = xt_register_template(&security_table,
|
||||
iptable_security_table_init);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
sectbl_ops = xt_hook_ops_alloc(&security_table, iptable_security_hook);
|
||||
if (IS_ERR(sectbl_ops))
|
||||
if (IS_ERR(sectbl_ops)) {
|
||||
xt_unregister_template(&security_table);
|
||||
return PTR_ERR(sectbl_ops);
|
||||
}
|
||||
|
||||
ret = register_pernet_subsys(&iptable_security_net_ops);
|
||||
if (ret < 0) {
|
||||
xt_unregister_template(&security_table);
|
||||
kfree(sectbl_ops);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = iptable_security_table_init(&init_net);
|
||||
if (ret) {
|
||||
unregister_pernet_subsys(&iptable_security_net_ops);
|
||||
kfree(sectbl_ops);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -100,6 +98,7 @@ static void __exit iptable_security_fini(void)
|
||||
{
|
||||
unregister_pernet_subsys(&iptable_security_net_ops);
|
||||
kfree(sectbl_ops);
|
||||
xt_unregister_template(&security_table);
|
||||
}
|
||||
|
||||
module_init(iptable_security_init);
|
||||
|
@ -19,15 +19,12 @@ MODULE_DESCRIPTION("ip6tables filter table");
|
||||
(1 << NF_INET_FORWARD) | \
|
||||
(1 << NF_INET_LOCAL_OUT))
|
||||
|
||||
static int __net_init ip6table_filter_table_init(struct net *net);
|
||||
|
||||
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,
|
||||
.table_init = ip6table_filter_table_init,
|
||||
};
|
||||
|
||||
/* The work comes in here from netfilter.c. */
|
||||
@ -44,7 +41,7 @@ static struct nf_hook_ops *filter_ops __read_mostly;
|
||||
static bool forward = true;
|
||||
module_param(forward, bool, 0000);
|
||||
|
||||
static int __net_init ip6table_filter_table_init(struct net *net)
|
||||
static int ip6table_filter_table_init(struct net *net)
|
||||
{
|
||||
struct ip6t_replace *repl;
|
||||
int err;
|
||||
@ -63,7 +60,7 @@ static int __net_init ip6table_filter_table_init(struct net *net)
|
||||
|
||||
static int __net_init ip6table_filter_net_init(struct net *net)
|
||||
{
|
||||
if (net == &init_net || !forward)
|
||||
if (!forward)
|
||||
return ip6table_filter_table_init(net);
|
||||
|
||||
return 0;
|
||||
@ -87,15 +84,24 @@ static struct pernet_operations ip6table_filter_net_ops = {
|
||||
|
||||
static int __init ip6table_filter_init(void)
|
||||
{
|
||||
int ret;
|
||||
int ret = xt_register_template(&packet_filter,
|
||||
ip6table_filter_table_init);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
filter_ops = xt_hook_ops_alloc(&packet_filter, ip6table_filter_hook);
|
||||
if (IS_ERR(filter_ops))
|
||||
if (IS_ERR(filter_ops)) {
|
||||
xt_unregister_template(&packet_filter);
|
||||
return PTR_ERR(filter_ops);
|
||||
}
|
||||
|
||||
ret = register_pernet_subsys(&ip6table_filter_net_ops);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
xt_unregister_template(&packet_filter);
|
||||
kfree(filter_ops);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -103,6 +109,7 @@ static int __init ip6table_filter_init(void)
|
||||
static void __exit ip6table_filter_fini(void)
|
||||
{
|
||||
unregister_pernet_subsys(&ip6table_filter_net_ops);
|
||||
xt_unregister_template(&packet_filter);
|
||||
kfree(filter_ops);
|
||||
}
|
||||
|
||||
|
@ -20,15 +20,12 @@ MODULE_DESCRIPTION("ip6tables mangle table");
|
||||
(1 << NF_INET_LOCAL_OUT) | \
|
||||
(1 << NF_INET_POST_ROUTING))
|
||||
|
||||
static int __net_init ip6table_mangle_table_init(struct net *net);
|
||||
|
||||
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,
|
||||
.table_init = ip6table_mangle_table_init,
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
@ -76,7 +73,7 @@ ip6table_mangle_hook(void *priv, struct sk_buff *skb,
|
||||
}
|
||||
|
||||
static struct nf_hook_ops *mangle_ops __read_mostly;
|
||||
static int __net_init ip6table_mangle_table_init(struct net *net)
|
||||
static int ip6table_mangle_table_init(struct net *net)
|
||||
{
|
||||
struct ip6t_replace *repl;
|
||||
int ret;
|
||||
@ -106,29 +103,32 @@ static struct pernet_operations ip6table_mangle_net_ops = {
|
||||
|
||||
static int __init ip6table_mangle_init(void)
|
||||
{
|
||||
int ret;
|
||||
int ret = xt_register_template(&packet_mangler,
|
||||
ip6table_mangle_table_init);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mangle_ops = xt_hook_ops_alloc(&packet_mangler, ip6table_mangle_hook);
|
||||
if (IS_ERR(mangle_ops))
|
||||
if (IS_ERR(mangle_ops)) {
|
||||
xt_unregister_template(&packet_mangler);
|
||||
return PTR_ERR(mangle_ops);
|
||||
}
|
||||
|
||||
ret = register_pernet_subsys(&ip6table_mangle_net_ops);
|
||||
if (ret < 0) {
|
||||
xt_unregister_template(&packet_mangler);
|
||||
kfree(mangle_ops);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ip6table_mangle_table_init(&init_net);
|
||||
if (ret) {
|
||||
unregister_pernet_subsys(&ip6table_mangle_net_ops);
|
||||
kfree(mangle_ops);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit ip6table_mangle_fini(void)
|
||||
{
|
||||
unregister_pernet_subsys(&ip6table_mangle_net_ops);
|
||||
xt_unregister_template(&packet_mangler);
|
||||
kfree(mangle_ops);
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,6 @@ struct ip6table_nat_pernet {
|
||||
struct nf_hook_ops *nf_nat_ops;
|
||||
};
|
||||
|
||||
static int __net_init ip6table_nat_table_init(struct net *net);
|
||||
|
||||
static unsigned int ip6table_nat_net_id __read_mostly;
|
||||
|
||||
static const struct xt_table nf_nat_ipv6_table = {
|
||||
@ -31,7 +29,6 @@ static const struct xt_table nf_nat_ipv6_table = {
|
||||
(1 << NF_INET_LOCAL_IN),
|
||||
.me = THIS_MODULE,
|
||||
.af = NFPROTO_IPV6,
|
||||
.table_init = ip6table_nat_table_init,
|
||||
};
|
||||
|
||||
static unsigned int ip6table_nat_do_chain(void *priv,
|
||||
@ -115,7 +112,7 @@ static void ip6t_nat_unregister_lookups(struct net *net)
|
||||
kfree(ops);
|
||||
}
|
||||
|
||||
static int __net_init ip6table_nat_table_init(struct net *net)
|
||||
static int ip6table_nat_table_init(struct net *net)
|
||||
{
|
||||
struct ip6t_replace *repl;
|
||||
int ret;
|
||||
@ -157,20 +154,23 @@ static struct pernet_operations ip6table_nat_net_ops = {
|
||||
|
||||
static int __init ip6table_nat_init(void)
|
||||
{
|
||||
int ret = register_pernet_subsys(&ip6table_nat_net_ops);
|
||||
int ret = xt_register_template(&nf_nat_ipv6_table,
|
||||
ip6table_nat_table_init);
|
||||
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ip6table_nat_table_init(&init_net);
|
||||
ret = register_pernet_subsys(&ip6table_nat_net_ops);
|
||||
if (ret)
|
||||
unregister_pernet_subsys(&ip6table_nat_net_ops);
|
||||
xt_unregister_template(&nf_nat_ipv6_table);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit ip6table_nat_exit(void)
|
||||
{
|
||||
unregister_pernet_subsys(&ip6table_nat_net_ops);
|
||||
xt_unregister_template(&nf_nat_ipv6_table);
|
||||
}
|
||||
|
||||
module_init(ip6table_nat_init);
|
||||
|
@ -11,8 +11,6 @@
|
||||
|
||||
#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
|
||||
|
||||
static int __net_init ip6table_raw_table_init(struct net *net);
|
||||
|
||||
static bool raw_before_defrag __read_mostly;
|
||||
MODULE_PARM_DESC(raw_before_defrag, "Enable raw table before defrag");
|
||||
module_param(raw_before_defrag, bool, 0000);
|
||||
@ -23,7 +21,6 @@ static const struct xt_table packet_raw = {
|
||||
.me = THIS_MODULE,
|
||||
.af = NFPROTO_IPV6,
|
||||
.priority = NF_IP6_PRI_RAW,
|
||||
.table_init = ip6table_raw_table_init,
|
||||
};
|
||||
|
||||
static const struct xt_table packet_raw_before_defrag = {
|
||||
@ -32,7 +29,6 @@ static const struct xt_table packet_raw_before_defrag = {
|
||||
.me = THIS_MODULE,
|
||||
.af = NFPROTO_IPV6,
|
||||
.priority = NF_IP6_PRI_RAW_BEFORE_DEFRAG,
|
||||
.table_init = ip6table_raw_table_init,
|
||||
};
|
||||
|
||||
/* The work comes in here from netfilter.c. */
|
||||
@ -45,7 +41,7 @@ ip6table_raw_hook(void *priv, struct sk_buff *skb,
|
||||
|
||||
static struct nf_hook_ops *rawtable_ops __read_mostly;
|
||||
|
||||
static int __net_init ip6table_raw_table_init(struct net *net)
|
||||
static int ip6table_raw_table_init(struct net *net)
|
||||
{
|
||||
struct ip6t_replace *repl;
|
||||
const struct xt_table *table = &packet_raw;
|
||||
@ -79,37 +75,39 @@ static struct pernet_operations ip6table_raw_net_ops = {
|
||||
|
||||
static int __init ip6table_raw_init(void)
|
||||
{
|
||||
int ret;
|
||||
const struct xt_table *table = &packet_raw;
|
||||
int ret;
|
||||
|
||||
if (raw_before_defrag) {
|
||||
table = &packet_raw_before_defrag;
|
||||
|
||||
pr_info("Enabling raw table before defrag\n");
|
||||
}
|
||||
|
||||
ret = xt_register_template(table, ip6table_raw_table_init);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Register hooks */
|
||||
rawtable_ops = xt_hook_ops_alloc(table, ip6table_raw_hook);
|
||||
if (IS_ERR(rawtable_ops))
|
||||
if (IS_ERR(rawtable_ops)) {
|
||||
xt_unregister_template(table);
|
||||
return PTR_ERR(rawtable_ops);
|
||||
}
|
||||
|
||||
ret = register_pernet_subsys(&ip6table_raw_net_ops);
|
||||
if (ret < 0) {
|
||||
kfree(rawtable_ops);
|
||||
xt_unregister_template(table);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ip6table_raw_table_init(&init_net);
|
||||
if (ret) {
|
||||
unregister_pernet_subsys(&ip6table_raw_net_ops);
|
||||
kfree(rawtable_ops);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit ip6table_raw_fini(void)
|
||||
{
|
||||
unregister_pernet_subsys(&ip6table_raw_net_ops);
|
||||
xt_unregister_template(&packet_raw);
|
||||
kfree(rawtable_ops);
|
||||
}
|
||||
|
||||
|
@ -24,15 +24,12 @@ MODULE_DESCRIPTION("ip6tables security table, for MAC rules");
|
||||
(1 << NF_INET_FORWARD) | \
|
||||
(1 << NF_INET_LOCAL_OUT)
|
||||
|
||||
static int __net_init ip6table_security_table_init(struct net *net);
|
||||
|
||||
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,
|
||||
.table_init = ip6table_security_table_init,
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
@ -44,7 +41,7 @@ ip6table_security_hook(void *priv, struct sk_buff *skb,
|
||||
|
||||
static struct nf_hook_ops *sectbl_ops __read_mostly;
|
||||
|
||||
static int __net_init ip6table_security_table_init(struct net *net)
|
||||
static int ip6table_security_table_init(struct net *net)
|
||||
{
|
||||
struct ip6t_replace *repl;
|
||||
int ret;
|
||||
@ -74,29 +71,32 @@ static struct pernet_operations ip6table_security_net_ops = {
|
||||
|
||||
static int __init ip6table_security_init(void)
|
||||
{
|
||||
int ret;
|
||||
int ret = xt_register_template(&security_table,
|
||||
ip6table_security_table_init);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
sectbl_ops = xt_hook_ops_alloc(&security_table, ip6table_security_hook);
|
||||
if (IS_ERR(sectbl_ops))
|
||||
if (IS_ERR(sectbl_ops)) {
|
||||
xt_unregister_template(&security_table);
|
||||
return PTR_ERR(sectbl_ops);
|
||||
}
|
||||
|
||||
ret = register_pernet_subsys(&ip6table_security_net_ops);
|
||||
if (ret < 0) {
|
||||
kfree(sectbl_ops);
|
||||
xt_unregister_template(&security_table);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ip6table_security_table_init(&init_net);
|
||||
if (ret) {
|
||||
unregister_pernet_subsys(&ip6table_security_net_ops);
|
||||
kfree(sectbl_ops);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit ip6table_security_fini(void)
|
||||
{
|
||||
unregister_pernet_subsys(&ip6table_security_net_ops);
|
||||
xt_unregister_template(&security_table);
|
||||
kfree(sectbl_ops);
|
||||
}
|
||||
|
||||
|
@ -852,6 +852,11 @@ static int ctnetlink_done(struct netlink_callback *cb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ctnetlink_filter_u32 {
|
||||
u32 val;
|
||||
u32 mask;
|
||||
};
|
||||
|
||||
struct ctnetlink_filter {
|
||||
u8 family;
|
||||
|
||||
@ -862,10 +867,8 @@ struct ctnetlink_filter {
|
||||
struct nf_conntrack_tuple reply;
|
||||
struct nf_conntrack_zone zone;
|
||||
|
||||
struct {
|
||||
u_int32_t val;
|
||||
u_int32_t mask;
|
||||
} mark;
|
||||
struct ctnetlink_filter_u32 mark;
|
||||
struct ctnetlink_filter_u32 status;
|
||||
};
|
||||
|
||||
static const struct nla_policy cta_filter_nla_policy[CTA_FILTER_MAX + 1] = {
|
||||
@ -907,6 +910,46 @@ static int ctnetlink_parse_tuple_filter(const struct nlattr * const cda[],
|
||||
struct nf_conntrack_zone *zone,
|
||||
u_int32_t flags);
|
||||
|
||||
static int ctnetlink_filter_parse_mark(struct ctnetlink_filter_u32 *mark,
|
||||
const struct nlattr * const cda[])
|
||||
{
|
||||
#ifdef CONFIG_NF_CONNTRACK_MARK
|
||||
if (cda[CTA_MARK]) {
|
||||
mark->val = ntohl(nla_get_be32(cda[CTA_MARK]));
|
||||
|
||||
if (cda[CTA_MARK_MASK])
|
||||
mark->mask = ntohl(nla_get_be32(cda[CTA_MARK_MASK]));
|
||||
else
|
||||
mark->mask = 0xffffffff;
|
||||
} else if (cda[CTA_MARK_MASK]) {
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ctnetlink_filter_parse_status(struct ctnetlink_filter_u32 *status,
|
||||
const struct nlattr * const cda[])
|
||||
{
|
||||
if (cda[CTA_STATUS]) {
|
||||
status->val = ntohl(nla_get_be32(cda[CTA_STATUS]));
|
||||
if (cda[CTA_STATUS_MASK])
|
||||
status->mask = ntohl(nla_get_be32(cda[CTA_STATUS_MASK]));
|
||||
else
|
||||
status->mask = status->val;
|
||||
|
||||
/* status->val == 0? always true, else always false. */
|
||||
if (status->mask == 0)
|
||||
return -EINVAL;
|
||||
} else if (cda[CTA_STATUS_MASK]) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* CTA_STATUS is NLA_U32, if this fires UAPI needs to be extended */
|
||||
BUILD_BUG_ON(__IPS_MAX_BIT >= 32);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ctnetlink_filter *
|
||||
ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
|
||||
{
|
||||
@ -924,18 +967,14 @@ ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
|
||||
|
||||
filter->family = family;
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_MARK
|
||||
if (cda[CTA_MARK]) {
|
||||
filter->mark.val = ntohl(nla_get_be32(cda[CTA_MARK]));
|
||||
if (cda[CTA_MARK_MASK])
|
||||
filter->mark.mask = ntohl(nla_get_be32(cda[CTA_MARK_MASK]));
|
||||
else
|
||||
filter->mark.mask = 0xffffffff;
|
||||
} else if (cda[CTA_MARK_MASK]) {
|
||||
err = -EINVAL;
|
||||
err = ctnetlink_filter_parse_mark(&filter->mark, cda);
|
||||
if (err)
|
||||
goto err_filter;
|
||||
}
|
||||
#endif
|
||||
|
||||
err = ctnetlink_filter_parse_status(&filter->status, cda);
|
||||
if (err)
|
||||
goto err_filter;
|
||||
|
||||
if (!cda[CTA_FILTER])
|
||||
return filter;
|
||||
|
||||
@ -989,7 +1028,7 @@ err_filter:
|
||||
|
||||
static bool ctnetlink_needs_filter(u8 family, const struct nlattr * const *cda)
|
||||
{
|
||||
return family || cda[CTA_MARK] || cda[CTA_FILTER];
|
||||
return family || cda[CTA_MARK] || cda[CTA_FILTER] || cda[CTA_STATUS];
|
||||
}
|
||||
|
||||
static int ctnetlink_start(struct netlink_callback *cb)
|
||||
@ -1082,6 +1121,7 @@ static int ctnetlink_filter_match(struct nf_conn *ct, void *data)
|
||||
{
|
||||
struct ctnetlink_filter *filter = data;
|
||||
struct nf_conntrack_tuple *tuple;
|
||||
u32 status;
|
||||
|
||||
if (filter == NULL)
|
||||
goto out;
|
||||
@ -1113,6 +1153,9 @@ static int ctnetlink_filter_match(struct nf_conn *ct, void *data)
|
||||
if ((ct->mark & filter->mark.mask) != filter->mark.val)
|
||||
goto ignore_entry;
|
||||
#endif
|
||||
status = (u32)READ_ONCE(ct->status);
|
||||
if ((status & filter->status.mask) != filter->status.val)
|
||||
goto ignore_entry;
|
||||
|
||||
out:
|
||||
return 1;
|
||||
@ -1495,6 +1538,7 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = {
|
||||
[CTA_LABELS_MASK] = { .type = NLA_BINARY,
|
||||
.len = NF_CT_LABELS_MAX_SIZE },
|
||||
[CTA_FILTER] = { .type = NLA_NESTED },
|
||||
[CTA_STATUS_MASK] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
static int ctnetlink_flush_iterate(struct nf_conn *ct, void *data)
|
||||
|
@ -180,15 +180,10 @@ static void flow_offload_fixup_tcp(struct ip_ct_tcp *tcp)
|
||||
|
||||
static void flow_offload_fixup_ct_timeout(struct nf_conn *ct)
|
||||
{
|
||||
const struct nf_conntrack_l4proto *l4proto;
|
||||
struct net *net = nf_ct_net(ct);
|
||||
int l4num = nf_ct_protonum(ct);
|
||||
unsigned int timeout;
|
||||
|
||||
l4proto = nf_ct_l4proto_find(l4num);
|
||||
if (!l4proto)
|
||||
return;
|
||||
|
||||
if (l4num == IPPROTO_TCP) {
|
||||
struct nf_tcp_net *tn = nf_tcp_pernet(net);
|
||||
|
||||
@ -273,15 +268,10 @@ static const struct rhashtable_params nf_flow_offload_rhash_params = {
|
||||
|
||||
unsigned long flow_offload_get_timeout(struct flow_offload *flow)
|
||||
{
|
||||
const struct nf_conntrack_l4proto *l4proto;
|
||||
unsigned long timeout = NF_FLOW_TIMEOUT;
|
||||
struct net *net = nf_ct_net(flow->ct);
|
||||
int l4num = nf_ct_protonum(flow->ct);
|
||||
|
||||
l4proto = nf_ct_l4proto_find(l4num);
|
||||
if (!l4proto)
|
||||
return timeout;
|
||||
|
||||
if (l4num == IPPROTO_TCP) {
|
||||
struct nf_tcp_net *tn = nf_tcp_pernet(net);
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#include "nf_internals.h"
|
||||
|
||||
static const struct nf_queue_handler __rcu *nf_queue_handler;
|
||||
|
||||
/*
|
||||
* Hook for nfnetlink_queue to register its queue handler.
|
||||
* We do this so that most of the NFQUEUE code can be modular.
|
||||
@ -29,20 +31,18 @@
|
||||
* receives, no matter what.
|
||||
*/
|
||||
|
||||
/* return EBUSY when somebody else is registered, return EEXIST if the
|
||||
* same handler is registered, return 0 in case of success. */
|
||||
void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh)
|
||||
void nf_register_queue_handler(const struct nf_queue_handler *qh)
|
||||
{
|
||||
/* should never happen, we only have one queueing backend in kernel */
|
||||
WARN_ON(rcu_access_pointer(net->nf.queue_handler));
|
||||
rcu_assign_pointer(net->nf.queue_handler, qh);
|
||||
WARN_ON(rcu_access_pointer(nf_queue_handler));
|
||||
rcu_assign_pointer(nf_queue_handler, qh);
|
||||
}
|
||||
EXPORT_SYMBOL(nf_register_queue_handler);
|
||||
|
||||
/* The caller must flush their queue before this */
|
||||
void nf_unregister_queue_handler(struct net *net)
|
||||
void nf_unregister_queue_handler(void)
|
||||
{
|
||||
RCU_INIT_POINTER(net->nf.queue_handler, NULL);
|
||||
RCU_INIT_POINTER(nf_queue_handler, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(nf_unregister_queue_handler);
|
||||
|
||||
@ -108,7 +108,7 @@ void nf_queue_nf_hook_drop(struct net *net)
|
||||
const struct nf_queue_handler *qh;
|
||||
|
||||
rcu_read_lock();
|
||||
qh = rcu_dereference(net->nf.queue_handler);
|
||||
qh = rcu_dereference(nf_queue_handler);
|
||||
if (qh)
|
||||
qh->nf_hook_drop(net);
|
||||
rcu_read_unlock();
|
||||
@ -149,12 +149,11 @@ static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state,
|
||||
{
|
||||
struct nf_queue_entry *entry = NULL;
|
||||
const struct nf_queue_handler *qh;
|
||||
struct net *net = state->net;
|
||||
unsigned int route_key_size;
|
||||
int status;
|
||||
|
||||
/* QUEUE == DROP if no one is waiting, to be safe. */
|
||||
qh = rcu_dereference(net->nf.queue_handler);
|
||||
qh = rcu_dereference(nf_queue_handler);
|
||||
if (!qh)
|
||||
return -ESRCH;
|
||||
|
||||
|
@ -951,6 +951,16 @@ static void nfqnl_nf_hook_drop(struct net *net)
|
||||
struct nfnl_queue_net *q = nfnl_queue_pernet(net);
|
||||
int i;
|
||||
|
||||
/* This function is also called on net namespace error unwind,
|
||||
* when pernet_ops->init() failed and ->exit() functions of the
|
||||
* previous pernet_ops gets called.
|
||||
*
|
||||
* This may result in a call to nfqnl_nf_hook_drop() before
|
||||
* struct nfnl_queue_net was allocated.
|
||||
*/
|
||||
if (!q)
|
||||
return;
|
||||
|
||||
for (i = 0; i < INSTANCE_BUCKETS; i++) {
|
||||
struct nfqnl_instance *inst;
|
||||
struct hlist_head *head = &q->instance_table[i];
|
||||
@ -1502,7 +1512,6 @@ static int __net_init nfnl_queue_net_init(struct net *net)
|
||||
&nfqnl_seq_ops, sizeof(struct iter_state)))
|
||||
return -ENOMEM;
|
||||
#endif
|
||||
nf_register_queue_handler(net, &nfqh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1511,7 +1520,6 @@ static void __net_exit nfnl_queue_net_exit(struct net *net)
|
||||
struct nfnl_queue_net *q = nfnl_queue_pernet(net);
|
||||
unsigned int i;
|
||||
|
||||
nf_unregister_queue_handler(net);
|
||||
#ifdef CONFIG_PROC_FS
|
||||
remove_proc_entry("nfnetlink_queue", net->nf.proc_netfilter);
|
||||
#endif
|
||||
@ -1555,6 +1563,8 @@ static int __init nfnetlink_queue_init(void)
|
||||
goto cleanup_netlink_subsys;
|
||||
}
|
||||
|
||||
nf_register_queue_handler(&nfqh);
|
||||
|
||||
return status;
|
||||
|
||||
cleanup_netlink_subsys:
|
||||
@ -1568,6 +1578,7 @@ out:
|
||||
|
||||
static void __exit nfnetlink_queue_fini(void)
|
||||
{
|
||||
nf_unregister_queue_handler();
|
||||
unregister_netdevice_notifier(&nfqnl_dev_notifier);
|
||||
nfnetlink_subsys_unregister(&nfqnl_subsys);
|
||||
netlink_unregister_notifier(&nfqnl_rtnl_notifier);
|
||||
|
@ -683,14 +683,12 @@ static int nfnl_compat_get_rcu(struct sk_buff *skb,
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
ret = netlink_unicast(info->sk, skb2, NETLINK_CB(skb).portid,
|
||||
MSG_DONTWAIT);
|
||||
if (ret > 0)
|
||||
ret = 0;
|
||||
ret = nfnetlink_unicast(skb2, info->net, NETLINK_CB(skb).portid);
|
||||
out_put:
|
||||
rcu_read_lock();
|
||||
module_put(THIS_MODULE);
|
||||
return ret == -EAGAIN ? -ENOBUFS : ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct nla_policy nfnl_compat_policy_get[NFTA_COMPAT_MAX+1] = {
|
||||
|
@ -39,6 +39,20 @@ MODULE_DESCRIPTION("{ip,ip6,arp,eb}_tables backend module");
|
||||
#define XT_PCPU_BLOCK_SIZE 4096
|
||||
#define XT_MAX_TABLE_SIZE (512 * 1024 * 1024)
|
||||
|
||||
struct xt_template {
|
||||
struct list_head list;
|
||||
|
||||
/* called when table is needed in the given netns */
|
||||
int (*table_init)(struct net *net);
|
||||
|
||||
struct module *me;
|
||||
|
||||
/* A unique name... */
|
||||
char name[XT_TABLE_MAXNAMELEN];
|
||||
};
|
||||
|
||||
static struct list_head xt_templates[NFPROTO_NUMPROTO];
|
||||
|
||||
struct xt_pernet {
|
||||
struct list_head tables[NFPROTO_NUMPROTO];
|
||||
};
|
||||
@ -1221,48 +1235,43 @@ struct xt_table *xt_find_table_lock(struct net *net, u_int8_t af,
|
||||
const char *name)
|
||||
{
|
||||
struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
|
||||
struct xt_table *t, *found = NULL;
|
||||
struct module *owner = NULL;
|
||||
struct xt_template *tmpl;
|
||||
struct xt_table *t;
|
||||
|
||||
mutex_lock(&xt[af].mutex);
|
||||
list_for_each_entry(t, &xt_net->tables[af], list)
|
||||
if (strcmp(t->name, name) == 0 && try_module_get(t->me))
|
||||
return t;
|
||||
|
||||
if (net == &init_net)
|
||||
goto out;
|
||||
|
||||
/* Table doesn't exist in this netns, re-try init */
|
||||
xt_net = net_generic(&init_net, xt_pernet_id);
|
||||
list_for_each_entry(t, &xt_net->tables[af], list) {
|
||||
/* Table doesn't exist in this netns, check larval list */
|
||||
list_for_each_entry(tmpl, &xt_templates[af], list) {
|
||||
int err;
|
||||
|
||||
if (strcmp(t->name, name))
|
||||
if (strcmp(tmpl->name, name))
|
||||
continue;
|
||||
if (!try_module_get(t->me))
|
||||
if (!try_module_get(tmpl->me))
|
||||
goto out;
|
||||
|
||||
owner = tmpl->me;
|
||||
|
||||
mutex_unlock(&xt[af].mutex);
|
||||
err = t->table_init(net);
|
||||
err = tmpl->table_init(net);
|
||||
if (err < 0) {
|
||||
module_put(t->me);
|
||||
module_put(owner);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
found = t;
|
||||
|
||||
mutex_lock(&xt[af].mutex);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
goto out;
|
||||
|
||||
xt_net = net_generic(net, xt_pernet_id);
|
||||
/* and once again: */
|
||||
list_for_each_entry(t, &xt_net->tables[af], list)
|
||||
if (strcmp(t->name, name) == 0)
|
||||
return t;
|
||||
|
||||
module_put(found->me);
|
||||
module_put(owner);
|
||||
out:
|
||||
mutex_unlock(&xt[af].mutex);
|
||||
return ERR_PTR(-ENOENT);
|
||||
@ -1749,6 +1758,58 @@ xt_hook_ops_alloc(const struct xt_table *table, nf_hookfn *fn)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_hook_ops_alloc);
|
||||
|
||||
int xt_register_template(const struct xt_table *table,
|
||||
int (*table_init)(struct net *net))
|
||||
{
|
||||
int ret = -EEXIST, af = table->af;
|
||||
struct xt_template *t;
|
||||
|
||||
mutex_lock(&xt[af].mutex);
|
||||
|
||||
list_for_each_entry(t, &xt_templates[af], list) {
|
||||
if (WARN_ON_ONCE(strcmp(table->name, t->name) == 0))
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = -ENOMEM;
|
||||
t = kzalloc(sizeof(*t), GFP_KERNEL);
|
||||
if (!t)
|
||||
goto out_unlock;
|
||||
|
||||
BUILD_BUG_ON(sizeof(t->name) != sizeof(table->name));
|
||||
|
||||
strscpy(t->name, table->name, sizeof(t->name));
|
||||
t->table_init = table_init;
|
||||
t->me = table->me;
|
||||
list_add(&t->list, &xt_templates[af]);
|
||||
ret = 0;
|
||||
out_unlock:
|
||||
mutex_unlock(&xt[af].mutex);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_register_template);
|
||||
|
||||
void xt_unregister_template(const struct xt_table *table)
|
||||
{
|
||||
struct xt_template *t;
|
||||
int af = table->af;
|
||||
|
||||
mutex_lock(&xt[af].mutex);
|
||||
list_for_each_entry(t, &xt_templates[af], list) {
|
||||
if (strcmp(table->name, t->name))
|
||||
continue;
|
||||
|
||||
list_del(&t->list);
|
||||
mutex_unlock(&xt[af].mutex);
|
||||
kfree(t);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_unlock(&xt[af].mutex);
|
||||
WARN_ON_ONCE(1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_unregister_template);
|
||||
|
||||
int xt_proto_init(struct net *net, u_int8_t af)
|
||||
{
|
||||
#ifdef CONFIG_PROC_FS
|
||||
@ -1937,6 +1998,7 @@ static int __init xt_init(void)
|
||||
#endif
|
||||
INIT_LIST_HEAD(&xt[i].target);
|
||||
INIT_LIST_HEAD(&xt[i].match);
|
||||
INIT_LIST_HEAD(&xt_templates[i]);
|
||||
}
|
||||
rv = register_pernet_subsys(&xt_net_ops);
|
||||
if (rv < 0)
|
||||
|
@ -351,21 +351,10 @@ notrack_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
static int notrack_chk(const struct xt_tgchk_param *par)
|
||||
{
|
||||
if (!par->net->xt.notrack_deprecated_warning) {
|
||||
pr_info("netfilter: NOTRACK target is deprecated, "
|
||||
"use CT instead or upgrade iptables\n");
|
||||
par->net->xt.notrack_deprecated_warning = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_target notrack_tg_reg __read_mostly = {
|
||||
.name = "NOTRACK",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.checkentry = notrack_chk,
|
||||
.target = notrack_tg,
|
||||
.table = "raw",
|
||||
.me = THIS_MODULE,
|
||||
|
Loading…
Reference in New Issue
Block a user