ipv6: Remove neigh argument from ndisc_send_redirect()
authorDavid S. Miller <davem@davemloft.net>
Fri, 27 Jan 2012 23:30:48 +0000 (15:30 -0800)
committerDavid S. Miller <davem@davemloft.net>
Sat, 28 Jan 2012 02:00:08 +0000 (21:00 -0500)
Instead, compute it as-needed inside of that function using
dst_neigh_lookup().

Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/ndisc.h
net/ipv6/ip6_output.c
net/ipv6/ndisc.c

index e3133c2..6f9c25a 100644 (file)
@@ -133,7 +133,6 @@ extern void                 ndisc_send_rs(struct net_device *dev,
                                              const struct in6_addr *daddr);
 
 extern void                    ndisc_send_redirect(struct sk_buff *skb,
-                                                   struct neighbour *neigh,
                                                    const struct in6_addr *target);
 
 extern int                     ndisc_mc_map(const struct in6_addr *addr, char *buf,
index d97e071..604809b 100644 (file)
@@ -486,7 +486,7 @@ int ip6_forward(struct sk_buff *skb)
                   and by source (inside ndisc_send_redirect)
                 */
                if (inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ))
-                       ndisc_send_redirect(skb, n, target);
+                       ndisc_send_redirect(skb, target);
        } else {
                int addrtype = ipv6_addr_type(&hdr->saddr);
 
index c574ebc..8d81701 100644 (file)
@@ -1512,8 +1512,7 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
        }
 }
 
-void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
-                        const struct in6_addr *target)
+void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 {
        struct net_device *dev = skb->dev;
        struct net *net = dev_net(dev);
@@ -1571,6 +1570,13 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
                goto release;
 
        if (dev->addr_len) {
+               struct neighbour *neigh = dst_neigh_lookup(skb_dst(skb), target);
+               if (!neigh) {
+                       ND_PRINTK2(KERN_WARNING
+                                  "ICMPv6 Redirect: no neigh for target address\n");
+                       goto release;
+               }
+
                read_lock_bh(&neigh->lock);
                if (neigh->nud_state & NUD_VALID) {
                        memcpy(ha_buf, neigh->ha, dev->addr_len);
@@ -1579,6 +1585,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
                        len += ndisc_opt_addr_space(dev);
                } else
                        read_unlock_bh(&neigh->lock);
+
+               neigh_release(neigh);
        }
 
        rd_len = min_t(unsigned int,