help: trying to gather process information, tx/rx byte count , ifindex for sends/receives

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The problem I'm trying to solve is associating some process
information (let's just say pid) with a socket in an fentry where it's
safe to grab pid/tgid.
It seems like inet_sendmsg is a pretty safe place to do this.

Say I want to gather information about the process initiating a
transmit as well as the interface the bit of data is going out of.
I put a fentry hook on inet_sendmsg to grab pid_tgid and then I put
another fentry hook onto ip_local_out to grab the interface.
The problem I'm seeing is that the data accessible from
fentry/ip_local_out seems unreliable. The `struct sock* sk` being
passed in often can't be associated with a `struct sock* sk` seen on
`inet_sendmsg`.

An example minimal toy program to help illustrate my dilemma.


struct {
  __uint(type, BPF_MAP_TYPE_LRU_HASH);
  __uint(max_entries, 1024);
  __type(key, struct socket*);
  __type(value, uint64_t);
} sock_to_tgid_pid SEC(".maps"); // pretty much a sk_storage, almost
interchangeable


SEC("fentry/inet_sendmsg")
int BPF_PROG(do_inet_sendmsg_enter,
             struct socket* sock,
             struct msghdr* msg,
             size_t size) {
    uint64_t pid_tgid = 0;
    pid_tgid = bpf_get_current_pid_tgid();
    bpf_map_update_elem(&sock_to_tgid_pid, sock, &pid_tgid, BPF_NOEXIST);
    return 0;
}

SEC("fentry/ip_local_out")
int BPF_PROG(do_ip_local_out, struct net* net, struct sock* sk, struct
sk_buff* skb) {
  struct socket* sock = BPF_CORE_READ(skb, sk, sk_socket);
 struct network_data* d = bpf_map_lookup_elem(&sock_to_tgid_pid,
sock); <==== This will sometimes fail
 if (d == NULL){
bpf_printk("Failed socket lookup");
}
}

The test case would be that I run ping several times and in some
situations the map lookup will be fine and other situations the map
lookup will fail.


My initial thought is that putting fentry/fexit hooks deep within the
networking stack might not be the best idea.. Maybe there is a lot of
nuance I'm not familiar with?

I then started looking at tc hooks, thinking that this is a well lit
path. Unfortunately for tc hooks a struct __sk_buff* is passed in and
there doesn't seem to be a way to get at the socket that owns the
data.

So my questions are:

1.) Does anyone see anything obviously wrong with my fentry approach?
2.) Is there a way to get at a socket cookie, sk_storage or a reliable
struct socket* from within a tc-ebpf?
3.) Am I asking on the wrong lkml and should instead cross-post this
to a more network oriented lkml?

Thanks in advance




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux