netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC] display bound packet types
@ 2007-03-08  0:42 Stephen Hemminger
  2007-03-08  2:56 ` David Miller
  0 siblings, 1 reply; 2+ messages in thread
From: Stephen Hemminger @ 2007-03-08  0:42 UTC (permalink / raw)
  To: netdev

While debugging I found it useful to see what packet types are in use.

This creates /proc/net/ptype with the format:

Type Device      Function
ALL  eth0     [ffffffff880b01b6] :af_packet:packet_rcv_spkt+0x0
0800          [ffffffff802330f8] ip_rcv+0x0
0011          [ffffffff881021ef] :llc:llc_rcv+0x0
0004          [ffffffff881021ef] :llc:llc_rcv+0x0
0806          [ffffffff8043de7f] arp_rcv+0x0
86dd          [ffffffff880c1b57] :ipv6:ipv6_rcv+0x0

Is it worth the space?

---
 net/core/dev.c |  131 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 131 insertions(+)

--- netem-dev.orig/net/core/dev.c
+++ netem-dev/net/core/dev.c
@@ -2217,6 +2217,132 @@ static const struct file_operations soft
 	.release = seq_release,
 };
 
+static void *ptype_get_idx(loff_t pos)
+{
+	struct packet_type *pt = NULL;
+	loff_t i = 0;
+	int t;
+
+	list_for_each_entry_rcu(pt, &ptype_all, list) {
+		if (i == pos)
+			return pt;
+		++i;
+	}
+
+	for (t = 0; t < 16; t++) {
+		list_for_each_entry_rcu(pt, &ptype_base[t], list) {
+			if (i == pos)
+				return pt;
+			++i;
+		}
+	}
+	return NULL;
+}
+
+static void *ptype_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	rcu_read_lock();
+	return *pos ? ptype_get_idx(*pos - 1) : SEQ_START_TOKEN;
+}
+
+static void *ptype_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	struct packet_type *pt;
+	struct list_head *nxt;
+	int hash;
+
+	++*pos;
+	if (v == SEQ_START_TOKEN)
+		return ptype_get_idx(0);
+
+	pt = v;
+	nxt = pt->list.next;
+	if (pt->type == htons(ETH_P_ALL)) {
+		if (nxt != &ptype_all)
+			goto found;
+		hash = 0;
+		nxt = ptype_base[0].next;
+	} else
+		hash = ntohs(pt->type) & 15;
+
+	while (nxt == &ptype_base[hash]) {
+		if (++hash >= 16)
+			return NULL;
+		nxt = ptype_base[hash].next;
+	}
+found:
+	return list_entry(nxt, struct packet_type, list);
+}
+
+static void ptype_seq_stop(struct seq_file *seq, void *v)
+{
+	rcu_read_unlock();
+}
+
+static int ptype_seq_show(struct seq_file *seq, void *v)
+{
+	struct packet_type *pt = v;
+
+	if (v == SEQ_START_TOKEN)
+		seq_puts(seq, "Type Device      Function\n");
+	else {
+		if (pt->type == htons(ETH_P_ALL))
+			seq_puts(seq, "ALL ");
+		else
+			seq_printf(seq, "%04x", ntohs(pt->type));
+
+		seq_printf(seq, " %-8s [%p]",
+			   pt->dev ? pt->dev->name : "",
+			   pt->func);
+#ifdef CONFIG_KALLSYMS
+		{
+			unsigned long offset = 0, symsize;
+			const char *symname;
+			char *modname;
+			char *delim = ":";
+			char namebuf[128];
+
+			symname = kallsyms_lookup((unsigned long)pt->func,
+						  &symsize, &offset,
+						  &modname, namebuf);
+
+			if (symname) {
+				if (!modname)
+					modname = delim = "";
+				seq_printf(seq, " %s%s%s%s+0x%lx",
+					   delim, modname, delim,
+					   symname, offset);
+			}
+		}
+#endif
+		seq_putc(seq, '\n');
+
+	}
+
+	return 0;
+}
+
+static struct seq_operations ptype_seq_ops = {
+	.start = ptype_seq_start,
+	.next  = ptype_seq_next,
+	.stop  = ptype_seq_stop,
+	.show  = ptype_seq_show,
+};
+
+static int ptype_seq_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &ptype_seq_ops);
+}
+
+static const struct file_operations ptype_seq_fops = {
+	.owner	 = THIS_MODULE,
+	.open    = ptype_seq_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release,
+};
+
+
 #ifdef CONFIG_WIRELESS_EXT
 extern int wireless_proc_init(void);
 #else
@@ -2231,6 +2357,9 @@ static int __init dev_proc_init(void)
 		goto out;
 	if (!proc_net_fops_create("softnet_stat", S_IRUGO, &softnet_seq_fops))
 		goto out_dev;
+	if (!proc_net_fops_create("ptype", S_IRUGO, &ptype_seq_fops))
+		goto out_dev2;
+
 	if (wireless_proc_init())
 		goto out_softnet;
 	rc = 0;
@@ -2238,6 +2367,8 @@ out:
 	return rc;
 out_softnet:
 	proc_net_remove("softnet_stat");
+out_dev2:
+	proc_net_remove("ptype");
 out_dev:
 	proc_net_remove("dev");
 	goto out;

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

* Re: [RFC] display bound packet types
  2007-03-08  0:42 [RFC] display bound packet types Stephen Hemminger
@ 2007-03-08  2:56 ` David Miller
  0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2007-03-08  2:56 UTC (permalink / raw)
  To: shemminger; +Cc: netdev

From: Stephen Hemminger <shemminger@linux-foundation.org>
Date: Wed, 7 Mar 2007 16:42:59 -0800

> While debugging I found it useful to see what packet types are in use.
> 
> This creates /proc/net/ptype with the format:
> 
> Type Device      Function
> ALL  eth0     [ffffffff880b01b6] :af_packet:packet_rcv_spkt+0x0
> 0800          [ffffffff802330f8] ip_rcv+0x0
> 0011          [ffffffff881021ef] :llc:llc_rcv+0x0
> 0004          [ffffffff881021ef] :llc:llc_rcv+0x0
> 0806          [ffffffff8043de7f] arp_rcv+0x0
> 86dd          [ffffffff880c1b57] :ipv6:ipv6_rcv+0x0
> 
> Is it worth the space?

I have no objections.

It would be nice to use kallsyms on that function address
though.

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

end of thread, other threads:[~2007-03-08  2:56 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-03-08  0:42 [RFC] display bound packet types Stephen Hemminger
2007-03-08  2:56 ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).