Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/tools/testing/selftests/bpf/prog_tests/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 7 kB image not shown  

Quelle  cgroup_link.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0

#include <test_progs.h>
#include "cgroup_helpers.h"
#include "testing_helpers.h"
#include "test_cgroup_link.skel.h"

static __u32 duration = 0;
#define PING_CMD "ping -q -c1 -w1 127.0.0.1 > /dev/null"

static struct test_cgroup_link *skel = NULL;

int ping_and_check(int exp_calls, int exp_alt_calls)
{
 skel->bss->calls = 0;
 skel->bss->alt_calls = 0;
 CHECK_FAIL(system(PING_CMD));
 if (CHECK(skel->bss->calls != exp_calls, "call_cnt",
    "exp %d, got %d\n", exp_calls, skel->bss->calls))
  return -EINVAL;
 if (CHECK(skel->bss->alt_calls != exp_alt_calls, "alt_call_cnt",
    "exp %d, got %d\n", exp_alt_calls, skel->bss->alt_calls))
  return -EINVAL;
 return 0;
}

void serial_test_cgroup_link(void)
{
 struct {
  const char *path;
  int fd;
 } cgs[] = {
  { "/cg1" },
  { "/cg1/cg2" },
  { "/cg1/cg2/cg3" },
  { "/cg1/cg2/cg3/cg4" },
 };
 int last_cg = ARRAY_SIZE(cgs) - 1, cg_nr = ARRAY_SIZE(cgs);
 DECLARE_LIBBPF_OPTS(bpf_link_update_opts, link_upd_opts);
 struct bpf_link *links[ARRAY_SIZE(cgs)] = {}, *tmp_link;
 __u32 prog_ids[ARRAY_SIZE(cgs)], prog_cnt = 0, attach_flags, prog_id;
 struct bpf_link_info info;
 int i = 0, err, prog_fd;
 bool detach_legacy = false;

 skel = test_cgroup_link__open_and_load();
 if (CHECK(!skel, "skel_open_load""failed to open/load skeleton\n"))
  return;
 prog_fd = bpf_program__fd(skel->progs.egress);

 err = setup_cgroup_environment();
 if (CHECK(err, "cg_init""failed: %d\n", err))
  goto cleanup;

 for (i = 0; i < cg_nr; i++) {
  cgs[i].fd = create_and_get_cgroup(cgs[i].path);
  if (!ASSERT_GE(cgs[i].fd, 0, "cg_create"))
   goto cleanup;
 }

 err = join_cgroup(cgs[last_cg].path);
 if (CHECK(err, "cg_join""fail: %d\n", err))
  goto cleanup;

 for (i = 0; i < cg_nr; i++) {
  links[i] = bpf_program__attach_cgroup(skel->progs.egress,
            cgs[i].fd);
  if (!ASSERT_OK_PTR(links[i], "cg_attach"))
   goto cleanup;
 }

 ping_and_check(cg_nr, 0);

 /* query the number of attached progs and attach flags in root cg */
 err = bpf_prog_query(cgs[0].fd, BPF_CGROUP_INET_EGRESS,
        0, &attach_flags, NULL, &prog_cnt);
 CHECK_FAIL(err);
 CHECK_FAIL(attach_flags != BPF_F_ALLOW_MULTI);
 if (CHECK(prog_cnt != 1, "effect_cnt""exp %d, got %d\n", 1, prog_cnt))
  goto cleanup;

 /* query the number of effective progs in last cg */
 err = bpf_prog_query(cgs[last_cg].fd, BPF_CGROUP_INET_EGRESS,
        BPF_F_QUERY_EFFECTIVE, NULL, NULL,
        &prog_cnt);
 CHECK_FAIL(err);
 if (CHECK(prog_cnt != cg_nr, "effect_cnt""exp %d, got %d\n",
    cg_nr, prog_cnt))
  goto cleanup;

 /* query the effective prog IDs in last cg */
 err = bpf_prog_query(cgs[last_cg].fd, BPF_CGROUP_INET_EGRESS,
        BPF_F_QUERY_EFFECTIVE, NULL, prog_ids,
        &prog_cnt);
 CHECK_FAIL(err);
 if (CHECK(prog_cnt != cg_nr, "effect_cnt""exp %d, got %d\n",
    cg_nr, prog_cnt))
  goto cleanup;
 for (i = 1; i < prog_cnt; i++) {
  CHECK(prog_ids[i - 1] != prog_ids[i], "prog_id_check",
        "idx %d, prev id %d, cur id %d\n",
        i, prog_ids[i - 1], prog_ids[i]);
 }

 /* detach bottom program and ping again */
 bpf_link__destroy(links[last_cg]);
 links[last_cg] = NULL;

 ping_and_check(cg_nr - 1, 0);

 /* mix in with non link-based multi-attachments */
 err = bpf_prog_attach(prog_fd, cgs[last_cg].fd,
         BPF_CGROUP_INET_EGRESS, BPF_F_ALLOW_MULTI);
 if (CHECK(err, "cg_attach_legacy""errno=%d\n", errno))
  goto cleanup;
 detach_legacy = true;

 links[last_cg] = bpf_program__attach_cgroup(skel->progs.egress,
          cgs[last_cg].fd);
 if (!ASSERT_OK_PTR(links[last_cg], "cg_attach"))
  goto cleanup;

 ping_and_check(cg_nr + 1, 0);

 /* detach link */
 bpf_link__destroy(links[last_cg]);
 links[last_cg] = NULL;

 /* detach legacy */
 err = bpf_prog_detach2(prog_fd, cgs[last_cg].fd, BPF_CGROUP_INET_EGRESS);
 if (CHECK(err, "cg_detach_legacy""errno=%d\n", errno))
  goto cleanup;
 detach_legacy = false;

 /* attach legacy exclusive prog attachment */
 err = bpf_prog_attach(prog_fd, cgs[last_cg].fd,
         BPF_CGROUP_INET_EGRESS, 0);
 if (CHECK(err, "cg_attach_exclusive""errno=%d\n", errno))
  goto cleanup;
 detach_legacy = true;

 /* attempt to mix in with multi-attach bpf_link */
 tmp_link = bpf_program__attach_cgroup(skel->progs.egress,
           cgs[last_cg].fd);
 if (!ASSERT_ERR_PTR(tmp_link, "cg_attach_fail")) {
  bpf_link__destroy(tmp_link);
  goto cleanup;
 }

 ping_and_check(cg_nr, 0);

 /* detach */
 err = bpf_prog_detach2(prog_fd, cgs[last_cg].fd, BPF_CGROUP_INET_EGRESS);
 if (CHECK(err, "cg_detach_legacy""errno=%d\n", errno))
  goto cleanup;
 detach_legacy = false;

 ping_and_check(cg_nr - 1, 0);

 /* attach back link-based one */
 links[last_cg] = bpf_program__attach_cgroup(skel->progs.egress,
          cgs[last_cg].fd);
 if (!ASSERT_OK_PTR(links[last_cg], "cg_attach"))
  goto cleanup;

 ping_and_check(cg_nr, 0);

 /* check legacy exclusive prog can't be attached */
 err = bpf_prog_attach(prog_fd, cgs[last_cg].fd,
         BPF_CGROUP_INET_EGRESS, 0);
 if (CHECK(!err, "cg_attach_exclusive""unexpected success")) {
  bpf_prog_detach2(prog_fd, cgs[last_cg].fd, BPF_CGROUP_INET_EGRESS);
  goto cleanup;
 }

 /* replace BPF programs inside their links for all but first link */
 for (i = 1; i < cg_nr; i++) {
  err = bpf_link__update_program(links[i], skel->progs.egress_alt);
  if (CHECK(err, "prog_upd""link #%d\n", i))
   goto cleanup;
 }

 ping_and_check(1, cg_nr - 1);

 /* Attempt program update with wrong expected BPF program */
 link_upd_opts.old_prog_fd = bpf_program__fd(skel->progs.egress_alt);
 link_upd_opts.flags = BPF_F_REPLACE;
 err = bpf_link_update(bpf_link__fd(links[0]),
         bpf_program__fd(skel->progs.egress_alt),
         &link_upd_opts);
 if (CHECK(err == 0 || errno != EPERM, "prog_cmpxchg1",
    "unexpectedly succeeded, err %d, errno %d\n", err, -errno))
  goto cleanup;

 /* Compare-exchange single link program from egress to egress_alt */
 link_upd_opts.old_prog_fd = bpf_program__fd(skel->progs.egress);
 link_upd_opts.flags = BPF_F_REPLACE;
 err = bpf_link_update(bpf_link__fd(links[0]),
         bpf_program__fd(skel->progs.egress_alt),
         &link_upd_opts);
 if (CHECK(err, "prog_cmpxchg2""errno %d\n", -errno))
  goto cleanup;

 /* ping */
 ping_and_check(0, cg_nr);

 /* close cgroup FDs before detaching links */
 for (i = 0; i < cg_nr; i++) {
  if (cgs[i].fd > 0) {
   close(cgs[i].fd);
   cgs[i].fd = -1;
  }
 }

 /* BPF programs should still get called */
 ping_and_check(0, cg_nr);

 prog_id = link_info_prog_id(links[0], &info);
 CHECK(prog_id == 0, "link_info""failed\n");
 CHECK(info.cgroup.cgroup_id == 0, "cgroup_id""unexpected %llu\n", info.cgroup.cgroup_id);

 err = bpf_link__detach(links[0]);
 if (CHECK(err, "link_detach""failed %d\n", err))
  goto cleanup;

 /* cgroup_id should be zero in link_info */
 prog_id = link_info_prog_id(links[0], &info);
 CHECK(prog_id == 0, "link_info""failed\n");
 CHECK(info.cgroup.cgroup_id != 0, "cgroup_id""unexpected %llu\n", info.cgroup.cgroup_id);

 /* First BPF program shouldn't be called anymore */
 ping_and_check(0, cg_nr - 1);

 /* leave cgroup and remove them, don't detach programs */
 cleanup_cgroup_environment();

 /* BPF programs should have been auto-detached */
 ping_and_check(0, 0);

cleanup:
 if (detach_legacy)
  bpf_prog_detach2(prog_fd, cgs[last_cg].fd,
     BPF_CGROUP_INET_EGRESS);

 for (i = 0; i < cg_nr; i++) {
  bpf_link__destroy(links[i]);
 }
 test_cgroup_link__destroy(skel);

 for (i = 0; i < cg_nr; i++) {
  if (cgs[i].fd > 0)
   close(cgs[i].fd);
 }
 cleanup_cgroup_environment();
}

Messung V0.5
C=95 H=92 G=93

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.