net: l3mdev: Allow the l3mdev to be a loopback
[cascardo/linux.git] / net / ipv4 / route.c
index 3e99278..f49b2c5 100644 (file)
@@ -2018,7 +2018,9 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
                return ERR_PTR(-EINVAL);
 
        if (likely(!IN_DEV_ROUTE_LOCALNET(in_dev)))
-               if (ipv4_is_loopback(fl4->saddr) && !(dev_out->flags & IFF_LOOPBACK))
+               if (ipv4_is_loopback(fl4->saddr) &&
+                   !(dev_out->flags & IFF_LOOPBACK) &&
+                   !netif_is_l3_master(dev_out))
                        return ERR_PTR(-EINVAL);
 
        if (ipv4_is_lbcast(fl4->daddr))
@@ -2302,7 +2304,9 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
                        else
                                fl4->saddr = fl4->daddr;
                }
-               dev_out = net->loopback_dev;
+
+               /* L3 master device is the loopback for that domain */
+               dev_out = l3mdev_master_dev_rcu(dev_out) ? : net->loopback_dev;
                fl4->flowi4_oif = dev_out->ifindex;
                flags |= RTCF_LOCAL;
                goto make_route;