summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2020-10-06 23:16:32 +0200
committerFlorian Westphal <fw@strlen.de>2020-10-15 15:22:05 +0200
commit09a3b2ba0c8228d1c6bf0f030cae97addb397351 (patch)
tree4001441996dd06c5b820fabcc31f7ecaa9ba2443
parentb4775dec9f80b74c522edec8ebb4af5092e0e82b (diff)
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>
-rw-r--r--include/linux/netfilter/nf_tables.h2
-rw-r--r--include/proto.h1
-rw-r--r--src/netlink_linearize.c2
-rw-r--r--src/proto.c8
4 files changed, 12 insertions, 1 deletions
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 10be073a..0b5fd5d5 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -733,10 +733,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 304b048e..b78bb9bc 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -103,6 +103,7 @@ struct proto_desc {
const char *name;
enum proto_desc_id id;
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 846df46b..e5f601d4 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -974,7 +974,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 7de2bbf9..725b0385 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -406,6 +406,7 @@ const struct proto_desc proto_icmp = {
.id = PROTO_DESC_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),
@@ -459,6 +460,7 @@ const struct proto_desc proto_igmp = {
.id = PROTO_DESC_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),
@@ -480,6 +482,7 @@ const struct proto_desc proto_udp = {
.id = PROTO_DESC_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),
@@ -539,6 +542,7 @@ const struct proto_desc proto_tcp = {
.id = PROTO_DESC_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),
@@ -620,6 +624,8 @@ const struct proto_desc proto_sctp = {
.name = "sctp",
.id = PROTO_DESC_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),
@@ -719,6 +725,7 @@ const struct proto_desc proto_ip = {
.id = PROTO_DESC_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),
@@ -816,6 +823,7 @@ const struct proto_desc proto_icmp6 = {
.id = PROTO_DESC_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),