net/tcp: Separate tcp_md5sig_info allocation into tcp_md5sig_info_add()
authorDmitry Safonov <dima@arista.com>
Wed, 23 Nov 2022 17:38:56 +0000 (17:38 +0000)
committerJakub Kicinski <kuba@kernel.org>
Thu, 1 Dec 2022 23:53:05 +0000 (15:53 -0800)
Add a helper to allocate tcp_md5sig_info, that will help later to
do/allocate things when info allocated, once per socket.

Signed-off-by: Dmitry Safonov <dima@arista.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Acked-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/ipv4/tcp_ipv4.c

index 1215fa4c1b9f3abcda47eef152cdc1f2978b95ab..c72e53835397ebbf081b0ff48c18628d2f0ed80a 100644 (file)
@@ -1161,6 +1161,24 @@ struct tcp_md5sig_key *tcp_v4_md5_lookup(const struct sock *sk,
 }
 EXPORT_SYMBOL(tcp_v4_md5_lookup);
 
+static int tcp_md5sig_info_add(struct sock *sk, gfp_t gfp)
+{
+       struct tcp_sock *tp = tcp_sk(sk);
+       struct tcp_md5sig_info *md5sig;
+
+       if (rcu_dereference_protected(tp->md5sig_info, lockdep_sock_is_held(sk)))
+               return 0;
+
+       md5sig = kmalloc(sizeof(*md5sig), gfp);
+       if (!md5sig)
+               return -ENOMEM;
+
+       sk_gso_disable(sk);
+       INIT_HLIST_HEAD(&md5sig->head);
+       rcu_assign_pointer(tp->md5sig_info, md5sig);
+       return 0;
+}
+
 /* This can be called on a newly created socket, from other files */
 int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr,
                   int family, u8 prefixlen, int l3index, u8 flags,
@@ -1191,17 +1209,11 @@ int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr,
                return 0;
        }
 
+       if (tcp_md5sig_info_add(sk, gfp))
+               return -ENOMEM;
+
        md5sig = rcu_dereference_protected(tp->md5sig_info,
                                           lockdep_sock_is_held(sk));
-       if (!md5sig) {
-               md5sig = kmalloc(sizeof(*md5sig), gfp);
-               if (!md5sig)
-                       return -ENOMEM;
-
-               sk_gso_disable(sk);
-               INIT_HLIST_HEAD(&md5sig->head);
-               rcu_assign_pointer(tp->md5sig_info, md5sig);
-       }
 
        key = sock_kmalloc(sk, sizeof(*key), gfp | __GFP_ZERO);
        if (!key)