diff options
author | Alexey Dobriyan <adobriyan@sw.ru> | 2008-04-14 03:56:02 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2008-04-14 03:56:02 -0400 |
commit | 666953df353194bef76086fa3f126241cbac3e3a (patch) | |
tree | bd69afed2996b0a521361efcd29e32ea7606e9ff /net/ipv4 | |
parent | 36e2a1b0f7f2598e38952494b91490f58aa221c8 (diff) |
[NETFILTER]: ip_tables: per-netns FILTER/MANGLE/RAW tables for real
Commit 9335f047fe61587ec82ff12fbb1220bcfdd32006 aka
"[NETFILTER]: ip_tables: per-netns FILTER, MANGLE, RAW"
added per-netns _view_ of iptables rules. They were shown to user, but
ignored by filtering code. Now that it's possible to at least ping loopback,
per-netns tables can affect filtering decisions.
netns is taken in case of
PRE_ROUTING, LOCAL_IN -- from in device,
POST_ROUTING, LOCAL_OUT -- from out device,
FORWARD -- from in device which should be equal to out device's netns.
This code is relatively new, so BUG_ON was plugged.
Wrappers were added to a) keep code the same from CONFIG_NET_NS=n users
(overwhelming majority), b) consolidate code in one place -- similar
changes will be done in ipv6 and arp netfilter code.
Signed-off-by: Alexey Dobriyan <adobriyan@sw.ru>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/netfilter/iptable_filter.c | 19 | ||||
-rw-r--r-- | net/ipv4/netfilter/iptable_mangle.c | 49 | ||||
-rw-r--r-- | net/ipv4/netfilter/iptable_raw.c | 6 |
3 files changed, 62 insertions, 12 deletions
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 69f3d7e6e96f..7fcf60adbbed 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c | |||
@@ -63,13 +63,25 @@ static struct xt_table packet_filter = { | |||
63 | 63 | ||
64 | /* The work comes in here from netfilter.c. */ | 64 | /* The work comes in here from netfilter.c. */ |
65 | static unsigned int | 65 | static unsigned int |
66 | ipt_local_in_hook(unsigned int hook, | ||
67 | struct sk_buff *skb, | ||
68 | const struct net_device *in, | ||
69 | const struct net_device *out, | ||
70 | int (*okfn)(struct sk_buff *)) | ||
71 | { | ||
72 | return ipt_do_table(skb, hook, in, out, | ||
73 | nf_local_in_net(in, out)->ipv4.iptable_filter); | ||
74 | } | ||
75 | |||
76 | static unsigned int | ||
66 | ipt_hook(unsigned int hook, | 77 | ipt_hook(unsigned int hook, |
67 | struct sk_buff *skb, | 78 | struct sk_buff *skb, |
68 | const struct net_device *in, | 79 | const struct net_device *in, |
69 | const struct net_device *out, | 80 | const struct net_device *out, |
70 | int (*okfn)(struct sk_buff *)) | 81 | int (*okfn)(struct sk_buff *)) |
71 | { | 82 | { |
72 | return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_filter); | 83 | return ipt_do_table(skb, hook, in, out, |
84 | nf_forward_net(in, out)->ipv4.iptable_filter); | ||
73 | } | 85 | } |
74 | 86 | ||
75 | static unsigned int | 87 | static unsigned int |
@@ -88,12 +100,13 @@ ipt_local_out_hook(unsigned int hook, | |||
88 | return NF_ACCEPT; | 100 | return NF_ACCEPT; |
89 | } | 101 | } |
90 | 102 | ||
91 | return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_filter); | 103 | return ipt_do_table(skb, hook, in, out, |
104 | nf_local_out_net(in, out)->ipv4.iptable_filter); | ||
92 | } | 105 | } |
93 | 106 | ||
94 | static struct nf_hook_ops ipt_ops[] __read_mostly = { | 107 | static struct nf_hook_ops ipt_ops[] __read_mostly = { |
95 | { | 108 | { |
96 | .hook = ipt_hook, | 109 | .hook = ipt_local_in_hook, |
97 | .owner = THIS_MODULE, | 110 | .owner = THIS_MODULE, |
98 | .pf = PF_INET, | 111 | .pf = PF_INET, |
99 | .hooknum = NF_INET_LOCAL_IN, | 112 | .hooknum = NF_INET_LOCAL_IN, |
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index c55a210853a7..ba827035b691 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c | |||
@@ -74,13 +74,47 @@ static struct xt_table packet_mangler = { | |||
74 | 74 | ||
75 | /* The work comes in here from netfilter.c. */ | 75 | /* The work comes in here from netfilter.c. */ |
76 | static unsigned int | 76 | static unsigned int |
77 | ipt_route_hook(unsigned int hook, | 77 | ipt_pre_routing_hook(unsigned int hook, |
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 | return ipt_do_table(skb, hook, in, out, | ||
84 | nf_pre_routing_net(in, out)->ipv4.iptable_mangle); | ||
85 | } | ||
86 | |||
87 | static unsigned int | ||
88 | ipt_post_routing_hook(unsigned int hook, | ||
89 | struct sk_buff *skb, | ||
90 | const struct net_device *in, | ||
91 | const struct net_device *out, | ||
92 | int (*okfn)(struct sk_buff *)) | ||
93 | { | ||
94 | return ipt_do_table(skb, hook, in, out, | ||
95 | nf_post_routing_net(in, out)->ipv4.iptable_mangle); | ||
96 | } | ||
97 | |||
98 | static unsigned int | ||
99 | ipt_local_in_hook(unsigned int hook, | ||
100 | struct sk_buff *skb, | ||
101 | const struct net_device *in, | ||
102 | const struct net_device *out, | ||
103 | int (*okfn)(struct sk_buff *)) | ||
104 | { | ||
105 | return ipt_do_table(skb, hook, in, out, | ||
106 | nf_local_in_net(in, out)->ipv4.iptable_mangle); | ||
107 | } | ||
108 | |||
109 | static unsigned int | ||
110 | ipt_forward_hook(unsigned int hook, | ||
78 | struct sk_buff *skb, | 111 | struct sk_buff *skb, |
79 | const struct net_device *in, | 112 | const struct net_device *in, |
80 | const struct net_device *out, | 113 | const struct net_device *out, |
81 | int (*okfn)(struct sk_buff *)) | 114 | int (*okfn)(struct sk_buff *)) |
82 | { | 115 | { |
83 | return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_mangle); | 116 | return ipt_do_table(skb, hook, in, out, |
117 | nf_forward_net(in, out)->ipv4.iptable_mangle); | ||
84 | } | 118 | } |
85 | 119 | ||
86 | static unsigned int | 120 | static unsigned int |
@@ -112,7 +146,8 @@ ipt_local_hook(unsigned int hook, | |||
112 | daddr = iph->daddr; | 146 | daddr = iph->daddr; |
113 | tos = iph->tos; | 147 | tos = iph->tos; |
114 | 148 | ||
115 | ret = ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_mangle); | 149 | ret = ipt_do_table(skb, hook, in, out, |
150 | nf_local_out_net(in, out)->ipv4.iptable_mangle); | ||
116 | /* Reroute for ANY change. */ | 151 | /* Reroute for ANY change. */ |
117 | if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) { | 152 | if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) { |
118 | iph = ip_hdr(skb); | 153 | iph = ip_hdr(skb); |
@@ -130,21 +165,21 @@ ipt_local_hook(unsigned int hook, | |||
130 | 165 | ||
131 | static struct nf_hook_ops ipt_ops[] __read_mostly = { | 166 | static struct nf_hook_ops ipt_ops[] __read_mostly = { |
132 | { | 167 | { |
133 | .hook = ipt_route_hook, | 168 | .hook = ipt_pre_routing_hook, |
134 | .owner = THIS_MODULE, | 169 | .owner = THIS_MODULE, |
135 | .pf = PF_INET, | 170 | .pf = PF_INET, |
136 | .hooknum = NF_INET_PRE_ROUTING, | 171 | .hooknum = NF_INET_PRE_ROUTING, |
137 | .priority = NF_IP_PRI_MANGLE, | 172 | .priority = NF_IP_PRI_MANGLE, |
138 | }, | 173 | }, |
139 | { | 174 | { |
140 | .hook = ipt_route_hook, | 175 | .hook = ipt_local_in_hook, |
141 | .owner = THIS_MODULE, | 176 | .owner = THIS_MODULE, |
142 | .pf = PF_INET, | 177 | .pf = PF_INET, |
143 | .hooknum = NF_INET_LOCAL_IN, | 178 | .hooknum = NF_INET_LOCAL_IN, |
144 | .priority = NF_IP_PRI_MANGLE, | 179 | .priority = NF_IP_PRI_MANGLE, |
145 | }, | 180 | }, |
146 | { | 181 | { |
147 | .hook = ipt_route_hook, | 182 | .hook = ipt_forward_hook, |
148 | .owner = THIS_MODULE, | 183 | .owner = THIS_MODULE, |
149 | .pf = PF_INET, | 184 | .pf = PF_INET, |
150 | .hooknum = NF_INET_FORWARD, | 185 | .hooknum = NF_INET_FORWARD, |
@@ -158,7 +193,7 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = { | |||
158 | .priority = NF_IP_PRI_MANGLE, | 193 | .priority = NF_IP_PRI_MANGLE, |
159 | }, | 194 | }, |
160 | { | 195 | { |
161 | .hook = ipt_route_hook, | 196 | .hook = ipt_post_routing_hook, |
162 | .owner = THIS_MODULE, | 197 | .owner = THIS_MODULE, |
163 | .pf = PF_INET, | 198 | .pf = PF_INET, |
164 | .hooknum = NF_INET_POST_ROUTING, | 199 | .hooknum = NF_INET_POST_ROUTING, |
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index e41fe8ca4e1c..4b689742d58b 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c | |||
@@ -52,7 +52,8 @@ ipt_hook(unsigned int hook, | |||
52 | const struct net_device *out, | 52 | const struct net_device *out, |
53 | int (*okfn)(struct sk_buff *)) | 53 | int (*okfn)(struct sk_buff *)) |
54 | { | 54 | { |
55 | return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_raw); | 55 | return ipt_do_table(skb, hook, in, out, |
56 | nf_pre_routing_net(in, out)->ipv4.iptable_raw); | ||
56 | } | 57 | } |
57 | 58 | ||
58 | static unsigned int | 59 | static unsigned int |
@@ -70,7 +71,8 @@ ipt_local_hook(unsigned int hook, | |||
70 | "packet.\n"); | 71 | "packet.\n"); |
71 | return NF_ACCEPT; | 72 | return NF_ACCEPT; |
72 | } | 73 | } |
73 | return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_raw); | 74 | return ipt_do_table(skb, hook, in, out, |
75 | nf_local_out_net(in, out)->ipv4.iptable_raw); | ||
74 | } | 76 | } |
75 | 77 | ||
76 | /* 'raw' is the very first table. */ | 78 | /* 'raw' is the very first table. */ |