162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright (c) Meta Platforms, Inc. and affiliates. */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "vmlinux.h" 562306a36Sopenharmony_ci#include "bpf_tracing_net.h" 662306a36Sopenharmony_ci#include <bpf/bpf_core_read.h> 762306a36Sopenharmony_ci#include <bpf/bpf_helpers.h> 862306a36Sopenharmony_ci#include <bpf/bpf_tracing.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#ifndef ARRAY_SIZE 1162306a36Sopenharmony_ci#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 1262306a36Sopenharmony_ci#endif 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ciextern unsigned long CONFIG_HZ __kconfig; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ciconst volatile char veth[IFNAMSIZ]; 1762306a36Sopenharmony_ciconst volatile int veth_ifindex; 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ciint nr_listen; 2062306a36Sopenharmony_ciint nr_passive; 2162306a36Sopenharmony_ciint nr_active; 2262306a36Sopenharmony_ciint nr_connect; 2362306a36Sopenharmony_ciint nr_binddev; 2462306a36Sopenharmony_ciint nr_socket_post_create; 2562306a36Sopenharmony_ciint nr_fin_wait1; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cistruct sockopt_test { 2862306a36Sopenharmony_ci int opt; 2962306a36Sopenharmony_ci int new; 3062306a36Sopenharmony_ci int restore; 3162306a36Sopenharmony_ci int expected; 3262306a36Sopenharmony_ci int tcp_expected; 3362306a36Sopenharmony_ci unsigned int flip:1; 3462306a36Sopenharmony_ci}; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cistatic const char not_exist_cc[] = "not_exist"; 3762306a36Sopenharmony_cistatic const char cubic_cc[] = "cubic"; 3862306a36Sopenharmony_cistatic const char reno_cc[] = "reno"; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_cistatic const struct sockopt_test sol_socket_tests[] = { 4162306a36Sopenharmony_ci { .opt = SO_REUSEADDR, .flip = 1, }, 4262306a36Sopenharmony_ci { .opt = SO_SNDBUF, .new = 8123, .expected = 8123 * 2, }, 4362306a36Sopenharmony_ci { .opt = SO_RCVBUF, .new = 8123, .expected = 8123 * 2, }, 4462306a36Sopenharmony_ci { .opt = SO_KEEPALIVE, .flip = 1, }, 4562306a36Sopenharmony_ci { .opt = SO_PRIORITY, .new = 0xeb9f, .expected = 0xeb9f, }, 4662306a36Sopenharmony_ci { .opt = SO_REUSEPORT, .flip = 1, }, 4762306a36Sopenharmony_ci { .opt = SO_RCVLOWAT, .new = 8123, .expected = 8123, }, 4862306a36Sopenharmony_ci { .opt = SO_MARK, .new = 0xeb9f, .expected = 0xeb9f, }, 4962306a36Sopenharmony_ci { .opt = SO_MAX_PACING_RATE, .new = 0xeb9f, .expected = 0xeb9f, }, 5062306a36Sopenharmony_ci { .opt = SO_TXREHASH, .flip = 1, }, 5162306a36Sopenharmony_ci { .opt = 0, }, 5262306a36Sopenharmony_ci}; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cistatic const struct sockopt_test sol_tcp_tests[] = { 5562306a36Sopenharmony_ci { .opt = TCP_NODELAY, .flip = 1, }, 5662306a36Sopenharmony_ci { .opt = TCP_KEEPIDLE, .new = 123, .expected = 123, .restore = 321, }, 5762306a36Sopenharmony_ci { .opt = TCP_KEEPINTVL, .new = 123, .expected = 123, .restore = 321, }, 5862306a36Sopenharmony_ci { .opt = TCP_KEEPCNT, .new = 123, .expected = 123, .restore = 124, }, 5962306a36Sopenharmony_ci { .opt = TCP_SYNCNT, .new = 123, .expected = 123, .restore = 124, }, 6062306a36Sopenharmony_ci { .opt = TCP_WINDOW_CLAMP, .new = 8123, .expected = 8123, .restore = 8124, }, 6162306a36Sopenharmony_ci { .opt = TCP_CONGESTION, }, 6262306a36Sopenharmony_ci { .opt = TCP_THIN_LINEAR_TIMEOUTS, .flip = 1, }, 6362306a36Sopenharmony_ci { .opt = TCP_USER_TIMEOUT, .new = 123400, .expected = 123400, }, 6462306a36Sopenharmony_ci { .opt = TCP_NOTSENT_LOWAT, .new = 1314, .expected = 1314, }, 6562306a36Sopenharmony_ci { .opt = 0, }, 6662306a36Sopenharmony_ci}; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cistatic const struct sockopt_test sol_ip_tests[] = { 6962306a36Sopenharmony_ci { .opt = IP_TOS, .new = 0xe1, .expected = 0xe1, .tcp_expected = 0xe0, }, 7062306a36Sopenharmony_ci { .opt = 0, }, 7162306a36Sopenharmony_ci}; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_cistatic const struct sockopt_test sol_ipv6_tests[] = { 7462306a36Sopenharmony_ci { .opt = IPV6_TCLASS, .new = 0xe1, .expected = 0xe1, .tcp_expected = 0xe0, }, 7562306a36Sopenharmony_ci { .opt = IPV6_AUTOFLOWLABEL, .flip = 1, }, 7662306a36Sopenharmony_ci { .opt = 0, }, 7762306a36Sopenharmony_ci}; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistruct loop_ctx { 8062306a36Sopenharmony_ci void *ctx; 8162306a36Sopenharmony_ci struct sock *sk; 8262306a36Sopenharmony_ci}; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_cistatic int bpf_test_sockopt_flip(void *ctx, struct sock *sk, 8562306a36Sopenharmony_ci const struct sockopt_test *t, 8662306a36Sopenharmony_ci int level) 8762306a36Sopenharmony_ci{ 8862306a36Sopenharmony_ci int old, tmp, new, opt = t->opt; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci opt = t->opt; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci if (bpf_getsockopt(ctx, level, opt, &old, sizeof(old))) 9362306a36Sopenharmony_ci return 1; 9462306a36Sopenharmony_ci /* kernel initialized txrehash to 255 */ 9562306a36Sopenharmony_ci if (level == SOL_SOCKET && opt == SO_TXREHASH && old != 0 && old != 1) 9662306a36Sopenharmony_ci old = 1; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci new = !old; 9962306a36Sopenharmony_ci if (bpf_setsockopt(ctx, level, opt, &new, sizeof(new))) 10062306a36Sopenharmony_ci return 1; 10162306a36Sopenharmony_ci if (bpf_getsockopt(ctx, level, opt, &tmp, sizeof(tmp)) || 10262306a36Sopenharmony_ci tmp != new) 10362306a36Sopenharmony_ci return 1; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci if (bpf_setsockopt(ctx, level, opt, &old, sizeof(old))) 10662306a36Sopenharmony_ci return 1; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci return 0; 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_cistatic int bpf_test_sockopt_int(void *ctx, struct sock *sk, 11262306a36Sopenharmony_ci const struct sockopt_test *t, 11362306a36Sopenharmony_ci int level) 11462306a36Sopenharmony_ci{ 11562306a36Sopenharmony_ci int old, tmp, new, expected, opt; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci opt = t->opt; 11862306a36Sopenharmony_ci new = t->new; 11962306a36Sopenharmony_ci if (sk->sk_type == SOCK_STREAM && t->tcp_expected) 12062306a36Sopenharmony_ci expected = t->tcp_expected; 12162306a36Sopenharmony_ci else 12262306a36Sopenharmony_ci expected = t->expected; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci if (bpf_getsockopt(ctx, level, opt, &old, sizeof(old)) || 12562306a36Sopenharmony_ci old == new) 12662306a36Sopenharmony_ci return 1; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci if (bpf_setsockopt(ctx, level, opt, &new, sizeof(new))) 12962306a36Sopenharmony_ci return 1; 13062306a36Sopenharmony_ci if (bpf_getsockopt(ctx, level, opt, &tmp, sizeof(tmp)) || 13162306a36Sopenharmony_ci tmp != expected) 13262306a36Sopenharmony_ci return 1; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci if (t->restore) 13562306a36Sopenharmony_ci old = t->restore; 13662306a36Sopenharmony_ci if (bpf_setsockopt(ctx, level, opt, &old, sizeof(old))) 13762306a36Sopenharmony_ci return 1; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci return 0; 14062306a36Sopenharmony_ci} 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_cistatic int bpf_test_socket_sockopt(__u32 i, struct loop_ctx *lc) 14362306a36Sopenharmony_ci{ 14462306a36Sopenharmony_ci const struct sockopt_test *t; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci if (i >= ARRAY_SIZE(sol_socket_tests)) 14762306a36Sopenharmony_ci return 1; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci t = &sol_socket_tests[i]; 15062306a36Sopenharmony_ci if (!t->opt) 15162306a36Sopenharmony_ci return 1; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci if (t->flip) 15462306a36Sopenharmony_ci return bpf_test_sockopt_flip(lc->ctx, lc->sk, t, SOL_SOCKET); 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci return bpf_test_sockopt_int(lc->ctx, lc->sk, t, SOL_SOCKET); 15762306a36Sopenharmony_ci} 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_cistatic int bpf_test_ip_sockopt(__u32 i, struct loop_ctx *lc) 16062306a36Sopenharmony_ci{ 16162306a36Sopenharmony_ci const struct sockopt_test *t; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci if (i >= ARRAY_SIZE(sol_ip_tests)) 16462306a36Sopenharmony_ci return 1; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci t = &sol_ip_tests[i]; 16762306a36Sopenharmony_ci if (!t->opt) 16862306a36Sopenharmony_ci return 1; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci if (t->flip) 17162306a36Sopenharmony_ci return bpf_test_sockopt_flip(lc->ctx, lc->sk, t, IPPROTO_IP); 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci return bpf_test_sockopt_int(lc->ctx, lc->sk, t, IPPROTO_IP); 17462306a36Sopenharmony_ci} 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_cistatic int bpf_test_ipv6_sockopt(__u32 i, struct loop_ctx *lc) 17762306a36Sopenharmony_ci{ 17862306a36Sopenharmony_ci const struct sockopt_test *t; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci if (i >= ARRAY_SIZE(sol_ipv6_tests)) 18162306a36Sopenharmony_ci return 1; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci t = &sol_ipv6_tests[i]; 18462306a36Sopenharmony_ci if (!t->opt) 18562306a36Sopenharmony_ci return 1; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci if (t->flip) 18862306a36Sopenharmony_ci return bpf_test_sockopt_flip(lc->ctx, lc->sk, t, IPPROTO_IPV6); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci return bpf_test_sockopt_int(lc->ctx, lc->sk, t, IPPROTO_IPV6); 19162306a36Sopenharmony_ci} 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_cistatic int bpf_test_tcp_sockopt(__u32 i, struct loop_ctx *lc) 19462306a36Sopenharmony_ci{ 19562306a36Sopenharmony_ci const struct sockopt_test *t; 19662306a36Sopenharmony_ci struct sock *sk; 19762306a36Sopenharmony_ci void *ctx; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci if (i >= ARRAY_SIZE(sol_tcp_tests)) 20062306a36Sopenharmony_ci return 1; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci t = &sol_tcp_tests[i]; 20362306a36Sopenharmony_ci if (!t->opt) 20462306a36Sopenharmony_ci return 1; 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci ctx = lc->ctx; 20762306a36Sopenharmony_ci sk = lc->sk; 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci if (t->opt == TCP_CONGESTION) { 21062306a36Sopenharmony_ci char old_cc[16], tmp_cc[16]; 21162306a36Sopenharmony_ci const char *new_cc; 21262306a36Sopenharmony_ci int new_cc_len; 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci if (!bpf_setsockopt(ctx, IPPROTO_TCP, TCP_CONGESTION, 21562306a36Sopenharmony_ci (void *)not_exist_cc, sizeof(not_exist_cc))) 21662306a36Sopenharmony_ci return 1; 21762306a36Sopenharmony_ci if (bpf_getsockopt(ctx, IPPROTO_TCP, TCP_CONGESTION, old_cc, sizeof(old_cc))) 21862306a36Sopenharmony_ci return 1; 21962306a36Sopenharmony_ci if (!bpf_strncmp(old_cc, sizeof(old_cc), cubic_cc)) { 22062306a36Sopenharmony_ci new_cc = reno_cc; 22162306a36Sopenharmony_ci new_cc_len = sizeof(reno_cc); 22262306a36Sopenharmony_ci } else { 22362306a36Sopenharmony_ci new_cc = cubic_cc; 22462306a36Sopenharmony_ci new_cc_len = sizeof(cubic_cc); 22562306a36Sopenharmony_ci } 22662306a36Sopenharmony_ci if (bpf_setsockopt(ctx, IPPROTO_TCP, TCP_CONGESTION, (void *)new_cc, 22762306a36Sopenharmony_ci new_cc_len)) 22862306a36Sopenharmony_ci return 1; 22962306a36Sopenharmony_ci if (bpf_getsockopt(ctx, IPPROTO_TCP, TCP_CONGESTION, tmp_cc, sizeof(tmp_cc))) 23062306a36Sopenharmony_ci return 1; 23162306a36Sopenharmony_ci if (bpf_strncmp(tmp_cc, sizeof(tmp_cc), new_cc)) 23262306a36Sopenharmony_ci return 1; 23362306a36Sopenharmony_ci if (bpf_setsockopt(ctx, IPPROTO_TCP, TCP_CONGESTION, old_cc, sizeof(old_cc))) 23462306a36Sopenharmony_ci return 1; 23562306a36Sopenharmony_ci return 0; 23662306a36Sopenharmony_ci } 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci if (t->flip) 23962306a36Sopenharmony_ci return bpf_test_sockopt_flip(ctx, sk, t, IPPROTO_TCP); 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci return bpf_test_sockopt_int(ctx, sk, t, IPPROTO_TCP); 24262306a36Sopenharmony_ci} 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_cistatic int bpf_test_sockopt(void *ctx, struct sock *sk) 24562306a36Sopenharmony_ci{ 24662306a36Sopenharmony_ci struct loop_ctx lc = { .ctx = ctx, .sk = sk, }; 24762306a36Sopenharmony_ci __u16 family, proto; 24862306a36Sopenharmony_ci int n; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci family = sk->sk_family; 25162306a36Sopenharmony_ci proto = sk->sk_protocol; 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci n = bpf_loop(ARRAY_SIZE(sol_socket_tests), bpf_test_socket_sockopt, &lc, 0); 25462306a36Sopenharmony_ci if (n != ARRAY_SIZE(sol_socket_tests)) 25562306a36Sopenharmony_ci return -1; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci if (proto == IPPROTO_TCP) { 25862306a36Sopenharmony_ci n = bpf_loop(ARRAY_SIZE(sol_tcp_tests), bpf_test_tcp_sockopt, &lc, 0); 25962306a36Sopenharmony_ci if (n != ARRAY_SIZE(sol_tcp_tests)) 26062306a36Sopenharmony_ci return -1; 26162306a36Sopenharmony_ci } 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci if (family == AF_INET) { 26462306a36Sopenharmony_ci n = bpf_loop(ARRAY_SIZE(sol_ip_tests), bpf_test_ip_sockopt, &lc, 0); 26562306a36Sopenharmony_ci if (n != ARRAY_SIZE(sol_ip_tests)) 26662306a36Sopenharmony_ci return -1; 26762306a36Sopenharmony_ci } else { 26862306a36Sopenharmony_ci n = bpf_loop(ARRAY_SIZE(sol_ipv6_tests), bpf_test_ipv6_sockopt, &lc, 0); 26962306a36Sopenharmony_ci if (n != ARRAY_SIZE(sol_ipv6_tests)) 27062306a36Sopenharmony_ci return -1; 27162306a36Sopenharmony_ci } 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci return 0; 27462306a36Sopenharmony_ci} 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_cistatic int binddev_test(void *ctx) 27762306a36Sopenharmony_ci{ 27862306a36Sopenharmony_ci const char empty_ifname[] = ""; 27962306a36Sopenharmony_ci int ifindex, zero = 0; 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci if (bpf_setsockopt(ctx, SOL_SOCKET, SO_BINDTODEVICE, 28262306a36Sopenharmony_ci (void *)veth, sizeof(veth))) 28362306a36Sopenharmony_ci return -1; 28462306a36Sopenharmony_ci if (bpf_getsockopt(ctx, SOL_SOCKET, SO_BINDTOIFINDEX, 28562306a36Sopenharmony_ci &ifindex, sizeof(int)) || 28662306a36Sopenharmony_ci ifindex != veth_ifindex) 28762306a36Sopenharmony_ci return -1; 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci if (bpf_setsockopt(ctx, SOL_SOCKET, SO_BINDTODEVICE, 29062306a36Sopenharmony_ci (void *)empty_ifname, sizeof(empty_ifname))) 29162306a36Sopenharmony_ci return -1; 29262306a36Sopenharmony_ci if (bpf_getsockopt(ctx, SOL_SOCKET, SO_BINDTOIFINDEX, 29362306a36Sopenharmony_ci &ifindex, sizeof(int)) || 29462306a36Sopenharmony_ci ifindex != 0) 29562306a36Sopenharmony_ci return -1; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci if (bpf_setsockopt(ctx, SOL_SOCKET, SO_BINDTOIFINDEX, 29862306a36Sopenharmony_ci (void *)&veth_ifindex, sizeof(int))) 29962306a36Sopenharmony_ci return -1; 30062306a36Sopenharmony_ci if (bpf_getsockopt(ctx, SOL_SOCKET, SO_BINDTOIFINDEX, 30162306a36Sopenharmony_ci &ifindex, sizeof(int)) || 30262306a36Sopenharmony_ci ifindex != veth_ifindex) 30362306a36Sopenharmony_ci return -1; 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci if (bpf_setsockopt(ctx, SOL_SOCKET, SO_BINDTOIFINDEX, 30662306a36Sopenharmony_ci &zero, sizeof(int))) 30762306a36Sopenharmony_ci return -1; 30862306a36Sopenharmony_ci if (bpf_getsockopt(ctx, SOL_SOCKET, SO_BINDTOIFINDEX, 30962306a36Sopenharmony_ci &ifindex, sizeof(int)) || 31062306a36Sopenharmony_ci ifindex != 0) 31162306a36Sopenharmony_ci return -1; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci return 0; 31462306a36Sopenharmony_ci} 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_cistatic int test_tcp_maxseg(void *ctx, struct sock *sk) 31762306a36Sopenharmony_ci{ 31862306a36Sopenharmony_ci int val = 1314, tmp; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci if (sk->sk_state != TCP_ESTABLISHED) 32162306a36Sopenharmony_ci return bpf_setsockopt(ctx, IPPROTO_TCP, TCP_MAXSEG, 32262306a36Sopenharmony_ci &val, sizeof(val)); 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci if (bpf_getsockopt(ctx, IPPROTO_TCP, TCP_MAXSEG, &tmp, sizeof(tmp)) || 32562306a36Sopenharmony_ci tmp > val) 32662306a36Sopenharmony_ci return -1; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci return 0; 32962306a36Sopenharmony_ci} 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_cistatic int test_tcp_saved_syn(void *ctx, struct sock *sk) 33262306a36Sopenharmony_ci{ 33362306a36Sopenharmony_ci __u8 saved_syn[20]; 33462306a36Sopenharmony_ci int one = 1; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci if (sk->sk_state == TCP_LISTEN) 33762306a36Sopenharmony_ci return bpf_setsockopt(ctx, IPPROTO_TCP, TCP_SAVE_SYN, 33862306a36Sopenharmony_ci &one, sizeof(one)); 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci return bpf_getsockopt(ctx, IPPROTO_TCP, TCP_SAVED_SYN, 34162306a36Sopenharmony_ci saved_syn, sizeof(saved_syn)); 34262306a36Sopenharmony_ci} 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ciSEC("lsm_cgroup/socket_post_create") 34562306a36Sopenharmony_ciint BPF_PROG(socket_post_create, struct socket *sock, int family, 34662306a36Sopenharmony_ci int type, int protocol, int kern) 34762306a36Sopenharmony_ci{ 34862306a36Sopenharmony_ci struct sock *sk = sock->sk; 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci if (!sk) 35162306a36Sopenharmony_ci return 1; 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci nr_socket_post_create += !bpf_test_sockopt(sk, sk); 35462306a36Sopenharmony_ci nr_binddev += !binddev_test(sk); 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ci return 1; 35762306a36Sopenharmony_ci} 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ciSEC("sockops") 36062306a36Sopenharmony_ciint skops_sockopt(struct bpf_sock_ops *skops) 36162306a36Sopenharmony_ci{ 36262306a36Sopenharmony_ci struct bpf_sock *bpf_sk = skops->sk; 36362306a36Sopenharmony_ci struct sock *sk; 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci if (!bpf_sk) 36662306a36Sopenharmony_ci return 1; 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci sk = (struct sock *)bpf_skc_to_tcp_sock(bpf_sk); 36962306a36Sopenharmony_ci if (!sk) 37062306a36Sopenharmony_ci return 1; 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci switch (skops->op) { 37362306a36Sopenharmony_ci case BPF_SOCK_OPS_TCP_LISTEN_CB: 37462306a36Sopenharmony_ci nr_listen += !(bpf_test_sockopt(skops, sk) || 37562306a36Sopenharmony_ci test_tcp_maxseg(skops, sk) || 37662306a36Sopenharmony_ci test_tcp_saved_syn(skops, sk)); 37762306a36Sopenharmony_ci break; 37862306a36Sopenharmony_ci case BPF_SOCK_OPS_TCP_CONNECT_CB: 37962306a36Sopenharmony_ci nr_connect += !(bpf_test_sockopt(skops, sk) || 38062306a36Sopenharmony_ci test_tcp_maxseg(skops, sk)); 38162306a36Sopenharmony_ci break; 38262306a36Sopenharmony_ci case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: 38362306a36Sopenharmony_ci nr_active += !(bpf_test_sockopt(skops, sk) || 38462306a36Sopenharmony_ci test_tcp_maxseg(skops, sk)); 38562306a36Sopenharmony_ci break; 38662306a36Sopenharmony_ci case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: 38762306a36Sopenharmony_ci nr_passive += !(bpf_test_sockopt(skops, sk) || 38862306a36Sopenharmony_ci test_tcp_maxseg(skops, sk) || 38962306a36Sopenharmony_ci test_tcp_saved_syn(skops, sk)); 39062306a36Sopenharmony_ci bpf_sock_ops_cb_flags_set(skops, 39162306a36Sopenharmony_ci skops->bpf_sock_ops_cb_flags | 39262306a36Sopenharmony_ci BPF_SOCK_OPS_STATE_CB_FLAG); 39362306a36Sopenharmony_ci break; 39462306a36Sopenharmony_ci case BPF_SOCK_OPS_STATE_CB: 39562306a36Sopenharmony_ci if (skops->args[1] == BPF_TCP_CLOSE_WAIT) 39662306a36Sopenharmony_ci nr_fin_wait1 += !bpf_test_sockopt(skops, sk); 39762306a36Sopenharmony_ci break; 39862306a36Sopenharmony_ci } 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci return 1; 40162306a36Sopenharmony_ci} 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_cichar _license[] SEC("license") = "GPL"; 404