aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/flow.h2
-rw-r--r--net/ipv4/route.c20
2 files changed, 15 insertions, 7 deletions
diff --git a/include/net/flow.h b/include/net/flow.h
index 228b2477ceec..b45a5e4fcadd 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -47,6 +47,8 @@ struct flowi {
47#define fl4_scope nl_u.ip4_u.scope 47#define fl4_scope nl_u.ip4_u.scope
48 48
49 __u8 proto; 49 __u8 proto;
50 __u8 flags;
51#define FLOWI_FLAG_ANYSRC 0x01
50 union { 52 union {
51 struct { 53 struct {
52 __be16 sport; 54 __be16 sport;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index f62187bb6d08..a6d7c584f53b 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2361,11 +2361,6 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
2361 ipv4_is_zeronet(oldflp->fl4_src)) 2361 ipv4_is_zeronet(oldflp->fl4_src))
2362 goto out; 2362 goto out;
2363 2363
2364 /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
2365 dev_out = ip_dev_find(net, oldflp->fl4_src);
2366 if (dev_out == NULL)
2367 goto out;
2368
2369 /* I removed check for oif == dev_out->oif here. 2364 /* I removed check for oif == dev_out->oif here.
2370 It was wrong for two reasons: 2365 It was wrong for two reasons:
2371 1. ip_dev_find(net, saddr) can return wrong iface, if saddr 2366 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,
2377 if (oldflp->oif == 0 2372 if (oldflp->oif == 0
2378 && (ipv4_is_multicast(oldflp->fl4_dst) || 2373 && (ipv4_is_multicast(oldflp->fl4_dst) ||
2379 oldflp->fl4_dst == htonl(0xFFFFFFFF))) { 2374 oldflp->fl4_dst == htonl(0xFFFFFFFF))) {
2375 /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
2376 dev_out = ip_dev_find(net, oldflp->fl4_src);
2377 if (dev_out == NULL)
2378 goto out;
2379
2380 /* Special hack: user can direct multicasts 2380 /* Special hack: user can direct multicasts
2381 and limited broadcast via necessary interface 2381 and limited broadcast via necessary interface
2382 without fiddling with IP_MULTICAST_IF or IP_PKTINFO. 2382 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,
2395 fl.oif = dev_out->ifindex; 2395 fl.oif = dev_out->ifindex;
2396 goto make_route; 2396 goto make_route;
2397 } 2397 }
2398 if (dev_out) 2398
2399 if (!(oldflp->flags & FLOWI_FLAG_ANYSRC)) {
2400 /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
2401 dev_out = ip_dev_find(net, oldflp->fl4_src);
2402 if (dev_out == NULL)
2403 goto out;
2399 dev_put(dev_out); 2404 dev_put(dev_out);
2400 dev_out = NULL; 2405 dev_out = NULL;
2406 }
2401 } 2407 }
2402 2408
2403 2409