net: Add routes to the table associated with the device
[deliverable/linux.git] / net / ipv4 / fib_semantics.c
index 410ddb67221e5bec39b0b1caf03cd8c224aa25c5..85e9a8abf15c274a4214057e35ebc1835525bed0 100644 (file)
@@ -838,6 +838,23 @@ __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh)
        return nh->nh_saddr;
 }
 
+static bool fib_valid_prefsrc(struct fib_config *cfg, __be32 fib_prefsrc)
+{
+       if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst ||
+           fib_prefsrc != cfg->fc_dst) {
+               int tb_id = cfg->fc_table;
+
+               if (tb_id == RT_TABLE_MAIN)
+                       tb_id = RT_TABLE_LOCAL;
+
+               if (inet_addr_type_table(cfg->fc_nlinfo.nl_net,
+                                        fib_prefsrc, tb_id) != RTN_LOCAL) {
+                       return false;
+               }
+       }
+       return true;
+}
+
 struct fib_info *fib_create_info(struct fib_config *cfg)
 {
        int err;
@@ -1033,12 +1050,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
                        fi->fib_flags |= RTNH_F_LINKDOWN;
        }
 
-       if (fi->fib_prefsrc) {
-               if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst ||
-                   fi->fib_prefsrc != cfg->fc_dst)
-                       if (inet_addr_type(net, fi->fib_prefsrc) != RTN_LOCAL)
-                               goto err_inval;
-       }
+       if (fi->fib_prefsrc && !fib_valid_prefsrc(cfg, fi->fib_prefsrc))
+               goto err_inval;
 
        change_nexthops(fi) {
                fib_info_update_nh_saddr(net, nexthop_nh);
This page took 0.025943 seconds and 5 git commands to generate.