This patch lays the groundwork for testing IPv4 and IPv6 sockaddr hooks
and their interaction with both socket syscalls and kernel functions
(e.g. kernel_connect, kernel_bind, etc.) and moves the test cases from
the old-style bpf/test_sock_addr.c self test into the sock_addr
prog_test.

Signed-off-by: Jordan Rife <[email protected]>
---
 .../selftests/bpf/prog_tests/sock_addr.c      | 391 ++++++++++++------
 1 file changed, 269 insertions(+), 122 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/sock_addr.c 
b/tools/testing/selftests/bpf/prog_tests/sock_addr.c
index 5fd6177189915..92879b971a098 100644
--- a/tools/testing/selftests/bpf/prog_tests/sock_addr.c
+++ b/tools/testing/selftests/bpf/prog_tests/sock_addr.c
@@ -3,16 +3,43 @@
 
 #include "test_progs.h"
 
+#include "bind4_prog.skel.h"
+#include "bind6_prog.skel.h"
 #include "connect_unix_prog.skel.h"
+#include "connect4_prog.skel.h"
+#include "connect6_prog.skel.h"
+#include "sendmsg4_prog.skel.h"
+#include "sendmsg6_prog.skel.h"
+#include "recvmsg4_prog.skel.h"
+#include "recvmsg6_prog.skel.h"
 #include "sendmsg_unix_prog.skel.h"
 #include "recvmsg_unix_prog.skel.h"
 #include "getsockname_unix_prog.skel.h"
 #include "getpeername_unix_prog.skel.h"
 #include "network_helpers.h"
 
+#define TEST_IF_PREFIX          "test_sock_addr"
+#define TEST_IPV4               "127.0.0.4"
+#define TEST_IPV6               "::6"
+
+#define SERV4_IP                "192.168.1.254"
+#define SERV4_REWRITE_IP        "127.0.0.1"
+#define SRC4_IP                 "172.16.0.1"
+#define SRC4_REWRITE_IP         TEST_IPV4
+#define SERV4_PORT              4040
+#define SERV4_REWRITE_PORT      4444
+
+#define SERV6_IP                "face:b00c:1234:5678::abcd"
+#define SERV6_REWRITE_IP        "::1"
+#define SERV6_V4MAPPED_IP       "::ffff:192.168.0.4"
+#define SRC6_IP                 "::1"
+#define SRC6_REWRITE_IP         TEST_IPV6
+#define SERV6_PORT              6060
+#define SERV6_REWRITE_PORT      6666
+
 #define SERVUN_ADDRESS         "bpf_cgroup_unix_test"
 #define SERVUN_REWRITE_ADDRESS "bpf_cgroup_unix_test_rewrite"
-#define SRCUN_ADDRESS         "bpf_cgroup_unix_test_src"
+#define SRCUN_ADDRESS          "bpf_cgroup_unix_test_src"
 
 enum sock_addr_test_type {
        SOCK_ADDR_TEST_BIND,
@@ -43,130 +70,148 @@ struct sock_addr_test {
        const char *expected_src_addr;
 };
 
-static void *connect_unix_prog_load(int cgroup_fd)
-{
-       struct connect_unix_prog *skel;
-
-       skel = connect_unix_prog__open_and_load();
-       if (!ASSERT_OK_PTR(skel, "skel_open"))
-               goto cleanup;
-
-       skel->links.connect_unix_prog = bpf_program__attach_cgroup(
-               skel->progs.connect_unix_prog, cgroup_fd);
-       if (!ASSERT_OK_PTR(skel->links.connect_unix_prog, "prog_attach"))
-               goto cleanup;
-
-       return skel;
-cleanup:
-       connect_unix_prog__destroy(skel);
-       return NULL;
-}
-
-static void connect_unix_prog_destroy(void *skel)
-{
-       connect_unix_prog__destroy(skel);
-}
-
-static void *sendmsg_unix_prog_load(int cgroup_fd)
-{
-       struct sendmsg_unix_prog *skel;
-
-       skel = sendmsg_unix_prog__open_and_load();
-       if (!ASSERT_OK_PTR(skel, "skel_open"))
-               goto cleanup;
-
-       skel->links.sendmsg_unix_prog = bpf_program__attach_cgroup(
-               skel->progs.sendmsg_unix_prog, cgroup_fd);
-       if (!ASSERT_OK_PTR(skel->links.sendmsg_unix_prog, "prog_attach"))
-               goto cleanup;
-
-       return skel;
-cleanup:
-       sendmsg_unix_prog__destroy(skel);
-       return NULL;
-}
-
-static void sendmsg_unix_prog_destroy(void *skel)
-{
-       sendmsg_unix_prog__destroy(skel);
-}
-
-static void *recvmsg_unix_prog_load(int cgroup_fd)
-{
-       struct recvmsg_unix_prog *skel;
-
-       skel = recvmsg_unix_prog__open_and_load();
-       if (!ASSERT_OK_PTR(skel, "skel_open"))
-               goto cleanup;
-
-       skel->links.recvmsg_unix_prog = bpf_program__attach_cgroup(
-               skel->progs.recvmsg_unix_prog, cgroup_fd);
-       if (!ASSERT_OK_PTR(skel->links.recvmsg_unix_prog, "prog_attach"))
-               goto cleanup;
-
-       return skel;
-cleanup:
-       recvmsg_unix_prog__destroy(skel);
-       return NULL;
-}
-
-static void recvmsg_unix_prog_destroy(void *skel)
-{
-       recvmsg_unix_prog__destroy(skel);
-}
-
-static void *getsockname_unix_prog_load(int cgroup_fd)
-{
-       struct getsockname_unix_prog *skel;
-
-       skel = getsockname_unix_prog__open_and_load();
-       if (!ASSERT_OK_PTR(skel, "skel_open"))
-               goto cleanup;
-
-       skel->links.getsockname_unix_prog = bpf_program__attach_cgroup(
-               skel->progs.getsockname_unix_prog, cgroup_fd);
-       if (!ASSERT_OK_PTR(skel->links.getsockname_unix_prog, "prog_attach"))
-               goto cleanup;
-
-       return skel;
-cleanup:
-       getsockname_unix_prog__destroy(skel);
-       return NULL;
+#define BPF_SKEL_FUNCS(skel_name, prog_name) \
+static void *skel_name##_load(int cgroup_fd) \
+{ \
+       struct skel_name *skel; \
+       skel = skel_name##__open_and_load(); \
+       if (!ASSERT_OK_PTR(skel, "skel_open")) \
+               goto cleanup; \
+       skel->links.prog_name = bpf_program__attach_cgroup( \
+               skel->progs.prog_name, cgroup_fd); \
+       if (!ASSERT_OK_PTR(skel->links.prog_name, "prog_attach")) \
+               goto cleanup; \
+       return skel; \
+cleanup: \
+       skel_name##__destroy(skel); \
+       return NULL; \
+} \
+static void skel_name##_destroy(void *skel) \
+{ \
+       skel_name##__destroy(skel); \
 }
 
-static void getsockname_unix_prog_destroy(void *skel)
-{
-       getsockname_unix_prog__destroy(skel);
-}
-
-static void *getpeername_unix_prog_load(int cgroup_fd)
-{
-       struct getpeername_unix_prog *skel;
-
-       skel = getpeername_unix_prog__open_and_load();
-       if (!ASSERT_OK_PTR(skel, "skel_open"))
-               goto cleanup;
-
-       skel->links.getpeername_unix_prog = bpf_program__attach_cgroup(
-               skel->progs.getpeername_unix_prog, cgroup_fd);
-       if (!ASSERT_OK_PTR(skel->links.getpeername_unix_prog, "prog_attach"))
-               goto cleanup;
-
-       return skel;
-cleanup:
-       getpeername_unix_prog__destroy(skel);
-       return NULL;
-}
-
-static void getpeername_unix_prog_destroy(void *skel)
-{
-       getpeername_unix_prog__destroy(skel);
-}
+BPF_SKEL_FUNCS(bind4_prog, bind_v4_prog);
+BPF_SKEL_FUNCS(bind6_prog, bind_v6_prog);
+BPF_SKEL_FUNCS(connect4_prog, connect_v4_prog);
+BPF_SKEL_FUNCS(connect6_prog, connect_v6_prog);
+BPF_SKEL_FUNCS(connect_unix_prog, connect_unix_prog);
+BPF_SKEL_FUNCS(sendmsg4_prog, sendmsg_v4_prog);
+BPF_SKEL_FUNCS(sendmsg6_prog, sendmsg_v6_prog);
+BPF_SKEL_FUNCS(sendmsg_unix_prog, sendmsg_unix_prog);
+BPF_SKEL_FUNCS(recvmsg4_prog, recvmsg4_prog);
+BPF_SKEL_FUNCS(recvmsg6_prog, recvmsg6_prog);
+BPF_SKEL_FUNCS(recvmsg_unix_prog, recvmsg_unix_prog);
+BPF_SKEL_FUNCS(getsockname_unix_prog, getsockname_unix_prog);
+BPF_SKEL_FUNCS(getpeername_unix_prog, getpeername_unix_prog);
 
 static struct sock_addr_test tests[] = {
+       /* bind - system calls */
+       {
+               SOCK_ADDR_TEST_BIND,
+               "bind4: bind (stream)",
+               bind4_prog_load,
+               bind4_prog_destroy,
+               AF_INET,
+               SOCK_STREAM,
+               SERV4_IP,
+               SERV4_PORT,
+               SERV4_REWRITE_IP,
+               SERV4_REWRITE_PORT,
+       },
+       {
+               SOCK_ADDR_TEST_BIND,
+               "bind4: bind (dgram)",
+               bind4_prog_load,
+               bind4_prog_destroy,
+               AF_INET,
+               SOCK_DGRAM,
+               SERV4_IP,
+               SERV4_PORT,
+               SERV4_REWRITE_IP,
+               SERV4_REWRITE_PORT,
+       },
+       {
+               SOCK_ADDR_TEST_BIND,
+               "bind6: bind (stream)",
+               bind6_prog_load,
+               bind6_prog_destroy,
+               AF_INET6,
+               SOCK_STREAM,
+               SERV6_IP,
+               SERV6_PORT,
+               SERV6_REWRITE_IP,
+               SERV6_REWRITE_PORT,
+       },
+       {
+               SOCK_ADDR_TEST_BIND,
+               "bind6: bind (dgram)",
+               bind6_prog_load,
+               bind6_prog_destroy,
+               AF_INET6,
+               SOCK_DGRAM,
+               SERV6_IP,
+               SERV6_PORT,
+               SERV6_REWRITE_IP,
+               SERV6_REWRITE_PORT,
+       },
+
+       /* connect - system calls */
+       {
+               SOCK_ADDR_TEST_CONNECT,
+               "connect4: connect (stream)",
+               connect4_prog_load,
+               connect4_prog_destroy,
+               AF_INET,
+               SOCK_STREAM,
+               SERV4_IP,
+               SERV4_PORT,
+               SERV4_REWRITE_IP,
+               SERV4_REWRITE_PORT,
+               SRC4_REWRITE_IP,
+       },
        {
                SOCK_ADDR_TEST_CONNECT,
-               "connect_unix",
+               "connect4: connect (dgram)",
+               connect4_prog_load,
+               connect4_prog_destroy,
+               AF_INET,
+               SOCK_DGRAM,
+               SERV4_IP,
+               SERV4_PORT,
+               SERV4_REWRITE_IP,
+               SERV4_REWRITE_PORT,
+               SRC4_REWRITE_IP,
+       },
+       {
+               SOCK_ADDR_TEST_CONNECT,
+               "connect6: connect (stream)",
+               connect6_prog_load,
+               connect6_prog_destroy,
+               AF_INET6,
+               SOCK_STREAM,
+               SERV6_IP,
+               SERV6_PORT,
+               SERV6_REWRITE_IP,
+               SERV6_REWRITE_PORT,
+               SRC6_REWRITE_IP,
+       },
+       {
+               SOCK_ADDR_TEST_CONNECT,
+               "connect6: connect (dgram)",
+               connect6_prog_load,
+               connect6_prog_destroy,
+               AF_INET6,
+               SOCK_DGRAM,
+               SERV6_IP,
+               SERV6_PORT,
+               SERV6_REWRITE_IP,
+               SERV6_REWRITE_PORT,
+               SRC6_REWRITE_IP,
+       },
+       {
+               SOCK_ADDR_TEST_CONNECT,
+               "connect_unix: connect (stream)",
                connect_unix_prog_load,
                connect_unix_prog_destroy,
                AF_UNIX,
@@ -177,9 +222,37 @@ static struct sock_addr_test tests[] = {
                0,
                NULL,
        },
+
+       /* sendmsg - system calls */
        {
                SOCK_ADDR_TEST_SENDMSG,
-               "sendmsg_unix",
+               "sendmsg4: sendmsg (dgram)",
+               sendmsg4_prog_load,
+               sendmsg4_prog_destroy,
+               AF_INET,
+               SOCK_DGRAM,
+               SERV4_IP,
+               SERV4_PORT,
+               SERV4_REWRITE_IP,
+               SERV4_REWRITE_PORT,
+               SRC4_REWRITE_IP,
+       },
+       {
+               SOCK_ADDR_TEST_SENDMSG,
+               "sendmsg6: sendmsg (dgram)",
+               sendmsg6_prog_load,
+               sendmsg6_prog_destroy,
+               AF_INET6,
+               SOCK_DGRAM,
+               SERV6_IP,
+               SERV6_PORT,
+               SERV6_REWRITE_IP,
+               SERV6_REWRITE_PORT,
+               SRC6_REWRITE_IP,
+       },
+       {
+               SOCK_ADDR_TEST_SENDMSG,
+               "sendmsg_unix: sendmsg (dgram)",
                sendmsg_unix_prog_load,
                sendmsg_unix_prog_destroy,
                AF_UNIX,
@@ -190,9 +263,37 @@ static struct sock_addr_test tests[] = {
                0,
                NULL,
        },
+
+       /* recvmsg - system calls */
+       {
+               SOCK_ADDR_TEST_RECVMSG,
+               "recvmsg4: recvfrom (dgram)",
+               recvmsg4_prog_load,
+               recvmsg4_prog_destroy,
+               AF_INET,
+               SOCK_DGRAM,
+               SERV4_REWRITE_IP,
+               SERV4_REWRITE_PORT,
+               SERV4_REWRITE_IP,
+               SERV4_REWRITE_PORT,
+               SERV4_IP,
+       },
        {
                SOCK_ADDR_TEST_RECVMSG,
-               "recvmsg_unix-dgram",
+               "recvmsg6: recvfrom (dgram)",
+               recvmsg6_prog_load,
+               recvmsg6_prog_destroy,
+               AF_INET6,
+               SOCK_DGRAM,
+               SERV6_REWRITE_IP,
+               SERV6_REWRITE_PORT,
+               SERV6_REWRITE_IP,
+               SERV6_REWRITE_PORT,
+               SERV6_IP,
+       },
+       {
+               SOCK_ADDR_TEST_RECVMSG,
+               "recvmsg_unix: recvfrom (dgram)",
                recvmsg_unix_prog_load,
                recvmsg_unix_prog_destroy,
                AF_UNIX,
@@ -205,7 +306,7 @@ static struct sock_addr_test tests[] = {
        },
        {
                SOCK_ADDR_TEST_RECVMSG,
-               "recvmsg_unix-stream",
+               "recvmsg_unix: recvfrom (stream)",
                recvmsg_unix_prog_load,
                recvmsg_unix_prog_destroy,
                AF_UNIX,
@@ -216,6 +317,8 @@ static struct sock_addr_test tests[] = {
                0,
                SERVUN_ADDRESS,
        },
+
+       /* getsockname - system calls */
        {
                SOCK_ADDR_TEST_GETSOCKNAME,
                "getsockname_unix",
@@ -229,6 +332,8 @@ static struct sock_addr_test tests[] = {
                0,
                NULL,
        },
+
+       /* getpeername - system calls */
        {
                SOCK_ADDR_TEST_GETPEERNAME,
                "getpeername_unix",
@@ -558,11 +663,52 @@ static void test_getpeername(struct sock_addr_test *test)
                close(serv);
 }
 
+static int ping_once(int ipv, const char *addr)
+{
+       const char *ping_cmd_prefix = "ping -";
+
+       if (!SYS_NOFAIL("type ping%d >/dev/null 2>&1", ipv))
+               ping_cmd_prefix = "ping";
+
+       return SYS_NOFAIL("%s%d -q -c 1 -W 1 %s >/dev/null 2>&1",
+                         ping_cmd_prefix, ipv, addr);
+}
+
+static int setup_test_env(void)
+{
+       SYS(err, "ip link add dev %s1 type veth peer name %s2", TEST_IF_PREFIX,
+           TEST_IF_PREFIX);
+       SYS(err, "ip link set %s1 up", TEST_IF_PREFIX);
+       SYS(err, "ip link set %s2 up", TEST_IF_PREFIX);
+       SYS(err, "ip -4 addr add %s/8 dev %s1", TEST_IPV4, TEST_IF_PREFIX);
+       SYS(err, "ip -6 addr add %s/128 dev %s1", TEST_IPV6, TEST_IF_PREFIX);
+
+       int i;
+
+       for (i = 0; i < 5; i++) {
+               if (!ping_once(4, TEST_IPV4) && !ping_once(6, TEST_IPV6))
+                       return 0;
+       }
+
+       ASSERT_FAIL("Timed out waiting for test IP to become available.");
+err:
+       return -1;
+}
+
+static void cleanup_test_env(void)
+{
+       SYS_NOFAIL("ip link del %s1 2>/dev/null", TEST_IF_PREFIX);
+       SYS_NOFAIL("ip link del %s2 2>/dev/null", TEST_IF_PREFIX);
+}
+
 void test_sock_addr(void)
 {
        int cgroup_fd = -1;
        void *skel;
 
+       if (!ASSERT_OK(setup_test_env(), "setup_test_env"))
+               goto cleanup;
+
        cgroup_fd = test__join_cgroup("/sock_addr");
        if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup"))
                goto cleanup;
@@ -609,4 +755,5 @@ void test_sock_addr(void)
 cleanup:
        if (cgroup_fd >= 0)
                close(cgroup_fd);
+       cleanup_test_env();
 }
-- 
2.44.0.478.gd926399ef9-goog


Reply via email to