* fix sock_ops test.

* forgot to update event count
This commit is contained in:
Shankar Seal 2023-11-28 08:08:56 -08:00 коммит произвёл GitHub
Родитель 5b3cbf0d29
Коммит 7bc877041e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 1683 добавлений и 2271 удалений

Просмотреть файл

@ -159,6 +159,10 @@ ebpf_result_to_errno(ebpf_result_t result)
error = EFAULT;
break;
case EBPF_OUT_OF_SPACE:
error = ENOSPC;
break;
default:
error = EOTHER;
break;

Просмотреть файл

@ -96,7 +96,7 @@ static const void* _ebpf_general_helpers[] = {
(void*)&_ebpf_core_get_time_ns,
(void*)&ebpf_core_csum_diff,
// Ring buffer output.
(void*)&ebpf_ring_buffer_map_output,
(void*)&_ebpf_core_ring_buffer_output,
(void*)&_ebpf_core_trace_printk2,
(void*)&_ebpf_core_trace_printk3,
(void*)&_ebpf_core_trace_printk4,

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -36,8 +36,8 @@ authorize_v4(bpf_sock_addr_t* ctx, void* connection_policy_map)
connection_tuple_t tuple_key = {0};
int* verdict = NULL;
tuple_key.dst_ip.ipv4 = ctx->user_ip4;
tuple_key.dst_port = ctx->user_port;
tuple_key.remote_ip.ipv4 = ctx->user_ip4;
tuple_key.remote_port = ctx->user_port;
tuple_key.protocol = ctx->protocol;
verdict = bpf_map_lookup_elem(connection_policy_map, &tuple_key);
@ -50,8 +50,8 @@ authorize_v6(bpf_sock_addr_t* ctx, void* connection_policy_map)
{
connection_tuple_t tuple_key = {0};
int* verdict;
__builtin_memcpy(tuple_key.dst_ip.ipv6, ctx->user_ip6, sizeof(ctx->user_ip6));
tuple_key.dst_port = ctx->user_port;
__builtin_memcpy(tuple_key.remote_ip.ipv6, ctx->user_ip6, sizeof(ctx->user_ip6));
tuple_key.remote_port = ctx->user_port;
tuple_key.protocol = ctx->protocol;
verdict = bpf_map_lookup_elem(connection_policy_map, &tuple_key);

Просмотреть файл

@ -10,7 +10,7 @@ struct
__uint(type, BPF_MAP_TYPE_HASH);
__type(key, connection_tuple_t);
__type(value, uint32_t);
__uint(max_entries, 1);
__uint(max_entries, 2);
} connection_map SEC(".maps");
struct
@ -19,51 +19,52 @@ struct
__uint(max_entries, 256 * 1024);
} audit_map SEC(".maps");
inline int
update_audit_map(audit_entry_t* audit_entry)
{
int result = -1;
if (bpf_map_lookup_elem(&connection_map, &audit_entry->tuple) != NULL) {
result = bpf_ringbuf_output(&audit_map, audit_entry, sizeof(*audit_entry), 0);
}
return result;
}
inline int
handle_v4(bpf_sock_ops_t* ctx, bool outbound, bool connected)
{
int result = 0;
audit_entry_t audit_entry = {0};
audit_entry.tuple.src_ip.ipv4 = (outbound) ? ctx->local_ip4 : ctx->remote_ip4;
audit_entry.tuple.src_port = (outbound) ? ctx->local_port : ctx->remote_port;
audit_entry.tuple.dst_ip.ipv4 = (outbound) ? ctx->remote_ip4 : ctx->local_ip4;
audit_entry.tuple.dst_port = (outbound) ? ctx->remote_port : ctx->local_port;
audit_entry.tuple.local_ip.ipv4 = ctx->local_ip4;
audit_entry.tuple.local_port = ctx->local_port;
audit_entry.tuple.remote_ip.ipv4 = ctx->remote_ip4;
audit_entry.tuple.remote_port = ctx->remote_port;
audit_entry.tuple.protocol = ctx->protocol;
audit_entry.tuple.interface_luid = ctx->interface_luid;
audit_entry.outbound = outbound;
audit_entry.connected = connected;
if (bpf_map_lookup_elem(&connection_map, &audit_entry.tuple) != NULL) {
result = bpf_ringbuf_output(&audit_map, &audit_entry, sizeof(audit_entry), 0);
}
return result;
return update_audit_map(&audit_entry);
}
inline int
handle_v6(bpf_sock_ops_t* ctx, bool outbound, bool connected)
{
int result = 0;
audit_entry_t audit_entry = {0};
void* ip6 = NULL;
ip6 = (outbound) ? ctx->local_ip6 : ctx->remote_ip6;
__builtin_memcpy(audit_entry.tuple.src_ip.ipv6, ip6, sizeof(uint32_t) * 4);
audit_entry.tuple.src_port = (outbound) ? ctx->local_port : ctx->remote_port;
ip6 = (outbound) ? ctx->remote_ip6 : ctx->local_ip6;
__builtin_memcpy(audit_entry.tuple.dst_ip.ipv6, ip6, sizeof(uint32_t) * 4);
audit_entry.tuple.dst_port = (outbound) ? ctx->remote_port : ctx->local_port;
ip6 = ctx->local_ip6;
__builtin_memcpy(audit_entry.tuple.local_ip.ipv6, ip6, sizeof(uint32_t) * 4);
audit_entry.tuple.local_port = ctx->local_port;
ip6 = ctx->remote_ip6;
__builtin_memcpy(audit_entry.tuple.remote_ip.ipv6, ip6, sizeof(uint32_t) * 4);
audit_entry.tuple.remote_port = ctx->remote_port;
audit_entry.tuple.protocol = ctx->protocol;
audit_entry.tuple.interface_luid = ctx->interface_luid;
audit_entry.outbound = outbound;
audit_entry.connected = connected;
if (bpf_map_lookup_elem(&connection_map, &audit_entry.tuple) != NULL) {
result = bpf_ringbuf_output(&audit_map, &audit_entry, sizeof(audit_entry), 0);
}
return result;
return update_audit_map(&audit_entry);
}
SEC("sockops")

Просмотреть файл

@ -60,13 +60,13 @@ connection_test(
connection_tuple_t tuple = {0};
if (address_family == AF_INET) {
tuple.dst_ip.ipv4 = htonl(INADDR_LOOPBACK);
printf("tuple.dst_ip.ipv4 = %x\n", tuple.dst_ip.ipv4);
tuple.remote_ip.ipv4 = htonl(INADDR_LOOPBACK);
printf("tuple.remote_ip.ipv4 = %x\n", tuple.remote_ip.ipv4);
} else {
memcpy(tuple.dst_ip.ipv6, &in6addr_loopback, sizeof(tuple.dst_ip.ipv6));
memcpy(tuple.remote_ip.ipv6, &in6addr_loopback, sizeof(tuple.remote_ip.ipv6));
}
tuple.dst_port = htons(SOCKET_TEST_PORT);
printf("tuple.dst_port = %x\n", tuple.dst_port);
tuple.remote_port = htons(SOCKET_TEST_PORT);
printf("tuple.remote_port = %x\n", tuple.remote_port);
tuple.protocol = protocol;
bpf_map* ingress_connection_policy_map = bpf_object__find_map_by_name(object, "ingress_connection_policy_map");
@ -271,10 +271,7 @@ connection_monitor_test(
// Ring buffer event callback context.
std::unique_ptr<ring_buffer_test_event_context_t> context = std::make_unique<ring_buffer_test_event_context_t>();
// Issue: https://github.com/microsoft/ebpf-for-windows/issues/2706
// Should there be a disconnect event for both inbound and outbound connections?
// Should the local and remote addresses be swapped for inbound vs outbound connections?
context->test_event_count = disconnect ? 3 : 2;
context->test_event_count = disconnect ? 4 : 2;
bpf_program* _program = bpf_object__find_program_by_name(object, "connection_monitor");
REQUIRE(_program != nullptr);
@ -283,23 +280,30 @@ connection_monitor_test(
int local_address_length = 0;
sender_socket.get_local_address(local_address, local_address_length);
connection_tuple_t tuple{};
connection_tuple_t tuple{}, reverse_tuple{};
if (address_family == AF_INET) {
tuple.src_ip.ipv4 = htonl(INADDR_LOOPBACK);
tuple.dst_ip.ipv4 = htonl(INADDR_LOOPBACK);
tuple.local_ip.ipv4 = htonl(INADDR_LOOPBACK);
tuple.remote_ip.ipv4 = htonl(INADDR_LOOPBACK);
} else {
memcpy(tuple.src_ip.ipv6, &in6addr_loopback, sizeof(tuple.src_ip.ipv6));
memcpy(tuple.dst_ip.ipv6, &in6addr_loopback, sizeof(tuple.src_ip.ipv6));
memcpy(tuple.local_ip.ipv6, &in6addr_loopback, sizeof(tuple.local_ip.ipv6));
memcpy(tuple.remote_ip.ipv6, &in6addr_loopback, sizeof(tuple.local_ip.ipv6));
}
tuple.src_port = INETADDR_PORT(local_address);
tuple.dst_port = htons(SOCKET_TEST_PORT);
tuple.local_port = INETADDR_PORT(local_address);
tuple.remote_port = htons(SOCKET_TEST_PORT);
tuple.protocol = protocol;
NET_LUID net_luid = {};
net_luid.Info.IfType = IF_TYPE_SOFTWARE_LOOPBACK;
tuple.interface_luid = net_luid.Value;
reverse_tuple.local_ip = tuple.remote_ip;
reverse_tuple.remote_ip = tuple.local_ip;
reverse_tuple.local_port = tuple.remote_port;
reverse_tuple.remote_port = tuple.local_port;
reverse_tuple.protocol = tuple.protocol;
reverse_tuple.interface_luid = tuple.interface_luid;
std::vector<std::vector<char>> audit_entry_list;
audit_entry_t audit_entries[3] = {0};
audit_entry_t audit_entries[4] = {0};
// Connect outbound.
audit_entries[0].tuple = tuple;
@ -309,19 +313,27 @@ connection_monitor_test(
audit_entry_list.push_back(std::vector<char>(p, p + sizeof(audit_entry_t)));
// Connect inbound.
audit_entries[1].tuple = tuple;
audit_entries[1].tuple = reverse_tuple;
audit_entries[1].connected = true;
audit_entries[1].outbound = false;
p = reinterpret_cast<char*>(&audit_entries[1]);
audit_entry_list.push_back(std::vector<char>(p, p + sizeof(audit_entry_t)));
// Disconnect.
// Create an audit entry for the disconnect case.
// The direction bit is set to false.
audit_entries[2].tuple = tuple;
audit_entries[2].connected = false;
audit_entries[2].outbound = false;
p = reinterpret_cast<char*>(&audit_entries[2]);
audit_entry_list.push_back(std::vector<char>(p, p + sizeof(audit_entry_t)));
// Create another audit entry for the disconnect event with the reverse packet tuple.
audit_entries[3].tuple = reverse_tuple;
audit_entries[3].connected = false;
audit_entries[3].outbound = false;
p = reinterpret_cast<char*>(&audit_entries[3]);
audit_entry_list.push_back(std::vector<char>(p, p + sizeof(audit_entry_t)));
context->records = &audit_entry_list;
// Get the std::future from the promise field in ring buffer event context, which should be in ready state
@ -338,9 +350,10 @@ connection_monitor_test(
bpf_map* connection_map = bpf_object__find_map_by_name(object, "connection_map");
REQUIRE(connection_map != nullptr);
// Update connection map with loopback packet tuple.
// Update connection map with loopback packet tuples.
uint32_t verdict = BPF_SOCK_ADDR_VERDICT_REJECT;
REQUIRE(bpf_map_update_elem(bpf_map__fd(connection_map), &tuple, &verdict, EBPF_ANY) == 0);
REQUIRE(bpf_map_update_elem(bpf_map__fd(connection_map), &reverse_tuple, &verdict, EBPF_ANY) == 0);
// Post an asynchronous receive on the receiver socket.
receiver_socket.post_async_receive();

Просмотреть файл

@ -20,10 +20,10 @@ typedef struct _ip_address
typedef struct _connection_tuple
{
ip_address_t src_ip;
uint16_t src_port;
ip_address_t dst_ip;
uint16_t dst_port;
ip_address_t local_ip;
uint16_t local_port;
ip_address_t remote_ip;
uint16_t remote_port;
uint32_t protocol;
uint64_t interface_luid;
} connection_tuple_t;