@@ -28,7 +28,6 @@ static bool assert_storage(struct bpf_map *map, const char *cgroup_path,
map_fd = bpf_map__fd(map);
key.cgroup_inode_id = get_cgroup_id(cgroup_path);
- key.attach_type = BPF_CGROUP_INET_EGRESS;
if (CHECK(bpf_map_lookup_elem(map_fd, &key, &value) < 0,
"map-lookup", "errno %d", errno))
return true;
@@ -48,7 +47,6 @@ static bool assert_storage_noexist(struct bpf_map *map, const char *cgroup_path)
map_fd = bpf_map__fd(map);
key.cgroup_inode_id = get_cgroup_id(cgroup_path);
- key.attach_type = BPF_CGROUP_INET_EGRESS;
if (CHECK(bpf_map_lookup_elem(map_fd, &key, &value) == 0,
"map-lookup", "succeeded, expected ENOENT"))
return true;
@@ -156,14 +154,92 @@ static void test_egress_only(int parent_cgroup_fd, int child_cgroup_fd)
static void test_egress_ingress(int parent_cgroup_fd, int child_cgroup_fd)
{
struct cg_storage_multi_egress_ingress *obj;
+ struct cgroup_value expected_cgroup_value;
+ struct bpf_link *parent_egress_link = NULL, *parent_ingress_link = NULL;
+ struct bpf_link *child_egress_link = NULL, *child_ingress_link = NULL;
+ bool err;
- /* Cannot load both programs due to verifier failure:
- * "only one cgroup storage of each type is allowed"
- */
obj = cg_storage_multi_egress_ingress__open_and_load();
- if (CHECK(obj || errno != EBUSY,
- "skel-load", "errno %d, expected EBUSY", errno))
+ if (CHECK(!obj, "skel-load", "errno %d", errno))
return;
+
+ /* Attach to parent cgroup, trigger packet from child.
+ * Assert that there is two runs, one with parent cgroup egress and
+ * one with parent cgroup ingress.
+ * Also assert that child cgroup's storage does not exist
+ */
+ parent_egress_link = bpf_program__attach_cgroup(obj->progs.egress,
+ parent_cgroup_fd);
+ if (CHECK(IS_ERR(parent_egress_link), "parent-egress-cg-attach",
+ "err %ld", PTR_ERR(parent_egress_link)))
+ goto close_bpf_object;
+ parent_ingress_link = bpf_program__attach_cgroup(obj->progs.ingress,
+ parent_cgroup_fd);
+ if (CHECK(IS_ERR(parent_ingress_link), "parent-ingress-cg-attach",
+ "err %ld", PTR_ERR(parent_ingress_link)))
+ goto close_bpf_object;
+ err = connect_send(CHILD_CGROUP);
+ if (CHECK(err, "first-connect-send", "errno %d", errno))
+ goto close_bpf_object;
+ if (CHECK(obj->bss->invocations != 2,
+ "first-invoke", "invocations=%d", obj->bss->invocations))
+ goto close_bpf_object;
+ expected_cgroup_value = (struct cgroup_value) {
+ .egress_pkts = 1,
+ .ingress_pkts = 1,
+ };
+ if (assert_storage(obj->maps.cgroup_storage,
+ PARENT_CGROUP, &expected_cgroup_value))
+ goto close_bpf_object;
+ if (assert_storage_noexist(obj->maps.cgroup_storage, CHILD_CGROUP))
+ goto close_bpf_object;
+
+ /* Attach to parent and child cgroup, trigger packet from child.
+ * Assert that there is four additional runs, parent cgroup egress and
+ * ingress, child cgroup egress and ingress.
+ */
+ child_egress_link = bpf_program__attach_cgroup(obj->progs.egress,
+ child_cgroup_fd);
+ if (CHECK(IS_ERR(child_egress_link), "child-egress-cg-attach",
+ "err %ld", PTR_ERR(child_egress_link)))
+ goto close_bpf_object;
+ child_ingress_link = bpf_program__attach_cgroup(obj->progs.ingress,
+ child_cgroup_fd);
+ if (CHECK(IS_ERR(child_ingress_link), "child-ingress-cg-attach",
+ "err %ld", PTR_ERR(child_ingress_link)))
+ goto close_bpf_object;
+ err = connect_send(CHILD_CGROUP);
+ if (CHECK(err, "second-connect-send", "errno %d", errno))
+ goto close_bpf_object;
+ if (CHECK(obj->bss->invocations != 6,
+ "second-invoke", "invocations=%d", obj->bss->invocations))
+ goto close_bpf_object;
+ expected_cgroup_value = (struct cgroup_value) {
+ .egress_pkts = 2,
+ .ingress_pkts = 2,
+ };
+ if (assert_storage(obj->maps.cgroup_storage,
+ PARENT_CGROUP, &expected_cgroup_value))
+ goto close_bpf_object;
+ expected_cgroup_value = (struct cgroup_value) {
+ .egress_pkts = 1,
+ .ingress_pkts = 1,
+ };
+ if (assert_storage(obj->maps.cgroup_storage,
+ CHILD_CGROUP, &expected_cgroup_value))
+ goto close_bpf_object;
+
+close_bpf_object:
+ if (parent_egress_link)
+ bpf_link__destroy(parent_egress_link);
+ if (parent_ingress_link)
+ bpf_link__destroy(parent_ingress_link);
+ if (child_egress_link)
+ bpf_link__destroy(child_egress_link);
+ if (child_ingress_link)
+ bpf_link__destroy(child_ingress_link);
+
+ cg_storage_multi_egress_ingress__destroy(obj);
}
void test_cg_storage_multi(void)