Commit 2b95efe7 authored by Jan Engelhardt's avatar Jan Engelhardt

netfilter: xtables: use xt_table for hook instantiation

The respective xt_table structures already have most of the metadata
needed for hook setup. Add a 'priority' field to struct xt_table so
that xt_hook_link() can be called with a reduced number of arguments.

So should we be having more tables in the future, it comes at no
static cost (only runtime, as before) - space saved:
6807373->6806555.
Signed-off-by: default avatarJan Engelhardt <jengelh@medozas.de>
parent 2b21e051
...@@ -361,6 +361,7 @@ struct xt_table { ...@@ -361,6 +361,7 @@ struct xt_table {
struct module *me; struct module *me;
u_int8_t af; /* address/protocol family */ u_int8_t af; /* address/protocol family */
int priority; /* hook order */
/* A unique name... */ /* A unique name... */
const char name[XT_TABLE_MAXNAMELEN]; const char name[XT_TABLE_MAXNAMELEN];
...@@ -522,6 +523,9 @@ static inline unsigned long ifname_compare_aligned(const char *_a, ...@@ -522,6 +523,9 @@ static inline unsigned long ifname_compare_aligned(const char *_a,
return ret; return ret;
} }
extern struct nf_hook_ops *xt_hook_link(const struct xt_table *, nf_hookfn *);
extern void xt_hook_unlink(const struct xt_table *, struct nf_hook_ops *);
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
#include <net/compat.h> #include <net/compat.h>
......
...@@ -50,6 +50,7 @@ static const struct xt_table packet_filter = { ...@@ -50,6 +50,7 @@ static const struct xt_table packet_filter = {
.valid_hooks = FILTER_VALID_HOOKS, .valid_hooks = FILTER_VALID_HOOKS,
.me = THIS_MODULE, .me = THIS_MODULE,
.af = NFPROTO_ARP, .af = NFPROTO_ARP,
.priority = NF_IP_PRI_FILTER,
}; };
/* The work comes in here from netfilter.c */ /* The work comes in here from netfilter.c */
...@@ -63,29 +64,7 @@ arptable_filter_hook(unsigned int hook, struct sk_buff *skb, ...@@ -63,29 +64,7 @@ arptable_filter_hook(unsigned int hook, struct sk_buff *skb,
return arpt_do_table(skb, hook, in, out, net->ipv4.arptable_filter); return arpt_do_table(skb, hook, in, out, net->ipv4.arptable_filter);
} }
static struct nf_hook_ops arpt_ops[] __read_mostly = { static struct nf_hook_ops *arpfilter_ops __read_mostly;
{
.hook = arptable_filter_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_ARP,
.hooknum = NF_ARP_IN,
.priority = NF_IP_PRI_FILTER,
},
{
.hook = arptable_filter_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_ARP,
.hooknum = NF_ARP_OUT,
.priority = NF_IP_PRI_FILTER,
},
{
.hook = arptable_filter_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_ARP,
.hooknum = NF_ARP_FORWARD,
.priority = NF_IP_PRI_FILTER,
},
};
static int __net_init arptable_filter_net_init(struct net *net) static int __net_init arptable_filter_net_init(struct net *net)
{ {
...@@ -115,9 +94,11 @@ static int __init arptable_filter_init(void) ...@@ -115,9 +94,11 @@ static int __init arptable_filter_init(void)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = nf_register_hooks(arpt_ops, ARRAY_SIZE(arpt_ops)); arpfilter_ops = xt_hook_link(&packet_filter, arptable_filter_hook);
if (ret < 0) if (IS_ERR(arpfilter_ops)) {
ret = PTR_ERR(arpfilter_ops);
goto cleanup_table; goto cleanup_table;
}
return ret; return ret;
cleanup_table: cleanup_table:
...@@ -127,7 +108,7 @@ static int __init arptable_filter_init(void) ...@@ -127,7 +108,7 @@ static int __init arptable_filter_init(void)
static void __exit arptable_filter_fini(void) static void __exit arptable_filter_fini(void)
{ {
nf_unregister_hooks(arpt_ops, ARRAY_SIZE(arpt_ops)); xt_hook_unlink(&packet_filter, arpfilter_ops);
unregister_pernet_subsys(&arptable_filter_net_ops); unregister_pernet_subsys(&arptable_filter_net_ops);
} }
......
...@@ -58,6 +58,7 @@ static const struct xt_table packet_filter = { ...@@ -58,6 +58,7 @@ static const struct xt_table packet_filter = {
.valid_hooks = FILTER_VALID_HOOKS, .valid_hooks = FILTER_VALID_HOOKS,
.me = THIS_MODULE, .me = THIS_MODULE,
.af = NFPROTO_IPV4, .af = NFPROTO_IPV4,
.priority = NF_IP_PRI_FILTER,
}; };
static unsigned int static unsigned int
...@@ -77,29 +78,7 @@ iptable_filter_hook(unsigned int hook, struct sk_buff *skb, ...@@ -77,29 +78,7 @@ iptable_filter_hook(unsigned int hook, struct sk_buff *skb,
return ipt_do_table(skb, hook, in, out, net->ipv4.iptable_filter); return ipt_do_table(skb, hook, in, out, net->ipv4.iptable_filter);
} }
static struct nf_hook_ops ipt_ops[] __read_mostly = { static struct nf_hook_ops *filter_ops __read_mostly;
{
.hook = iptable_filter_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_FILTER,
},
{
.hook = iptable_filter_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_FORWARD,
.priority = NF_IP_PRI_FILTER,
},
{
.hook = iptable_filter_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_FILTER,
},
};
/* Default to forward because I got too much mail already. */ /* Default to forward because I got too much mail already. */
static int forward = NF_ACCEPT; static int forward = NF_ACCEPT;
...@@ -142,9 +121,11 @@ static int __init iptable_filter_init(void) ...@@ -142,9 +121,11 @@ static int __init iptable_filter_init(void)
return ret; return ret;
/* Register hooks */ /* Register hooks */
ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); filter_ops = xt_hook_link(&packet_filter, iptable_filter_hook);
if (ret < 0) if (IS_ERR(filter_ops)) {
ret = PTR_ERR(filter_ops);
goto cleanup_table; goto cleanup_table;
}
return ret; return ret;
...@@ -155,7 +136,7 @@ static int __init iptable_filter_init(void) ...@@ -155,7 +136,7 @@ static int __init iptable_filter_init(void)
static void __exit iptable_filter_fini(void) static void __exit iptable_filter_fini(void)
{ {
nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); xt_hook_unlink(&packet_filter, filter_ops);
unregister_pernet_subsys(&iptable_filter_net_ops); unregister_pernet_subsys(&iptable_filter_net_ops);
} }
......
...@@ -69,6 +69,7 @@ static const struct xt_table packet_mangler = { ...@@ -69,6 +69,7 @@ static const struct xt_table packet_mangler = {
.valid_hooks = MANGLE_VALID_HOOKS, .valid_hooks = MANGLE_VALID_HOOKS,
.me = THIS_MODULE, .me = THIS_MODULE,
.af = NFPROTO_IPV4, .af = NFPROTO_IPV4,
.priority = NF_IP_PRI_MANGLE,
}; };
static unsigned int static unsigned int
...@@ -129,43 +130,7 @@ iptable_mangle_hook(unsigned int hook, ...@@ -129,43 +130,7 @@ iptable_mangle_hook(unsigned int hook,
dev_net(in)->ipv4.iptable_mangle); dev_net(in)->ipv4.iptable_mangle);
} }
static struct nf_hook_ops ipt_ops[] __read_mostly = { static struct nf_hook_ops *mangle_ops __read_mostly;
{
.hook = iptable_mangle_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_MANGLE,
},
{
.hook = iptable_mangle_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_MANGLE,
},
{
.hook = iptable_mangle_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_FORWARD,
.priority = NF_IP_PRI_MANGLE,
},
{
.hook = iptable_mangle_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_MANGLE,
},
{
.hook = iptable_mangle_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_MANGLE,
},
};
static int __net_init iptable_mangle_net_init(struct net *net) static int __net_init iptable_mangle_net_init(struct net *net)
{ {
...@@ -196,9 +161,11 @@ static int __init iptable_mangle_init(void) ...@@ -196,9 +161,11 @@ static int __init iptable_mangle_init(void)
return ret; return ret;
/* Register hooks */ /* Register hooks */
ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); mangle_ops = xt_hook_link(&packet_mangler, iptable_mangle_hook);
if (ret < 0) if (IS_ERR(mangle_ops)) {
ret = PTR_ERR(mangle_ops);
goto cleanup_table; goto cleanup_table;
}
return ret; return ret;
...@@ -209,7 +176,7 @@ static int __init iptable_mangle_init(void) ...@@ -209,7 +176,7 @@ static int __init iptable_mangle_init(void)
static void __exit iptable_mangle_fini(void) static void __exit iptable_mangle_fini(void)
{ {
nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); xt_hook_unlink(&packet_mangler, mangle_ops);
unregister_pernet_subsys(&iptable_mangle_net_ops); unregister_pernet_subsys(&iptable_mangle_net_ops);
} }
......
...@@ -41,6 +41,7 @@ static const struct xt_table packet_raw = { ...@@ -41,6 +41,7 @@ static const struct xt_table packet_raw = {
.valid_hooks = RAW_VALID_HOOKS, .valid_hooks = RAW_VALID_HOOKS,
.me = THIS_MODULE, .me = THIS_MODULE,
.af = NFPROTO_IPV4, .af = NFPROTO_IPV4,
.priority = NF_IP_PRI_RAW,
}; };
/* The work comes in here from netfilter.c. */ /* The work comes in here from netfilter.c. */
...@@ -61,23 +62,7 @@ iptable_raw_hook(unsigned int hook, struct sk_buff *skb, ...@@ -61,23 +62,7 @@ iptable_raw_hook(unsigned int hook, struct sk_buff *skb,
return ipt_do_table(skb, hook, in, out, net->ipv4.iptable_raw); return ipt_do_table(skb, hook, in, out, net->ipv4.iptable_raw);
} }
/* 'raw' is the very first table. */ static struct nf_hook_ops *rawtable_ops __read_mostly;
static struct nf_hook_ops ipt_ops[] __read_mostly = {
{
.hook = iptable_raw_hook,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_RAW,
.owner = THIS_MODULE,
},
{
.hook = iptable_raw_hook,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_RAW,
.owner = THIS_MODULE,
},
};
static int __net_init iptable_raw_net_init(struct net *net) static int __net_init iptable_raw_net_init(struct net *net)
{ {
...@@ -108,9 +93,11 @@ static int __init iptable_raw_init(void) ...@@ -108,9 +93,11 @@ static int __init iptable_raw_init(void)
return ret; return ret;
/* Register hooks */ /* Register hooks */
ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); rawtable_ops = xt_hook_link(&packet_raw, iptable_raw_hook);
if (ret < 0) if (IS_ERR(rawtable_ops)) {
ret = PTR_ERR(rawtable_ops);
goto cleanup_table; goto cleanup_table;
}
return ret; return ret;
...@@ -121,7 +108,7 @@ static int __init iptable_raw_init(void) ...@@ -121,7 +108,7 @@ static int __init iptable_raw_init(void)
static void __exit iptable_raw_fini(void) static void __exit iptable_raw_fini(void)
{ {
nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); xt_hook_unlink(&packet_raw, rawtable_ops);
unregister_pernet_subsys(&iptable_raw_net_ops); unregister_pernet_subsys(&iptable_raw_net_ops);
} }
......
...@@ -62,6 +62,7 @@ static const struct xt_table security_table = { ...@@ -62,6 +62,7 @@ static const struct xt_table security_table = {
.valid_hooks = SECURITY_VALID_HOOKS, .valid_hooks = SECURITY_VALID_HOOKS,
.me = THIS_MODULE, .me = THIS_MODULE,
.af = NFPROTO_IPV4, .af = NFPROTO_IPV4,
.priority = NF_IP_PRI_SECURITY,
}; };
static unsigned int static unsigned int
...@@ -82,29 +83,7 @@ iptable_security_hook(unsigned int hook, struct sk_buff *skb, ...@@ -82,29 +83,7 @@ iptable_security_hook(unsigned int hook, struct sk_buff *skb,
return ipt_do_table(skb, hook, in, out, net->ipv4.iptable_security); return ipt_do_table(skb, hook, in, out, net->ipv4.iptable_security);
} }
static struct nf_hook_ops ipt_ops[] __read_mostly = { static struct nf_hook_ops *sectbl_ops __read_mostly;
{
.hook = iptable_security_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_SECURITY,
},
{
.hook = iptable_security_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_FORWARD,
.priority = NF_IP_PRI_SECURITY,
},
{
.hook = iptable_security_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_SECURITY,
},
};
static int __net_init iptable_security_net_init(struct net *net) static int __net_init iptable_security_net_init(struct net *net)
{ {
...@@ -135,9 +114,11 @@ static int __init iptable_security_init(void) ...@@ -135,9 +114,11 @@ static int __init iptable_security_init(void)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); sectbl_ops = xt_hook_link(&security_table, iptable_security_hook);
if (ret < 0) if (IS_ERR(sectbl_ops)) {
ret = PTR_ERR(sectbl_ops);
goto cleanup_table; goto cleanup_table;
}
return ret; return ret;
...@@ -148,7 +129,7 @@ static int __init iptable_security_init(void) ...@@ -148,7 +129,7 @@ static int __init iptable_security_init(void)
static void __exit iptable_security_fini(void) static void __exit iptable_security_fini(void)
{ {
nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); xt_hook_unlink(&security_table, sectbl_ops);
unregister_pernet_subsys(&iptable_security_net_ops); unregister_pernet_subsys(&iptable_security_net_ops);
} }
......
...@@ -56,6 +56,7 @@ static const struct xt_table packet_filter = { ...@@ -56,6 +56,7 @@ static const struct xt_table packet_filter = {
.valid_hooks = FILTER_VALID_HOOKS, .valid_hooks = FILTER_VALID_HOOKS,
.me = THIS_MODULE, .me = THIS_MODULE,
.af = NFPROTO_IPV6, .af = NFPROTO_IPV6,
.priority = NF_IP6_PRI_FILTER,
}; };
/* The work comes in here from netfilter.c. */ /* The work comes in here from netfilter.c. */
...@@ -69,29 +70,7 @@ ip6table_filter_hook(unsigned int hook, struct sk_buff *skb, ...@@ -69,29 +70,7 @@ ip6table_filter_hook(unsigned int hook, struct sk_buff *skb,
return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_filter); return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_filter);
} }
static struct nf_hook_ops ip6t_ops[] __read_mostly = { static struct nf_hook_ops *filter_ops __read_mostly;
{
.hook = ip6table_filter_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP6_PRI_FILTER,
},
{
.hook = ip6table_filter_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_FORWARD,
.priority = NF_IP6_PRI_FILTER,
},
{
.hook = ip6table_filter_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_FILTER,
},
};
/* Default to forward because I got too much mail already. */ /* Default to forward because I got too much mail already. */
static int forward = NF_ACCEPT; static int forward = NF_ACCEPT;
...@@ -134,9 +113,11 @@ static int __init ip6table_filter_init(void) ...@@ -134,9 +113,11 @@ static int __init ip6table_filter_init(void)
return ret; return ret;
/* Register hooks */ /* Register hooks */
ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); filter_ops = xt_hook_link(&packet_filter, ip6table_filter_hook);
if (ret < 0) if (IS_ERR(filter_ops)) {
ret = PTR_ERR(filter_ops);
goto cleanup_table; goto cleanup_table;
}
return ret; return ret;
...@@ -147,7 +128,7 @@ static int __init ip6table_filter_init(void) ...@@ -147,7 +128,7 @@ static int __init ip6table_filter_init(void)
static void __exit ip6table_filter_fini(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); unregister_pernet_subsys(&ip6table_filter_net_ops);
} }
......
...@@ -62,6 +62,7 @@ static const struct xt_table packet_mangler = { ...@@ -62,6 +62,7 @@ static const struct xt_table packet_mangler = {
.valid_hooks = MANGLE_VALID_HOOKS, .valid_hooks = MANGLE_VALID_HOOKS,
.me = THIS_MODULE, .me = THIS_MODULE,
.af = NFPROTO_IPV6, .af = NFPROTO_IPV6,
.priority = NF_IP6_PRI_MANGLE,
}; };
static unsigned int static unsigned int
...@@ -122,44 +123,7 @@ ip6table_mangle_hook(unsigned int hook, struct sk_buff *skb, ...@@ -122,44 +123,7 @@ ip6table_mangle_hook(unsigned int hook, struct sk_buff *skb,
dev_net(in)->ipv6.ip6table_mangle); dev_net(in)->ipv6.ip6table_mangle);
} }
static struct nf_hook_ops ip6t_ops[] __read_mostly = { static struct nf_hook_ops *mangle_ops __read_mostly;
{
.hook = ip6table_mangle_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP6_PRI_MANGLE,
},
{
.hook = ip6table_mangle_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP6_PRI_MANGLE,
},
{
.hook = ip6table_mangle_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_FORWARD,
.priority = NF_IP6_PRI_MANGLE,
},
{
.hook = ip6table_mangle_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_MANGLE,
},
{
.hook = ip6table_mangle_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP6_PRI_MANGLE,
},
};
static int __net_init ip6table_mangle_net_init(struct net *net) static int __net_init ip6table_mangle_net_init(struct net *net)
{ {
/* Register table */ /* Register table */
...@@ -189,9 +153,11 @@ static int __init ip6table_mangle_init(void) ...@@ -189,9 +153,11 @@ static int __init ip6table_mangle_init(void)
return ret; return ret;
/* Register hooks */ /* Register hooks */
ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); mangle_ops = xt_hook_link(&packet_mangler, ip6table_mangle_hook);
if (ret < 0) if (IS_ERR(mangle_ops)) {
ret = PTR_ERR(mangle_ops);
goto cleanup_table; goto cleanup_table;
}
return ret; return ret;
...@@ -202,7 +168,7 @@ static int __init ip6table_mangle_init(void) ...@@ -202,7 +168,7 @@ static int __init ip6table_mangle_init(void)
static void __exit ip6table_mangle_fini(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); unregister_pernet_subsys(&ip6table_mangle_net_ops);
} }
......
...@@ -40,6 +40,7 @@ static const struct xt_table packet_raw = { ...@@ -40,6 +40,7 @@ static const struct xt_table packet_raw = {
.valid_hooks = RAW_VALID_HOOKS, .valid_hooks = RAW_VALID_HOOKS,
.me = THIS_MODULE, .me = THIS_MODULE,
.af = NFPROTO_IPV6, .af = NFPROTO_IPV6,
.priority = NF_IP6_PRI_FIRST,
}; };
/* The work comes in here from netfilter.c. */ /* The work comes in here from netfilter.c. */
...@@ -53,22 +54,7 @@ ip6table_raw_hook(unsigned int hook, struct sk_buff *skb, ...@@ -53,22 +54,7 @@ ip6table_raw_hook(unsigned int hook, struct sk_buff *skb,
return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_raw); return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_raw);
} }
static struct nf_hook_ops ip6t_ops[] __read_mostly = { static struct nf_hook_ops *rawtable_ops __read_mostly;
{
.hook = ip6table_raw_hook,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP6_PRI_FIRST,
.owner = THIS_MODULE,
},
{
.hook = ip6table_raw_hook,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_FIRST,
.owner = THIS_MODULE,
},
};
static int __net_init ip6table_raw_net_init(struct net *net) static int __net_init ip6table_raw_net_init(struct net *net)
{ {
...@@ -99,9 +85,11 @@ static int __init ip6table_raw_init(void) ...@@ -99,9 +85,11 @@ static int __init ip6table_raw_init(void)
return ret; return ret;
/* Register hooks */ /* Register hooks */
ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); rawtable_ops = xt_hook_link(&packet_raw, ip6table_raw_hook);
if (ret < 0) if (IS_ERR(rawtable_ops)) {
ret = PTR_ERR(rawtable_ops);
goto cleanup_table; goto cleanup_table;
}
return ret; return ret;
...@@ -112,7 +100,7 @@ static int __init ip6table_raw_init(void) ...@@ -112,7 +100,7 @@ static int __init ip6table_raw_init(void)
static void __exit ip6table_raw_fini(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); unregister_pernet_subsys(&ip6table_raw_net_ops);
} }
......
...@@ -61,6 +61,7 @@ static const struct xt_table security_table = { ...@@ -61,6 +61,7 @@ static const struct xt_table security_table = {
.valid_hooks = SECURITY_VALID_HOOKS, .valid_hooks = SECURITY_VALID_HOOKS,
.me = THIS_MODULE, .me = THIS_MODULE,
.af = NFPROTO_IPV6, .af = NFPROTO_IPV6,
.priority = NF_IP6_PRI_SECURITY,
}; };
static unsigned int static unsigned int
...@@ -74,29 +75,7 @@ ip6table_security_hook(unsigned int hook, struct sk_buff *skb, ...@@ -74,29 +75,7 @@ ip6table_security_hook(unsigned int hook, struct sk_buff *skb,
return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_security); return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_security);
} }
static struct nf_hook_ops ip6t_ops[] __read_mostly = { static struct nf_hook_ops *sectbl_ops __read_mostly;
{
.hook = ip6table_security_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP6_PRI_SECURITY,
},
{
.hook = ip6table_security_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_FORWARD,
.priority = NF_IP6_PRI_SECURITY,
},
{
.hook = ip6table_security_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_SECURITY,
},
};
static int __net_init ip6table_security_net_init(struct net *net) static int __net_init ip6table_security_net_init(struct net *net)
{ {
...@@ -127,9 +106,11 @@ static int __init ip6table_security_init(void) ...@@ -127,9 +106,11 @@ static int __init ip6table_security_init(void)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); sectbl_ops = xt_hook_link(&security_table, ip6table_security_hook);
if (ret < 0) if (IS_ERR(sectbl_ops)) {
ret = PTR_ERR(sectbl_ops);
goto cleanup_table; goto cleanup_table;
}
return ret; return ret;
...@@ -140,7 +121,7 @@ static int __init ip6table_security_init(void) ...@@ -140,7 +121,7 @@ static int __init ip6table_security_init(void)
static void __exit ip6table_security_fini(void) 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); unregister_pernet_subsys(&ip6table_security_net_ops);
} }
......
...@@ -1091,6 +1091,60 @@ static const struct file_operations xt_target_ops = { ...@@ -1091,6 +1091,60 @@ static const struct file_operations xt_target_ops = {
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
/**
* xt_hook_link - set up hooks for a new table
* @table: table with metadata needed to set up hooks
* @fn: Hook function
*
* This function will take care of creating and registering the necessary
* Netfilter hooks for XT tables.
*/
struct nf_hook_ops *xt_hook_link(const struct xt_table *table, nf_hookfn *fn)
{
unsigned int hook_mask = table->valid_hooks;
uint8_t i, num_hooks = hweight32(hook_mask);
uint8_t hooknum;
struct nf_hook_ops *ops;
int ret;
ops = kmalloc(sizeof(*ops) * num_hooks, GFP_KERNEL);
if (ops == NULL)
return ERR_PTR(-ENOMEM);
for (i = 0, hooknum = 0; i < num_hooks && hook_mask != 0;
hook_mask >>= 1, ++hooknum) {
if (!(hook_mask & 1))
continue;
ops[i].hook = fn;
ops[i].owner = table->me;
ops[i].pf = table->af;
ops[i].hooknum = hooknum;
ops[i].priority = table->priority;
++i;
}
ret = nf_register_hooks(ops, num_hooks);
if (ret < 0) {
kfree(ops);
return ERR_PTR(ret);
}
return ops;
}
EXPORT_SYMBOL_GPL(xt_hook_link);
/**
* xt_hook_unlink - remove hooks for a table
* @ops: nf_hook_ops array as returned by nf_hook_link
* @hook_mask: the very same mask that was passed to nf_hook_link
*/
void xt_hook_unlink(const struct xt_table *table, struct nf_hook_ops *ops)
{
nf_unregister_hooks(ops, hweight32(table->valid_hooks));
kfree(ops);
}
EXPORT_SYMBOL_GPL(xt_hook_unlink);
int xt_proto_init(struct net *net, u_int8_t af) int xt_proto_init(struct net *net, u_int8_t af)
{ {
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment