]> rtime.felk.cvut.cz Git - zynq/linux.git/blobdiff - net/ipv4/ip_sockglue.c
Merge tag 'v4.0.8' into xlnx_4.0.8-rt6
[zynq/linux.git] / net / ipv4 / ip_sockglue.c
index 5cd99271d3a6a07c17a915fddde7a5a0c8a86618..d9e8ff31aba062b5848cd5d96f41069669646245 100644 (file)
@@ -432,6 +432,15 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 inf
                kfree_skb(skb);
 }
 
+/* For some errors we have valid addr_offset even with zero payload and
+ * zero port. Also, addr_offset should be supported if port is set.
+ */
+static inline bool ipv4_datagram_support_addr(struct sock_exterr_skb *serr)
+{
+       return serr->ee.ee_origin == SO_EE_ORIGIN_ICMP ||
+              serr->ee.ee_origin == SO_EE_ORIGIN_LOCAL || serr->port;
+}
+
 /* IPv4 supports cmsg on all imcp errors and some timestamps
  *
  * Timestamp code paths do not initialize the fields expected by cmsg:
@@ -498,7 +507,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
 
        serr = SKB_EXT_ERR(skb);
 
-       if (sin && serr->port) {
+       if (sin && ipv4_datagram_support_addr(serr)) {
                sin->sin_family = AF_INET;
                sin->sin_addr.s_addr = *(__be32 *)(skb_network_header(skb) +
                                                   serr->addr_offset);