From 2d300e7a1a160e005128848e7d0d2029f831437a Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Fri, 16 Mar 2018 13:25:15 +0100
Subject: [PATCH 1/3] sysctl: Add U32 handling.

---
 sbin/sysctl/sysctl.c            |  6 ++++++
 share/man/man9/Makefile         |  2 ++
 share/man/man9/sysctl.9         | 16 ++++++++++++++--
 share/man/man9/sysctl_add_oid.9 | 16 +++++++++++++++-
 sys/kern/kern_sysctl.c          | 21 +++++++++++++++++++++
 sys/sys/sysctl.h                | 11 +++++++++++
 6 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c
index 64785fabf6..0bb9e17d96 100644
--- a/sbin/sysctl/sysctl.c
+++ b/sbin/sysctl/sysctl.c
@@ -157,6 +157,7 @@ parse(const char *string)
 	size_t len;
 	int i, j;
 	void *newval = NULL;
+	uint32_t u32val;
 	int intval;
 	unsigned int uintval;
 	long longval;
@@ -258,6 +259,11 @@ parse(const char *string)
 				newval = &uquadval;
 				newsize = sizeof(uquadval);
 				break;
+			case CTLTYPE_U32:
+				u32val = (uint32_t)strtoul(newval, NULL, 0);
+				newval = &u32val;
+				newsize = sizeof(u32val);
+				break;
 			case CTLTYPE_OPAQUE:
 				if (strcmp(fmt, "T,dev_t") == 0 ||
 				    strcmp(fmt, "T,udev_t") == 0
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 66e90f8487..56ed8197e8 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -910,6 +910,7 @@ MLINKS+=sysctl.9 SYSCTL_DECL.9 \
 	sysctl.9 SYSCTL_QUAD.9 \
 	sysctl.9 SYSCTL_STRING.9 \
 	sysctl.9 SYSCTL_STRUCT.9 \
+	sysctl.9 SYSCTL_U32.9 \
 	sysctl.9 SYSCTL_UINT.9 \
 	sysctl.9 SYSCTL_ULONG.9 \
 	sysctl.9 SYSCTL_UQUAD.9
@@ -922,6 +923,7 @@ MLINKS+=sysctl_add_oid.9 SYSCTL_ADD_INT.9 \
 	sysctl_add_oid.9 SYSCTL_ADD_QUAD.9 \
 	sysctl_add_oid.9 SYSCTL_ADD_STRING.9 \
 	sysctl_add_oid.9 SYSCTL_ADD_STRUCT.9 \
+	sysctl_add_oid.9 SYSCTL_ADD_U32.9 \
 	sysctl_add_oid.9 SYSCTL_ADD_UINT.9 \
 	sysctl_add_oid.9 SYSCTL_ADD_ULONG.9 \
 	sysctl_add_oid.9 SYSCTL_ADD_UQUAD.9 \
diff --git a/share/man/man9/sysctl.9 b/share/man/man9/sysctl.9
index c2c756804c..9726ffd915 100644
--- a/share/man/man9/sysctl.9
+++ b/share/man/man9/sysctl.9
@@ -24,9 +24,8 @@
 .\" SUCH DAMAGE.
 .\"
 .\" $FreeBSD: src/share/man/man9/sysctl.9,v 1.3 2006/04/28 23:21:36 keramida Exp $
-.\" $DragonFly: src/share/man/man9/sysctl.9,v 1.6 2008/09/02 11:50:46 matthias Exp $
 .\"
-.Dd September 2, 2008
+.Dd March 16, 2018
 .Dt SYSCTL 9
 .Os
 .Sh NAME
@@ -39,6 +38,7 @@
 .Nm SYSCTL_PROC ,
 .Nm SYSCTL_STRING ,
 .Nm SYSCTL_STRUCT ,
+.Nm SYSCTL_U32 ,
 .Nm SYSCTL_UINT ,
 .Nm SYSCTL_ULONG ,
 .Nm SYSCTL_UQUAD
@@ -123,6 +123,15 @@
 .Fa "type"
 .Fa "descr"
 .Fc
+.Fo SYSCTL_U32
+.Fa "parent"
+.Fa "number"
+.Fa "name"
+.Fa "access"
+.Fa "ptr"
+.Fa "val"
+.Fa "descr"
+.Fc
 .Fo SYSCTL_UINT
 .Fa "parent"
 .Fa "nbr"
@@ -174,6 +183,7 @@ New nodes are declared using one of
 .Nm SYSCTL_PROC ,
 .Nm SYSCTL_STRING ,
 .Nm SYSCTL_STRUCT ,
+.Nm SYSCTL_U32 ,
 .Nm SYSCTL_UINT ,
 .Nm SYSCTL_ULONG ,
 and
@@ -204,6 +214,8 @@ This is an opaque data structure.
 .It Dv CTLTYPE_STRUCT
 Alias for
 .Dv CTLTYPE_OPAQUE .
+.It Dv CTLTYPE_U32
+This is a 32-bit unsigned integer.
 .It Dv CTLTYPE_UINT
 This is an unsigned integer.
 .It Dv CTLTYPE_LONG
diff --git a/share/man/man9/sysctl_add_oid.9 b/share/man/man9/sysctl_add_oid.9
index ef22dff8e6..a0417958d7 100644
--- a/share/man/man9/sysctl_add_oid.9
+++ b/share/man/man9/sysctl_add_oid.9
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD: src/share/man/man9/sysctl_add_oid.9,v 1.21 2006/04/28 10:45:27 rwatson Exp $
 .\"
-.Dd May 16, 2015
+.Dd March 16, 2018
 .Dt SYSCTL_ADD_OID 9
 .Os
 .Sh NAME
@@ -98,6 +98,16 @@
 .Fa "const char *descr"
 .Fc
 .Ft struct sysctl_oid *
+.Fo SYSCTL_ADD_U32
+.Fa "struct sysctl_ctx_list *ctx"
+.Fa "struct sysctl_oid_list *parent"
+.Fa "int number"
+.Fa "const char *name"
+.Fa "int access"
+.Fa "uint32_t *arg"
+.Fa "int len"
+.Fa "const char *descr"
+.Fc
 .Fo SYSCTL_ADD_INT
 .Fa "struct sysctl_ctx_list *ctx"
 .Fa "struct sysctl_oid_list *parent"
@@ -424,6 +434,10 @@ creates an oid of type
 to which child oids may be added.
 .It Fn SYSCTL_ADD_STRING
 creates an oid that handles a zero-terminated character string.
+.It Fn SYSCTL_ADD_U32
+creates an oid that handles a
+.Li uint16_t
+variable.
 .It Fn SYSCTL_ADD_INT
 creates an oid that handles an
 .Li int
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 66f7dd65da..0d4c3c1484 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -573,6 +573,7 @@ sysctl_sysctl_debug_dump_node(struct sysctl_oid_list *l, int i)
 			case CTLTYPE_INT:    kprintf(" Int\n"); break;
 			case CTLTYPE_STRING: kprintf(" String\n"); break;
 			case CTLTYPE_QUAD:   kprintf(" Quad\n"); break;
+			case CTLTYPE_U32:    kprintf(" uint32_t\n"); break;
 			case CTLTYPE_OPAQUE: kprintf(" Opaque/struct\n"); break;
 			default:	     kprintf("\n");
 		}
@@ -855,6 +856,26 @@ SYSCTL_NODE(_sysctl, 5, oiddescr, CTLFLAG_RD | CTLFLAG_NOLOCK,
  * Default "handler" functions.
  */
 
+/*
+ * Handle a 32-bit number, signed or unsigned.  arg1 points to it.
+ */
+
+int
+sysctl_handle_32(SYSCTL_HANDLER_ARGS)
+{
+	int error = 0;
+
+	if (!arg1)
+		return (EINVAL);
+	error = SYSCTL_OUT(req, arg1, sizeof(int32_t));
+
+	if (error || !req->newptr)
+		return (error);
+
+	error = SYSCTL_IN(req, arg1, sizeof(int32_t));
+	return (error);
+}
+
 /*
  * Handle an int, signed or unsigned.
  * Two cases:
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index edfaa31109..6fea21aa43 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -77,6 +77,7 @@ struct ctlname {
 #define	CTLTYPE_LONG	7	/* name describes a long */
 #define	CTLTYPE_ULONG	8	/* name describes an unsigned long */
 #define	CTLTYPE_UQUAD	9	/* name describes an unsigned 64-bit number */
+#define	CTLTYPE_U32	0xf	/* name describes an unsigned 32-bit number */
 
 #define	CTLFLAG_RD	0x80000000	/* Allow reads of variable */
 #define	CTLFLAG_WR	0x40000000	/* Allow writes to the variable */
@@ -157,6 +158,7 @@ struct sysctl_oid {
 #define SYSCTL_OUT(r, p, l)	(r->oldfunc)(r, p, l)
 #define SYSCTL_OUT_STR(r, p)	(r->oldfunc)(r, p, strlen(p) + 1)
 
+int sysctl_handle_32(SYSCTL_HANDLER_ARGS);
 int sysctl_handle_int(SYSCTL_HANDLER_ARGS);
 int sysctl_handle_long(SYSCTL_HANDLER_ARGS);
 int sysctl_handle_quad(SYSCTL_HANDLER_ARGS);
@@ -317,6 +319,15 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
 		CTLTYPE_ULONG|CTLFLAG_NOLOCK|(access),			\
 		ptr, 0, sysctl_handle_long, "LU", descr)
 
+/* Oid for an unsigned 32-bit int.  The pointer must be non NULL. */
+#define SYSCTL_U32(parent, nbr, name, access, ptr, val, descr)	\
+	SYSCTL_OID(parent, nbr, name, CTLTYPE_U32|(access),		\
+		ptr, val, sysctl_handle_32, "IU", descr)
+
+#define SYSCTL_ADD_U32(ctx, parent, nbr, name, access, ptr, descr)	\
+	sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_U32|(access),	\
+	ptr, 0, sysctl_handle_32, "IU", descr)
+
 /* Oid for an opaque object.  Specified by a pointer and a length. */
 #define SYSCTL_OPAQUE(parent, nbr, name, access, ptr, len, fmt, descr)	\
 	SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|(access),		\
-- 
2.17.0

