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 | ||
