PERFORCE change 165379 for review

Gabor Pali pgj at FreeBSD.org
Mon Jun 29 09:19:15 UTC 2009


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

Change 165379 by pgj at petymeg-current on 2009/06/29 09:18:49

	Add "spcblist" sysctl(8) variable for diverted IP connections.

Affected files ...

.. //depot/projects/soc2009/pgj_libstat/src/sys/netinet/ip_divert.c#2 edit

Differences ...

==== //depot/projects/soc2009/pgj_libstat/src/sys/netinet/ip_divert.c#2 (text+ko) ====

@@ -54,6 +54,7 @@
 #include <sys/proc.h>
 #include <sys/protosw.h>
 #include <sys/rwlock.h>
+#include <sys/sbuf.h>
 #include <sys/signalvar.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
@@ -695,10 +696,121 @@
 	return error;
 }
 
+static int
+div_spcblist(SYSCTL_HANDLER_ARGS)
+{
+	struct inpcb_stream is;
+	struct inpcb_data id;
+	struct sbuf sbuf;
+	int error, i, buflen;
+	char *buffer;
+
+	struct inpcb *inp, **inp_list;
+	struct socket *sock;
+
+	bzero(&is, sizeof(is));
+	is.is_version = INPCB_STREAM_VERSION;
+
+	INP_INFO_RLOCK(&V_divcbinfo);
+	is.is_gencnt = V_divcbinfo.ipi_gencnt;
+	is.is_count = V_divcbinfo_ipi_count;
+	INP_INFO_RUNLOCK(&V_divcbinfo);
+
+	inp_list = malloc(is.is_count * sizeof(*inp_list), M_TEMP, M_WAITOK);
+	if (inp_list == NULL)
+		return (ENOMEM);
+
+	INP_INFO_RLOCK(&V_divcbinfo);
+	for (inp = LIST_FIRST(V_divcbinfo.ipi_listhead), i = 0;
+	    inp != NULL && i < is.is_count; inp = LIST_NEXT(inp, inp_list)) {
+		INP_RLOCK(inp);
+		if (inp->inp_gencnt <= is.is_gencnt &&
+		    cr_canseeinpcb(req->td->td_ucred) == 0)
+			inp_list[i++] = inp;
+		INP_RUNLOCK(inp);
+	}
+	INP_INFO_RUNLOCK(&V_divcbinfo);
+	is.is_count = i;
+
+	error = 0;
+	buflen = sizeof(is) + is.is_count * sizeof(id) + 1;
+	buffer = malloc(buflen, M_TEMP, M_WAITOK | M_ZERO);
+	sbuf_new(&sbuf, buffer, buflen, SBUF_FIXEDLEN);
+
+	if (sbuf_bcat(&sbuf, &is, sizeof(is)) < 0) {
+		error = ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < is.is_count; i++) {
+		inp = inp_list[i];
+		INP_RLOCK(inp);
+		if (inp->inp_gencnt <= is.is_gencnt) {
+			bzero(&id, sizeof(id));
+			id.id_gencnt = inp->inp_gencnt;
+			sock = inp->inp_socket;
+			if (sock != NULL) {
+				id.id_qlen = sock->so_qlen;
+				id.id_incqlen = sock->so_incqlen;
+				id.id_qlimit = sock->so_qlimit;
+				id.id_snd_cc = sock->so_snd.sb_cc;
+				id.id_snd_mcnt = sock->so_snd.sb_mcnt;
+				id.id_snd_ccnt = sock->so_snd.sb_ccnt;
+				id.id_snd_hiwat = sock->so_snd.sb_hiwat;
+				id.id_snd_lowat = sock->so_snd.sb_lowat;
+				id.id_snd_mbcnt = sock->so_snd.sb_mbcnt;
+				id.id_snd_mbmax = sock->so_snd.sb_mbmax;
+				id.id_rcv_cc = sock->so_rcv.sb_cc;
+				id.id_rcv_mcnt = sock->so_rcv.sb_mcnt;
+				id.id_rcv_ccnt = sock->so_rcv.sb_ccnt;
+				id.id_rcv_hiwat = sock->so_rcv.sb_hiwat;
+				id.id_rcv_lowat = sock->so_rcv.sb_lowat;
+				id.id_rcv_mbcnt = sock->so_rcv.sb_mbcnt;
+				id.id_rcv_mbmax = sock->so_rcv.sb_mbmax;
+				id.id_pcb = (u_long)sock->so_pcb;
+				id.id_protocol = sock->so_proto->pr_protocol;
+			}
+			id.id_flags = inp->inp_flags;
+			id.id_vflag = inp->inp_vflag;
+			id.id_lport = inp->inp_lport;
+			id.id_fport = inp->inp_fport;
+			if (inp->inp_vflag & INP_IPV4) {
+				bcopy(&inp->inp_laddr, &id.id_laddr,
+				    sizeof(inp->inp_laddr));
+				bcopy(&inp->inp_faddr, &id.id_faddr,
+				    sizeof(inp->inp_faddr));
+			}
+#ifdef INET6
+			else if (inp->inp_vflag & INP_IPV6) {
+				bcopy(&inp->in6p_laddr, &id.id_laddr,
+				    sizeof(inp->in6p_laddr));
+				bcopy(&inp->in6p_faddr, &id.id_faddr,
+				    sizeof(inp->in6p_faddr));
+			}
+#endif
+			if (sbuf_bcat(&sbuf, &id, sizeof(id)) < 0) {
+				INP_RUNLOCK(inp);
+				error = ENOMEM;
+				goto out;
+			}
+		}
+		INP_RUNLOCK(inp);
+	}
+	sbuf_finish(&sbuf);
+	error = SYSCTL_OUT(req, sbuf_data(&sbuf), sbuf_len(&sbuf));
+out:
+	free(inp_list, M_TEMP);
+	free(buffer, M_TEMP);
+	return (error);
+}
+
 #ifdef SYSCTL_NODE
 SYSCTL_NODE(_net_inet, IPPROTO_DIVERT, divert, CTLFLAG_RW, 0, "IPDIVERT");
 SYSCTL_PROC(_net_inet_divert, OID_AUTO, pcblist, CTLFLAG_RD, 0, 0,
 	    div_pcblist, "S,xinpcb", "List of active divert sockets");
+SYSCTL_PROC(_net_inet_divert, OID_AUTO, spcblist, CTLFLAG_RD|CTLTYPE_STRUCT,
+    0, 0, div_spcblist, "s,struct inpcb_data",
+    "List of active divert sockets (stream)");
 #endif
 
 struct pr_usrreqs div_usrreqs = {


More information about the p4-projects mailing list