Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 202654
b: refs/heads/master
c: 96d3622
h: refs/heads/master
v: v3
  • Loading branch information
Eric Dumazet authored and David S. Miller committed Jun 3, 2010
1 parent f8c0fed commit 88eed8a
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 19 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: b5f7e7554753e2cc3ef3bef0271fdb32027df2ba
refs/heads/master: 96d362202bfc0e5da78ee59b1645296fbca515f4
35 changes: 17 additions & 18 deletions trunk/net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -1843,13 +1843,14 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
rt->rt_type = res->type;
}

/* called in rcu_read_lock() section */
static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
u8 tos, struct net_device *dev, int our)
{
unsigned hash;
unsigned int hash;
struct rtable *rth;
__be32 spec_dst;
struct in_device *in_dev = in_dev_get(dev);
struct in_device *in_dev = __in_dev_get_rcu(dev);
u32 itag = 0;
int err;

Expand Down Expand Up @@ -1914,18 +1915,14 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
#endif
RT_CACHE_STAT_INC(in_slow_mc);

in_dev_put(in_dev);
hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev)));
return rt_intern_hash(hash, rth, NULL, skb, dev->ifindex);

e_nobufs:
in_dev_put(in_dev);
return -ENOBUFS;

e_inval:
err = -EINVAL;
return -EINVAL;
e_err:
in_dev_put(in_dev);
return err;
}

Expand Down Expand Up @@ -2101,7 +2098,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
u8 tos, struct net_device *dev)
{
struct fib_result res;
struct in_device *in_dev = in_dev_get(dev);
struct in_device *in_dev = __in_dev_get_rcu(dev);
struct flowi fl = { .nl_u = { .ip4_u =
{ .daddr = daddr,
.saddr = saddr,
Expand Down Expand Up @@ -2179,7 +2176,6 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,

err = ip_mkroute_input(skb, &res, &fl, in_dev, daddr, saddr, tos);
done:
in_dev_put(in_dev);
if (free_res)
fib_res_put(&res);
out: return err;
Expand Down Expand Up @@ -2288,16 +2284,18 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,
unsigned hash;
int iif = dev->ifindex;
struct net *net;
int res;

net = dev_net(dev);

rcu_read_lock();

if (!rt_caching(net))
goto skip_cache;

tos &= IPTOS_RT_MASK;
hash = rt_hash(daddr, saddr, iif, rt_genid(net));

rcu_read_lock();
for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
rth = rcu_dereference(rth->u.dst.rt_next)) {
if ((((__force u32)rth->fl.fl4_dst ^ (__force u32)daddr) |
Expand All @@ -2321,7 +2319,6 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,
}
RT_CACHE_STAT_INC(in_hlist_search);
}
rcu_read_unlock();

skip_cache:
/* Multicast recognition logic is moved from route cache to here.
Expand All @@ -2336,28 +2333,30 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,
route cache entry is created eventually.
*/
if (ipv4_is_multicast(daddr)) {
struct in_device *in_dev;
struct in_device *in_dev = __in_dev_get_rcu(dev);

rcu_read_lock();
if ((in_dev = __in_dev_get_rcu(dev)) != NULL) {
if (in_dev) {
int our = ip_check_mc(in_dev, daddr, saddr,
ip_hdr(skb)->protocol);
ip_hdr(skb)->protocol);
if (our
#ifdef CONFIG_IP_MROUTE
||
(!ipv4_is_local_multicast(daddr) &&
IN_DEV_MFORWARD(in_dev))
#endif
) {
int res = ip_route_input_mc(skb, daddr, saddr,
tos, dev, our);
rcu_read_unlock();
return ip_route_input_mc(skb, daddr, saddr,
tos, dev, our);
return res;
}
}
rcu_read_unlock();
return -EINVAL;
}
return ip_route_input_slow(skb, daddr, saddr, tos, dev);
res = ip_route_input_slow(skb, daddr, saddr, tos, dev);
rcu_read_unlock();
return res;
}
EXPORT_SYMBOL(ip_route_input_common);

Expand Down

0 comments on commit 88eed8a

Please sign in to comment.