Commit 8e667a06 authored by Jordan Rife's avatar Jordan Rife Committed by Martin KaFai Lau

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: default avatarJordan Rife <jrife@google.com>
Link: https://lore.kernel.org/r/20240429214529.2644801-2-jrife@google.comSigned-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
parent 08e90da6
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#include <bpf/bpf_helpers.h> #include <bpf/bpf_helpers.h>
#include <bpf/bpf_endian.h> #include <bpf/bpf_endian.h>
#include "bind_prog.h"
#define SERV4_IP 0xc0a801feU /* 192.168.1.254 */ #define SERV4_IP 0xc0a801feU /* 192.168.1.254 */
#define SERV4_PORT 4040 #define SERV4_PORT 4040
#define SERV4_REWRITE_IP 0x7f000001U /* 127.0.0.1 */ #define SERV4_REWRITE_IP 0x7f000001U /* 127.0.0.1 */
...@@ -118,23 +120,23 @@ int bind_v4_prog(struct bpf_sock_addr *ctx) ...@@ -118,23 +120,23 @@ int bind_v4_prog(struct bpf_sock_addr *ctx)
// u8 narrow loads: // u8 narrow loads:
user_ip4 = 0; user_ip4 = 0;
user_ip4 |= ((volatile __u8 *)&ctx->user_ip4)[0] << 0; user_ip4 |= load_byte(ctx->user_ip4, 0, sizeof(user_ip4));
user_ip4 |= ((volatile __u8 *)&ctx->user_ip4)[1] << 8; user_ip4 |= load_byte(ctx->user_ip4, 1, sizeof(user_ip4));
user_ip4 |= ((volatile __u8 *)&ctx->user_ip4)[2] << 16; user_ip4 |= load_byte(ctx->user_ip4, 2, sizeof(user_ip4));
user_ip4 |= ((volatile __u8 *)&ctx->user_ip4)[3] << 24; user_ip4 |= load_byte(ctx->user_ip4, 3, sizeof(user_ip4));
if (ctx->user_ip4 != user_ip4) if (ctx->user_ip4 != user_ip4)
return 0; return 0;
user_port = 0; user_port = 0;
user_port |= ((volatile __u8 *)&ctx->user_port)[0] << 0; user_port |= load_byte(ctx->user_port, 0, sizeof(user_port));
user_port |= ((volatile __u8 *)&ctx->user_port)[1] << 8; user_port |= load_byte(ctx->user_port, 1, sizeof(user_port));
if (ctx->user_port != user_port) if (ctx->user_port != user_port)
return 0; return 0;
// u16 narrow loads: // u16 narrow loads:
user_ip4 = 0; user_ip4 = 0;
user_ip4 |= ((volatile __u16 *)&ctx->user_ip4)[0] << 0; user_ip4 |= load_word(ctx->user_ip4, 0, sizeof(user_ip4));
user_ip4 |= ((volatile __u16 *)&ctx->user_ip4)[1] << 16; user_ip4 |= load_word(ctx->user_ip4, 1, sizeof(user_ip4));
if (ctx->user_ip4 != user_ip4) if (ctx->user_ip4 != user_ip4)
return 0; return 0;
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#include <bpf/bpf_helpers.h> #include <bpf/bpf_helpers.h>
#include <bpf/bpf_endian.h> #include <bpf/bpf_endian.h>
#include "bind_prog.h"
#define SERV6_IP_0 0xfaceb00c /* face:b00c:1234:5678::abcd */ #define SERV6_IP_0 0xfaceb00c /* face:b00c:1234:5678::abcd */
#define SERV6_IP_1 0x12345678 #define SERV6_IP_1 0x12345678
#define SERV6_IP_2 0x00000000 #define SERV6_IP_2 0x00000000
...@@ -129,25 +131,25 @@ int bind_v6_prog(struct bpf_sock_addr *ctx) ...@@ -129,25 +131,25 @@ int bind_v6_prog(struct bpf_sock_addr *ctx)
// u8 narrow loads: // u8 narrow loads:
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
user_ip6 = 0; user_ip6 = 0;
user_ip6 |= ((volatile __u8 *)&ctx->user_ip6[i])[0] << 0; user_ip6 |= load_byte(ctx->user_ip6[i], 0, sizeof(user_ip6));
user_ip6 |= ((volatile __u8 *)&ctx->user_ip6[i])[1] << 8; user_ip6 |= load_byte(ctx->user_ip6[i], 1, sizeof(user_ip6));
user_ip6 |= ((volatile __u8 *)&ctx->user_ip6[i])[2] << 16; user_ip6 |= load_byte(ctx->user_ip6[i], 2, sizeof(user_ip6));
user_ip6 |= ((volatile __u8 *)&ctx->user_ip6[i])[3] << 24; user_ip6 |= load_byte(ctx->user_ip6[i], 3, sizeof(user_ip6));
if (ctx->user_ip6[i] != user_ip6) if (ctx->user_ip6[i] != user_ip6)
return 0; return 0;
} }
user_port = 0; user_port = 0;
user_port |= ((volatile __u8 *)&ctx->user_port)[0] << 0; user_port |= load_byte(ctx->user_port, 0, sizeof(user_port));
user_port |= ((volatile __u8 *)&ctx->user_port)[1] << 8; user_port |= load_byte(ctx->user_port, 1, sizeof(user_port));
if (ctx->user_port != user_port) if (ctx->user_port != user_port)
return 0; return 0;
// u16 narrow loads: // u16 narrow loads:
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
user_ip6 = 0; user_ip6 = 0;
user_ip6 |= ((volatile __u16 *)&ctx->user_ip6[i])[0] << 0; user_ip6 |= load_word(ctx->user_ip6[i], 0, sizeof(user_ip6));
user_ip6 |= ((volatile __u16 *)&ctx->user_ip6[i])[1] << 16; user_ip6 |= load_word(ctx->user_ip6[i], 1, sizeof(user_ip6));
if (ctx->user_ip6[i] != user_ip6) if (ctx->user_ip6[i] != user_ip6)
return 0; return 0;
} }
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __BIND_PROG_H__
#define __BIND_PROG_H__
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define load_byte(src, b, s) \
(((volatile __u8 *)&(src))[b] << 8 * b)
#define load_word(src, w, s) \
(((volatile __u16 *)&(src))[w] << 16 * w)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define load_byte(src, b, s) \
(((volatile __u8 *)&(src))[(b) + (sizeof(src) - (s))] << 8 * ((s) - (b) - 1))
#define load_word(src, w, s) \
(((volatile __u16 *)&(src))[w] << 16 * (((s) / 2) - (w) - 1))
#else
# error "Fix your compiler's __BYTE_ORDER__?!"
#endif
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment