|
@@ -36,6 +36,7 @@
|
|
|
#include <net/inet_hashtables.h>
|
|
|
#include <net/checksum.h>
|
|
|
#include <net/request_sock.h>
|
|
|
+#include <net/sock_reuseport.h>
|
|
|
#include <net/sock.h>
|
|
|
#include <net/snmp.h>
|
|
|
#include <net/ip.h>
|
|
@@ -473,9 +474,22 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb);
|
|
|
*/
|
|
|
static inline void tcp_synq_overflow(const struct sock *sk)
|
|
|
{
|
|
|
- unsigned int last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp;
|
|
|
+ unsigned int last_overflow;
|
|
|
unsigned int now = jiffies;
|
|
|
|
|
|
+ if (sk->sk_reuseport) {
|
|
|
+ struct sock_reuseport *reuse;
|
|
|
+
|
|
|
+ reuse = rcu_dereference(sk->sk_reuseport_cb);
|
|
|
+ if (likely(reuse)) {
|
|
|
+ last_overflow = READ_ONCE(reuse->synq_overflow_ts);
|
|
|
+ if (time_after32(now, last_overflow + HZ))
|
|
|
+ WRITE_ONCE(reuse->synq_overflow_ts, now);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp;
|
|
|
if (time_after32(now, last_overflow + HZ))
|
|
|
tcp_sk(sk)->rx_opt.ts_recent_stamp = now;
|
|
|
}
|
|
@@ -483,9 +497,21 @@ static inline void tcp_synq_overflow(const struct sock *sk)
|
|
|
/* syncookies: no recent synqueue overflow on this listening socket? */
|
|
|
static inline bool tcp_synq_no_recent_overflow(const struct sock *sk)
|
|
|
{
|
|
|
- unsigned int last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp;
|
|
|
+ unsigned int last_overflow;
|
|
|
unsigned int now = jiffies;
|
|
|
|
|
|
+ if (sk->sk_reuseport) {
|
|
|
+ struct sock_reuseport *reuse;
|
|
|
+
|
|
|
+ reuse = rcu_dereference(sk->sk_reuseport_cb);
|
|
|
+ if (likely(reuse)) {
|
|
|
+ last_overflow = READ_ONCE(reuse->synq_overflow_ts);
|
|
|
+ return time_after32(now, last_overflow +
|
|
|
+ TCP_SYNCOOKIE_VALID);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp;
|
|
|
return time_after32(now, last_overflow + TCP_SYNCOOKIE_VALID);
|
|
|
}
|
|
|
|