aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-01-09 21:36:01 -0500
committerDavid S. Miller <davem@davemloft.net>2014-01-09 21:36:01 -0500
commit751fcac19aeb4f10a246c777517f393d7bc7a9a8 (patch)
tree62c54b84ef9f18e2dc9abe53ee0a502755fcfd6d /net/ipv6
parentbfec4c3b71c25d307d8e4005518fb5dbff43192d (diff)
parentcf4dfa85395ebe2769267a072b39e48301669842 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nftables
Pablo Neira Ayuso says: ==================== nf_tables updates for net-next The following patchset contains the following nf_tables updates, mostly updates from Patrick McHardy, they are: * Add the "inet" table and filter chain type for this new netfilter family: NFPROTO_INET. This special table/chain allows IPv4 and IPv6 rules, this should help to simplify the burden in the administration of dual stack firewalls. This also includes several patches to prepare the infrastructure for this new table and a new meta extension to match the layer 3 and 4 protocol numbers, from Patrick McHardy. * Load both IPv4 and IPv6 conntrack modules in nft_ct if the rule is used in NFPROTO_INET, as we don't certainly know which one would be used, also from Patrick McHardy. * Do not allow to delete a table that contains sets, otherwise these sets become orphan, from Patrick McHardy. * Hold a reference to the corresponding nf_tables family module when creating a table of that family type, to avoid the module deletion when in use, from Patrick McHardy. * Update chain counters before setting the chain policy to ensure that we don't leave the chain in inconsistent state in case of errors (aka. restore chain atomicity). This also fixes a possible leak if it fails to allocate the chain counters if no counters are passed to be restored, from Patrick McHardy. * Don't check for overflows in the table counter if we are just renaming a chain, from Patrick McHardy. * Replay the netlink request after dropping the nfnl lock to load the module that supports provides a chain type, from Patrick. * Fix chain type module references, from Patrick. * Several cleanups, function renames, constification and code refactorizations also from Patrick McHardy. * Add support to set the connmark, this can be used to set it based on the meta mark (similar feature to -j CONNMARK --restore), from Kristian Evensen. * A couple of fixes to the recently added meta/set support and nft_reject, and fix missing chain type unregistration if we fail to register our the family table/filter chain type, from myself. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/netfilter/nf_tables_ipv6.c65
-rw-r--r--net/ipv6/netfilter/nft_chain_nat_ipv6.c10
-rw-r--r--net/ipv6/netfilter/nft_chain_route_ipv6.c10
3 files changed, 43 insertions, 42 deletions
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index d77db8a13505..0d812b31277d 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -16,34 +16,51 @@
16#include <net/netfilter/nf_tables.h> 16#include <net/netfilter/nf_tables.h>
17#include <net/netfilter/nf_tables_ipv6.h> 17#include <net/netfilter/nf_tables_ipv6.h>
18 18
19static unsigned int nft_do_chain_ipv6(const struct nf_hook_ops *ops,
20 struct sk_buff *skb,
21 const struct net_device *in,
22 const struct net_device *out,
23 int (*okfn)(struct sk_buff *))
24{
25 struct nft_pktinfo pkt;
26
27 /* malformed packet, drop it */
28 if (nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out) < 0)
29 return NF_DROP;
30
31 return nft_do_chain(&pkt, ops);
32}
33
19static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops, 34static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops,
20 struct sk_buff *skb, 35 struct sk_buff *skb,
21 const struct net_device *in, 36 const struct net_device *in,
22 const struct net_device *out, 37 const struct net_device *out,
23 int (*okfn)(struct sk_buff *)) 38 int (*okfn)(struct sk_buff *))
24{ 39{
25 struct nft_pktinfo pkt;
26
27 if (unlikely(skb->len < sizeof(struct ipv6hdr))) { 40 if (unlikely(skb->len < sizeof(struct ipv6hdr))) {
28 if (net_ratelimit()) 41 if (net_ratelimit())
29 pr_info("nf_tables_ipv6: ignoring short SOCK_RAW " 42 pr_info("nf_tables_ipv6: ignoring short SOCK_RAW "
30 "packet\n"); 43 "packet\n");
31 return NF_ACCEPT; 44 return NF_ACCEPT;
32 } 45 }
33 if (nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out) < 0)
34 return NF_DROP;
35 46
36 return nft_do_chain_pktinfo(&pkt, ops); 47 return nft_do_chain_ipv6(ops, skb, in, out, okfn);
37} 48}
38 49
39static struct nft_af_info nft_af_ipv6 __read_mostly = { 50struct nft_af_info nft_af_ipv6 __read_mostly = {
40 .family = NFPROTO_IPV6, 51 .family = NFPROTO_IPV6,
41 .nhooks = NF_INET_NUMHOOKS, 52 .nhooks = NF_INET_NUMHOOKS,
42 .owner = THIS_MODULE, 53 .owner = THIS_MODULE,
54 .nops = 1,
43 .hooks = { 55 .hooks = {
56 [NF_INET_LOCAL_IN] = nft_do_chain_ipv6,
44 [NF_INET_LOCAL_OUT] = nft_ipv6_output, 57 [NF_INET_LOCAL_OUT] = nft_ipv6_output,
58 [NF_INET_FORWARD] = nft_do_chain_ipv6,
59 [NF_INET_PRE_ROUTING] = nft_do_chain_ipv6,
60 [NF_INET_POST_ROUTING] = nft_do_chain_ipv6,
45 }, 61 },
46}; 62};
63EXPORT_SYMBOL_GPL(nft_af_ipv6);
47 64
48static int nf_tables_ipv6_init_net(struct net *net) 65static int nf_tables_ipv6_init_net(struct net *net)
49{ 66{
@@ -73,44 +90,28 @@ static struct pernet_operations nf_tables_ipv6_net_ops = {
73 .exit = nf_tables_ipv6_exit_net, 90 .exit = nf_tables_ipv6_exit_net,
74}; 91};
75 92
76static unsigned int 93static const struct nf_chain_type filter_ipv6 = {
77nft_do_chain_ipv6(const struct nf_hook_ops *ops,
78 struct sk_buff *skb,
79 const struct net_device *in,
80 const struct net_device *out,
81 int (*okfn)(struct sk_buff *))
82{
83 struct nft_pktinfo pkt;
84
85 /* malformed packet, drop it */
86 if (nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out) < 0)
87 return NF_DROP;
88
89 return nft_do_chain_pktinfo(&pkt, ops);
90}
91
92static struct nf_chain_type filter_ipv6 = {
93 .family = NFPROTO_IPV6,
94 .name = "filter", 94 .name = "filter",
95 .type = NFT_CHAIN_T_DEFAULT, 95 .type = NFT_CHAIN_T_DEFAULT,
96 .family = NFPROTO_IPV6,
97 .owner = THIS_MODULE,
96 .hook_mask = (1 << NF_INET_LOCAL_IN) | 98 .hook_mask = (1 << NF_INET_LOCAL_IN) |
97 (1 << NF_INET_LOCAL_OUT) | 99 (1 << NF_INET_LOCAL_OUT) |
98 (1 << NF_INET_FORWARD) | 100 (1 << NF_INET_FORWARD) |
99 (1 << NF_INET_PRE_ROUTING) | 101 (1 << NF_INET_PRE_ROUTING) |
100 (1 << NF_INET_POST_ROUTING), 102 (1 << NF_INET_POST_ROUTING),
101 .fn = {
102 [NF_INET_LOCAL_IN] = nft_do_chain_ipv6,
103 [NF_INET_LOCAL_OUT] = nft_ipv6_output,
104 [NF_INET_FORWARD] = nft_do_chain_ipv6,
105 [NF_INET_PRE_ROUTING] = nft_do_chain_ipv6,
106 [NF_INET_POST_ROUTING] = nft_do_chain_ipv6,
107 },
108}; 103};
109 104
110static int __init nf_tables_ipv6_init(void) 105static int __init nf_tables_ipv6_init(void)
111{ 106{
107 int ret;
108
112 nft_register_chain_type(&filter_ipv6); 109 nft_register_chain_type(&filter_ipv6);
113 return register_pernet_subsys(&nf_tables_ipv6_net_ops); 110 ret = register_pernet_subsys(&nf_tables_ipv6_net_ops);
111 if (ret < 0)
112 nft_unregister_chain_type(&filter_ipv6);
113
114 return ret;
114} 115}
115 116
116static void __exit nf_tables_ipv6_exit(void) 117static void __exit nf_tables_ipv6_exit(void)
diff --git a/net/ipv6/netfilter/nft_chain_nat_ipv6.c b/net/ipv6/netfilter/nft_chain_nat_ipv6.c
index e86dcd70dc76..9c3297a768fd 100644
--- a/net/ipv6/netfilter/nft_chain_nat_ipv6.c
+++ b/net/ipv6/netfilter/nft_chain_nat_ipv6.c
@@ -79,7 +79,7 @@ static unsigned int nf_nat_ipv6_fn(const struct nf_hook_ops *ops,
79 79
80 nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out); 80 nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out);
81 81
82 ret = nft_do_chain_pktinfo(&pkt, ops); 82 ret = nft_do_chain(&pkt, ops);
83 if (ret != NF_ACCEPT) 83 if (ret != NF_ACCEPT)
84 return ret; 84 return ret;
85 if (!nf_nat_initialized(ct, maniptype)) { 85 if (!nf_nat_initialized(ct, maniptype)) {
@@ -170,21 +170,21 @@ static unsigned int nf_nat_ipv6_output(const struct nf_hook_ops *ops,
170 return ret; 170 return ret;
171} 171}
172 172
173static struct nf_chain_type nft_chain_nat_ipv6 = { 173static const struct nf_chain_type nft_chain_nat_ipv6 = {
174 .family = NFPROTO_IPV6,
175 .name = "nat", 174 .name = "nat",
176 .type = NFT_CHAIN_T_NAT, 175 .type = NFT_CHAIN_T_NAT,
176 .family = NFPROTO_IPV6,
177 .owner = THIS_MODULE,
177 .hook_mask = (1 << NF_INET_PRE_ROUTING) | 178 .hook_mask = (1 << NF_INET_PRE_ROUTING) |
178 (1 << NF_INET_POST_ROUTING) | 179 (1 << NF_INET_POST_ROUTING) |
179 (1 << NF_INET_LOCAL_OUT) | 180 (1 << NF_INET_LOCAL_OUT) |
180 (1 << NF_INET_LOCAL_IN), 181 (1 << NF_INET_LOCAL_IN),
181 .fn = { 182 .hooks = {
182 [NF_INET_PRE_ROUTING] = nf_nat_ipv6_prerouting, 183 [NF_INET_PRE_ROUTING] = nf_nat_ipv6_prerouting,
183 [NF_INET_POST_ROUTING] = nf_nat_ipv6_postrouting, 184 [NF_INET_POST_ROUTING] = nf_nat_ipv6_postrouting,
184 [NF_INET_LOCAL_OUT] = nf_nat_ipv6_output, 185 [NF_INET_LOCAL_OUT] = nf_nat_ipv6_output,
185 [NF_INET_LOCAL_IN] = nf_nat_ipv6_fn, 186 [NF_INET_LOCAL_IN] = nf_nat_ipv6_fn,
186 }, 187 },
187 .me = THIS_MODULE,
188}; 188};
189 189
190static int __init nft_chain_nat_ipv6_init(void) 190static int __init nft_chain_nat_ipv6_init(void)
diff --git a/net/ipv6/netfilter/nft_chain_route_ipv6.c b/net/ipv6/netfilter/nft_chain_route_ipv6.c
index 3fe40f0456ad..42031299585e 100644
--- a/net/ipv6/netfilter/nft_chain_route_ipv6.c
+++ b/net/ipv6/netfilter/nft_chain_route_ipv6.c
@@ -47,7 +47,7 @@ static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
47 /* flowlabel and prio (includes version, which shouldn't change either */ 47 /* flowlabel and prio (includes version, which shouldn't change either */
48 flowlabel = *((u32 *)ipv6_hdr(skb)); 48 flowlabel = *((u32 *)ipv6_hdr(skb));
49 49
50 ret = nft_do_chain_pktinfo(&pkt, ops); 50 ret = nft_do_chain(&pkt, ops);
51 if (ret != NF_DROP && ret != NF_QUEUE && 51 if (ret != NF_DROP && ret != NF_QUEUE &&
52 (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) || 52 (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) ||
53 memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) || 53 memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) ||
@@ -59,15 +59,15 @@ static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
59 return ret; 59 return ret;
60} 60}
61 61
62static struct nf_chain_type nft_chain_route_ipv6 = { 62static const struct nf_chain_type nft_chain_route_ipv6 = {
63 .family = NFPROTO_IPV6,
64 .name = "route", 63 .name = "route",
65 .type = NFT_CHAIN_T_ROUTE, 64 .type = NFT_CHAIN_T_ROUTE,
65 .family = NFPROTO_IPV6,
66 .owner = THIS_MODULE,
66 .hook_mask = (1 << NF_INET_LOCAL_OUT), 67 .hook_mask = (1 << NF_INET_LOCAL_OUT),
67 .fn = { 68 .hooks = {
68 [NF_INET_LOCAL_OUT] = nf_route_table_hook, 69 [NF_INET_LOCAL_OUT] = nf_route_table_hook,
69 }, 70 },
70 .me = THIS_MODULE,
71}; 71};
72 72
73static int __init nft_chain_route_init(void) 73static int __init nft_chain_route_init(void)