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); 105d4a89c1eSYiFei Zhu if (CHECK(IS_ERR(parent_link), "parent-cg-attach", 106d4a89c1eSYiFei Zhu "err %ld", PTR_ERR(parent_link))) 107d4a89c1eSYiFei Zhu goto close_bpf_object; 108d4a89c1eSYiFei Zhu err = connect_send(CHILD_CGROUP); 109d4a89c1eSYiFei Zhu if (CHECK(err, "first-connect-send", "errno %d", errno)) 110d4a89c1eSYiFei Zhu goto close_bpf_object; 111d4a89c1eSYiFei Zhu if (CHECK(obj->bss->invocations != 1, 112d4a89c1eSYiFei Zhu "first-invoke", "invocations=%d", obj->bss->invocations)) 113d4a89c1eSYiFei Zhu goto close_bpf_object; 1143573f384SYiFei Zhu key.cgroup_inode_id = get_cgroup_id(PARENT_CGROUP); 1159e5bd1f7SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 1 }; 1169e5bd1f7SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 1173573f384SYiFei Zhu &key, &expected_cgroup_value)) 118d4a89c1eSYiFei Zhu goto close_bpf_object; 1193573f384SYiFei Zhu key.cgroup_inode_id = get_cgroup_id(CHILD_CGROUP); 1203573f384SYiFei Zhu if (assert_storage_noexist(obj->maps.cgroup_storage, &key)) 121d4a89c1eSYiFei Zhu goto close_bpf_object; 122d4a89c1eSYiFei Zhu 123d4a89c1eSYiFei Zhu /* Attach to parent and child cgroup, trigger packet from child. 124d4a89c1eSYiFei Zhu * Assert that there are two additional runs, one that run with parent 125d4a89c1eSYiFei Zhu * cgroup's storage and one with child cgroup's storage. 126d4a89c1eSYiFei Zhu */ 127d4a89c1eSYiFei Zhu child_link = bpf_program__attach_cgroup(obj->progs.egress, 128d4a89c1eSYiFei Zhu child_cgroup_fd); 129d4a89c1eSYiFei Zhu if (CHECK(IS_ERR(child_link), "child-cg-attach", 130d4a89c1eSYiFei Zhu "err %ld", PTR_ERR(child_link))) 131d4a89c1eSYiFei Zhu goto close_bpf_object; 132d4a89c1eSYiFei Zhu err = connect_send(CHILD_CGROUP); 133d4a89c1eSYiFei Zhu if (CHECK(err, "second-connect-send", "errno %d", errno)) 134d4a89c1eSYiFei Zhu goto close_bpf_object; 135d4a89c1eSYiFei Zhu if (CHECK(obj->bss->invocations != 3, 136d4a89c1eSYiFei Zhu "second-invoke", "invocations=%d", obj->bss->invocations)) 137d4a89c1eSYiFei Zhu goto close_bpf_object; 1383573f384SYiFei Zhu key.cgroup_inode_id = get_cgroup_id(PARENT_CGROUP); 1399e5bd1f7SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 2 }; 1409e5bd1f7SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 1413573f384SYiFei Zhu &key, &expected_cgroup_value)) 142d4a89c1eSYiFei Zhu goto close_bpf_object; 1433573f384SYiFei Zhu key.cgroup_inode_id = get_cgroup_id(CHILD_CGROUP); 1449e5bd1f7SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 1 }; 1459e5bd1f7SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 1463573f384SYiFei Zhu &key, &expected_cgroup_value)) 147d4a89c1eSYiFei Zhu goto close_bpf_object; 148d4a89c1eSYiFei Zhu 149d4a89c1eSYiFei Zhu close_bpf_object: 150d4a89c1eSYiFei Zhu bpf_link__destroy(parent_link); 151d4a89c1eSYiFei Zhu bpf_link__destroy(child_link); 152d4a89c1eSYiFei Zhu 153d4a89c1eSYiFei Zhu cg_storage_multi_egress_only__destroy(obj); 154d4a89c1eSYiFei Zhu } 155d4a89c1eSYiFei Zhu 1563573f384SYiFei Zhu static void test_isolated(int parent_cgroup_fd, int child_cgroup_fd) 1579e5bd1f7SYiFei Zhu { 1583573f384SYiFei Zhu struct cg_storage_multi_isolated *obj; 1593573f384SYiFei Zhu struct cgroup_value expected_cgroup_value; 1603573f384SYiFei Zhu struct bpf_cgroup_storage_key key; 1613573f384SYiFei Zhu struct bpf_link *parent_egress1_link = NULL, *parent_egress2_link = NULL; 1623573f384SYiFei Zhu struct bpf_link *child_egress1_link = NULL, *child_egress2_link = NULL; 1633573f384SYiFei Zhu struct bpf_link *parent_ingress_link = NULL, *child_ingress_link = NULL; 1643573f384SYiFei Zhu bool err; 1659e5bd1f7SYiFei Zhu 1663573f384SYiFei Zhu obj = cg_storage_multi_isolated__open_and_load(); 1673573f384SYiFei Zhu if (CHECK(!obj, "skel-load", "errno %d", errno)) 1683573f384SYiFei Zhu return; 1693573f384SYiFei Zhu 1703573f384SYiFei Zhu /* Attach to parent cgroup, trigger packet from child. 1713573f384SYiFei Zhu * Assert that there is three runs, two with parent cgroup egress and 1723573f384SYiFei Zhu * one with parent cgroup ingress, stored in separate parent storages. 1733573f384SYiFei Zhu * Also assert that child cgroup's storages does not exist 1749e5bd1f7SYiFei Zhu */ 1753573f384SYiFei Zhu parent_egress1_link = bpf_program__attach_cgroup(obj->progs.egress1, 1763573f384SYiFei Zhu parent_cgroup_fd); 1773573f384SYiFei Zhu if (CHECK(IS_ERR(parent_egress1_link), "parent-egress1-cg-attach", 1783573f384SYiFei Zhu "err %ld", PTR_ERR(parent_egress1_link))) 1793573f384SYiFei Zhu goto close_bpf_object; 1803573f384SYiFei Zhu parent_egress2_link = bpf_program__attach_cgroup(obj->progs.egress2, 1813573f384SYiFei Zhu parent_cgroup_fd); 1823573f384SYiFei Zhu if (CHECK(IS_ERR(parent_egress2_link), "parent-egress2-cg-attach", 1833573f384SYiFei Zhu "err %ld", PTR_ERR(parent_egress2_link))) 1843573f384SYiFei Zhu goto close_bpf_object; 1853573f384SYiFei Zhu parent_ingress_link = bpf_program__attach_cgroup(obj->progs.ingress, 1863573f384SYiFei Zhu parent_cgroup_fd); 1873573f384SYiFei Zhu if (CHECK(IS_ERR(parent_ingress_link), "parent-ingress-cg-attach", 1883573f384SYiFei Zhu "err %ld", PTR_ERR(parent_ingress_link))) 1893573f384SYiFei Zhu goto close_bpf_object; 1903573f384SYiFei Zhu err = connect_send(CHILD_CGROUP); 1913573f384SYiFei Zhu if (CHECK(err, "first-connect-send", "errno %d", errno)) 1923573f384SYiFei Zhu goto close_bpf_object; 1933573f384SYiFei Zhu if (CHECK(obj->bss->invocations != 3, 1943573f384SYiFei Zhu "first-invoke", "invocations=%d", obj->bss->invocations)) 1953573f384SYiFei Zhu goto close_bpf_object; 1963573f384SYiFei Zhu key.cgroup_inode_id = get_cgroup_id(PARENT_CGROUP); 1973573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_EGRESS; 1983573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 2 }; 1993573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 2003573f384SYiFei Zhu &key, &expected_cgroup_value)) 2013573f384SYiFei Zhu goto close_bpf_object; 2023573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_INGRESS; 2033573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .ingress_pkts = 1 }; 2043573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 2053573f384SYiFei Zhu &key, &expected_cgroup_value)) 2063573f384SYiFei Zhu goto close_bpf_object; 2073573f384SYiFei Zhu key.cgroup_inode_id = get_cgroup_id(CHILD_CGROUP); 2083573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_EGRESS; 2093573f384SYiFei Zhu if (assert_storage_noexist(obj->maps.cgroup_storage, &key)) 2103573f384SYiFei Zhu goto close_bpf_object; 2113573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_INGRESS; 2123573f384SYiFei Zhu if (assert_storage_noexist(obj->maps.cgroup_storage, &key)) 2133573f384SYiFei Zhu goto close_bpf_object; 2149e5bd1f7SYiFei Zhu 2153573f384SYiFei Zhu /* Attach to parent and child cgroup, trigger packet from child. 2163573f384SYiFei Zhu * Assert that there is six additional runs, parent cgroup egresses and 2173573f384SYiFei Zhu * ingress, child cgroup egresses and ingress. 2183573f384SYiFei Zhu * Assert that egree and ingress storages are separate. 2193573f384SYiFei Zhu */ 2203573f384SYiFei Zhu child_egress1_link = bpf_program__attach_cgroup(obj->progs.egress1, 2213573f384SYiFei Zhu child_cgroup_fd); 2223573f384SYiFei Zhu if (CHECK(IS_ERR(child_egress1_link), "child-egress1-cg-attach", 2233573f384SYiFei Zhu "err %ld", PTR_ERR(child_egress1_link))) 2243573f384SYiFei Zhu goto close_bpf_object; 2253573f384SYiFei Zhu child_egress2_link = bpf_program__attach_cgroup(obj->progs.egress2, 2263573f384SYiFei Zhu child_cgroup_fd); 2273573f384SYiFei Zhu if (CHECK(IS_ERR(child_egress2_link), "child-egress2-cg-attach", 2283573f384SYiFei Zhu "err %ld", PTR_ERR(child_egress2_link))) 2293573f384SYiFei Zhu goto close_bpf_object; 2303573f384SYiFei Zhu child_ingress_link = bpf_program__attach_cgroup(obj->progs.ingress, 2313573f384SYiFei Zhu child_cgroup_fd); 2323573f384SYiFei Zhu if (CHECK(IS_ERR(child_ingress_link), "child-ingress-cg-attach", 2333573f384SYiFei Zhu "err %ld", PTR_ERR(child_ingress_link))) 2343573f384SYiFei Zhu goto close_bpf_object; 2353573f384SYiFei Zhu err = connect_send(CHILD_CGROUP); 2363573f384SYiFei Zhu if (CHECK(err, "second-connect-send", "errno %d", errno)) 2373573f384SYiFei Zhu goto close_bpf_object; 2383573f384SYiFei Zhu if (CHECK(obj->bss->invocations != 9, 2393573f384SYiFei Zhu "second-invoke", "invocations=%d", obj->bss->invocations)) 2403573f384SYiFei Zhu goto close_bpf_object; 2413573f384SYiFei Zhu key.cgroup_inode_id = get_cgroup_id(PARENT_CGROUP); 2423573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_EGRESS; 2433573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 4 }; 2443573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 2453573f384SYiFei Zhu &key, &expected_cgroup_value)) 2463573f384SYiFei Zhu goto close_bpf_object; 2473573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_INGRESS; 2483573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .ingress_pkts = 2 }; 2493573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 2503573f384SYiFei Zhu &key, &expected_cgroup_value)) 2513573f384SYiFei Zhu goto close_bpf_object; 2523573f384SYiFei Zhu key.cgroup_inode_id = get_cgroup_id(CHILD_CGROUP); 2533573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_EGRESS; 2543573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .egress_pkts = 2 }; 2553573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 2563573f384SYiFei Zhu &key, &expected_cgroup_value)) 2573573f384SYiFei Zhu goto close_bpf_object; 2583573f384SYiFei Zhu key.attach_type = BPF_CGROUP_INET_INGRESS; 2593573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { .ingress_pkts = 1 }; 2603573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 2613573f384SYiFei Zhu &key, &expected_cgroup_value)) 2623573f384SYiFei Zhu goto close_bpf_object; 2633573f384SYiFei Zhu 2643573f384SYiFei Zhu close_bpf_object: 2653573f384SYiFei Zhu bpf_link__destroy(parent_egress1_link); 2663573f384SYiFei Zhu bpf_link__destroy(parent_egress2_link); 2673573f384SYiFei Zhu bpf_link__destroy(parent_ingress_link); 2683573f384SYiFei Zhu bpf_link__destroy(child_egress1_link); 2693573f384SYiFei Zhu bpf_link__destroy(child_egress2_link); 2703573f384SYiFei Zhu bpf_link__destroy(child_ingress_link); 2713573f384SYiFei Zhu 2723573f384SYiFei Zhu cg_storage_multi_isolated__destroy(obj); 2733573f384SYiFei Zhu } 2743573f384SYiFei Zhu 2753573f384SYiFei Zhu static void test_shared(int parent_cgroup_fd, int child_cgroup_fd) 2763573f384SYiFei Zhu { 2773573f384SYiFei Zhu struct cg_storage_multi_shared *obj; 2783573f384SYiFei Zhu struct cgroup_value expected_cgroup_value; 2793573f384SYiFei Zhu __u64 key; 2803573f384SYiFei Zhu struct bpf_link *parent_egress1_link = NULL, *parent_egress2_link = NULL; 2813573f384SYiFei Zhu struct bpf_link *child_egress1_link = NULL, *child_egress2_link = NULL; 2823573f384SYiFei Zhu struct bpf_link *parent_ingress_link = NULL, *child_ingress_link = NULL; 2833573f384SYiFei Zhu bool err; 2843573f384SYiFei Zhu 2853573f384SYiFei Zhu obj = cg_storage_multi_shared__open_and_load(); 2863573f384SYiFei Zhu if (CHECK(!obj, "skel-load", "errno %d", errno)) 2873573f384SYiFei Zhu return; 2883573f384SYiFei Zhu 2893573f384SYiFei Zhu /* Attach to parent cgroup, trigger packet from child. 2903573f384SYiFei Zhu * Assert that there is three runs, two with parent cgroup egress and 2913573f384SYiFei Zhu * one with parent cgroup ingress. 2923573f384SYiFei Zhu * Also assert that child cgroup's storage does not exist 2933573f384SYiFei Zhu */ 2943573f384SYiFei Zhu parent_egress1_link = bpf_program__attach_cgroup(obj->progs.egress1, 2953573f384SYiFei Zhu parent_cgroup_fd); 2963573f384SYiFei Zhu if (CHECK(IS_ERR(parent_egress1_link), "parent-egress1-cg-attach", 2973573f384SYiFei Zhu "err %ld", PTR_ERR(parent_egress1_link))) 2983573f384SYiFei Zhu goto close_bpf_object; 2993573f384SYiFei Zhu parent_egress2_link = bpf_program__attach_cgroup(obj->progs.egress2, 3003573f384SYiFei Zhu parent_cgroup_fd); 3013573f384SYiFei Zhu if (CHECK(IS_ERR(parent_egress2_link), "parent-egress2-cg-attach", 3023573f384SYiFei Zhu "err %ld", PTR_ERR(parent_egress2_link))) 3033573f384SYiFei Zhu goto close_bpf_object; 3043573f384SYiFei Zhu parent_ingress_link = bpf_program__attach_cgroup(obj->progs.ingress, 3053573f384SYiFei Zhu parent_cgroup_fd); 3063573f384SYiFei Zhu if (CHECK(IS_ERR(parent_ingress_link), "parent-ingress-cg-attach", 3073573f384SYiFei Zhu "err %ld", PTR_ERR(parent_ingress_link))) 3083573f384SYiFei Zhu goto close_bpf_object; 3093573f384SYiFei Zhu err = connect_send(CHILD_CGROUP); 3103573f384SYiFei Zhu if (CHECK(err, "first-connect-send", "errno %d", errno)) 3113573f384SYiFei Zhu goto close_bpf_object; 3123573f384SYiFei Zhu if (CHECK(obj->bss->invocations != 3, 3133573f384SYiFei Zhu "first-invoke", "invocations=%d", obj->bss->invocations)) 3143573f384SYiFei Zhu goto close_bpf_object; 3153573f384SYiFei Zhu key = get_cgroup_id(PARENT_CGROUP); 3163573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { 3173573f384SYiFei Zhu .egress_pkts = 2, 3183573f384SYiFei Zhu .ingress_pkts = 1, 3193573f384SYiFei Zhu }; 3203573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 3213573f384SYiFei Zhu &key, &expected_cgroup_value)) 3223573f384SYiFei Zhu goto close_bpf_object; 3233573f384SYiFei Zhu key = get_cgroup_id(CHILD_CGROUP); 3243573f384SYiFei Zhu if (assert_storage_noexist(obj->maps.cgroup_storage, &key)) 3253573f384SYiFei Zhu goto close_bpf_object; 3263573f384SYiFei Zhu 3273573f384SYiFei Zhu /* Attach to parent and child cgroup, trigger packet from child. 3283573f384SYiFei Zhu * Assert that there is six additional runs, parent cgroup egresses and 3293573f384SYiFei Zhu * ingress, child cgroup egresses and ingress. 3303573f384SYiFei Zhu */ 3313573f384SYiFei Zhu child_egress1_link = bpf_program__attach_cgroup(obj->progs.egress1, 3323573f384SYiFei Zhu child_cgroup_fd); 3333573f384SYiFei Zhu if (CHECK(IS_ERR(child_egress1_link), "child-egress1-cg-attach", 3343573f384SYiFei Zhu "err %ld", PTR_ERR(child_egress1_link))) 3353573f384SYiFei Zhu goto close_bpf_object; 3363573f384SYiFei Zhu child_egress2_link = bpf_program__attach_cgroup(obj->progs.egress2, 3373573f384SYiFei Zhu child_cgroup_fd); 3383573f384SYiFei Zhu if (CHECK(IS_ERR(child_egress2_link), "child-egress2-cg-attach", 3393573f384SYiFei Zhu "err %ld", PTR_ERR(child_egress2_link))) 3403573f384SYiFei Zhu goto close_bpf_object; 3413573f384SYiFei Zhu child_ingress_link = bpf_program__attach_cgroup(obj->progs.ingress, 3423573f384SYiFei Zhu child_cgroup_fd); 3433573f384SYiFei Zhu if (CHECK(IS_ERR(child_ingress_link), "child-ingress-cg-attach", 3443573f384SYiFei Zhu "err %ld", PTR_ERR(child_ingress_link))) 3453573f384SYiFei Zhu goto close_bpf_object; 3463573f384SYiFei Zhu err = connect_send(CHILD_CGROUP); 3473573f384SYiFei Zhu if (CHECK(err, "second-connect-send", "errno %d", errno)) 3483573f384SYiFei Zhu goto close_bpf_object; 3493573f384SYiFei Zhu if (CHECK(obj->bss->invocations != 9, 3503573f384SYiFei Zhu "second-invoke", "invocations=%d", obj->bss->invocations)) 3513573f384SYiFei Zhu goto close_bpf_object; 3523573f384SYiFei Zhu key = get_cgroup_id(PARENT_CGROUP); 3533573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { 3543573f384SYiFei Zhu .egress_pkts = 4, 3553573f384SYiFei Zhu .ingress_pkts = 2, 3563573f384SYiFei Zhu }; 3573573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 3583573f384SYiFei Zhu &key, &expected_cgroup_value)) 3593573f384SYiFei Zhu goto close_bpf_object; 3603573f384SYiFei Zhu key = get_cgroup_id(CHILD_CGROUP); 3613573f384SYiFei Zhu expected_cgroup_value = (struct cgroup_value) { 3623573f384SYiFei Zhu .egress_pkts = 2, 3633573f384SYiFei Zhu .ingress_pkts = 1, 3643573f384SYiFei Zhu }; 3653573f384SYiFei Zhu if (assert_storage(obj->maps.cgroup_storage, 3663573f384SYiFei Zhu &key, &expected_cgroup_value)) 3673573f384SYiFei Zhu goto close_bpf_object; 3683573f384SYiFei Zhu 3693573f384SYiFei Zhu close_bpf_object: 3703573f384SYiFei Zhu bpf_link__destroy(parent_egress1_link); 3713573f384SYiFei Zhu bpf_link__destroy(parent_egress2_link); 3723573f384SYiFei Zhu bpf_link__destroy(parent_ingress_link); 3733573f384SYiFei Zhu bpf_link__destroy(child_egress1_link); 3743573f384SYiFei Zhu bpf_link__destroy(child_egress2_link); 3753573f384SYiFei Zhu bpf_link__destroy(child_ingress_link); 3763573f384SYiFei Zhu 3773573f384SYiFei Zhu cg_storage_multi_shared__destroy(obj); 3789e5bd1f7SYiFei Zhu } 3799e5bd1f7SYiFei Zhu 380d4a89c1eSYiFei Zhu void test_cg_storage_multi(void) 381d4a89c1eSYiFei Zhu { 382d4a89c1eSYiFei Zhu int parent_cgroup_fd = -1, child_cgroup_fd = -1; 383d4a89c1eSYiFei Zhu 384d4a89c1eSYiFei Zhu parent_cgroup_fd = test__join_cgroup(PARENT_CGROUP); 385d4a89c1eSYiFei Zhu if (CHECK(parent_cgroup_fd < 0, "cg-create-parent", "errno %d", errno)) 386d4a89c1eSYiFei Zhu goto close_cgroup_fd; 387d4a89c1eSYiFei Zhu child_cgroup_fd = create_and_get_cgroup(CHILD_CGROUP); 388d4a89c1eSYiFei Zhu if (CHECK(child_cgroup_fd < 0, "cg-create-child", "errno %d", errno)) 389d4a89c1eSYiFei Zhu goto close_cgroup_fd; 390d4a89c1eSYiFei Zhu 391d4a89c1eSYiFei Zhu if (test__start_subtest("egress_only")) 392d4a89c1eSYiFei Zhu test_egress_only(parent_cgroup_fd, child_cgroup_fd); 393d4a89c1eSYiFei Zhu 3943573f384SYiFei Zhu if (test__start_subtest("isolated")) 3953573f384SYiFei Zhu test_isolated(parent_cgroup_fd, child_cgroup_fd); 3963573f384SYiFei Zhu 3973573f384SYiFei Zhu if (test__start_subtest("shared")) 3983573f384SYiFei Zhu test_shared(parent_cgroup_fd, child_cgroup_fd); 3999e5bd1f7SYiFei Zhu 400d4a89c1eSYiFei Zhu close_cgroup_fd: 401d4a89c1eSYiFei Zhu close(child_cgroup_fd); 402d4a89c1eSYiFei Zhu close(parent_cgroup_fd); 403d4a89c1eSYiFei Zhu } 404