-stable review patch.  If anyone has any objections, please let us know.
------------------

From: Bart De Schuymer <[EMAIL PROTECTED]>

The attached patch resolves an issue where a IP DNATed packet with a
martian source is forwarded while it's better to drop it. It also
resolves messages complaining about ip forwarding being disabled while
it's actually enabled. Thanks to lepton <[EMAIL PROTECTED]> for
reporting this problem.

This is probably a candidate for the -stable release.

Signed-off-by: Bart De Schuymer <[EMAIL PROTECTED]>
Signed-off-by: Patrick McHardy <[EMAIL PROTECTED]>
Signed-off-by: Chris Wright <[EMAIL PROTECTED]>
---
commit bb01f827bae980efdecc33fbcdc1b90f1c355b3e
tree 432a8f2843b47ccac094efea35da6f19731ed834
parent 14f5487cb9bd34cd59360d2cac7dccac9b27e8ce
author Bart De Schuymer <[EMAIL PROTECTED]> Mon, 04 Dec 2006 12:19:46 +0100
committer Patrick McHardy <[EMAIL PROTECTED]> Mon, 04 Dec 2006 12:19:46 +0100

 net/bridge/br_netfilter.c |   36 ++++++++++++++++++++++++++++--------
 1 file changed, 28 insertions(+), 8 deletions(-)

--- linux-2.6.19.orig/net/bridge/br_netfilter.c
+++ linux-2.6.19/net/bridge/br_netfilter.c
@@ -34,6 +34,7 @@
 #include <linux/netfilter_ipv6.h>
 #include <linux/netfilter_arp.h>
 #include <linux/in_route.h>
+#include <linux/inetdevice.h>
 
 #include <net/ip.h>
 #include <net/ipv6.h>
@@ -222,10 +223,14 @@ static void __br_dnat_complain(void)
  *
  * Otherwise, the packet is considered to be routed and we just
  * change the destination MAC address so that the packet will
- * later be passed up to the IP stack to be routed.
+ * later be passed up to the IP stack to be routed. For a redirected
+ * packet, ip_route_input() will give back the localhost as output device,
+ * which differs from the bridge device.
  *
  * Let us now consider the case that ip_route_input() fails:
  *
+ * This can be because the destination address is martian, in which case
+ * the packet will be dropped.
  * After a "echo '0' > /proc/sys/net/ipv4/ip_forward" ip_route_input()
  * will fail, while __ip_route_output_key() will return success. The source
  * address for __ip_route_output_key() is set to zero, so __ip_route_output_key
@@ -238,7 +243,8 @@ static void __br_dnat_complain(void)
  *
  * --Lennert, 20020411
  * --Bart, 20020416 (updated)
- * --Bart, 20021007 (updated) */
+ * --Bart, 20021007 (updated)
+ * --Bart, 20062711 (updated) */
 static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
 {
        if (skb->pkt_type == PACKET_OTHERHOST) {
@@ -265,15 +271,15 @@ static int br_nf_pre_routing_finish(stru
        struct net_device *dev = skb->dev;
        struct iphdr *iph = skb->nh.iph;
        struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+       int err;
 
        if (nf_bridge->mask & BRNF_PKT_TYPE) {
                skb->pkt_type = PACKET_OTHERHOST;
                nf_bridge->mask ^= BRNF_PKT_TYPE;
        }
        nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
-
        if (dnat_took_place(skb)) {
-               if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev)) 
{
+               if ((err = ip_route_input(skb, iph->daddr, iph->saddr, 
iph->tos, dev))) {
                        struct rtable *rt;
                        struct flowi fl = {
                                .nl_u = {
@@ -284,19 +290,33 @@ static int br_nf_pre_routing_finish(stru
                                },
                                .proto = 0,
                        };
+                       struct in_device *in_dev = in_dev_get(dev);
+
+                       /* If err equals -EHOSTUNREACH the error is due to a
+                        * martian destination or due to the fact that
+                        * forwarding is disabled. For most martian packets,
+                        * ip_route_output_key() will fail. It won't fail for 2 
types of
+                        * martian destinations: loopback destinations and 
destination
+                        * 0.0.0.0. In both cases the packet will be dropped 
because the
+                        * destination is the loopback device and not the 
bridge. */
+                       if (err != -EHOSTUNREACH || !in_dev || 
IN_DEV_FORWARD(in_dev))
+                               goto free_skb;
 
                        if (!ip_route_output_key(&rt, &fl)) {
                                /* - Bridged-and-DNAT'ed traffic doesn't
-                                *   require ip_forwarding.
-                                * - Deal with redirected traffic. */
-                               if (((struct dst_entry *)rt)->dev == dev ||
-                                   rt->rt_type == RTN_LOCAL) {
+                                *   require ip_forwarding. */
+                               if (((struct dst_entry *)rt)->dev == dev) {
                                        skb->dst = (struct dst_entry *)rt;
                                        goto bridged_dnat;
                                }
+                               /* we are sure that forwarding is disabled, so 
printing
+                                * this message is no problem. Note that the 
packet could
+                                * still have a martian destination address, in 
which case
+                                * the packet could be dropped even if 
forwarding were enabled */
                                __br_dnat_complain();
                                dst_release((struct dst_entry *)rt);
                        }
+free_skb:
                        kfree_skb(skb);
                        return 0;
                } else {

--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to