@@ -131,6 +131,8 @@
#define SO_BUF_LOCK 72
+#define SO_TXREHASH_MODE 73
+
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64
@@ -142,6 +142,8 @@
#define SO_BUF_LOCK 72
+#define SO_TXREHASH_MODE 73
+
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64
@@ -123,6 +123,8 @@
#define SO_BUF_LOCK 0x4046
+#define SO_TXREHASH_MODE 0x4047
+
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64
@@ -124,8 +124,9 @@
#define SO_BUF_LOCK 0x0051
-#if !defined(__KERNEL__)
+#define SO_TXREHASH_MODE 0x0052
+#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64
#define SO_TIMESTAMP SO_TIMESTAMP_OLD
@@ -313,6 +313,7 @@ struct bpf_local_storage;
* @sk_rcvtimeo: %SO_RCVTIMEO setting
* @sk_sndtimeo: %SO_SNDTIMEO setting
* @sk_txhash: computed flow hash for use on transmit
+ * @sk_txrehash_mode: configuration bits for controlling TX hash rethink
* @sk_filter: socket filtering instructions
* @sk_timer: sock cleanup timer
* @sk_stamp: time stamp of last packet received
@@ -462,6 +463,7 @@ struct sock {
unsigned int sk_gso_max_size;
gfp_t sk_allocation;
__u32 sk_txhash;
+ unsigned int sk_txrehash_mode;
/*
* Because of non atomicity rules, all
@@ -1953,7 +1955,11 @@ static inline bool sk_rethink_txhash(struct sock *sk, unsigned int level)
if (!sk->sk_txhash)
return false;
- rehash_mode = READ_ONCE(sock_net(sk)->core.sysctl_txrehash_mode);
+ if (sk->sk_txrehash_mode == SOCK_TXREHASH_MODE_DEFAULT)
+ rehash_mode =
+ READ_ONCE(sock_net(sk)->core.sysctl_txrehash_mode);
+ else
+ rehash_mode = sk->sk_txrehash_mode;
if (level & rehash_mode) {
sk_set_txhash(sk);
@@ -126,6 +126,8 @@
#define SO_BUF_LOCK 72
+#define SO_TXREHASH_MODE 73
+
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
@@ -1367,6 +1367,17 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
~SOCK_BUF_LOCK_MASK);
break;
+ case SO_TXREHASH_MODE:
+ if (val == SOCK_TXREHASH_MODE_DEFAULT ||
+ (val & ~SOCK_TXREHASH_MODE_MASK)) {
+ ret = -EINVAL;
+ break;
+ }
+
+ sk->sk_txrehash_mode = val;
+
+ break;
+
default:
ret = -ENOPROTOOPT;
break;
@@ -1733,6 +1744,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
v.val = sk->sk_userlocks & SOCK_BUF_LOCK_MASK;
break;
+ case SO_TXREHASH_MODE:
+ v.val = sk->sk_txrehash_mode;
+ break;
+
default:
/* We implement the SO_SNDLOWAT etc to not be settable
* (1003.1g 7).
@@ -3158,6 +3173,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
sk->sk_pacing_rate = ~0UL;
WRITE_ONCE(sk->sk_pacing_shift, 10);
sk->sk_incoming_cpu = -1;
+ sk->sk_txrehash_mode = SOCK_TXREHASH_MODE_DEFAULT;
sk_rx_queue_clear(sk);
/*