]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ipvs: show the current conn_tab size to users
authorJulian Anastasov <ja@ssi.bg>
Sat, 4 Apr 2026 15:34:37 +0000 (18:34 +0300)
committerFlorian Westphal <fw@strlen.de>
Fri, 10 Apr 2026 10:16:25 +0000 (12:16 +0200)
As conn_tab is per-net, better to show the current hash table size
to users instead of the ip_vs_conn_tab_size (max).

Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Florian Westphal <fw@strlen.de>
net/netfilter/ipvs/ip_vs_ctl.c

index a1f070cb76c328d745fd5ef94d4433c4094ddac5..1322dd54ed7c2255dab4b487a7a906008ccef1e5 100644 (file)
@@ -281,6 +281,20 @@ unlock:
        mutex_unlock(&ipvs->est_mutex);
 }
 
+static int get_conn_tab_size(struct netns_ipvs *ipvs)
+{
+       const struct ip_vs_rht *t;
+       int size = 0;
+
+       rcu_read_lock();
+       t = rcu_dereference(ipvs->conn_tab);
+       if (t)
+               size = t->size;
+       rcu_read_unlock();
+
+       return size;
+}
+
 int
 ip_vs_use_count_inc(void)
 {
@@ -2741,10 +2755,13 @@ static void ip_vs_info_seq_stop(struct seq_file *seq, void *v)
 
 static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
 {
+       struct net *net = seq_file_net(seq);
+       struct netns_ipvs *ipvs = net_ipvs(net);
+
        if (v == SEQ_START_TOKEN) {
                seq_printf(seq,
                        "IP Virtual Server version %d.%d.%d (size=%d)\n",
-                       NVERSION(IP_VS_VERSION_CODE), ip_vs_conn_tab_size);
+                       NVERSION(IP_VS_VERSION_CODE), get_conn_tab_size(ipvs));
                seq_puts(seq,
                         "Prot LocalAddress:Port Scheduler Flags\n");
                seq_puts(seq,
@@ -3425,7 +3442,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
                char buf[64];
 
                sprintf(buf, "IP Virtual Server version %d.%d.%d (size=%d)",
-                       NVERSION(IP_VS_VERSION_CODE), ip_vs_conn_tab_size);
+                       NVERSION(IP_VS_VERSION_CODE), get_conn_tab_size(ipvs));
                if (copy_to_user(user, buf, strlen(buf)+1) != 0) {
                        ret = -EFAULT;
                        goto out;
@@ -3437,8 +3454,9 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
        case IP_VS_SO_GET_INFO:
        {
                struct ip_vs_getinfo info;
+
                info.version = IP_VS_VERSION_CODE;
-               info.size = ip_vs_conn_tab_size;
+               info.size = get_conn_tab_size(ipvs);
                info.num_services =
                        atomic_read(&ipvs->num_services[IP_VS_AF_INET]);
                if (copy_to_user(user, &info, sizeof(info)) != 0)
@@ -4447,7 +4465,7 @@ static int ip_vs_genl_get_cmd(struct sk_buff *skb, struct genl_info *info)
                if (nla_put_u32(msg, IPVS_INFO_ATTR_VERSION,
                                IP_VS_VERSION_CODE) ||
                    nla_put_u32(msg, IPVS_INFO_ATTR_CONN_TAB_SIZE,
-                               ip_vs_conn_tab_size))
+                               get_conn_tab_size(ipvs)))
                        goto nla_put_failure;
                break;
        }