summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Eremin <a.eremin@nexenta.com>2015-06-05 08:00:15 -0700
committerRichard Lowe <richlowe@richlowe.net>2015-06-09 13:29:27 -0400
commit19581f849bf7a7ff70969056873a9f08150b2e7c (patch)
tree8f068c7ccceb25628d71b2562355f8da03c43ef6
parentf68770eaa148461c70a7bafc74cf10adf8fb4add (diff)
downloadillumos-joyent-19581f849bf7a7ff70969056873a9f08150b2e7c.tar.gz
4770 soconfig(1M) needs an option to print the in-kernel socket configuration table
Reviewed by: Gordon Ross <gordon.ross@nexenta.com> Approved by: Richard Lowe <richlowe@richlowe.net>
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/soconfig.c70
-rw-r--r--usr/src/man/man1m/soconfig.1m17
-rw-r--r--usr/src/uts/common/fs/sockfs/sockparams.c81
-rw-r--r--usr/src/uts/common/fs/sockfs/socksyscalls.c6
-rw-r--r--usr/src/uts/common/sys/socketvar.h28
5 files changed, 200 insertions, 2 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/soconfig.c b/usr/src/cmd/cmd-inet/usr.sbin/soconfig.c
index 2e9ccfe4fd..a9315cb218 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/soconfig.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/soconfig.c
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
#include <ctype.h>
@@ -54,6 +55,9 @@
* soconfig <fam> <type> <protocol>
* deregisters
*
+ * soconfig -l
+ * print the in-kernel socket configuration table
+ *
* Filter Operations (Consolidation Private):
*
* soconfig -F <name> <modname> {auto [top | bottom | before:filter |
@@ -79,6 +83,8 @@ static void usage(void);
static int parse_filter_params(int argc, char **argv);
+static int print_socktable();
+
int
main(argc, argv)
int argc;
@@ -94,6 +100,11 @@ main(argc, argv)
#endif
(void) textdomain(TEXT_DOMAIN);
+ if (argc == 1 && strcmp(argv[0], "-l") == 0) {
+ ret = print_socktable();
+ exit(ret);
+ }
+
if (argc >= 2 && strcmp(argv[0], "-F") == 0) {
argc--; argv++;
ret = parse_filter_params(argc, argv);
@@ -128,7 +139,8 @@ usage(void)
"Usage: soconfig -d <dir>\n"
"\tsoconfig -f <file>\n"
"\tsoconfig <fam> <type> <protocol> <path|module>\n"
- "\tsoconfig <fam> <type> <protocol>\n"));
+ "\tsoconfig <fam> <type> <protocol>\n"
+ "\tsoconfig -l\n"));
}
/*
@@ -575,3 +587,59 @@ parse_filter_params(int argc, char **argv)
free(socktuples);
return (0);
}
+
+/*
+ * Print the in-kernel socket configuration table
+ */
+
+static int
+print_socktable()
+{
+ sockconfig_socktable_t sc_table;
+ int i;
+
+ (void) memset(&sc_table, 0, sizeof (sockconfig_socktable_t));
+
+ /* get number of entries */
+ if (_sockconfig(SOCKCONFIG_GET_SOCKTABLE, &sc_table) == -1) {
+ fprintf(stderr,
+ gettext("cannot get in-kernel socket table: %s\n"),
+ strerror(errno));
+ return (-1);
+ }
+ if (sc_table.num_of_entries == 0)
+ return (0);
+
+ sc_table.st_entries = calloc(sc_table.num_of_entries,
+ sizeof (sockconfig_socktable_entry_t));
+ if (sc_table.st_entries == NULL) {
+ fprintf(stderr, gettext("out of memory\n"));
+ return (-1);
+ }
+
+ /* get socket table entries */
+ if (_sockconfig(SOCKCONFIG_GET_SOCKTABLE, &sc_table) == -1) {
+ fprintf(stderr,
+ gettext("cannot get in-kernel socket table: %s\n"),
+ strerror(errno));
+ return (-1);
+ }
+
+ printf("%6s %4s %5s %15s %15s %6s %6s\n",
+ "FAMILY", "TYPE", "PROTO", "STRDEV", "SOCKMOD",
+ "REFS", "FLAGS");
+ for (i = 0; i < sc_table.num_of_entries; i++) {
+ printf("%6u %4u %5u %15s %15s %6u %#6x\n",
+ sc_table.st_entries[i].se_family,
+ sc_table.st_entries[i].se_type,
+ sc_table.st_entries[i].se_protocol,
+ (strcmp(sc_table.st_entries[i].se_modname,
+ "socktpi") == 0) ?
+ sc_table.st_entries[i].se_strdev : "-",
+ sc_table.st_entries[i].se_modname,
+ sc_table.st_entries[i].se_refcnt,
+ sc_table.st_entries[i].se_flags);
+ }
+ free(sc_table.st_entries);
+ return (0);
+}
diff --git a/usr/src/man/man1m/soconfig.1m b/usr/src/man/man1m/soconfig.1m
index b747bada11..6166bba627 100644
--- a/usr/src/man/man1m/soconfig.1m
+++ b/usr/src/man/man1m/soconfig.1m
@@ -1,9 +1,10 @@
'\" te
.\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved
+.\" Copyright 2015 Nexenta Systems, Inc. All rights reserved.
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH SOCONFIG 1M "Apr 12, 2014"
+.TH SOCONFIG 1M "May 21, 2015"
.SH NAME
soconfig \- configure transport providers for use by sockets
.SH SYNOPSIS
@@ -22,6 +23,11 @@ soconfig \- configure transport providers for use by sockets
\fB/sbin/soconfig\fR \fIfamily\fR \fItype\fR \fIprotocol\fR [\fImodule\fR | \fIpath\fR]
.fi
+.LP
+.nf
+\fB/sbin/soconfig\fR \fB-l\fR
+.fi
+
.SH DESCRIPTION
.sp
.LP
@@ -66,6 +72,15 @@ These fields are described in the \fBOPERANDS\fR section below.
An example of \fIfile\fR can be found in the \fBEXAMPLES\fR section below.
.RE
+.sp
+.ne 2
+.na
+\fB\fB-l\fR
+.ad
+.RS 11n
+Print the in-kernel socket configuration table.
+.RE
+
.SH OPERANDS
.sp
.LP
diff --git a/usr/src/uts/common/fs/sockfs/sockparams.c b/usr/src/uts/common/fs/sockfs/sockparams.c
index fb147f5cf6..1015decaac 100644
--- a/usr/src/uts/common/fs/sockfs/sockparams.c
+++ b/usr/src/uts/common/fs/sockfs/sockparams.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
@@ -30,6 +31,7 @@
#include <sys/sysmacros.h>
#include <sys/cmn_err.h>
#include <sys/list.h>
+#include <sys/sunddi.h>
#include <sys/stropts.h>
#include <sys/socket.h>
@@ -824,3 +826,82 @@ sockparams_new_filter(sof_entry_t *ent)
sockparams_filter_cleanup_impl(ent, &sphead);
return (error);
}
+
+/*
+ * Setup and return socket configuration table.
+ */
+int
+sockparams_copyout_socktable(uintptr_t socktable)
+{
+ STRUCT_DECL(sockconfig_socktable, st);
+ struct sockparams *sp;
+ uint_t count;
+ uint_t i = 0;
+ int ret = 0;
+ sockconfig_socktable_entry_t *se;
+
+ STRUCT_INIT(st, get_udatamodel());
+ if (ddi_copyin((void *)socktable, STRUCT_BUF(st),
+ STRUCT_SIZE(st), 0) != 0)
+ return (EFAULT);
+
+ rw_enter(&sockconf_lock, RW_READER);
+
+ count = STRUCT_FGET(st, num_of_entries);
+ /*
+ * If the output buffer is size zero, just copy out the count.
+ */
+ if (count == 0) {
+ for (sp = list_head(&sphead); sp != NULL;
+ sp = list_next(&sphead, sp)) {
+ count++;
+ }
+ STRUCT_FSET(st, num_of_entries, count);
+
+ rw_exit(&sockconf_lock);
+ if (ddi_copyout(STRUCT_BUF(st), (void *)socktable,
+ STRUCT_SIZE(st), 0) != 0)
+ return (EFAULT);
+
+ return (0);
+ }
+
+ se = kmem_alloc(count * sizeof (sockconfig_socktable_entry_t),
+ KM_SLEEP);
+ for (sp = list_head(&sphead); sp != NULL;
+ sp = list_next(&sphead, sp)) {
+ if (i >= count) {
+ /*
+ * Return if the number of entries has changed.
+ */
+ rw_exit(&sockconf_lock);
+ kmem_free(se,
+ count * sizeof (sockconfig_socktable_entry_t));
+ return (EAGAIN);
+ }
+ se[i].se_family = sp->sp_family;
+ se[i].se_type = sp->sp_type;
+ se[i].se_protocol = sp->sp_protocol;
+ (void) strncpy(se[i].se_modname, sp->sp_smod_name,
+ MODMAXNAMELEN);
+ if (sp->sp_sdev_info.sd_devpath != NULL)
+ (void) strncpy(se[i].se_strdev,
+ sp->sp_sdev_info.sd_devpath, MAXPATHLEN);
+ se[i].se_refcnt = sp->sp_refcnt;
+ se[i].se_flags = sp->sp_flags;
+ i++;
+ }
+ rw_exit(&sockconf_lock);
+ if (ddi_copyout(se, STRUCT_FGETP(st, st_entries),
+ i * sizeof (sockconfig_socktable_entry_t), 0) != 0)
+ ret = EFAULT;
+
+ STRUCT_FSET(st, num_of_entries, i);
+ kmem_free(se, count * sizeof (sockconfig_socktable_entry_t));
+
+ if (ddi_copyout(STRUCT_BUF(st), (void *)socktable,
+ STRUCT_SIZE(st), 0) != 0)
+ ret = EFAULT;
+
+ return (ret);
+}
diff --git a/usr/src/uts/common/fs/sockfs/socksyscalls.c b/usr/src/uts/common/fs/sockfs/socksyscalls.c
index a86cda937c..21f3744895 100644
--- a/usr/src/uts/common/fs/sockfs/socksyscalls.c
+++ b/usr/src/uts/common/fs/sockfs/socksyscalls.c
@@ -24,6 +24,9 @@
*/
/* Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. */
+/*
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
+ */
#include <sys/types.h>
#include <sys/t_lock.h>
@@ -1862,6 +1865,9 @@ sockconfig(int cmd, void *arg1, void *arg2, void *arg3, void *arg4)
case SOCKCONFIG_REMOVE_FILTER:
error = sockconfig_remove_filter((const char *)arg1);
break;
+ case SOCKCONFIG_GET_SOCKTABLE:
+ error = sockparams_copyout_socktable((int)(uintptr_t)arg1);
+ break;
default:
#ifdef DEBUG
cmn_err(CE_NOTE, "sockconfig: unkonwn subcommand %d", cmd);
diff --git a/usr/src/uts/common/sys/socketvar.h b/usr/src/uts/common/sys/socketvar.h
index 8221c620a8..52fa3a5822 100644
--- a/usr/src/uts/common/sys/socketvar.h
+++ b/usr/src/uts/common/sys/socketvar.h
@@ -35,6 +35,9 @@
* software developed by the University of California, Berkeley, and its
* contributors.
*/
+/*
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
+ */
#ifndef _SYS_SOCKETVAR_H
#define _SYS_SOCKETVAR_H
@@ -506,6 +509,7 @@ extern int sockparams_add(struct sockparams *);
extern int sockparams_delete(int, int, int);
extern int sockparams_new_filter(struct sof_entry *);
extern void sockparams_filter_cleanup(struct sof_entry *);
+extern int sockparams_copyout_socktable(uintptr_t);
extern void smod_init(void);
extern void smod_add(smod_info_t *);
@@ -975,6 +979,7 @@ struct sockinfo {
#define SOCKCONFIG_REMOVE_SOCK 1
#define SOCKCONFIG_ADD_FILTER 2
#define SOCKCONFIG_REMOVE_FILTER 3
+#define SOCKCONFIG_GET_SOCKTABLE 4
/*
* Data structures for configuring socket filters.
@@ -1013,6 +1018,24 @@ struct sockconfig_filter_props {
sof_socktuple_t *sfp_socktuple;
};
+/*
+ * Data structures for the in-kernel socket configuration table.
+ */
+typedef struct sockconfig_socktable_entry {
+ int se_family;
+ int se_type;
+ int se_protocol;
+ int se_refcnt;
+ int se_flags;
+ char se_modname[MODMAXNAMELEN];
+ char se_strdev[MAXPATHLEN];
+} sockconfig_socktable_entry_t;
+
+typedef struct sockconfig_socktable {
+ uint_t num_of_entries;
+ sockconfig_socktable_entry_t *st_entries;
+} sockconfig_socktable_t;
+
#ifdef _SYSCALL32
typedef struct sof_socktuple32 {
@@ -1030,6 +1053,11 @@ struct sockconfig_filter_props32 {
caddr32_t sfp_socktuple;
};
+typedef struct sockconfig_socktable32 {
+ uint_t num_of_entries;
+ caddr32_t st_entries;
+} sockconfig_socktable32_t;
+
#endif /* _SYSCALL32 */
#define SOCKMOD_PATH "socketmod" /* dir where sockmods are stored */