| From 1aa600d8dff471f1d12721cff0b1b664807dd026 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sun, 21 Apr 2024 16:22:32 +0200 |
| Subject: ipvs: Fix checksumming on GSO of SCTP packets |
| |
| From: Ismael Luceno <iluceno@suse.de> |
| |
| [ Upstream commit e10d3ba4d434ed172914617ed8d74bd411421193 ] |
| |
| It was observed in the wild that pairs of consecutive packets would leave |
| the IPVS with the same wrong checksum, and the issue only went away when |
| disabling GSO. |
| |
| IPVS needs to avoid computing the SCTP checksum when using GSO. |
| |
| Fixes: 90017accff61 ("sctp: Add GSO support") |
| Co-developed-by: Firo Yang <firo.yang@suse.com> |
| Signed-off-by: Ismael Luceno <iluceno@suse.de> |
| Tested-by: Andreas Taschner <andreas.taschner@suse.com> |
| Acked-by: Julian Anastasov <ja@ssi.bg> |
| Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/netfilter/ipvs/ip_vs_proto_sctp.c | 6 ++++-- |
| 1 file changed, 4 insertions(+), 2 deletions(-) |
| |
| diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c |
| index a0921adc31a9f..1e689c7141271 100644 |
| --- a/net/netfilter/ipvs/ip_vs_proto_sctp.c |
| +++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c |
| @@ -126,7 +126,8 @@ sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, |
| if (sctph->source != cp->vport || payload_csum || |
| skb->ip_summed == CHECKSUM_PARTIAL) { |
| sctph->source = cp->vport; |
| - sctp_nat_csum(skb, sctph, sctphoff); |
| + if (!skb_is_gso(skb) || !skb_is_gso_sctp(skb)) |
| + sctp_nat_csum(skb, sctph, sctphoff); |
| } else { |
| skb->ip_summed = CHECKSUM_UNNECESSARY; |
| } |
| @@ -174,7 +175,8 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, |
| (skb->ip_summed == CHECKSUM_PARTIAL && |
| !(skb_dst(skb)->dev->features & NETIF_F_SCTP_CRC))) { |
| sctph->dest = cp->dport; |
| - sctp_nat_csum(skb, sctph, sctphoff); |
| + if (!skb_is_gso(skb) || !skb_is_gso_sctp(skb)) |
| + sctp_nat_csum(skb, sctph, sctphoff); |
| } else if (skb->ip_summed != CHECKSUM_PARTIAL) { |
| skb->ip_summed = CHECKSUM_UNNECESSARY; |
| } |
| -- |
| 2.43.0 |
| |