[v6,14/21] net/tcp: Add TCP-AO SNE support
Commit Message
Add Sequence Number Extension (SNE) extension 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>
---
net/ipv4/tcp_input.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
@@ -3528,9 +3528,21 @@ static inline bool tcp_may_update_window(const struct tcp_sock *tp,
static void tcp_snd_una_update(struct tcp_sock *tp, u32 ack)
{
u32 delta = ack - tp->snd_una;
+#ifdef CONFIG_TCP_AO
+ struct tcp_ao_info *ao;
+#endif
sock_owned_by_me((struct sock *)tp);
tp->bytes_acked += delta;
+#ifdef CONFIG_TCP_AO
+ ao = rcu_dereference_protected(tp->ao_info,
+ lockdep_sock_is_held((struct sock *)tp));
+ if (ao) {
+ if (ack < ao->snd_sne_seq)
+ ao->snd_sne++;
+ ao->snd_sne_seq = ack;
+ }
+#endif
tp->snd_una = ack;
}
@@ -3538,9 +3550,21 @@ static void tcp_snd_una_update(struct tcp_sock *tp, u32 ack)
static void tcp_rcv_nxt_update(struct tcp_sock *tp, u32 seq)
{
u32 delta = seq - tp->rcv_nxt;
+#ifdef CONFIG_TCP_AO
+ struct tcp_ao_info *ao;
+#endif
sock_owned_by_me((struct sock *)tp);
tp->bytes_received += delta;
+#ifdef CONFIG_TCP_AO
+ ao = rcu_dereference_protected(tp->ao_info,
+ lockdep_sock_is_held((struct sock *)tp));
+ if (ao) {
+ if (seq < ao->rcv_sne_seq)
+ ao->rcv_sne++;
+ ao->rcv_sne_seq = seq;
+ }
+#endif
WRITE_ONCE(tp->rcv_nxt, seq);
}
@@ -6371,6 +6395,17 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
* simultaneous connect with crossed SYNs.
* Particularly, it can be connect to self.
*/
+#ifdef CONFIG_TCP_AO
+ struct tcp_ao_info *ao;
+
+ ao = rcu_dereference_protected(tp->ao_info,
+ lockdep_sock_is_held(sk));
+ if (ao) {
+ ao->risn = th->seq;
+ ao->rcv_sne = 0;
+ ao->rcv_sne_seq = ntohl(th->seq);
+ }
+#endif
tcp_set_state(sk, TCP_SYN_RECV);
if (tp->rx_opt.saw_tstamp) {