* [PATCH] (7/13) aarp convert to seq_file
@ 2003-08-29 21:05 Stephen Hemminger
0 siblings, 0 replies; only message in thread
From: Stephen Hemminger @ 2003-08-29 21:05 UTC (permalink / raw)
To: Jay Schulist, David S. Miller; +Cc: netdev
Convert aarp to seq_file interface.
The output format is slightly changed:
- address is printed in same format as /proc/net/atalk/interface
- retry and last_sent are only shown for unresolved entries
- times shown in seconds.hundreths rather than raw jiffies
- column headers changed to same format as /proc/net/atalk/interface
diff -Nru a/net/appletalk/aarp.c b/net/appletalk/aarp.c
--- a/net/appletalk/aarp.c Fri Aug 29 13:31:39 2003
+++ b/net/appletalk/aarp.c Fri Aug 29 13:31:39 2003
@@ -37,6 +37,7 @@
#include <linux/atalk.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME;
int sysctl_aarp_tick_time = AARP_TICK_TIME;
@@ -888,96 +889,176 @@
write_unlock_bh(&aarp_lock);
}
-/* Called from proc fs */
-static int aarp_get_info(char *buffer, char **start, off_t offset, int length)
+#ifdef CONFIG_PROC_FS
+struct aarp_iter_state {
+ int bucket;
+ struct aarp_entry **table;
+};
+
+/*
+ * Get the aarp entry that is in the chain described
+ * by the iterator.
+ * If pos is set then skip till that index.
+ * pos = 1 is the first entry
+ */
+static struct aarp_entry *iter_next(struct aarp_iter_state *iter, loff_t *pos)
{
- /* we should dump all our AARP entries */
+ int ct = iter->bucket;
+ struct aarp_entry **table = iter->table;
+ loff_t off = 0;
struct aarp_entry *entry;
- int ct, len = sprintf(buffer,
- "%-10.10s %-10.10s%-18.18s%12.12s%12.12s "
- "xmit_count status\n",
- "address", "device", "hw addr", "last_sent",
- "expires");
+
+ rescan:
+ while(ct < AARP_HASH_SIZE) {
+ for (entry = table[ct]; entry; entry = entry->next) {
+ if (!pos || ++off == *pos) {
+ iter->table = table;
+ iter->bucket = ct;
+ return entry;
+ }
+ }
+ ++ct;
+ }
+
+ if (table == resolved) {
+ ct = 0;
+ table = unresolved;
+ goto rescan;
+ }
+ if (table == unresolved) {
+ ct = 0;
+ table = proxies;
+ goto rescan;
+ }
+ return NULL;
+}
+
+static void *aarp_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ struct aarp_iter_state *iter = seq->private;
read_lock_bh(&aarp_lock);
+ iter->table = resolved;
+ iter->bucket = 0;
- for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
- for (entry = resolved[ct]; entry; entry = entry->next) {
- len += sprintf(buffer + len, "%6u:%-3u ",
- (unsigned int)ntohs(entry->target_addr.s_net),
- (unsigned int)(entry->target_addr.s_node));
- len += sprintf(buffer + len, "%-10.10s",
- entry->dev->name);
- len += sprintf(buffer + len,
- "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
- (int)(entry->hwaddr[0] & 0x000000FF),
- (int)(entry->hwaddr[1] & 0x000000FF),
- (int)(entry->hwaddr[2] & 0x000000FF),
- (int)(entry->hwaddr[3] & 0x000000FF),
- (int)(entry->hwaddr[4] & 0x000000FF),
- (int)(entry->hwaddr[5] & 0x000000FF));
- len += sprintf(buffer + len, "%12lu ""%12lu ",
- (unsigned long)entry->last_sent,
- (unsigned long)entry->expires_at);
- len += sprintf(buffer + len, "%10u",
- (unsigned int)entry->xmit_count);
+ return *pos ? iter_next(iter, pos) : ((void *)1);
+}
- len += sprintf(buffer + len, " resolved\n");
- }
- }
+static void *aarp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct aarp_entry *entry = v;
+ struct aarp_iter_state *iter = seq->private;
- for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
- for (entry = unresolved[ct]; entry; entry = entry->next) {
- len += sprintf(buffer + len, "%6u:%-3u ",
- (unsigned int)ntohs(entry->target_addr.s_net),
- (unsigned int)(entry->target_addr.s_node));
- len += sprintf(buffer + len, "%-10.10s",
- entry->dev->name);
- len += sprintf(buffer + len,
- "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
- (int)(entry->hwaddr[0] & 0x000000FF),
- (int)(entry->hwaddr[1] & 0x000000FF),
- (int)(entry->hwaddr[2] & 0x000000FF),
- (int)(entry->hwaddr[3] & 0x000000FF),
- (int)(entry->hwaddr[4] & 0x000000FF),
- (int)(entry->hwaddr[5] & 0x000000FF));
- len += sprintf(buffer + len, "%12lu ""%12lu ",
- (unsigned long)entry->last_sent,
- (unsigned long)entry->expires_at);
- len += sprintf(buffer + len, "%10u",
- (unsigned int)entry->xmit_count);
- len += sprintf(buffer + len, " unresolved\n");
- }
- }
+ ++*pos;
- for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
- for (entry = proxies[ct]; entry; entry = entry->next) {
- len += sprintf(buffer + len, "%6u:%-3u ",
- (unsigned int)ntohs(entry->target_addr.s_net),
- (unsigned int)(entry->target_addr.s_node));
- len += sprintf(buffer + len, "%-10.10s",
- entry->dev->name);
- len += sprintf(buffer + len,
- "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
- (int)(entry->hwaddr[0] & 0x000000FF),
- (int)(entry->hwaddr[1] & 0x000000FF),
- (int)(entry->hwaddr[2] & 0x000000FF),
- (int)(entry->hwaddr[3] & 0x000000FF),
- (int)(entry->hwaddr[4] & 0x000000FF),
- (int)(entry->hwaddr[5] & 0x000000FF));
- len += sprintf(buffer + len, "%12lu ""%12lu ",
- (unsigned long)entry->last_sent,
- (unsigned long)entry->expires_at);
- len += sprintf(buffer + len, "%10u",
- (unsigned int)entry->xmit_count);
- len += sprintf(buffer + len, " proxy\n");
- }
+ /* first line after header */
+ if (v == ((void *)1))
+ entry = iter_next(iter, NULL);
+
+ /* next entry in current bucket */
+ else if (entry->next)
+ entry = entry->next;
+
+ /* next bucket or table */
+ else {
+ ++iter->bucket;
+ entry = iter_next(iter, NULL);
}
+ return entry;
+}
+static void aarp_seq_stop(struct seq_file *seq, void *v)
+{
read_unlock_bh(&aarp_lock);
- return len;
}
+static const char *dt2str(unsigned long ticks)
+{
+ static char buf[32];
+
+ sprintf(buf, "%ld.%02ld", ticks / HZ, ((ticks % HZ) * 100 ) / HZ);
+
+ return buf;
+}
+
+static int aarp_seq_show(struct seq_file *seq, void *v)
+{
+ struct aarp_iter_state *iter = seq->private;
+ struct aarp_entry *entry = v;
+ unsigned long now = jiffies;
+
+ if (v == ((void *)1))
+ seq_puts(seq,
+ "Address Interface Hardware Address"
+ " Expires LastSend Retry Status\n");
+ else {
+ seq_printf(seq, "%04X:%02X %-12s",
+ ntohs(entry->target_addr.s_net),
+ (unsigned int) entry->target_addr.s_node,
+ entry->dev ? entry->dev->name : "????");
+ seq_printf(seq, "%02X:%02X:%02X:%02X:%02X:%02X",
+ entry->hwaddr[0] & 0xFF,
+ entry->hwaddr[1] & 0xFF,
+ entry->hwaddr[2] & 0xFF,
+ entry->hwaddr[3] & 0xFF,
+ entry->hwaddr[4] & 0xFF,
+ entry->hwaddr[5] & 0xFF);
+ seq_printf(seq, " %8s",
+ dt2str((long)entry->expires_at - (long)now));
+ if (iter->table == unresolved)
+ seq_printf(seq, " %8s %6hu",
+ dt2str(now - entry->last_sent),
+ entry->xmit_count);
+ else
+ seq_puts(seq, " ");
+ seq_printf(seq, " %s\n",
+ (iter->table == resolved) ? "resolved"
+ : (iter->table == unresolved) ? "unresolved"
+ : (iter->table == proxies) ? "proxies"
+ : "unknown");
+ }
+ return 0;
+}
+
+static struct seq_operations aarp_seq_ops = {
+ .start = aarp_seq_start,
+ .next = aarp_seq_next,
+ .stop = aarp_seq_stop,
+ .show = aarp_seq_show,
+};
+
+static int aarp_seq_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ int rc = -ENOMEM;
+ struct aarp_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+
+ if (!s)
+ goto out;
+
+ rc = seq_open(file, &aarp_seq_ops);
+ if (rc)
+ goto out_kfree;
+
+ seq = file->private_data;
+ seq->private = s;
+ memset(s, 0, sizeof(*s));
+out:
+ return rc;
+out_kfree:
+ kfree(s);
+ goto out;
+}
+
+struct file_operations atalk_seq_arp_fops = {
+ .owner = THIS_MODULE,
+ .open = aarp_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_private,
+};
+#endif
+
/* General module cleanup. Called from cleanup_module() in ddp.c. */
void aarp_cleanup_module(void)
{
@@ -990,7 +1071,7 @@
#ifdef CONFIG_PROC_FS
void aarp_register_proc_fs(void)
{
- proc_net_create("aarp", 0, aarp_get_info);
+ proc_net_fops_create("aarp", S_IRUGO, &atalk_seq_arp_fops);
}
void aarp_unregister_proc_fs(void)
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2003-08-29 21:05 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-08-29 21:05 [PATCH] (7/13) aarp convert to seq_file Stephen Hemminger
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.