On Thu, Jan 27, 2022 at 9:24 AM Jakub Sitnicki <jakub@xxxxxxxxxxxxxx> wrote: > > Menglong Dong reports that the documentation for the dst_port field in > struct bpf_sock is inaccurate and confusing. From the BPF program PoV, the > field is a zero-padded 16-bit integer in network byte order. The value > appears to the BPF user as if laid out in memory as so: > > offsetof(struct bpf_sock, dst_port) + 0 <port MSB> > + 8 <port LSB> > +16 0x00 > +24 0x00 > > 32-, 16-, and 8-bit wide loads from the field are all allowed, but only if > the offset into the field is 0. > > 32-bit wide loads from dst_port are especially confusing. The loaded value, > after converting to host byte order with bpf_ntohl(dst_port), contains the > port number in the upper 16-bits. > > Remove the confusion by splitting the field into two 16-bit fields. For > backward compatibility, allow 32-bit wide loads from offsetof(struct > bpf_sock, dst_port). > > While at it, allow loads 8-bit loads at offset [0] and [1] from dst_port. > > Reported-by: Menglong Dong <imagedong@xxxxxxxxxxx> > Signed-off-by: Jakub Sitnicki <jakub@xxxxxxxxxxxxxx> > --- > include/uapi/linux/bpf.h | 3 ++- > net/core/filter.c | 9 ++++++++- > 2 files changed, 10 insertions(+), 2 deletions(-) > > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h > index 4a2f7041ebae..027e84b18b51 100644 > --- a/include/uapi/linux/bpf.h > +++ b/include/uapi/linux/bpf.h > @@ -5574,7 +5574,8 @@ struct bpf_sock { > __u32 src_ip4; > __u32 src_ip6[4]; > __u32 src_port; /* host byte order */ > - __u32 dst_port; /* network byte order */ > + __be16 dst_port; /* network byte order */ > + __u16 zero_padding; I was wondering can we do '__u16 :16' here ? Should we do the same for bpf_sk_lookup->remote_port as well for consistency? Thanks for the idea and the patches!