From cba55832f6b3746d96fc28a948214f41e182b6d0 Mon Sep 17 00:00:00 2001 From: Dylan Reimerink Date: Sat, 23 Nov 2024 16:34:24 +0100 Subject: [PATCH] libbpf/ebpf: Add endian conversion functions This commit adds pages for endian conversion functions to the libbpf ebpf library. Signed-off-by: Dylan Reimerink --- .aspell.en.pws | 1 + docs/ebpf-library/libbpf/ebpf/SUMMARY.md | 6 ++ .../libbpf/ebpf/bpf_be64_to_cpu.md | 50 ++++++++++++++ .../libbpf/ebpf/bpf_cpu_to_be64.md | 50 ++++++++++++++ docs/ebpf-library/libbpf/ebpf/bpf_htonl.md | 69 +++++++++++++++++++ docs/ebpf-library/libbpf/ebpf/bpf_htons.md | 67 ++++++++++++++++++ docs/ebpf-library/libbpf/ebpf/bpf_ntohl.md | 69 +++++++++++++++++++ docs/ebpf-library/libbpf/ebpf/bpf_ntohs.md | 67 ++++++++++++++++++ docs/ebpf-library/libbpf/ebpf/index.md | 12 ++-- 9 files changed, 385 insertions(+), 6 deletions(-) create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_be64_to_cpu.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_cpu_to_be64.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_htonl.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_htons.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_ntohl.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_ntohs.md diff --git a/.aspell.en.pws b/.aspell.en.pws index b9cee7c..67e9228 100644 --- a/.aspell.en.pws +++ b/.aspell.en.pws @@ -149,6 +149,7 @@ incrementing misprediction sleepable endian +endianness callee verifier verifier's diff --git a/docs/ebpf-library/libbpf/ebpf/SUMMARY.md b/docs/ebpf-library/libbpf/ebpf/SUMMARY.md index f2c4e89..c86dd6f 100644 --- a/docs/ebpf-library/libbpf/ebpf/SUMMARY.md +++ b/docs/ebpf-library/libbpf/ebpf/SUMMARY.md @@ -38,3 +38,9 @@ - [`bpf_for_each`](bpf_for_each.md) - [`bpf_for`](bpf_for.md) - [`bpf_repeat`](bpf_repeat.md) +- [`bpf_htons`](bpf_htons.md) +- [`bpf_ntohs`](bpf_ntohs.md) +- [`bpf_htonl`](bpf_htonl.md) +- [`bpf_ntohl`](bpf_ntohl.md) +- [`bpf_cpu_to_be64`](bpf_cpu_to_be64.md) +- [`bpf_be64_to_cpu`](bpf_be64_to_cpu.md) diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_be64_to_cpu.md b/docs/ebpf-library/libbpf/ebpf/bpf_be64_to_cpu.md new file mode 100644 index 0000000..e3de2a9 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_be64_to_cpu.md @@ -0,0 +1,50 @@ +--- +title: "Libbpf eBPF macro 'bpf_be64_to_cpu'" +description: "This page documents the 'bpf_be64_to_cpu' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_be64_to_cpu` + +[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) + +The `bpf_be64_to_cpu` macro is used to convert a 64-bit number from network byte order to host byte order. + +## Definition + +```c +#define ___bpf_mvb(x, b, n, m) ((__u##b)(x) << (b-(n+1)*8) >> (b-8) << (m*8)) + +#define ___bpf_swab64(x) ((__u64)( \ + ___bpf_mvb(x, 64, 0, 7) | \ + ___bpf_mvb(x, 64, 1, 6) | \ + ___bpf_mvb(x, 64, 2, 5) | \ + ___bpf_mvb(x, 64, 3, 4) | \ + ___bpf_mvb(x, 64, 4, 3) | \ + ___bpf_mvb(x, 64, 5, 2) | \ + ___bpf_mvb(x, 64, 6, 1) | \ + ___bpf_mvb(x, 64, 7, 0))) + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define __bpf_be64_to_cpu(x) __builtin_bswap64(x) +# define __bpf_constant_be64_to_cpu(x) ___bpf_swab64(x) +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define __bpf_be64_to_cpu(x) (x) +# define __bpf_constant_be64_to_cpu(x) (x) +#else +# error "Fix your compiler's __BYTE_ORDER__?!" +#endif + +#define bpf_be64_to_cpu(x) \ + (__builtin_constant_p(x) ? \ + __bpf_constant_be64_to_cpu(x) : __bpf_be64_to_cpu(x)) +``` + +## Usage + +Converts a 64-bit number (a `long long`) from host byte order to network byte order. + +The implementation checks the endianness of the host system and if the number is a compile time constant or not. If the endianness of the system we are compiling on is already in network order, the macro simply returns the number as is. Otherwise if conversion is needed, and the number is a compile time constant, the conversion is done at compile time. If the number is not a compile time constant, a compiler builtin is used to emit byte swap instructions. + +### Example + +!!! example "Docs could be improved" + This part of the docs is incomplete, contributions are very welcome diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_cpu_to_be64.md b/docs/ebpf-library/libbpf/ebpf/bpf_cpu_to_be64.md new file mode 100644 index 0000000..694b682 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_cpu_to_be64.md @@ -0,0 +1,50 @@ +--- +title: "Libbpf eBPF macro 'bpf_cpu_to_be64'" +description: "This page documents the 'bpf_cpu_to_be64' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_cpu_to_be64` + +[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) + +The `bpf_cpu_to_be64` macro is used to convert a 64-bit number from host byte order to network byte order. + +## Definition + +```c +#define ___bpf_mvb(x, b, n, m) ((__u##b)(x) << (b-(n+1)*8) >> (b-8) << (m*8)) + +#define ___bpf_swab64(x) ((__u64)( \ + ___bpf_mvb(x, 64, 0, 7) | \ + ___bpf_mvb(x, 64, 1, 6) | \ + ___bpf_mvb(x, 64, 2, 5) | \ + ___bpf_mvb(x, 64, 3, 4) | \ + ___bpf_mvb(x, 64, 4, 3) | \ + ___bpf_mvb(x, 64, 5, 2) | \ + ___bpf_mvb(x, 64, 6, 1) | \ + ___bpf_mvb(x, 64, 7, 0))) + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define __bpf_cpu_to_be64(x) __builtin_bswap64(x) +# define __bpf_constant_cpu_to_be64(x) ___bpf_swab64(x) +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define __bpf_cpu_to_be64(x) (x) +# define __bpf_constant_cpu_to_be64(x) (x) +#else +# error "Fix your compiler's __BYTE_ORDER__?!" +#endif + +#define bpf_cpu_to_be64(x) \ + (__builtin_constant_p(x) ? \ + __bpf_constant_cpu_to_be64(x) : __bpf_cpu_to_be64(x)) +``` + +## Usage + +Converts a 64-bit number (a `long long`) from host byte order to network byte order. + +The implementation checks the endianness of the host system and if the number is a compile time constant or not. If the endianness of the system we are compiling on is already in network order, the macro simply returns the number as is. Otherwise if conversion is needed, and the number is a compile time constant, the conversion is done at compile time. If the number is not a compile time constant, a compiler builtin is used to emit byte swap instructions. + +### Example + +!!! example "Docs could be improved" + This part of the docs is incomplete, contributions are very welcome diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_htonl.md b/docs/ebpf-library/libbpf/ebpf/bpf_htonl.md new file mode 100644 index 0000000..24f78dd --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_htonl.md @@ -0,0 +1,69 @@ +--- +title: "Libbpf eBPF macro 'bpf_htonl'" +description: "This page documents the 'bpf_htonl' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_htonl` + +[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) + +The `bpf_htonl` macro is used to convert a 32-bit number from host byte order to network byte order. + +## Definition + +```c +#define ___bpf_mvb(x, b, n, m) ((__u##b)(x) << (b-(n+1)*8) >> (b-8) << (m*8)) + +#define ___bpf_swab32(x) ((__u32)( \ + ___bpf_mvb(x, 32, 0, 3) | \ + ___bpf_mvb(x, 32, 1, 2) | \ + ___bpf_mvb(x, 32, 2, 1) | \ + ___bpf_mvb(x, 32, 3, 0))) + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define __bpf_htonl(x) __builtin_bswap32(x) +# define __bpf_constant_htonl(x) ___bpf_swab32(x) +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define __bpf_htonl(x) (x) +# define __bpf_constant_htonl(x) (x) +#else +# error "Fix your compiler's __BYTE_ORDER__?!" +#endif + +#define bpf_htonl(x) \ + (__builtin_constant_p(x) ? \ + __bpf_constant_htonl(x) : __bpf_htonl(x)) +``` + +## Usage + +This macro implements the analog of the `htonl` function from the standard C library. `htonl` being short for "host to network long", converts a 32-bit number (a `long`) from host byte order to network byte order. + +The implementation checks the endianness of the host system and if the number is a compile time constant or not. If the endianness of the system we are compiling on is already in network order, the macro simply returns the number as is. Otherwise if conversion is needed, and the number is a compile time constant, the conversion is done at compile time. If the number is not a compile time constant, a compiler builtin is used to emit byte swap instructions. + +### Example + +Only allow a socket to bind to `192.168.1.254` and port `4040`. + +```c hl_lines="16" +#define SERV4_IP 0xc0a801feU /* 192.168.1.254 */ +#define SERV4_PORT 4040 + +SEC("cgroup/bind4") +int bind_v4_prog(struct bpf_sock_addr *ctx) +{ + struct bpf_sock *sk; + + sk = ctx->sk; + if (!sk) + return 0; + + if (sk->family != AF_INET) + return 0; + + if (ctx->user_ip4 != bpf_htonl(SERV4_IP) || + ctx->user_port != bpf_htons(SERV4_PORT)) + return 0; + + return 1; +} +``` diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_htons.md b/docs/ebpf-library/libbpf/ebpf/bpf_htons.md new file mode 100644 index 0000000..19a6c6c --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_htons.md @@ -0,0 +1,67 @@ +--- +title: "Libbpf eBPF macro 'bpf_htons'" +description: "This page documents the 'bpf_htons' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_htons` + +[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) + +The `bpf_htons` macro is used to convert a 16-bit number from host byte order to network byte order. + +## Definition + +```c +#define ___bpf_mvb(x, b, n, m) ((__u##b)(x) << (b-(n+1)*8) >> (b-8) << (m*8)) + +#define ___bpf_swab16(x) ((__u16)( \ + ___bpf_mvb(x, 16, 0, 1) | \ + ___bpf_mvb(x, 16, 1, 0))) + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define __bpf_htons(x) __builtin_bswap16(x) +# define __bpf_constant_htons(x) ___bpf_swab16(x) +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define __bpf_htons(x) (x) +# define __bpf_constant_htons(x) (x) +#else +# error "Fix your compiler's __BYTE_ORDER__?!" +#endif + +#define bpf_htons(x) \ + (__builtin_constant_p(x) ? \ + __bpf_constant_htons(x) : __bpf_htons(x)) +``` + +## Usage + +This macro implements the analog of the `htons` function from the standard C library. `htons` being short for "host to network short", converts a 16-bit number (a `short`) from host byte order to network byte order. + +The implementation checks the endianness of the host system and if the number is a compile time constant or not. If the endianness of the system we are compiling on is already in network order, the macro simply returns the number as is. Otherwise if conversion is needed, and the number is a compile time constant, the conversion is done at compile time. If the number is not a compile time constant, a compiler builtin is used to emit byte swap instructions. + +### Example + +Only allow a socket to bind to `192.168.1.254` and port `4040`. + +```c hl_lines="17" +#define SERV4_IP 0xc0a801feU /* 192.168.1.254 */ +#define SERV4_PORT 4040 + +SEC("cgroup/bind4") +int bind_v4_prog(struct bpf_sock_addr *ctx) +{ + struct bpf_sock *sk; + + sk = ctx->sk; + if (!sk) + return 0; + + if (sk->family != AF_INET) + return 0; + + if (ctx->user_ip4 != bpf_htonl(SERV4_IP) || + ctx->user_port != bpf_htons(SERV4_PORT)) + return 0; + + return 1; +} +``` diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_ntohl.md b/docs/ebpf-library/libbpf/ebpf/bpf_ntohl.md new file mode 100644 index 0000000..e84bf54 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_ntohl.md @@ -0,0 +1,69 @@ +--- +title: "Libbpf eBPF macro 'bpf_ntohl'" +description: "This page documents the 'bpf_ntohl' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_ntohl` + +[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) + +The `bpf_ntohl` macro is used to convert a 32-bit number from network byte order to host byte order. + +## Definition + +```c +#define ___bpf_mvb(x, b, n, m) ((__u##b)(x) << (b-(n+1)*8) >> (b-8) << (m*8)) + +#define ___bpf_swab32(x) ((__u32)( \ + ___bpf_mvb(x, 32, 0, 3) | \ + ___bpf_mvb(x, 32, 1, 2) | \ + ___bpf_mvb(x, 32, 2, 1) | \ + ___bpf_mvb(x, 32, 3, 0))) + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define __bpf_ntohl(x) __builtin_bswap32(x) +# define __bpf_constant_ntohl(x) ___bpf_swab32(x) +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define __bpf_ntohl(x) (x) +# define __bpf_constant_ntohl(x) (x) +#else +# error "Fix your compiler's __BYTE_ORDER__?!" +#endif + +#define bpf_ntohl(x) \ + (__builtin_constant_p(x) ? \ + __bpf_constant_ntohl(x) : __bpf_ntohl(x)) +``` + +## Usage + +This macro implements the analog of the `ntonl` function from the standard C library. `ntonl` being short for "network to host long", converts a 32-bit number (a `long`) from network byte order to host byte order. + +The implementation checks the endianness of the host system and if the number is a compile time constant or not. If the endianness of the system we are compiling on is already in network order, the macro simply returns the number as is. Otherwise if conversion is needed, and the number is a compile time constant, the conversion is done at compile time. If the number is not a compile time constant, a compiler builtin is used to emit byte swap instructions. + +### Example + +Only allow a socket to bind to `192.168.1.254` and port `4040`. + +```c hl_lines="16" +#define SERV4_IP 0xc0a801feU /* 192.168.1.254 */ +#define SERV4_PORT 4040 + +SEC("cgroup/bind4") +int bind_v4_prog(struct bpf_sock_addr *ctx) +{ + struct bpf_sock *sk; + + sk = ctx->sk; + if (!sk) + return 0; + + if (sk->family != AF_INET) + return 0; + + if (bpf_ntohl(ctx->user_ip4) != SERV4_IP || + bpf_ntohs(ctx->user_port) != SERV4_PORT) + return 0; + + return 1; +} +``` diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_ntohs.md b/docs/ebpf-library/libbpf/ebpf/bpf_ntohs.md new file mode 100644 index 0000000..99f37be --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_ntohs.md @@ -0,0 +1,67 @@ +--- +title: "Libbpf eBPF macro 'bpf_ntohs'" +description: "This page documents the 'bpf_ntohs' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_ntohs` + +[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) + +The `bpf_ntohs` macro is used to convert a 16-bit number from network byte order to host byte order. + +## Definition + +```c +#define ___bpf_mvb(x, b, n, m) ((__u##b)(x) << (b-(n+1)*8) >> (b-8) << (m*8)) + +#define ___bpf_swab16(x) ((__u16)( \ + ___bpf_mvb(x, 16, 0, 1) | \ + ___bpf_mvb(x, 16, 1, 0))) + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define __bpf_ntohs(x) __builtin_bswap16(x) +# define __bpf_constant_ntohs(x) ___bpf_swab16(x) +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define __bpf_ntohs(x) (x) +# define __bpf_constant_ntohs(x) (x) +#else +# error "Fix your compiler's __BYTE_ORDER__?!" +#endif + +#define bpf_ntohs(x) \ + (__builtin_constant_p(x) ? \ + __bpf_constant_ntohs(x) : __bpf_ntohs(x)) +``` + +## Usage + +This macro implements the analog of the `ntons` function from the standard C library. `ntons` being short for "network to host short", converts a 16-bit number (a `short`) from network byte order to host byte order. + +The implementation checks the endianness of the host system and if the number is a compile time constant or not. If the endianness of the system we are compiling on is already in network order, the macro simply returns the number as is. Otherwise if conversion is needed, and the number is a compile time constant, the conversion is done at compile time. If the number is not a compile time constant, a compiler builtin is used to emit byte swap instructions. + +### Example + +Only allow a socket to bind to `192.168.1.254` and port `4040`. + +```c hl_lines="17" +#define SERV4_IP 0xc0a801feU /* 192.168.1.254 */ +#define SERV4_PORT 4040 + +SEC("cgroup/bind4") +int bind_v4_prog(struct bpf_sock_addr *ctx) +{ + struct bpf_sock *sk; + + sk = ctx->sk; + if (!sk) + return 0; + + if (sk->family != AF_INET) + return 0; + + if (bpf_ntohl(ctx->user_ip4) != SERV4_IP || + bpf_ntohs(ctx->user_port) != SERV4_PORT) + return 0; + + return 1; +} +``` diff --git a/docs/ebpf-library/libbpf/ebpf/index.md b/docs/ebpf-library/libbpf/ebpf/index.md index b56f934..bc37a19 100644 --- a/docs/ebpf-library/libbpf/ebpf/index.md +++ b/docs/ebpf-library/libbpf/ebpf/index.md @@ -72,12 +72,12 @@ The `bpf_endian.h` file contains macros for endianess conversion. It is useful w The file contains definitions for the following: -* `bpf_htons` -* `bpf_ntohs` -* `bpf_htonl` -* `bpf_ntohl` -* `bpf_cpu_to_be64` -* `bpf_be64_to_cpu` +* [`bpf_htons`](bpf_htons.md) +* [`bpf_ntohs`](bpf_ntohs.md) +* [`bpf_htonl`](bpf_htonl.md) +* [`bpf_ntohl`](bpf_ntohl.md) +* [`bpf_cpu_to_be64`](bpf_cpu_to_be64.md) +* [`bpf_be64_to_cpu`](bpf_be64_to_cpu.md) ## [`bpf_tracing.h`](https://github.com/libbpf/libbpf/blob/master/src/bpf_tracing.h)