Helpers

Macros and utility functions shared across bpfilter: the cleanup-attribute machinery, ownership-transfer helpers (TAKE_PTR, TAKE_FD), and common memory and string helpers.

See Memory and resource management for the philosophy and the rules these helpers enforce.

Defines

_BF_APPLY0(t, s, dummy)
_BF_APPLY1(t, s, a)
_BF_APPLY2(t, s, a, ...)
_BF_APPLY3(t, s, a, ...)
_BF_APPLY4(t, s, a, ...)
_BF_APPLY5(t, s, a, ...)
_BF_APPLY6(t, s, a, ...)
_BF_APPLY7(t, s, a, ...)
_BF_APPLY8(t, s, a, ...)
_BF_APPLY9(t, s, a, ...)
_BF_APPLY10(t, s, a, ...)
_BF_APPLY11(t, s, a, ...)
_BF_APPLY12(t, s, a, ...)
_BF_APPLY13(t, s, a, ...)
_BF_APPLY14(t, s, a, ...)
_BF_APPLY15(t, s, a, ...)
_BF_APPLY16(t, s, a, ...)
__BF_NUM_ARGS1(dummy, x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...)
_BF_NUM_ARGS(...)
___BF_APPLY_ALL(t, s, n, ...)
__BF_APPLY_ALL(t, s, n, ...)
_BF_APPLY_ALL(t, s, ...)
BF_BASE_10
BF_BASE_16
_BF_ALIGNED(addr, mask)
BF_ALIGNED_64(addr)
BF_ALIGNED_32(addr)
BF_ALIGNED_16(addr)
BF_FLAGS(...)

Generate a bitflag from multiple values.

Enumeration are used extensively to define related values. Thanks to enumeration’s continuous values, they are used as array indexes to convert them into strings.

However, they can sometimes be combined, leading to very wordy code, e.g. 1 << ENUM_VAL_1 | 1 << ENUM_VAL_5.

BF_FLAGS can be used to replace the wordy code with a simpler macro call, e.g. BF_FLAGS(ENUL_VAL_1, ENUM_VAL_5). It will automatically create an integer with the enumeration values as a set bit index in the bitflag.

Returns:

Bitflag for variadic values.

BF_FLAG(n)

Shift 1 by n to create a flag.

See also

BF_FLAGS

Returns:

1ULL << n to be used as a flag.

BF_FLAGS_MASK(max_value)

Generate a bitmask covering all valid flags below max_value.

Returns:

Mask with bits 0 through max_value-1 set.

bf_packed
bf_unused
BF_STR(s)
_BF_STR(s)
static_assert_enum_mapping(array, n_values)

Generate a build error if an enumeration to string mapping array contains fewer entries than members in the enumeration.

Parameters:
  • array – Array containing the mapping between the enumeration values and ther string representation.

  • n_values – Number of values in the enumeration, usually the _BF_$NAME_MAX enumeration value.

TAKE_GENERIC(var, type, nullvalue)

Set ptr to NULL and return its previous value.

Inspired from systemd’s TAKE_PTR() macro, which is itself inspired from Rust’s Option::take() method: https://doc.rust-lang.org/std/option/enum.Option.html#method.take

Parameters:
  • var – Variable to return the value of.

  • type – Type of var.

  • nullvalue – Value to set var to.

Returns:

Value of var before it was set to nullvalue.

TAKE_PTR_TYPE(ptr, type)
TAKE_PTR(ptr)
TAKE_STRUCT_TYPE(s, type)
TAKE_STRUCT(s)
TAKE_FD(fd)
ARRAY_SIZE(x)

Get the number of element in an array.

Parameters:
  • x – The array.

Returns:

size_t The number of elements in the array.

_cleanup_close_
bf_strerror(v)

Return a string describing the given error code.

This function must be used over strerror(), which is marked at mt-unsafe.

Parameters:
  • v – Error code, can be positive or negative.

bf_swap(a, b)

Swap two values.

Parameters:
  • a – First value to swap.

  • b – Second value to swap.

bf_min(a, b)
bf_max(a, b)
_cleanup_free_
BF_FREEP(p)

Free a pointer and set it to NULL, type-safe.

Manual counterpart of _cleanup_free_ and bf_freep. Calls free(*p) then assigns NULL to *p. *p may be NULL, in which case the call is a no-op.

Implemented as a macro so it accepts any T ** argument without the (void *) cast that bf_freep(void *) would otherwise require at the call site. Use this for direct manual frees; use bf_freep when a function pointer is needed.

Parameters:
  • p – Address of the pointer to free.

Pre:

p is not NULL.

Functions

const char *strerrordesc_np(int errnum)
char *bf_ltrim(char *str)

Strip whitespace from the beginning of a string.

Parameters:
  • str – String to trim. Can’t be NULL.

Returns:

Trimmed version of str, as a pointer to a character of str.

char *bf_rtrim(char *str)

Strip whitespace from the end of a string.

str will be modified to insert \0 after the last non-whitespace character.

Parameters:
  • str – String to trim. Can’t be NULL.

Returns:

Trimmed version of str, as a pointer to a character of str.

char *bf_trim(char *str)

Strip whitespace from the beginning and the end of a string.

str will be modified to insert \0 after the last non-whitespace character.

Parameters:
  • str – String to trim. Can’t be NULL.

Returns:

Trimmed version of str, as a pointer to a character of str.

static inline void bf_freep(void *ptr)

Free a pointer and set it to NULL.

Frees *ptr with free() and sets *ptr to NULL. If *ptr is already NULL, the call is a no-op (per free()).

This is the function form of the free-and-null helper. It is used:

  • As the cleanup callback bound to the _cleanup_free_ attribute.

  • As a function pointer where a void (*)(void *) callback is expected (e.g. bf_list_ops_default(bf_freep, ...)).

For direct manual frees in source code, prefer the BF_FREEP() macro: it accepts any T ** argument without the explicit (void *) cast that Clang would otherwise require for the multilevel pointer conversion.

Parameters:
  • ptr – Address of the pointer to free, typed as void * so the cleanup-attribute machinery and other callback consumers can pass any T ** to it.

Pre:

ptr is not NULL.

void closep(int *fd)

Close a file descriptor and set it to -1.

bpfilter uses -1 as neutral value for file descriptor, meaning it doesn’t represent an open file yet. Once closed, a file descriptor should be reset to -1.

closep is used to close a file descriptor. File descriptors with negative values are ignored (-1 is used for “unset”, but will also ignore file descriptors containing negative errno values). Once closed, *fd is set to -1.

If the call to close fails, a warning is printed, and the file descriptor is assumed to be already closed.

Todo:

Ensure file descriptors are always initialized to -1, and closed using closep.

Parameters:
  • fd – File descriptor to close. Can’t be NULL.

static inline void *bf_memdup(const void *src, size_t len)

Duplicate a memory region.

Allocate a new buffer of size len and copy src into it. Requirements applicable to src and len:

  • If src is NULL, len must be 0. In this case, NULL is returned.

  • If src is non-NULL, a new buffer of len bytes will be allocated to store the first len bytes of src. This new buffer is then returned.

Unless NULL is returned, the new buffer is owned by the caller.

Parameters:
  • src – Source buffer to copy to dst.

  • len – Number of bytes to copy to dst.

Returns:

Pointer to the new buffer, or NULL on failure.

static inline void *bf_memcpy(void *dst, const void *src, size_t len)

Copy len bytes from src to dst.

Allow for src to be NULL and/or len to be zero:

  • If src is NULL, len must be equal 0. dst is not modified.

  • If src is not NULL, len can be equal to 0, in which case dst is not modified.

Parameters:
  • dst – Destination buffer. Can’t be NULL, and must be big enough to store len bytes from src.

  • src – Source buffer to copy to dst.

  • len – Number of bytes to copy to dst.

Returns:

Pointer to dst.

int bf_realloc(void **ptr, size_t size)

Reallocate ptr into a new buffer of size size.

Behaves similarly to realloc(), except that ptr is left unchanged if allocation fails, and an error is returned.

Parameters:
  • ptr – Memory buffer to grow. Can’t be NULL.

  • size – New size of the memory buffer.

Returns:

0 on success, or a negative errno value on failure.

static inline bool bf_streq(const char *lhs, const char *rhs)

Check if strings are equal.

If any of lhs, rhs is NULL, the strings are considered inequal.

Parameters:
  • lhs – First string.

  • rhs – Second string.

Returns:

True if both strings are equal.

static inline bool bf_strneq(const char *lhs, const char *rhs, size_t n)

Similar to bf_streq, except it compares only the first n characters.

If any of lhs, rhs is NULL, the strings are considered inequal.

Parameters:
  • lhs – First string.

  • rhs – Second string.

  • n – Number of characters to compare.

Returns:

True if both strings are equal.

static inline bool bf_streq_i(const char *lhs, const char *rhs)

Case insensitive alternative to bf_streq.

int bf_strncpy(char *dst, size_t len, const char *src)

Copy a string to a buffer.

src is copied to dst . If src is too long, at most len bytes are copied (including the termination character).

Parameters:
  • dst – Destination buffer. Can’t be NULL.

  • len – Length of the destination buffer. The function will not copy more than len bytes to dst , including \0 . Can’t be 0.

  • src – Soucre buffer to copy from. Will only be copied up to the termination character if it fits. Can’t be NULL.

Returns:

0 on success, or -E2BIG if src can’t fit in dst .

int bf_read_file(const char *path, void **buf, size_t *len)

Read the contents of a file into a buffer.

Parameters:
  • path – Path to the file to read. Can’t be NULL.

  • buf – Pointer to a pointer to a buffer. The buffer will be allocated automatically. The caller is responsible to free it. If bf_read_file fails, buf is left unchanged.

  • len – Length of the allocated buffer. Populated by the function.

Returns:

0 on success, negative errno value on error.

int bf_write_file(const char *path, const void *buf, size_t len)

Write the contents of a buffer into a file.

Parameters:
  • path – Path to the file to write. Can’t be NULL.

  • buf – Buffer to write.

  • len – Number of bytes to write the to file.

Returns:

0 on success, negative errno value on error.

uint64_t bf_fnv1a_init(void)

FNV-1a 64-bit offset basis (the initial hash value).

Returns:

The initial hash value to pass to bf_fnv1a().

uint64_t bf_fnv1a(const void *data, size_t len, uint64_t hash)

Compute a FNV-1a 64-bit hash.

Pass bf_fnv1a_init() as hash for the initial call. To hash multiple fields, chain calls by passing the previous return value.

Parameters:
  • data – Data to hash. Can’t be NULL.

  • len – Number of bytes to hash.

  • hash – Initial or chained hash value.

Returns:

Updated hash value.