On Sat, Apr 06, 2002 at 10:55:27AM +0200, Bart De Schuymer wrote:

> > To cover these cases, two tests are needed.
> >
> > 1. If the function ip_route_input returns success, it means
> >    that #2 was the case, and we have to overwrite the destination
> >    ethernet address with our own address and pass the packet
> >    up the stack to have it routed.
> >
> > 2. If not, #1 was the case.  We call ip_route_output to
> >    attach a needed dst_entry structure to the packet and we
> >    send the packet out.
> 
> Aha, now I get it :-)
> Never did quite understand br_nf_pre_routing_finish.

Hmm.. should I add a big fat comment over it?


> > What I did not consider was the case where IP forwarding is
> > disabled.  In that case, ip_route_input will fail, not for the
> > reason that the new destination IP address is in the same bridge
> > port group, but for the reason because the IP stack notices
> > that this packet would have to be forwarded, and it refuses to
> > do so.
> >
> > I'm not totally sure what the best way is, but I guess I should
> > turn the 'crash now' into a 'drop packet and write a message
> > to the system log'.
> >
> > Ideas?
> 
> I agree. The cause for this problem is not a kernel bug, it's
> the forgetful/unknowing nature of the user. You could write a
> message stating that he maybe should turn on ip_forward.

OK.. how does this look?

Any other submissions for 0.0.7?  Do you still want me to add
those PF_BRIDGE priorities you sent me a while ago?


cheers,
Lennert



--- br_netfilter.c.orig Sat Apr  6 16:04:03 2002
+++ br_netfilter.c      Sat Apr  6 16:07:54 2002
@@ -84,23 +84,35 @@
        rt_flags:       0
 };
 
 
 /* PF_BRIDGE/PRE_ROUTING *********************************************/
+static void __br_dnat_complain()
+{
+       static unsigned long last_complaint = 0;
+
+       if (jiffies - last_complaint >= 5 * HZ) {
+               printk(KERN_WARNING "Performing DNAT on a bridge requires IP "
+                       "forwarding to be enabled\n");
+               last_complaint = jiffies;
+       }
+}
+
 static int br_nf_pre_routing_finish(struct sk_buff *skb)
 {
        struct net_device *dev = skb->dev;
        struct iphdr *iph = skb->nh.iph;
 
        if (dnat_took_place(skb)) {
                if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev)) {
                        struct rtable *rt;
 
                        if (ip_route_output(&rt, iph->daddr, 0, iph->tos, 
dev->ifindex)) {
-                               /* This test is racy.  */
-                               if (!ip_route_output(&rt, iph->daddr, 0, iph->tos, 0))
-                                       BUG();
+                               if (!ip_route_output(&rt, iph->daddr, 0, iph->tos, 0)) 
+{
+                                       __br_dnat_complain();
+                                       dst_release((struct dst_entry *)rt);
+                               }
 
                                kfree_skb(skb);
                                return 0;
                        }
 
_______________________________________________
Bridge mailing list
[EMAIL PROTECTED]
http://www.math.leidenuniv.nl/mailman/listinfo/bridge

Reply via email to