Skip to content

Commit

Permalink
libbpf/ebpf: Add endian conversion functions
Browse files Browse the repository at this point in the history
This commit adds pages for endian conversion functions to the libbpf
ebpf library.

Signed-off-by: Dylan Reimerink <[email protected]>
  • Loading branch information
dylandreimerink committed Nov 23, 2024
1 parent 06bc979 commit dd77191
Show file tree
Hide file tree
Showing 9 changed files with 385 additions and 6 deletions.
1 change: 1 addition & 0 deletions .aspell.en.pws
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ incrementing
misprediction
sleepable
endian
endianness
callee
verifier
verifier's
Expand Down
6 changes: 6 additions & 0 deletions docs/ebpf-library/libbpf/ebpf/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
50 changes: 50 additions & 0 deletions docs/ebpf-library/libbpf/ebpf/bpf_be64_to_cpu.md
Original file line number Diff line number Diff line change
@@ -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
50 changes: 50 additions & 0 deletions docs/ebpf-library/libbpf/ebpf/bpf_cpu_to_be64.md
Original file line number Diff line number Diff line change
@@ -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
69 changes: 69 additions & 0 deletions docs/ebpf-library/libbpf/ebpf/bpf_htonl.md
Original file line number Diff line number Diff line change
@@ -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;
}
```
67 changes: 67 additions & 0 deletions docs/ebpf-library/libbpf/ebpf/bpf_htons.md
Original file line number Diff line number Diff line change
@@ -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;
}
```
69 changes: 69 additions & 0 deletions docs/ebpf-library/libbpf/ebpf/bpf_ntohl.md
Original file line number Diff line number Diff line change
@@ -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;
}
```
67 changes: 67 additions & 0 deletions docs/ebpf-library/libbpf/ebpf/bpf_ntohs.md
Original file line number Diff line number Diff line change
@@ -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;
}
```
Loading

0 comments on commit dd77191

Please sign in to comment.