--- /dev/null
+From aksecurity@gmail.com Fri Apr 19 11:39:50 2019
+From: Amit Klein <aksecurity@gmail.com>
+Date: Thu, 18 Apr 2019 21:07:11 +0000
+Subject: inet: update the IP ID generation algorithm to higher standards.
+To: stable@vger.kernel.org
+Cc: Greg KH <gregkh@linuxfoundation.org>
+Message-ID: <20190418210711.GA14024@linux-dev.tyosb345ce3ufhj0w14gubr5le.bx.internal.cloudapp.net>
+Content-Disposition: inline
+
+From: Amit Klein <aksecurity@gmail.com>
+
+Commit 355b98553789 ("netns: provide pure entropy for net_hash_mix()")
+makes net_hash_mix() return a true 32 bits of entropy. When used in the
+IP ID generation algorithm, this has the effect of extending the IP ID
+generation key from 32 bits to 64 bits.
+
+However, net_hash_mix() is only used for IP ID generation starting with
+kernel version 4.1. Therefore, earlier kernels remain with 32-bit key
+no matter what the net_hash_mix() return value is.
+
+This change addresses the issue by explicitly extending the key to 64
+bits for kernels older than 4.1.
+
+Signed-off-by: Amit Klein <aksecurity@gmail.com>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/route.c | 4 +++-
+ net/ipv6/ip6_output.c | 3 +++
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -488,13 +488,15 @@ EXPORT_SYMBOL(ip_idents_reserve);
+ void __ip_select_ident(struct iphdr *iph, int segs)
+ {
+ static u32 ip_idents_hashrnd __read_mostly;
++ static u32 ip_idents_hashrnd_extra __read_mostly;
+ u32 hash, id;
+
+ net_get_random_once(&ip_idents_hashrnd, sizeof(ip_idents_hashrnd));
++ net_get_random_once(&ip_idents_hashrnd_extra, sizeof(ip_idents_hashrnd_extra));
+
+ hash = jhash_3words((__force u32)iph->daddr,
+ (__force u32)iph->saddr,
+- iph->protocol,
++ iph->protocol ^ ip_idents_hashrnd_extra,
+ ip_idents_hashrnd);
+ id = ip_idents_reserve(hash, segs);
+ iph->id = htons(id);
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -546,12 +546,15 @@ static void ip6_copy_metadata(struct sk_
+ static void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)
+ {
+ static u32 ip6_idents_hashrnd __read_mostly;
++ static u32 ip6_idents_hashrnd_extra __read_mostly;
+ u32 hash, id;
+
+ net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd));
++ net_get_random_once(&ip6_idents_hashrnd_extra, sizeof(ip6_idents_hashrnd_extra));
+
+ hash = __ipv6_addr_jhash(&rt->rt6i_dst.addr, ip6_idents_hashrnd);
+ hash = __ipv6_addr_jhash(&rt->rt6i_src.addr, hash);
++ hash = jhash_1word(hash, ip6_idents_hashrnd_extra);
+
+ id = ip_idents_reserve(hash, 1);
+ fhdr->identification = htonl(id);