diff options
| author | Roland Dreier <roland@purestorage.com> | 2011-01-31 16:16:00 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-01-31 16:16:00 -0500 |
| commit | ec831ea72ee5d7d473899e27a86bd659482c4d0d (patch) | |
| tree | 9bce912eff9cc0aaeb1f47659e99f1d6c9951f80 | |
| parent | c4c93106741bbf61ecd05a2a835af8e3bf31c1bd (diff) | |
net: Add default_mtu() methods to blackhole dst_ops
When an IPSEC SA is still being set up, __xfrm_lookup() will return
-EREMOTE and so ip_route_output_flow() will return a blackhole route.
This can happen in a sndmsg call, and after d33e455337ea ("net: Abstract
default MTU metric calculation behind an accessor.") this leads to a
crash in ip_append_data() because the blackhole dst_ops have no
default_mtu() method and so dst_mtu() calls a NULL pointer.
Fix this by adding default_mtu() methods (that simply return 0, matching
the old behavior) to the blackhole dst_ops.
The IPv4 part of this patch fixes a crash that I saw when using an IPSEC
VPN; the IPv6 part is untested because I don't have an IPv6 VPN, but it
looks to be needed as well.
Signed-off-by: Roland Dreier <roland@purestorage.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/ipv4/route.c | 6 | ||||
| -rw-r--r-- | net/ipv6/route.c | 6 |
2 files changed, 12 insertions, 0 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 351dc4e8524..788a3e74834 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -2707,6 +2707,11 @@ static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 coo | |||
| 2707 | return NULL; | 2707 | return NULL; |
| 2708 | } | 2708 | } |
| 2709 | 2709 | ||
| 2710 | static unsigned int ipv4_blackhole_default_mtu(const struct dst_entry *dst) | ||
| 2711 | { | ||
| 2712 | return 0; | ||
| 2713 | } | ||
| 2714 | |||
| 2710 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) | 2715 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) |
| 2711 | { | 2716 | { |
| 2712 | } | 2717 | } |
| @@ -2716,6 +2721,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = { | |||
| 2716 | .protocol = cpu_to_be16(ETH_P_IP), | 2721 | .protocol = cpu_to_be16(ETH_P_IP), |
| 2717 | .destroy = ipv4_dst_destroy, | 2722 | .destroy = ipv4_dst_destroy, |
| 2718 | .check = ipv4_blackhole_dst_check, | 2723 | .check = ipv4_blackhole_dst_check, |
| 2724 | .default_mtu = ipv4_blackhole_default_mtu, | ||
| 2719 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, | 2725 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, |
| 2720 | }; | 2726 | }; |
| 2721 | 2727 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 28a85fc63cb..1c29f95695d 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -113,6 +113,11 @@ static struct dst_ops ip6_dst_ops_template = { | |||
| 113 | .local_out = __ip6_local_out, | 113 | .local_out = __ip6_local_out, |
| 114 | }; | 114 | }; |
| 115 | 115 | ||
| 116 | static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst) | ||
| 117 | { | ||
| 118 | return 0; | ||
| 119 | } | ||
| 120 | |||
| 116 | static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) | 121 | static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) |
| 117 | { | 122 | { |
| 118 | } | 123 | } |
| @@ -122,6 +127,7 @@ static struct dst_ops ip6_dst_blackhole_ops = { | |||
| 122 | .protocol = cpu_to_be16(ETH_P_IPV6), | 127 | .protocol = cpu_to_be16(ETH_P_IPV6), |
| 123 | .destroy = ip6_dst_destroy, | 128 | .destroy = ip6_dst_destroy, |
| 124 | .check = ip6_dst_check, | 129 | .check = ip6_dst_check, |
| 130 | .default_mtu = ip6_blackhole_default_mtu, | ||
| 125 | .update_pmtu = ip6_rt_blackhole_update_pmtu, | 131 | .update_pmtu = ip6_rt_blackhole_update_pmtu, |
| 126 | }; | 132 | }; |
| 127 | 133 | ||
