Skip to content

Commit

Permalink
Disable eBPF capture backend in case of eBPF objects failed to load (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
iluxa authored Jan 22, 2025
1 parent c70d7f3 commit 680b32d
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 35 deletions.
19 changes: 12 additions & 7 deletions bpf/packet_sniffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ cgroup_skb/ingress hook│ │cgroup_skb/egress

#include "packet_sniffer_v1.c"

struct pkt {
struct pkt
{
__u64 timestamp;
__u64 cgroup_id;
__u64 id;
Expand All @@ -57,18 +58,21 @@ struct pkt {
unsigned char buf[PKT_PART_LEN];
};

struct {
struct
{
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__uint(max_entries, 1);
__type(key, int);
__type(value, struct pkt);
} pkt_heap SEC(".maps");

struct pkt_id_t {
struct pkt_id_t
{
__u64 id;
struct bpf_spin_lock lock;
};
struct {
struct
{
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(max_entries, 1);
__type(key, int);
Expand Down Expand Up @@ -151,12 +155,12 @@ static __always_inline int filter_packets(struct __sk_buff *skb, void *cgrpctxma
if (side == PACKET_DIRECTION_RECEIVED)
{
TRACE_PACKET("cg/in", true, skb->local_ip4, skb->remote_ip4, skb->local_port & 0xffff, skb->remote_port & 0xffff, cgroup_id);
save_packet(skb, src_ip, skb->remote_port>>16, dst_ip, bpf_htons(skb->local_port), cgroup_id, side);
save_packet(skb, src_ip, skb->remote_port >> 16, dst_ip, bpf_htons(skb->local_port), cgroup_id, side);
}
else
{
TRACE_PACKET("cg/out", true, skb->local_ip4, skb->remote_ip4, skb->local_port & 0xffff, skb->remote_port & 0xffff, cgroup_id);
save_packet(skb, src_ip, bpf_htons(skb->local_port), dst_ip, skb->remote_port>>16, cgroup_id, side);
save_packet(skb, src_ip, bpf_htons(skb->local_port), dst_ip, skb->remote_port >> 16, cgroup_id, side);
}

return 1;
Expand Down Expand Up @@ -245,7 +249,8 @@ static __noinline void _save_packet(struct pkt_sniffer_ctx *ctx)
bpf_spin_unlock(&pkt_id_ptr->lock);

// send initial chunk before the first packet
if (unlikely(packet_id == 0)) {
if (unlikely(packet_id == 0))
{
if (bpf_perf_event_output(skb, &pkts_buffer, BPF_F_CURRENT_CPU, p, 0))
{
log_error(skb, LOG_ERROR_PKT_SNIFFER, 11, 0l, 0l);
Expand Down
63 changes: 43 additions & 20 deletions pkg/bpf/bpf.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func programHelperExists(pt ebpf.ProgramType, helper asm.BuiltinFunc) uint64 {
return 0
}

func NewBpfObjects(disableEbpfCapture, preferCgroupV1 bool) (*BpfObjects, error) {
func NewBpfObjects(disableEbpfCapture *bool, preferCgroupV1 bool) (*BpfObjects, error) {
var err error

objs := BpfObjects{}
Expand All @@ -112,7 +112,7 @@ func NewBpfObjects(disableEbpfCapture, preferCgroupV1 bool) (*BpfObjects, error)
tlsPath := filepath.Join(PinPath, PinNameTLSPackets)

if !kernel.CheckKernelVersion(5, 4, 0) {
disableEbpfCapture = true
*disableEbpfCapture = true
}

markDisabledEBPF := func() error {
Expand All @@ -126,7 +126,7 @@ func NewBpfObjects(disableEbpfCapture, preferCgroupV1 bool) (*BpfObjects, error)
}

ebpfBackendStatus := "enabled"
if disableEbpfCapture {
if *disableEbpfCapture {
ebpfBackendStatus = "disabled"
if err = markDisabledEBPF(); err != nil {
return nil, err
Expand Down Expand Up @@ -161,7 +161,7 @@ func NewBpfObjects(disableEbpfCapture, preferCgroupV1 bool) (*BpfObjects, error)
}

disableCapture := uint64(0)
if disableEbpfCapture {
if *disableEbpfCapture {
disableCapture = 1
}

Expand All @@ -180,7 +180,7 @@ func NewBpfObjects(disableEbpfCapture, preferCgroupV1 bool) (*BpfObjects, error)
"DISABLE_EBPF_CAPTURE": disableCapture,
}

if !disableEbpfCapture {
if !*disableEbpfCapture {
pktsBuffer, err := ebpf.LoadPinnedMap(plainPath, nil)
if err == nil {
mapReplacements["pkts_buffer"] = pktsBuffer
Expand All @@ -198,27 +198,50 @@ func NewBpfObjects(disableEbpfCapture, preferCgroupV1 bool) (*BpfObjects, error)
log.Error().Msg(fmt.Sprintf("load tls packets map failed: %v", err))
}

if disableEbpfCapture {
loadTracer := func(obj *TracerObjects) (err error) {
if err = objects.loadBpfObjects(bpfConsts, mapReplacements, bytes.NewReader(_TracerBytes)); err != nil {
err = fmt.Errorf("load tracer objects failed: %v", err)
return
}
*obj = *objects.bpfObjs.(*TracerObjects)
return
}

loadTracerNoEbpf := func(obj *TracerObjects) (err error) {
if err = objectsNoEbpf.loadBpfObjects(bpfConsts, mapReplacements, bytes.NewReader(_TracerNoEbpfBytes)); err != nil {
log.Error().Msg(fmt.Sprintf("load bpf objects failed: %v", err))
return nil, err
err = fmt.Errorf("load tracer noBpf objects failed: %v", err)
return
}

o := objectsNoEbpf.bpfObjs.(*TracerNoEbpfObjects)
if err = copier.Copy(&objs.BpfObjs.TracerPrograms, &o.TracerNoEbpfPrograms); err != nil {
log.Error().Msg(fmt.Sprintf("copy program objects failed: %v", err))
return nil, err
if err = copier.Copy(&obj.TracerPrograms, &o.TracerNoEbpfPrograms); err != nil {
err = fmt.Errorf("copy program objects failed: %v", err)
return
}
if err = copier.Copy(&objs.BpfObjs.TracerMaps, &o.TracerNoEbpfMaps); err != nil {
log.Error().Msg(fmt.Sprintf("copy map objects failed: %v", err))
return nil, err
if err = copier.Copy(&obj.TracerMaps, &o.TracerNoEbpfMaps); err != nil {
err = fmt.Errorf("copy map objects failed: %v", err)
return
}
} else {
if err = objects.loadBpfObjects(bpfConsts, mapReplacements, bytes.NewReader(_TracerBytes)); err != nil {
log.Error().Msg(fmt.Sprintf("load bpf objects failed: %v", err))
return nil, err
return
}

if !*disableEbpfCapture {
err = loadTracer(&objs.BpfObjs)
if err != nil {
log.Warn().Msg(fmt.Sprintf("load tracer objects failed, trying load without ebpf packet capture backend. Error: %v", err))
if err = markDisabledEBPF(); err != nil {
return nil, err
}
objs = BpfObjects{}
*disableEbpfCapture = true
}
}

if *disableEbpfCapture {
err = loadTracerNoEbpf(&objs.BpfObjs)
if err != nil {
log.Warn().Msg(fmt.Sprintf("load tracer noEbpf objects failed. Error: %v", err))
}
objs.BpfObjs = *objects.bpfObjs.(*TracerObjects)
}
}

Expand Down Expand Up @@ -252,7 +275,7 @@ func NewBpfObjects(disableEbpfCapture, preferCgroupV1 bool) (*BpfObjects, error)
return nil
}

if !disableEbpfCapture {
if !*disableEbpfCapture {
if err = pinMap("pkts_buffer", plainPath, objs.BpfObjs.PktsBuffer); err != nil {
return nil, err
}
Expand Down
3 changes: 0 additions & 3 deletions pkg/bpf/tracer_bpfel_arm64.go

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

Binary file modified pkg/bpf/tracer_bpfel_arm64.o
Binary file not shown.
3 changes: 0 additions & 3 deletions pkg/bpf/tracer_bpfel_x86.go

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

Binary file modified pkg/bpf/tracer_bpfel_x86.o
Binary file not shown.
5 changes: 3 additions & 2 deletions tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (t *Tracer) Init(
return fmt.Errorf("cgroups controller create failed")
}

t.bpfObjects, err = bpf.NewBpfObjects(*disableEbpfCapture, *preferCgroupV1Capture)
t.bpfObjects, err = bpf.NewBpfObjects(disableEbpfCapture, *preferCgroupV1Capture)
if err != nil {
return fmt.Errorf("creating bpf failed: %v", err)
}
Expand Down Expand Up @@ -221,7 +221,8 @@ func initBPFSubsystem() {
}
}

_, err := bpf.NewBpfObjects(false, false)
disableEbpf := false
_, err := bpf.NewBpfObjects(&disableEbpf, false)
if err != nil {
log.Error().Err(err).Msg("create objects failed")
}
Expand Down

0 comments on commit 680b32d

Please sign in to comment.