|
@@ -2361,11 +2361,6 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
|
|
|
ipv4_is_zeronet(oldflp->fl4_src))
|
|
|
goto out;
|
|
|
|
|
|
- /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
|
|
|
- dev_out = ip_dev_find(net, oldflp->fl4_src);
|
|
|
- if (dev_out == NULL)
|
|
|
- goto out;
|
|
|
-
|
|
|
/* I removed check for oif == dev_out->oif here.
|
|
|
It was wrong for two reasons:
|
|
|
1. ip_dev_find(net, saddr) can return wrong iface, if saddr
|
|
@@ -2377,6 +2372,11 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
|
|
|
if (oldflp->oif == 0
|
|
|
&& (ipv4_is_multicast(oldflp->fl4_dst) ||
|
|
|
oldflp->fl4_dst == htonl(0xFFFFFFFF))) {
|
|
|
+ /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
|
|
|
+ dev_out = ip_dev_find(net, oldflp->fl4_src);
|
|
|
+ if (dev_out == NULL)
|
|
|
+ goto out;
|
|
|
+
|
|
|
/* Special hack: user can direct multicasts
|
|
|
and limited broadcast via necessary interface
|
|
|
without fiddling with IP_MULTICAST_IF or IP_PKTINFO.
|
|
@@ -2395,9 +2395,15 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
|
|
|
fl.oif = dev_out->ifindex;
|
|
|
goto make_route;
|
|
|
}
|
|
|
- if (dev_out)
|
|
|
+
|
|
|
+ if (!(oldflp->flags & FLOWI_FLAG_ANYSRC)) {
|
|
|
+ /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
|
|
|
+ dev_out = ip_dev_find(net, oldflp->fl4_src);
|
|
|
+ if (dev_out == NULL)
|
|
|
+ goto out;
|
|
|
dev_put(dev_out);
|
|
|
- dev_out = NULL;
|
|
|
+ dev_out = NULL;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|