diff options
author | Jan Engelhardt <jengelh@medozas.de> | 2010-04-19 10:06:52 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-04-19 10:06:52 -0400 |
commit | cd58bcd9787ef4c16ab6e442c4f1bf3539b3ab39 (patch) | |
tree | 949741c18227ae46f841501507ad440f35e659e5 | |
parent | f3c5c1bfd430858d3a05436f82c51e53104feb6b (diff) |
netfilter: xt_TEE: have cloned packet travel through Xtables too
Since Xtables is now reentrant/nestable, the cloned packet can also go
through Xtables and be subject to rules itself.
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r-- | net/ipv4/ip_output.c | 1 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 1 | ||||
-rw-r--r-- | net/netfilter/xt_TEE.c | 40 |
3 files changed, 18 insertions, 24 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 0abfddec1e26..f09135e1e14f 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -309,7 +309,6 @@ int ip_output(struct sk_buff *skb) | |||
309 | ip_finish_output, | 309 | ip_finish_output, |
310 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | 310 | !(IPCB(skb)->flags & IPSKB_REROUTED)); |
311 | } | 311 | } |
312 | EXPORT_SYMBOL_GPL(ip_output); | ||
313 | 312 | ||
314 | int ip_queue_xmit(struct sk_buff *skb, int ipfragok) | 313 | int ip_queue_xmit(struct sk_buff *skb, int ipfragok) |
315 | { | 314 | { |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index d09be7ff8735..c10a38a71a5e 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -176,7 +176,6 @@ int ip6_output(struct sk_buff *skb) | |||
176 | ip6_finish_output, | 176 | ip6_finish_output, |
177 | !(IP6CB(skb)->flags & IP6SKB_REROUTED)); | 177 | !(IP6CB(skb)->flags & IP6SKB_REROUTED)); |
178 | } | 178 | } |
179 | EXPORT_SYMBOL_GPL(ip6_output); | ||
180 | 179 | ||
181 | /* | 180 | /* |
182 | * xmit an sk_buff (used by TCP) | 181 | * xmit an sk_buff (used by TCP) |
diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c index b3d730163f12..842e7012eca7 100644 --- a/net/netfilter/xt_TEE.c +++ b/net/netfilter/xt_TEE.c | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | #include <linux/ip.h> | 13 | #include <linux/ip.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/percpu.h> | ||
15 | #include <linux/route.h> | 16 | #include <linux/route.h> |
16 | #include <linux/skbuff.h> | 17 | #include <linux/skbuff.h> |
17 | #include <net/checksum.h> | 18 | #include <net/checksum.h> |
@@ -32,6 +33,7 @@ | |||
32 | #endif | 33 | #endif |
33 | 34 | ||
34 | static const union nf_inet_addr tee_zero_address; | 35 | static const union nf_inet_addr tee_zero_address; |
36 | static DEFINE_PER_CPU(bool, tee_active); | ||
35 | 37 | ||
36 | static struct net *pick_net(struct sk_buff *skb) | 38 | static struct net *pick_net(struct sk_buff *skb) |
37 | { | 39 | { |
@@ -91,6 +93,8 @@ tee_tg4(struct sk_buff *skb, const struct xt_target_param *par) | |||
91 | const struct xt_tee_tginfo *info = par->targinfo; | 93 | const struct xt_tee_tginfo *info = par->targinfo; |
92 | struct iphdr *iph; | 94 | struct iphdr *iph; |
93 | 95 | ||
96 | if (percpu_read(tee_active)) | ||
97 | return XT_CONTINUE; | ||
94 | /* | 98 | /* |
95 | * Copy the skb, and route the copy. Will later return %XT_CONTINUE for | 99 | * Copy the skb, and route the copy. Will later return %XT_CONTINUE for |
96 | * the original skb, which should continue on its way as if nothing has | 100 | * the original skb, which should continue on its way as if nothing has |
@@ -125,24 +129,13 @@ tee_tg4(struct sk_buff *skb, const struct xt_target_param *par) | |||
125 | --iph->ttl; | 129 | --iph->ttl; |
126 | ip_send_check(iph); | 130 | ip_send_check(iph); |
127 | 131 | ||
128 | /* | 132 | if (tee_tg_route4(skb, info)) { |
129 | * Xtables is not reentrant currently, so a choice has to be made: | 133 | percpu_write(tee_active, true); |
130 | * 1. return absolute verdict for the original and let the cloned | 134 | ip_local_out(skb); |
131 | * packet travel through the chains | 135 | percpu_write(tee_active, false); |
132 | * 2. let the original continue travelling and not pass the clone | 136 | } else { |
133 | * to Xtables. | ||
134 | * #2 is chosen. Normally, we would use ip_local_out for the clone. | ||
135 | * Because iph->check is already correct and we don't pass it to | ||
136 | * Xtables anyway, a shortcut to dst_output [forwards to ip_output] can | ||
137 | * be taken. %IPSKB_REROUTED needs to be set so that ip_output does not | ||
138 | * invoke POSTROUTING on the cloned packet. | ||
139 | */ | ||
140 | IPCB(skb)->flags |= IPSKB_REROUTED; | ||
141 | if (tee_tg_route4(skb, info)) | ||
142 | ip_output(skb); | ||
143 | else | ||
144 | kfree_skb(skb); | 137 | kfree_skb(skb); |
145 | 138 | } | |
146 | return XT_CONTINUE; | 139 | return XT_CONTINUE; |
147 | } | 140 | } |
148 | 141 | ||
@@ -177,6 +170,8 @@ tee_tg6(struct sk_buff *skb, const struct xt_target_param *par) | |||
177 | { | 170 | { |
178 | const struct xt_tee_tginfo *info = par->targinfo; | 171 | const struct xt_tee_tginfo *info = par->targinfo; |
179 | 172 | ||
173 | if (percpu_read(tee_active)) | ||
174 | return XT_CONTINUE; | ||
180 | skb = pskb_copy(skb, GFP_ATOMIC); | 175 | skb = pskb_copy(skb, GFP_ATOMIC); |
181 | if (skb == NULL) | 176 | if (skb == NULL) |
182 | return XT_CONTINUE; | 177 | return XT_CONTINUE; |
@@ -192,12 +187,13 @@ tee_tg6(struct sk_buff *skb, const struct xt_target_param *par) | |||
192 | struct ipv6hdr *iph = ipv6_hdr(skb); | 187 | struct ipv6hdr *iph = ipv6_hdr(skb); |
193 | --iph->hop_limit; | 188 | --iph->hop_limit; |
194 | } | 189 | } |
195 | IP6CB(skb)->flags |= IP6SKB_REROUTED; | 190 | if (tee_tg_route6(skb, info)) { |
196 | if (tee_tg_route6(skb, info)) | 191 | percpu_write(tee_active, true); |
197 | ip6_output(skb); | 192 | ip6_local_out(skb); |
198 | else | 193 | percpu_write(tee_active, false); |
194 | } else { | ||
199 | kfree_skb(skb); | 195 | kfree_skb(skb); |
200 | 196 | } | |
201 | return XT_CONTINUE; | 197 | return XT_CONTINUE; |
202 | } | 198 | } |
203 | #endif /* WITH_IPV6 */ | 199 | #endif /* WITH_IPV6 */ |