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.
|