Re: git: 0849f1634a70 - main - tests/netinet: add test for IP_MULTICAST_IF
Date: Mon, 24 Mar 2025 02:45:55 UTC
On 23 Mar 2025, at 8:40, Gleb Smirnoff wrote: > The branch main has been updated by glebius: > > URL: > https://cgit.FreeBSD.org/src/commit/?id=0849f1634a70099b90256ceece52a598eeb3280e > > commit 0849f1634a70099b90256ceece52a598eeb3280e > Author: Gleb Smirnoff <glebius@FreeBSD.org> > AuthorDate: 2025-03-22 22:44:20 +0000 > Commit: Gleb Smirnoff <glebius@FreeBSD.org> > CommitDate: 2025-03-22 23:39:50 +0000 > > tests/netinet: add test for IP_MULTICAST_IF > It bugs me a little that we have to jump through hoops to get a C program running in a specific jail/network setup. It’s somewhat common for that to happen, and I’m sure there’d be more cases if it were easier to do (e.g. the getaddrinfo tests you’ve been working on could be even more useful with a custom DNS server, so in their own vnet jail). I took a stab at that: diff --git a/tests/sys/netinet/multicast.sh b/tests/sys/netinet/multicast.sh index eb2b962dac70..7476daeb832a 100644 --- a/tests/sys/netinet/multicast.sh +++ b/tests/sys/netinet/multicast.sh @@ -26,6 +26,15 @@ . $(atf_get_srcdir)/../common/vnet.subr +ctest_j() +{ + jail=$1 + shift + + cc -x c - -o tmp || atf_fail "Failed to build" + jexec $jail `pwd`/tmp $@ || atf_fail "Test program failed" +} + # See regression fixed in baad45c9c12028964acd0b58096f3aaa0fb22859 atf_test_case "IP_MULTICAST_IF" "cleanup" IP_MULTICAST_IF_head() @@ -33,7 +42,6 @@ IP_MULTICAST_IF_head() atf_set descr \ 'sendto() for IP_MULTICAST_IF socket does not do routing lookup' atf_set require.user root - } IP_MULTICAST_IF_body() @@ -46,8 +54,45 @@ IP_MULTICAST_IF_body() vnet_mkjail mjail ${epair}a jexec mjail ifconfig ${epair}a up jexec mjail ifconfig ${epair}a 192.0.2.1/24 - atf_check -s exit:0 -o empty \ - jexec mjail $(atf_get_srcdir)/sendto-IP_MULTICAST_IF 192.0.2.1 + + ctest_j mjail 192.0.2.1 <<EOF +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <assert.h> +#include <err.h> + +int +main(int argc, char *argv[]) +{ + struct sockaddr_in sin = { + .sin_family = AF_INET, + .sin_len = sizeof(struct sockaddr_in), + }; + struct in_addr in; + int s, rv; + + if (argc < 2) + errx(1, "Usage: %s IPv4-address", argv[0]); + + if (inet_pton(AF_INET, argv[1], &in) != 1) + err(1, "inet_pton(%s) failed", argv[1]); + + assert((s = socket(PF_INET, SOCK_DGRAM, 0)) > 0); + assert(bind(s, (struct sockaddr *)&sin, sizeof(sin)) == 0); + assert(setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &in, sizeof(in)) + == 0); + /* RFC 6676 */ + assert(inet_pton(AF_INET, "233.252.0.1", &sin.sin_addr) == 1); + sin.sin_port = htons(6676); + rv = sendto(s, &sin, sizeof(sin), 0, + (struct sockaddr *)&sin, sizeof(sin)); + if (rv != sizeof(sin)) + err(1, "sendto failed"); + + return (0); +} +EOF } IP_MULTICAST_IF_cleanup() The downside is that we’re compiling the C test code on every run, but I expect test programs to be tiny, so that’s not too much of a cost. Does this seem useful to you too? Best regards, Kristof