diff options
author | Julian Anastasov <ja@ssi.bg> | 2017-02-25 10:57:43 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-02-26 21:35:24 -0500 |
commit | 1ecc9ad02c3d4cf44bc94bffcb3b12e7861b00a7 (patch) | |
tree | 07885bcb036945316b5f8add64dd202ae99c9f48 | |
parent | c4d2603dac3a555e4bb324daf5cb5cdb5694eedd (diff) |
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.c | 29 |
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) | |||
2836 | return mtu ? : dst_mtu(dst->path); | 2836 | return mtu ? : dst_mtu(dst->path); |
2837 | } | 2837 | } |
2838 | 2838 | ||
2839 | static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst, | 2839 | static const void *xfrm_get_dst_nexthop(const struct dst_entry *dst, |
2840 | struct sk_buff *skb, | 2840 | const void *daddr) |
2841 | const void *daddr) | ||
2842 | { | ||
2843 | return dst->path->ops->neigh_lookup(dst, skb, daddr); | ||
2844 | } | ||
2845 | |||
2846 | static void xfrm_confirm_neigh(const struct dst_entry *dst, const void *daddr) | ||
2847 | { | 2841 | { |
2848 | const struct dst_entry *path = dst->path; | 2842 | const struct dst_entry *path = dst->path; |
2849 | 2843 | ||
@@ -2857,6 +2851,25 @@ static void xfrm_confirm_neigh(const struct dst_entry *dst, const void *daddr) | |||
2857 | else if (!(xfrm->type->flags & XFRM_TYPE_LOCAL_COADDR)) | 2851 | else if (!(xfrm->type->flags & XFRM_TYPE_LOCAL_COADDR)) |
2858 | daddr = &xfrm->id.daddr; | 2852 | daddr = &xfrm->id.daddr; |
2859 | } | 2853 | } |
2854 | return daddr; | ||
2855 | } | ||
2856 | |||
2857 | static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst, | ||
2858 | struct sk_buff *skb, | ||
2859 | const void *daddr) | ||
2860 | { | ||
2861 | const struct dst_entry *path = dst->path; | ||
2862 | |||
2863 | if (!skb) | ||
2864 | daddr = xfrm_get_dst_nexthop(dst, daddr); | ||
2865 | return path->ops->neigh_lookup(path, skb, daddr); | ||
2866 | } | ||
2867 | |||
2868 | static void xfrm_confirm_neigh(const struct dst_entry *dst, const void *daddr) | ||
2869 | { | ||
2870 | const struct dst_entry *path = dst->path; | ||
2871 | |||
2872 | daddr = xfrm_get_dst_nexthop(dst, daddr); | ||
2860 | path->ops->confirm_neigh(path, daddr); | 2873 | path->ops->confirm_neigh(path, daddr); |
2861 | } | 2874 | } |
2862 | 2875 | ||