aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r--net/ipv6/route.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index c518e4ec0cea..4b581c675bb2 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -120,21 +120,27 @@ static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
120 return p; 120 return p;
121} 121}
122 122
123static inline const void *choose_neigh_daddr(struct rt6_info *rt, const void *daddr) 123static inline const void *choose_neigh_daddr(struct rt6_info *rt,
124 struct sk_buff *skb,
125 const void *daddr)
124{ 126{
125 struct in6_addr *p = &rt->rt6i_gateway; 127 struct in6_addr *p = &rt->rt6i_gateway;
126 128
127 if (!ipv6_addr_any(p)) 129 if (!ipv6_addr_any(p))
128 return (const void *) p; 130 return (const void *) p;
131 else if (skb)
132 return &ipv6_hdr(skb)->daddr;
129 return daddr; 133 return daddr;
130} 134}
131 135
132static struct neighbour *ip6_neigh_lookup(const struct dst_entry *dst, const void *daddr) 136static struct neighbour *ip6_neigh_lookup(const struct dst_entry *dst,
137 struct sk_buff *skb,
138 const void *daddr)
133{ 139{
134 struct rt6_info *rt = (struct rt6_info *) dst; 140 struct rt6_info *rt = (struct rt6_info *) dst;
135 struct neighbour *n; 141 struct neighbour *n;
136 142
137 daddr = choose_neigh_daddr(rt, daddr); 143 daddr = choose_neigh_daddr(rt, skb, daddr);
138 n = __ipv6_neigh_lookup(&nd_tbl, dst->dev, daddr); 144 n = __ipv6_neigh_lookup(&nd_tbl, dst->dev, daddr);
139 if (n) 145 if (n)
140 return n; 146 return n;
@@ -1162,7 +1168,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
1162 if (neigh) 1168 if (neigh)
1163 neigh_hold(neigh); 1169 neigh_hold(neigh);
1164 else { 1170 else {
1165 neigh = ip6_neigh_lookup(&rt->dst, &fl6->daddr); 1171 neigh = ip6_neigh_lookup(&rt->dst, NULL, &fl6->daddr);
1166 if (IS_ERR(neigh)) { 1172 if (IS_ERR(neigh)) {
1167 in6_dev_put(idev); 1173 in6_dev_put(idev);
1168 dst_free(&rt->dst); 1174 dst_free(&rt->dst);