aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/datagram.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 762a58c772b8..62d908e64eeb 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -325,6 +325,16 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu)
325 kfree_skb(skb); 325 kfree_skb(skb);
326} 326}
327 327
328/* For some errors we have valid addr_offset even with zero payload and
329 * zero port. Also, addr_offset should be supported if port is set.
330 */
331static inline bool ipv6_datagram_support_addr(struct sock_exterr_skb *serr)
332{
333 return serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6 ||
334 serr->ee.ee_origin == SO_EE_ORIGIN_ICMP ||
335 serr->ee.ee_origin == SO_EE_ORIGIN_LOCAL || serr->port;
336}
337
328/* IPv6 supports cmsg on all origins aside from SO_EE_ORIGIN_LOCAL. 338/* IPv6 supports cmsg on all origins aside from SO_EE_ORIGIN_LOCAL.
329 * 339 *
330 * At one point, excluding local errors was a quick test to identify icmp/icmp6 340 * At one point, excluding local errors was a quick test to identify icmp/icmp6
@@ -389,7 +399,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
389 399
390 serr = SKB_EXT_ERR(skb); 400 serr = SKB_EXT_ERR(skb);
391 401
392 if (sin && serr->port) { 402 if (sin && ipv6_datagram_support_addr(serr)) {
393 const unsigned char *nh = skb_network_header(skb); 403 const unsigned char *nh = skb_network_header(skb);
394 sin->sin6_family = AF_INET6; 404 sin->sin6_family = AF_INET6;
395 sin->sin6_flowinfo = 0; 405 sin->sin6_flowinfo = 0;