summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulian Anastasov <ja@ssi.bg>2017-02-25 17:57:43 +0200
committerDavid S. Miller <davem@davemloft.net>2017-02-26 21:35:24 -0500
commit1ecc9ad02c3d4cf44bc94bffcb3b12e7861b00a7 (patch)
tree07885bcb036945316b5f8add64dd202ae99c9f48
parentc4d2603dac3a555e4bb324daf5cb5cdb5694eedd (diff)
downloadlinux-1ecc9ad02c3d4cf44bc94bffcb3b12e7861b00a7.tar.gz
linux-1ecc9ad02c3d4cf44bc94bffcb3b12e7861b00a7.tar.bz2
linux-1ecc9ad02c3d4cf44bc94bffcb3b12e7861b00a7.zip
xfrm: provide correct dst in xfrm_neigh_lookup
Fix xfrm_neigh_lookup to provide dst->path to the neigh_lookup dst_ops method. When skb is provided, the IP address in packet should already match the dst->path address family. But for the non-skb case, we should consider the last tunnel address as nexthop address. Fixes: f894cbf847c9 ("net: Add optional SKB arg to dst_ops->neigh_lookup().") Signed-off-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/xfrm/xfrm_policy.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 5f3e87866438..0806dccdf507 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2836,14 +2836,8 @@ static unsigned int xfrm_mtu(const struct dst_entry *dst)
return mtu ? : dst_mtu(dst->path);
}
-static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst,
- struct sk_buff *skb,
- const void *daddr)
-{
- return dst->path->ops->neigh_lookup(dst, skb, daddr);
-}
-
-static void xfrm_confirm_neigh(const struct dst_entry *dst, const void *daddr)
+static const void *xfrm_get_dst_nexthop(const struct dst_entry *dst,
+ const void *daddr)
{
const struct dst_entry *path = dst->path;
@@ -2857,6 +2851,25 @@ static void xfrm_confirm_neigh(const struct dst_entry *dst, const void *daddr)
else if (!(xfrm->type->flags & XFRM_TYPE_LOCAL_COADDR))
daddr = &xfrm->id.daddr;
}
+ return daddr;
+}
+
+static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst,
+ struct sk_buff *skb,
+ const void *daddr)
+{
+ const struct dst_entry *path = dst->path;
+
+ if (!skb)
+ daddr = xfrm_get_dst_nexthop(dst, daddr);
+ return path->ops->neigh_lookup(path, skb, daddr);
+}
+
+static void xfrm_confirm_neigh(const struct dst_entry *dst, const void *daddr)
+{
+ const struct dst_entry *path = dst->path;
+
+ daddr = xfrm_get_dst_nexthop(dst, daddr);
path->ops->confirm_neigh(path, daddr);
}