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
1 change: 1 addition & 0 deletions .github/workflows/golangci-lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ jobs:
IS_NOT_MERGE_GROUP: ${{ github.event_name != 'merge_group' }}
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
CGO_ENABLED: 0
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
if: env.IS_NOT_MERGE_GROUP
Expand Down
27 changes: 27 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -601,3 +601,30 @@ update-hubble:
echo " git push origin deps/update-hubble-to-$$latest_version"; \
echo "Then create a pull request on GitHub."; \
fi

.PHONY: update-libbpf
update-libbpf: ## Update libbpf headers and sources from upstream
@echo "Updating libbpf from upstream..."
@TMPDIR=$$(mktemp -d); \
echo "Cloning libbpf repository to $$TMPDIR..."; \
git clone --depth 1 https://github.com/libbpf/libbpf.git $$TMPDIR; \
echo "Copying libbpf source files..."; \
rm -rf $(REPO_ROOT)/pkg/plugin/lib/common/libbpf/_src/*; \
cp $$TMPDIR/src/*.c $(REPO_ROOT)/pkg/plugin/lib/common/libbpf/_src/ 2>/dev/null || true; \
cp $$TMPDIR/src/*.h $(REPO_ROOT)/pkg/plugin/lib/common/libbpf/_src/ 2>/dev/null || true; \
echo "Copying libbpf include files..."; \
rm -rf $(REPO_ROOT)/pkg/plugin/lib/common/libbpf/_include/linux/*; \
rm -rf $(REPO_ROOT)/pkg/plugin/lib/common/libbpf/_include/uapi/*; \
rm -rf $(REPO_ROOT)/pkg/plugin/lib/common/libbpf/_include/asm/*; \
cp -r $$TMPDIR/include/linux/* $(REPO_ROOT)/pkg/plugin/lib/common/libbpf/_include/linux/ 2>/dev/null || true; \
cp -r $$TMPDIR/include/uapi/* $(REPO_ROOT)/pkg/plugin/lib/common/libbpf/_include/uapi/ 2>/dev/null || true; \
cp -r $$TMPDIR/include/asm/* $(REPO_ROOT)/pkg/plugin/lib/common/libbpf/_include/asm/ 2>/dev/null || true; \
echo "Adding placeholder.go files..."; \
find $(REPO_ROOT)/pkg/plugin/lib/common/libbpf/_src -type d -exec sh -c 'echo "package placeholder" > {}/placeholder.go' \;; \
find $(REPO_ROOT)/pkg/plugin/lib/common/libbpf/_include -type d -exec sh -c 'echo "package placeholder" > {}/placeholder.go' \;; \
echo "Cleaning up temporary directory..."; \
rm -rf $$TMPDIR; \
echo ""; \
echo "libbpf files updated successfully!"; \
echo "Note: vmlinux.h files are architecture-specific and should be generated separately."; \
echo "To regenerate vmlinux.h, run: make update-vmlinux"
3 changes: 3 additions & 0 deletions controller/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ ARG GOOS=linux # default to linux
ARG VERSION
ENV GOARCH=${GOARCH}
ENV GOOS=${GOOS}
ENV CGO_ENABLED=0
RUN --mount=type=cache,target="/root/.cache/go-build" go build -v -o /go/bin/retina/captureworkload -ldflags "-X github.com/microsoft/retina/internal/buildinfo.Version="$VERSION" -X github.com/microsoft/retina/internal/buildinfo.ApplicationInsightsID="$APP_INSIGHTS_ID"" captureworkload/main.go


Expand All @@ -63,6 +64,7 @@ ARG GOOS=linux # default to linux
ARG VERSION
ENV GOARCH=${GOARCH}
ENV GOOS=${GOOS}
ENV CGO_ENABLED=0
RUN --mount=type=cache,target="/root/.cache/go-build" go build -x -v -o /go/bin/retina/controller -ldflags "-X github.com/microsoft/retina/internal/buildinfo.Version="$VERSION" -X github.com/microsoft/retina/internal/buildinfo.ApplicationInsightsID="$APP_INSIGHTS_ID"" controller/main.go


Expand All @@ -74,6 +76,7 @@ ARG GOOS=linux # default to linux
ARG VERSION
ENV GOARCH=${GOARCH}
ENV GOOS=${GOOS}
ENV CGO_ENABLED=0
RUN --mount=type=cache,target="/root/.cache/go-build" go build -v -o /go/bin/retina/initretina -ldflags "-X github.com/microsoft/retina/internal/buildinfo.Version="$VERSION" -X github.com/microsoft/retina/internal/buildinfo.ApplicationInsightsID="$APP_INSIGHTS_ID"" init/retina/main_linux.go


Expand Down
12 changes: 1 addition & 11 deletions controller/Dockerfile.gogen
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,8 @@ ENV GOOS=${GOOS}
ARG GOARCH=amd64
ENV GOARCH=${GOARCH}

RUN apt-get update &&\
apt-get -y install lsb-release wget software-properties-common gnupg file git make

# Install clang and llvm.
RUN wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
RUN add-apt-repository "deb http://apt.llvm.org/bullseye/ llvm-toolchain-bullseye-14 main"
RUN apt-get update

RUN apt-get install -y clang-14 lldb-14 lld-14 clangd-14 man-db
RUN apt-get install -y bpftool libbpf-dev

RUN ln -s /usr/bin/clang-14 /usr/bin/clang
RUN tdnf install -y clang lld bpftool libbpf-devel gnupg file git make lsb-release wget

WORKDIR /app

Expand Down
2 changes: 0 additions & 2 deletions pkg/hubble/common/decoder_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import (
"github.com/cilium/cilium/pkg/labels"
)

//go:generate go run github.com/golang/mock/[email protected] -source decoder.go -destination=mocks/mock_types.go -package=mocks

type EpDecoder interface {
Decode(ip netip.Addr) *flow.Endpoint
IsEndpointOnLocalHost(ip string) bool
Expand Down
44 changes: 37 additions & 7 deletions pkg/plugin/dropreason/_cprog/drop_reason.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ static void get_packet_from_skb(struct packet *p, struct sk_buff *skb)
#endif
}

#ifdef ADVANCED_METRICS
#if ADVANCED_METRICS == 1
static void get_packet_from_sock(struct packet *p, struct sock *sk)
{
// extract 5 tuple from pid
Expand Down Expand Up @@ -256,6 +258,8 @@ static void get_packet_from_sock(struct packet *p, struct sock *sk)
p->dst_port = bpf_ntohs(dport);
p->src_port = bpf_ntohs(sport);
}
#endif
#endif

/*
This function will be saving the PID and length of skb it is working on.
Expand Down Expand Up @@ -312,8 +316,7 @@ int BPF_KRETPROBE(nf_hook_slow_ret, int retVal)
}

SEC("fexit/nf_hook_slow")
int BPF_PROG(nf_hook_slow_fexit, struct sk_buff *skb, struct nf_hook_state *state,
const struct nf_hook_entries *e, unsigned int s, int retVal)
int BPF_PROG(nf_hook_slow_fexit, struct sk_buff *skb, struct nf_hook_state *state, int retVal)
{
if (retVal < 0) {
__u32 skb_len = 0;
Expand Down Expand Up @@ -358,15 +361,30 @@ int BPF_PROG(tcp_v4_connect_fexit, struct sock *sk, struct sockaddr *uaddr, int
}

SEC("kprobe/inet_csk_accept")
int BPF_KPROBE(inet_csk_accept, struct sock *sk, int flags, int *err, bool kern)
int BPF_KPROBE(inet_csk_accept)
{
/*
This function will save the reference value to error.
in kretprobe we look at the value we got back in that reference
*/
__u64 pid_tgid = bpf_get_current_pid_tgid();
__u32 pid = pid_tgid >> 32;
__u64 err_ptr = (__u64)err;

__u64 err_ptr = 0;

// Linux v6.10-rc1+
// https://github.com/torvalds/linux/commit/92ef0fd55ac80dfc2e4654edfe5d1ddfa6e070fe
if (bpf_core_type_exists(struct proto_accept_arg)) {
struct proto_accept_arg *arg = (struct proto_accept_arg *)PT_REGS_PARM2(ctx);

int *err_ptr_raw = 0;
bpf_core_read(&err_ptr_raw, sizeof(err_ptr_raw), &arg->err);
err_ptr = (__u64)err_ptr_raw;
} else {
int *err = (int *)PT_REGS_PARM3(ctx);
err_ptr = (__u64)err;
}

bpf_map_update_elem(&retina_dropreason_accept_pids, &pid, &err_ptr, BPF_ANY);
return 0;
}
Expand Down Expand Up @@ -415,16 +433,28 @@ int BPF_KRETPROBE(inet_csk_accept_ret, struct sock *sk)
}

SEC("fexit/inet_csk_accept")
int BPF_PROG(inet_csk_accept_fexit, struct sock *sk, int flags, int *err, struct sock *retsk)
int BPF_PROG(inet_csk_accept_fexit)
{
// Use bpf_core_read for compatibility with both Linux v6.10-rc1+ and older versions.
// https://github.com/torvalds/linux/commit/92ef0fd55ac80dfc2e4654edfe5d1ddfa6e070fe
struct sock *retsk = NULL;

int offset;
if (bpf_core_type_exists(struct proto_accept_arg))
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting this part right requires some extensive testing. It would be good to have this covered by some form of automated tests to make sure code from those probes work as expected.

offset = 8 * 2; // Linux 6.10+: 2 parameters (sk, arg)
else
offset = 8 * 4; // Older kernels: 4 parameters (sk, newsock, flags, err)

bpf_core_read(&retsk, sizeof(retsk), (void *)ctx + offset);

if (retsk != NULL) {
return 0;
}

// TODO
// Pass 0 packet length - get_packet_from_sock above doesn't obtain this value, either.
// Pass 0 return value; verifier failure, same as buggy kprobe above.
update_metrics_map_basic(TCP_ACCEPT_BASIC, 0, 0);
update_metrics_map_basic(TCP_ACCEPT_BASIC, 0, 0);

return 0;
}
Expand Down Expand Up @@ -549,4 +579,4 @@ int BPF_PROG(nf_conntrack_confirm_fexit, struct sk_buff *skb, int retVal)

update_metrics_map_basic(CONNTRACK_ADD_DROP, retVal, skb_len);
return 0;
}
}
3 changes: 0 additions & 3 deletions pkg/plugin/dropreason/mocks/mock_types_linux.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pkg/plugin/dropreason/types_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ type (
// Interface to https://pkg.go.dev/github.com/cilium/ebpf#Map.
// Added for unit tests.
//
//go:generate go run go.uber.org/mock/[email protected] -source=types_linux.go -destination=mocks/mock_types.go -package=dropreason . IMap IMapIterator IPerfReader
//go:generate go run go.uber.org/mock/[email protected] -source=types_linux.go -destination=mocks/mock_types_linux.go -package=dropreason . IMap IMapIterator IPerfReader
type IMapIterator interface {
Next(keyOut interface{}, valueOut interface{}) bool
Err() error
Expand Down
Loading
Loading