All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ipv4: make arp seq_file show method only produce one record per call
@ 2002-10-17  1:01 Arnaldo Carvalho de Melo
  2002-10-17  0:58 ` David S. Miller
  0 siblings, 1 reply; 10+ messages in thread
From: Arnaldo Carvalho de Melo @ 2002-10-17  1:01 UTC (permalink / raw)
  To: David S. Miller; +Cc: Linux Kernel Mailing List

David,

	Please pull from:

master.kernel.org:/home/acme/BK/net-2.5

- Arnaldo


You can import this changeset into BK by piping this whole message to:
'| bk receive [path to repository]' or apply the patch as usual.

===================================================================


ChangeSet@1.859, 2002-10-16 21:41:11-03:00, acme@conectiva.com.br
  o ipv4: make arp seq_file show method only produce one record per call


 ip_proc.c |  214 +++++++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 150 insertions(+), 64 deletions(-)


diff -Nru a/net/ipv4/ip_proc.c b/net/ipv4/ip_proc.c
--- a/net/ipv4/ip_proc.c	Wed Oct 16 21:44:36 2002
+++ b/net/ipv4/ip_proc.c	Wed Oct 16 21:44:36 2002
@@ -67,99 +67,185 @@
 }
 #endif /* CONFIG_AX25 */
 
+struct arp_iter_state {
+	loff_t  is_pneigh: 1,
+		bucket:	   6,
+		pos:	   sizeof(loff_t) * 8 - 7;
+};
+
+static __inline__ struct neighbour *neigh_get_bucket(loff_t *pos)
+{
+	struct neighbour *n = NULL;
+	struct arp_iter_state* state = (struct arp_iter_state *)pos;
+	loff_t l = state->pos;
+	int i, bucket = state->bucket;
+
+	for (; bucket <= NEIGH_HASHMASK; ++bucket)
+		for (i = 0, n = arp_tbl.hash_buckets[bucket]; n;
+		     ++i, n = n->next)
+			/* Do not confuse users "arp -a" with magic entries */
+			if ((n->nud_state & ~NUD_NOARP) && !l--) {
+				state->pos    = i;
+				state->bucket = bucket;
+				goto out;
+			}
+out:
+	return n;
+}
+
+static __inline__ struct pneigh_entry *pneigh_get_bucket(loff_t *pos)
+{
+	struct pneigh_entry *n = NULL;
+	struct arp_iter_state* state = (struct arp_iter_state *)pos;
+	loff_t l = state->pos;
+	int i, bucket = state->bucket;
+
+	for (; bucket <= PNEIGH_HASHMASK; ++bucket)
+		for (i = 0, n = arp_tbl.phash_buckets[bucket]; n;
+		     ++i, n = n->next)
+			if (!l--) {
+				state->pos    = i;
+				state->bucket = bucket;
+				goto out;
+			}
+out:
+	return n;
+}
+
+static __inline__ void *arp_get_bucket(struct seq_file *seq, loff_t *pos)
+{
+	void *rc = neigh_get_bucket(pos);
+
+	if (!rc) {
+		struct arp_iter_state* state = (struct arp_iter_state *)pos;
+
+		read_unlock_bh(&arp_tbl.lock);
+		state->is_pneigh = 1;
+		state->bucket	 = 0;
+		state->pos	 = 0;
+		/* HACK: till there is state we can pass to seq_show...  */
+		seq->private = (void *)1;
+		rc = pneigh_get_bucket(pos);
+	}
+	return rc;
+}
+
 static void *arp_seq_start(struct seq_file *seq, loff_t *pos)
 {
-	return (void *)(unsigned long)++*pos;
+	read_lock_bh(&arp_tbl.lock);
+	return *pos ? arp_get_bucket(seq, pos) : (void *)1;
 }
 
 static void *arp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-	return (void *)(unsigned long)((++*pos) >=
-				       (NEIGH_HASHMASK +
-					PNEIGH_HASHMASK - 1) ? 0 : *pos);
+	void *rc;
+	struct arp_iter_state* state;
+
+	if (v == (void *)1) {
+		rc = arp_get_bucket(seq, pos);
+		goto out;
+	}
+
+	state = (struct arp_iter_state *)pos;
+	if (!state->is_pneigh) {
+		struct neighbour *n = v;
+
+		rc = n = n->next;
+		if (n)
+			goto out;
+		state->pos = 0;
+		++state->bucket;
+		rc = neigh_get_bucket(pos);
+		if (rc)
+			goto out;
+		read_unlock_bh(&arp_tbl.lock);
+		/* HACK: till there is state we can pass to seq_show...  */
+		seq->private	 = (void *)1;
+		state->is_pneigh = 1;
+		state->bucket	 = 0;
+		state->pos	 = 0;
+		rc = pneigh_get_bucket(pos);
+	} else {
+		struct pneigh_entry *pn = v;
+
+		pn = pn->next;
+		if (!pn) {
+			++state->bucket;
+			state->pos = 0;
+			pn = pneigh_get_bucket(pos);
+		}
+		rc = pn;
+	}
+out:
+	++*pos;
+	return rc;
 }
 
 static void arp_seq_stop(struct seq_file *seq, void *v)
 {
+	if (!seq->private)
+		read_unlock_bh(&arp_tbl.lock);
 }
 
 #define HBUFFERLEN 30
 
-static __inline__ void arp_format_neigh_table(struct seq_file *seq, int entry)
+static __inline__ void arp_format_neigh_entry(struct seq_file *seq,
+					      struct neighbour *n)
 {
 	char hbuffer[HBUFFERLEN];
 	const char hexbuf[] = "0123456789ABCDEF";
-	struct neighbour *n;
 	int k, j;
+	char tbuf[16];
+	struct net_device *dev = n->dev;
+	int hatype = dev->type;
 
-	read_lock_bh(&arp_tbl.lock);
-	for (n = arp_tbl.hash_buckets[entry]; n; n = n->next) {
-		char tbuf[16];
-		struct net_device *dev = n->dev;
-		int hatype = dev->type;
-
-		/* Do not confuse users "arp -a" with magic entries */
-		if (!(n->nud_state & ~NUD_NOARP))
-			continue;
-
-		read_lock(&n->lock);
-		/* Convert hardware address to XX:XX:XX:XX ... form. */
+	read_lock(&n->lock);
+	/* Convert hardware address to XX:XX:XX:XX ... form. */
 #ifdef CONFIG_AX25
-		if (hatype == ARPHRD_AX25 || hatype == ARPHRD_NETROM)
-			ax2asc2((ax25_address *)n->ha, hbuffer);
-		else {
+	if (hatype == ARPHRD_AX25 || hatype == ARPHRD_NETROM)
+		ax2asc2((ax25_address *)n->ha, hbuffer);
+	else {
 #endif
-		for (k = 0, j = 0; k < HBUFFERLEN - 3 &&
-				   j < dev->addr_len; j++) {
-			hbuffer[k++] = hexbuf[(n->ha[j] >> 4) & 15];
-			hbuffer[k++] = hexbuf[n->ha[j] & 15];
-			hbuffer[k++] = ':';
-		}
-		hbuffer[--k] = 0;
+	for (k = 0, j = 0; k < HBUFFERLEN - 3 && j < dev->addr_len; j++) {
+		hbuffer[k++] = hexbuf[(n->ha[j] >> 4) & 15];
+		hbuffer[k++] = hexbuf[n->ha[j] & 15];
+		hbuffer[k++] = ':';
+	}
+	hbuffer[--k] = 0;
 #ifdef CONFIG_AX25
-		}
-#endif
-		sprintf(tbuf, "%u.%u.%u.%u",
-			NIPQUAD(*(u32*)n->primary_key));
-		seq_printf(seq, "%-16s 0x%-10x0x%-10x%s"
-				"     *        %s\n",
-			   tbuf, hatype, arp_state_to_flags(n), 
-			   hbuffer, dev->name);
-		read_unlock(&n->lock);
-	}
-	read_unlock_bh(&arp_tbl.lock);
-}
-
-static __inline__ void arp_format_pneigh_table(struct seq_file *seq, int entry)
-{
-	struct pneigh_entry *n;
-
-	for (n = arp_tbl.phash_buckets[entry]; n; n = n->next) {
-		struct net_device *dev = n->dev;
-		int hatype = dev ? dev->type : 0;
-		char tbuf[16];
-
-		sprintf(tbuf, "%u.%u.%u.%u", NIPQUAD(*(u32*)n->key));
-		seq_printf(seq, "%-16s 0x%-10x0x%-10x%s"
-				"     *        %s\n",
-			   tbuf, hatype, ATF_PUBL | ATF_PERM,
-			   "00:00:00:00:00:00",
-			   dev ? dev->name : "*");
 	}
+#endif
+	sprintf(tbuf, "%u.%u.%u.%u", NIPQUAD(*(u32*)n->primary_key));
+	seq_printf(seq, "%-16s 0x%-10x0x%-10x%s     *        %s\n",
+		   tbuf, hatype, arp_state_to_flags(n), hbuffer, dev->name);
+	read_unlock(&n->lock);
 }
 
-static int arp_seq_show(struct seq_file *seq, void *v)
+static __inline__ void arp_format_pneigh_entry(struct seq_file *seq,
+					       struct pneigh_entry *n)
 {
-	unsigned long l = (unsigned long)v - 1;
 
-	if (!l)
+	struct net_device *dev = n->dev;
+	int hatype = dev ? dev->type : 0;
+	char tbuf[16];
+
+	sprintf(tbuf, "%u.%u.%u.%u", NIPQUAD(*(u32*)n->key));
+	seq_printf(seq, "%-16s 0x%-10x0x%-10x%s     *        %s\n",
+		   tbuf, hatype, ATF_PUBL | ATF_PERM, "00:00:00:00:00:00",
+		   dev ? dev->name : "*");
+}
+
+static int arp_seq_show(struct seq_file *seq, void *v)
+{
+	if (v == (void *)1)
 		seq_puts(seq, "IP address       HW type     Flags       "
 			      "HW address            Mask     Device\n");
-
-	if (l <= NEIGH_HASHMASK)
-		arp_format_neigh_table(seq, l);
-	else
-		arp_format_pneigh_table(seq, l - NEIGH_HASHMASK);
+	else {
+		if (seq->private)
+			arp_format_pneigh_entry(seq, v);
+		else
+			arp_format_neigh_entry(seq, v);
+	}
 
 	return 0;
 }

===================================================================


This BitKeeper patch contains the following changesets:
1.859
## Wrapped with gzip_uu ##


begin 664 bkpatch14639
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
&HG+_$P``
`
end

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2002-10-17  2:17 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-10-17  1:01 [PATCH] ipv4: make arp seq_file show method only produce one record per call Arnaldo Carvalho de Melo
2002-10-17  0:58 ` David S. Miller
2002-10-17  1:11   ` Arnaldo Carvalho de Melo
2002-10-17  1:15     ` David S. Miller
2002-10-17  1:30       ` Neil Brown
2002-10-17  1:28         ` David S. Miller
2002-10-17  2:00           ` Arnaldo Carvalho de Melo
2002-10-17  2:10             ` Arnaldo Carvalho de Melo
2002-10-17  2:23               ` Arnaldo Carvalho de Melo
2002-10-17  1:35       ` Arnaldo Carvalho de Melo

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.