diff options
-rw-r--r-- | include/net/flow.h | 2 | ||||
-rw-r--r-- | net/ipv4/route.c | 20 |
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 | ||