~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/prog_tests/connect_ping.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 
  3 /*
  4  * Copyright 2022 Google LLC.
  5  */
  6 
  7 #define _GNU_SOURCE
  8 #include <sys/mount.h>
  9 
 10 #include "test_progs.h"
 11 #include "cgroup_helpers.h"
 12 #include "network_helpers.h"
 13 
 14 #include "connect_ping.skel.h"
 15 
 16 /* 2001:db8::1 */
 17 #define BINDADDR_V6 { { { 0x20,0x01,0x0d,0xb8,0,0,0,0,0,0,0,0,0,0,0,1 } } }
 18 static const struct in6_addr bindaddr_v6 = BINDADDR_V6;
 19 
 20 static void subtest(int cgroup_fd, struct connect_ping *skel,
 21                     int family, int do_bind)
 22 {
 23         struct sockaddr_in sa4 = {
 24                 .sin_family = AF_INET,
 25                 .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
 26         };
 27         struct sockaddr_in6 sa6 = {
 28                 .sin6_family = AF_INET6,
 29                 .sin6_addr = IN6ADDR_LOOPBACK_INIT,
 30         };
 31         struct sockaddr *sa = NULL;
 32         socklen_t sa_len;
 33         int protocol = -1;
 34         int sock_fd;
 35 
 36         switch (family) {
 37         case AF_INET:
 38                 sa = (struct sockaddr *)&sa4;
 39                 sa_len = sizeof(sa4);
 40                 protocol = IPPROTO_ICMP;
 41                 break;
 42         case AF_INET6:
 43                 sa = (struct sockaddr *)&sa6;
 44                 sa_len = sizeof(sa6);
 45                 protocol = IPPROTO_ICMPV6;
 46                 break;
 47         }
 48 
 49         memset(skel->bss, 0, sizeof(*skel->bss));
 50         skel->bss->do_bind = do_bind;
 51 
 52         sock_fd = socket(family, SOCK_DGRAM, protocol);
 53         if (!ASSERT_GE(sock_fd, 0, "sock-create"))
 54                 return;
 55 
 56         if (!ASSERT_OK(connect(sock_fd, sa, sa_len), "connect"))
 57                 goto close_sock;
 58 
 59         if (!ASSERT_EQ(skel->bss->invocations_v4, family == AF_INET ? 1 : 0,
 60                        "invocations_v4"))
 61                 goto close_sock;
 62         if (!ASSERT_EQ(skel->bss->invocations_v6, family == AF_INET6 ? 1 : 0,
 63                        "invocations_v6"))
 64                 goto close_sock;
 65         if (!ASSERT_EQ(skel->bss->has_error, 0, "has_error"))
 66                 goto close_sock;
 67 
 68         if (!ASSERT_OK(getsockname(sock_fd, sa, &sa_len),
 69                        "getsockname"))
 70                 goto close_sock;
 71 
 72         switch (family) {
 73         case AF_INET:
 74                 if (!ASSERT_EQ(sa4.sin_family, family, "sin_family"))
 75                         goto close_sock;
 76                 if (!ASSERT_EQ(sa4.sin_addr.s_addr,
 77                                htonl(do_bind ? 0x01010101 : INADDR_LOOPBACK),
 78                                "sin_addr"))
 79                         goto close_sock;
 80                 break;
 81         case AF_INET6:
 82                 if (!ASSERT_EQ(sa6.sin6_family, AF_INET6, "sin6_family"))
 83                         goto close_sock;
 84                 if (!ASSERT_EQ(memcmp(&sa6.sin6_addr,
 85                                       do_bind ? &bindaddr_v6 : &in6addr_loopback,
 86                                       sizeof(sa6.sin6_addr)),
 87                                0, "sin6_addr"))
 88                         goto close_sock;
 89                 break;
 90         }
 91 
 92 close_sock:
 93         close(sock_fd);
 94 }
 95 
 96 void test_connect_ping(void)
 97 {
 98         struct connect_ping *skel;
 99         int cgroup_fd;
100 
101         if (!ASSERT_OK(unshare(CLONE_NEWNET | CLONE_NEWNS), "unshare"))
102                 return;
103 
104         /* overmount sysfs, and making original sysfs private so overmount
105          * does not propagate to other mntns.
106          */
107         if (!ASSERT_OK(mount("none", "/sys", NULL, MS_PRIVATE, NULL),
108                        "remount-private-sys"))
109                 return;
110         if (!ASSERT_OK(mount("sysfs", "/sys", "sysfs", 0, NULL),
111                        "mount-sys"))
112                 return;
113         if (!ASSERT_OK(mount("bpffs", "/sys/fs/bpf", "bpf", 0, NULL),
114                        "mount-bpf"))
115                 goto clean_mount;
116 
117         if (!ASSERT_OK(system("ip link set dev lo up"), "lo-up"))
118                 goto clean_mount;
119         if (!ASSERT_OK(system("ip addr add 1.1.1.1 dev lo"), "lo-addr-v4"))
120                 goto clean_mount;
121         if (!ASSERT_OK(system("ip -6 addr add 2001:db8::1 dev lo"), "lo-addr-v6"))
122                 goto clean_mount;
123         if (write_sysctl("/proc/sys/net/ipv4/ping_group_range", "0 0"))
124                 goto clean_mount;
125 
126         cgroup_fd = test__join_cgroup("/connect_ping");
127         if (!ASSERT_GE(cgroup_fd, 0, "cg-create"))
128                 goto clean_mount;
129 
130         skel = connect_ping__open_and_load();
131         if (!ASSERT_OK_PTR(skel, "skel-load"))
132                 goto close_cgroup;
133         skel->links.connect_v4_prog =
134                 bpf_program__attach_cgroup(skel->progs.connect_v4_prog, cgroup_fd);
135         if (!ASSERT_OK_PTR(skel->links.connect_v4_prog, "cg-attach-v4"))
136                 goto skel_destroy;
137         skel->links.connect_v6_prog =
138                 bpf_program__attach_cgroup(skel->progs.connect_v6_prog, cgroup_fd);
139         if (!ASSERT_OK_PTR(skel->links.connect_v6_prog, "cg-attach-v6"))
140                 goto skel_destroy;
141 
142         /* Connect a v4 ping socket to localhost, assert that only v4 is called,
143          * and called exactly once, and that the socket's bound address is
144          * original loopback address.
145          */
146         if (test__start_subtest("ipv4"))
147                 subtest(cgroup_fd, skel, AF_INET, 0);
148 
149         /* Connect a v4 ping socket to localhost, assert that only v4 is called,
150          * and called exactly once, and that the socket's bound address is
151          * address we explicitly bound.
152          */
153         if (test__start_subtest("ipv4-bind"))
154                 subtest(cgroup_fd, skel, AF_INET, 1);
155 
156         /* Connect a v6 ping socket to localhost, assert that only v6 is called,
157          * and called exactly once, and that the socket's bound address is
158          * original loopback address.
159          */
160         if (test__start_subtest("ipv6"))
161                 subtest(cgroup_fd, skel, AF_INET6, 0);
162 
163         /* Connect a v6 ping socket to localhost, assert that only v6 is called,
164          * and called exactly once, and that the socket's bound address is
165          * address we explicitly bound.
166          */
167         if (test__start_subtest("ipv6-bind"))
168                 subtest(cgroup_fd, skel, AF_INET6, 1);
169 
170 skel_destroy:
171         connect_ping__destroy(skel);
172 
173 close_cgroup:
174         close(cgroup_fd);
175 
176 clean_mount:
177         umount2("/sys", MNT_DETACH);
178 }
179 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php