From: Geliang Tang <redacted>
Currently, nvmet-tcp only applies the received IPv4 TOS value when setting
up a queue socket, but does not handle the IPv6 traffic class.
Extend the queue socket setup to handle AF_INET6 sockets. Obtain the
traffic class from the IPv6 socket's rcv_flowinfo and apply it through
IPV6_TCLASS using do_sock_setsockopt().
Signed-off-by: Geliang Tang <redacted>
---
drivers/nvme/target/tcp.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
index 38b0c446ae89..ed413aa5601c 100644
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -1737,6 +1737,22 @@ static int nvmet_tcp_sock_set_tos(struct sock *sk)
return 0;
}
+static int nvmet_tcp_sock_set_tclass(struct sock *sk)
+{
+#if IS_ENABLED(CONFIG_IPV6)
+ if (sk->sk_family == AF_INET6) {
+ int tclass = ip6_tclass(inet6_sk(sk)->rcv_flowinfo);
+
+ if (tclass > 0)
+ return do_sock_setsockopt(sk->sk_socket, false,
+ SOL_IPV6, IPV6_TCLASS,
+ KERNEL_SOCKPTR(&tclass),
+ sizeof(tclass));
+ }
+#endif
+ return 0;
+}
+
static int nvmet_tcp_set_queue_sock(struct nvmet_tcp_queue *queue)
{
struct socket *sock = queue->sock;@@ -1772,6 +1788,10 @@ static int nvmet_tcp_set_queue_sock(struct nvmet_tcp_queue *queue)
if (ret)
return ret;
+ ret = nvmet_tcp_sock_set_tclass(sock->sk);
+ if (ret)
+ return ret;
+
ret = 0;
write_lock_bh(&sock->sk->sk_callback_lock);
if (sock->sk->sk_state != TCP_ESTABLISHED) {--
2.53.0