Skip to content

Commit

Permalink
netfilter: xt_TEE: have cloned packet travel through Xtables too
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jan Engelhardt authored and Patrick McHardy committed Apr 19, 2010
1 parent f3c5c1b commit cd58bcd
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 24 deletions.
1 change: 0 additions & 1 deletion net/ipv4/ip_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,6 @@ int ip_output(struct sk_buff *skb)
ip_finish_output,
!(IPCB(skb)->flags & IPSKB_REROUTED));
}
EXPORT_SYMBOL_GPL(ip_output);

int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
{
Expand Down
1 change: 0 additions & 1 deletion net/ipv6/ip6_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ int ip6_output(struct sk_buff *skb)
ip6_finish_output,
!(IP6CB(skb)->flags & IP6SKB_REROUTED));
}
EXPORT_SYMBOL_GPL(ip6_output);

/*
* xmit an sk_buff (used by TCP)
Expand Down
40 changes: 18 additions & 22 deletions net/netfilter/xt_TEE.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
#include <linux/ip.h>
#include <linux/module.h>
#include <linux/percpu.h>
#include <linux/route.h>
#include <linux/skbuff.h>
#include <net/checksum.h>
Expand All @@ -32,6 +33,7 @@
#endif

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)
{
Expand Down Expand Up @@ -91,6 +93,8 @@ tee_tg4(struct sk_buff *skb, const struct xt_target_param *par)
const struct xt_tee_tginfo *info = par->targinfo;
struct iphdr *iph;

if (percpu_read(tee_active))
return XT_CONTINUE;
/*
* 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
Expand Down Expand Up @@ -125,24 +129,13 @@ tee_tg4(struct sk_buff *skb, const struct xt_target_param *par)
--iph->ttl;
ip_send_check(iph);

/*
* Xtables is not reentrant currently, so a choice has to be made:
* 1. return absolute verdict for the original and let the cloned
* packet travel through the chains
* 2. let the original continue travelling and not pass the clone
* 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
if (tee_tg_route4(skb, info)) {
percpu_write(tee_active, true);
ip_local_out(skb);
percpu_write(tee_active, false);
} else {
kfree_skb(skb);

}
return XT_CONTINUE;
}

Expand Down Expand Up @@ -177,6 +170,8 @@ tee_tg6(struct sk_buff *skb, const struct xt_target_param *par)
{
const struct xt_tee_tginfo *info = par->targinfo;

if (percpu_read(tee_active))
return XT_CONTINUE;
skb = pskb_copy(skb, GFP_ATOMIC);
if (skb == NULL)
return XT_CONTINUE;
Expand All @@ -192,12 +187,13 @@ tee_tg6(struct sk_buff *skb, const struct xt_target_param *par)
struct ipv6hdr *iph = ipv6_hdr(skb);
--iph->hop_limit;
}
IP6CB(skb)->flags |= IP6SKB_REROUTED;
if (tee_tg_route6(skb, info))
ip6_output(skb);
else
if (tee_tg_route6(skb, info)) {
percpu_write(tee_active, true);
ip6_local_out(skb);
percpu_write(tee_active, false);
} else {
kfree_skb(skb);

}
return XT_CONTINUE;
}
#endif /* WITH_IPV6 */
Expand Down

0 comments on commit cd58bcd

Please sign in to comment.