Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
0002 #ifndef __BPF_ENDIAN__
0003 #define __BPF_ENDIAN__
0004 
0005 /*
0006  * Isolate byte #n and put it into byte #m, for __u##b type.
0007  * E.g., moving byte #6 (nnnnnnnn) into byte #1 (mmmmmmmm) for __u64:
0008  * 1) xxxxxxxx nnnnnnnn xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx mmmmmmmm xxxxxxxx
0009  * 2) nnnnnnnn xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx mmmmmmmm xxxxxxxx 00000000
0010  * 3) 00000000 00000000 00000000 00000000 00000000 00000000 00000000 nnnnnnnn
0011  * 4) 00000000 00000000 00000000 00000000 00000000 00000000 nnnnnnnn 00000000
0012  */
0013 #define ___bpf_mvb(x, b, n, m) ((__u##b)(x) << (b-(n+1)*8) >> (b-8) << (m*8))
0014 
0015 #define ___bpf_swab16(x) ((__u16)(          \
0016               ___bpf_mvb(x, 16, 0, 1) | \
0017               ___bpf_mvb(x, 16, 1, 0)))
0018 
0019 #define ___bpf_swab32(x) ((__u32)(          \
0020               ___bpf_mvb(x, 32, 0, 3) | \
0021               ___bpf_mvb(x, 32, 1, 2) | \
0022               ___bpf_mvb(x, 32, 2, 1) | \
0023               ___bpf_mvb(x, 32, 3, 0)))
0024 
0025 #define ___bpf_swab64(x) ((__u64)(          \
0026               ___bpf_mvb(x, 64, 0, 7) | \
0027               ___bpf_mvb(x, 64, 1, 6) | \
0028               ___bpf_mvb(x, 64, 2, 5) | \
0029               ___bpf_mvb(x, 64, 3, 4) | \
0030               ___bpf_mvb(x, 64, 4, 3) | \
0031               ___bpf_mvb(x, 64, 5, 2) | \
0032               ___bpf_mvb(x, 64, 6, 1) | \
0033               ___bpf_mvb(x, 64, 7, 0)))
0034 
0035 /* LLVM's BPF target selects the endianness of the CPU
0036  * it compiles on, or the user specifies (bpfel/bpfeb),
0037  * respectively. The used __BYTE_ORDER__ is defined by
0038  * the compiler, we cannot rely on __BYTE_ORDER from
0039  * libc headers, since it doesn't reflect the actual
0040  * requested byte order.
0041  *
0042  * Note, LLVM's BPF target has different __builtin_bswapX()
0043  * semantics. It does map to BPF_ALU | BPF_END | BPF_TO_BE
0044  * in bpfel and bpfeb case, which means below, that we map
0045  * to cpu_to_be16(). We could use it unconditionally in BPF
0046  * case, but better not rely on it, so that this header here
0047  * can be used from application and BPF program side, which
0048  * use different targets.
0049  */
0050 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
0051 # define __bpf_ntohs(x)         __builtin_bswap16(x)
0052 # define __bpf_htons(x)         __builtin_bswap16(x)
0053 # define __bpf_constant_ntohs(x)    ___bpf_swab16(x)
0054 # define __bpf_constant_htons(x)    ___bpf_swab16(x)
0055 # define __bpf_ntohl(x)         __builtin_bswap32(x)
0056 # define __bpf_htonl(x)         __builtin_bswap32(x)
0057 # define __bpf_constant_ntohl(x)    ___bpf_swab32(x)
0058 # define __bpf_constant_htonl(x)    ___bpf_swab32(x)
0059 # define __bpf_be64_to_cpu(x)       __builtin_bswap64(x)
0060 # define __bpf_cpu_to_be64(x)       __builtin_bswap64(x)
0061 # define __bpf_constant_be64_to_cpu(x)  ___bpf_swab64(x)
0062 # define __bpf_constant_cpu_to_be64(x)  ___bpf_swab64(x)
0063 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
0064 # define __bpf_ntohs(x)         (x)
0065 # define __bpf_htons(x)         (x)
0066 # define __bpf_constant_ntohs(x)    (x)
0067 # define __bpf_constant_htons(x)    (x)
0068 # define __bpf_ntohl(x)         (x)
0069 # define __bpf_htonl(x)         (x)
0070 # define __bpf_constant_ntohl(x)    (x)
0071 # define __bpf_constant_htonl(x)    (x)
0072 # define __bpf_be64_to_cpu(x)       (x)
0073 # define __bpf_cpu_to_be64(x)       (x)
0074 # define __bpf_constant_be64_to_cpu(x)  (x)
0075 # define __bpf_constant_cpu_to_be64(x)  (x)
0076 #else
0077 # error "Fix your compiler's __BYTE_ORDER__?!"
0078 #endif
0079 
0080 #define bpf_htons(x)                \
0081     (__builtin_constant_p(x) ?      \
0082      __bpf_constant_htons(x) : __bpf_htons(x))
0083 #define bpf_ntohs(x)                \
0084     (__builtin_constant_p(x) ?      \
0085      __bpf_constant_ntohs(x) : __bpf_ntohs(x))
0086 #define bpf_htonl(x)                \
0087     (__builtin_constant_p(x) ?      \
0088      __bpf_constant_htonl(x) : __bpf_htonl(x))
0089 #define bpf_ntohl(x)                \
0090     (__builtin_constant_p(x) ?      \
0091      __bpf_constant_ntohl(x) : __bpf_ntohl(x))
0092 #define bpf_cpu_to_be64(x)          \
0093     (__builtin_constant_p(x) ?      \
0094      __bpf_constant_cpu_to_be64(x) : __bpf_cpu_to_be64(x))
0095 #define bpf_be64_to_cpu(x)          \
0096     (__builtin_constant_p(x) ?      \
0097      __bpf_constant_be64_to_cpu(x) : __bpf_be64_to_cpu(x))
0098 
0099 #endif /* __BPF_ENDIAN__ */