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 <gleb...@freebsd.org>
AuthorDate: 2025-03-22 22:44:20 +0000
Commit:     Gleb Smirnoff <gleb...@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

Reply via email to