@@ -26,7 +26,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_FAIL(bpf_map_lookup_elem(map_fd, &key, &value) < 0))
return true;
if (CHECK_FAIL(memcmp(&value, expected, sizeof(struct cgroup_value))))
@@ -44,7 +43,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_FAIL(bpf_map_lookup_elem(map_fd, &key, &value) == 0))
return true;
if (CHECK_FAIL(errno != ENOENT))
@@ -147,16 +145,83 @@ 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;
+ int err;
if (!test__start_subtest("egress_ingress"))
return;
- /* 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_FAIL(obj || errno != EBUSY))
+ if (CHECK_FAIL(!obj))
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
+ */
+ err = bpf_prog_attach(bpf_program__fd(obj->progs.egress),
+ parent_cgroup_fd,
+ BPF_CGROUP_INET_EGRESS, BPF_F_ALLOW_MULTI);
+ if (CHECK_FAIL(err))
+ goto close_bpf_object;
+ err = bpf_prog_attach(bpf_program__fd(obj->progs.ingress),
+ parent_cgroup_fd,
+ BPF_CGROUP_INET_INGRESS, BPF_F_ALLOW_MULTI);
+ if (CHECK_FAIL(err))
+ goto close_bpf_object;
+ err = connect_send(CHILD_CGROUP);
+ if (CHECK_FAIL(err))
+ goto close_bpf_object;
+ if (CHECK_FAIL(obj->bss->invocations != 2))
+ goto close_bpf_object;
+ expected_cgroup_value = (struct cgroup_value) {
+ .egress_pkts = 1,
+ .ingress_pkts = 1,
+ };
+ if (CHECK_FAIL(assert_storage(obj->maps.cgroup_storage,
+ PARENT_CGROUP, &expected_cgroup_value)))
+ goto close_bpf_object;
+ if (CHECK_FAIL(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.
+ */
+ err = bpf_prog_attach(bpf_program__fd(obj->progs.egress),
+ child_cgroup_fd,
+ BPF_CGROUP_INET_EGRESS, BPF_F_ALLOW_MULTI);
+ if (CHECK_FAIL(err))
+ goto close_bpf_object;
+ err = bpf_prog_attach(bpf_program__fd(obj->progs.ingress),
+ child_cgroup_fd,
+ BPF_CGROUP_INET_INGRESS, BPF_F_ALLOW_MULTI);
+ if (CHECK_FAIL(err))
+ goto close_bpf_object;
+ err = connect_send(CHILD_CGROUP);
+ if (CHECK_FAIL(err))
+ goto close_bpf_object;
+ if (CHECK_FAIL(obj->bss->invocations != 6))
+ goto close_bpf_object;
+ expected_cgroup_value = (struct cgroup_value) {
+ .egress_pkts = 2,
+ .ingress_pkts = 2,
+ };
+ if (CHECK_FAIL(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 (CHECK_FAIL(assert_storage(obj->maps.cgroup_storage,
+ CHILD_CGROUP, &expected_cgroup_value)))
+ goto close_bpf_object;
+
+close_bpf_object:
+ cg_storage_multi_egress_ingress__destroy(obj);
}
void test_cg_storage_multi(void)