diff options
author | David S. Miller <davem@davemloft.net> | 2012-01-28 00:07:56 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-01-28 03:00:08 +0100 |
commit | eb857186eb771998fc9ab4bfd398a6fedb5a295c (patch) | |
tree | e3cde1845c4672b8123b34b631133f28194873a7 /net/ipv6/ndisc.c | |
parent | ipv4: ip_gre: Convert to dst_neigh_lookup() (diff) | |
download | linux-eb857186eb771998fc9ab4bfd398a6fedb5a295c.tar.xz linux-eb857186eb771998fc9ab4bfd398a6fedb5a295c.zip |
ipv6: ndisc: Convert to dst_neigh_lookup()
Now all code paths grab a local reference to the neigh, so if neigh
is not NULL we unconditionally release it at the end. The old logic
would only release if we didn't have a non-NULL 'rt'.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ndisc.c')
-rw-r--r-- | net/ipv6/ndisc.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index d8f02ef88e59..c574ebce3fb5 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1223,11 +1223,17 @@ static void ndisc_router_discovery(struct sk_buff *skb) rt = rt6_get_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev); - if (rt) - neigh = dst_get_neighbour_noref(&rt->dst); - + if (rt) { + neigh = dst_neigh_lookup(&rt->dst, &ipv6_hdr(skb)->saddr); + if (!neigh) { + ND_PRINTK0(KERN_ERR + "ICMPv6 RA: %s() got default router without neighbour.\n", + __func__); + dst_release(&rt->dst); + return; + } + } if (rt && lifetime == 0) { - neigh_clone(neigh); ip6_del_rt(rt); rt = NULL; } @@ -1244,7 +1250,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) return; } - neigh = dst_get_neighbour_noref(&rt->dst); + neigh = dst_neigh_lookup(&rt->dst, &ipv6_hdr(skb)->saddr); if (neigh == NULL) { ND_PRINTK0(KERN_ERR "ICMPv6 RA: %s() got default router without neighbour.\n", @@ -1411,7 +1417,7 @@ skip_routeinfo: out: if (rt) dst_release(&rt->dst); - else if (neigh) + if (neigh) neigh_release(neigh); } |