0

As @andy-dalton suggests. I changed type of err and initialized it. But it still outputs the same results.

The modified code:

SEC("sockops")
int bpf_sockops_cb(struct bpf_sock_ops *skops) {
    u32 op = 0;

    long err;

    err = bpf_core_read(&op, sizeof(op), &skops->op);
    if (err) {
        bpf_printk("err code %ld\n", err);
    }

    bpf_printk("op1 = %u, op2 = %u \n", op, skops->op);

    return 0;
}

The outputs:

curl-286392  [011] ....1 44631.729219: bpf_trace_printk: op1 = 3245625024, op2 = 3 

            curl-286392  [011] ....1 44631.729223: bpf_trace_printk: op1 = 3245625024, op2 = 2 

            curl-286392  [011] ....1 44631.729223: bpf_trace_printk: op1 = 3245625024, op2 = 1 

            curl-286392  [011] ....1 44631.729224: bpf_trace_printk: op1 = 3245625024, op2 = 6

My eBPF program as follows.

#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_endian.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
#include "common.h"

char __license[] SEC("license") = "GPL";

SEC("sockops")
int bpf_sockops_cb(struct bpf_sock_ops *skops) {
    u32 op;

    int err;

    err = bpf_core_read(&op, sizeof(op), &skops->op);
    if (err) {
        bpf_printk("err\n");
    }

    bpf_printk("op1 = %u, op2 = %u \n", op, skops->op);

    return 0;
}

When I check the tracing output by cat /sys/kernel/debug/tracing/trace_pipe, it shows that op1 != op2.

curl-1466326 [009] ....1 241519.609044: bpf_trace_printk: op1 = 3913290112, op2 = 3 

            curl-1466326 [009] ....1 241519.609048: bpf_trace_printk: op1 = 3913290112, op2 = 2 

            curl-1466326 [009] ....1 241519.609048: bpf_trace_printk: op1 = 3913290112, op2 = 1 

            curl-1466326 [009] ....1 241519.609049: bpf_trace_printk: op1 = 3913290112, op2 = 6

Why does op1 and op2 become different ?

1
  • You might want to (1) initialize op before calling bpf_core_read() so you can see if the function is changing anything and (2) make the type of err be long instead of int. If you do that, does anything change? If so, please edit your question and include the details. Commented Dec 9, 2024 at 20:21

1 Answer 1

0

I dump the related ebpf instruction as follows. I found a weird thing:

  1. At line 5, bpf_core_read reads the value at address r6 (the first argument of bpf_sockops_cb).
  2. At line 32, bpf_printk outputs the value at address r6 + 48.

I think it is the reason.

int bpf_sockops_cb(struct bpf_sock_ops * skops):
; int bpf_sockops_cb(struct bpf_sock_ops *skops) {
   0: (bf) r6 = r1
   1: (b7) r7 = 0
; u32 op = 0;
   2: (63) *(u32 *)(r10 -4) = r7
   3: (b7) r1 = 0
   4: (bf) r3 = r6
   5: (0f) r3 += r1
   6: (bf) r1 = r10
; 
   7: (07) r1 += -4
; err = bpf_core_read(&op, sizeof(op), &skops->op);
   8: (b7) r2 = 4
   9: (85) call bpf_probe_read_kernel#-69680
; if (err) {
  10: (15) if r0 == 0x0 goto pc+12
  11: (b7) r1 = 10
; bpf_printk("err code %ld\n", err);
  12: (6b) *(u16 *)(r10 -20) = r1
  13: (b7) r1 = 1684808992
  14: (63) *(u32 *)(r10 -24) = r1
  15: (18) r1 = 0x65646f6320727265
  17: (7b) *(u64 *)(r10 -32) = r1
  18: (bf) r1 = r10
  19: (07) r1 += -32
  20: (b7) r2 = 14
  21: (bf) r3 = r0
  22: (85) call bpf_trace_printk#-69392
  23: (b7) r1 = 169899301
; bpf_printk("op1 = %u, op2 = %u \n", op, skops->op);
  24: (63) *(u32 *)(r10 -16) = r1
  25: (18) r1 = 0x203d2032706f202c
  27: (7b) *(u64 *)(r10 -24) = r1
  28: (18) r1 = 0x7525203d2031706f
  30: (7b) *(u64 *)(r10 -32) = r1
  31: (73) *(u8 *)(r10 -12) = r7
  32: (71) r4 = *(u8 *)(r6 +48)
  33: (61) r3 = *(u32 *)(r10 -4)
  34: (bf) r1 = r10
  35: (07) r1 += -32
  36: (b7) r2 = 21
  37: (85) call bpf_trace_printk#-69392
; return 0;
  38: (b7) r0 = 0
  39: (95) exit

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.