|
@@ -3734,21 +3734,15 @@ static struct net_proto_family pfkey_family_ops = {
|
|
|
};
|
|
|
|
|
|
#ifdef CONFIG_PROC_FS
|
|
|
-static int pfkey_read_proc(char *buffer, char **start, off_t offset,
|
|
|
- int length, int *eof, void *data)
|
|
|
+static int pfkey_seq_show(struct seq_file *f, void *v)
|
|
|
{
|
|
|
- off_t pos = 0;
|
|
|
- off_t begin = 0;
|
|
|
- int len = 0;
|
|
|
struct sock *s;
|
|
|
- struct hlist_node *node;
|
|
|
-
|
|
|
- len += sprintf(buffer,"sk RefCnt Rmem Wmem User Inode\n");
|
|
|
-
|
|
|
- read_lock(&pfkey_table_lock);
|
|
|
|
|
|
- sk_for_each(s, node, &pfkey_table) {
|
|
|
- len += sprintf(buffer+len,"%p %-6d %-6u %-6u %-6u %-6lu",
|
|
|
+ s = (struct sock *)v;
|
|
|
+ if (v == SEQ_START_TOKEN)
|
|
|
+ seq_printf(f ,"sk RefCnt Rmem Wmem User Inode\n");
|
|
|
+ else
|
|
|
+ seq_printf(f ,"%p %-6d %-6u %-6u %-6u %-6lu\n",
|
|
|
s,
|
|
|
atomic_read(&s->sk_refcnt),
|
|
|
atomic_read(&s->sk_rmem_alloc),
|
|
@@ -3756,40 +3750,68 @@ static int pfkey_read_proc(char *buffer, char **start, off_t offset,
|
|
|
sock_i_uid(s),
|
|
|
sock_i_ino(s)
|
|
|
);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos)
|
|
|
+{
|
|
|
+ struct sock *s;
|
|
|
+ struct hlist_node *node;
|
|
|
+ loff_t pos = *ppos;
|
|
|
|
|
|
- buffer[len++] = '\n';
|
|
|
+ read_lock(&pfkey_table_lock);
|
|
|
+ if (pos == 0)
|
|
|
+ return SEQ_START_TOKEN;
|
|
|
|
|
|
- pos = begin + len;
|
|
|
- if (pos < offset) {
|
|
|
- len = 0;
|
|
|
- begin = pos;
|
|
|
- }
|
|
|
- if(pos > offset + length)
|
|
|
- goto done;
|
|
|
- }
|
|
|
- *eof = 1;
|
|
|
+ sk_for_each(s, node, &pfkey_table)
|
|
|
+ if (pos-- == 1)
|
|
|
+ return s;
|
|
|
|
|
|
-done:
|
|
|
- read_unlock(&pfkey_table_lock);
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+static void *pfkey_seq_next(struct seq_file *f, void *v, loff_t *ppos)
|
|
|
+{
|
|
|
+ ++*ppos;
|
|
|
+ return (v == SEQ_START_TOKEN) ?
|
|
|
+ sk_head(&pfkey_table) :
|
|
|
+ sk_next((struct sock *)v);
|
|
|
+}
|
|
|
|
|
|
- *start = buffer + (offset - begin);
|
|
|
- len -= (offset - begin);
|
|
|
+static void pfkey_seq_stop(struct seq_file *f, void *v)
|
|
|
+{
|
|
|
+ read_unlock(&pfkey_table_lock);
|
|
|
+}
|
|
|
|
|
|
- if (len > length)
|
|
|
- len = length;
|
|
|
- if (len < 0)
|
|
|
- len = 0;
|
|
|
+static struct seq_operations pfkey_seq_ops = {
|
|
|
+ .start = pfkey_seq_start,
|
|
|
+ .next = pfkey_seq_next,
|
|
|
+ .stop = pfkey_seq_stop,
|
|
|
+ .show = pfkey_seq_show,
|
|
|
+};
|
|
|
|
|
|
- return len;
|
|
|
+static int pfkey_seq_open(struct inode *inode, struct file *file)
|
|
|
+{
|
|
|
+ return seq_open(file, &pfkey_seq_ops);
|
|
|
}
|
|
|
|
|
|
+static struct file_operations pfkey_proc_ops = {
|
|
|
+ .open = pfkey_seq_open,
|
|
|
+ .read = seq_read,
|
|
|
+ .llseek = seq_lseek,
|
|
|
+ .release = seq_release,
|
|
|
+};
|
|
|
+
|
|
|
static int pfkey_init_proc(void)
|
|
|
{
|
|
|
- if (create_proc_read_entry("pfkey", 0, init_net.proc_net,
|
|
|
- pfkey_read_proc, NULL) == NULL)
|
|
|
+ struct proc_dir_entry *e;
|
|
|
+
|
|
|
+ e = create_proc_entry("pfkey", 0, init_net.proc_net);
|
|
|
+ if (e == NULL)
|
|
|
return -ENOMEM;
|
|
|
- else
|
|
|
- return 0;
|
|
|
+
|
|
|
+ e->proc_fops = &pfkey_proc_ops;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static void pfkey_exit_proc(void)
|