Commit a210d01ae3ee006b59e54e772a7f212486e0f021

Authored by Julian Anastasov
Committed by David S. Miller
1 parent 4edd87ad5c

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>

Showing 2 changed files with 15 additions and 7 deletions Side-by-side Diff

... ... @@ -47,6 +47,8 @@
47 47 #define fl4_scope nl_u.ip4_u.scope
48 48  
49 49 __u8 proto;
  50 + __u8 flags;
  51 +#define FLOWI_FLAG_ANYSRC 0x01
50 52 union {
51 53 struct {
52 54 __be16 sport;
... ... @@ -2361,11 +2361,6 @@
2361 2361 ipv4_is_zeronet(oldflp->fl4_src))
2362 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 2364 /* I removed check for oif == dev_out->oif here.
2370 2365 It was wrong for two reasons:
2371 2366 1. ip_dev_find(net, saddr) can return wrong iface, if saddr
... ... @@ -2377,6 +2372,11 @@
2377 2372 if (oldflp->oif == 0
2378 2373 && (ipv4_is_multicast(oldflp->fl4_dst) ||
2379 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 2380 /* Special hack: user can direct multicasts
2381 2381 and limited broadcast via necessary interface
2382 2382 without fiddling with IP_MULTICAST_IF or IP_PKTINFO.
2383 2383  
... ... @@ -2395,9 +2395,15 @@
2395 2395 fl.oif = dev_out->ifindex;
2396 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 2404 dev_put(dev_out);
2400   - dev_out = NULL;
  2405 + dev_out = NULL;
  2406 + }
2401 2407 }
2402 2408  
2403 2409