Commit cd58bcd9 authored by Jan Engelhardt's avatar Jan Engelhardt Committed by Patrick McHardy

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: default avatarJan Engelhardt <jengelh@medozas.de>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent f3c5c1bf
...@@ -309,7 +309,6 @@ int ip_output(struct sk_buff *skb) ...@@ -309,7 +309,6 @@ int ip_output(struct sk_buff *skb)
ip_finish_output, ip_finish_output,
!(IPCB(skb)->flags & IPSKB_REROUTED)); !(IPCB(skb)->flags & IPSKB_REROUTED));
} }
EXPORT_SYMBOL_GPL(ip_output);
int ip_queue_xmit(struct sk_buff *skb, int ipfragok) int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
{ {
......
...@@ -176,7 +176,6 @@ int ip6_output(struct sk_buff *skb) ...@@ -176,7 +176,6 @@ int ip6_output(struct sk_buff *skb)
ip6_finish_output, ip6_finish_output,
!(IP6CB(skb)->flags & IP6SKB_REROUTED)); !(IP6CB(skb)->flags & IP6SKB_REROUTED));
} }
EXPORT_SYMBOL_GPL(ip6_output);
/* /*
* xmit an sk_buff (used by TCP) * xmit an sk_buff (used by TCP)
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
*/ */
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/percpu.h>
#include <linux/route.h> #include <linux/route.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <net/checksum.h> #include <net/checksum.h>
...@@ -32,6 +33,7 @@ ...@@ -32,6 +33,7 @@
#endif #endif
static const union nf_inet_addr tee_zero_address; static const union nf_inet_addr tee_zero_address;
static DEFINE_PER_CPU(bool, tee_active);
static struct net *pick_net(struct sk_buff *skb) static struct net *pick_net(struct sk_buff *skb)
{ {
...@@ -91,6 +93,8 @@ tee_tg4(struct sk_buff *skb, const struct xt_target_param *par) ...@@ -91,6 +93,8 @@ tee_tg4(struct sk_buff *skb, const struct xt_target_param *par)
const struct xt_tee_tginfo *info = par->targinfo; const struct xt_tee_tginfo *info = par->targinfo;
struct iphdr *iph; struct iphdr *iph;
if (percpu_read(tee_active))
return XT_CONTINUE;
/* /*
* Copy the skb, and route the copy. Will later return %XT_CONTINUE for * Copy the skb, and route the copy. Will later return %XT_CONTINUE for
* the original skb, which should continue on its way as if nothing has * 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,24 +129,13 @@ tee_tg4(struct sk_buff *skb, const struct xt_target_param *par)
--iph->ttl; --iph->ttl;
ip_send_check(iph); ip_send_check(iph);
/* if (tee_tg_route4(skb, info)) {
* Xtables is not reentrant currently, so a choice has to be made: percpu_write(tee_active, true);
* 1. return absolute verdict for the original and let the cloned ip_local_out(skb);
* packet travel through the chains percpu_write(tee_active, false);
* 2. let the original continue travelling and not pass the clone } else {
* to Xtables.
* #2 is chosen. Normally, we would use ip_local_out for the clone.
* Because iph->check is already correct and we don't pass it to
* Xtables anyway, a shortcut to dst_output [forwards to ip_output] can
* be taken. %IPSKB_REROUTED needs to be set so that ip_output does not
* invoke POSTROUTING on the cloned packet.
*/
IPCB(skb)->flags |= IPSKB_REROUTED;
if (tee_tg_route4(skb, info))
ip_output(skb);
else
kfree_skb(skb); kfree_skb(skb);
}
return XT_CONTINUE; return XT_CONTINUE;
} }
...@@ -177,6 +170,8 @@ tee_tg6(struct sk_buff *skb, const struct xt_target_param *par) ...@@ -177,6 +170,8 @@ tee_tg6(struct sk_buff *skb, const struct xt_target_param *par)
{ {
const struct xt_tee_tginfo *info = par->targinfo; const struct xt_tee_tginfo *info = par->targinfo;
if (percpu_read(tee_active))
return XT_CONTINUE;
skb = pskb_copy(skb, GFP_ATOMIC); skb = pskb_copy(skb, GFP_ATOMIC);
if (skb == NULL) if (skb == NULL)
return XT_CONTINUE; return XT_CONTINUE;
...@@ -192,12 +187,13 @@ tee_tg6(struct sk_buff *skb, const struct xt_target_param *par) ...@@ -192,12 +187,13 @@ tee_tg6(struct sk_buff *skb, const struct xt_target_param *par)
struct ipv6hdr *iph = ipv6_hdr(skb); struct ipv6hdr *iph = ipv6_hdr(skb);
--iph->hop_limit; --iph->hop_limit;
} }
IP6CB(skb)->flags |= IP6SKB_REROUTED; if (tee_tg_route6(skb, info)) {
if (tee_tg_route6(skb, info)) percpu_write(tee_active, true);
ip6_output(skb); ip6_local_out(skb);
else percpu_write(tee_active, false);
} else {
kfree_skb(skb); kfree_skb(skb);
}
return XT_CONTINUE; return XT_CONTINUE;
} }
#endif /* WITH_IPV6 */ #endif /* WITH_IPV6 */
......
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