From nobody Fri Feb 21 01:57:25 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4YzYD61VfBz5nmRb; Fri, 21 Feb 2025 01:57:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4YzYD569gGz3nqm; Fri, 21 Feb 2025 01:57:25 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1740103045; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=vTLOgN+6eD81oGqn8XONYDsmYtIjdpJpU4C1vfPUhYU=; b=IzsnS2n5hIzukyBLTwM9h1Uc63bA2vg0+pIF8S73oJRGcRNfbXhJVH69Soi8UYeK3oDyN6 t5EIKmXJshjJ3UcFCJ3+TH1SOdsUUDjByD9oIKvDMuhLXmLliqexbZvRJ8Nu5rJhTKL0T+ 60VX45ZQrxcYsAKdEWRyCqv8+Zv24F5ljeSRBQk3bYb36nEp2HSIe9AWSBiqtpkHx6ZSUM PPdQzJN58g9tY2YI/91GdOUhFyQrmi1ytVjWm9o6NQM899zmTe5HMy6f8owPEvy09NAnFP MGs3g4rEwVMRK0kzifmRBKPQ8eCr4kPiyHxMpGKpDzeYiSQ5r4nAfo0oBBTQWA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1740103045; a=rsa-sha256; cv=none; b=CPu4dmfqUjL95zA9GRtxbqTw5Bn+UGrKNhW7xRgcs5SRMzZhQH5YTZiR2nOWwK8oLCu/RU TDUB3Ry2mvKxGtydi6xtTOx58dS5+XzEZDCwsitHRZZxCysEHWi7MJuVk51olv8Cnm/Xtk 29nfw0oOeoCxfUvW4fGQLrTCGwpzURKJLqD4W/y2D79BRiA2zb+qACcOfCZkVJjAAwlaPR WY7UvQRn1n4vhyt7lwxzsNm1AgNozBGf4foiILrOkXreXctFz6WI++BJeK3cP74x7EuKcV XI0tAseIURr3s78uL4paPtV7LA5Brql5qBRabqLJNNESFPktI4f8Fs2jxTN7mg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1740103045; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=vTLOgN+6eD81oGqn8XONYDsmYtIjdpJpU4C1vfPUhYU=; b=IjASpn6bJlV4dx4xMyehhlgAdBkI8MKhsI/c0DybWCIFY2cQjdRy9nwcy/eASB+IrP6vHc NAZwAL5bbIOTrwUvJGTtXMQdejBSs9X2H7i0WKRtXWbu+MybRo43CsIuWu540xwL00w1dL 9/2Zytd3aYzIn861K4+PS/BOUTXFfCJtH+yoj7SACluWt8QF0BWPHp/+1x3IBDmrXZRGvF 9u3T1InEVu9qhxZCxYEpOkTQwvA+Y2PLoBhQRV4MQ4eh11IaNJCo2H0ZDuIVLvc6JECMwn C4wOf4l5CjYmB3MkGkUxVhQUQ0t2GbvK83qGWyuU0+vEZVXDEG/h7WOpJZ/oww== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4YzYD55lRsz1GDg; Fri, 21 Feb 2025 01:57:25 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 51L1vPU2067696; Fri, 21 Feb 2025 01:57:25 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 51L1vPfJ067693; Fri, 21 Feb 2025 01:57:25 GMT (envelope-from git) Date: Fri, 21 Feb 2025 01:57:25 GMT Message-Id: <202502210157.51L1vPfJ067693@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: 3ff5faee9e75 - stable/14 - tools: Add a small program to demonstrate FIB handling in bind(2) List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 3ff5faee9e753e70191bb17489600dceaee0424a Auto-Submitted: auto-generated The branch stable/14 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=3ff5faee9e753e70191bb17489600dceaee0424a commit 3ff5faee9e753e70191bb17489600dceaee0424a Author: Mark Johnston AuthorDate: 2025-02-04 16:45:21 +0000 Commit: Mark Johnston CommitDate: 2025-02-21 01:04:50 +0000 tools: Add a small program to demonstrate FIB handling in bind(2) MFC after: 2 weeks Sponsored by: Klara, Inc. Sponsored by: Stormshield (cherry picked from commit 3fa552149885766b009d95d20bdf651786fac7b7) --- tools/tools/fib_multibind/Makefile | 4 + tools/tools/fib_multibind/sink.c | 237 +++++++++++++++++++++++++++++++++++++ 2 files changed, 241 insertions(+) diff --git a/tools/tools/fib_multibind/Makefile b/tools/tools/fib_multibind/Makefile new file mode 100644 index 000000000000..1d447e788a4f --- /dev/null +++ b/tools/tools/fib_multibind/Makefile @@ -0,0 +1,4 @@ +PROG= sink +MAN= + +.include diff --git a/tools/tools/fib_multibind/sink.c b/tools/tools/fib_multibind/sink.c new file mode 100644 index 000000000000..fe93a66fe266 --- /dev/null +++ b/tools/tools/fib_multibind/sink.c @@ -0,0 +1,237 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2025 Klara, Inc. + */ + +/* + * A program to demonstrate the effects of the net.inet.tcp.bind_all_fibs and + * net.inet.udp.bind_all_fibs sysctls when they are set to 0. + * + * The program accepts TCP connections (default) or UDP datagrams (-u flag) and + * prints the FIB on which they were received, then discards them. If -a is + * specific, the program accepts data from all FIBs, otherwise it only accepts + * data from the FIB specified by the -f option. + */ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +struct sink_softc { + struct sockaddr_storage ss; + enum { SINK_TCP, SINK_UDP } type; + int nfibs; + int kq; + int *fds; +}; + +static void _Noreturn +usage(void) +{ + fprintf(stderr, + "usage: sink [-au] [-f ] [] \n"); + exit(1); +} + +static void +check_multibind(struct sink_softc *sc) +{ + const char *sysctl; + size_t len; + int error, val; + + sysctl = sc->type == SINK_TCP ? "net.inet.tcp.bind_all_fibs" : + "net.inet.udp.bind_all_fibs"; + len = sizeof(val); + error = sysctlbyname(sysctl, &val, &len, NULL, 0); + if (error != 0) + err(1, "sysctlbyname(%s)", sysctl); + if (val != 0) + errx(1, "multibind is disabled, set %s=0 to enable", sysctl); +} + +static void +addrinfo(struct sink_softc *sc, const char *addr, int port) +{ + struct addrinfo hints, *res, *res1; + char portstr[8]; + int error; + + memset(&sc->ss, 0, sizeof(sc->ss)); + + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = sc->type == SINK_TCP ? SOCK_STREAM : SOCK_DGRAM; + snprintf(portstr, sizeof(portstr), "%d", port); + error = getaddrinfo(addr, portstr, &hints, &res); + if (error != 0) + errx(1, "%s", gai_strerror(error)); + for (res1 = res; res != NULL; res = res->ai_next) { + if ((res->ai_protocol == IPPROTO_TCP && sc->type == SINK_TCP) || + (res->ai_protocol == IPPROTO_UDP && sc->type == SINK_UDP)) { + memcpy(&sc->ss, res->ai_addr, res->ai_addrlen); + break; + } + } + if (res == NULL) { + errx(1, "no %s address found for '%s'", + sc->type == SINK_TCP ? "TCP" : "UDP", addr); + } + freeaddrinfo(res1); +} + +int +main(int argc, char **argv) +{ + struct sink_softc sc; + const char *laddr; + int ch, error, fib, lport; + bool all; + + all = false; + sc.type = SINK_TCP; + fib = -1; + while ((ch = getopt(argc, argv, "af:u")) != -1) { + switch (ch) { + case 'a': + all = true; + break; + case 'f': + fib = atoi(optarg); + break; + case 'u': + sc.type = SINK_UDP; + break; + default: + usage(); + break; + } + } + argc -= optind; + argv += optind; + + if (all && fib != -1) + errx(1, "-a and -f are mutually exclusive"); + if (fib == -1) { + size_t len; + + error = sysctlbyname("net.my_fibnum", &fib, &len, NULL, 0); + if (error != 0) + err(1, "sysctlbyname(net.my_fibnum)"); + } + + if (argc == 2) { + laddr = argv[0]; + lport = atoi(argv[1]); + } else if (argc == 1) { + laddr = NULL; + lport = atoi(argv[0]); + } else { + usage(); + } + addrinfo(&sc, laddr, lport); + + check_multibind(&sc); + + sc.kq = kqueue(); + if (sc.kq == -1) + err(1, "kqueue"); + + if (all) { + size_t len; + + len = sizeof(sc.nfibs); + error = sysctlbyname("net.fibs", &sc.nfibs, &len, NULL, 0); + if (error != 0) + err(1, "sysctlbyname(net.fibs)"); + } else { + sc.nfibs = 1; + } + + sc.fds = calloc(all ? sc.nfibs : 1, sizeof(int)); + if (sc.fds == NULL) + err(1, "calloc"); + for (int i = 0; i < sc.nfibs; i++) { + struct kevent kev; + int s; + + if (sc.type == SINK_TCP) + s = socket(sc.ss.ss_family, SOCK_STREAM, 0); + else + s = socket(sc.ss.ss_family, SOCK_DGRAM, 0); + if (s == -1) + err(1, "socket"); + error = setsockopt(s, SOL_SOCKET, SO_SETFIB, + all ? &i : &fib, sizeof(int)); + if (error != 0) + err(1, "setsockopt(SO_SETFIB)"); + + error = bind(s, (struct sockaddr *)&sc.ss, sc.ss.ss_len); + if (error != 0) + err(1, "bind"); + + if (sc.type == SINK_TCP) { + error = listen(s, 5); + if (error != 0) + err(1, "listen"); + } + + EV_SET(&kev, s, EVFILT_READ, EV_ADD, 0, 0, NULL); + error = kevent(sc.kq, &kev, 1, NULL, 0, NULL); + if (error != 0) + err(1, "kevent"); + + sc.fds[i] = s; + } + + for (;;) { + struct kevent kev; + socklen_t optlen; + int n; + + n = kevent(sc.kq, NULL, 0, &kev, 1, NULL); + if (n == -1) + err(1, "kevent"); + if (n == 0) + continue; + + optlen = sizeof(fib); + error = getsockopt((int)kev.ident, SOL_SOCKET, SO_FIB, + &fib, &optlen); + if (error == -1) + err(1, "getsockopt(SO_FIB)"); + + if (sc.type == SINK_TCP) { + int cs; + + printf("accepting connection from FIB %d\n", fib); + + cs = accept((int)kev.ident, NULL, NULL); + if (cs == -1) + err(1, "accept"); + close(cs); + } else { + char buf[1024]; + ssize_t nb; + + printf("receiving datagram from FIB %d\n", fib); + + nb = recvfrom((int)kev.ident, buf, sizeof(buf), 0, + NULL, NULL); + if (nb == -1) + err(1, "recvfrom"); + } + } + + return (0); +}