Skip to content

Commit

Permalink
netfilter: nfnetlink_queue: unbreak SCTP traffic
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Antonio Ojea authored and Pablo Neira Ayuso committed Aug 19, 2024
1 parent 1bf8e07 commit 26a77d0
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 2 deletions.
1 change: 1 addition & 0 deletions net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
12 changes: 10 additions & 2 deletions net/netfilter/nfnetlink_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,14 @@ static int nfqnl_put_bridge(struct nf_queue_entry *entry, struct sk_buff *skb)
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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 26a77d0

Please sign in to comment.