netdev
[Top] [All Lists]

Re: [2 bugs] iptable_nat module makes a black hole for GRE packets, ipta

To: david@xxxxxxxxxxxxxx
Subject: Re: [2 bugs] iptable_nat module makes a black hole for GRE packets, iptables only plays with ICMP/UDP/TCP
From: Rusty Russell <rusty@xxxxxxxxxxxxxxxx>
Date: Mon, 05 Jun 2000 03:57:26 +1000
Cc: alan@xxxxxxxxxxxxxxxxxxx, netdev@xxxxxxxxxxx
In-reply-to: Your message of "Mon, 05 Jun 2000 01:50:02 +1000." <393A7A41.6ED4C7CB@kalifornia.com>
Sender: owner-netdev@xxxxxxxxxxx
In message <393A7A41.6ED4C7CB@xxxxxxxxxxxxxx> you write:
> Alan first.  Alan, please remove "GRE is broken" from the todo list.
> Replace it with "iptable_nat module breaks GRE" and add "iptables
> generally doesn't handle protocols outside the top 3".

Belay that.  These are the same `feature': entunnelled GRE packets
don't go through LOCAL_OUT.  I didn't do that originally because I
wasn't sure what the best policy for tunnels.

It's since become clear (with usage), that tunnels should pass
entunnelled packets through the NF_IP_LOCAL_OUT hook.

David, please try this patch (may need some mangling, it's off the top
of my head).  If it helps, I'll add it to the pile.

--- working-2.4.0-test1/net/ipv4/ip_gre.c.~1~   Thu May 25 12:41:52 2000
+++ working-2.4.0-test1/net/ipv4/ip_gre.c       Mon Jun  5 03:51:47 2000
@@ -529,6 +529,49 @@
 #endif
 }
 
+#ifdef CONFIG_NETFILTER
+/* To preserve the cute illusion that a locally-generated packet can
+   be mangled before routing, we actually reroute if a hook altered
+   the packet. -RR */
+static int route_me_harder(struct sk_buff *skb)
+{
+       struct iphdr *iph = skb->nh.iph;
+       struct rtable *rt;
+
+       if (ip_route_output(&rt, iph->daddr, iph->saddr,
+                           RT_TOS(iph->tos) | RTO_CONN,
+                           skb->sk ? skb->sk->bound_dev_if : 0)) {
+               printk("route_me_harder: No more route.\n");
+               return -EINVAL;
+       }
+
+       /* Drop old route. */
+       dst_release(skb->dst);
+
+       skb->dst = &rt->u.dst;
+       return 0;
+}
+#endif
+
+/* Do route recalc if netfilter changes skb. */
+static inline int
+send_maybe_reroute(struct sk_buff *skb)
+{
+#ifdef CONFIG_NETFILTER
+       if (skb->nfcache & NFC_ALTERED) {
+               if (route_me_harder(skb) != 0) {
+                       kfree_skb(skb);
+                       return -EINVAL;
+               }
+       }
+#endif
+       stats->tx_bytes += skb->len;
+       stats->tx_packets++;
+       ip_send(skb);
+       tunnel->recursion--;
+       return 0;
+}
+
 int ipgre_rcv(struct sk_buff *skb, unsigned short len)
 {
        struct iphdr *iph = skb->nh.iph;
@@ -827,12 +870,8 @@
        skb->nfct = NULL;
 #endif
 
-       stats->tx_bytes += skb->len;
-       stats->tx_packets++;
-       ip_send(skb);
-       tunnel->recursion--;
-       return 0;
-
+       return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
+                      send_maybe_reroute);
 tx_error_icmp:
        dst_link_failure(skb);
 
--
Hacking time.

<Prev in Thread] Current Thread [Next in Thread>