PERFORCE change 82865 for review

soc-anders soc-anders at FreeBSD.org
Tue Aug 30 19:15:42 GMT 2005


http://perforce.freebsd.org/chv.cgi?CH=82865

Change 82865 by soc-anders at soc-anders_gimli on 2005/08/30 19:14:54

	Created external versions of the multicast interface structs
	(vif/mif) and mcast route cache. The new structures are accessible
	via sysctl (net.inet.ip.xviftable/xmfctable and 
	net.inet6.ip6.xmif6table/xmf6ctable).
	
	Modified netstat to access mcast routing info via sysctl rather than
	kvm.

Affected files ...

.. //depot/projects/soc2005/ifcleanup/src/src/sys/netinet/ip_mroute.c#2 edit
.. //depot/projects/soc2005/ifcleanup/src/src/sys/netinet/ip_mroute.h#2 edit
.. //depot/projects/soc2005/ifcleanup/src/src/sys/netinet6/ip6_mroute.c#3 edit
.. //depot/projects/soc2005/ifcleanup/src/src/sys/netinet6/ip6_mroute.h#2 edit
.. //depot/projects/soc2005/ifcleanup/src/src/usr.bin/netstat/if.c#6 edit
.. //depot/projects/soc2005/ifcleanup/src/src/usr.bin/netstat/mroute.c#3 edit
.. //depot/projects/soc2005/ifcleanup/src/src/usr.bin/netstat/mroute6.c#3 edit

Differences ...

==== //depot/projects/soc2005/ifcleanup/src/src/sys/netinet/ip_mroute.c#2 (text+ko) ====

@@ -135,6 +135,11 @@
     &mfctable, sizeof(mfctable), "S,*mfc[MFCTBLSIZ]",
     "Multicast Forwarding Table (struct *mfc[MFCTBLSIZ], netinet/ip_mroute.h)");
 
+static int get_mfctable(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_net_inet_ip, OID_AUTO, xmfctable, CTLFLAG_RD, 0, 0,
+	    get_mfctable, "S,xmfc", "");
+
+
 static struct mtx mfc_mtx;
 #define	MFC_LOCK()	mtx_lock(&mfc_mtx)
 #define	MFC_UNLOCK()	mtx_unlock(&mfc_mtx)
@@ -150,6 +155,10 @@
     &viftable, sizeof(viftable), "S,vif[MAXVIFS]",
     "Multicast Virtual Interfaces (struct vif[MAXVIFS], netinet/ip_mroute.h)");
 
+static int get_viftable(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_net_inet_ip, OID_AUTO, xviftable, CTLFLAG_RD, 0, 0,
+	    get_viftable, "S,xvif", "");
+
 static struct mtx vif_mtx;
 #define	VIF_LOCK()	mtx_lock(&vif_mtx)
 #define	VIF_UNLOCK()	mtx_unlock(&vif_mtx)
@@ -3461,6 +3470,134 @@
     return 0;
 }
 
+static int
+get_mfctable(SYSCTL_HANDLER_ARGS)
+{
+	struct mfc *rt;
+	struct xmfc *xrt = NULL;
+	struct bw_meter *bm;
+	struct xbw_meter *xbm;
+	int i;
+	size_t mfcsz = 0;
+	char *buf = req->oldptr;
+	size_t bufsz = req->oldlen;
+
+	MFC_LOCK();
+	/*
+	 * The following is rather inefficient. Since two subsequent calls to this
+	 * function is likely to occur, maybe there should be some caching.
+	 */
+	for (i = 0; i < MFCTBLSIZ; i++) {
+		for (rt = mfctable[i]; rt != NULL; rt = rt->mfc_next) {
+			mfcsz += sizeof(*xrt);
+
+			if (buf) {
+				if (mfcsz > bufsz)
+					return ENOMEM;
+				xrt = (struct xmfc *)buf;
+				bzero(xrt, sizeof(*xrt));
+
+#define MFC_CP(x) bcopy(&rt->x, &xrt->x, sizeof(xrt->x))
+#define MFC_XCP(x,s) bcopy(rt->x, xrt->x, (s))
+#define MFC_ASSI(x) xrt->x = rt->x
+				MFC_CP(mfc_origin);
+				MFC_CP(mfc_mcastgrp);
+				MFC_ASSI(mfc_parent);
+				MFC_XCP(mfc_ttls, MAXVIFS);
+				MFC_ASSI(mfc_pkt_cnt);
+				MFC_ASSI(mfc_byte_cnt);
+				MFC_ASSI(mfc_wrong_if);
+				MFC_ASSI(mfc_expire);
+				MFC_CP(mfc_last_assert);
+				struct rtdetq *rtq;
+				for (rtq = rt->mfc_stall; rtq != NULL;
+				     rtq = rtq->next)
+					xrt->xmfc_stall_cnt++;
+				MFC_XCP(mfc_flags, MAXVIFS);
+				MFC_CP(mfc_rp);
+#undef MFC_CP
+#undef MFC_XCP
+#undef MFC_ASSI
+				buf += sizeof(*xrt);
+			}
+
+			for (bm = rt->mfc_bw_meter; bm != NULL;
+			     bm = bm->bm_mfc_next) {
+				
+				mfcsz += sizeof(*xbm);
+				if (!buf)
+					continue;
+				if (mfcsz > bufsz)
+					return ENOMEM;
+
+				xrt->xmfc_xbw_meter_cnt++;
+				xbm = (struct xbw_meter *)buf;
+				bzero(xbm, sizeof(*xbm));
+				xbm->bm_flags = bm->bm_flags;
+#define BM_CP(x) bcopy(&bm->x, &xbm->x, sizeof(xbm->x))
+				BM_CP(bm_threshold);
+				BM_CP(bm_measured);
+				BM_CP(bm_start_time);
+#undef BM_CP
+				buf += sizeof(*xbm);
+			}
+		}
+	}
+	MFC_UNLOCK();
+
+	req->oldlen = mfcsz;
+	return 0;
+}
+
+static int
+get_viftable(SYSCTL_HANDLER_ARGS)
+{
+	struct xvif *xv;
+	int vifi;
+	size_t vifsz = 0;
+	char *buf = req->oldptr;
+	size_t bufsz = req->oldlen;
+
+	VIF_LOCK();
+	for (vifi = 0; vifi < MAXVIFS; vifi++) {
+		if (viftable[vifi].v_lcl_addr.s_addr == 0)
+			continue;
+
+		vifsz += sizeof(*xv);
+		if (!buf)
+			continue;
+
+		if (vifsz > bufsz)
+			return ENOMEM;
+
+		xv = (struct xvif *)buf;
+		buf += sizeof(*xv);
+#define XV_ASSI(p) xv->p = viftable[vifi].p;
+#define XV_CP(p) bcopy(&viftable[vifi].p, &xv->p, sizeof(viftable[vifi].p))
+		
+		xv->xv_vifi = vifi;
+		XV_ASSI(v_flags);
+		XV_ASSI(v_threshold);
+		XV_ASSI(v_rate_limit);
+		XV_CP(v_lcl_addr);
+		XV_CP(v_rmt_addr);
+		xv->xv_if_index = viftable[vifi].v_ifp->if_index;
+		XV_ASSI(v_pkt_in);
+		XV_ASSI(v_pkt_out);
+		XV_ASSI(v_bytes_in);
+		XV_ASSI(v_bytes_out);
+		XV_CP(v_route);
+		XV_ASSI(v_rsvp_on);
+#undef XV_ASSI
+#undef XV_CP	
+	}
+
+	VIF_UNLOCK();
+
+	req->oldlen = vifsz;
+	return 0;
+}
+
 static moduledata_t ip_mroutemod = {
     "ip_mroute",
     ip_mroute_modevent,

==== //depot/projects/soc2005/ifcleanup/src/src/sys/netinet/ip_mroute.h#2 (text+ko) ====

@@ -267,6 +267,22 @@
     struct socket      *v_rsvpd;	/* RSVP daemon socket */
 };
 
+/* External sysctl structure */
+struct xvif {
+    vifi_t 		xv_vifi; 	/* location in viftable              */	
+    u_char		v_flags;	/* VIFF_ flags defined above         */
+    u_char		v_threshold;	/* min ttl required to forward on vif*/
+    u_int		v_rate_limit;	/* max rate			     */
+    struct in_addr	v_lcl_addr;	/* local interface address           */
+    struct in_addr	v_rmt_addr;	/* remote address (tunnels only)     */
+    u_short 		xv_if_index;	/* interface index                   */
+    u_long		v_pkt_in;	/* # pkts in on interface            */
+    u_long		v_pkt_out;	/* # pkts out on interface           */
+    u_long		v_bytes_in;	/* # bytes in on interface	     */
+    u_long		v_bytes_out;	/* # bytes out on interface	     */
+    struct route	v_route;	/* cached route if this is a tunnel */
+    u_int		v_rsvp_on;	/* RSVP listening on this vif */
+};
 /*
  * The kernel's multicast forwarding cache entry structure
  * (A field for the type of service (mfc_tos) is to be added
@@ -289,6 +305,24 @@
 	struct bw_meter	*mfc_bw_meter;		/* list of bandwidth meters  */
 };
 
+/* External sysctl structure */
+struct xmfc {
+	struct in_addr	mfc_origin;		/* IP origin of mcasts	     */
+	struct in_addr  mfc_mcastgrp;		/* multicast group associated*/
+	vifi_t		mfc_parent;		/* incoming vif              */
+	u_char		mfc_ttls[MAXVIFS];	/* forwarding ttls on vifs   */
+	u_long		mfc_pkt_cnt;		/* pkt count for src-grp     */
+	u_long		mfc_byte_cnt;		/* byte count for src-grp    */
+	u_long		mfc_wrong_if;		/* wrong if for src-grp	     */
+	int		mfc_expire;		/* time to clean entry up    */
+	struct timeval	mfc_last_assert;	/* last time I sent an assert*/
+	u_short		xmfc_stall_cnt;		/* # of packets awaiting mfc */
+	uint8_t		mfc_flags[MAXVIFS];	/* the MRT_MFC_FLAGS_* flags */
+	struct in_addr	mfc_rp;		        /* the RP address	     */
+	u_short 	xmfc_xbw_meter_cnt;	/* number of bandwidth meters 
+                                                   following the struct      */
+};
+
 /*
  * Struct used to communicate from kernel to multicast router
  * note the convenient similarity to an IP packet
@@ -371,6 +405,14 @@
 	struct timeval	bm_start_time;		/* abs. time		     */
 };
 
+/* External sysctl structure */
+struct xbw_meter {
+	uint32_t bm_flags; 
+	struct bw_data bm_threshold;
+	struct bw_data bm_measured;
+	struct timeval bm_start_time;
+};
+
 #ifdef _KERNEL
 
 struct sockopt;

==== //depot/projects/soc2005/ifcleanup/src/src/sys/netinet6/ip6_mroute.c#3 (text+ko) ====

@@ -137,14 +137,27 @@
 struct socket  *ip6_mrouter = NULL;
 int		ip6_mrouter_ver = 0;
 int		ip6_mrtproto = IPPROTO_PIM;    /* for netstat only */
+SYSCTL_DECL(_net_inet6_ip6);
 struct mrt6stat	mrt6stat;
+SYSCTL_STRUCT(_net_inet6_ip6, OID_AUTO, mrt6stat, CTLFLAG_RD,
+	      &mrt6stat, mrt6stat, 
+	      "Multicast Routing Statistics (struct mrt6stat, netinet6/ip6_mroute.h)");
 
 #define NO_RTE_FOUND 	0x1
 #define RTE_FOUND	0x2
 
 struct mf6c	*mf6ctable[MF6CTBLSIZ];
+static int get_xmf6ctable(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_net_inet6_ip6, OID_AUTO, xmf6ctable, CTLFLAG_RD, 0, 0,
+	    get_xmf6ctable, "S,xmf6c", "");
+
 u_char		n6expire[MF6CTBLSIZ];
+
 static struct mif6 mif6table[MAXMIFS];
+static int get_xmif6table(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_net_inet6_ip6, OID_AUTO, xmif6table, CTLFLAG_RD, 0, 0,
+	    get_xmif6table, "S,xmif", "");
+
 #ifdef MRT6DEBUG
 u_int		mrt6debug = 0;	  /* debug level 	*/
 #define DEBUG_MFC	0x02
@@ -1874,3 +1887,96 @@
 	rip6_input(&m, offp, proto);
 	return (IPPROTO_DONE);
 }
+
+static int 
+get_xmif6table(SYSCTL_HANDLER_ARGS)
+{
+	struct xmif6 *xmif;
+	struct mif6 *mif;
+	int mifi;
+	size_t xmifsz = 0;
+	size_t bufsz = req->oldlen;
+	char *buf = req->oldptr;
+
+	for (mifi = 0, mif = mif6table; mifi < MAXMIFS; mifi++, mif++) {
+		if (mif->m6_ifp == NULL)
+			continue;
+
+		xmifsz += sizeof(*xmif);
+		if (!buf)
+			continue;
+
+		if (xmifsz > bufsz)
+			return ENOMEM;
+
+		xmif = (struct xmif6 *)buf;
+		buf += sizeof(*xmif);
+		
+#define XMIF_CP(x) bcopy(&mif->x, &xmif->x, sizeof(mif->x))
+#define XMIF_ASSI(x) xmif->x = mif->x
+		xmif->xm6_mifi = mifi;
+		XMIF_ASSI(m6_flags);
+		XMIF_ASSI(m6_rate_limit);
+		XMIF_CP(m6_lcl_addr);
+		xmif->xm6_if_index = mif->m6_ifp->if_index;
+		XMIF_ASSI(m6_pkt_in);
+		XMIF_ASSI(m6_pkt_out);
+		XMIF_ASSI(m6_bytes_in);
+		XMIF_ASSI(m6_bytes_out);
+		XMIF_CP(m6_route);
+#undef XMIF_CP
+#undef XMIF_ASSI
+
+	}
+	req->oldlen = xmifsz;
+	return 0;
+}
+
+static int
+get_xmf6ctable(SYSCTL_HANDLER_ARGS)
+{
+	struct xmf6c *xmf;
+	struct mf6c *mf;
+	struct rtdetq *rt;
+	char *buf = req->oldptr;
+	size_t bufsz = req->oldlen;
+	size_t xmfsz = 0;
+	int i;
+
+	for (i = 0; i < MF6CTBLSIZ; i++) {
+		mf = mf6ctable[i];
+		while (mf) {
+			xmfsz += sizeof(*xmf);
+			
+			if (buf) {
+				if (xmfsz > bufsz)
+					return ENOMEM;
+				xmf = (struct xmf6c *)buf;
+				buf += sizeof(*xmf);
+
+#define XMF_CP(x) bcopy(&mf->x, &xmf->x, sizeof(mf->x))
+#define XMF_ASSI(x) xmf->x = mf->x
+				XMF_CP(mf6c_origin);
+				XMF_CP(mf6c_mcastgrp);
+				XMF_ASSI(mf6c_parent);
+				XMF_CP(mf6c_ifset);
+				XMF_ASSI(mf6c_pkt_cnt);
+				XMF_ASSI(mf6c_byte_cnt);
+				XMF_ASSI(mf6c_wrong_if);
+				XMF_ASSI(mf6c_expire);
+				XMF_CP(mf6c_last_assert);
+				xmf->xmf6c_stall_cnt = 0;
+
+				for (rt = mf->mf6c_stall; rt != NULL; rt = rt->next)
+					xmf->xmf6c_stall_cnt++;
+#undef XMF_ASSI
+#undef XMF_CP
+
+			}
+			mf = mf->mf6c_next;
+		}
+	}
+
+	req->oldlen = xmfsz;
+	return 0;
+}

==== //depot/projects/soc2005/ifcleanup/src/src/sys/netinet6/ip6_mroute.h#2 (text+ko) ====

@@ -225,6 +225,20 @@
 #endif
 };
 
+/* External sysctl structure */
+struct xmif6 {
+	mifi_t xm6_mifi; /* location in mif6table */
+        u_char   	m6_flags;     	/* MIFF_ flags defined above         */
+	u_int      	m6_rate_limit; 	/* max rate			     */
+	struct in6_addr	m6_lcl_addr;   	/* local interface address           */
+	u_short  xm6_if_index;     	/* interface index                   */
+	u_quad_t	m6_pkt_in;	/* # pkts in on interface            */
+	u_quad_t	m6_pkt_out;	/* # pkts out on interface           */
+	u_quad_t	m6_bytes_in;	/* # bytes in on interface	     */
+	u_quad_t	m6_bytes_out;	/* # bytes out on interface	     */
+	struct route_in6 m6_route;/* cached route if this is a tunnel */
+};
+
 /*
  * The kernel's multicast forwarding cache entry structure
  */
@@ -243,6 +257,21 @@
 	struct mf6c    *mf6c_next;		/* hash table linkage */
 };
 
+/* External sysctl structure */
+struct xmf6c {
+	struct sockaddr_in6  mf6c_origin;	/* IPv6 origin of mcasts     */
+	struct sockaddr_in6  mf6c_mcastgrp;	/* multicast group associated*/
+	mifi_t	    	 mf6c_parent; 		/* incoming IF               */
+	struct if_set	 mf6c_ifset;		/* set of outgoing IFs */
+
+	u_quad_t    	mf6c_pkt_cnt;		/* pkt count for src-grp     */
+	u_quad_t    	mf6c_byte_cnt;		/* byte count for src-grp    */
+	u_quad_t    	mf6c_wrong_if;		/* wrong if for src-grp	     */
+	int	    	mf6c_expire;		/* time to clean entry up    */
+	struct timeval  mf6c_last_assert;	/* last time I sent an assert*/
+	long int xmf6c_stall_cnt; /* # pkts waiting for route */
+};
+
 #define MF6C_INCOMPLETE_PARENT ((mifi_t)-1)
 
 /*

==== //depot/projects/soc2005/ifcleanup/src/src/usr.bin/netstat/if.c#6 (text+ko) ====

@@ -62,12 +62,8 @@
 #include <unistd.h>
 #include <err.h>
 
-#define IFCLEANUP
-
-#ifdef IFCLEANUP
 #include <net/if_mib.h>
 #include <net/route.h>
-#endif
 
 #include "netstat.h"
 

==== //depot/projects/soc2005/ifcleanup/src/src/usr.bin/netstat/mroute.c#3 (text+ko) ====

@@ -66,42 +66,41 @@
 #include <stdlib.h>
 #include "netstat.h"
 
-static void print_bw_meter(struct bw_meter *bw_meter, int *banner_printed);
+static void print_xbw_meter(struct xbw_meter *xbw_meter, int *banner_printed);
 
 void
 mroutepr(u_long mfcaddr, u_long vifaddr)
 {
-#ifdef IFCLEANUP
-	struct mfc *mfctable[MFCTBLSIZ];
-	struct vif viftable[MAXVIFS];
-	struct mfc mfc, *m;
-	struct vif *v;
-	vifi_t vifi;
+	struct xmfc *xmfc;
+	struct xvif *xv;
 	int i;
 	int banner_printed;
 	int saved_numeric_addr;
 	vifi_t maxvif = 0;
 	size_t len;
+	char *buf, *cur, *end;
 
-	len = sizeof(viftable);
-	if (sysctlbyname("net.inet.ip.viftable", viftable, &len, NULL, 0) < 0) {
+	len = 0;
+	if (sysctlbyname("net.inet.ip.xviftable", NULL, &len, NULL, 0) < 0) {
 		printf("No IPv4 multicast routing compiled into this system.\n");
 	}
-
-	len = sizeof(mfctable);
-	if (sysctlbyname("net.inet.ip.mfctable", mfctable, &len, NULL, 0) < 0) {
-		printf("No IPv4 multicast routing compiled into this system.\n");
+	if (len > 0) {
+		if ((buf = malloc(len)) == NULL)
+			err(1, "malloc");
+		if (sysctlbyname("net.inet.ip.xviftable", buf, &len, NULL, 0) < 0) {
+			free(buf);
+			return;
+		}
 	}
-
 	saved_numeric_addr = numeric_addr;
 	numeric_addr = 1;
 
 	banner_printed = 0;
-	for (vifi = 0, v = viftable; vifi < MAXVIFS; ++vifi, ++v) {
-		if (v->v_lcl_addr.s_addr == 0)
-			continue;
+
+	len = len/sizeof(*xv);
+	for (i = 0, xv = (struct xvif *)buf; i < len; ++i, ++xv) {
 
-		maxvif = vifi;
+		maxvif = xv->xv_vifi;
 		if (!banner_printed) {
 			printf("\nVirtual Interface Table\n"
 			       " Vif   Thresh   Rate   Local-Address   "
@@ -111,72 +110,82 @@
 
 		printf(" %2u    %6u   %4d   %-15.15s",
 					/* opposite math of add_vif() */
-		    vifi, v->v_threshold, v->v_rate_limit * 1000 / 1024, 
-		    routename(v->v_lcl_addr.s_addr));
-		printf(" %-15.15s", (v->v_flags & VIFF_TUNNEL) ?
-		    routename(v->v_rmt_addr.s_addr) : "");
+		    xv->xv_vifi, xv->v_threshold, xv->v_rate_limit * 1000 / 1024, 
+		    routename(xv->v_lcl_addr.s_addr));
+		printf(" %-15.15s", (xv->v_flags & VIFF_TUNNEL) ?
+		    routename(xv->v_rmt_addr.s_addr) : "");
 
-		printf(" %9lu  %9lu\n", v->v_pkt_in, v->v_pkt_out);
+		printf(" %9lu  %9lu\n", xv->v_pkt_in, xv->v_pkt_out);
 	}
 	if (!banner_printed)
 		printf("\nVirtual Interface Table is empty\n");
+	else
+		free(buf);
+	banner_printed = 0;
 
-	banner_printed = 0;
-	for (i = 0; i < MFCTBLSIZ; ++i) {
-		m = mfctable[i];
-		while(m) {
-			kread((u_long)m, (char *)&mfc, sizeof mfc);
+	len = 0;
+	if (sysctlbyname("net.inet.ip.xmfctable", NULL, &len, NULL, 0) < 0) {
+		printf("No IPv4 multicast routing compiled into this system.\n");
+	}
+	if (len > 0) {
+		if ((buf = malloc(len)) == NULL) 
+			err(1, "malloc");
+		if (sysctlbyname("net.inet.ip.xmfctable", buf, &len, NULL, 0) < 0) {
+			free(buf);
+			return;
+		}
+	}
+	
+	cur = buf;
+	end = cur + len;
+	while (cur < end) {
+		xmfc = (struct xmfc *)cur;
+		cur += sizeof(*xmfc);
 
-			if (!banner_printed) {
-				printf("\nIPv4 Multicast Forwarding Cache\n"
-				       " Origin          Group            "
-				       " Packets In-Vif  Out-Vifs:Ttls\n");
-				banner_printed = 1;
-			}
+		if (!banner_printed) {
+			printf("\nIPv4 Multicast Forwarding Cache\n"
+			       " Origin          Group            "
+			       " Packets In-Vif  Out-Vifs:Ttls\n");
+			banner_printed = 1;
+		}
 
-			printf(" %-15.15s", routename(mfc.mfc_origin.s_addr));
-			printf(" %-15.15s", routename(mfc.mfc_mcastgrp.s_addr));
-			printf(" %9lu", mfc.mfc_pkt_cnt);
-			printf("  %3d   ", mfc.mfc_parent);
-			for (vifi = 0; vifi <= maxvif; vifi++) {
-				if (mfc.mfc_ttls[vifi] > 0)
-					printf(" %u:%u", vifi, 
-					       mfc.mfc_ttls[vifi]);
-			}
-			printf("\n");
+		printf(" %-15.15s", routename(xmfc->mfc_origin.s_addr));
+		printf(" %-15.15s", routename(xmfc->mfc_mcastgrp.s_addr));
+		printf(" %9lu", xmfc->mfc_pkt_cnt);
+		printf("  %3d   ", xmfc->mfc_parent);
+		for (i = 0; i <= maxvif; i++) {
+			if (xmfc->mfc_ttls[i] > 0)
+				printf(" %u:%u", i, 
+				       xmfc->mfc_ttls[i]);
+		}
+		printf("\n");
 
-			/* Print the bw meter information */
-			{
-				struct bw_meter bw_meter, *bwm;
-				int banner_printed2 = 0;
-				
-				bwm = mfc.mfc_bw_meter;
-				while (bwm) {
-				    kread((u_long)bwm, (char *)&bw_meter,
-						sizeof bw_meter);
-				    print_bw_meter(&bw_meter,
-						&banner_printed2);
-				    bwm = bw_meter.bm_mfc_next;
-				}
+		/* Print the bw meter information */
+		for (i = 0; i < xmfc->xmfc_xbw_meter_cnt; i++) {
+			struct xbw_meter *xbwm = (struct xbw_meter *)cur;
+			int banner_printed2 = 0;
+			cur += sizeof(*xbwm);
+	       	
+			print_xbw_meter(xbwm,
+					&banner_printed2);
+		}
 #if 0	/* Don't ever print it? */
-				if (! banner_printed2)
-				    printf("\n  No Bandwidth Meters\n");
+		if (! banner_printed2)
+			printf("\n  No Bandwidth Meters\n");
 #endif
-			}
+	}
 
-			m = mfc.mfc_next;
-		}
-	}
 	if (!banner_printed)
 		printf("\nMulticast Routing Table is empty\n");
+	else
+		free(buf);
 
 	printf("\n");
 	numeric_addr = saved_numeric_addr;
-#endif /* IFCLEANUP */
 }
 
 static void
-print_bw_meter(struct bw_meter *bw_meter, int *banner_printed)
+print_xbw_meter(struct xbw_meter *xbw_meter, int *banner_printed)
 {
 	char s0[256], s1[256], s2[256], s3[256];
 	struct timeval now, end, delta;
@@ -194,46 +203,46 @@
 	}
 
 	/* The measured values */
-	if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS)
-		sprintf(s1, "%llu", bw_meter->bm_measured.b_packets);
+	if (xbw_meter->bm_flags & BW_METER_UNIT_PACKETS)
+		sprintf(s1, "%llu", xbw_meter->bm_measured.b_packets);
 	else
 		sprintf(s1, "?");
-	if (bw_meter->bm_flags & BW_METER_UNIT_BYTES)
-		sprintf(s2, "%llu", bw_meter->bm_measured.b_bytes);
+	if (xbw_meter->bm_flags & BW_METER_UNIT_BYTES)
+		sprintf(s2, "%llu", xbw_meter->bm_measured.b_bytes);
 	else
 		sprintf(s2, "?");
 	sprintf(s0, "%lu.%lu|%s|%s",
-		bw_meter->bm_start_time.tv_sec,
-		bw_meter->bm_start_time.tv_usec,
+		xbw_meter->bm_start_time.tv_sec,
+		xbw_meter->bm_start_time.tv_usec,
 		s1, s2);
 	printf("  %-30s", s0);
 
 	/* The type of entry */
 	sprintf(s0, "%s", "?");
-	if (bw_meter->bm_flags & BW_METER_GEQ)
+	if (xbw_meter->bm_flags & BW_METER_GEQ)
 		sprintf(s0, "%s", ">=");
-	else if (bw_meter->bm_flags & BW_METER_LEQ)
+	else if (xbw_meter->bm_flags & BW_METER_LEQ)
 		sprintf(s0, "%s", "<=");
 	printf("  %-3s", s0);
 
 	/* The threshold values */
-	if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS)
-		sprintf(s1, "%llu", bw_meter->bm_threshold.b_packets);
+	if (xbw_meter->bm_flags & BW_METER_UNIT_PACKETS)
+		sprintf(s1, "%llu", xbw_meter->bm_threshold.b_packets);
 	else
 		sprintf(s1, "?");
-	if (bw_meter->bm_flags & BW_METER_UNIT_BYTES)
-		sprintf(s2, "%llu", bw_meter->bm_threshold.b_bytes);
+	if (xbw_meter->bm_flags & BW_METER_UNIT_BYTES)
+		sprintf(s2, "%llu", xbw_meter->bm_threshold.b_bytes);
 	else
 		sprintf(s2, "?");
 	sprintf(s0, "%lu.%lu|%s|%s",
-		bw_meter->bm_threshold.b_time.tv_sec,
-		bw_meter->bm_threshold.b_time.tv_usec,
+		xbw_meter->bm_threshold.b_time.tv_sec,
+		xbw_meter->bm_threshold.b_time.tv_usec,
 		s1, s2);
 	printf("  %-30s", s0);
 
 	/* Remaining time */
-	timeradd(&bw_meter->bm_start_time,
-		 &bw_meter->bm_threshold.b_time, &end);
+	timeradd(&xbw_meter->bm_start_time,
+		 &xbw_meter->bm_threshold.b_time, &end);
 	if (timercmp(&now, &end, <=)) {
 		timersub(&end, &now, &delta);
 		sprintf(s3, "%lu.%lu", delta.tv_sec, delta.tv_usec);

==== //depot/projects/soc2005/ifcleanup/src/src/usr.bin/netstat/mroute6.c#3 (text+ko) ====

@@ -75,7 +75,10 @@
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/protosw.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
 
+
 #include <net/if.h>
 #include <net/if_var.h>
 #include <net/route.h>
@@ -83,6 +86,9 @@
 #include <netinet/in.h>
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <err.h>
+
 
 #define	KERNEL 1
 #include <netinet6/ip6_mroute.h>
@@ -96,39 +102,38 @@
 void
 mroute6pr(u_long mfcaddr, u_long mifaddr)
 {
-#ifdef IFCLEANUP
-	struct mf6c *mf6ctable[MF6CTBLSIZ], *mfcp;
-	struct mif6 mif6table[MAXMIFS];
-	struct mf6c mfc;
-	struct rtdetq rte, *rtep;
-	struct mif6 *mifp;
+	char *buf;
+	struct xmif6 *xmifp;
+	struct xmf6c *xmfc;
 	mifi_t mifi;
 	int i;
 	int banner_printed;
 	int saved_numeric_addr;
 	mifi_t maxmif = 0;
-	long int waitings;
+	size_t len = 0;
 
-	if (mfcaddr == 0 || mifaddr == 0) {
+	if (sysctlbyname("net.inet6.ip6.xmif6table", 0, &len, NULL, 0) < 0) {
 		printf("No IPv6 multicast routing compiled into this"
 		       " system.\n");
 		return;
 	}
+	if (len > 0) {
+		if ((buf = malloc(len)) == NULL)
+			err(1, "malloc");
+		if (sysctlbyname("net.inet6.ip6.xmif6table", buf, 
+				 &len, NULL, 0) < 0)
+			return;
+	}
 
 	saved_numeric_addr = numeric_addr;
 	numeric_addr = 1;
 
-	kread(mifaddr, (char *)&mif6table, sizeof(mif6table));
 	banner_printed = 0;
-	for (mifi = 0, mifp = mif6table; mifi < MAXMIFS; ++mifi, ++mifp) {
-		struct ifnet ifnet;
+	len = len/sizeof(*xmifp);
+	for (i = 0, xmifp = (struct xmif6 *)buf; i < len; ++i, ++xmifp) {
 		char ifname[IFNAMSIZ];
 
-		if (mifp->m6_ifp == NULL)
-			continue;
-
-		kread((u_long)mifp->m6_ifp, (char *)&ifnet, sizeof(ifnet));
-		maxmif = mifi;
+		maxmif = xmifp->xm6_mifi;
 		if (!banner_printed) {
 			printf("\nIPv6 Multicast Interface Table\n"
 			       " Mif   Rate   PhyIF   "
@@ -137,78 +142,77 @@
 		}
 
 		printf("  %2u   %4d",
-		       mifi, mifp->m6_rate_limit);
-		printf("   %5s", (mifp->m6_flags & MIFF_REGISTER) ?
-		       "reg0" : if_indextoname(ifnet.if_index, ifname));
+		       xmifp->xm6_mifi, xmifp->m6_rate_limit);
+		printf("   %5s", (xmifp->m6_flags & MIFF_REGISTER) ?
+		       "reg0" : if_indextoname(xmifp->xm6_if_index, ifname));
 
-		printf(" %9llu  %9llu\n", (unsigned long long)mifp->m6_pkt_in,
-		    (unsigned long long)mifp->m6_pkt_out);
+		printf(" %9llu  %9llu\n", (unsigned long long)xmifp->m6_pkt_in,
+		    (unsigned long long)xmifp->m6_pkt_out);
 	}
 	if (!banner_printed)
 		printf("\nIPv6 Multicast Interface Table is empty\n");
+	else
+		free(buf);
 
-	kread(mfcaddr, (char *)&mf6ctable, sizeof(mf6ctable));
+	if (sysctlbyname("net.inet6.ip6.xmf6ctable", NULL, &len, NULL, 0) < 0)
+		return;
+	if (len > 0) {
+		if ((buf = malloc(len)) == NULL)
+			err(1, "malloc");
+		if (sysctlbyname("net.inet6.ip6.xmf6ctable", buf, &len, NULL, 0) < 0)
+			return;
+	}
 	banner_printed = 0;
-	for (i = 0; i < MF6CTBLSIZ; ++i) {
-		mfcp = mf6ctable[i];
-		while(mfcp) {
-			kread((u_long)mfcp, (char *)&mfc, sizeof(mfc));
-			if (!banner_printed) {
-				printf ("\nIPv6 Multicast Forwarding Cache\n");
-				printf(" %-*.*s %-*.*s %s",
-				       WID_ORG, WID_ORG, "Origin",
-				       WID_GRP, WID_GRP, "Group",
-				       "  Packets Waits In-Mif  Out-Mifs\n");
-				banner_printed = 1;
-			}
+	len = len/sizeof(*xmfc);
+	for (i = 0, xmfc = (struct xmf6c *)buf; i < len; ++i, ++xmfc) {
+		if (!banner_printed) {
+			printf ("\nIPv6 Multicast Forwarding Cache\n");
+			printf(" %-*.*s %-*.*s %s",
+			       WID_ORG, WID_ORG, "Origin",
+			       WID_GRP, WID_GRP, "Group",
+			       "  Packets Waits In-Mif  Out-Mifs\n");
+			banner_printed = 1;
+		}
 
-			printf(" %-*.*s", WID_ORG, WID_ORG,
-			       routename6(&mfc.mf6c_origin));
-			printf(" %-*.*s", WID_GRP, WID_GRP,
-			       routename6(&mfc.mf6c_mcastgrp));
-			printf(" %9llu", (unsigned long long)mfc.mf6c_pkt_cnt);
+		printf(" %-*.*s", WID_ORG, WID_ORG,
+		       routename6(&xmfc->mf6c_origin));
+		printf(" %-*.*s", WID_GRP, WID_GRP,
+		       routename6(&xmfc->mf6c_mcastgrp));
+		printf(" %9llu", (unsigned long long)xmfc->mf6c_pkt_cnt);
 
-			for (waitings = 0, rtep = mfc.mf6c_stall; rtep; ) {
-				waitings++;
-				kread((u_long)rtep, (char *)&rte, sizeof(rte));
-				rtep = rte.next;
-			}
-			printf("   %3ld", waitings);
+		printf("   %3ld", xmfc->xmf6c_stall_cnt);
 
-			if (mfc.mf6c_parent == MF6C_INCOMPLETE_PARENT)
-				printf(" ---   ");
-			else
-				printf("  %3d   ", mfc.mf6c_parent);
-			for (mifi = 0; mifi <= maxmif; mifi++) {
-				if (IF_ISSET(mifi, &mfc.mf6c_ifset))
-					printf(" %u", mifi);
-			}
-			printf("\n");
-
-			mfcp = mfc.mf6c_next;
+		if (xmfc->mf6c_parent == MF6C_INCOMPLETE_PARENT)
+			printf(" ---   ");
+		else
+			printf("  %3d   ", xmfc->mf6c_parent);
+		for (mifi = 0; mifi <= maxmif; mifi++) {
+			if (IF_ISSET(mifi, &xmfc->mf6c_ifset))
+				printf(" %u", mifi);
 		}
+		printf("\n");
 	}
 	if (!banner_printed)
 		printf("\nIPv6 Multicast Routing Table is empty\n");
+	else
+		free(buf);
 
 	printf("\n");
 	numeric_addr = saved_numeric_addr;
-#endif /* IFCLEANUP */
 }
 
 void
 mrt6_stats(u_long mstaddr)
 {
-#ifdef IFCLEANUP
 	struct mrt6stat mrtstat;
+	size_t len = sizeof(mrtstat);
 
-	if (mstaddr == 0) {
+	if (sysctlbyname("net.inet6.ip6.mrt6stat", &mrtstat, &len, NULL, 0) < 0) {
 		printf("No IPv6 multicast routing compiled into this"
 		       " system.\n");
 		return;
 	}
 
-	kread(mstaddr, (char *)&mrtstat, sizeof(mrtstat));
 	printf("IPv6 multicast forwarding:\n");
 
 #define	p(f, m) if (mrtstat.f || sflag <= 1) \
@@ -234,6 +238,5 @@
 
 #undef	p2
 #undef	p
-#endif /* IFCLEANUP */
 }
 #endif /*INET6*/


More information about the p4-projects mailing list