Module Name:    src
Committed By:   dyoung
Date:           Thu Aug 13 00:23:32 UTC 2009

Modified Files:
        src/sys/net: if.c if.h

Log Message:
Use sysctl(9) to expose to userland each interface transmission
queue's maximum length, current length, and number of drops.  E.g.,

% sysctl net.interfaces.bnx0
net.interfaces.bnx0.sndq.len = 0
net.interfaces.bnx0.sndq.maxlen = 509
net.interfaces.bnx0.sndq.drops = 0

Let userland adjust the maximum queue length.

While I'm here, add a 64-bit generation number, if_index_gen, to
ifnet; the pair [ifp->if_index, ifp->if_index_gen] can serve to
identify an ifnet for the lifetime of the system.  I will use this
in an upcoming change.

Ok m...@.


To generate a diff of this commit:
cvs rdiff -u -r1.233 -r1.234 src/sys/net/if.c
cvs rdiff -u -r1.142 -r1.143 src/sys/net/if.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/if.c
diff -u src/sys/net/if.c:1.233 src/sys/net/if.c:1.234
--- src/sys/net/if.c:1.233	Thu Feb 12 19:05:36 2009
+++ src/sys/net/if.c	Thu Aug 13 00:23:31 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.c,v 1.233 2009/02/12 19:05:36 christos Exp $	*/
+/*	$NetBSD: if.c,v 1.234 2009/08/13 00:23:31 dyoung Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.233 2009/02/12 19:05:36 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.234 2009/08/13 00:23:31 dyoung Exp $");
 
 #include "opt_inet.h"
 
@@ -159,11 +159,16 @@
 static LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
 static int if_cloners_count;
 
+static uint64_t index_gen;
+static kmutex_t index_gen_mtx;
+
 #ifdef PFIL_HOOKS
 struct pfil_head if_pfil;	/* packet filtering hook for interfaces */
 #endif
 
 static void if_detach_queues(struct ifnet *, struct ifqueue *);
+static void sysctl_sndq_setup(struct sysctllog **, const char *,
+    struct ifaltq *);
 
 /*
  * Network interface utility routines.
@@ -175,6 +180,7 @@
 ifinit(void)
 {
 
+	mutex_init(&index_gen_mtx, MUTEX_DEFAULT, IPL_NONE);
 	callout_init(&if_slowtimo_ch, 0);
 	if_slowtimo(NULL);
 }
@@ -447,6 +453,10 @@
 	if (ifp->if_ioctl == NULL)
 		ifp->if_ioctl = ifioctl_common;
 
+	mutex_enter(&index_gen_mtx);
+	ifp->if_index_gen = index_gen++;
+	mutex_exit(&index_gen_mtx);
+
 	ifp->if_index = if_index;
 	if (ifindex2ifnet == NULL)
 		if_index++;
@@ -524,6 +534,9 @@
 
 	if (ifp->if_snd.ifq_maxlen == 0)
 		ifp->if_snd.ifq_maxlen = ifqmaxlen;
+
+	sysctl_sndq_setup(&ifp->if_sysctl_log, ifp->if_xname, &ifp->if_snd);
+
 	ifp->if_broadcastaddr = 0; /* reliably crash if used uninitialized */
 
 	ifp->if_link_state = LINK_STATE_UNKNOWN;
@@ -666,6 +679,7 @@
 		altq_detach(&ifp->if_snd);
 #endif
 
+	sysctl_teardown(&ifp->if_sysctl_log);
 
 #if NCARP > 0
 	/* Remove the interface from any carp group it is a part of.  */
@@ -1874,6 +1888,73 @@
 }
 
 
+static void
+sysctl_sndq_setup(struct sysctllog **clog, const char *ifname,
+    struct ifaltq *ifq)
+{
+	const struct sysctlnode *cnode, *rnode;
+
+	if (sysctl_createv(clog, 0, NULL, &rnode,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_NODE, "net", NULL,
+		       NULL, 0, NULL, 0,
+		       CTL_NET, CTL_EOL) != 0)
+		goto bad;
+
+	if (sysctl_createv(clog, 0, &rnode, &rnode,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_NODE, "interfaces",
+		       SYSCTL_DESCR("Per-interface controls"),
+		       NULL, 0, NULL, 0,
+		       CTL_CREATE, CTL_EOL) != 0)
+		goto bad;
+
+	if (sysctl_createv(clog, 0, &rnode, &rnode,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_NODE, ifname,
+		       SYSCTL_DESCR("Interface controls"),
+		       NULL, 0, NULL, 0,
+		       CTL_CREATE, CTL_EOL) != 0)
+		goto bad;
+
+	if (sysctl_createv(clog, 0, &rnode, &rnode,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_NODE, "sndq",
+		       SYSCTL_DESCR("Interface output queue controls"),
+		       NULL, 0, NULL, 0,
+		       CTL_CREATE, CTL_EOL) != 0)
+		goto bad;
+
+	if (sysctl_createv(clog, 0, &rnode, &cnode,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_INT, "len",
+		       SYSCTL_DESCR("Current output queue length"),
+		       NULL, 0, &ifq->ifq_len, 0,
+		       CTL_CREATE, CTL_EOL) != 0)
+		goto bad;
+
+	if (sysctl_createv(clog, 0, &rnode, &cnode,
+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+		       CTLTYPE_INT, "maxlen",
+		       SYSCTL_DESCR("Maximum allowed output queue length"),
+		       NULL, 0, &ifq->ifq_maxlen, 0,
+		       CTL_CREATE, CTL_EOL) != 0)
+		goto bad;
+
+	if (sysctl_createv(clog, 0, &rnode, &cnode,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_INT, "drops",
+		       SYSCTL_DESCR("Packets dropped due to full output queue"),
+		       NULL, 0, &ifq->ifq_drops, 0,
+		       CTL_CREATE, CTL_EOL) != 0)
+		goto bad;
+
+	return;
+bad:
+	printf("%s: could not attach sysctl nodes\n", ifname);
+	return;
+}
+
 #if defined(INET) || defined(INET6)
 static void
 sysctl_net_ifq_setup(struct sysctllog **clog,

Index: src/sys/net/if.h
diff -u src/sys/net/if.h:1.142 src/sys/net/if.h:1.143
--- src/sys/net/if.h:1.142	Sun Jan 11 02:45:54 2009
+++ src/sys/net/if.h	Thu Aug 13 00:23:32 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.h,v 1.142 2009/01/11 02:45:54 christos Exp $	*/
+/*	$NetBSD: if.h,v 1.143 2009/08/13 00:23:32 dyoung Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -282,6 +282,21 @@
 	 */
 	void	*if_pf_kif;		/* pf interface abstraction */
 	void	*if_pf_groups;		/* pf interface groups */
+	/*
+	 * During an ifnet's lifetime, it has only one if_index, but
+	 * and if_index is not sufficient to identify an ifnet
+	 * because during the lifetime of the system, many ifnets may occupy a
+	 * given if_index.  Let us tell different ifnets at the same
+	 * if_index apart by their if_index_gen, a unique number that each ifnet
+	 * is assigned when it if_attach()s.  Now, the kernel can use the
+	 * pair (if_index, if_index_gen) as a weak reference to an ifnet.
+	 */
+	uint64_t if_index_gen;		/* generation number for the ifnet
+					 * at if_index: if two ifnets' index
+					 * and generation number are both the
+					 * same, they are the same ifnet.
+					 */
+	struct sysctllog	*if_sysctl_log;
 };
 #define	if_mtu		if_data.ifi_mtu
 #define	if_type		if_data.ifi_type

Reply via email to