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 5 kB image not shown  

Quelle  sockopt_sk.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
#include <test_progs.h>
#include "cgroup_helpers.h"

#include <netinet/tcp.h>
#include <linux/netlink.h>
#include "sockopt_sk.skel.h"

#ifndef SOL_TCP
#define SOL_TCP IPPROTO_TCP
#endif

#define SOL_CUSTOM   0xdeadbeef

static int getsetsockopt(void)
{
 int fd, err;
 union {
  char u8[4];
  __u32 u32;
  char cc[16]; /* TCP_CA_NAME_MAX */
  struct tcp_zerocopy_receive zc;
 } buf = {};
 socklen_t optlen;
 char *big_buf = NULL;

 fd = socket(AF_INET, SOCK_STREAM, 0);
 if (fd < 0) {
  log_err("Failed to create socket");
  return -1;
 }

 /* IP_TOS - BPF bypass */

 optlen = getpagesize() * 2;
 big_buf = calloc(1, optlen);
 if (!big_buf) {
  log_err("Couldn't allocate two pages");
  goto err;
 }

 *(int *)big_buf = 0x08;
 err = setsockopt(fd, SOL_IP, IP_TOS, big_buf, optlen);
 if (err) {
  log_err("Failed to call setsockopt(IP_TOS)");
  goto err;
 }

 memset(big_buf, 0, optlen);
 optlen = 1;
 err = getsockopt(fd, SOL_IP, IP_TOS, big_buf, &optlen);
 if (err) {
  log_err("Failed to call getsockopt(IP_TOS)");
  goto err;
 }

 if (*big_buf != 0x08) {
  log_err("Unexpected getsockopt(IP_TOS) optval 0x%x != 0x08",
   (int)*big_buf);
  goto err;
 }

 /* IP_TTL - EPERM */

 buf.u8[0] = 1;
 err = setsockopt(fd, SOL_IP, IP_TTL, &buf, 1);
 if (!err || errno != EPERM) {
  log_err("Unexpected success from setsockopt(IP_TTL)");
  goto err;
 }

 /* SOL_CUSTOM - handled by BPF */

 buf.u8[0] = 0x01;
 err = setsockopt(fd, SOL_CUSTOM, 0, &buf, 1);
 if (err) {
  log_err("Failed to call setsockopt");
  goto err;
 }

 buf.u32 = 0x00;
 optlen = 4;
 err = getsockopt(fd, SOL_CUSTOM, 0, &buf, &optlen);
 if (err) {
  log_err("Failed to call getsockopt");
  goto err;
 }

 if (optlen != 1) {
  log_err("Unexpected optlen %d != 1", optlen);
  goto err;
 }
 if (buf.u8[0] != 0x01) {
  log_err("Unexpected buf[0] 0x%02x != 0x01", buf.u8[0]);
  goto err;
 }

 /* IP_FREEBIND - BPF can't access optval past PAGE_SIZE */

 optlen = getpagesize() * 2;
 memset(big_buf, 0, optlen);

 err = setsockopt(fd, SOL_IP, IP_FREEBIND, big_buf, optlen);
 if (err != 0) {
  log_err("Failed to call setsockopt, ret=%d", err);
  goto err;
 }

 err = getsockopt(fd, SOL_IP, IP_FREEBIND, big_buf, &optlen);
 if (err != 0) {
  log_err("Failed to call getsockopt, ret=%d", err);
  goto err;
 }

 if (optlen != 1 || *(__u8 *)big_buf != 0x55) {
  log_err("Unexpected IP_FREEBIND getsockopt, optlen=%d, optval=0x%x",
   optlen, *(__u8 *)big_buf);
 }

 /* SO_SNDBUF is overwritten */

 buf.u32 = 0x01010101;
 err = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buf, 4);
 if (err) {
  log_err("Failed to call setsockopt(SO_SNDBUF)");
  goto err;
 }

 buf.u32 = 0x00;
 optlen = 4;
 err = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buf, &optlen);
 if (err) {
  log_err("Failed to call getsockopt(SO_SNDBUF)");
  goto err;
 }

 if (buf.u32 != 0x55AA*2) {
  log_err("Unexpected getsockopt(SO_SNDBUF) 0x%x != 0x55AA*2",
   buf.u32);
  goto err;
 }

 /* TCP_CONGESTION can extend the string */

 strcpy(buf.cc, "nv");
 err = setsockopt(fd, SOL_TCP, TCP_CONGESTION, &buf, strlen("nv"));
 if (err) {
  log_err("Failed to call setsockopt(TCP_CONGESTION)");
  goto err;
 }


 optlen = sizeof(buf.cc);
 err = getsockopt(fd, SOL_TCP, TCP_CONGESTION, &buf, &optlen);
 if (err) {
  log_err("Failed to call getsockopt(TCP_CONGESTION)");
  goto err;
 }

 if (strcmp(buf.cc, "cubic") != 0) {
  log_err("Unexpected getsockopt(TCP_CONGESTION) %s != %s",
   buf.cc, "cubic");
  goto err;
 }

 /* TCP_ZEROCOPY_RECEIVE triggers */
 memset(&buf, 0, sizeof(buf));
 optlen = sizeof(buf.zc);
 err = getsockopt(fd, SOL_TCP, TCP_ZEROCOPY_RECEIVE, &buf, &optlen);
 if (err) {
  log_err("Unexpected getsockopt(TCP_ZEROCOPY_RECEIVE) err=%d errno=%d",
   err, errno);
  goto err;
 }

 memset(&buf, 0, sizeof(buf));
 buf.zc.address = 12345; /* Not page aligned. Rejected by tcp_zerocopy_receive() */
 optlen = sizeof(buf.zc);
 errno = 0;
 err = getsockopt(fd, SOL_TCP, TCP_ZEROCOPY_RECEIVE, &buf, &optlen);
 if (errno != EINVAL) {
  log_err("Unexpected getsockopt(TCP_ZEROCOPY_RECEIVE) err=%d errno=%d",
   err, errno);
  goto err;
 }

 /* optval=NULL case is handled correctly */

 close(fd);
 fd = socket(AF_NETLINK, SOCK_RAW, 0);
 if (fd < 0) {
  log_err("Failed to create AF_NETLINK socket");
  return -1;
 }

 buf.u32 = 1;
 optlen = sizeof(__u32);
 err = setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &buf, optlen);
 if (err) {
  log_err("Unexpected getsockopt(NETLINK_ADD_MEMBERSHIP) err=%d errno=%d",
   err, errno);
  goto err;
 }

 optlen = 0;
 err = getsockopt(fd, SOL_NETLINK, NETLINK_LIST_MEMBERSHIPS, NULL, &optlen);
 if (err) {
  log_err("Unexpected getsockopt(NETLINK_LIST_MEMBERSHIPS) err=%d errno=%d",
   err, errno);
  goto err;
 }
 ASSERT_EQ(optlen, 8, "Unexpected NETLINK_LIST_MEMBERSHIPS value");

 free(big_buf);
 close(fd);
 return 0;
err:
 free(big_buf);
 close(fd);
 return -1;
}

static void run_test(int cgroup_fd)
{
 struct sockopt_sk *skel;

 skel = sockopt_sk__open_and_load();
 if (!ASSERT_OK_PTR(skel, "skel_load"))
  goto cleanup;

 skel->bss->page_size = getpagesize();

 skel->links._setsockopt =
  bpf_program__attach_cgroup(skel->progs._setsockopt, cgroup_fd);
 if (!ASSERT_OK_PTR(skel->links._setsockopt, "setsockopt_link"))
  goto cleanup;

 skel->links._getsockopt =
  bpf_program__attach_cgroup(skel->progs._getsockopt, cgroup_fd);
 if (!ASSERT_OK_PTR(skel->links._getsockopt, "getsockopt_link"))
  goto cleanup;

 ASSERT_OK(getsetsockopt(), "getsetsockopt");

cleanup:
 sockopt_sk__destroy(skel);
}

void test_sockopt_sk(void)
{
 int cgroup_fd;

 cgroup_fd = test__join_cgroup("/sockopt_sk");
 if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup /sockopt_sk"))
  return;

 run_test(cgroup_fd);
 close(cgroup_fd);
}

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

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