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 | ||
