Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


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.4 Sekunden  ¤

*© 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge