On Thu, 2020-09-10 at 09:55 -0700, Andrii Nakryiko wrote: > On Wed, Sep 9, 2020 at 6:59 PM Ilya Leoshkevich <iii@xxxxxxxxxxxxx> > wrote: > > This test makes a lot of narrow load checks while assuming little > > endian architecture, and therefore fails on s390. > > > > Fix by introducing LSB and LSW macros and using them to perform > > narrow > > loads. > > > > Fixes: 0ab5539f8584 ("selftests/bpf: Tests for BPF_SK_LOOKUP attach > > point") > > Signed-off-by: Ilya Leoshkevich <iii@xxxxxxxxxxxxx> > > --- > > Jakub, > > Can you please help review this to make sure no error accidentally > slipped in? Gentle ping. > > > .../selftests/bpf/progs/test_sk_lookup.c | 264 ++++++++++-- > > ------ > > 1 file changed, 149 insertions(+), 115 deletions(-) > > > > diff --git a/tools/testing/selftests/bpf/progs/test_sk_lookup.c > > b/tools/testing/selftests/bpf/progs/test_sk_lookup.c > > index bbf8296f4d66..94e6d370967b 100644 > > --- a/tools/testing/selftests/bpf/progs/test_sk_lookup.c > > +++ b/tools/testing/selftests/bpf/progs/test_sk_lookup.c > > @@ -19,6 +19,17 @@ > > #define IP6(aaaa, bbbb, cccc, dddd) \ > > { bpf_htonl(aaaa), bpf_htonl(bbbb), bpf_htonl(cccc), > > bpf_htonl(dddd) } > > > > +/* Macros for least-significant byte and word accesses. */ > > +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ > > +#define LSE_INDEX(index, size) (index) > > +#else > > +#define LSE_INDEX(index, size) ((size) - (index) - 1) > > +#endif > > +#define LSB(value, index) \ > > + (((__u8 *)&(value))[LSE_INDEX((index), sizeof(value))]) > > +#define LSW(value, index) \ > > + (((__u16 *)&(value))[LSE_INDEX((index), sizeof(value) / > > 2)]) > > + > > #define MAX_SOCKS 32 > > > > struct { > > @@ -369,171 +380,194 @@ int ctx_narrow_access(struct bpf_sk_lookup > > *ctx) > > { > > struct bpf_sock *sk; > > int err, family; > > - __u16 *half; > > - __u8 *byte; > > bool v4; > > > > v4 = (ctx->family == AF_INET); > > > > /* Narrow loads from family field */ > > - byte = (__u8 *)&ctx->family; > > - half = (__u16 *)&ctx->family; > > - if (byte[0] != (v4 ? AF_INET : AF_INET6) || > > - byte[1] != 0 || byte[2] != 0 || byte[3] != 0) > > + if (LSB(ctx->family, 0) != (v4 ? AF_INET : AF_INET6) || > > + LSB(ctx->family, 1) != 0 || LSB(ctx->family, 2) != 0 || > > + LSB(ctx->family, 3) != 0) > > return SK_DROP; > > - if (half[0] != (v4 ? AF_INET : AF_INET6)) > > + if (LSW(ctx->family, 0) != (v4 ? AF_INET : AF_INET6)) > > return SK_DROP; > > > > - byte = (__u8 *)&ctx->protocol; > > - if (byte[0] != IPPROTO_TCP || > > - byte[1] != 0 || byte[2] != 0 || byte[3] != 0) > > + /* Narrow loads from protocol field */ > > + if (LSB(ctx->protocol, 0) != IPPROTO_TCP || > > + LSB(ctx->protocol, 1) != 0 || LSB(ctx->protocol, 2) != > > 0 || > > + LSB(ctx->protocol, 3) != 0) > > return SK_DROP; > > - half = (__u16 *)&ctx->protocol; > > - if (half[0] != IPPROTO_TCP) > > + if (LSW(ctx->protocol, 0) != IPPROTO_TCP) > > return SK_DROP; > > > > /* Narrow loads from remote_port field. Expect non-0 value. > > */ > > - byte = (__u8 *)&ctx->remote_port; > > - if (byte[0] == 0 && byte[1] == 0 && byte[2] == 0 && byte[3] > > == 0) > > + if (LSB(ctx->remote_port, 0) == 0 && LSB(ctx->remote_port, > > 1) == 0 && > > + LSB(ctx->remote_port, 2) == 0 && LSB(ctx->remote_port, > > 3) == 0) > > return SK_DROP; > > - half = (__u16 *)&ctx->remote_port; > > - if (half[0] == 0) > > + if (LSW(ctx->remote_port, 0) == 0) > > return SK_DROP; > > > > /* Narrow loads from local_port field. Expect DST_PORT. */ > > - byte = (__u8 *)&ctx->local_port; > > - if (byte[0] != ((DST_PORT >> 0) & 0xff) || > > - byte[1] != ((DST_PORT >> 8) & 0xff) || > > - byte[2] != 0 || byte[3] != 0) > > + if (LSB(ctx->local_port, 0) != ((DST_PORT >> 0) & 0xff) || > > + LSB(ctx->local_port, 1) != ((DST_PORT >> 8) & 0xff) || > > + LSB(ctx->local_port, 2) != 0 || LSB(ctx->local_port, 3) > > != 0) > > return SK_DROP; > > - half = (__u16 *)&ctx->local_port; > > - if (half[0] != DST_PORT) > > + if (LSW(ctx->local_port, 0) != DST_PORT) > > return SK_DROP; > > > > /* Narrow loads from IPv4 fields */ > > if (v4) { > > /* Expect non-0.0.0.0 in remote_ip4 */ > > - byte = (__u8 *)&ctx->remote_ip4; > > - if (byte[0] == 0 && byte[1] == 0 && > > - byte[2] == 0 && byte[3] == 0) > > + if (LSB(ctx->remote_ip4, 0) == 0 && > > + LSB(ctx->remote_ip4, 1) == 0 && > > + LSB(ctx->remote_ip4, 2) == 0 && > > + LSB(ctx->remote_ip4, 3) == 0) > > return SK_DROP; > > - half = (__u16 *)&ctx->remote_ip4; > > - if (half[0] == 0 && half[1] == 0) > > + if (LSW(ctx->remote_ip4, 0) == 0 && > > + LSW(ctx->remote_ip4, 1) == 0) > > return SK_DROP; > > > > /* Expect DST_IP4 in local_ip4 */ > > - byte = (__u8 *)&ctx->local_ip4; > > - if (byte[0] != ((DST_IP4 >> 0) & 0xff) || > > - byte[1] != ((DST_IP4 >> 8) & 0xff) || > > - byte[2] != ((DST_IP4 >> 16) & 0xff) || > > - byte[3] != ((DST_IP4 >> 24) & 0xff)) > > + if (LSB(ctx->local_ip4, 0) != ((DST_IP4 >> 0) & > > 0xff) || > > + LSB(ctx->local_ip4, 1) != ((DST_IP4 >> 8) & > > 0xff) || > > + LSB(ctx->local_ip4, 2) != ((DST_IP4 >> 16) & > > 0xff) || > > + LSB(ctx->local_ip4, 3) != ((DST_IP4 >> 24) & > > 0xff)) > > return SK_DROP; > > - half = (__u16 *)&ctx->local_ip4; > > - if (half[0] != ((DST_IP4 >> 0) & 0xffff) || > > - half[1] != ((DST_IP4 >> 16) & 0xffff)) > > + if (LSW(ctx->local_ip4, 0) != ((DST_IP4 >> 0) & > > 0xffff) || > > + LSW(ctx->local_ip4, 1) != ((DST_IP4 >> 16) & > > 0xffff)) > > return SK_DROP; > > } else { > > /* Expect 0.0.0.0 IPs when family != AF_INET */ > > - byte = (__u8 *)&ctx->remote_ip4; > > - if (byte[0] != 0 || byte[1] != 0 && > > - byte[2] != 0 || byte[3] != 0) > > + if (LSB(ctx->remote_ip4, 0) != 0 || > > + LSB(ctx->remote_ip4, 1) != 0 || > > + LSB(ctx->remote_ip4, 2) != 0 || > > + LSB(ctx->remote_ip4, 3) != 0) > > return SK_DROP; > > - half = (__u16 *)&ctx->remote_ip4; > > - if (half[0] != 0 || half[1] != 0) > > + if (LSW(ctx->remote_ip4, 0) != 0 || > > + LSW(ctx->remote_ip4, 1) != 0) > > return SK_DROP; > > > > - byte = (__u8 *)&ctx->local_ip4; > > - if (byte[0] != 0 || byte[1] != 0 && > > - byte[2] != 0 || byte[3] != 0) > > + if (LSB(ctx->local_ip4, 0) != 0 || > > + LSB(ctx->local_ip4, 1) != 0 || > > + LSB(ctx->local_ip4, 2) != 0 || LSB(ctx- > > >local_ip4, 3) != 0) > > return SK_DROP; > > - half = (__u16 *)&ctx->local_ip4; > > - if (half[0] != 0 || half[1] != 0) > > + if (LSW(ctx->local_ip4, 0) != 0 || LSW(ctx- > > >local_ip4, 1) != 0) > > return SK_DROP; > > } > > > > /* Narrow loads from IPv6 fields */ > > if (!v4) { > > - /* Expenct non-:: IP in remote_ip6 */ > > - byte = (__u8 *)&ctx->remote_ip6; > > - if (byte[0] == 0 && byte[1] == 0 && > > - byte[2] == 0 && byte[3] == 0 && > > - byte[4] == 0 && byte[5] == 0 && > > - byte[6] == 0 && byte[7] == 0 && > > - byte[8] == 0 && byte[9] == 0 && > > - byte[10] == 0 && byte[11] == 0 && > > - byte[12] == 0 && byte[13] == 0 && > > - byte[14] == 0 && byte[15] == 0) > > + /* Expect non-:: IP in remote_ip6 */ > > + if (LSB(ctx->remote_ip6[0], 0) == 0 && > > + LSB(ctx->remote_ip6[0], 1) == 0 && > > + LSB(ctx->remote_ip6[0], 2) == 0 && > > + LSB(ctx->remote_ip6[0], 3) == 0 && > > + LSB(ctx->remote_ip6[1], 0) == 0 && > > + LSB(ctx->remote_ip6[1], 1) == 0 && > > + LSB(ctx->remote_ip6[1], 2) == 0 && > > + LSB(ctx->remote_ip6[1], 3) == 0 && > > + LSB(ctx->remote_ip6[2], 0) == 0 && > > + LSB(ctx->remote_ip6[2], 1) == 0 && > > + LSB(ctx->remote_ip6[2], 2) == 0 && > > + LSB(ctx->remote_ip6[2], 3) == 0 && > > + LSB(ctx->remote_ip6[3], 0) == 0 && > > + LSB(ctx->remote_ip6[3], 1) == 0 && > > + LSB(ctx->remote_ip6[3], 2) == 0 && > > + LSB(ctx->remote_ip6[3], 3) == 0) > > return SK_DROP; > > - half = (__u16 *)&ctx->remote_ip6; > > - if (half[0] == 0 && half[1] == 0 && > > - half[2] == 0 && half[3] == 0 && > > - half[4] == 0 && half[5] == 0 && > > - half[6] == 0 && half[7] == 0) > > + if (LSW(ctx->remote_ip6[0], 0) == 0 && > > + LSW(ctx->remote_ip6[0], 1) == 0 && > > + LSW(ctx->remote_ip6[1], 0) == 0 && > > + LSW(ctx->remote_ip6[1], 1) == 0 && > > + LSW(ctx->remote_ip6[2], 0) == 0 && > > + LSW(ctx->remote_ip6[2], 1) == 0 && > > + LSW(ctx->remote_ip6[3], 0) == 0 && > > + LSW(ctx->remote_ip6[3], 1) == 0) > > return SK_DROP; > > - > > /* Expect DST_IP6 in local_ip6 */ > > - byte = (__u8 *)&ctx->local_ip6; > > - if (byte[0] != ((DST_IP6[0] >> 0) & 0xff) || > > - byte[1] != ((DST_IP6[0] >> 8) & 0xff) || > > - byte[2] != ((DST_IP6[0] >> 16) & 0xff) || > > - byte[3] != ((DST_IP6[0] >> 24) & 0xff) || > > - byte[4] != ((DST_IP6[1] >> 0) & 0xff) || > > - byte[5] != ((DST_IP6[1] >> 8) & 0xff) || > > - byte[6] != ((DST_IP6[1] >> 16) & 0xff) || > > - byte[7] != ((DST_IP6[1] >> 24) & 0xff) || > > - byte[8] != ((DST_IP6[2] >> 0) & 0xff) || > > - byte[9] != ((DST_IP6[2] >> 8) & 0xff) || > > - byte[10] != ((DST_IP6[2] >> 16) & 0xff) || > > - byte[11] != ((DST_IP6[2] >> 24) & 0xff) || > > - byte[12] != ((DST_IP6[3] >> 0) & 0xff) || > > - byte[13] != ((DST_IP6[3] >> 8) & 0xff) || > > - byte[14] != ((DST_IP6[3] >> 16) & 0xff) || > > - byte[15] != ((DST_IP6[3] >> 24) & 0xff)) > > + if (LSB(ctx->local_ip6[0], 0) != ((DST_IP6[0] >> 0) > > & 0xff) || > > + LSB(ctx->local_ip6[0], 1) != ((DST_IP6[0] >> 8) > > & 0xff) || > > + LSB(ctx->local_ip6[0], 2) != ((DST_IP6[0] >> > > 16) & 0xff) || > > + LSB(ctx->local_ip6[0], 3) != ((DST_IP6[0] >> > > 24) & 0xff) || > > + LSB(ctx->local_ip6[1], 0) != ((DST_IP6[1] >> 0) > > & 0xff) || > > + LSB(ctx->local_ip6[1], 1) != ((DST_IP6[1] >> 8) > > & 0xff) || > > + LSB(ctx->local_ip6[1], 2) != ((DST_IP6[1] >> > > 16) & 0xff) || > > + LSB(ctx->local_ip6[1], 3) != ((DST_IP6[1] >> > > 24) & 0xff) || > > + LSB(ctx->local_ip6[2], 0) != ((DST_IP6[2] >> 0) > > & 0xff) || > > + LSB(ctx->local_ip6[2], 1) != ((DST_IP6[2] >> 8) > > & 0xff) || > > + LSB(ctx->local_ip6[2], 2) != ((DST_IP6[2] >> > > 16) & 0xff) || > > + LSB(ctx->local_ip6[2], 3) != ((DST_IP6[2] >> > > 24) & 0xff) || > > + LSB(ctx->local_ip6[3], 0) != ((DST_IP6[3] >> 0) > > & 0xff) || > > + LSB(ctx->local_ip6[3], 1) != ((DST_IP6[3] >> 8) > > & 0xff) || > > + LSB(ctx->local_ip6[3], 2) != ((DST_IP6[3] >> > > 16) & 0xff) || > > + LSB(ctx->local_ip6[3], 3) != ((DST_IP6[3] >> > > 24) & 0xff)) > > return SK_DROP; > > - half = (__u16 *)&ctx->local_ip6; > > - if (half[0] != ((DST_IP6[0] >> 0) & 0xffff) || > > - half[1] != ((DST_IP6[0] >> 16) & 0xffff) || > > - half[2] != ((DST_IP6[1] >> 0) & 0xffff) || > > - half[3] != ((DST_IP6[1] >> 16) & 0xffff) || > > - half[4] != ((DST_IP6[2] >> 0) & 0xffff) || > > - half[5] != ((DST_IP6[2] >> 16) & 0xffff) || > > - half[6] != ((DST_IP6[3] >> 0) & 0xffff) || > > - half[7] != ((DST_IP6[3] >> 16) & 0xffff)) > > + if (LSW(ctx->local_ip6[0], 0) != ((DST_IP6[0] >> 0) > > & 0xffff) || > > + LSW(ctx->local_ip6[0], 1) != > > + ((DST_IP6[0] >> 16) & 0xffff) || > > + LSW(ctx->local_ip6[1], 0) != ((DST_IP6[1] >> 0) > > & 0xffff) || > > + LSW(ctx->local_ip6[1], 1) != > > + ((DST_IP6[1] >> 16) & 0xffff) || > > + LSW(ctx->local_ip6[2], 0) != ((DST_IP6[2] >> 0) > > & 0xffff) || > > + LSW(ctx->local_ip6[2], 1) != > > + ((DST_IP6[2] >> 16) & 0xffff) || > > + LSW(ctx->local_ip6[3], 0) != ((DST_IP6[3] >> 0) > > & 0xffff) || > > + LSW(ctx->local_ip6[3], 1) != ((DST_IP6[3] >> > > 16) & 0xffff)) > > return SK_DROP; > > } else { > > /* Expect :: IPs when family != AF_INET6 */ > > - byte = (__u8 *)&ctx->remote_ip6; > > - if (byte[0] != 0 || byte[1] != 0 || > > - byte[2] != 0 || byte[3] != 0 || > > - byte[4] != 0 || byte[5] != 0 || > > - byte[6] != 0 || byte[7] != 0 || > > - byte[8] != 0 || byte[9] != 0 || > > - byte[10] != 0 || byte[11] != 0 || > > - byte[12] != 0 || byte[13] != 0 || > > - byte[14] != 0 || byte[15] != 0) > > + if (LSB(ctx->remote_ip6[0], 0) != 0 || > > + LSB(ctx->remote_ip6[0], 1) != 0 || > > + LSB(ctx->remote_ip6[0], 2) != 0 || > > + LSB(ctx->remote_ip6[0], 3) != 0 || > > + LSB(ctx->remote_ip6[1], 0) != 0 || > > + LSB(ctx->remote_ip6[1], 1) != 0 || > > + LSB(ctx->remote_ip6[1], 2) != 0 || > > + LSB(ctx->remote_ip6[1], 3) != 0 || > > + LSB(ctx->remote_ip6[2], 0) != 0 || > > + LSB(ctx->remote_ip6[2], 1) != 0 || > > + LSB(ctx->remote_ip6[2], 2) != 0 || > > + LSB(ctx->remote_ip6[2], 3) != 0 || > > + LSB(ctx->remote_ip6[3], 0) != 0 || > > + LSB(ctx->remote_ip6[3], 1) != 0 || > > + LSB(ctx->remote_ip6[3], 2) != 0 || > > + LSB(ctx->remote_ip6[3], 3) != 0) > > return SK_DROP; > > - half = (__u16 *)&ctx->remote_ip6; > > - if (half[0] != 0 || half[1] != 0 || > > - half[2] != 0 || half[3] != 0 || > > - half[4] != 0 || half[5] != 0 || > > - half[6] != 0 || half[7] != 0) > > + if (LSW(ctx->remote_ip6[0], 0) != 0 || > > + LSW(ctx->remote_ip6[0], 1) != 0 || > > + LSW(ctx->remote_ip6[1], 0) != 0 || > > + LSW(ctx->remote_ip6[1], 1) != 0 || > > + LSW(ctx->remote_ip6[2], 0) != 0 || > > + LSW(ctx->remote_ip6[2], 1) != 0 || > > + LSW(ctx->remote_ip6[3], 0) != 0 || > > + LSW(ctx->remote_ip6[3], 1) != 0) > > return SK_DROP; > > > > - byte = (__u8 *)&ctx->local_ip6; > > - if (byte[0] != 0 || byte[1] != 0 || > > - byte[2] != 0 || byte[3] != 0 || > > - byte[4] != 0 || byte[5] != 0 || > > - byte[6] != 0 || byte[7] != 0 || > > - byte[8] != 0 || byte[9] != 0 || > > - byte[10] != 0 || byte[11] != 0 || > > - byte[12] != 0 || byte[13] != 0 || > > - byte[14] != 0 || byte[15] != 0) > > + if (LSB(ctx->local_ip6[0], 0) != 0 || > > + LSB(ctx->local_ip6[0], 1) != 0 || > > + LSB(ctx->local_ip6[0], 2) != 0 || > > + LSB(ctx->local_ip6[0], 3) != 0 || > > + LSB(ctx->local_ip6[1], 0) != 0 || > > + LSB(ctx->local_ip6[1], 1) != 0 || > > + LSB(ctx->local_ip6[1], 2) != 0 || > > + LSB(ctx->local_ip6[1], 3) != 0 || > > + LSB(ctx->local_ip6[2], 0) != 0 || > > + LSB(ctx->local_ip6[2], 1) != 0 || > > + LSB(ctx->local_ip6[2], 2) != 0 || > > + LSB(ctx->local_ip6[2], 3) != 0 || > > + LSB(ctx->local_ip6[3], 0) != 0 || > > + LSB(ctx->local_ip6[3], 1) != 0 || > > + LSB(ctx->local_ip6[3], 2) != 0 || > > + LSB(ctx->local_ip6[3], 3) != 0) > > return SK_DROP; > > - half = (__u16 *)&ctx->local_ip6; > > - if (half[0] != 0 || half[1] != 0 || > > - half[2] != 0 || half[3] != 0 || > > - half[4] != 0 || half[5] != 0 || > > - half[6] != 0 || half[7] != 0) > > + if (LSW(ctx->remote_ip6[0], 0) != 0 || > > + LSW(ctx->remote_ip6[0], 1) != 0 || > > + LSW(ctx->remote_ip6[1], 0) != 0 || > > + LSW(ctx->remote_ip6[1], 1) != 0 || > > + LSW(ctx->remote_ip6[2], 0) != 0 || > > + LSW(ctx->remote_ip6[2], 1) != 0 || > > + LSW(ctx->remote_ip6[3], 0) != 0 || > > + LSW(ctx->remote_ip6[3], 1) != 0) > > return SK_DROP; > > } > > > > -- > > 2.25.4 > >