Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Fix bind program for big endian systems

Without this fix, the bind4 and bind6 programs will reject bind attempts
on big endian systems. This patch ensures that CI tests pass for the
s390x architecture.

Signed-off-by: Jordan Rife <jrife@google.com>
Link: https://lore.kernel.org/r/20240429214529.2644801-2-jrife@google.com
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>

authored by

Jordan Rife and committed by
Martin KaFai Lau
8e667a06 08e90da6

+39 -16
+10 -8
tools/testing/selftests/bpf/progs/bind4_prog.c
··· 12 12 #include <bpf/bpf_helpers.h> 13 13 #include <bpf/bpf_endian.h> 14 14 15 + #include "bind_prog.h" 16 + 15 17 #define SERV4_IP 0xc0a801feU /* 192.168.1.254 */ 16 18 #define SERV4_PORT 4040 17 19 #define SERV4_REWRITE_IP 0x7f000001U /* 127.0.0.1 */ ··· 120 118 121 119 // u8 narrow loads: 122 120 user_ip4 = 0; 123 - user_ip4 |= ((volatile __u8 *)&ctx->user_ip4)[0] << 0; 124 - user_ip4 |= ((volatile __u8 *)&ctx->user_ip4)[1] << 8; 125 - user_ip4 |= ((volatile __u8 *)&ctx->user_ip4)[2] << 16; 126 - user_ip4 |= ((volatile __u8 *)&ctx->user_ip4)[3] << 24; 121 + user_ip4 |= load_byte(ctx->user_ip4, 0, sizeof(user_ip4)); 122 + user_ip4 |= load_byte(ctx->user_ip4, 1, sizeof(user_ip4)); 123 + user_ip4 |= load_byte(ctx->user_ip4, 2, sizeof(user_ip4)); 124 + user_ip4 |= load_byte(ctx->user_ip4, 3, sizeof(user_ip4)); 127 125 if (ctx->user_ip4 != user_ip4) 128 126 return 0; 129 127 130 128 user_port = 0; 131 - user_port |= ((volatile __u8 *)&ctx->user_port)[0] << 0; 132 - user_port |= ((volatile __u8 *)&ctx->user_port)[1] << 8; 129 + user_port |= load_byte(ctx->user_port, 0, sizeof(user_port)); 130 + user_port |= load_byte(ctx->user_port, 1, sizeof(user_port)); 133 131 if (ctx->user_port != user_port) 134 132 return 0; 135 133 136 134 // u16 narrow loads: 137 135 user_ip4 = 0; 138 - user_ip4 |= ((volatile __u16 *)&ctx->user_ip4)[0] << 0; 139 - user_ip4 |= ((volatile __u16 *)&ctx->user_ip4)[1] << 16; 136 + user_ip4 |= load_word(ctx->user_ip4, 0, sizeof(user_ip4)); 137 + user_ip4 |= load_word(ctx->user_ip4, 1, sizeof(user_ip4)); 140 138 if (ctx->user_ip4 != user_ip4) 141 139 return 0; 142 140
+10 -8
tools/testing/selftests/bpf/progs/bind6_prog.c
··· 12 12 #include <bpf/bpf_helpers.h> 13 13 #include <bpf/bpf_endian.h> 14 14 15 + #include "bind_prog.h" 16 + 15 17 #define SERV6_IP_0 0xfaceb00c /* face:b00c:1234:5678::abcd */ 16 18 #define SERV6_IP_1 0x12345678 17 19 #define SERV6_IP_2 0x00000000 ··· 131 129 // u8 narrow loads: 132 130 for (i = 0; i < 4; i++) { 133 131 user_ip6 = 0; 134 - user_ip6 |= ((volatile __u8 *)&ctx->user_ip6[i])[0] << 0; 135 - user_ip6 |= ((volatile __u8 *)&ctx->user_ip6[i])[1] << 8; 136 - user_ip6 |= ((volatile __u8 *)&ctx->user_ip6[i])[2] << 16; 137 - user_ip6 |= ((volatile __u8 *)&ctx->user_ip6[i])[3] << 24; 132 + user_ip6 |= load_byte(ctx->user_ip6[i], 0, sizeof(user_ip6)); 133 + user_ip6 |= load_byte(ctx->user_ip6[i], 1, sizeof(user_ip6)); 134 + user_ip6 |= load_byte(ctx->user_ip6[i], 2, sizeof(user_ip6)); 135 + user_ip6 |= load_byte(ctx->user_ip6[i], 3, sizeof(user_ip6)); 138 136 if (ctx->user_ip6[i] != user_ip6) 139 137 return 0; 140 138 } 141 139 142 140 user_port = 0; 143 - user_port |= ((volatile __u8 *)&ctx->user_port)[0] << 0; 144 - user_port |= ((volatile __u8 *)&ctx->user_port)[1] << 8; 141 + user_port |= load_byte(ctx->user_port, 0, sizeof(user_port)); 142 + user_port |= load_byte(ctx->user_port, 1, sizeof(user_port)); 145 143 if (ctx->user_port != user_port) 146 144 return 0; 147 145 148 146 // u16 narrow loads: 149 147 for (i = 0; i < 4; i++) { 150 148 user_ip6 = 0; 151 - user_ip6 |= ((volatile __u16 *)&ctx->user_ip6[i])[0] << 0; 152 - user_ip6 |= ((volatile __u16 *)&ctx->user_ip6[i])[1] << 16; 149 + user_ip6 |= load_word(ctx->user_ip6[i], 0, sizeof(user_ip6)); 150 + user_ip6 |= load_word(ctx->user_ip6[i], 1, sizeof(user_ip6)); 153 151 if (ctx->user_ip6[i] != user_ip6) 154 152 return 0; 155 153 }
+19
tools/testing/selftests/bpf/progs/bind_prog.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __BIND_PROG_H__ 3 + #define __BIND_PROG_H__ 4 + 5 + #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 6 + #define load_byte(src, b, s) \ 7 + (((volatile __u8 *)&(src))[b] << 8 * b) 8 + #define load_word(src, w, s) \ 9 + (((volatile __u16 *)&(src))[w] << 16 * w) 10 + #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 11 + #define load_byte(src, b, s) \ 12 + (((volatile __u8 *)&(src))[(b) + (sizeof(src) - (s))] << 8 * ((s) - (b) - 1)) 13 + #define load_word(src, w, s) \ 14 + (((volatile __u16 *)&(src))[w] << 16 * (((s) / 2) - (w) - 1)) 15 + #else 16 + # error "Fix your compiler's __BYTE_ORDER__?!" 17 + #endif 18 + 19 + #endif