Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .mk/bc.mk
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ define MAPS
"ipsec_ingress_map":"hash",
"ipsec_egress_map":"hash",
"ssl_data_event_map":"ringbuf",
"dns_name_map":"per_cpu_array"
"dns_name_map":"per_cpu_array",
"quic_flows":"per_cpu_hash"
}
endef

Expand Down
54 changes: 52 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ PROTOC_ARTIFACTS := pkg/pbflow
# regular expressions for excluded file patterns
EXCLUDE_COVERAGE_FILES="(/cmd/)|(bpf_bpfe)|(/examples/)|(/pkg/pbflow/)"

# Container image for running linux tests from non-linux hosts (e.g. macOS).
# Prefer matching the *host* Go toolchain version (go env GOVERSION), which tends to
# be more reliable than GO_VERSION (used for generator tooling) and avoids "go: not found".
HOST_GO_VERSION := $(shell go env GOVERSION 2>/dev/null | sed 's/^go//')
TEST_CONTAINER_IMAGE ?= $(if $(HOST_GO_VERSION),golang:$(HOST_GO_VERSION),golang:$(GO_VERSION))

.DEFAULT_GOAL := help

# build a single arch target provided as argument
Expand Down Expand Up @@ -162,7 +168,29 @@ compile: ## Compile ebpf agent project
.PHONY: test
test: ## Test code using go test
@echo "### Testing code"
GOOS=$(GOOS) go test -mod vendor ./pkg/... ./cmd/... -coverpkg=./... -coverprofile cover.all.out
@if [ "$$(go env GOOS)" = "linux" ]; then \
go test -mod vendor ./pkg/... ./cmd/... -coverpkg=./... -coverprofile cover.all.out; \
else \
$(MAKE) test-container; \
fi

.PHONY: test-container
test-container: ## Run linux tests in a container (useful on macOS)
@echo "### Testing in linux container ($(TEST_CONTAINER_IMAGE))"
@if [ -z "$(OCI_BIN_PATH)" ]; then \
echo "ERROR: docker/podman not found in PATH. Install one, or run 'make test-unit' instead."; \
exit 1; \
fi
@$(OCI_BIN) run --rm \
-u $$(id -u):$$(id -g) \
-v "$$(pwd)":/src \
-w /src \
-e HOME=/tmp \
-e GOPATH=/tmp/go \
-e GOCACHE=/tmp/go-build \
-e CGO_ENABLED=0 \
$(TEST_CONTAINER_IMAGE) \
sh -lc 'mkdir -p "$$GOPATH" "$$GOCACHE"; export PATH="/usr/local/go/bin:/go/bin:$$PATH"; command -v go >/dev/null || (echo "ERROR: go not found; PATH=$$PATH" && exit 127); go version && go test -mod vendor ./pkg/... ./cmd/... -coverpkg=./... -coverprofile cover.all.out && go test -v ./pkg/maps'

.PHONY: verify-maps
verify-maps: ## Verify map names consistency across all sources
Expand All @@ -172,7 +200,29 @@ verify-maps: ## Verify map names consistency across all sources
.PHONY: test-race
test-race: ## Test code using go test -race
@echo "### Testing code for race conditions"
GOOS=$(GOOS) go test -race -mod vendor ./pkg/... ./cmd/...
@if [ "$$(go env GOOS)" = "linux" ]; then \
go test -race -mod vendor ./pkg/... ./cmd/...; \
else \
$(MAKE) test-race-container; \
fi

.PHONY: test-race-container
test-race-container: ## Run go test -race in a linux container (useful on macOS)
@echo "### Testing code for race conditions in linux container ($(TEST_CONTAINER_IMAGE))"
@if [ -z "$(OCI_BIN_PATH)" ]; then \
echo "ERROR: docker/podman not found in PATH."; \
exit 1; \
fi
@$(OCI_BIN) run --rm \
-u $$(id -u):$$(id -g) \
-v "$$(pwd)":/src \
-w /src \
-e HOME=/tmp \
-e GOPATH=/tmp/go \
-e GOCACHE=/tmp/go-build \
-e CGO_ENABLED=1 \
$(TEST_CONTAINER_IMAGE) \
sh -lc 'mkdir -p "$$GOPATH" "$$GOCACHE"; export PATH="/usr/local/go/bin:/go/bin:$$PATH"; command -v go >/dev/null || (echo "ERROR: go not found; PATH=$$PATH" && exit 127); go version && go test -race -mod vendor ./pkg/... ./cmd/...'

.PHONY: cov-exclude-generated
cov-exclude-generated:
Expand Down
1 change: 1 addition & 0 deletions bpf/configs.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ volatile const u8 network_events_monitoring_groupid = 0;
volatile const u8 enable_pkt_translation_tracking = 0;
volatile const u8 enable_ipsec = 0;
volatile const u8 enable_openssl_tracking = 0;
volatile const u8 enable_quic_tracking = 0;
#endif //__CONFIGS_H__
9 changes: 9 additions & 0 deletions bpf/flows.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@
*/
#include "openssl_tracker.h"

/*
* Defines quic tracker
*/
#include "quic_tracker.h"

// return 0 on success, 1 if capacity reached
static __always_inline int add_observed_intf(flow_metrics *value, pkt_info *pkt, u32 if_index,
u8 direction) {
Expand Down Expand Up @@ -186,6 +191,10 @@ static inline int flow_monitor(struct __sk_buff *skb, u8 direction) {
if (enable_dns_tracking) {
dns_errno = track_dns_packet(skb, &pkt);
}
if (enable_quic_tracking) {
track_quic_packet(skb, &pkt, eth_protocol, direction, len);
}

flow_metrics *aggregate_flow = (flow_metrics *)bpf_map_lookup_elem(&aggregated_flows, &id);
if (aggregate_flow != NULL) {
update_existing_flow(aggregate_flow, &pkt, len, flow_sampling, skb->ifindex, direction);
Expand Down
9 changes: 9 additions & 0 deletions bpf/maps_definition.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,5 +152,14 @@ struct {
__uint(max_entries, 1 << 27); // 16KB * 1000 events/sec * 5sec "eviction time" = ~128MB
__uint(pinning, LIBBPF_PIN_BY_NAME);
} ssl_data_event_map SEC(".maps");
// QUIC flow tracking map - keyed by flow_id (like other flow maps)
struct {
__uint(type, BPF_MAP_TYPE_PERCPU_HASH);
__type(key, flow_id);
__type(value, quic_metrics);
__uint(max_entries, 1 << 16);
__uint(map_flags, BPF_F_NO_PREALLOC);
__uint(pinning, LIBBPF_PIN_BY_NAME);
} quic_flows SEC(".maps");

#endif //__MAPS_DEFINITION_H__
Loading
Loading