1d4a89c1eSYiFei Zhu // SPDX-License-Identifier: GPL-2.0-only 2d4a89c1eSYiFei Zhu 3d4a89c1eSYiFei Zhu /* 4d4a89c1eSYiFei Zhu * Copyright 2020 Google LLC. 5d4a89c1eSYiFei Zhu */ 6d4a89c1eSYiFei Zhu 7d4a89c1eSYiFei Zhu #include <test_progs.h> 8d4a89c1eSYiFei Zhu #include <cgroup_helpers.h> 9d4a89c1eSYiFei Zhu #include <network_helpers.h> 10d4a89c1eSYiFei Zhu 119e5bd1f7SYiFei Zhu #include "progs/cg_storage_multi.h" 129e5bd1f7SYiFei Zhu 13d4a89c1eSYiFei Zhu #include "cg_storage_multi_egress_only.skel.h" 143573f384SYiFei Zhu #include "cg_storage_multi_isolated.skel.h" 153573f384SYiFei Zhu #include "cg_storage_multi_shared.skel.h" 16d4a89c1eSYiFei Zhu 17d4a89c1eSYiFei Zhu #define PARENT_CGROUP "/cgroup_storage" 18d4a89c1eSYiFei Zhu #define CHILD_CGROUP "/cgroup_storage/child" 19d4a89c1eSYiFei Zhu 20d4a89c1eSYiFei Zhu static int duration; 21d4a89c1eSYiFei Zhu 223573f384SYiFei Zhu static bool assert_storage(struct bpf_map *map, const void *key, 239e5bd1f7SYiFei Zhu struct cgroup_value *expected) 24d4a89c1eSYiFei Zhu { 259e5bd1f7SYiFei Zhu struct cgroup_value value; 26d4a89c1eSYiFei Zhu int map_fd; 27d4a89c1eSYiFei Zhu 28d4a89c1eSYiFei Zhu map_fd = bpf_map__fd(map); 29d4a89c1eSYiFei Zhu 303573f384SYiFei Zhu if (CHECK(bpf_map_lookup_elem(map_fd, key, &value) < 0, 31d4a89c1eSYiFei Zhu "map-lookup", "errno %d", errno)) 32d4a89c1eSYiFei Zhu return true; 339e5bd1f7SYiFei Zhu if (CHECK(memcmp(&value, expected, sizeof(struct cgroup_value)), 349e5bd1f7SYiFei Zhu "assert-storage", "storages differ")) 35d4a89c1eSYiFei Zhu return true; 36d4a89c1eSYiFei Zhu 37d4a89c1eSYiFei Zhu return false; 38d4a89c1eSYiFei Zhu } 39d4a89c1eSYiFei Zhu 403573f384SYiFei Zhu static bool assert_storage_noexist(struct bpf_map *map, const void *key) 41d4a89c1eSYiFei Zhu { 429e5bd1f7SYiFei Zhu struct cgroup_value value; 43d4a89c1eSYiFei Zhu int map_fd; 44d4a89c1eSYiFei Zhu 45d4a89c1eSYiFei Zhu map_fd = bpf_map__fd(map); 46d4a89c1eSYiFei Zhu 473573f384SYiFei Zhu if (CHECK(bpf_map_lookup_elem(map_fd, key, &value) == 0, 48d4a89c1eSYiFei Zhu "map-lookup", "succeeded, expected ENOENT")) 49d4a89c1eSYiFei Zhu return true; 50d4a89c1eSYiFei Zhu if (CHECK(errno != ENOENT, 51d4a89c1eSYiFei Zhu "map-lookup", "errno %d, expected ENOENT", errno)) 52d4a89c1eSYiFei Zhu return true; 53d4a89c1eSYiFei Zhu 54d4a89c1eSYiFei Zhu return false; 55d4a89c1eSYiFei Zhu } 56d4a89c1eSYiFei Zhu 57d4a89c1eSYiFei Zhu static bool connect_send(const char *cgroup_path) 58d4a89c1eSYiFei Zhu { 59d4a89c1eSYiFei Zhu bool res = true; 60d4a89c1eSYiFei Zhu int server_fd = -1, client_fd = -1; 61d4a89c1eSYiFei Zhu 62d4a89c1eSYiFei Zhu if (join_cgroup(cgroup_path)) 63d4a89c1eSYiFei Zhu goto out_clean; 64d4a89c1eSYiFei Zhu 65d4a89c1eSYiFei Zhu server_fd = start_server(AF_INET, SOCK_DGRAM, NULL, 0, 0); 66d4a89c1eSYiFei Zhu if (server_fd < 0) 67d4a89c1eSYiFei Zhu goto out_clean; 68d4a89c1eSYiFei Zhu 69d4a89c1eSYiFei Zhu client_fd = connect_to_fd(server_fd, 0); 70d4a89c1eSYiFei Zhu if (client_fd < 0) 71d4a89c1eSYiFei Zhu goto out_clean; 72d4a89c1eSYiFei Zhu 73d4a89c1eSYiFei Zhu if (send(client_fd, "message", strlen("message"), 0) < 0) 74d4a89c1eSYiFei Zhu goto out_clean; 75d4a89c1eSYiFei Zhu 76d4a89c1eSYiFei Zhu res = false; 77d4a89c1eSYiFei Zhu 78d4a89c1eSYiFei Zhu out_clean: 79d4a89c1eSYiFei Zhu close(client_fd); 80d4a89c1eSYiFei Zhu close(server_fd); 81d4a89c1eSYiFei Zhu return res; 82d4a89c1eSYiFei Zhu } 83d4a89c1eSYiFei Zhu 84d4a89c1eSYiFei Zhu static void test_egress_only(int parent_cgroup_fd, int child_cgroup_fd) 85d4a89c1eSYiFei Zhu { 86d4a89c1eSYiFei Zhu struct cg_storage_multi_egress_only *obj; 879e5bd1f7SYiFei Zhu struct cgroup_value expected_cgroup_value; 883573f384SYiFei Zhu struct bpf_cgroup_storage_key key; 89d4a89c1eSYiFei Zhu struct bpf_link *parent_link = NULL, *child_link = NULL; 90d4a89c1eSYiFei Zhu bool err; 91d4a89c1eSYiFei Zhu 923573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_EGRESS; 933573f384SYiFei Zhu 94d4a89c1eSYiFei Zhu obj = cg_storage_multi_egress_only__open_and_load(); 95d4a89c1eSYiFei Zhu if (CHECK(!obj, "skel-load", "errno %d", errno)) 96d4a89c1eSYiFei Zhu return; 97d4a89c1eSYiFei Zhu 98d4a89c1eSYiFei Zhu /* Attach to parent cgroup, trigger packet from child. 99d4a89c1eSYiFei Zhu * Assert that there is only one run and in that run the storage is 100d4a89c1eSYiFei Zhu * parent cgroup's storage. 101d4a89c1eSYiFei Zhu * Also assert that child cgroup's storage does not exist 102d4a89c1eSYiFei Zhu */ 103d4a89c1eSYiFei Zhu parent_link = bpf_program__attach_cgroup(obj->progs.egress, 104d4a89c1eSYiFei Zhu parent_cgroup_fd); 105bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(parent_link, "parent-cg-attach")) 106d4a89c1eSYiFei Zhu goto close_bpf_object; 107d4a89c1eSYiFei Zhu err = connect_send(CHILD_CGROUP); 108d4a89c1eSYiFei Zhu if (CHECK(err, "first-connect-send", "errno %d", errno)) 109d4a89c1eSYiFei Zhu goto close_bpf_object; 110d4a89c1eSYiFei Zhu if (CHECK(obj->bss->invocations != 1, 111d4a89c1eSYiFei Zhu "first-invoke", "invocations=%d", obj->bss->invocations)) 112d4a89c1eSYiFei Zhu goto close_bpf_object; 1133573f384SYiFei Zhu key.cgroup_inode_id = get_cgroup_id(PARENT_CGROUP); 1149e5bd1f7SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 1 }; 1159e5bd1f7SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 1163573f384SYiFei Zhu &key, &expected_cgroup_value)) 117d4a89c1eSYiFei Zhu goto close_bpf_object; 1183573f384SYiFei Zhu key.cgroup_inode_id = get_cgroup_id(CHILD_CGROUP); 1193573f384SYiFei Zhu if (assert_storage_noexist(obj->maps.cgroup_storage, &key)) 120d4a89c1eSYiFei Zhu goto close_bpf_object; 121d4a89c1eSYiFei Zhu 122d4a89c1eSYiFei Zhu /* Attach to parent and child cgroup, trigger packet from child. 123d4a89c1eSYiFei Zhu * Assert that there are two additional runs, one that run with parent 124d4a89c1eSYiFei Zhu * cgroup's storage and one with child cgroup's storage. 125d4a89c1eSYiFei Zhu */ 126d4a89c1eSYiFei Zhu child_link = bpf_program__attach_cgroup(obj->progs.egress, 127d4a89c1eSYiFei Zhu child_cgroup_fd); 128bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(child_link, "child-cg-attach")) 129d4a89c1eSYiFei Zhu goto close_bpf_object; 130d4a89c1eSYiFei Zhu err = connect_send(CHILD_CGROUP); 131d4a89c1eSYiFei Zhu if (CHECK(err, "second-connect-send", "errno %d", errno)) 132d4a89c1eSYiFei Zhu goto close_bpf_object; 133d4a89c1eSYiFei Zhu if (CHECK(obj->bss->invocations != 3, 134d4a89c1eSYiFei Zhu "second-invoke", "invocations=%d", obj->bss->invocations)) 135d4a89c1eSYiFei Zhu goto close_bpf_object; 1363573f384SYiFei Zhu key.cgroup_inode_id = get_cgroup_id(PARENT_CGROUP); 1379e5bd1f7SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 2 }; 1389e5bd1f7SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 1393573f384SYiFei Zhu &key, &expected_cgroup_value)) 140d4a89c1eSYiFei Zhu goto close_bpf_object; 1413573f384SYiFei Zhu key.cgroup_inode_id = get_cgroup_id(CHILD_CGROUP); 1429e5bd1f7SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 1 }; 1439e5bd1f7SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 1443573f384SYiFei Zhu &key, &expected_cgroup_value)) 145d4a89c1eSYiFei Zhu goto close_bpf_object; 146d4a89c1eSYiFei Zhu 147d4a89c1eSYiFei Zhu close_bpf_object: 148d4a89c1eSYiFei Zhu bpf_link__destroy(parent_link); 149d4a89c1eSYiFei Zhu bpf_link__destroy(child_link); 150d4a89c1eSYiFei Zhu 151d4a89c1eSYiFei Zhu cg_storage_multi_egress_only__destroy(obj); 152d4a89c1eSYiFei Zhu } 153d4a89c1eSYiFei Zhu 1543573f384SYiFei Zhu static void test_isolated(int parent_cgroup_fd, int child_cgroup_fd) 1559e5bd1f7SYiFei Zhu { 1563573f384SYiFei Zhu struct cg_storage_multi_isolated *obj; 1573573f384SYiFei Zhu struct cgroup_value expected_cgroup_value; 1583573f384SYiFei Zhu struct bpf_cgroup_storage_key key; 1593573f384SYiFei Zhu struct bpf_link *parent_egress1_link = NULL, *parent_egress2_link = NULL; 1603573f384SYiFei Zhu struct bpf_link *child_egress1_link = NULL, *child_egress2_link = NULL; 1613573f384SYiFei Zhu struct bpf_link *parent_ingress_link = NULL, *child_ingress_link = NULL; 1623573f384SYiFei Zhu bool err; 1639e5bd1f7SYiFei Zhu 1643573f384SYiFei Zhu obj = cg_storage_multi_isolated__open_and_load(); 1653573f384SYiFei Zhu if (CHECK(!obj, "skel-load", "errno %d", errno)) 1663573f384SYiFei Zhu return; 1673573f384SYiFei Zhu 1683573f384SYiFei Zhu /* Attach to parent cgroup, trigger packet from child. 1693573f384SYiFei Zhu * Assert that there is three runs, two with parent cgroup egress and 1703573f384SYiFei Zhu * one with parent cgroup ingress, stored in separate parent storages. 1713573f384SYiFei Zhu * Also assert that child cgroup's storages does not exist 1729e5bd1f7SYiFei Zhu */ 1733573f384SYiFei Zhu parent_egress1_link = bpf_program__attach_cgroup(obj->progs.egress1, 1743573f384SYiFei Zhu parent_cgroup_fd); 175bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(parent_egress1_link, "parent-egress1-cg-attach")) 1763573f384SYiFei Zhu goto close_bpf_object; 1773573f384SYiFei Zhu parent_egress2_link = bpf_program__attach_cgroup(obj->progs.egress2, 1783573f384SYiFei Zhu parent_cgroup_fd); 179bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(parent_egress2_link, "parent-egress2-cg-attach")) 1803573f384SYiFei Zhu goto close_bpf_object; 1813573f384SYiFei Zhu parent_ingress_link = bpf_program__attach_cgroup(obj->progs.ingress, 1823573f384SYiFei Zhu parent_cgroup_fd); 183bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(parent_ingress_link, "parent-ingress-cg-attach")) 1843573f384SYiFei Zhu goto close_bpf_object; 1853573f384SYiFei Zhu err = connect_send(CHILD_CGROUP); 1863573f384SYiFei Zhu if (CHECK(err, "first-connect-send", "errno %d", errno)) 1873573f384SYiFei Zhu goto close_bpf_object; 1883573f384SYiFei Zhu if (CHECK(obj->bss->invocations != 3, 1893573f384SYiFei Zhu "first-invoke", "invocations=%d", obj->bss->invocations)) 1903573f384SYiFei Zhu goto close_bpf_object; 1913573f384SYiFei Zhu key.cgroup_inode_id = get_cgroup_id(PARENT_CGROUP); 1923573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_EGRESS; 1933573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 2 }; 1943573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 1953573f384SYiFei Zhu &key, &expected_cgroup_value)) 1963573f384SYiFei Zhu goto close_bpf_object; 1973573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_INGRESS; 1983573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .ingress_pkts = 1 }; 1993573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 2003573f384SYiFei Zhu &key, &expected_cgroup_value)) 2013573f384SYiFei Zhu goto close_bpf_object; 2023573f384SYiFei Zhu key.cgroup_inode_id = get_cgroup_id(CHILD_CGROUP); 2033573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_EGRESS; 2043573f384SYiFei Zhu if (assert_storage_noexist(obj->maps.cgroup_storage, &key)) 2053573f384SYiFei Zhu goto close_bpf_object; 2063573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_INGRESS; 2073573f384SYiFei Zhu if (assert_storage_noexist(obj->maps.cgroup_storage, &key)) 2083573f384SYiFei Zhu goto close_bpf_object; 2099e5bd1f7SYiFei Zhu 2103573f384SYiFei Zhu /* Attach to parent and child cgroup, trigger packet from child. 2113573f384SYiFei Zhu * Assert that there is six additional runs, parent cgroup egresses and 2123573f384SYiFei Zhu * ingress, child cgroup egresses and ingress. 2133573f384SYiFei Zhu * Assert that egree and ingress storages are separate. 2143573f384SYiFei Zhu */ 2153573f384SYiFei Zhu child_egress1_link = bpf_program__attach_cgroup(obj->progs.egress1, 2163573f384SYiFei Zhu child_cgroup_fd); 217bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(child_egress1_link, "child-egress1-cg-attach")) 2183573f384SYiFei Zhu goto close_bpf_object; 2193573f384SYiFei Zhu child_egress2_link = bpf_program__attach_cgroup(obj->progs.egress2, 2203573f384SYiFei Zhu child_cgroup_fd); 221bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(child_egress2_link, "child-egress2-cg-attach")) 2223573f384SYiFei Zhu goto close_bpf_object; 2233573f384SYiFei Zhu child_ingress_link = bpf_program__attach_cgroup(obj->progs.ingress, 2243573f384SYiFei Zhu child_cgroup_fd); 225bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(child_ingress_link, "child-ingress-cg-attach")) 2263573f384SYiFei Zhu goto close_bpf_object; 2273573f384SYiFei Zhu err = connect_send(CHILD_CGROUP); 2283573f384SYiFei Zhu if (CHECK(err, "second-connect-send", "errno %d", errno)) 2293573f384SYiFei Zhu goto close_bpf_object; 2303573f384SYiFei Zhu if (CHECK(obj->bss->invocations != 9, 2313573f384SYiFei Zhu "second-invoke", "invocations=%d", obj->bss->invocations)) 2323573f384SYiFei Zhu goto close_bpf_object; 2333573f384SYiFei Zhu key.cgroup_inode_id = get_cgroup_id(PARENT_CGROUP); 2343573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_EGRESS; 2353573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 4 }; 2363573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 2373573f384SYiFei Zhu &key, &expected_cgroup_value)) 2383573f384SYiFei Zhu goto close_bpf_object; 2393573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_INGRESS; 2403573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .ingress_pkts = 2 }; 2413573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 2423573f384SYiFei Zhu &key, &expected_cgroup_value)) 2433573f384SYiFei Zhu goto close_bpf_object; 2443573f384SYiFei Zhu key.cgroup_inode_id = get_cgroup_id(CHILD_CGROUP); 2453573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_EGRESS; 2463573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 2 }; 2473573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 2483573f384SYiFei Zhu &key, &expected_cgroup_value)) 2493573f384SYiFei Zhu goto close_bpf_object; 2503573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_INGRESS; 2513573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .ingress_pkts = 1 }; 2523573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 2533573f384SYiFei Zhu &key, &expected_cgroup_value)) 2543573f384SYiFei Zhu goto close_bpf_object; 2553573f384SYiFei Zhu 2563573f384SYiFei Zhu close_bpf_object: 2573573f384SYiFei Zhu bpf_link__destroy(parent_egress1_link); 2583573f384SYiFei Zhu bpf_link__destroy(parent_egress2_link); 2593573f384SYiFei Zhu bpf_link__destroy(parent_ingress_link); 2603573f384SYiFei Zhu bpf_link__destroy(child_egress1_link); 2613573f384SYiFei Zhu bpf_link__destroy(child_egress2_link); 2623573f384SYiFei Zhu bpf_link__destroy(child_ingress_link); 2633573f384SYiFei Zhu 2643573f384SYiFei Zhu cg_storage_multi_isolated__destroy(obj); 2653573f384SYiFei Zhu } 2663573f384SYiFei Zhu 2673573f384SYiFei Zhu static void test_shared(int parent_cgroup_fd, int child_cgroup_fd) 2683573f384SYiFei Zhu { 2693573f384SYiFei Zhu struct cg_storage_multi_shared *obj; 2703573f384SYiFei Zhu struct cgroup_value expected_cgroup_value; 2713573f384SYiFei Zhu __u64 key; 2723573f384SYiFei Zhu struct bpf_link *parent_egress1_link = NULL, *parent_egress2_link = NULL; 2733573f384SYiFei Zhu struct bpf_link *child_egress1_link = NULL, *child_egress2_link = NULL; 2743573f384SYiFei Zhu struct bpf_link *parent_ingress_link = NULL, *child_ingress_link = NULL; 2753573f384SYiFei Zhu bool err; 2763573f384SYiFei Zhu 2773573f384SYiFei Zhu obj = cg_storage_multi_shared__open_and_load(); 2783573f384SYiFei Zhu if (CHECK(!obj, "skel-load", "errno %d", errno)) 2793573f384SYiFei Zhu return; 2803573f384SYiFei Zhu 2813573f384SYiFei Zhu /* Attach to parent cgroup, trigger packet from child. 2823573f384SYiFei Zhu * Assert that there is three runs, two with parent cgroup egress and 2833573f384SYiFei Zhu * one with parent cgroup ingress. 2843573f384SYiFei Zhu * Also assert that child cgroup's storage does not exist 2853573f384SYiFei Zhu */ 2863573f384SYiFei Zhu parent_egress1_link = bpf_program__attach_cgroup(obj->progs.egress1, 2873573f384SYiFei Zhu parent_cgroup_fd); 288bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(parent_egress1_link, "parent-egress1-cg-attach")) 2893573f384SYiFei Zhu goto close_bpf_object; 2903573f384SYiFei Zhu parent_egress2_link = bpf_program__attach_cgroup(obj->progs.egress2, 2913573f384SYiFei Zhu parent_cgroup_fd); 292bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(parent_egress2_link, "parent-egress2-cg-attach")) 2933573f384SYiFei Zhu goto close_bpf_object; 2943573f384SYiFei Zhu parent_ingress_link = bpf_program__attach_cgroup(obj->progs.ingress, 2953573f384SYiFei Zhu parent_cgroup_fd); 296bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(parent_ingress_link, "parent-ingress-cg-attach")) 2973573f384SYiFei Zhu goto close_bpf_object; 2983573f384SYiFei Zhu err = connect_send(CHILD_CGROUP); 2993573f384SYiFei Zhu if (CHECK(err, "first-connect-send", "errno %d", errno)) 3003573f384SYiFei Zhu goto close_bpf_object; 3013573f384SYiFei Zhu if (CHECK(obj->bss->invocations != 3, 3023573f384SYiFei Zhu "first-invoke", "invocations=%d", obj->bss->invocations)) 3033573f384SYiFei Zhu goto close_bpf_object; 3043573f384SYiFei Zhu key = get_cgroup_id(PARENT_CGROUP); 3053573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { 3063573f384SYiFei Zhu .egress_pkts = 2, 3073573f384SYiFei Zhu .ingress_pkts = 1, 3083573f384SYiFei Zhu }; 3093573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 3103573f384SYiFei Zhu &key, &expected_cgroup_value)) 3113573f384SYiFei Zhu goto close_bpf_object; 3123573f384SYiFei Zhu key = get_cgroup_id(CHILD_CGROUP); 3133573f384SYiFei Zhu if (assert_storage_noexist(obj->maps.cgroup_storage, &key)) 3143573f384SYiFei Zhu goto close_bpf_object; 3153573f384SYiFei Zhu 3163573f384SYiFei Zhu /* Attach to parent and child cgroup, trigger packet from child. 3173573f384SYiFei Zhu * Assert that there is six additional runs, parent cgroup egresses and 3183573f384SYiFei Zhu * ingress, child cgroup egresses and ingress. 3193573f384SYiFei Zhu */ 3203573f384SYiFei Zhu child_egress1_link = bpf_program__attach_cgroup(obj->progs.egress1, 3213573f384SYiFei Zhu child_cgroup_fd); 322bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(child_egress1_link, "child-egress1-cg-attach")) 3233573f384SYiFei Zhu goto close_bpf_object; 3243573f384SYiFei Zhu child_egress2_link = bpf_program__attach_cgroup(obj->progs.egress2, 3253573f384SYiFei Zhu child_cgroup_fd); 326bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(child_egress2_link, "child-egress2-cg-attach")) 3273573f384SYiFei Zhu goto close_bpf_object; 3283573f384SYiFei Zhu child_ingress_link = bpf_program__attach_cgroup(obj->progs.ingress, 3293573f384SYiFei Zhu child_cgroup_fd); 330bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(child_ingress_link, "child-ingress-cg-attach")) 3313573f384SYiFei Zhu goto close_bpf_object; 3323573f384SYiFei Zhu err = connect_send(CHILD_CGROUP); 3333573f384SYiFei Zhu if (CHECK(err, "second-connect-send", "errno %d", errno)) 3343573f384SYiFei Zhu goto close_bpf_object; 3353573f384SYiFei Zhu if (CHECK(obj->bss->invocations != 9, 3363573f384SYiFei Zhu "second-invoke", "invocations=%d", obj->bss->invocations)) 3373573f384SYiFei Zhu goto close_bpf_object; 3383573f384SYiFei Zhu key = get_cgroup_id(PARENT_CGROUP); 3393573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { 3403573f384SYiFei Zhu .egress_pkts = 4, 3413573f384SYiFei Zhu .ingress_pkts = 2, 3423573f384SYiFei Zhu }; 3433573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 3443573f384SYiFei Zhu &key, &expected_cgroup_value)) 3453573f384SYiFei Zhu goto close_bpf_object; 3463573f384SYiFei Zhu key = get_cgroup_id(CHILD_CGROUP); 3473573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { 3483573f384SYiFei Zhu .egress_pkts = 2, 3493573f384SYiFei Zhu .ingress_pkts = 1, 3503573f384SYiFei Zhu }; 3513573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 3523573f384SYiFei Zhu &key, &expected_cgroup_value)) 3533573f384SYiFei Zhu goto close_bpf_object; 3543573f384SYiFei Zhu 3553573f384SYiFei Zhu close_bpf_object: 3563573f384SYiFei Zhu bpf_link__destroy(parent_egress1_link); 3573573f384SYiFei Zhu bpf_link__destroy(parent_egress2_link); 3583573f384SYiFei Zhu bpf_link__destroy(parent_ingress_link); 3593573f384SYiFei Zhu bpf_link__destroy(child_egress1_link); 3603573f384SYiFei Zhu bpf_link__destroy(child_egress2_link); 3613573f384SYiFei Zhu bpf_link__destroy(child_ingress_link); 3623573f384SYiFei Zhu 3633573f384SYiFei Zhu cg_storage_multi_shared__destroy(obj); 3649e5bd1f7SYiFei Zhu } 3659e5bd1f7SYiFei Zhu 366*d3f7b166SYucong Sun void serial_test_cg_storage_multi(void) 367d4a89c1eSYiFei Zhu { 368d4a89c1eSYiFei Zhu int parent_cgroup_fd = -1, child_cgroup_fd = -1; 369d4a89c1eSYiFei Zhu 370d4a89c1eSYiFei Zhu parent_cgroup_fd = test__join_cgroup(PARENT_CGROUP); 371d4a89c1eSYiFei Zhu if (CHECK(parent_cgroup_fd < 0, "cg-create-parent", "errno %d", errno)) 372d4a89c1eSYiFei Zhu goto close_cgroup_fd; 373d4a89c1eSYiFei Zhu child_cgroup_fd = create_and_get_cgroup(CHILD_CGROUP); 374d4a89c1eSYiFei Zhu if (CHECK(child_cgroup_fd < 0, "cg-create-child", "errno %d", errno)) 375d4a89c1eSYiFei Zhu goto close_cgroup_fd; 376d4a89c1eSYiFei Zhu 377d4a89c1eSYiFei Zhu if (test__start_subtest("egress_only")) 378d4a89c1eSYiFei Zhu test_egress_only(parent_cgroup_fd, child_cgroup_fd); 379d4a89c1eSYiFei Zhu 3803573f384SYiFei Zhu if (test__start_subtest("isolated")) 3813573f384SYiFei Zhu test_isolated(parent_cgroup_fd, child_cgroup_fd); 3823573f384SYiFei Zhu 3833573f384SYiFei Zhu if (test__start_subtest("shared")) 3843573f384SYiFei Zhu test_shared(parent_cgroup_fd, child_cgroup_fd); 3859e5bd1f7SYiFei Zhu 386d4a89c1eSYiFei Zhu close_cgroup_fd: 387d4a89c1eSYiFei Zhu close(child_cgroup_fd); 388d4a89c1eSYiFei Zhu close(parent_cgroup_fd); 389d4a89c1eSYiFei Zhu } 390