]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
proto: add sctp crc32 checksum fixup
authorFlorian Westphal <fw@strlen.de>
Tue, 6 Oct 2020 21:16:32 +0000 (23:16 +0200)
committerFlorian Westphal <fw@strlen.de>
Thu, 15 Oct 2020 13:22:05 +0000 (15:22 +0200)
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
include/proto.h
src/netlink_linearize.c
src/proto.c

index 10be073aeb8dd63942192ea7f1ac9536dbbaad79..0b5fd5d52bb6e26318774aaf84a475328d1abfb1 100644 (file)
@@ -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 {
index 304b048e4e6007d1eb97ebbfddea14162cd4c413..b78bb9bc2a7121659590d312c8f53a2ba39754a4 100644 (file)
@@ -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;
index 846df46b75fd31184ac727fd21804bbbbd9014bd..e5f601d4bc946ba78a7c1d501d5ca7203cf992a8 100644 (file)
@@ -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);
        }
index 7de2bbf91ae4abc09197d6d0928ee4ea6acedb09..725b03851e980005fb9889e1807025c207a332b0 100644 (file)
@@ -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),