diff --git a/include/uapi/linux/in.h b/include/uapi/linux/in.h index 48e8a225b985ae646b4bba2cdcdf62ca9c42a7a6..2a66ab49f14dd25b08b8d64ab8ee87e6f4e4a606 100644 --- a/include/uapi/linux/in.h +++ b/include/uapi/linux/in.h @@ -280,6 +280,9 @@ struct sockaddr_in { /* Address indicating an error return. */ #define INADDR_NONE ((unsigned long int) 0xffffffff) +/* Dummy address for src of ICMP replies if no real address is set (RFC7600). */ +#define INADDR_DUMMY ((unsigned long int) 0xc0000008) + /* Network number for local host loopback. */ #define IN_LOOPBACKNET 127 diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 609a73fe6fbbe70ecdddf34d182b59168889e11b..88d676beda399fa3f032e7c0fc27b0c444983d9d 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -746,6 +746,13 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info, icmp_param.data_len = room; icmp_param.head_len = sizeof(struct icmphdr); + /* if we don't have a source address at this point, fall back to the + * dummy address instead of sending out a packet with a source address + * of 0.0.0.0 + */ + if (!fl4.saddr) + fl4.saddr = htonl(INADDR_DUMMY); + icmp_push_reply(&icmp_param, &fl4, &ipc, &rt); ende: ip_rt_put(rt);