aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntonio Ojea <aojea@google.com>2024-06-27 13:27:10 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2024-08-19 18:44:50 +0200
commit26a77d02891ab62172085a4f94af9b3c90aed387 (patch)
tree71cfce9c45789c72eb15af4238c5639cb2394d42
parentdt-binding: ptp: fsl,ptp: add pci1957,ee02 compatible string for fsl,enetc-ptp (diff)
downloadlinux-26a77d02891ab62172085a4f94af9b3c90aed387.tar.gz
linux-26a77d02891ab62172085a4f94af9b3c90aed387.zip
netfilter: nfnetlink_queue: unbreak SCTP traffic
when packet is enqueued with nfqueue and GSO is enabled, checksum calculation has to take into account the protocol, as SCTP uses a 32 bits CRC checksum. Enter skb_gso_segment() path in case of SCTP GSO packets because skb_zerocopy() does not support for GSO_BY_FRAGS. Joint work with Pablo. Signed-off-by: Antonio Ojea <aojea@google.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--net/core/dev.c1
-rw-r--r--net/netfilter/nfnetlink_queue.c12
2 files changed, 11 insertions, 2 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index e7260889d4cb..8384282acadf 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3386,6 +3386,7 @@ int skb_crc32c_csum_help(struct sk_buff *skb)
out:
return ret;
}
+EXPORT_SYMBOL(skb_crc32c_csum_help);
__be16 skb_network_protocol(struct sk_buff *skb, int *depth)
{
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index e0716da256bf..d2773ce9b585 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -540,6 +540,14 @@ nla_put_failure:
return -1;
}
+static int nf_queue_checksum_help(struct sk_buff *entskb)
+{
+ if (skb_csum_is_sctp(entskb))
+ return skb_crc32c_csum_help(entskb);
+
+ return skb_checksum_help(entskb);
+}
+
static struct sk_buff *
nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
struct nf_queue_entry *entry,
@@ -602,7 +610,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
case NFQNL_COPY_PACKET:
if (!(queue->flags & NFQA_CFG_F_GSO) &&
entskb->ip_summed == CHECKSUM_PARTIAL &&
- skb_checksum_help(entskb))
+ nf_queue_checksum_help(entskb))
return NULL;
data_len = READ_ONCE(queue->copy_range);
@@ -1014,7 +1022,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
break;
}
- if ((queue->flags & NFQA_CFG_F_GSO) || !skb_is_gso(skb))
+ if (!skb_is_gso(skb) || ((queue->flags & NFQA_CFG_F_GSO) && !skb_is_gso_sctp(skb)))
return __nfqnl_enqueue_packet(net, queue, entry);
nf_bridge_adjust_skb_data(skb);