The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=7f5539d6a66471f59de0550f4b8e3369e0b1b2c7
commit 7f5539d6a66471f59de0550f4b8e3369e0b1b2c7 Author: Warner Losh <[email protected]> AuthorDate: 2026-06-22 22:17:07 +0000 Commit: Warner Losh <[email protected]> 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
