Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpf,metrics: add line/file information to drop metrics #30972

Merged
merged 3 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 5 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,9 @@ TEST_LDFLAGS=-ldflags "-X github.com/cilium/cilium/pkg/kvstore.consulDummyAddres

TEST_UNITTEST_LDFLAGS=-ldflags "-X github.com/cilium/cilium/pkg/datapath.datapathSHA256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"

BPF_SOURCE_NAMES_TO_IDS ?= bpf/source_names_to_ids.h
GO_SOURCE_NAMES_TO_IDS ?= pkg/monitor/datapath_drop.go
build: $(SUBDIRS) ## Builds all the components for Cilium by executing make in the respective sub directories.

build: check-sources $(SUBDIRS) ## Builds all the components for Cilium by executing make in the respective sub directories.

build-container: check-sources ## Builds components required for cilium-agent container.
build-container: ## Builds components required for cilium-agent container.
for i in $(SUBDIRS_CILIUM_CONTAINER); do $(MAKE) $(SUBMAKEOPTS) -C $$i all; done

build-container-operator: ## Builds components required for cilium-operator container.
Expand Down Expand Up @@ -497,10 +494,8 @@ endif
$(QUIET) contrib/scripts/check-time.sh
@$(ECHO_CHECK) contrib/scripts/check-go-testdata.sh
$(QUIET) contrib/scripts/check-go-testdata.sh

check-sources:
@$(ECHO_CHECK) pkg/datapath/loader/check-sources.sh
$(QUIET) BPF_SOURCE_NAMES_TO_IDS=$(BPF_SOURCE_NAMES_TO_IDS) GO_SOURCE_NAMES_TO_IDS=$(GO_SOURCE_NAMES_TO_IDS) pkg/datapath/loader/check-sources.sh
@$(ECHO_CHECK) contrib/scripts/check-source-info.sh
$(QUIET) contrib/scripts/check-source-info.sh

pprof-heap: ## Get Go pprof heap profile.
$(QUIET)$(GO) tool pprof http://localhost:6060/debug/pprof/heap
Expand Down Expand Up @@ -566,7 +561,7 @@ help: ## Display help for the Makefile, from https://www.thapaliya.com/en/writin
$(call print_help_line,"docker-operator-*-image","Build platform specific cilium-operator images(alibabacloud, aws, azure, generic)")
$(call print_help_line,"docker-*-image-unstripped","Build unstripped version of above docker images(cilium, hubble-relay, operator etc.)")

.PHONY: help clean clean-container dev-doctor force generate-api generate-health-api generate-operator-api generate-hubble-api install licenses-all veryclean check-sources
.PHONY: help clean clean-container dev-doctor force generate-api generate-health-api generate-operator-api generate-hubble-api install licenses-all veryclean
force :;

# this top level run_bpf_tests target will run the bpf unit tests inside the Cilium Builder container.
Expand Down
6 changes: 5 additions & 1 deletion bpf/lib/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "config.h"
#include "tunnel.h"

#include "source_info.h"

#ifndef AF_INET
#define AF_INET 2
#endif
Expand Down Expand Up @@ -433,7 +435,9 @@ struct metrics_key {
__u8 reason; /* 0: forwarded, >0 dropped */
__u8 dir:2, /* 1: ingress 2: egress */
pad:6;
__u16 reserved[3]; /* reserved for future extension */
__u16 line; /* __MAGIC_LINE__ */
__u8 file; /* __MAGIC_FILE__, needs to fit __source_file_name_to_id */
__u8 reserved[3]; /* reserved for future extension */
};


Expand Down
16 changes: 6 additions & 10 deletions bpf/lib/drop.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ _send_drop_notify(__u8 file, __u16 line, struct __ctx_buff *ctx,
ctx_store_meta(ctx, 3, dst_id);
ctx_store_meta(ctx, 4, exitcode | file << 8 | line << 16);

update_metrics(ctx_full_len(ctx), direction, (__u8)reason);
_update_metrics(ctx_full_len(ctx), direction, (__u8)reason, line, file);
ret = tail_call_internal(ctx, CILIUM_CALL_DROP_NOTIFY, NULL);
/* ignore the returned error, use caller-provided exitcode */

Expand All @@ -130,7 +130,7 @@ int _send_drop_notify(__u8 file __maybe_unused, __u16 line __maybe_unused,
__u32 dst __maybe_unused, __u32 dst_id __maybe_unused,
__u32 reason, __u32 exitcode, enum metric_dir direction)
{
update_metrics(ctx_full_len(ctx), direction, (__u8)reason);
_update_metrics(ctx_full_len(ctx), direction, (__u8)reason, line, file);
return exitcode;
}
#endif /* DROP_NOTIFY */
Expand Down Expand Up @@ -163,24 +163,20 @@ int _send_drop_notify(__u8 file __maybe_unused, __u16 line __maybe_unused,
__DROP_REASON(err) | ((__u8)(__ext_err < -128 ? 0 : __ext_err) << 8); \
})

#include "../source_names_to_ids.h"

#define __MAGIC_FILE__ (__u8)__source_file_name_to_id(__FILE_NAME__)

#define send_drop_notify(ctx, src, dst, dst_id, reason, exitcode, direction) \
_send_drop_notify(__MAGIC_FILE__, __LINE__, ctx, src, dst, dst_id, \
_send_drop_notify(__MAGIC_FILE__, __MAGIC_LINE__, ctx, src, dst, dst_id, \
__DROP_REASON(reason), exitcode, direction)

#define send_drop_notify_error(ctx, src, reason, exitcode, direction) \
_send_drop_notify(__MAGIC_FILE__, __LINE__, ctx, src, 0, 0, \
_send_drop_notify(__MAGIC_FILE__, __MAGIC_LINE__, ctx, src, 0, 0, \
__DROP_REASON(reason), exitcode, direction)

#define send_drop_notify_ext(ctx, src, dst, dst_id, reason, ext_err, exitcode, direction) \
_send_drop_notify(__MAGIC_FILE__, __LINE__, ctx, src, dst, dst_id, \
_send_drop_notify(__MAGIC_FILE__, __MAGIC_LINE__, ctx, src, dst, dst_id, \
__DROP_REASON_EXT(reason, ext_err), exitcode, direction)

#define send_drop_notify_error_ext(ctx, src, reason, ext_err, exitcode, direction) \
_send_drop_notify(__MAGIC_FILE__, __LINE__, ctx, src, 0, 0, \
_send_drop_notify(__MAGIC_FILE__, __MAGIC_LINE__, ctx, src, 0, 0, \
__DROP_REASON_EXT(reason, ext_err), exitcode, direction)

#endif /* __LIB_DROP__ */
9 changes: 6 additions & 3 deletions bpf/lib/metrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,18 @@
* is the drop error code.
* Update the metrics map.
*/
static __always_inline void update_metrics(__u64 bytes, __u8 direction,
__u8 reason)
#define update_metrics(bytes, direction, reason) \
_update_metrics(bytes, direction, reason, __MAGIC_LINE__, __MAGIC_FILE__)
static __always_inline void _update_metrics(__u64 bytes, __u8 direction,
__u8 reason, __u16 line, __u8 file)
{
struct metrics_value *entry, new_entry = {};
struct metrics_key key = {};

key.reason = reason;
key.dir = direction;

key.line = line;
key.file = file;

entry = map_lookup_elem(&METRICS_MAP, &key);
if (entry) {
Expand Down
32 changes: 24 additions & 8 deletions bpf/source_names_to_ids.h → bpf/lib/source_info.h
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/* Copyright Authors of Cilium */
#ifndef HEADER_NAMES_TO_IDS_H_
#define HEADER_NAMES_TO_IDS_H_
#pragma once

#ifndef BPF_TEST
#define __MAGIC_FILE__ (__u8)__id_for_file(__FILE_NAME__)
#define __MAGIC_LINE__ __LINE__
#else
/* bpf tests assert that metrics get updated by performing a map lookup.
* This cannot work if the metrics key has dynamic components like line/file
* info, so disable this during tests.
*/
#define __MAGIC_FILE__ 0
#define __MAGIC_LINE__ 0
#endif

#define _strcase_(id, known_name) do { \
if (!__builtin_strcmp(header_name, known_name)) \
return id; \
} while (0)

/*
* The __source_file_name_to_id function is used inside lib/drop.h to encode
* source file information with drop info messages. It must be always inlined,
* otherwise clang won't translate this to a constexpr.
* __id_for_file is used by __MAGIC_FILE__ to encode source file information in
* drop notifications and forward/drop metrics. It must be inlined, otherwise
* clang won't translate this to a constexpr.
*
* The following list of files is static, but it is validated during build with
* the pkg/datapath/loader/check-sources.sh tool.
*/
static __always_inline int
__source_file_name_to_id(const char *const header_name)
__id_for_file(const char *const header_name)
{
/* @@ source files list begin */

Expand All @@ -26,6 +37,8 @@ __source_file_name_to_id(const char *const header_name)
_strcase_(2, "bpf_lxc.c");
_strcase_(3, "bpf_overlay.c");
_strcase_(4, "bpf_xdp.c");
_strcase_(5, "bpf_sock.c");
_strcase_(6, "bpf_network.c");

/* header files from bpf/lib/ */
_strcase_(101, "arp.h");
Expand All @@ -35,12 +48,15 @@ __source_file_name_to_id(const char *const header_name)
_strcase_(105, "nodeport.h");
_strcase_(106, "lb.h");
_strcase_(107, "mcast.h");
_strcase_(108, "ipv4.h");
_strcase_(109, "conntrack.h");
_strcase_(110, "l3.h");
_strcase_(111, "trace.h");
_strcase_(112, "encap.h");

/* @@ source files list end */

return 0;
}

#undef _strcase_

#endif /* HEADER_NAMES_TO_IDS_H_ */
33 changes: 19 additions & 14 deletions bpf/lib/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,35 +79,37 @@ enum {
*
* Update metrics based on a trace event
*/
#define update_trace_metrics(ctx, obs_point, reason) \
_update_trace_metrics(ctx, obs_point, reason, __MAGIC_LINE__, __MAGIC_FILE__)
static __always_inline void
update_trace_metrics(struct __ctx_buff *ctx, enum trace_point obs_point,
enum trace_reason reason)
_update_trace_metrics(struct __ctx_buff *ctx, enum trace_point obs_point,
enum trace_reason reason, __u16 line, __u8 file)
{
__u8 encrypted;

switch (obs_point) {
case TRACE_TO_LXC:
update_metrics(ctx_full_len(ctx), METRIC_INGRESS,
REASON_FORWARDED);
_update_metrics(ctx_full_len(ctx), METRIC_INGRESS,
REASON_FORWARDED, line, file);
break;
case TRACE_TO_HOST:
case TRACE_TO_STACK:
case TRACE_TO_OVERLAY:
case TRACE_TO_NETWORK:
update_metrics(ctx_full_len(ctx), METRIC_EGRESS,
REASON_FORWARDED);
_update_metrics(ctx_full_len(ctx), METRIC_EGRESS,
REASON_FORWARDED, line, file);
break;
case TRACE_FROM_HOST:
case TRACE_FROM_STACK:
case TRACE_FROM_OVERLAY:
case TRACE_FROM_NETWORK:
encrypted = reason & TRACE_REASON_ENCRYPTED;
if (!encrypted)
update_metrics(ctx_full_len(ctx), METRIC_INGRESS,
REASON_PLAINTEXT);
_update_metrics(ctx_full_len(ctx), METRIC_INGRESS,
REASON_PLAINTEXT, line, file);
else
update_metrics(ctx_full_len(ctx), METRIC_INGRESS,
REASON_DECRYPT);
_update_metrics(ctx_full_len(ctx), METRIC_INGRESS,
REASON_DECRYPT, line, file);
break;
/* TRACE_FROM_LXC, i.e endpoint-to-endpoint delivery is handled
* separately in ipv*_local_delivery() where we can bump an egress
Expand Down Expand Up @@ -183,17 +185,20 @@ emit_trace_notify(enum trace_point obs_point, __u32 monitor)
return true;
}

#define send_trace_notify(ctx, obs_point, src, dst, dst_id, ifindex, reason, monitor) \
_send_trace_notify(ctx, obs_point, src, dst, dst_id, ifindex, reason, monitor, \
__MAGIC_LINE__, __MAGIC_FILE__)
static __always_inline void
send_trace_notify(struct __ctx_buff *ctx, enum trace_point obs_point,
__u32 src, __u32 dst, __u16 dst_id, __u32 ifindex,
enum trace_reason reason, __u32 monitor)
_send_trace_notify(struct __ctx_buff *ctx, enum trace_point obs_point,
__u32 src, __u32 dst, __u16 dst_id, __u32 ifindex,
enum trace_reason reason, __u32 monitor, __u16 line, __u8 file)
{
__u64 ctx_len = ctx_full_len(ctx);
__u64 cap_len = min_t(__u64, monitor ? : TRACE_PAYLOAD_LEN,
ctx_len);
struct trace_notify msg __align_stack_8;

update_trace_metrics(ctx, obs_point, reason);
_update_trace_metrics(ctx, obs_point, reason, line, file);

if (!emit_trace_notify(obs_point, monitor))
return;
Expand Down
1 change: 1 addition & 0 deletions bugtool/cmd/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ func copyCiliumInfoCommands(cmdDir string, k8sPods []string) []string {
ciliumCommands := []string{
fmt.Sprintf("cilium-dbg debuginfo --output=markdown,json -f --output-directory=%s", cmdDir),
"cilium-dbg metrics list",
"cilium-dbg bpf metrics list",
"cilium-dbg fqdn cache list",
"cilium-dbg config -a",
"cilium-dbg encrypt status",
Expand Down