aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorTom Herbert <therbert@google.com>2010-05-23 15:54:12 -0400
committerDavid S. Miller <davem@davemloft.net>2010-09-29 02:38:15 -0400
commit4465b469008bc03b98a1b8df4e9ae501b6c69d4b (patch)
tree89cd40165e62694e8ed84d4d60486350ebd8b992 /net/ipv4
parentfc34ecd07f15358e2b29620fafeb8a6a9528ce79 (diff)
ipv4: Allow configuring subnets as local addresses
This patch allows a host to be configured to respond to any address in a specified range as if it were local, without actually needing to configure the address on an interface. This is done through routing table configuration. For instance, to configure a host to respond to any address in 10.1/16 received on eth0 as a local address we can do: ip rule add from all iif eth0 lookup 200 ip route add local 10.1/16 dev lo proto kernel scope host src 127.0.0.1 table 200 This host is now reachable by any 10.1/16 address (route lookup on input for packets received on eth0 can find the route). On output, the rule will not be matched so that this host can still send packets to 10.1/16 (not sent on loopback). Presumably, external routing can be configured to make sense out of this. To make this work, we needed to modify the logic in finding the interface which is assigned a given source address for output (dev_ip_find). We perform a normal fib_lookup instead of just a lookup on the local table, and in the lookup we ignore the input interface for matching. This patch is useful to implement IP-anycast for subnets of virtual addresses. Signed-off-by: Tom Herbert <therbert@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/fib_frontend.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 7d02a9f999fa..981f3c59b334 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -153,17 +153,16 @@ static void fib_flush(struct net *net)
153 153
154struct net_device * ip_dev_find(struct net *net, __be32 addr) 154struct net_device * ip_dev_find(struct net *net, __be32 addr)
155{ 155{
156 struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } }; 156 struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } },
157 .flags = FLOWI_FLAG_MATCH_ANY_IIF };
157 struct fib_result res; 158 struct fib_result res;
158 struct net_device *dev = NULL; 159 struct net_device *dev = NULL;
159 struct fib_table *local_table;
160 160
161#ifdef CONFIG_IP_MULTIPLE_TABLES 161#ifdef CONFIG_IP_MULTIPLE_TABLES
162 res.r = NULL; 162 res.r = NULL;
163#endif 163#endif
164 164
165 local_table = fib_get_table(net, RT_TABLE_LOCAL); 165 if (fib_lookup(net, &fl, &res))
166 if (!local_table || fib_table_lookup(local_table, &fl, &res))
167 return NULL; 166 return NULL;
168 if (res.type != RTN_LOCAL) 167 if (res.type != RTN_LOCAL)
169 goto out; 168 goto out;