net: Add optional SKB arg to dst_ops->neigh_lookup().
[firefly-linux-kernel-4.4.55.git] / net / ipv4 / route.c
index bae36386e7221640f23e2de0e3880abec43ac24d..7453dfcdb439c28dbbc490fa44636698831cc135 100644 (file)
@@ -188,7 +188,9 @@ static u32 *ipv4_cow_metrics(struct dst_entry *dst, unsigned long old)
        return p;
 }
 
-static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const void *daddr);
+static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst,
+                                          struct sk_buff *skb,
+                                          const void *daddr);
 
 static struct dst_ops ipv4_dst_ops = {
        .family =               AF_INET,
@@ -1088,7 +1090,9 @@ static int slow_chain_length(const struct rtable *head)
        return length >> FRACT_BITS;
 }
 
-static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const void *daddr)
+static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst,
+                                          struct sk_buff *skb,
+                                          const void *daddr)
 {
        struct net_device *dev = dst->dev;
        const __be32 *pkey = daddr;
@@ -1098,6 +1102,8 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const vo
        rt = (const struct rtable *) dst;
        if (rt->rt_gateway)
                pkey = (const __be32 *) &rt->rt_gateway;
+       else if (skb)
+               pkey = &ip_hdr(skb)->daddr;
 
        n = __ipv4_neigh_lookup(dev, *(__force u32 *)pkey);
        if (n)
@@ -1107,7 +1113,7 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const vo
 
 static int rt_bind_neighbour(struct rtable *rt)
 {
-       struct neighbour *n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway);
+       struct neighbour *n = ipv4_neigh_lookup(&rt->dst, NULL, &rt->rt_gateway);
        if (IS_ERR(n))
                return PTR_ERR(n);
        dst_set_neighbour(&rt->dst, n);
@@ -1388,7 +1394,7 @@ static void check_peer_redir(struct dst_entry *dst, struct inet_peer *peer)
 
        rt->rt_gateway = peer->redirect_learned.a4;
 
-       n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway);
+       n = ipv4_neigh_lookup(&rt->dst, NULL, &rt->rt_gateway);
        if (IS_ERR(n)) {
                rt->rt_gateway = orig_gw;
                return;