static const __be32 inaddr_any = 0;
        struct net_device *dev = dst->dev;
        const __be32 *pkey = daddr;
+       const struct rtable *rt;
        struct neighbour *n;
 
+       rt = (const struct rtable *) dst;
+
        if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
                pkey = &inaddr_any;
+       else if (rt->rt_gateway)
+               pkey = (const __be32 *) &rt->rt_gateway;
 
        n = __ipv4_neigh_lookup(&arp_tbl, dev, *(__force u32 *)pkey);
        if (n)
 
        return p;
 }
 
+static inline const void *choose_neigh_daddr(struct rt6_info *rt, const void *daddr)
+{
+       struct in6_addr *p = &rt->rt6i_gateway;
+
+       if (p->s6_addr32[0] | p->s6_addr32[1] |
+           p->s6_addr32[2] | p->s6_addr32[3])
+               return (const void *) p;
+       return daddr;
+}
+
 static struct neighbour *ip6_neigh_lookup(const struct dst_entry *dst, const void *daddr)
 {
-       struct neighbour *n = __ipv6_neigh_lookup(&nd_tbl, dst->dev, daddr);
+       struct rt6_info *rt = (struct rt6_info *) dst;
+       struct neighbour *n;
+
+       daddr = choose_neigh_daddr(rt, daddr);
+       n = __ipv6_neigh_lookup(&nd_tbl, dst->dev, daddr);
        if (n)
                return n;
        return neigh_create(&nd_tbl, daddr, dst->dev);