This source file includes following definitions.
- getsetsockopt
- prog_attach
- run_test
- test_sockopt_sk
1
2 #include <test_progs.h>
3 #include "cgroup_helpers.h"
4
5 #define SOL_CUSTOM 0xdeadbeef
6
7 static int getsetsockopt(void)
8 {
9 int fd, err;
10 union {
11 char u8[4];
12 __u32 u32;
13 char cc[16];
14 } buf = {};
15 socklen_t optlen;
16
17 fd = socket(AF_INET, SOCK_STREAM, 0);
18 if (fd < 0) {
19 log_err("Failed to create socket");
20 return -1;
21 }
22
23
24
25 buf.u8[0] = 0x08;
26 err = setsockopt(fd, SOL_IP, IP_TOS, &buf, 1);
27 if (err) {
28 log_err("Failed to call setsockopt(IP_TOS)");
29 goto err;
30 }
31
32 buf.u8[0] = 0x00;
33 optlen = 1;
34 err = getsockopt(fd, SOL_IP, IP_TOS, &buf, &optlen);
35 if (err) {
36 log_err("Failed to call getsockopt(IP_TOS)");
37 goto err;
38 }
39
40 if (buf.u8[0] != 0x08) {
41 log_err("Unexpected getsockopt(IP_TOS) buf[0] 0x%02x != 0x08",
42 buf.u8[0]);
43 goto err;
44 }
45
46
47
48 buf.u8[0] = 1;
49 err = setsockopt(fd, SOL_IP, IP_TTL, &buf, 1);
50 if (!err || errno != EPERM) {
51 log_err("Unexpected success from setsockopt(IP_TTL)");
52 goto err;
53 }
54
55
56
57 buf.u8[0] = 0x01;
58 err = setsockopt(fd, SOL_CUSTOM, 0, &buf, 1);
59 if (err) {
60 log_err("Failed to call setsockopt");
61 goto err;
62 }
63
64 buf.u32 = 0x00;
65 optlen = 4;
66 err = getsockopt(fd, SOL_CUSTOM, 0, &buf, &optlen);
67 if (err) {
68 log_err("Failed to call getsockopt");
69 goto err;
70 }
71
72 if (optlen != 1) {
73 log_err("Unexpected optlen %d != 1", optlen);
74 goto err;
75 }
76 if (buf.u8[0] != 0x01) {
77 log_err("Unexpected buf[0] 0x%02x != 0x01", buf.u8[0]);
78 goto err;
79 }
80
81
82
83 buf.u32 = 0x01010101;
84 err = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buf, 4);
85 if (err) {
86 log_err("Failed to call setsockopt(SO_SNDBUF)");
87 goto err;
88 }
89
90 buf.u32 = 0x00;
91 optlen = 4;
92 err = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buf, &optlen);
93 if (err) {
94 log_err("Failed to call getsockopt(SO_SNDBUF)");
95 goto err;
96 }
97
98 if (buf.u32 != 0x55AA*2) {
99 log_err("Unexpected getsockopt(SO_SNDBUF) 0x%x != 0x55AA*2",
100 buf.u32);
101 goto err;
102 }
103
104
105
106 strcpy(buf.cc, "nv");
107 err = setsockopt(fd, SOL_TCP, TCP_CONGESTION, &buf, strlen("nv"));
108 if (err) {
109 log_err("Failed to call setsockopt(TCP_CONGESTION)");
110 goto err;
111 }
112
113
114 optlen = sizeof(buf.cc);
115 err = getsockopt(fd, SOL_TCP, TCP_CONGESTION, &buf, &optlen);
116 if (err) {
117 log_err("Failed to call getsockopt(TCP_CONGESTION)");
118 goto err;
119 }
120
121 if (strcmp(buf.cc, "cubic") != 0) {
122 log_err("Unexpected getsockopt(TCP_CONGESTION) %s != %s",
123 buf.cc, "cubic");
124 goto err;
125 }
126
127 close(fd);
128 return 0;
129 err:
130 close(fd);
131 return -1;
132 }
133
134 static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title)
135 {
136 enum bpf_attach_type attach_type;
137 enum bpf_prog_type prog_type;
138 struct bpf_program *prog;
139 int err;
140
141 err = libbpf_prog_type_by_name(title, &prog_type, &attach_type);
142 if (err) {
143 log_err("Failed to deduct types for %s BPF program", title);
144 return -1;
145 }
146
147 prog = bpf_object__find_program_by_title(obj, title);
148 if (!prog) {
149 log_err("Failed to find %s BPF program", title);
150 return -1;
151 }
152
153 err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd,
154 attach_type, 0);
155 if (err) {
156 log_err("Failed to attach %s BPF program", title);
157 return -1;
158 }
159
160 return 0;
161 }
162
163 static void run_test(int cgroup_fd)
164 {
165 struct bpf_prog_load_attr attr = {
166 .file = "./sockopt_sk.o",
167 };
168 struct bpf_object *obj;
169 int ignored;
170 int err;
171
172 err = bpf_prog_load_xattr(&attr, &obj, &ignored);
173 if (CHECK_FAIL(err))
174 return;
175
176 err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt");
177 if (CHECK_FAIL(err))
178 goto close_bpf_object;
179
180 err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt");
181 if (CHECK_FAIL(err))
182 goto close_bpf_object;
183
184 CHECK_FAIL(getsetsockopt());
185
186 close_bpf_object:
187 bpf_object__close(obj);
188 }
189
190 void test_sockopt_sk(void)
191 {
192 int cgroup_fd;
193
194 cgroup_fd = test__join_cgroup("/sockopt_sk");
195 if (CHECK_FAIL(cgroup_fd < 0))
196 return;
197
198 run_test(cgroup_fd);
199 close(cgroup_fd);
200 }