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


Quelle  assign_reuse.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2023 Isovalent */
#include <uapi/linux/if_link.h>
#include <test_progs.h>

#include <netinet/tcp.h>
#include <netinet/udp.h>

#include "network_helpers.h"
#include "test_assign_reuse.skel.h"

#define NS_TEST "assign_reuse"
#define LOOPBACK 1
#define PORT 4443

static int attach_reuseport(int sock_fd, int prog_fd)
{
 return setsockopt(sock_fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_EBPF,
     &prog_fd, sizeof(prog_fd));
}

static __u64 cookie(int fd)
{
 __u64 cookie = 0;
 socklen_t cookie_len = sizeof(cookie);
 int ret;

 ret = getsockopt(fd, SOL_SOCKET, SO_COOKIE, &cookie, &cookie_len);
 ASSERT_OK(ret, "cookie");
 ASSERT_GT(cookie, 0, "cookie_invalid");

 return cookie;
}

static int echo_test_udp(int fd_sv)
{
 struct sockaddr_storage addr = {};
 socklen_t len = sizeof(addr);
 char buff[1] = {};
 int fd_cl = -1, ret;

 fd_cl = connect_to_fd(fd_sv, 100);
 ASSERT_GT(fd_cl, 0, "create_client");
 ASSERT_EQ(getsockname(fd_cl, (void *)&addr, &len), 0, "getsockname");

 ASSERT_EQ(send(fd_cl, buff, sizeof(buff), 0), 1, "send_client");

 ret = recv(fd_sv, buff, sizeof(buff), 0);
 if (ret < 0) {
  close(fd_cl);
  return errno;
 }

 ASSERT_EQ(ret, 1, "recv_server");
 ASSERT_EQ(sendto(fd_sv, buff, sizeof(buff), 0, (void *)&addr, len), 1, "send_server");
 ASSERT_EQ(recv(fd_cl, buff, sizeof(buff), 0), 1, "recv_client");
 close(fd_cl);
 return 0;
}

static int echo_test_tcp(int fd_sv)
{
 char buff[1] = {};
 int fd_cl = -1, fd_sv_cl = -1;

 fd_cl = connect_to_fd(fd_sv, 100);
 if (fd_cl < 0)
  return errno;

 fd_sv_cl = accept(fd_sv, NULL, NULL);
 ASSERT_GE(fd_sv_cl, 0, "accept_fd");

 ASSERT_EQ(send(fd_cl, buff, sizeof(buff), 0), 1, "send_client");
 ASSERT_EQ(recv(fd_sv_cl, buff, sizeof(buff), 0), 1, "recv_server");
 ASSERT_EQ(send(fd_sv_cl, buff, sizeof(buff), 0), 1, "send_server");
 ASSERT_EQ(recv(fd_cl, buff, sizeof(buff), 0), 1, "recv_client");
 close(fd_sv_cl);
 close(fd_cl);
 return 0;
}

void run_assign_reuse(int family, int sotype, const char *ip, __u16 port)
{
 DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook,
  .ifindex = LOOPBACK,
  .attach_point = BPF_TC_INGRESS,
 );
 DECLARE_LIBBPF_OPTS(bpf_tc_opts, tc_opts,
  .handle = 1,
  .priority = 1,
 );
 bool hook_created = false, tc_attached = false;
 int ret, fd_tc, fd_accept, fd_drop, fd_map;
 int *fd_sv = NULL;
 __u64 fd_val;
 struct test_assign_reuse *skel;
 const int zero = 0;

 skel = test_assign_reuse__open();
 if (!ASSERT_OK_PTR(skel, "skel_open"))
  goto cleanup;

 skel->rodata->dest_port = port;

 ret = test_assign_reuse__load(skel);
 if (!ASSERT_OK(ret, "skel_load"))
  goto cleanup;

 ASSERT_EQ(skel->bss->sk_cookie_seen, 0, "cookie_init");

 fd_tc = bpf_program__fd(skel->progs.tc_main);
 fd_accept = bpf_program__fd(skel->progs.reuse_accept);
 fd_drop = bpf_program__fd(skel->progs.reuse_drop);
 fd_map = bpf_map__fd(skel->maps.sk_map);

 fd_sv = start_reuseport_server(family, sotype, ip, port, 100, 1);
 if (!ASSERT_NEQ(fd_sv, NULL, "start_reuseport_server"))
  goto cleanup;

 ret = attach_reuseport(*fd_sv, fd_drop);
 if (!ASSERT_OK(ret, "attach_reuseport"))
  goto cleanup;

 fd_val = *fd_sv;
 ret = bpf_map_update_elem(fd_map, &zero, &fd_val, BPF_NOEXIST);
 if (!ASSERT_OK(ret, "bpf_sk_map"))
  goto cleanup;

 ret = bpf_tc_hook_create(&tc_hook);
 if (ret == 0)
  hook_created = true;
 ret = ret == -EEXIST ? 0 : ret;
 if (!ASSERT_OK(ret, "bpf_tc_hook_create"))
  goto cleanup;

 tc_opts.prog_fd = fd_tc;
 ret = bpf_tc_attach(&tc_hook, &tc_opts);
 if (!ASSERT_OK(ret, "bpf_tc_attach"))
  goto cleanup;
 tc_attached = true;

 if (sotype == SOCK_STREAM)
  ASSERT_EQ(echo_test_tcp(*fd_sv), ECONNREFUSED, "drop_tcp");
 else
  ASSERT_EQ(echo_test_udp(*fd_sv), EAGAIN, "drop_udp");
 ASSERT_EQ(skel->bss->reuseport_executed, 1, "program executed once");

 skel->bss->sk_cookie_seen = 0;
 skel->bss->reuseport_executed = 0;
 ASSERT_OK(attach_reuseport(*fd_sv, fd_accept), "attach_reuseport(accept)");

 if (sotype == SOCK_STREAM)
  ASSERT_EQ(echo_test_tcp(*fd_sv), 0, "echo_tcp");
 else
  ASSERT_EQ(echo_test_udp(*fd_sv), 0, "echo_udp");

 ASSERT_EQ(skel->bss->sk_cookie_seen, cookie(*fd_sv),
    "cookie_mismatch");
 ASSERT_EQ(skel->bss->reuseport_executed, 1, "program executed once");
cleanup:
 if (tc_attached) {
  tc_opts.flags = tc_opts.prog_fd = tc_opts.prog_id = 0;
  ret = bpf_tc_detach(&tc_hook, &tc_opts);
  ASSERT_OK(ret, "bpf_tc_detach");
 }
 if (hook_created) {
  tc_hook.attach_point = BPF_TC_INGRESS | BPF_TC_EGRESS;
  bpf_tc_hook_destroy(&tc_hook);
 }
 test_assign_reuse__destroy(skel);
 free_fds(fd_sv, 1);
}

void test_assign_reuse(void)
{
 struct nstoken *tok = NULL;

 SYS(out, "ip netns add %s", NS_TEST);
 SYS(cleanup, "ip -net %s link set dev lo up", NS_TEST);

 tok = open_netns(NS_TEST);
 if (!ASSERT_OK_PTR(tok, "netns token"))
  return;

 if (test__start_subtest("tcpv4"))
  run_assign_reuse(AF_INET, SOCK_STREAM, "127.0.0.1", PORT);
 if (test__start_subtest("tcpv6"))
  run_assign_reuse(AF_INET6, SOCK_STREAM, "::1", PORT);
 if (test__start_subtest("udpv4"))
  run_assign_reuse(AF_INET, SOCK_DGRAM, "127.0.0.1", PORT);
 if (test__start_subtest("udpv6"))
  run_assign_reuse(AF_INET6, SOCK_DGRAM, "::1", PORT);

cleanup:
 close_netns(tok);
 SYS_NOFAIL("ip netns delete %s", NS_TEST);
out:
 return;
}

Messung V0.5
C=95 H=86 G=90

¤ Dauer der Verarbeitung: 0.19 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


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