summaryrefslogtreecommitdiffstats
path: root/include/net
diff options
context:
space:
mode:
authorDmitry Safonov <dima@arista.com>2023-10-23 21:22:06 +0200
committerDavid S. Miller <davem@davemloft.net>2023-10-27 11:35:45 +0200
commit64382c71a5575741933dfdb0cf7162c6e9b8854e (patch)
tree9e21fcb808c8285192549c0cc747e659e5c3e762 /include/net
parentnet/tcp: Add TCP-AO segments counters (diff)
downloadlinux-64382c71a5575741933dfdb0cf7162c6e9b8854e.tar.xz
linux-64382c71a5575741933dfdb0cf7162c6e9b8854e.zip
net/tcp: Add TCP-AO SNE support
Add Sequence Number Extension (SNE) for TCP-AO. This is needed to protect long-living TCP-AO connections from replaying attacks after sequence number roll-over, see RFC5925 (6.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>
Diffstat (limited to 'include/net')
-rw-r--r--include/net/tcp_ao.h22
1 files changed, 21 insertions, 1 deletions
diff --git a/include/net/tcp_ao.h b/include/net/tcp_ao.h
index cfb55bd9411b..0c3516d1b968 100644
--- a/include/net/tcp_ao.h
+++ b/include/net/tcp_ao.h
@@ -95,6 +95,25 @@ struct tcp_ao_info {
__unused :31;
__be32 lisn;
__be32 risn;
+ /* Sequence Number Extension (SNE) are upper 4 bytes for SEQ,
+ * that protect TCP-AO connection from replayed old TCP segments.
+ * See RFC5925 (6.2).
+ * In order to get correct SNE, there's a helper tcp_ao_compute_sne().
+ * It needs SEQ basis to understand whereabouts are lower SEQ numbers.
+ * According to that basis vector, it can provide incremented SNE
+ * when SEQ rolls over or provide decremented SNE when there's
+ * a retransmitted segment from before-rolling over.
+ * - for request sockets such basis is rcv_isn/snt_isn, which seems
+ * good enough as it's unexpected to receive 4 Gbytes on reqsk.
+ * - for full sockets the basis is rcv_nxt/snd_una. snd_una is
+ * taken instead of snd_nxt as currently it's easier to track
+ * in tcp_snd_una_update(), rather than updating SNE in all
+ * WRITE_ONCE(tp->snd_nxt, ...)
+ * - for time-wait sockets the basis is tw_rcv_nxt/tw_snd_nxt.
+ * tw_snd_nxt is not expected to change, while tw_rcv_nxt may.
+ */
+ u32 snd_sne;
+ u32 rcv_sne;
refcount_t refcnt; /* Protects twsk destruction */
struct rcu_head rcu;
};
@@ -147,6 +166,7 @@ enum skb_drop_reason tcp_inbound_ao_hash(struct sock *sk,
const struct sk_buff *skb, unsigned short int family,
const struct request_sock *req,
const struct tcp_ao_hdr *aoh);
+u32 tcp_ao_compute_sne(u32 next_sne, u32 next_seq, u32 seq);
struct tcp_ao_key *tcp_ao_do_lookup(const struct sock *sk,
const union tcp_ao_addr *addr,
int family, int sndid, int rcvid);
@@ -156,7 +176,7 @@ int tcp_ao_hash_hdr(unsigned short family, char *ao_hash,
const union tcp_ao_addr *saddr,
const struct tcphdr *th, u32 sne);
int tcp_ao_prepare_reset(const struct sock *sk, struct sk_buff *skb,
- const struct tcp_ao_hdr *aoh, int l3index,
+ const struct tcp_ao_hdr *aoh, int l3index, u32 seq,
struct tcp_ao_key **key, char **traffic_key,
bool *allocated_traffic_key, u8 *keyid, u32 *sne);