]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/ipv4/fib_frontend.c
ipv4: Allow configuring subnets as local addresses
[net-next-2.6.git] / net / ipv4 / fib_frontend.c
index a43968918350244a057e6f3364727d6a2aa7baf2..981f3c59b33412b8674b1974ca1b4877cde97511 100644 (file)
@@ -153,17 +153,16 @@ static void fib_flush(struct net *net)
 
 struct net_device * ip_dev_find(struct net *net, __be32 addr)
 {
-       struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
+       struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } },
+                           .flags = FLOWI_FLAG_MATCH_ANY_IIF };
        struct fib_result res;
        struct net_device *dev = NULL;
-       struct fib_table *local_table;
 
 #ifdef CONFIG_IP_MULTIPLE_TABLES
        res.r = NULL;
 #endif
 
-       local_table = fib_get_table(net, RT_TABLE_LOCAL);
-       if (!local_table || fib_table_lookup(local_table, &fl, &res))
+       if (fib_lookup(net, &fl, &res))
                return NULL;
        if (res.type != RTN_LOCAL)
                goto out;
@@ -246,6 +245,7 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
 
        struct fib_result res;
        int no_addr, rpf, accept_local;
+       bool dev_match;
        int ret;
        struct net *net;
 
@@ -273,12 +273,22 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
        }
        *spec_dst = FIB_RES_PREFSRC(res);
        fib_combine_itag(itag, &res);
+       dev_match = false;
+
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
-       if (FIB_RES_DEV(res) == dev || res.fi->fib_nhs > 1)
+       for (ret = 0; ret < res.fi->fib_nhs; ret++) {
+               struct fib_nh *nh = &res.fi->fib_nh[ret];
+
+               if (nh->nh_dev == dev) {
+                       dev_match = true;
+                       break;
+               }
+       }
 #else
        if (FIB_RES_DEV(res) == dev)
+               dev_match = true;
 #endif
-       {
+       if (dev_match) {
                ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
                fib_res_put(&res);
                return ret;