]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ipv4: add ip_sock_set_tos
authorChristoph Hellwig <hch@lst.de>
Thu, 28 May 2020 05:12:26 +0000 (07:12 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 28 May 2020 18:11:45 +0000 (11:11 -0700)
Add a helper to directly set the IP_TOS sockopt from kernel space without
going through a fake uaccess.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/nvme/host/tcp.c
drivers/nvme/target/tcp.c
include/net/ip.h
net/ipv4/ip_sockglue.c

index 2872584f52f6375726f2a077069e292f666449db..4c972d8abf317295365d66c9bce7d07dcfd686ee 100644 (file)
@@ -1313,7 +1313,7 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl,
 {
        struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl);
        struct nvme_tcp_queue *queue = &ctrl->queues[qid];
-       int ret, opt, rcv_pdu_size;
+       int ret, rcv_pdu_size;
 
        queue->ctrl = ctrl;
        INIT_LIST_HEAD(&queue->send_list);
@@ -1352,16 +1352,8 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl,
                sock_set_priority(queue->sock->sk, so_priority);
 
        /* Set socket type of service */
-       if (nctrl->opts->tos >= 0) {
-               opt = nctrl->opts->tos;
-               ret = kernel_setsockopt(queue->sock, SOL_IP, IP_TOS,
-                               (char *)&opt, sizeof(opt));
-               if (ret) {
-                       dev_err(nctrl->device,
-                               "failed to set IP_TOS sock opt %d\n", ret);
-                       goto err_sock;
-               }
-       }
+       if (nctrl->opts->tos >= 0)
+               ip_sock_set_tos(queue->sock->sk, nctrl->opts->tos);
 
        queue->sock->sk->sk_allocation = GFP_ATOMIC;
        nvme_tcp_set_queue_io_cpu(queue);
index 55bc4c3c0a74a9d1337f098cae1094f51f51170c..4546049a96b379a7bbab39547819800976d7045a 100644 (file)
@@ -1452,14 +1452,8 @@ static int nvmet_tcp_set_queue_sock(struct nvmet_tcp_queue *queue)
                sock_set_priority(sock->sk, so_priority);
 
        /* Set socket type of service */
-       if (inet->rcv_tos > 0) {
-               int tos = inet->rcv_tos;
-
-               ret = kernel_setsockopt(sock, SOL_IP, IP_TOS,
-                               (char *)&tos, sizeof(tos));
-               if (ret)
-                       return ret;
-       }
+       if (inet->rcv_tos > 0)
+               ip_sock_set_tos(sock->sk, inet->rcv_tos);
 
        write_lock_bh(&sock->sk->sk_callback_lock);
        sock->sk->sk_user_data = queue;
index 5b317c9f4470a93abae9cbe8e7dfd3e919aa8851..2fc52e26fa88bbf5dfc5eab57a38788f6bcab0aa 100644 (file)
@@ -765,4 +765,6 @@ static inline bool inetdev_valid_mtu(unsigned int mtu)
        return likely(mtu >= IPV4_MIN_MTU);
 }
 
+void ip_sock_set_tos(struct sock *sk, int val);
+
 #endif /* _IP_H */
index f43d5f12aa86afce60707fd24a1209ec9846b560..b43a29e11f4a50f8d11602541b3ae7a37f01fb06 100644 (file)
@@ -560,6 +560,26 @@ out:
        return err;
 }
 
+static void __ip_sock_set_tos(struct sock *sk, int val)
+{
+       if (sk->sk_type == SOCK_STREAM) {
+               val &= ~INET_ECN_MASK;
+               val |= inet_sk(sk)->tos & INET_ECN_MASK;
+       }
+       if (inet_sk(sk)->tos != val) {
+               inet_sk(sk)->tos = val;
+               sk->sk_priority = rt_tos2priority(val);
+               sk_dst_reset(sk);
+       }
+}
+
+void ip_sock_set_tos(struct sock *sk, int val)
+{
+       lock_sock(sk);
+       __ip_sock_set_tos(sk, val);
+       release_sock(sk);
+}
+EXPORT_SYMBOL(ip_sock_set_tos);
 
 /*
  *     Socket option code for IP. This is the end of the line after any
@@ -823,15 +843,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                        inet->cmsg_flags &= ~IP_CMSG_RECVFRAGSIZE;
                break;
        case IP_TOS:    /* This sets both TOS and Precedence */
-               if (sk->sk_type == SOCK_STREAM) {
-                       val &= ~INET_ECN_MASK;
-                       val |= inet->tos & INET_ECN_MASK;
-               }
-               if (inet->tos != val) {
-                       inet->tos = val;
-                       sk->sk_priority = rt_tos2priority(val);
-                       sk_dst_reset(sk);
-               }
+               __ip_sock_set_tos(sk, val);
                break;
        case IP_TTL:
                if (optlen < 1)