git: 7f5539d6a664 - main - qemu: Add tools to generate useful tables from FreeBSD sources
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 22 Jun 2026 23:08:22 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=7f5539d6a66471f59de0550f4b8e3369e0b1b2c7
commit 7f5539d6a66471f59de0550f4b8e3369e0b1b2c7
Author: Warner Losh <imp@FreeBSD.org>
AuthorDate: 2026-06-22 22:17:07 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-06-22 23:06:14 +0000
qemu: Add tools to generate useful tables from FreeBSD sources
This generates a table of all the socket options with fixed types
so that programs like qemu can use those tables rather than having
to free code thigs.
Sponsored by: Netflix
---
tools/qemu/README.md | 6 +++
tools/qemu/gen_sockopt.sh | 108 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 114 insertions(+)
diff --git a/tools/qemu/README.md b/tools/qemu/README.md
new file mode 100644
index 000000000000..a1a083fc02b8
--- /dev/null
+++ b/tools/qemu/README.md
@@ -0,0 +1,6 @@
+# Scripts for use with QEMU
+
+For bsd-user in qemu, it is desireable to have tables generated from the source
+tree. This directory has the collection of those scripts that need the full
+source tree to generate. They may graduate to qemu's repo if/when all the
+supported releases have the data in a normal install.
diff --git a/tools/qemu/gen_sockopt.sh b/tools/qemu/gen_sockopt.sh
new file mode 100755
index 000000000000..3002895c8bd3
--- /dev/null
+++ b/tools/qemu/gen_sockopt.sh
@@ -0,0 +1,108 @@
+#!/bin/sh
+
+# Generate a table that describes the socket options in the tree. We assume
+# that the socket options are of the form
+# #define OPT 123 /* type,type; rest */
+# in the listed files.
+
+if [ $# -ne 1 ]; then
+ echo "usage: $(basename $0) freebsd-sys-dir"
+ exit 1
+fi
+sysdir=$1
+
+gen_table() {
+
+ unifdef -k -D__BSD_VISIBLE__=1 -U_KERNEL < ${sysdir}/$1 | \
+ sed -n '/#define[[:space:]]*.*\/\*.*;.*\*\//p' | \
+ awk -vlevel=$2 '
+BEGIN { printf("static struct sockopt_entry %s[] = {\n", tolower(level)); }
+{
+ s=$5;
+ if (match(s, ";$") == 0) {
+ s=$6;
+ }
+ gsub(";", "", s);
+ if (match(s, "^buf") == 0) {
+ s = toupper(s);
+ printf ("\t{ %-12s, %-20s, {", level, $2);
+ split(s, a, ",");
+ for (t in a) {
+ printf (" SOCKOPT_TYPE_%s,", a[t]);
+ }
+ printf(" } },\n");
+ }
+}
+END { printf("\t{ SOCK_LEVEL_NONE }\n};\n\n"); }
+'
+}
+
+gen_types() {
+
+ unifdef -k -D__BSD_VISIBLE__=1 -U_KERNEL | \
+ sed -n '/#define[[:space:]]*.*\/\*.*;.*\*\//p' | \
+ awk '
+{
+ s=$5;
+ if (match(s, ";$") == 0) {
+ s=$6;
+ }
+ gsub(";", "", s);
+ if (match(s, "^buf") == 0) {
+ s = toupper(s);
+ split(s, a, ",");
+ for (t in a) {
+ printf ("\tSOCKOPT_TYPE_%s, \n", a[t]);
+ }
+ }
+}'
+}
+
+cat <<EOF
+/* Auto-generated by $(basename $0) -- do not edit */
+#pragma once
+
+#define SOCK_LEVEL_NONE -1234
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+
+enum sockopt_type {
+ SOCKOPT_TYPE_NONE = 0,
+EOF
+cat ${sysdir}/sys/socket.h ${sysdir}/netinet/in.h ${sysdir}/netinet6/in6.h \
+ ${sysdir}/netinet/tcp.h ${sysdir}/netinet/udp.h ${sysdir}/sys/un.h | \
+ gen_types | sort -u
+cat <<EOF
+};
+
+struct sockopt_entry {
+ int level;
+ int optname;
+ enum sockopt_type type[5];
+};
+EOF
+
+gen_table sys/socket.h SOL_SOCKET
+gen_table netinet/in.h IPPROTO_IP
+gen_table netinet6/in6.h IPPROTO_IPV6
+gen_table netinet/tcp.h IPPROTO_TCP
+gen_table netinet/udp.h IPPROTO_UDP
+gen_table sys/un.h SOL_LOCAL
+
+cat <<EOF
+static struct sockopt_cache {
+ int level;
+ struct sockopt_entry *entry;
+} so_cache[] = {
+ { SOL_SOCKET, sol_socket },
+ { IPPROTO_IP, ipproto_ip },
+ { IPPROTO_IPV6, ipproto_ipv6 },
+ { IPPROTO_TCP, ipproto_tcp },
+ { IPPROTO_UDP, ipproto_udp },
+ { SOL_LOCAL, sol_local },
+};
+EOF