]> git.ipfire.org Git - thirdparty/xtables-addons.git/commitdiff
TEE: various cleanups, add comments
authorJan Engelhardt <jengelh@medozas.de>
Thu, 20 Nov 2008 23:16:11 +0000 (00:16 +0100)
committerJan Engelhardt <jengelh@medozas.de>
Fri, 21 Nov 2008 00:15:03 +0000 (01:15 +0100)
Normalize function names in light of upcoming IPv6 support.
Reformat other lines.
Add comment note about tee_send4.

extensions/xt_TEE.c

index 447254db2b97f937335af792dd4ac65d146feedf..9ef79a861e14b5d43886463055e9dcdba65a145e 100644 (file)
@@ -29,7 +29,7 @@ static struct nf_conn tee_track;
 #include "compat_xtables.h"
 #include "xt_TEE.h"
 
-static const union nf_inet_addr zero_address;
+static const union nf_inet_addr tee_zero_address;
 
 /*
  * Try to route the packet according to the routing keys specified in
@@ -47,20 +47,16 @@ static const union nf_inet_addr zero_address;
  *         true  - if the packet was succesfully routed to the
  *                 destination desired
  */
-static bool tee_routing(struct sk_buff *skb,
-                        const struct xt_tee_tginfo *info)
+static bool
+tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info)
 {
        int err;
        struct rtable *rt;
-       struct iphdr *iph = ip_hdr(skb);
-       struct flowi fl = {
-               .nl_u = {
-                       .ip4_u = {
-                               .daddr = info->gw.ip,
-                               .scope = RT_SCOPE_UNIVERSE,
-                       }
-               }
-       };
+       struct flowi fl;
+
+       memset(&fl, 0, sizeof(fl));
+       fl.nl_u.ip4_u.daddr = info->gw.ip;
+       fl.nl_u.ip4_u.scope = RT_SCOPE_UNIVERSE;
 
        /* Trying to route the packet using the standard routing table. */
        err = ip_route_output_key(&init_net, &rt, &fl);
@@ -71,22 +67,14 @@ static bool tee_routing(struct sk_buff *skb,
                return false;
        }
 
-       /* Drop old route. */
        dst_release(skb->dst);
-       skb->dst = NULL;
-
-       /*
-        * Success if no oif specified or if the oif correspond to the
-        * one desired.
-        * [SC]: always the case, because we have no oif.
-        */
        skb->dst      = &rt->u.dst;
        skb->dev      = skb->dst->dev;
        skb->protocol = htons(ETH_P_IP);
        return true;
 }
 
-static bool dev_hh_avail(const struct net_device *dev)
+static inline bool dev_hh_avail(const struct net_device *dev)
 {
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
        return dev->hard_header != NULL;
@@ -102,14 +90,14 @@ static bool dev_hh_avail(const struct net_device *dev)
  * POST: the packet is sent with the link layer header pushed
  *       the packet is destroyed
  */
-static void tee_ip_direct_send(struct sk_buff *skb)
+static void tee_tg_send4(struct sk_buff *skb)
 {
        const struct dst_entry *dst  = skb->dst;
        const struct net_device *dev = dst->dev;
        unsigned int hh_len = LL_RESERVED_SPACE(dev);
 
        /* Be paranoid, rather than too clever. */
-       if (unlikely(skb_headroom(skb) < hh_len) && dev_hh_avail(dev)) {
+       if (unlikely(skb_headroom(skb) < hh_len && dev_hh_avail(dev))) {
                struct sk_buff *skb2;
 
                skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev));
@@ -141,7 +129,7 @@ static void tee_ip_direct_send(struct sk_buff *skb)
  * packets when we see they already have that ->nfct.
  */
 static unsigned int
-tee_tg(struct sk_buff **pskb, const struct xt_target_param *par)
+tee_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
 {
        const struct xt_tee_tginfo *info = par->targinfo;
        struct sk_buff *skb = *pskb;
@@ -199,8 +187,24 @@ tee_tg(struct sk_buff **pskb, const struct xt_target_param *par)
        nf_conntrack_get(skb->nfct);
 #endif
 
-       if (tee_routing(skb, info))
-               tee_ip_direct_send(skb);
+       /*
+        * Normally, we would just use ip_local_out. Because iph->check is
+        * already correct, we could take a shortcut and call dst_output
+        * [forwards to ip_output] directly. ip_output however will invoke
+        * Netfilter hooks and cause reentrancy. So we skip that too and go
+        * directly to ip_finish_output. Since we should not do XFRM, control
+        * passes to ip_finish_output2. That function is not exported, so it is
+        * copied here as tee_ip_direct_send.
+        *
+        * We do no XFRM on the cloned packet on purpose! The choice of
+        * iptables match options will control whether the raw packet or the
+        * transformed version is cloned.
+        *
+        * Also on purpose, no fragmentation is done, to preserve the
+        * packet as best as possible.
+        */
+       if (tee_tg_route4(skb, info))
+               tee_tg_send4(skb);
 
        return XT_CONTINUE;
 }
@@ -210,7 +214,8 @@ static bool tee_tg_check(const struct xt_tgchk_param *par)
        const struct xt_tee_tginfo *info = par->targinfo;
 
        /* 0.0.0.0 and :: not allowed */
-       return memcmp(&info->gw, &zero_address, sizeof(zero_address)) != 0;
+       return memcmp(&info->gw, &tee_zero_address,
+              sizeof(tee_zero_address)) != 0;
 }
 
 static struct xt_target tee_tg_reg __read_mostly = {
@@ -218,7 +223,7 @@ static struct xt_target tee_tg_reg __read_mostly = {
        .revision   = 0,
        .family     = NFPROTO_IPV4,
        .table      = "mangle",
-       .target     = tee_tg,
+       .target     = tee_tg4,
        .targetsize = sizeof(struct xt_tee_tginfo),
        .checkentry = tee_tg_check,
        .me         = THIS_MODULE,
@@ -252,7 +257,7 @@ static void __exit tee_tg_exit(void)
 module_init(tee_tg_init);
 module_exit(tee_tg_exit);
 MODULE_AUTHOR("Sebastian Claßen <sebastian.classen@freenet.ag>");
-MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
 MODULE_DESCRIPTION("Xtables: Reroute packet copy");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_TEE");