net/tcp: Add option for TCP-AO to (not) hash header
authorDmitry Safonov <dima@arista.com>
Mon, 23 Oct 2023 19:22:09 +0000 (20:22 +0100)
committerDavid S. Miller <davem@davemloft.net>
Fri, 27 Oct 2023 09:35:45 +0000 (10:35 +0100)
Provide setsockopt() key flag that makes TCP-AO exclude hashing TCP
header for peers that match the key. This is needed for interraction
with middleboxes that may change TCP options, see RFC5925 (9.2).

Co-developed-by: Francesco Ruggeri <fruggeri@arista.com>
Signed-off-by: Francesco Ruggeri <fruggeri@arista.com>
Co-developed-by: Salam Noureddine <noureddine@arista.com>
Signed-off-by: Salam Noureddine <noureddine@arista.com>
Signed-off-by: Dmitry Safonov <dima@arista.com>
Acked-by: David Ahern <dsahern@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/uapi/linux/tcp.h
net/ipv4/tcp_ao.c

index d8b2ea23f12a14266bd134c8c53c9f0ea4a843bf..320aab010f9ab105a97df0ca8d65eb137390d23b 100644 (file)
@@ -367,6 +367,11 @@ struct tcp_diag_md5sig {
 #define TCP_AO_MAXKEYLEN       80
 
 #define TCP_AO_KEYF_IFINDEX    (1 << 0)        /* L3 ifindex for VRF */
+#define TCP_AO_KEYF_EXCLUDE_OPT        (1 << 1)        /* "Indicates whether TCP
+                                                *  options other than TCP-AO
+                                                *  are included in the MAC
+                                                *  calculation"
+                                                */
 
 struct tcp_ao_add { /* setsockopt(TCP_AO_ADD_KEY) */
        struct __kernel_sockaddr_storage addr;  /* peer's address for the key */
index 223af5c9eaf359a8a0e40f786fc1e570376b7bef..10cc6be4d537352e25cde56d3c7d711f90f5d7aa 100644 (file)
@@ -562,7 +562,8 @@ int tcp_ao_hash_hdr(unsigned short int family, char *ao_hash,
                WARN_ON_ONCE(1);
                goto clear_hash;
        }
-       if (tcp_ao_hash_header(&hp, th, false,
+       if (tcp_ao_hash_header(&hp, th,
+                              !!(key->keyflags & TCP_AO_KEYF_EXCLUDE_OPT),
                               ao_hash, hash_offset, tcp_ao_maclen(key)))
                goto clear_hash;
        ahash_request_set_crypt(hp.req, NULL, hash_buf, 0);
@@ -610,7 +611,8 @@ int tcp_ao_hash_skb(unsigned short int family,
                goto clear_hash;
        if (tcp_ao_hash_pseudoheader(family, sk, skb, &hp, skb->len))
                goto clear_hash;
-       if (tcp_ao_hash_header(&hp, th, false,
+       if (tcp_ao_hash_header(&hp, th,
+                              !!(key->keyflags & TCP_AO_KEYF_EXCLUDE_OPT),
                               ao_hash, hash_offset, tcp_ao_maclen(key)))
                goto clear_hash;
        if (tcp_sigpool_hash_skb_data(&hp, skb, th->doff << 2))
@@ -1454,7 +1456,7 @@ static struct tcp_ao_info *setsockopt_ao_info(struct sock *sk)
        return ERR_PTR(-ESOCKTNOSUPPORT);
 }
 
-#define TCP_AO_KEYF_ALL                (0)
+#define TCP_AO_KEYF_ALL                (TCP_AO_KEYF_EXCLUDE_OPT)
 
 static struct tcp_ao_key *tcp_ao_key_alloc(struct sock *sk,
                                           struct tcp_ao_add *cmd)