Commit 26a77d02 authored by Antonio Ojea's avatar Antonio Ojea Committed by Pablo Neira Ayuso
Browse files

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: default avatarAntonio Ojea <aojea@google.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 1bf8e07c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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)
{
+10 −2
Original line number Diff line number Diff line
@@ -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,
@@ -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);