]> git.itanic.dy.fi Git - linux-stable/commitdiff
net: restore ip source validation
authorJamal Hadi Salim <hadi@cyberus.ca>
Sat, 26 Dec 2009 01:30:22 +0000 (17:30 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 9 Feb 2010 12:50:55 +0000 (04:50 -0800)
[ Upstream commit 28f6aeea3f12d37bd258b2c0d5ba891bff4ec479 ]

when using policy routing and the skb mark:
there are cases where a back path validation requires us
to use a different routing table for src ip validation than
the one used for mapping ingress dst ip.
One such a case is transparent proxying where we pretend to be
the destination system and therefore the local table
is used for incoming packets but possibly a main table would
be used on outbound.
Make the default behavior to allow the above and if users
need to turn on the symmetry via sysctl src_valid_mark

Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
include/linux/inetdevice.h
include/linux/sysctl.h
net/ipv4/devinet.c
net/ipv4/fib_frontend.c

index ad27c7da87986da346da3d62f29e88bec957280a..9cd0bcf307593bce1a9d617d27bece7dc5094cc1 100644 (file)
@@ -83,6 +83,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev)
 #define IN_DEV_FORWARD(in_dev)         IN_DEV_CONF_GET((in_dev), FORWARDING)
 #define IN_DEV_MFORWARD(in_dev)                IN_DEV_ANDCONF((in_dev), MC_FORWARDING)
 #define IN_DEV_RPFILTER(in_dev)                IN_DEV_MAXCONF((in_dev), RP_FILTER)
+#define IN_DEV_SRC_VMARK(in_dev)       IN_DEV_ORCONF((in_dev), SRC_VMARK)
 #define IN_DEV_SOURCE_ROUTE(in_dev)    IN_DEV_ANDCONF((in_dev), \
                                                       ACCEPT_SOURCE_ROUTE)
 #define IN_DEV_BOOTP_RELAY(in_dev)     IN_DEV_ANDCONF((in_dev), BOOTP_RELAY)
index 1e4743ee6831039d8b6d8e5773d7f5eebafcd33d..0eb69420b2f47bb95079c31303ee5fa0e184f3f2 100644 (file)
@@ -490,6 +490,7 @@ enum
        NET_IPV4_CONF_PROMOTE_SECONDARIES=20,
        NET_IPV4_CONF_ARP_ACCEPT=21,
        NET_IPV4_CONF_ARP_NOTIFY=22,
+       NET_IPV4_CONF_SRC_VMARK=24,
        __NET_IPV4_CONF_MAX
 };
 
index 5df2f6a0b0f01da83bead89554bb7e7492298646..0030e73728e44fbfd9b35cbdec12a8b15782134c 100644 (file)
@@ -1450,6 +1450,7 @@ static struct devinet_sysctl_table {
                DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
                DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
                                        "accept_source_route"),
+               DEVINET_SYSCTL_RW_ENTRY(SRC_VMARK, "src_valid_mark"),
                DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
                DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
                DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
index aa00398be80e6f8114da351f07bd0ba585577f17..29391eebd731dce0edac9a13326ac13dadc01a4e 100644 (file)
@@ -251,6 +251,8 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
        if (in_dev) {
                no_addr = in_dev->ifa_list == NULL;
                rpf = IN_DEV_RPFILTER(in_dev);
+               if (mark && !IN_DEV_SRC_VMARK(in_dev))
+                       fl.mark = 0;
        }
        rcu_read_unlock();