Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.3-rc3 211 lines 4.0 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2 3#include <errno.h> 4#include <stdio.h> 5#include <unistd.h> 6#include <sys/types.h> 7#include <sys/socket.h> 8#include <netinet/in.h> 9 10#include <linux/filter.h> 11#include <bpf/bpf.h> 12#include <bpf/libbpf.h> 13 14#include "bpf_rlimit.h" 15#include "bpf_util.h" 16#include "cgroup_helpers.h" 17 18#define CG_PATH "/sockopt" 19 20#define SOL_CUSTOM 0xdeadbeef 21 22static int getsetsockopt(void) 23{ 24 int fd, err; 25 union { 26 char u8[4]; 27 __u32 u32; 28 } buf = {}; 29 socklen_t optlen; 30 31 fd = socket(AF_INET, SOCK_STREAM, 0); 32 if (fd < 0) { 33 log_err("Failed to create socket"); 34 return -1; 35 } 36 37 /* IP_TOS - BPF bypass */ 38 39 buf.u8[0] = 0x08; 40 err = setsockopt(fd, SOL_IP, IP_TOS, &buf, 1); 41 if (err) { 42 log_err("Failed to call setsockopt(IP_TOS)"); 43 goto err; 44 } 45 46 buf.u8[0] = 0x00; 47 optlen = 1; 48 err = getsockopt(fd, SOL_IP, IP_TOS, &buf, &optlen); 49 if (err) { 50 log_err("Failed to call getsockopt(IP_TOS)"); 51 goto err; 52 } 53 54 if (buf.u8[0] != 0x08) { 55 log_err("Unexpected getsockopt(IP_TOS) buf[0] 0x%02x != 0x08", 56 buf.u8[0]); 57 goto err; 58 } 59 60 /* IP_TTL - EPERM */ 61 62 buf.u8[0] = 1; 63 err = setsockopt(fd, SOL_IP, IP_TTL, &buf, 1); 64 if (!err || errno != EPERM) { 65 log_err("Unexpected success from setsockopt(IP_TTL)"); 66 goto err; 67 } 68 69 /* SOL_CUSTOM - handled by BPF */ 70 71 buf.u8[0] = 0x01; 72 err = setsockopt(fd, SOL_CUSTOM, 0, &buf, 1); 73 if (err) { 74 log_err("Failed to call setsockopt"); 75 goto err; 76 } 77 78 buf.u32 = 0x00; 79 optlen = 4; 80 err = getsockopt(fd, SOL_CUSTOM, 0, &buf, &optlen); 81 if (err) { 82 log_err("Failed to call getsockopt"); 83 goto err; 84 } 85 86 if (optlen != 1) { 87 log_err("Unexpected optlen %d != 1", optlen); 88 goto err; 89 } 90 if (buf.u8[0] != 0x01) { 91 log_err("Unexpected buf[0] 0x%02x != 0x01", buf.u8[0]); 92 goto err; 93 } 94 95 /* SO_SNDBUF is overwritten */ 96 97 buf.u32 = 0x01010101; 98 err = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buf, 4); 99 if (err) { 100 log_err("Failed to call setsockopt(SO_SNDBUF)"); 101 goto err; 102 } 103 104 buf.u32 = 0x00; 105 optlen = 4; 106 err = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buf, &optlen); 107 if (err) { 108 log_err("Failed to call getsockopt(SO_SNDBUF)"); 109 goto err; 110 } 111 112 if (buf.u32 != 0x55AA*2) { 113 log_err("Unexpected getsockopt(SO_SNDBUF) 0x%x != 0x55AA*2", 114 buf.u32); 115 goto err; 116 } 117 118 close(fd); 119 return 0; 120err: 121 close(fd); 122 return -1; 123} 124 125static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title) 126{ 127 enum bpf_attach_type attach_type; 128 enum bpf_prog_type prog_type; 129 struct bpf_program *prog; 130 int err; 131 132 err = libbpf_prog_type_by_name(title, &prog_type, &attach_type); 133 if (err) { 134 log_err("Failed to deduct types for %s BPF program", title); 135 return -1; 136 } 137 138 prog = bpf_object__find_program_by_title(obj, title); 139 if (!prog) { 140 log_err("Failed to find %s BPF program", title); 141 return -1; 142 } 143 144 err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, 145 attach_type, 0); 146 if (err) { 147 log_err("Failed to attach %s BPF program", title); 148 return -1; 149 } 150 151 return 0; 152} 153 154static int run_test(int cgroup_fd) 155{ 156 struct bpf_prog_load_attr attr = { 157 .file = "./sockopt_sk.o", 158 }; 159 struct bpf_object *obj; 160 int ignored; 161 int err; 162 163 err = bpf_prog_load_xattr(&attr, &obj, &ignored); 164 if (err) { 165 log_err("Failed to load BPF object"); 166 return -1; 167 } 168 169 err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt"); 170 if (err) 171 goto close_bpf_object; 172 173 err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt"); 174 if (err) 175 goto close_bpf_object; 176 177 err = getsetsockopt(); 178 179close_bpf_object: 180 bpf_object__close(obj); 181 return err; 182} 183 184int main(int args, char **argv) 185{ 186 int cgroup_fd; 187 int err = EXIT_SUCCESS; 188 189 if (setup_cgroup_environment()) 190 goto cleanup_obj; 191 192 cgroup_fd = create_and_get_cgroup(CG_PATH); 193 if (cgroup_fd < 0) 194 goto cleanup_cgroup_env; 195 196 if (join_cgroup(CG_PATH)) 197 goto cleanup_cgroup; 198 199 if (run_test(cgroup_fd)) 200 err = EXIT_FAILURE; 201 202 printf("test_sockopt_sk: %s\n", 203 err == EXIT_SUCCESS ? "PASSED" : "FAILED"); 204 205cleanup_cgroup: 206 close(cgroup_fd); 207cleanup_cgroup_env: 208 cleanup_cgroup_environment(); 209cleanup_obj: 210 return err; 211}