135 lines
4.8 KiB
Diff
135 lines
4.8 KiB
Diff
|
From 876a1202351264f6d3b105258f10bde693870bd4 Mon Sep 17 00:00:00 2001
|
||
|
From: Phil Sutter <psutter@redhat.com>
|
||
|
Date: Mon, 7 Dec 2020 18:27:16 +0100
|
||
|
Subject: [PATCH] proto: add sctp crc32 checksum fixup
|
||
|
|
||
|
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1895804
|
||
|
Upstream Status: nftables commit 09a3b2ba0c822
|
||
|
|
||
|
commit 09a3b2ba0c8228d1c6bf0f030cae97addb397351
|
||
|
Author: Florian Westphal <fw@strlen.de>
|
||
|
Date: Tue Oct 6 23:16:32 2020 +0200
|
||
|
|
||
|
proto: add sctp crc32 checksum fixup
|
||
|
|
||
|
Stateless SCTP header mangling doesn't work reliably.
|
||
|
This tells the kernel to update the checksum field using
|
||
|
the sctp crc32 algorithm.
|
||
|
|
||
|
Note that this needs additional kernel support to work.
|
||
|
|
||
|
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||
|
---
|
||
|
include/linux/netfilter/nf_tables.h | 2 ++
|
||
|
include/proto.h | 1 +
|
||
|
src/netlink_linearize.c | 2 +-
|
||
|
src/proto.c | 8 ++++++++
|
||
|
4 files changed, 12 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
|
||
|
index 9b54a86..1328b8e 100644
|
||
|
--- a/include/linux/netfilter/nf_tables.h
|
||
|
+++ b/include/linux/netfilter/nf_tables.h
|
||
|
@@ -707,10 +707,12 @@ enum nft_payload_bases {
|
||
|
*
|
||
|
* @NFT_PAYLOAD_CSUM_NONE: no checksumming
|
||
|
* @NFT_PAYLOAD_CSUM_INET: internet checksum (RFC 791)
|
||
|
+ * @NFT_PAYLOAD_CSUM_SCTP: CRC-32c, for use in SCTP header (RFC 3309)
|
||
|
*/
|
||
|
enum nft_payload_csum_types {
|
||
|
NFT_PAYLOAD_CSUM_NONE,
|
||
|
NFT_PAYLOAD_CSUM_INET,
|
||
|
+ NFT_PAYLOAD_CSUM_SCTP,
|
||
|
};
|
||
|
|
||
|
enum nft_payload_csum_flags {
|
||
|
diff --git a/include/proto.h b/include/proto.h
|
||
|
index fab48c1..436cbe3 100644
|
||
|
--- a/include/proto.h
|
||
|
+++ b/include/proto.h
|
||
|
@@ -78,6 +78,7 @@ struct proto_hdr_template {
|
||
|
struct proto_desc {
|
||
|
const char *name;
|
||
|
enum proto_bases base;
|
||
|
+ enum nft_payload_csum_types checksum_type;
|
||
|
unsigned int checksum_key;
|
||
|
unsigned int protocol_key;
|
||
|
unsigned int length;
|
||
|
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
|
||
|
index cb1b7fe..606d97a 100644
|
||
|
--- a/src/netlink_linearize.c
|
||
|
+++ b/src/netlink_linearize.c
|
||
|
@@ -937,7 +937,7 @@ static void netlink_gen_payload_stmt(struct netlink_linearize_ctx *ctx,
|
||
|
expr->len / BITS_PER_BYTE);
|
||
|
if (csum_off) {
|
||
|
nftnl_expr_set_u32(nle, NFTNL_EXPR_PAYLOAD_CSUM_TYPE,
|
||
|
- NFT_PAYLOAD_CSUM_INET);
|
||
|
+ desc->checksum_type);
|
||
|
nftnl_expr_set_u32(nle, NFTNL_EXPR_PAYLOAD_CSUM_OFFSET,
|
||
|
csum_off / BITS_PER_BYTE);
|
||
|
}
|
||
|
diff --git a/src/proto.c b/src/proto.c
|
||
|
index 40ce590..8360abf 100644
|
||
|
--- a/src/proto.c
|
||
|
+++ b/src/proto.c
|
||
|
@@ -345,6 +345,7 @@ const struct proto_desc proto_icmp = {
|
||
|
.name = "icmp",
|
||
|
.base = PROTO_BASE_TRANSPORT_HDR,
|
||
|
.checksum_key = ICMPHDR_CHECKSUM,
|
||
|
+ .checksum_type = NFT_PAYLOAD_CSUM_INET,
|
||
|
.templates = {
|
||
|
[ICMPHDR_TYPE] = ICMPHDR_TYPE("type", &icmp_type_type, type),
|
||
|
[ICMPHDR_CODE] = ICMPHDR_TYPE("code", &icmp_code_type, code),
|
||
|
@@ -397,6 +398,7 @@ const struct proto_desc proto_igmp = {
|
||
|
.name = "igmp",
|
||
|
.base = PROTO_BASE_TRANSPORT_HDR,
|
||
|
.checksum_key = IGMPHDR_CHECKSUM,
|
||
|
+ .checksum_type = NFT_PAYLOAD_CSUM_INET,
|
||
|
.templates = {
|
||
|
[IGMPHDR_TYPE] = IGMPHDR_TYPE("type", &igmp_type_type, igmp_type),
|
||
|
[IGMPHDR_MRT] = IGMPHDR_FIELD("mrt", igmp_code),
|
||
|
@@ -417,6 +419,7 @@ const struct proto_desc proto_udp = {
|
||
|
.name = "udp",
|
||
|
.base = PROTO_BASE_TRANSPORT_HDR,
|
||
|
.checksum_key = UDPHDR_CHECKSUM,
|
||
|
+ .checksum_type = NFT_PAYLOAD_CSUM_INET,
|
||
|
.templates = {
|
||
|
[UDPHDR_SPORT] = INET_SERVICE("sport", struct udphdr, source),
|
||
|
[UDPHDR_DPORT] = INET_SERVICE("dport", struct udphdr, dest),
|
||
|
@@ -474,6 +477,7 @@ const struct proto_desc proto_tcp = {
|
||
|
.name = "tcp",
|
||
|
.base = PROTO_BASE_TRANSPORT_HDR,
|
||
|
.checksum_key = TCPHDR_CHECKSUM,
|
||
|
+ .checksum_type = NFT_PAYLOAD_CSUM_INET,
|
||
|
.templates = {
|
||
|
[TCPHDR_SPORT] = INET_SERVICE("sport", struct tcphdr, source),
|
||
|
[TCPHDR_DPORT] = INET_SERVICE("dport", struct tcphdr, dest),
|
||
|
@@ -553,6 +557,8 @@ const struct proto_desc proto_dccp = {
|
||
|
const struct proto_desc proto_sctp = {
|
||
|
.name = "sctp",
|
||
|
.base = PROTO_BASE_TRANSPORT_HDR,
|
||
|
+ .checksum_key = SCTPHDR_CHECKSUM,
|
||
|
+ .checksum_type = NFT_PAYLOAD_CSUM_SCTP,
|
||
|
.templates = {
|
||
|
[SCTPHDR_SPORT] = INET_SERVICE("sport", struct sctphdr, source),
|
||
|
[SCTPHDR_DPORT] = INET_SERVICE("dport", struct sctphdr, dest),
|
||
|
@@ -650,6 +656,7 @@ const struct proto_desc proto_ip = {
|
||
|
.name = "ip",
|
||
|
.base = PROTO_BASE_NETWORK_HDR,
|
||
|
.checksum_key = IPHDR_CHECKSUM,
|
||
|
+ .checksum_type = NFT_PAYLOAD_CSUM_INET,
|
||
|
.protocols = {
|
||
|
PROTO_LINK(IPPROTO_ICMP, &proto_icmp),
|
||
|
PROTO_LINK(IPPROTO_IGMP, &proto_igmp),
|
||
|
@@ -746,6 +753,7 @@ const struct proto_desc proto_icmp6 = {
|
||
|
.name = "icmpv6",
|
||
|
.base = PROTO_BASE_TRANSPORT_HDR,
|
||
|
.checksum_key = ICMP6HDR_CHECKSUM,
|
||
|
+ .checksum_type = NFT_PAYLOAD_CSUM_INET,
|
||
|
.templates = {
|
||
|
[ICMP6HDR_TYPE] = ICMP6HDR_TYPE("type", &icmp6_type_type, icmp6_type),
|
||
|
[ICMP6HDR_CODE] = ICMP6HDR_TYPE("code", &icmpv6_code_type, icmp6_code),
|
||
|
--
|
||
|
1.8.3.1
|
||
|
|