From: Greg Kroah-Hartman Date: Fri, 15 Jan 2021 09:21:09 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.4.252~26 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2f0af9b4208b0036e0a393bb52a381eef66564c7;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: net-fix-pmtu-check-in-nopmtudisc-mode.patch net-ip-always-refragment-ip-defragmented-packets.patch --- diff --git a/queue-4.9/net-fix-pmtu-check-in-nopmtudisc-mode.patch b/queue-4.9/net-fix-pmtu-check-in-nopmtudisc-mode.patch new file mode 100644 index 00000000000..17f0e9f3678 --- /dev/null +++ b/queue-4.9/net-fix-pmtu-check-in-nopmtudisc-mode.patch @@ -0,0 +1,61 @@ +From foo@baz Fri Jan 15 09:43:29 AM CET 2021 +From: Florian Westphal +Date: Wed, 6 Jan 2021 00:15:22 +0100 +Subject: net: fix pmtu check in nopmtudisc mode + +From: Florian Westphal + +[ Upstream commit 50c661670f6a3908c273503dfa206dfc7aa54c07 ] + +For some reason ip_tunnel insist on setting the DF bit anyway when the +inner header has the DF bit set, EVEN if the tunnel was configured with +'nopmtudisc'. + +This means that the script added in the previous commit +cannot be made to work by adding the 'nopmtudisc' flag to the +ip tunnel configuration. Doing so breaks connectivity even for the +without-conntrack/netfilter scenario. + +When nopmtudisc is set, the tunnel will skip the mtu check, so no +icmp error is sent to client. Then, because inner header has DF set, +the outer header gets added with DF bit set as well. + +IP stack then sends an error to itself because the packet exceeds +the device MTU. + +Fixes: 23a3647bc4f93 ("ip_tunnels: Use skb-len to PMTU check.") +Cc: Stefano Brivio +Signed-off-by: Florian Westphal +Acked-by: Pablo Neira Ayuso +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_tunnel.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/net/ipv4/ip_tunnel.c ++++ b/net/ipv4/ip_tunnel.c +@@ -743,7 +743,11 @@ void ip_tunnel_xmit(struct sk_buff *skb, + goto tx_error; + } + +- if (tnl_update_pmtu(dev, skb, rt, tnl_params->frag_off, inner_iph)) { ++ df = tnl_params->frag_off; ++ if (skb->protocol == htons(ETH_P_IP) && !tunnel->ignore_df) ++ df |= (inner_iph->frag_off & htons(IP_DF)); ++ ++ if (tnl_update_pmtu(dev, skb, rt, df, inner_iph)) { + ip_rt_put(rt); + goto tx_error; + } +@@ -771,10 +775,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, + ttl = ip4_dst_hoplimit(&rt->dst); + } + +- df = tnl_params->frag_off; +- if (skb->protocol == htons(ETH_P_IP) && !tunnel->ignore_df) +- df |= (inner_iph->frag_off&htons(IP_DF)); +- + max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr) + + rt->dst.header_len + ip_encap_hlen(&tunnel->encap); + if (max_headroom > dev->needed_headroom) diff --git a/queue-4.9/net-ip-always-refragment-ip-defragmented-packets.patch b/queue-4.9/net-ip-always-refragment-ip-defragmented-packets.patch new file mode 100644 index 00000000000..d681a9df53b --- /dev/null +++ b/queue-4.9/net-ip-always-refragment-ip-defragmented-packets.patch @@ -0,0 +1,67 @@ +From foo@baz Fri Jan 15 10:15:43 AM CET 2021 +From: Florian Westphal +Date: Wed, 6 Jan 2021 00:15:23 +0100 +Subject: net: ip: always refragment ip defragmented packets + +From: Florian Westphal + +[ Upstream commit bb4cc1a18856a73f0ff5137df0c2a31f4c50f6cf ] + +Conntrack reassembly records the largest fragment size seen in IPCB. +However, when this gets forwarded/transmitted, fragmentation will only +be forced if one of the fragmented packets had the DF bit set. + +In that case, a flag in IPCB will force fragmentation even if the +MTU is large enough. + +This should work fine, but this breaks with ip tunnels. +Consider client that sends a UDP datagram of size X to another host. + +The client fragments the datagram, so two packets, of size y and z, are +sent. DF bit is not set on any of these packets. + +Middlebox netfilter reassembles those packets back to single size-X +packet, before routing decision. + +packet-size-vs-mtu checks in ip_forward are irrelevant, because DF bit +isn't set. At output time, ip refragmentation is skipped as well +because x is still smaller than the mtu of the output device. + +If ttransmit device is an ip tunnel, the packet size increases to +x+overhead. + +Also, tunnel might be configured to force DF bit on outer header. + +In this case, packet will be dropped (exceeds MTU) and an ICMP error is +generated back to sender. + +But sender already respects the announced MTU, all the packets that +it sent did fit the announced mtu. + +Force refragmentation as per original sizes unconditionally so ip tunnel +will encapsulate the fragments instead. + +The only other solution I see is to place ip refragmentation in +the ip_tunnel code to handle this case. + +Fixes: d6b915e29f4ad ("ip_fragment: don't forward defragmented DF packet") +Reported-by: Christian Perle +Signed-off-by: Florian Westphal +Acked-by: Pablo Neira Ayuso +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_output.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -300,7 +300,7 @@ static int ip_finish_output(struct net * + if (skb_is_gso(skb)) + return ip_finish_output_gso(net, sk, skb, mtu); + +- if (skb->len > mtu || (IPCB(skb)->flags & IPSKB_FRAG_PMTU)) ++ if (skb->len > mtu || IPCB(skb)->frag_max_size) + return ip_fragment(net, sk, skb, mtu, ip_finish_output2); + + return ip_finish_output2(net, sk, skb); diff --git a/queue-4.9/powerpc-fix-incorrect-stw-ux-u-x-instructions-in-__s.patch b/queue-4.9/powerpc-fix-incorrect-stw-ux-u-x-instructions-in-__s.patch index bc55b5ebec7..6e0d803bad6 100644 --- a/queue-4.9/powerpc-fix-incorrect-stw-ux-u-x-instructions-in-__s.patch +++ b/queue-4.9/powerpc-fix-incorrect-stw-ux-u-x-instructions-in-__s.patch @@ -28,15 +28,13 @@ Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/96354bd77977a6a933fe9020da57629007fdb920.1603358942.git.christophe.leroy@csgroup.eu Signed-off-by: Sasha Levin --- - arch/powerpc/include/asm/book3s/32/pgtable.h | 4 ++-- - arch/powerpc/include/asm/nohash/pgtable.h | 4 ++-- + arch/powerpc/include/asm/book3s/32/pgtable.h | 4 ++-- + arch/powerpc/include/asm/nohash/pgtable.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) -diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h -index 6b8b2d57fdc8c..e588028922a83 100644 --- a/arch/powerpc/include/asm/book3s/32/pgtable.h +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h -@@ -411,9 +411,9 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, +@@ -411,9 +411,9 @@ static inline void __set_pte_at(struct m if (pte_val(*ptep) & _PAGE_HASHPTE) flush_hash_entry(mm, ptep, addr); __asm__ __volatile__("\ @@ -48,11 +46,9 @@ index 6b8b2d57fdc8c..e588028922a83 100644 : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4)) : "r" (pte) : "memory"); -diff --git a/arch/powerpc/include/asm/nohash/pgtable.h b/arch/powerpc/include/asm/nohash/pgtable.h -index 1263c22d60d85..330fe178c0c5e 100644 --- a/arch/powerpc/include/asm/nohash/pgtable.h +++ b/arch/powerpc/include/asm/nohash/pgtable.h -@@ -155,9 +155,9 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, +@@ -155,9 +155,9 @@ static inline void __set_pte_at(struct m flush_hash_entry(mm, ptep, addr); #endif __asm__ __volatile__("\ @@ -64,6 +60,3 @@ index 1263c22d60d85..330fe178c0c5e 100644 : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4)) : "r" (pte) : "memory"); --- -2.27.0 - diff --git a/queue-4.9/series b/queue-4.9/series index 108b6fc04d0..27db570253c 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -5,3 +5,5 @@ xcopy-loop-over-devices-using-idr-helper.patch scsi-target-fix-xcopy-naa-identifier-lookup.patch target-add-xcopy-target-segment-desc-sense-codes.patch powerpc-fix-incorrect-stw-ux-u-x-instructions-in-__s.patch +net-ip-always-refragment-ip-defragmented-packets.patch +net-fix-pmtu-check-in-nopmtudisc-mode.patch