socsvn commit: r286826 - soc2015/btw/head/sys/net

btw at FreeBSD.org btw at FreeBSD.org
Mon Jun 8 09:57:03 UTC 2015


Author: btw
Date: Mon Jun  8 09:57:00 2015
New Revision: 286826
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=286826

Log:
  Add a temporary sysctl to export the statistics of ifring to userspace.

Modified:
  soc2015/btw/head/sys/net/if.c
  soc2015/btw/head/sys/net/if.h
  soc2015/btw/head/sys/net/if_mib.c
  soc2015/btw/head/sys/net/if_mib.h
  soc2015/btw/head/sys/net/if_var.h

Modified: soc2015/btw/head/sys/net/if.c
==============================================================================
--- soc2015/btw/head/sys/net/if.c	Mon Jun  8 07:06:33 2015	(r286825)
+++ soc2015/btw/head/sys/net/if.c	Mon Jun  8 09:57:00 2015	(r286826)
@@ -45,6 +45,7 @@
 #include <sys/systm.h>
 #include <sys/priv.h>
 #include <sys/proc.h>
+#include <sys/smp.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/protosw.h>
@@ -1769,6 +1770,39 @@
 }
 
 /*
+ * Copy data from ifring to userland API structure if_ring_data.
+ */
+void
+if_ring_data_copy(struct ifnet *ifp, struct if_ring_data *ifrd)
+{
+	struct ifrstat *ifrs;
+	struct xifrstat *xifrs;
+	int ri, cpu;
+
+	ifrd->ifrd_epoch = ifp->if_epoch;
+	ifrd->ifrd_lastchange = ifp->if_lastchange;
+
+	ifrd->ifrd_ncpus = mp_ncpus;
+	ifrd->ifrd_nrings = ifp->if_nrings;
+
+	for (ri = 0; ri < ifp->if_nrings; ri++) {
+		for (cpu = 0; cpu < mp_ncpus; cpu++) {
+
+			ifrs = &ifp->if_rings[ri]->ifr_stats[cpu];
+			xifrs = &ifrd->ifrd_stats[ri * mp_ncpus + cpu];
+
+			xifrs->ifrs_ifinput = ifrs->ifrs_ifinput;
+			xifrs->ifrs_netisr = ifrs->ifrs_netisr;
+			xifrs->ifrs_ether = ifrs->ifrs_ether;
+			xifrs->ifrs_ip = ifrs->ifrs_ip;
+			xifrs->ifrs_ip6 = ifrs->ifrs_ip6;
+			xifrs->ifrs_udp = ifrs->ifrs_udp;
+			xifrs->ifrs_tcp = ifrs->ifrs_tcp;
+		}
+	}
+}
+
+/*
  * Initialization, destruction and refcounting functions for ifaddrs.
  */
 struct ifaddr *

Modified: soc2015/btw/head/sys/net/if.h
==============================================================================
--- soc2015/btw/head/sys/net/if.h	Mon Jun  8 07:06:33 2015	(r286825)
+++ soc2015/btw/head/sys/net/if.h	Mon Jun  8 09:57:00 2015	(r286826)
@@ -68,6 +68,35 @@
 	char	*ifcr_buffer;		/* buffer for cloner names */
 };
 
+struct xifrstat {
+	uint64_t ifrs_ifinput;
+	uint64_t ifrs_netisr;
+	uint64_t ifrs_ether;
+	uint64_t ifrs_ip;
+	uint64_t ifrs_ip6;
+	uint64_t ifrs_udp;
+	uint64_t ifrs_tcp;
+};
+
+struct if_ring_data {
+	/* Unions are here to make sizes MI. */
+	union {				/* uptime at attach or stat reset */
+		time_t		ifrd_epoch;
+		uint64_t	__ifrd_epoch_ph;
+	};
+	union {				/* time of last administrative change */
+		struct timeval	ifrd_lastchange;
+		struct {
+			uint64_t ph1;
+			uint64_t ph2;
+		} __ifrd_lastchange_ph;
+	};
+
+	int ifrd_ncpus;
+	int ifrd_nrings;
+	struct xifrstat ifrd_stats[0];
+};
+
 /*
  * Structure describing information about an interface
  * which may be of interest to management entities.

Modified: soc2015/btw/head/sys/net/if_mib.c
==============================================================================
--- soc2015/btw/head/sys/net/if_mib.c	Mon Jun  8 07:06:33 2015	(r286825)
+++ soc2015/btw/head/sys/net/if_mib.c	Mon Jun  8 09:57:00 2015	(r286826)
@@ -32,6 +32,7 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/smp.h>
 #include <sys/socket.h>
 #include <sys/sysctl.h>
 
@@ -54,6 +55,8 @@
  *						- a link-type-specific data
  *						  structure (as might be used
  *						  by an SNMP agent
+ *			.ifdata.<ifindex>.ringinfo
+ *						- what's in `struct if_ring_data'
  *
  * Perhaps someday we will make addresses accessible via this interface
  * as well (then there will be four such...).  The reason that the
@@ -78,7 +81,7 @@
 	int error;
 	u_int namelen = arg2;
 	struct ifnet *ifp;
-	struct ifmibdata ifmd;
+	struct ifmibdata *ifmd = NULL;
 	size_t dlen;
 	char *dbuf;
 
@@ -96,18 +99,23 @@
 		goto out;
 
 	case IFDATA_GENERAL:
-		bzero(&ifmd, sizeof(ifmd));
-		strlcpy(ifmd.ifmd_name, ifp->if_xname, sizeof(ifmd.ifmd_name));
+		ifmd = malloc(sizeof(*ifmd), M_TEMP, M_NOWAIT | M_ZERO);
+		if (ifmd == NULL) {
+			error = ENOMEM;
+			goto out;
+		}
+		strlcpy(ifmd->ifmd_name, ifp->if_xname,
+		    sizeof(ifmd->ifmd_name));
 
-		ifmd.ifmd_pcount = ifp->if_pcount;
-		if_data_copy(ifp, &ifmd.ifmd_data);
+		ifmd->ifmd_pcount = ifp->if_pcount;
+		if_data_copy(ifp, &ifmd->ifmd_data);
 
-		ifmd.ifmd_flags = ifp->if_flags;
-		ifmd.ifmd_snd_len = 0;		/* XXXGL */
-		ifmd.ifmd_snd_maxlen = 0;	/* XXXGL */
-		ifmd.ifmd_snd_drops = if_get_counter(ifp, IFCOUNTER_OQDROPS);
+		ifmd->ifmd_flags = ifp->if_flags;
+		ifmd->ifmd_snd_len = 0;		/* XXXGL */
+		ifmd->ifmd_snd_maxlen = 0;	/* XXXGL */
+		ifmd->ifmd_snd_drops = if_get_counter(ifp, IFCOUNTER_OQDROPS);
 
-		error = SYSCTL_OUT(req, &ifmd, sizeof ifmd);
+		error = SYSCTL_OUT(req, ifmd, sizeof(*ifmd));
 		if (error)
 			goto out;
 		break;
@@ -140,8 +148,28 @@
 			error = EPERM;
 		free(dbuf, M_TEMP);
 		goto out;
+
+	case IFDATA_RINGINFO:
+		dlen = sizeof(*ifmd) + sizeof(struct xifrstat) * mp_ncpus *
+		    ifp->if_nrings;
+
+		ifmd = malloc(dlen, M_TEMP, M_NOWAIT | M_ZERO);
+		if (ifmd == NULL) {
+			error = ENOMEM;
+			goto out;
+		}
+		strlcpy(ifmd->ifmd_name, ifp->if_xname,
+		    sizeof(ifmd->ifmd_name));
+		if_ring_data_copy(ifp, &ifmd->ifmd_ring_data);
+
+		error = SYSCTL_OUT(req, ifmd, dlen);
+		if (error)
+			goto out;
+		break;
 	}
 out:
+	if (ifmd != NULL)
+		free(ifmd, M_TEMP);
 	if_rele(ifp);
 	return error;
 }

Modified: soc2015/btw/head/sys/net/if_mib.h
==============================================================================
--- soc2015/btw/head/sys/net/if_mib.h	Mon Jun  8 07:06:33 2015	(r286825)
+++ soc2015/btw/head/sys/net/if_mib.h	Mon Jun  8 09:57:00 2015	(r286826)
@@ -40,9 +40,16 @@
 	int	ifmd_snd_maxlen; /* maximum length of send queue */
 	int	ifmd_snd_drops;	/* number of drops in send queue */
 	int	ifmd_filler[4];	/* for future expansion */
-	struct	if_data ifmd_data; /* generic information and statistics */
+	union {
+		struct if_data ifmd_data; /* generic information and statistics */
+		struct if_ring_data ifmd_ring_data;
+	};
 };
 
+#ifdef CTASSERT
+CTASSERT(sizeof(struct if_data) >= sizeof(struct if_ring_data));
+#endif
+
 /*
  * sysctl MIB tags at the net.link.generic level
  */
@@ -55,6 +62,7 @@
 #define	IFDATA_GENERAL	1	/* generic stats for all kinds of ifaces */
 #define	IFDATA_LINKSPECIFIC	2 /* specific to the type of interface */
 #define	IFDATA_DRIVERNAME	3 /* driver name and unit */
+#define	IFDATA_RINGINFO		4 /* ring statistics */
 
 /*
  * MIB tags at the net.link.generic.system level

Modified: soc2015/btw/head/sys/net/if_var.h
==============================================================================
--- soc2015/btw/head/sys/net/if_var.h	Mon Jun  8 07:06:33 2015	(r286825)
+++ soc2015/btw/head/sys/net/if_var.h	Mon Jun  8 09:57:00 2015	(r286826)
@@ -450,6 +450,7 @@
 int	if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen);
 
 void	if_data_copy(struct ifnet *, struct if_data *);
+void	if_ring_data_copy(struct ifnet *, struct if_ring_data *);
 int	if_getmtu_family(if_t ifp, int family);
 
 int if_setupmultiaddr(if_t ifp, void *mta, int *cnt, int max);


More information about the svn-soc-all mailing list