diff options
author | Julian Anastasov <ja@ssi.bg> | 2008-10-01 10:28:28 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-10-01 10:28:28 -0400 |
commit | a210d01ae3ee006b59e54e772a7f212486e0f021 (patch) | |
tree | ceea5f8de75e70b13641f340e3b13a125a52567a | |
parent | 4edd87ad5cad8e159e0db3ce3131b3d97219c9cd (diff) |
ipv4: Loosen source address check on IPv4 output
ip_route_output() contains a check to make sure that no flows with
non-local source IP addresses are routed. This obviously makes using
such addresses impossible.
This patch introduces a flowi flag which makes omitting this check
possible. The new flag provides a way of handling transparent and
non-transparent connections differently.
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
Signed-off-by: David S. Miller <davem@davemloft.net>
-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 | ||