brintos

brintos / linux-shallow public Read only

0
0
Text · 13.4 KiB · 10224f8 Raw
394 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2 3/*4 * Copyright 2020 Google LLC.5 */6 7#include <test_progs.h>8#include <cgroup_helpers.h>9#include <network_helpers.h>10 11#include "progs/cg_storage_multi.h"12 13#include "cg_storage_multi_egress_only.skel.h"14#include "cg_storage_multi_isolated.skel.h"15#include "cg_storage_multi_shared.skel.h"16 17#define PARENT_CGROUP "/cgroup_storage"18#define CHILD_CGROUP "/cgroup_storage/child"19 20static int duration;21 22static bool assert_storage(struct bpf_map *map, const void *key,23			   struct cgroup_value *expected)24{25	struct cgroup_value value;26	int map_fd;27 28	map_fd = bpf_map__fd(map);29 30	if (CHECK(bpf_map_lookup_elem(map_fd, key, &value) < 0,31		  "map-lookup", "errno %d", errno))32		return true;33	if (CHECK(memcmp(&value, expected, sizeof(struct cgroup_value)),34		  "assert-storage", "storages differ"))35		return true;36 37	return false;38}39 40static bool assert_storage_noexist(struct bpf_map *map, const void *key)41{42	struct cgroup_value value;43	int map_fd;44 45	map_fd = bpf_map__fd(map);46 47	if (CHECK(bpf_map_lookup_elem(map_fd, key, &value) == 0,48		  "map-lookup", "succeeded, expected ENOENT"))49		return true;50	if (CHECK(errno != ENOENT,51		  "map-lookup", "errno %d, expected ENOENT", errno))52		return true;53 54	return false;55}56 57static bool connect_send(const char *cgroup_path)58{59	int server_fd = -1, client_fd = -1;60	char message[] = "message";61	bool res = true;62 63	if (join_cgroup(cgroup_path))64		goto out_clean;65 66	server_fd = start_server(AF_INET, SOCK_DGRAM, NULL, 0, 0);67	if (server_fd < 0)68		goto out_clean;69 70	client_fd = connect_to_fd(server_fd, 0);71	if (client_fd < 0)72		goto out_clean;73 74	if (send(client_fd, &message, sizeof(message), 0) < 0)75		goto out_clean;76 77	if (read(server_fd, &message, sizeof(message)) < 0)78		goto out_clean;79 80	res = false;81 82out_clean:83	close(client_fd);84	close(server_fd);85	return res;86}87 88static void test_egress_only(int parent_cgroup_fd, int child_cgroup_fd)89{90	struct cg_storage_multi_egress_only *obj;91	struct cgroup_value expected_cgroup_value;92	struct bpf_cgroup_storage_key key;93	struct bpf_link *parent_link = NULL, *child_link = NULL;94	bool err;95 96	key.attach_type = BPF_CGROUP_INET_EGRESS;97 98	obj = cg_storage_multi_egress_only__open_and_load();99	if (CHECK(!obj, "skel-load", "errno %d", errno))100		return;101 102	/* Attach to parent cgroup, trigger packet from child.103	 * Assert that there is only one run and in that run the storage is104	 * parent cgroup's storage.105	 * Also assert that child cgroup's storage does not exist106	 */107	parent_link = bpf_program__attach_cgroup(obj->progs.egress,108						 parent_cgroup_fd);109	if (!ASSERT_OK_PTR(parent_link, "parent-cg-attach"))110		goto close_bpf_object;111	err = connect_send(CHILD_CGROUP);112	if (CHECK(err, "first-connect-send", "errno %d", errno))113		goto close_bpf_object;114	if (CHECK(obj->bss->invocations != 1,115		  "first-invoke", "invocations=%d", obj->bss->invocations))116		goto close_bpf_object;117	key.cgroup_inode_id = get_cgroup_id(PARENT_CGROUP);118	expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 1 };119	if (assert_storage(obj->maps.cgroup_storage,120			   &key, &expected_cgroup_value))121		goto close_bpf_object;122	key.cgroup_inode_id = get_cgroup_id(CHILD_CGROUP);123	if (assert_storage_noexist(obj->maps.cgroup_storage, &key))124		goto close_bpf_object;125 126	/* Attach to parent and child cgroup, trigger packet from child.127	 * Assert that there are two additional runs, one that run with parent128	 * cgroup's storage and one with child cgroup's storage.129	 */130	child_link = bpf_program__attach_cgroup(obj->progs.egress,131						child_cgroup_fd);132	if (!ASSERT_OK_PTR(child_link, "child-cg-attach"))133		goto close_bpf_object;134	err = connect_send(CHILD_CGROUP);135	if (CHECK(err, "second-connect-send", "errno %d", errno))136		goto close_bpf_object;137	if (CHECK(obj->bss->invocations != 3,138		  "second-invoke", "invocations=%d", obj->bss->invocations))139		goto close_bpf_object;140	key.cgroup_inode_id = get_cgroup_id(PARENT_CGROUP);141	expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 2 };142	if (assert_storage(obj->maps.cgroup_storage,143			   &key, &expected_cgroup_value))144		goto close_bpf_object;145	key.cgroup_inode_id = get_cgroup_id(CHILD_CGROUP);146	expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 1 };147	if (assert_storage(obj->maps.cgroup_storage,148			   &key, &expected_cgroup_value))149		goto close_bpf_object;150 151close_bpf_object:152	bpf_link__destroy(parent_link);153	bpf_link__destroy(child_link);154 155	cg_storage_multi_egress_only__destroy(obj);156}157 158static void test_isolated(int parent_cgroup_fd, int child_cgroup_fd)159{160	struct cg_storage_multi_isolated *obj;161	struct cgroup_value expected_cgroup_value;162	struct bpf_cgroup_storage_key key;163	struct bpf_link *parent_egress1_link = NULL, *parent_egress2_link = NULL;164	struct bpf_link *child_egress1_link = NULL, *child_egress2_link = NULL;165	struct bpf_link *parent_ingress_link = NULL, *child_ingress_link = NULL;166	bool err;167 168	obj = cg_storage_multi_isolated__open_and_load();169	if (CHECK(!obj, "skel-load", "errno %d", errno))170		return;171 172	/* Attach to parent cgroup, trigger packet from child.173	 * Assert that there is three runs, two with parent cgroup egress and174	 * one with parent cgroup ingress, stored in separate parent storages.175	 * Also assert that child cgroup's storages does not exist176	 */177	parent_egress1_link = bpf_program__attach_cgroup(obj->progs.egress1,178							 parent_cgroup_fd);179	if (!ASSERT_OK_PTR(parent_egress1_link, "parent-egress1-cg-attach"))180		goto close_bpf_object;181	parent_egress2_link = bpf_program__attach_cgroup(obj->progs.egress2,182							 parent_cgroup_fd);183	if (!ASSERT_OK_PTR(parent_egress2_link, "parent-egress2-cg-attach"))184		goto close_bpf_object;185	parent_ingress_link = bpf_program__attach_cgroup(obj->progs.ingress,186							 parent_cgroup_fd);187	if (!ASSERT_OK_PTR(parent_ingress_link, "parent-ingress-cg-attach"))188		goto close_bpf_object;189	err = connect_send(CHILD_CGROUP);190	if (CHECK(err, "first-connect-send", "errno %d", errno))191		goto close_bpf_object;192	if (CHECK(obj->bss->invocations != 3,193		  "first-invoke", "invocations=%d", obj->bss->invocations))194		goto close_bpf_object;195	key.cgroup_inode_id = get_cgroup_id(PARENT_CGROUP);196	key.attach_type = BPF_CGROUP_INET_EGRESS;197	expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 2 };198	if (assert_storage(obj->maps.cgroup_storage,199			   &key, &expected_cgroup_value))200		goto close_bpf_object;201	key.attach_type = BPF_CGROUP_INET_INGRESS;202	expected_cgroup_value = (struct cgroup_value) { .ingress_pkts = 1 };203	if (assert_storage(obj->maps.cgroup_storage,204			   &key, &expected_cgroup_value))205		goto close_bpf_object;206	key.cgroup_inode_id = get_cgroup_id(CHILD_CGROUP);207	key.attach_type = BPF_CGROUP_INET_EGRESS;208	if (assert_storage_noexist(obj->maps.cgroup_storage, &key))209		goto close_bpf_object;210	key.attach_type = BPF_CGROUP_INET_INGRESS;211	if (assert_storage_noexist(obj->maps.cgroup_storage, &key))212		goto close_bpf_object;213 214	/* Attach to parent and child cgroup, trigger packet from child.215	 * Assert that there is six additional runs, parent cgroup egresses and216	 * ingress, child cgroup egresses and ingress.217	 * Assert that egress and ingress storages are separate.218	 */219	child_egress1_link = bpf_program__attach_cgroup(obj->progs.egress1,220							child_cgroup_fd);221	if (!ASSERT_OK_PTR(child_egress1_link, "child-egress1-cg-attach"))222		goto close_bpf_object;223	child_egress2_link = bpf_program__attach_cgroup(obj->progs.egress2,224							child_cgroup_fd);225	if (!ASSERT_OK_PTR(child_egress2_link, "child-egress2-cg-attach"))226		goto close_bpf_object;227	child_ingress_link = bpf_program__attach_cgroup(obj->progs.ingress,228							child_cgroup_fd);229	if (!ASSERT_OK_PTR(child_ingress_link, "child-ingress-cg-attach"))230		goto close_bpf_object;231	err = connect_send(CHILD_CGROUP);232	if (CHECK(err, "second-connect-send", "errno %d", errno))233		goto close_bpf_object;234	if (CHECK(obj->bss->invocations != 9,235		  "second-invoke", "invocations=%d", obj->bss->invocations))236		goto close_bpf_object;237	key.cgroup_inode_id = get_cgroup_id(PARENT_CGROUP);238	key.attach_type = BPF_CGROUP_INET_EGRESS;239	expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 4 };240	if (assert_storage(obj->maps.cgroup_storage,241			   &key, &expected_cgroup_value))242		goto close_bpf_object;243	key.attach_type = BPF_CGROUP_INET_INGRESS;244	expected_cgroup_value = (struct cgroup_value) { .ingress_pkts = 2 };245	if (assert_storage(obj->maps.cgroup_storage,246			   &key, &expected_cgroup_value))247		goto close_bpf_object;248	key.cgroup_inode_id = get_cgroup_id(CHILD_CGROUP);249	key.attach_type = BPF_CGROUP_INET_EGRESS;250	expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 2 };251	if (assert_storage(obj->maps.cgroup_storage,252			   &key, &expected_cgroup_value))253		goto close_bpf_object;254	key.attach_type = BPF_CGROUP_INET_INGRESS;255	expected_cgroup_value = (struct cgroup_value) { .ingress_pkts = 1 };256	if (assert_storage(obj->maps.cgroup_storage,257			   &key, &expected_cgroup_value))258		goto close_bpf_object;259 260close_bpf_object:261	bpf_link__destroy(parent_egress1_link);262	bpf_link__destroy(parent_egress2_link);263	bpf_link__destroy(parent_ingress_link);264	bpf_link__destroy(child_egress1_link);265	bpf_link__destroy(child_egress2_link);266	bpf_link__destroy(child_ingress_link);267 268	cg_storage_multi_isolated__destroy(obj);269}270 271static void test_shared(int parent_cgroup_fd, int child_cgroup_fd)272{273	struct cg_storage_multi_shared *obj;274	struct cgroup_value expected_cgroup_value;275	__u64 key;276	struct bpf_link *parent_egress1_link = NULL, *parent_egress2_link = NULL;277	struct bpf_link *child_egress1_link = NULL, *child_egress2_link = NULL;278	struct bpf_link *parent_ingress_link = NULL, *child_ingress_link = NULL;279	bool err;280 281	obj = cg_storage_multi_shared__open_and_load();282	if (CHECK(!obj, "skel-load", "errno %d", errno))283		return;284 285	/* Attach to parent cgroup, trigger packet from child.286	 * Assert that there is three runs, two with parent cgroup egress and287	 * one with parent cgroup ingress.288	 * Also assert that child cgroup's storage does not exist289	 */290	parent_egress1_link = bpf_program__attach_cgroup(obj->progs.egress1,291							 parent_cgroup_fd);292	if (!ASSERT_OK_PTR(parent_egress1_link, "parent-egress1-cg-attach"))293		goto close_bpf_object;294	parent_egress2_link = bpf_program__attach_cgroup(obj->progs.egress2,295							 parent_cgroup_fd);296	if (!ASSERT_OK_PTR(parent_egress2_link, "parent-egress2-cg-attach"))297		goto close_bpf_object;298	parent_ingress_link = bpf_program__attach_cgroup(obj->progs.ingress,299							 parent_cgroup_fd);300	if (!ASSERT_OK_PTR(parent_ingress_link, "parent-ingress-cg-attach"))301		goto close_bpf_object;302	err = connect_send(CHILD_CGROUP);303	if (CHECK(err, "first-connect-send", "errno %d", errno))304		goto close_bpf_object;305	if (CHECK(obj->bss->invocations != 3,306		  "first-invoke", "invocations=%d", obj->bss->invocations))307		goto close_bpf_object;308	key = get_cgroup_id(PARENT_CGROUP);309	expected_cgroup_value = (struct cgroup_value) {310		.egress_pkts = 2,311		.ingress_pkts = 1,312	};313	if (assert_storage(obj->maps.cgroup_storage,314			   &key, &expected_cgroup_value))315		goto close_bpf_object;316	key = get_cgroup_id(CHILD_CGROUP);317	if (assert_storage_noexist(obj->maps.cgroup_storage, &key))318		goto close_bpf_object;319 320	/* Attach to parent and child cgroup, trigger packet from child.321	 * Assert that there is six additional runs, parent cgroup egresses and322	 * ingress, child cgroup egresses and ingress.323	 */324	child_egress1_link = bpf_program__attach_cgroup(obj->progs.egress1,325							child_cgroup_fd);326	if (!ASSERT_OK_PTR(child_egress1_link, "child-egress1-cg-attach"))327		goto close_bpf_object;328	child_egress2_link = bpf_program__attach_cgroup(obj->progs.egress2,329							child_cgroup_fd);330	if (!ASSERT_OK_PTR(child_egress2_link, "child-egress2-cg-attach"))331		goto close_bpf_object;332	child_ingress_link = bpf_program__attach_cgroup(obj->progs.ingress,333							child_cgroup_fd);334	if (!ASSERT_OK_PTR(child_ingress_link, "child-ingress-cg-attach"))335		goto close_bpf_object;336	err = connect_send(CHILD_CGROUP);337	if (CHECK(err, "second-connect-send", "errno %d", errno))338		goto close_bpf_object;339	if (CHECK(obj->bss->invocations != 9,340		  "second-invoke", "invocations=%d", obj->bss->invocations))341		goto close_bpf_object;342	key = get_cgroup_id(PARENT_CGROUP);343	expected_cgroup_value = (struct cgroup_value) {344		.egress_pkts = 4,345		.ingress_pkts = 2,346	};347	if (assert_storage(obj->maps.cgroup_storage,348			   &key, &expected_cgroup_value))349		goto close_bpf_object;350	key = get_cgroup_id(CHILD_CGROUP);351	expected_cgroup_value = (struct cgroup_value) {352		.egress_pkts = 2,353		.ingress_pkts = 1,354	};355	if (assert_storage(obj->maps.cgroup_storage,356			   &key, &expected_cgroup_value))357		goto close_bpf_object;358 359close_bpf_object:360	bpf_link__destroy(parent_egress1_link);361	bpf_link__destroy(parent_egress2_link);362	bpf_link__destroy(parent_ingress_link);363	bpf_link__destroy(child_egress1_link);364	bpf_link__destroy(child_egress2_link);365	bpf_link__destroy(child_ingress_link);366 367	cg_storage_multi_shared__destroy(obj);368}369 370void serial_test_cg_storage_multi(void)371{372	int parent_cgroup_fd = -1, child_cgroup_fd = -1;373 374	parent_cgroup_fd = test__join_cgroup(PARENT_CGROUP);375	if (CHECK(parent_cgroup_fd < 0, "cg-create-parent", "errno %d", errno))376		goto close_cgroup_fd;377	child_cgroup_fd = create_and_get_cgroup(CHILD_CGROUP);378	if (CHECK(child_cgroup_fd < 0, "cg-create-child", "errno %d", errno))379		goto close_cgroup_fd;380 381	if (test__start_subtest("egress_only"))382		test_egress_only(parent_cgroup_fd, child_cgroup_fd);383 384	if (test__start_subtest("isolated"))385		test_isolated(parent_cgroup_fd, child_cgroup_fd);386 387	if (test__start_subtest("shared"))388		test_shared(parent_cgroup_fd, child_cgroup_fd);389 390close_cgroup_fd:391	close(child_cgroup_fd);392	close(parent_cgroup_fd);393}394