On Wed, Aug 03, 2022 at 04:30:54PM -0700, sdf@xxxxxxxxxx wrote: > > +struct sock_common { > > + unsigned short skc_family; > > + unsigned long skc_flags; > > + unsigned char skc_reuse:4; > > + unsigned char skc_reuseport:1; > > + unsigned char skc_ipv6only:1; > > + unsigned char skc_net_refcnt:1; > > +} __attribute__((preserve_access_index)); > > + > > +struct sock { > > + struct sock_common __sk_common; > > + __u16 sk_type; > > + __u16 sk_protocol; > > + int sk_rcvlowat; > > + __u32 sk_mark; > > + unsigned long sk_max_pacing_rate; > > + unsigned int keepalive_time; > > + unsigned int keepalive_intvl; > > +} __attribute__((preserve_access_index)); > > + > > +struct tcp_options_received { > > + __u16 user_mss; > > +} __attribute__((preserve_access_index)); > > I'm assuming you're not using vmlinux here because it doesn't bring > it most of the defines? Should we add missing stuff to bpf_tracing_net.h > instead? Ah, actually my first attempt was to use vmlinux.h and had all defines ready for addition to bpf_tracing_net.h. However, I hit an issue in reading bitfield. It is why the bitfield in the tcp_sock below is sandwiched between __u32. I think it is likely LLVM and/or CO-RE related. Yonghong is helping to investigate it. In the mean time, I define those mini struct here. Once the bitfield issue is resolved, we can go back to use vmlinux.h. > > > +struct ipv6_pinfo { > > + __u16 recverr:1, > > + sndflow:1, > > + repflow:1, > > + pmtudisc:3, > > + padding:1, > > + srcprefs:3, > > + dontfrag:1, > > + autoflowlabel:1, > > + autoflowlabel_set:1, > > + mc_all:1, > > + recverr_rfc4884:1, > > + rtalert_isolate:1; > > +} __attribute__((preserve_access_index)); > > + > > +struct inet_sock { > > + /* sk and pinet6 has to be the first two members of inet_sock */ > > + struct sock sk; > > + struct ipv6_pinfo *pinet6; > > +} __attribute__((preserve_access_index)); > > + > > +struct inet_connection_sock { > > + __u32 icsk_user_timeout; > > + __u8 icsk_syn_retries; > > +} __attribute__((preserve_access_index)); > > + > > +struct tcp_sock { > > + struct inet_connection_sock inet_conn; > > + struct tcp_options_received rx_opt; > > + __u8 save_syn:2, > > + syn_data:1, > > + syn_fastopen:1, > > + syn_fastopen_exp:1, > > + syn_fastopen_ch:1, > > + syn_data_acked:1, > > + is_cwnd_limited:1; > > + __u32 window_clamp; > > + __u8 nonagle : 4, > > + thin_lto : 1, > > + recvmsg_inq : 1, > > + repair : 1, > > + frto : 1; > > + __u32 notsent_lowat; > > + __u8 keepalive_probes; > > + unsigned int keepalive_time; > > + unsigned int keepalive_intvl; > > +} __attribute__((preserve_access_index)); > > + > > +struct socket { > > + struct sock *sk; > > +} __attribute__((preserve_access_index)); > > + > > +struct loop_ctx { > > + void *ctx; > > + struct sock *sk; > > +}; > > + > > +static int __bpf_getsockopt(void *ctx, struct sock *sk, > > + int level, int opt, int *optval, > > + int optlen) > > +{ > > + if (level == SOL_SOCKET) { > > + switch (opt) { > > + case SO_REUSEADDR: > > + *optval = !!(sk->__sk_common.skc_reuse); > > + break; > > + case SO_KEEPALIVE: > > + *optval = !!(sk->__sk_common.skc_flags & (1UL << 3)); > > + break; > > + case SO_RCVLOWAT: > > + *optval = sk->sk_rcvlowat; > > + break; > > What's the idea with the options above? Why not allow them in > bpf_getsockopt instead? I am planning to refactor the bpf_getsockopt also, so trying to avoid adding more dup code at this point while they can directly be read from sk through PTR_TO_BTF_ID. btw, since we are on bpf_getsockopt(), do you still see a usage on bpf_getsockopt() for those 'integer-value' optnames that can be easily read from the sk pointer ? > > > + case SO_MARK: > > + *optval = sk->sk_mark; > > + break; > > SO_MARK should be handled by bpf_getsockopt ? Good point, will remove SO_MARK case. Thanks for the review!