0001
0002
0003
0004
0005
0006
0007 #include <test_progs.h>
0008 #include <cgroup_helpers.h>
0009 #include <network_helpers.h>
0010
0011 #include "cgroup_getset_retval_setsockopt.skel.h"
0012 #include "cgroup_getset_retval_getsockopt.skel.h"
0013
0014 #define SOL_CUSTOM 0xdeadbeef
0015
0016 static int zero;
0017
0018 static void test_setsockopt_set(int cgroup_fd, int sock_fd)
0019 {
0020 struct cgroup_getset_retval_setsockopt *obj;
0021 struct bpf_link *link_set_eunatch = NULL;
0022
0023 obj = cgroup_getset_retval_setsockopt__open_and_load();
0024 if (!ASSERT_OK_PTR(obj, "skel-load"))
0025 return;
0026
0027
0028
0029
0030 link_set_eunatch = bpf_program__attach_cgroup(obj->progs.set_eunatch,
0031 cgroup_fd);
0032 if (!ASSERT_OK_PTR(link_set_eunatch, "cg-attach-set_eunatch"))
0033 goto close_bpf_object;
0034
0035 if (!ASSERT_ERR(setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR,
0036 &zero, sizeof(int)), "setsockopt"))
0037 goto close_bpf_object;
0038 if (!ASSERT_EQ(errno, EUNATCH, "setsockopt-errno"))
0039 goto close_bpf_object;
0040
0041 if (!ASSERT_EQ(obj->bss->invocations, 1, "invocations"))
0042 goto close_bpf_object;
0043 if (!ASSERT_FALSE(obj->bss->assertion_error, "assertion_error"))
0044 goto close_bpf_object;
0045
0046 close_bpf_object:
0047 bpf_link__destroy(link_set_eunatch);
0048
0049 cgroup_getset_retval_setsockopt__destroy(obj);
0050 }
0051
0052 static void test_setsockopt_set_and_get(int cgroup_fd, int sock_fd)
0053 {
0054 struct cgroup_getset_retval_setsockopt *obj;
0055 struct bpf_link *link_set_eunatch = NULL, *link_get_retval = NULL;
0056
0057 obj = cgroup_getset_retval_setsockopt__open_and_load();
0058 if (!ASSERT_OK_PTR(obj, "skel-load"))
0059 return;
0060
0061
0062
0063
0064 link_set_eunatch = bpf_program__attach_cgroup(obj->progs.set_eunatch,
0065 cgroup_fd);
0066 if (!ASSERT_OK_PTR(link_set_eunatch, "cg-attach-set_eunatch"))
0067 goto close_bpf_object;
0068 link_get_retval = bpf_program__attach_cgroup(obj->progs.get_retval,
0069 cgroup_fd);
0070 if (!ASSERT_OK_PTR(link_get_retval, "cg-attach-get_retval"))
0071 goto close_bpf_object;
0072
0073 if (!ASSERT_ERR(setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR,
0074 &zero, sizeof(int)), "setsockopt"))
0075 goto close_bpf_object;
0076 if (!ASSERT_EQ(errno, EUNATCH, "setsockopt-errno"))
0077 goto close_bpf_object;
0078
0079 if (!ASSERT_EQ(obj->bss->invocations, 2, "invocations"))
0080 goto close_bpf_object;
0081 if (!ASSERT_FALSE(obj->bss->assertion_error, "assertion_error"))
0082 goto close_bpf_object;
0083 if (!ASSERT_EQ(obj->bss->retval_value, -EUNATCH, "retval_value"))
0084 goto close_bpf_object;
0085
0086 close_bpf_object:
0087 bpf_link__destroy(link_set_eunatch);
0088 bpf_link__destroy(link_get_retval);
0089
0090 cgroup_getset_retval_setsockopt__destroy(obj);
0091 }
0092
0093 static void test_setsockopt_default_zero(int cgroup_fd, int sock_fd)
0094 {
0095 struct cgroup_getset_retval_setsockopt *obj;
0096 struct bpf_link *link_get_retval = NULL;
0097
0098 obj = cgroup_getset_retval_setsockopt__open_and_load();
0099 if (!ASSERT_OK_PTR(obj, "skel-load"))
0100 return;
0101
0102
0103
0104
0105 link_get_retval = bpf_program__attach_cgroup(obj->progs.get_retval,
0106 cgroup_fd);
0107 if (!ASSERT_OK_PTR(link_get_retval, "cg-attach-get_retval"))
0108 goto close_bpf_object;
0109
0110 if (!ASSERT_OK(setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR,
0111 &zero, sizeof(int)), "setsockopt"))
0112 goto close_bpf_object;
0113
0114 if (!ASSERT_EQ(obj->bss->invocations, 1, "invocations"))
0115 goto close_bpf_object;
0116 if (!ASSERT_FALSE(obj->bss->assertion_error, "assertion_error"))
0117 goto close_bpf_object;
0118 if (!ASSERT_EQ(obj->bss->retval_value, 0, "retval_value"))
0119 goto close_bpf_object;
0120
0121 close_bpf_object:
0122 bpf_link__destroy(link_get_retval);
0123
0124 cgroup_getset_retval_setsockopt__destroy(obj);
0125 }
0126
0127 static void test_setsockopt_default_zero_and_set(int cgroup_fd, int sock_fd)
0128 {
0129 struct cgroup_getset_retval_setsockopt *obj;
0130 struct bpf_link *link_get_retval = NULL, *link_set_eunatch = NULL;
0131
0132 obj = cgroup_getset_retval_setsockopt__open_and_load();
0133 if (!ASSERT_OK_PTR(obj, "skel-load"))
0134 return;
0135
0136
0137
0138
0139
0140 link_get_retval = bpf_program__attach_cgroup(obj->progs.get_retval,
0141 cgroup_fd);
0142 if (!ASSERT_OK_PTR(link_get_retval, "cg-attach-get_retval"))
0143 goto close_bpf_object;
0144 link_set_eunatch = bpf_program__attach_cgroup(obj->progs.set_eunatch,
0145 cgroup_fd);
0146 if (!ASSERT_OK_PTR(link_set_eunatch, "cg-attach-set_eunatch"))
0147 goto close_bpf_object;
0148
0149 if (!ASSERT_ERR(setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR,
0150 &zero, sizeof(int)), "setsockopt"))
0151 goto close_bpf_object;
0152 if (!ASSERT_EQ(errno, EUNATCH, "setsockopt-errno"))
0153 goto close_bpf_object;
0154
0155 if (!ASSERT_EQ(obj->bss->invocations, 2, "invocations"))
0156 goto close_bpf_object;
0157 if (!ASSERT_FALSE(obj->bss->assertion_error, "assertion_error"))
0158 goto close_bpf_object;
0159 if (!ASSERT_EQ(obj->bss->retval_value, 0, "retval_value"))
0160 goto close_bpf_object;
0161
0162 close_bpf_object:
0163 bpf_link__destroy(link_get_retval);
0164 bpf_link__destroy(link_set_eunatch);
0165
0166 cgroup_getset_retval_setsockopt__destroy(obj);
0167 }
0168
0169 static void test_setsockopt_override(int cgroup_fd, int sock_fd)
0170 {
0171 struct cgroup_getset_retval_setsockopt *obj;
0172 struct bpf_link *link_set_eunatch = NULL, *link_set_eisconn = NULL;
0173 struct bpf_link *link_get_retval = NULL;
0174
0175 obj = cgroup_getset_retval_setsockopt__open_and_load();
0176 if (!ASSERT_OK_PTR(obj, "skel-load"))
0177 return;
0178
0179
0180
0181
0182
0183 link_set_eunatch = bpf_program__attach_cgroup(obj->progs.set_eunatch,
0184 cgroup_fd);
0185 if (!ASSERT_OK_PTR(link_set_eunatch, "cg-attach-set_eunatch"))
0186 goto close_bpf_object;
0187 link_set_eisconn = bpf_program__attach_cgroup(obj->progs.set_eisconn,
0188 cgroup_fd);
0189 if (!ASSERT_OK_PTR(link_set_eisconn, "cg-attach-set_eisconn"))
0190 goto close_bpf_object;
0191 link_get_retval = bpf_program__attach_cgroup(obj->progs.get_retval,
0192 cgroup_fd);
0193 if (!ASSERT_OK_PTR(link_get_retval, "cg-attach-get_retval"))
0194 goto close_bpf_object;
0195
0196 if (!ASSERT_ERR(setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR,
0197 &zero, sizeof(int)), "setsockopt"))
0198 goto close_bpf_object;
0199 if (!ASSERT_EQ(errno, EISCONN, "setsockopt-errno"))
0200 goto close_bpf_object;
0201
0202 if (!ASSERT_EQ(obj->bss->invocations, 3, "invocations"))
0203 goto close_bpf_object;
0204 if (!ASSERT_FALSE(obj->bss->assertion_error, "assertion_error"))
0205 goto close_bpf_object;
0206 if (!ASSERT_EQ(obj->bss->retval_value, -EISCONN, "retval_value"))
0207 goto close_bpf_object;
0208
0209 close_bpf_object:
0210 bpf_link__destroy(link_set_eunatch);
0211 bpf_link__destroy(link_set_eisconn);
0212 bpf_link__destroy(link_get_retval);
0213
0214 cgroup_getset_retval_setsockopt__destroy(obj);
0215 }
0216
0217 static void test_setsockopt_legacy_eperm(int cgroup_fd, int sock_fd)
0218 {
0219 struct cgroup_getset_retval_setsockopt *obj;
0220 struct bpf_link *link_legacy_eperm = NULL, *link_get_retval = NULL;
0221
0222 obj = cgroup_getset_retval_setsockopt__open_and_load();
0223 if (!ASSERT_OK_PTR(obj, "skel-load"))
0224 return;
0225
0226
0227
0228
0229
0230
0231 link_legacy_eperm = bpf_program__attach_cgroup(obj->progs.legacy_eperm,
0232 cgroup_fd);
0233 if (!ASSERT_OK_PTR(link_legacy_eperm, "cg-attach-legacy_eperm"))
0234 goto close_bpf_object;
0235 link_get_retval = bpf_program__attach_cgroup(obj->progs.get_retval,
0236 cgroup_fd);
0237 if (!ASSERT_OK_PTR(link_get_retval, "cg-attach-get_retval"))
0238 goto close_bpf_object;
0239
0240 if (!ASSERT_ERR(setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR,
0241 &zero, sizeof(int)), "setsockopt"))
0242 goto close_bpf_object;
0243 if (!ASSERT_EQ(errno, EPERM, "setsockopt-errno"))
0244 goto close_bpf_object;
0245
0246 if (!ASSERT_EQ(obj->bss->invocations, 2, "invocations"))
0247 goto close_bpf_object;
0248 if (!ASSERT_FALSE(obj->bss->assertion_error, "assertion_error"))
0249 goto close_bpf_object;
0250 if (!ASSERT_EQ(obj->bss->retval_value, -EPERM, "retval_value"))
0251 goto close_bpf_object;
0252
0253 close_bpf_object:
0254 bpf_link__destroy(link_legacy_eperm);
0255 bpf_link__destroy(link_get_retval);
0256
0257 cgroup_getset_retval_setsockopt__destroy(obj);
0258 }
0259
0260 static void test_setsockopt_legacy_no_override(int cgroup_fd, int sock_fd)
0261 {
0262 struct cgroup_getset_retval_setsockopt *obj;
0263 struct bpf_link *link_set_eunatch = NULL, *link_legacy_eperm = NULL;
0264 struct bpf_link *link_get_retval = NULL;
0265
0266 obj = cgroup_getset_retval_setsockopt__open_and_load();
0267 if (!ASSERT_OK_PTR(obj, "skel-load"))
0268 return;
0269
0270
0271
0272
0273
0274
0275
0276 link_set_eunatch = bpf_program__attach_cgroup(obj->progs.set_eunatch,
0277 cgroup_fd);
0278 if (!ASSERT_OK_PTR(link_set_eunatch, "cg-attach-set_eunatch"))
0279 goto close_bpf_object;
0280 link_legacy_eperm = bpf_program__attach_cgroup(obj->progs.legacy_eperm,
0281 cgroup_fd);
0282 if (!ASSERT_OK_PTR(link_legacy_eperm, "cg-attach-legacy_eperm"))
0283 goto close_bpf_object;
0284 link_get_retval = bpf_program__attach_cgroup(obj->progs.get_retval,
0285 cgroup_fd);
0286 if (!ASSERT_OK_PTR(link_get_retval, "cg-attach-get_retval"))
0287 goto close_bpf_object;
0288
0289 if (!ASSERT_ERR(setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR,
0290 &zero, sizeof(int)), "setsockopt"))
0291 goto close_bpf_object;
0292 if (!ASSERT_EQ(errno, EUNATCH, "setsockopt-errno"))
0293 goto close_bpf_object;
0294
0295 if (!ASSERT_EQ(obj->bss->invocations, 3, "invocations"))
0296 goto close_bpf_object;
0297 if (!ASSERT_FALSE(obj->bss->assertion_error, "assertion_error"))
0298 goto close_bpf_object;
0299 if (!ASSERT_EQ(obj->bss->retval_value, -EUNATCH, "retval_value"))
0300 goto close_bpf_object;
0301
0302 close_bpf_object:
0303 bpf_link__destroy(link_set_eunatch);
0304 bpf_link__destroy(link_legacy_eperm);
0305 bpf_link__destroy(link_get_retval);
0306
0307 cgroup_getset_retval_setsockopt__destroy(obj);
0308 }
0309
0310 static void test_getsockopt_get(int cgroup_fd, int sock_fd)
0311 {
0312 struct cgroup_getset_retval_getsockopt *obj;
0313 struct bpf_link *link_get_retval = NULL;
0314 int buf;
0315 socklen_t optlen = sizeof(buf);
0316
0317 obj = cgroup_getset_retval_getsockopt__open_and_load();
0318 if (!ASSERT_OK_PTR(obj, "skel-load"))
0319 return;
0320
0321
0322
0323
0324 link_get_retval = bpf_program__attach_cgroup(obj->progs.get_retval,
0325 cgroup_fd);
0326 if (!ASSERT_OK_PTR(link_get_retval, "cg-attach-get_retval"))
0327 goto close_bpf_object;
0328
0329 if (!ASSERT_ERR(getsockopt(sock_fd, SOL_CUSTOM, 0,
0330 &buf, &optlen), "getsockopt"))
0331 goto close_bpf_object;
0332 if (!ASSERT_EQ(errno, EOPNOTSUPP, "getsockopt-errno"))
0333 goto close_bpf_object;
0334
0335 if (!ASSERT_EQ(obj->bss->invocations, 1, "invocations"))
0336 goto close_bpf_object;
0337 if (!ASSERT_FALSE(obj->bss->assertion_error, "assertion_error"))
0338 goto close_bpf_object;
0339 if (!ASSERT_EQ(obj->bss->retval_value, -EOPNOTSUPP, "retval_value"))
0340 goto close_bpf_object;
0341 if (!ASSERT_EQ(obj->bss->ctx_retval_value, -EOPNOTSUPP, "ctx_retval_value"))
0342 goto close_bpf_object;
0343
0344 close_bpf_object:
0345 bpf_link__destroy(link_get_retval);
0346
0347 cgroup_getset_retval_getsockopt__destroy(obj);
0348 }
0349
0350 static void test_getsockopt_override(int cgroup_fd, int sock_fd)
0351 {
0352 struct cgroup_getset_retval_getsockopt *obj;
0353 struct bpf_link *link_set_eisconn = NULL;
0354 int buf;
0355 socklen_t optlen = sizeof(buf);
0356
0357 obj = cgroup_getset_retval_getsockopt__open_and_load();
0358 if (!ASSERT_OK_PTR(obj, "skel-load"))
0359 return;
0360
0361
0362
0363
0364 link_set_eisconn = bpf_program__attach_cgroup(obj->progs.set_eisconn,
0365 cgroup_fd);
0366 if (!ASSERT_OK_PTR(link_set_eisconn, "cg-attach-set_eisconn"))
0367 goto close_bpf_object;
0368
0369 if (!ASSERT_ERR(getsockopt(sock_fd, SOL_CUSTOM, 0,
0370 &buf, &optlen), "getsockopt"))
0371 goto close_bpf_object;
0372 if (!ASSERT_EQ(errno, EISCONN, "getsockopt-errno"))
0373 goto close_bpf_object;
0374
0375 if (!ASSERT_EQ(obj->bss->invocations, 1, "invocations"))
0376 goto close_bpf_object;
0377 if (!ASSERT_FALSE(obj->bss->assertion_error, "assertion_error"))
0378 goto close_bpf_object;
0379
0380 close_bpf_object:
0381 bpf_link__destroy(link_set_eisconn);
0382
0383 cgroup_getset_retval_getsockopt__destroy(obj);
0384 }
0385
0386 static void test_getsockopt_retval_sync(int cgroup_fd, int sock_fd)
0387 {
0388 struct cgroup_getset_retval_getsockopt *obj;
0389 struct bpf_link *link_set_eisconn = NULL, *link_clear_retval = NULL;
0390 struct bpf_link *link_get_retval = NULL;
0391 int buf;
0392 socklen_t optlen = sizeof(buf);
0393
0394 obj = cgroup_getset_retval_getsockopt__open_and_load();
0395 if (!ASSERT_OK_PTR(obj, "skel-load"))
0396 return;
0397
0398
0399
0400
0401
0402 link_set_eisconn = bpf_program__attach_cgroup(obj->progs.set_eisconn,
0403 cgroup_fd);
0404 if (!ASSERT_OK_PTR(link_set_eisconn, "cg-attach-set_eisconn"))
0405 goto close_bpf_object;
0406 link_clear_retval = bpf_program__attach_cgroup(obj->progs.clear_retval,
0407 cgroup_fd);
0408 if (!ASSERT_OK_PTR(link_clear_retval, "cg-attach-clear_retval"))
0409 goto close_bpf_object;
0410 link_get_retval = bpf_program__attach_cgroup(obj->progs.get_retval,
0411 cgroup_fd);
0412 if (!ASSERT_OK_PTR(link_get_retval, "cg-attach-get_retval"))
0413 goto close_bpf_object;
0414
0415 if (!ASSERT_OK(getsockopt(sock_fd, SOL_CUSTOM, 0,
0416 &buf, &optlen), "getsockopt"))
0417 goto close_bpf_object;
0418
0419 if (!ASSERT_EQ(obj->bss->invocations, 3, "invocations"))
0420 goto close_bpf_object;
0421 if (!ASSERT_FALSE(obj->bss->assertion_error, "assertion_error"))
0422 goto close_bpf_object;
0423 if (!ASSERT_EQ(obj->bss->retval_value, 0, "retval_value"))
0424 goto close_bpf_object;
0425 if (!ASSERT_EQ(obj->bss->ctx_retval_value, 0, "ctx_retval_value"))
0426 goto close_bpf_object;
0427
0428 close_bpf_object:
0429 bpf_link__destroy(link_set_eisconn);
0430 bpf_link__destroy(link_clear_retval);
0431 bpf_link__destroy(link_get_retval);
0432
0433 cgroup_getset_retval_getsockopt__destroy(obj);
0434 }
0435
0436 void test_cgroup_getset_retval(void)
0437 {
0438 int cgroup_fd = -1;
0439 int sock_fd = -1;
0440
0441 cgroup_fd = test__join_cgroup("/cgroup_getset_retval");
0442 if (!ASSERT_GE(cgroup_fd, 0, "cg-create"))
0443 goto close_fd;
0444
0445 sock_fd = start_server(AF_INET, SOCK_DGRAM, NULL, 0, 0);
0446 if (!ASSERT_GE(sock_fd, 0, "start-server"))
0447 goto close_fd;
0448
0449 if (test__start_subtest("setsockopt-set"))
0450 test_setsockopt_set(cgroup_fd, sock_fd);
0451
0452 if (test__start_subtest("setsockopt-set_and_get"))
0453 test_setsockopt_set_and_get(cgroup_fd, sock_fd);
0454
0455 if (test__start_subtest("setsockopt-default_zero"))
0456 test_setsockopt_default_zero(cgroup_fd, sock_fd);
0457
0458 if (test__start_subtest("setsockopt-default_zero_and_set"))
0459 test_setsockopt_default_zero_and_set(cgroup_fd, sock_fd);
0460
0461 if (test__start_subtest("setsockopt-override"))
0462 test_setsockopt_override(cgroup_fd, sock_fd);
0463
0464 if (test__start_subtest("setsockopt-legacy_eperm"))
0465 test_setsockopt_legacy_eperm(cgroup_fd, sock_fd);
0466
0467 if (test__start_subtest("setsockopt-legacy_no_override"))
0468 test_setsockopt_legacy_no_override(cgroup_fd, sock_fd);
0469
0470 if (test__start_subtest("getsockopt-get"))
0471 test_getsockopt_get(cgroup_fd, sock_fd);
0472
0473 if (test__start_subtest("getsockopt-override"))
0474 test_getsockopt_override(cgroup_fd, sock_fd);
0475
0476 if (test__start_subtest("getsockopt-retval_sync"))
0477 test_getsockopt_retval_sync(cgroup_fd, sock_fd);
0478
0479 close_fd:
0480 close(cgroup_fd);
0481 }