diff options
author | Patrick McHardy <kaber@trash.net> | 2014-01-03 07:16:16 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-01-07 17:57:25 -0500 |
commit | 1d49144c0aaa61be4e3ccbef9cc5c40b0ec5f2fe (patch) | |
tree | 1711f39fb9f9ba1fed9bcb9afcf55499b0cef3b6 | |
parent | 115a60b173af0170e0db26b9a3fd6a911fba70a3 (diff) |
netfilter: nf_tables: add "inet" table for IPv4/IPv6
This patch adds a new table family and a new filter chain that you can
use to attach IPv4 and IPv6 rules. This should help to simplify
rule-set maintainance in dual-stack setups.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | include/net/netfilter/nf_tables_ipv4.h | 2 | ||||
-rw-r--r-- | include/net/netfilter/nf_tables_ipv6.h | 2 | ||||
-rw-r--r-- | include/net/netns/nftables.h | 1 | ||||
-rw-r--r-- | include/uapi/linux/netfilter.h | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_tables_ipv4.c | 3 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_tables_ipv6.c | 3 | ||||
-rw-r--r-- | net/netfilter/Kconfig | 8 | ||||
-rw-r--r-- | net/netfilter/Makefile | 1 | ||||
-rw-r--r-- | net/netfilter/nf_tables_inet.c | 97 |
9 files changed, 116 insertions, 2 deletions
diff --git a/include/net/netfilter/nf_tables_ipv4.h b/include/net/netfilter/nf_tables_ipv4.h index 1be1c2c197ee..f7b3a669aad3 100644 --- a/include/net/netfilter/nf_tables_ipv4.h +++ b/include/net/netfilter/nf_tables_ipv4.h | |||
@@ -20,4 +20,6 @@ nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt, | |||
20 | pkt->xt.fragoff = ntohs(ip->frag_off) & IP_OFFSET; | 20 | pkt->xt.fragoff = ntohs(ip->frag_off) & IP_OFFSET; |
21 | } | 21 | } |
22 | 22 | ||
23 | extern struct nft_af_info nft_af_ipv4; | ||
24 | |||
23 | #endif | 25 | #endif |
diff --git a/include/net/netfilter/nf_tables_ipv6.h b/include/net/netfilter/nf_tables_ipv6.h index 4a9b88a65963..3d8ae489be0d 100644 --- a/include/net/netfilter/nf_tables_ipv6.h +++ b/include/net/netfilter/nf_tables_ipv6.h | |||
@@ -27,4 +27,6 @@ nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt, | |||
27 | return 0; | 27 | return 0; |
28 | } | 28 | } |
29 | 29 | ||
30 | extern struct nft_af_info nft_af_ipv6; | ||
31 | |||
30 | #endif | 32 | #endif |
diff --git a/include/net/netns/nftables.h b/include/net/netns/nftables.h index 15d056d534e3..26a394cb91a8 100644 --- a/include/net/netns/nftables.h +++ b/include/net/netns/nftables.h | |||
@@ -10,6 +10,7 @@ struct netns_nftables { | |||
10 | struct list_head commit_list; | 10 | struct list_head commit_list; |
11 | struct nft_af_info *ipv4; | 11 | struct nft_af_info *ipv4; |
12 | struct nft_af_info *ipv6; | 12 | struct nft_af_info *ipv6; |
13 | struct nft_af_info *inet; | ||
13 | struct nft_af_info *arp; | 14 | struct nft_af_info *arp; |
14 | struct nft_af_info *bridge; | 15 | struct nft_af_info *bridge; |
15 | u8 gencursor; | 16 | u8 gencursor; |
diff --git a/include/uapi/linux/netfilter.h b/include/uapi/linux/netfilter.h index f7dc0ebeeba5..ef1b1f88ca18 100644 --- a/include/uapi/linux/netfilter.h +++ b/include/uapi/linux/netfilter.h | |||
@@ -53,6 +53,7 @@ enum nf_inet_hooks { | |||
53 | 53 | ||
54 | enum { | 54 | enum { |
55 | NFPROTO_UNSPEC = 0, | 55 | NFPROTO_UNSPEC = 0, |
56 | NFPROTO_INET = 1, | ||
56 | NFPROTO_IPV4 = 2, | 57 | NFPROTO_IPV4 = 2, |
57 | NFPROTO_ARP = 3, | 58 | NFPROTO_ARP = 3, |
58 | NFPROTO_BRIDGE = 7, | 59 | NFPROTO_BRIDGE = 7, |
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c index 177c3bceb7ca..da927dc9f636 100644 --- a/net/ipv4/netfilter/nf_tables_ipv4.c +++ b/net/ipv4/netfilter/nf_tables_ipv4.c | |||
@@ -48,7 +48,7 @@ static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops, | |||
48 | return nft_do_chain_ipv4(ops, skb, in, out, okfn); | 48 | return nft_do_chain_ipv4(ops, skb, in, out, okfn); |
49 | } | 49 | } |
50 | 50 | ||
51 | static struct nft_af_info nft_af_ipv4 __read_mostly = { | 51 | struct nft_af_info nft_af_ipv4 __read_mostly = { |
52 | .family = NFPROTO_IPV4, | 52 | .family = NFPROTO_IPV4, |
53 | .nhooks = NF_INET_NUMHOOKS, | 53 | .nhooks = NF_INET_NUMHOOKS, |
54 | .owner = THIS_MODULE, | 54 | .owner = THIS_MODULE, |
@@ -61,6 +61,7 @@ static struct nft_af_info nft_af_ipv4 __read_mostly = { | |||
61 | [NF_INET_POST_ROUTING] = nft_do_chain_ipv4, | 61 | [NF_INET_POST_ROUTING] = nft_do_chain_ipv4, |
62 | }, | 62 | }, |
63 | }; | 63 | }; |
64 | EXPORT_SYMBOL_GPL(nft_af_ipv4); | ||
64 | 65 | ||
65 | static int nf_tables_ipv4_init_net(struct net *net) | 66 | static int nf_tables_ipv4_init_net(struct net *net) |
66 | { | 67 | { |
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c index 642280e44b65..025e7f4e8ac5 100644 --- a/net/ipv6/netfilter/nf_tables_ipv6.c +++ b/net/ipv6/netfilter/nf_tables_ipv6.c | |||
@@ -47,7 +47,7 @@ static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops, | |||
47 | return nft_do_chain_ipv6(ops, skb, in, out, okfn); | 47 | return nft_do_chain_ipv6(ops, skb, in, out, okfn); |
48 | } | 48 | } |
49 | 49 | ||
50 | static struct nft_af_info nft_af_ipv6 __read_mostly = { | 50 | struct nft_af_info nft_af_ipv6 __read_mostly = { |
51 | .family = NFPROTO_IPV6, | 51 | .family = NFPROTO_IPV6, |
52 | .nhooks = NF_INET_NUMHOOKS, | 52 | .nhooks = NF_INET_NUMHOOKS, |
53 | .owner = THIS_MODULE, | 53 | .owner = THIS_MODULE, |
@@ -60,6 +60,7 @@ static struct nft_af_info nft_af_ipv6 __read_mostly = { | |||
60 | [NF_INET_POST_ROUTING] = nft_do_chain_ipv6, | 60 | [NF_INET_POST_ROUTING] = nft_do_chain_ipv6, |
61 | }, | 61 | }, |
62 | }; | 62 | }; |
63 | EXPORT_SYMBOL_GPL(nft_af_ipv6); | ||
63 | 64 | ||
64 | static int nf_tables_ipv6_init_net(struct net *net) | 65 | static int nf_tables_ipv6_init_net(struct net *net) |
65 | { | 66 | { |
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index c3b3b26c4c4e..37d2092705a7 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig | |||
@@ -428,6 +428,14 @@ config NF_TABLES | |||
428 | 428 | ||
429 | To compile it as a module, choose M here. | 429 | To compile it as a module, choose M here. |
430 | 430 | ||
431 | config NF_TABLES_INET | ||
432 | depends on NF_TABLES | ||
433 | select NF_TABLES_IPV4 | ||
434 | select NF_TABLES_IPV6 | ||
435 | tristate "Netfilter nf_tables mixed IPv4/IPv6 tables support" | ||
436 | help | ||
437 | This option enables support for a mixed IPv4/IPv6 "inet" table. | ||
438 | |||
431 | config NFT_EXTHDR | 439 | config NFT_EXTHDR |
432 | depends on NF_TABLES | 440 | depends on NF_TABLES |
433 | tristate "Netfilter nf_tables IPv6 exthdr module" | 441 | tristate "Netfilter nf_tables IPv6 exthdr module" |
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 78b4e1c9c595..74c066109334 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile | |||
@@ -70,6 +70,7 @@ nf_tables-objs += nft_immediate.o nft_cmp.o nft_lookup.o | |||
70 | nf_tables-objs += nft_bitwise.o nft_byteorder.o nft_payload.o | 70 | nf_tables-objs += nft_bitwise.o nft_byteorder.o nft_payload.o |
71 | 71 | ||
72 | obj-$(CONFIG_NF_TABLES) += nf_tables.o | 72 | obj-$(CONFIG_NF_TABLES) += nf_tables.o |
73 | obj-$(CONFIG_NF_TABLES_INET) += nf_tables_inet.o | ||
73 | obj-$(CONFIG_NFT_COMPAT) += nft_compat.o | 74 | obj-$(CONFIG_NFT_COMPAT) += nft_compat.o |
74 | obj-$(CONFIG_NFT_EXTHDR) += nft_exthdr.o | 75 | obj-$(CONFIG_NFT_EXTHDR) += nft_exthdr.o |
75 | obj-$(CONFIG_NFT_META) += nft_meta.o | 76 | obj-$(CONFIG_NFT_META) += nft_meta.o |
diff --git a/net/netfilter/nf_tables_inet.c b/net/netfilter/nf_tables_inet.c new file mode 100644 index 000000000000..ac0edcb549de --- /dev/null +++ b/net/netfilter/nf_tables_inet.c | |||
@@ -0,0 +1,97 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012-2014 Patrick McHardy <kaber@trash.net> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/ip.h> | ||
12 | #include <linux/netfilter_ipv4.h> | ||
13 | #include <linux/netfilter_ipv6.h> | ||
14 | #include <net/netfilter/nf_tables.h> | ||
15 | #include <net/netfilter/nf_tables_ipv4.h> | ||
16 | #include <net/netfilter/nf_tables_ipv6.h> | ||
17 | #include <net/ip.h> | ||
18 | |||
19 | static void nft_inet_hook_ops_init(struct nf_hook_ops *ops, unsigned int n) | ||
20 | { | ||
21 | struct nft_af_info *afi; | ||
22 | |||
23 | if (n == 1) | ||
24 | afi = &nft_af_ipv4; | ||
25 | else | ||
26 | afi = &nft_af_ipv6; | ||
27 | |||
28 | ops->pf = afi->family; | ||
29 | if (afi->hooks[ops->hooknum]) | ||
30 | ops->hook = afi->hooks[ops->hooknum]; | ||
31 | } | ||
32 | |||
33 | static struct nft_af_info nft_af_inet __read_mostly = { | ||
34 | .family = NFPROTO_INET, | ||
35 | .nhooks = NF_INET_NUMHOOKS, | ||
36 | .owner = THIS_MODULE, | ||
37 | .nops = 2, | ||
38 | .hook_ops_init = nft_inet_hook_ops_init, | ||
39 | }; | ||
40 | |||
41 | static int __net_init nf_tables_inet_init_net(struct net *net) | ||
42 | { | ||
43 | net->nft.inet = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL); | ||
44 | if (net->nft.inet == NULL) | ||
45 | return -ENOMEM; | ||
46 | memcpy(net->nft.inet, &nft_af_inet, sizeof(nft_af_inet)); | ||
47 | |||
48 | if (nft_register_afinfo(net, net->nft.inet) < 0) | ||
49 | goto err; | ||
50 | |||
51 | return 0; | ||
52 | |||
53 | err: | ||
54 | kfree(net->nft.inet); | ||
55 | return -ENOMEM; | ||
56 | } | ||
57 | |||
58 | static void __net_exit nf_tables_inet_exit_net(struct net *net) | ||
59 | { | ||
60 | nft_unregister_afinfo(net->nft.inet); | ||
61 | kfree(net->nft.inet); | ||
62 | } | ||
63 | |||
64 | static struct pernet_operations nf_tables_inet_net_ops = { | ||
65 | .init = nf_tables_inet_init_net, | ||
66 | .exit = nf_tables_inet_exit_net, | ||
67 | }; | ||
68 | |||
69 | static struct nf_chain_type filter_inet = { | ||
70 | .family = NFPROTO_INET, | ||
71 | .name = "filter", | ||
72 | .type = NFT_CHAIN_T_DEFAULT, | ||
73 | .hook_mask = (1 << NF_INET_LOCAL_IN) | | ||
74 | (1 << NF_INET_LOCAL_OUT) | | ||
75 | (1 << NF_INET_FORWARD) | | ||
76 | (1 << NF_INET_PRE_ROUTING) | | ||
77 | (1 << NF_INET_POST_ROUTING), | ||
78 | }; | ||
79 | |||
80 | static int __init nf_tables_inet_init(void) | ||
81 | { | ||
82 | nft_register_chain_type(&filter_inet); | ||
83 | return register_pernet_subsys(&nf_tables_inet_net_ops); | ||
84 | } | ||
85 | |||
86 | static void __exit nf_tables_inet_exit(void) | ||
87 | { | ||
88 | unregister_pernet_subsys(&nf_tables_inet_net_ops); | ||
89 | nft_unregister_chain_type(&filter_inet); | ||
90 | } | ||
91 | |||
92 | module_init(nf_tables_inet_init); | ||
93 | module_exit(nf_tables_inet_exit); | ||
94 | |||
95 | MODULE_LICENSE("GPL"); | ||
96 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
97 | MODULE_ALIAS_NFT_FAMILY(1); | ||