]> git.hungrycats.org Git - linux/commitdiff
[NET]: Generic network statistics
authorHarald Welte <laforge@gnumonks.org>
Tue, 28 Sep 2004 07:22:31 +0000 (00:22 -0700)
committerDavid S. Miller <davem@nuts.davemloft.net>
Tue, 28 Sep 2004 07:22:31 +0000 (00:22 -0700)
This patch moves the following files in /proc:
/proc/net/rt_cache_stat  /proc/net/stat/rt_cache
/proc/net/ip_conntrack_stat /proc/net/stat/ip_conntrack
/proc/net/arp_cache_stat /proc/net/stat/arp_cache
/proc/net/clip_arp_cache_stat /proc/net/stat/clip_arp_cache
/proc/net/dn_neigh_cache_stat /proc/net/stat/dn_neigh_cache

This allows a generic statistics tool to scan for all available statistics
by doing readdir(2) on /proc/net/stat

It also adds a special first 'template' line to rt_cache and ip_conntrack
in order to facilitate compatibility once somebody adds new fields to the
output lines.

WARNING:
This breaks existing rtstat.c and ctstat.c userspace programs
(hopefully for the last time).  rtstat is non-existant or broken in
major distributions anyway, and ctstat is too new for any distros
having it picked up.  Therefore, we justify this breakage.

A new unified statistics tool for routing cache, connection tracking and
neighbour cache is under development and will be included with iproute2.

Signed-off-by: Harald Welte <laforge@gnumonks.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
fs/proc/root.c
include/linux/proc_fs.h
net/core/neighbour.c
net/ipv4/netfilter/ip_conntrack_standalone.c
net/ipv4/route.c

index 4ece27d0251489e2371d087e03573a8de82cc891..6151f0592f28520e7e0104bc6fd47359ebaef247 100644 (file)
@@ -18,7 +18,7 @@
 #include <asm/bitops.h>
 #include <linux/smp_lock.h>
 
-struct proc_dir_entry *proc_net, *proc_bus, *proc_root_fs, *proc_root_driver;
+struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver;
 
 #ifdef CONFIG_SYSCTL
 struct proc_dir_entry *proc_sys_root;
@@ -53,6 +53,8 @@ void __init proc_root_init(void)
        }
        proc_misc_init();
        proc_net = proc_mkdir("net", NULL);
+       proc_net_stat = proc_mkdir("net/stat", NULL);
+
 #ifdef CONFIG_SYSVIPC
        proc_mkdir("sysvipc", NULL);
 #endif
@@ -157,5 +159,6 @@ EXPORT_SYMBOL(remove_proc_entry);
 EXPORT_SYMBOL(proc_root);
 EXPORT_SYMBOL(proc_root_fs);
 EXPORT_SYMBOL(proc_net);
+EXPORT_SYMBOL(proc_net_stat);
 EXPORT_SYMBOL(proc_bus);
 EXPORT_SYMBOL(proc_root_driver);
index abcfc4bca26816938b4f0fca06edde3ff471bee9..c83dd15b728caaeef29131bacd69b465074a114a 100644 (file)
@@ -79,6 +79,7 @@ struct kcore_list {
 extern struct proc_dir_entry proc_root;
 extern struct proc_dir_entry *proc_root_fs;
 extern struct proc_dir_entry *proc_net;
+extern struct proc_dir_entry *proc_net_stat;
 extern struct proc_dir_entry *proc_bus;
 extern struct proc_dir_entry *proc_root_driver;
 extern struct proc_dir_entry *proc_root_kcore;
index 5f4fca15aa94afb76fdf51e09d852c46468035ee..a5509ef5570ed46a48857cc1e3aca2ba81e74d9a 100644 (file)
@@ -1334,22 +1334,11 @@ void neigh_table_init(struct neigh_table *tbl)
                panic("cannot create neighbour cache statistics");
        
 #ifdef CONFIG_PROC_FS
-#define NC_STAT_SUFFIX "_stat"
-       {
-       char *proc_stat_name;
-       proc_stat_name = kmalloc(strlen(tbl->id) + 
-                                strlen(NC_STAT_SUFFIX) + 1, GFP_KERNEL);
-       if (!proc_stat_name)
-               panic("cannot allocate neighbour cache proc name buffer");
-       strcpy(proc_stat_name, tbl->id);
-       strcat(proc_stat_name, NC_STAT_SUFFIX);
-
-       tbl->pde = create_proc_entry(proc_stat_name, 0, proc_net);
+       tbl->pde = create_proc_entry(tbl->id, 0, proc_net_stat);
        if (!tbl->pde) 
                panic("cannot create neighbour proc dir entry");
        tbl->pde->proc_fops = &neigh_stat_seq_fops;
        tbl->pde->data = tbl;
-       }
 #endif
 
        tbl->hash_mask = 1;
index dbd569b58dcdcaf06e5ada36c29940752c6c7ed9..9abaf01a72cca85776649035afc0bce854efcff4 100644 (file)
@@ -268,10 +268,13 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
 {
        int cpu;
 
-       for (cpu = *pos; cpu < NR_CPUS; ++cpu) {
+       if (*pos == 0)
+               return SEQ_START_TOKEN;
+
+       for (cpu = *pos-1; cpu < NR_CPUS; ++cpu) {
                if (!cpu_possible(cpu))
                        continue;
-               *pos = cpu;
+               *pos = cpu+1;
                return &per_cpu(ip_conntrack_stat, cpu);
        }
 
@@ -282,10 +285,10 @@ static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
        int cpu;
 
-       for (cpu = *pos + 1; cpu < NR_CPUS; ++cpu) {
+       for (cpu = *pos; cpu < NR_CPUS; ++cpu) {
                if (!cpu_possible(cpu))
                        continue;
-               *pos = cpu;
+               *pos = cpu+1;
                return &per_cpu(ip_conntrack_stat, cpu);
        }
 
@@ -301,6 +304,11 @@ static int ct_cpu_seq_show(struct seq_file *seq, void *v)
        unsigned int nr_conntracks = atomic_read(&ip_conntrack_count);
        struct ip_conntrack_stat *st = v;
 
+       if (v == SEQ_START_TOKEN) {
+               seq_printf(seq, "entries  searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error  expect_new expect_create expect_delete\n");
+               return 0;
+       }
+
        seq_printf(seq, "%08x  %08x %08x %08x %08x %08x %08x %08x "
                        "%08x %08x %08x %08x %08x  %08x %08x %08x \n",
                   nr_conntracks,
@@ -735,10 +743,11 @@ static int init_or_cleanup(int init)
                                        &exp_file_ops);
        if (!proc_exp) goto cleanup_proc;
 
-       proc_stat = proc_net_fops_create("ip_conntrack_stat", S_IRUGO,
-                                        &ct_cpu_seq_fops);
+       proc_stat = create_proc_entry("ip_conntrack", S_IRUGO, proc_net_stat);
        if (!proc_stat)
                goto cleanup_proc_exp;
+
+       proc_stat->proc_fops = &ct_cpu_seq_fops;
        proc_stat->owner = THIS_MODULE;
 #endif
 
index 73b19d735c90383eb36d49ee8beb3b9647db0c93..455cc0e775496fe62a6c52abfd5e1eb0ba3c37e2 100644 (file)
@@ -356,10 +356,13 @@ static void *rt_cpu_seq_start(struct seq_file *seq, loff_t *pos)
 {
        int cpu;
 
-       for (cpu = *pos; cpu < NR_CPUS; ++cpu) {
+       if (*pos == 0)
+               return SEQ_START_TOKEN;
+
+       for (cpu = *pos-1; cpu < NR_CPUS; ++cpu) {
                if (!cpu_possible(cpu))
                        continue;
-               *pos = cpu;
+               *pos = cpu+1;
                return per_cpu_ptr(rt_cache_stat, cpu);
        }
        return NULL;
@@ -369,10 +372,10 @@ static void *rt_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
        int cpu;
 
-       for (cpu = *pos + 1; cpu < NR_CPUS; ++cpu) {
+       for (cpu = *pos; cpu < NR_CPUS; ++cpu) {
                if (!cpu_possible(cpu))
                        continue;
-               *pos = cpu;
+               *pos = cpu+1;
                return per_cpu_ptr(rt_cache_stat, cpu);
        }
        return NULL;
@@ -387,6 +390,11 @@ static void rt_cpu_seq_stop(struct seq_file *seq, void *v)
 static int rt_cpu_seq_show(struct seq_file *seq, void *v)
 {
        struct rt_cache_stat *st = v;
+
+       if (v == SEQ_START_TOKEN) {
+               seq_printf(seq, "entries  in_hit in_slow_tot in_no_route in_brd in_martian_dst in_martian_src  out_hit out_slow_tot out_slow_mc  gc_total gc_ignored gc_goal_miss gc_dst_overflow in_hlist_search out_hlist_search\n");
+               return 0;
+       }
        
        seq_printf(seq,"%08x  %08x %08x %08x %08x %08x %08x %08x "
                   " %08x %08x %08x %08x %08x %08x %08x %08x %08x \n",
@@ -2783,12 +2791,16 @@ int __init ip_rt_init(void)
        add_timer(&rt_secret_timer);
 
 #ifdef CONFIG_PROC_FS
+       {
+       struct proc_dir_entry *rtstat_pde = NULL; /* keep gcc happy */
        if (!proc_net_fops_create("rt_cache", S_IRUGO, &rt_cache_seq_fops) ||
-           !proc_net_fops_create("rt_cache_stat", S_IRUGO, &rt_cpu_seq_fops)) {
+           !(rtstat_pde = create_proc_entry("rt_cache", S_IRUGO, 
+                                            proc_net_stat))) {
                free_percpu(rt_cache_stat);
                return -ENOMEM;
        }
-
+       rtstat_pde->proc_fops = &rt_cpu_seq_fops;
+       }
 #ifdef CONFIG_NET_CLS_ROUTE
        create_proc_read_entry("rt_acct", 0, proc_net, ip_rt_acct_read, NULL);
 #endif