Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 214822
b: refs/heads/master
c: 0197aa3
h: refs/heads/master
v: v3
  • Loading branch information
Eric Dumazet authored and David S. Miller committed Oct 1, 2010
1 parent f6d1124 commit e6b417c
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 27 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 82efee1499a27c06f5afb11b07db384fdb3f7004
refs/heads/master: 0197aa38df2ce550c0bfc96194b07ce6b68af814
38 changes: 12 additions & 26 deletions trunk/net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -2487,6 +2487,7 @@ static int ip_mkroute_output(struct rtable **rp,

/*
* Major route resolver routine.
* called with rcu_read_lock();
*/

static int ip_route_output_slow(struct net *net, struct rtable **rp,
Expand All @@ -2505,7 +2506,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
.iif = net->loopback_dev->ifindex,
.oif = oldflp->oif };
struct fib_result res;
unsigned flags = 0;
unsigned int flags = 0;
struct net_device *dev_out = NULL;
int free_res = 0;
int err;
Expand Down Expand Up @@ -2535,7 +2536,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
(ipv4_is_multicast(oldflp->fl4_dst) ||
oldflp->fl4_dst == htonl(0xFFFFFFFF))) {
/* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
dev_out = ip_dev_find(net, oldflp->fl4_src);
dev_out = __ip_dev_find(net, oldflp->fl4_src, false);
if (dev_out == NULL)
goto out;

Expand All @@ -2560,26 +2561,21 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,

if (!(oldflp->flags & FLOWI_FLAG_ANYSRC)) {
/* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
dev_out = ip_dev_find(net, oldflp->fl4_src);
if (dev_out == NULL)
if (!__ip_dev_find(net, oldflp->fl4_src, false))
goto out;
dev_put(dev_out);
dev_out = NULL;
}
}


if (oldflp->oif) {
dev_out = dev_get_by_index(net, oldflp->oif);
dev_out = dev_get_by_index_rcu(net, oldflp->oif);
err = -ENODEV;
if (dev_out == NULL)
goto out;

/* RACE: Check return value of inet_select_addr instead. */
if (rcu_dereference_raw(dev_out->ip_ptr) == NULL) {
dev_put(dev_out);
if (rcu_dereference(dev_out->ip_ptr) == NULL)
goto out; /* Wrong error code */
}

if (ipv4_is_local_multicast(oldflp->fl4_dst) ||
oldflp->fl4_dst == htonl(0xFFFFFFFF)) {
Expand All @@ -2602,10 +2598,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
fl.fl4_dst = fl.fl4_src;
if (!fl.fl4_dst)
fl.fl4_dst = fl.fl4_src = htonl(INADDR_LOOPBACK);
if (dev_out)
dev_put(dev_out);
dev_out = net->loopback_dev;
dev_hold(dev_out);
fl.oif = net->loopback_dev->ifindex;
res.type = RTN_LOCAL;
flags |= RTCF_LOCAL;
Expand Down Expand Up @@ -2639,8 +2632,6 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
res.type = RTN_UNICAST;
goto make_route;
}
if (dev_out)
dev_put(dev_out);
err = -ENETUNREACH;
goto out;
}
Expand All @@ -2649,10 +2640,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
if (res.type == RTN_LOCAL) {
if (!fl.fl4_src)
fl.fl4_src = fl.fl4_dst;
if (dev_out)
dev_put(dev_out);
dev_out = net->loopback_dev;
dev_hold(dev_out);
fl.oif = dev_out->ifindex;
if (res.fi)
fib_info_put(res.fi);
Expand All @@ -2672,28 +2660,23 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
if (!fl.fl4_src)
fl.fl4_src = FIB_RES_PREFSRC(res);

if (dev_out)
dev_put(dev_out);
dev_out = FIB_RES_DEV(res);
dev_hold(dev_out);
fl.oif = dev_out->ifindex;


make_route:
err = ip_mkroute_output(rp, &res, &fl, oldflp, dev_out, flags);


if (free_res)
fib_res_put(&res);
if (dev_out)
dev_put(dev_out);
out: return err;
}

int __ip_route_output_key(struct net *net, struct rtable **rp,
const struct flowi *flp)
{
unsigned hash;
unsigned int hash;
int res;
struct rtable *rth;

if (!rt_caching(net))
Expand Down Expand Up @@ -2724,7 +2707,10 @@ int __ip_route_output_key(struct net *net, struct rtable **rp,
rcu_read_unlock_bh();

slow_output:
return ip_route_output_slow(net, rp, flp);
rcu_read_lock();
res = ip_route_output_slow(net, rp, flp);
rcu_read_unlock();
return res;
}
EXPORT_SYMBOL_GPL(__ip_route_output_key);

Expand Down

0 comments on commit e6b417c

Please sign in to comment.