mirror of
https://git.netfilter.org/nftables
synced 2026-01-27 02:44:07 +00:00
xmalloc() (and similar x-functions) are used for allocation. They wrap malloc()/realloc() but will abort the program on ENOMEM. The meaning of xmalloc() is that it wraps malloc() but aborts on failure. I don't think x-functions should have the notion, that this were potentially a different memory allocator that must be paired with a particular xfree(). Even if the original intent was that the allocator is abstracted (and possibly not backed by standard malloc()/free()), then that doesn't seem a good idea. Nowadays libc allocators are pretty good, and we would need a very special use cases to switch to something else. In other words, it will never happen that xmalloc() is not backed by malloc(). Also there were a few places, where a xmalloc() was already "wrongly" paired with free() (for example, iface_cache_release(), exit_cookie(), nft_run_cmd_from_buffer()). Or note how pid2name() returns an allocated string from fscanf(), which needs to be freed with free() (and not xfree()). This requirement bubbles up the callers portid2name() and name_by_portid(). This case was actually handled correctly and the buffer was freed with free(). But it shows that mixing different allocators is cumbersome to get right. Of course, we don't actually have different allocators and whether to use free() or xfree() makes no different. The point is that xfree() serves no actual purpose except raising irrelevant questions about whether x-functions are correctly paired with xfree(). Note that xfree() also used to accept const pointers. It is bad to unconditionally for all deallocations. Instead prefer to use plain free(). To free a const pointer use free_const() which obviously wraps free, as indicated by the name. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
155 lines
3.8 KiB
C
155 lines
3.8 KiB
C
#ifndef NFTABLES_UTILS_H
|
|
#define NFTABLES_UTILS_H
|
|
|
|
#include <asm/byteorder.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <assert.h>
|
|
#include <list.h>
|
|
#include <gmputil.h>
|
|
|
|
#ifdef HAVE_VISIBILITY_HIDDEN
|
|
# define __visible __attribute__((visibility("default")))
|
|
# define EXPORT_SYMBOL(x) typeof(x) (x) __visible;
|
|
#else
|
|
# define EXPORT_SYMBOL
|
|
#endif
|
|
|
|
#define BITS_PER_BYTE 8
|
|
|
|
#define pr_debug(fmt, arg...) printf(fmt, ##arg)
|
|
|
|
#if defined(HAVE_LIBGMP)
|
|
#define pr_gmp_debug(fmt, arg...) gmp_printf(fmt, ##arg)
|
|
#else
|
|
#define pr_gmp_debug(fmt, arg...) ({ if (false) {}; 0; })
|
|
#endif
|
|
|
|
#define __fmtstring(x, y) __attribute__((format(printf, x, y)))
|
|
#if 0
|
|
#define __gmp_fmtstring(x, y) __fmtstring(x, y)
|
|
#else
|
|
#define __gmp_fmtstring(x, y)
|
|
#endif
|
|
|
|
#define __must_check __attribute__((warn_unused_result))
|
|
#define __noreturn __attribute__((__noreturn__))
|
|
|
|
#define BUG(fmt, arg...) ({ fprintf(stderr, "BUG: " fmt, ##arg); assert(0); abort(); })
|
|
|
|
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
|
|
#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1)
|
|
|
|
#define __must_be_array(a) \
|
|
BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0])))
|
|
|
|
#define container_of(ptr, type, member) ({ \
|
|
typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
|
(type *)( (void *)__mptr - offsetof(type,member) );})
|
|
|
|
/**
|
|
* Return a pointer to a constant variable of a size smaller than the variable.
|
|
*/
|
|
#ifdef __LITTLE_ENDIAN_BITFIELD
|
|
#define constant_data_ptr(val, len) \
|
|
((void *)&(val))
|
|
#elif defined(__BIG_ENDIAN_BITFIELD)
|
|
#define constant_data_ptr(val, len) \
|
|
((void *)&(val) + sizeof(val) - div_round_up(len, BITS_PER_BYTE))
|
|
#else
|
|
#error "byteorder undefined"
|
|
#endif
|
|
|
|
#define field_sizeof(t, f) (sizeof(((t *)NULL)->f))
|
|
#define array_size(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
|
|
#define div_round_up(n, d) (((n) + (d) - 1) / (d))
|
|
#define round_up(n, b) (div_round_up(n, b) * b)
|
|
|
|
#define min(_x, _y) ({ \
|
|
_x < _y ? _x : _y; })
|
|
|
|
#define max(_x, _y) ({ \
|
|
_x > _y ? _x : _y; })
|
|
|
|
#define SNPRINTF_BUFFER_SIZE(ret, len, offset) \
|
|
({ \
|
|
const int _ret = (ret); \
|
|
size_t *const _len = (len); \
|
|
size_t *const _offset = (offset); \
|
|
bool _not_truncated = true; \
|
|
size_t _ret2; \
|
|
\
|
|
assert(_ret >= 0); \
|
|
\
|
|
if ((size_t) _ret >= *_len) { \
|
|
/* Truncated.
|
|
*
|
|
* We will leave "len" at zero and increment
|
|
* "offset" to point one byte after the buffer
|
|
* (after the terminating NUL byte). */ \
|
|
_ret2 = *_len; \
|
|
_not_truncated = false; \
|
|
} else \
|
|
_ret2 = (size_t) _ret; \
|
|
\
|
|
*_offset += _ret2; \
|
|
*_len -= _ret2; \
|
|
\
|
|
_not_truncated; \
|
|
})
|
|
|
|
#define MSEC_PER_SEC 1000L
|
|
|
|
/**
|
|
* fls - find last (most-significant) bit set
|
|
* @x: the word to search
|
|
*
|
|
* This is defined the same way as ffs.
|
|
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
|
|
*/
|
|
static inline int fls(uint32_t x)
|
|
{
|
|
int r = 32;
|
|
|
|
if (!x)
|
|
return 0;
|
|
if (!(x & 0xffff0000u)) {
|
|
x <<= 16;
|
|
r -= 16;
|
|
}
|
|
if (!(x & 0xff000000u)) {
|
|
x <<= 8;
|
|
r -= 8;
|
|
}
|
|
if (!(x & 0xf0000000u)) {
|
|
x <<= 4;
|
|
r -= 4;
|
|
}
|
|
if (!(x & 0xc0000000u)) {
|
|
x <<= 2;
|
|
r -= 2;
|
|
}
|
|
if (!(x & 0x80000000u)) {
|
|
x <<= 1;
|
|
r -= 1;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
extern void __memory_allocation_error(const char *filename, uint32_t line) __noreturn;
|
|
|
|
#define memory_allocation_error() \
|
|
__memory_allocation_error(__FILE__, __LINE__);
|
|
|
|
extern void *xmalloc(size_t size);
|
|
extern void *xmalloc_array(size_t nmemb, size_t size);
|
|
extern void *xrealloc(void *ptr, size_t size);
|
|
extern void *xzalloc(size_t size);
|
|
extern void *xzalloc_array(size_t nmemb, size_t size);
|
|
extern char *xstrdup(const char *s);
|
|
extern void xstrunescape(const char *in, char *out);
|
|
extern int round_pow_2(unsigned int value);
|
|
|
|
#endif /* NFTABLES_UTILS_H */
|