1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3 * Copyright (c) 2003-2012 Thomas Graf <[email protected]>
4 */
5
6 #ifndef __NETLINK_BASE_NL_BASE_UTILS_H__
7 #define __NETLINK_BASE_NL_BASE_UTILS_H__
8
9 #include <byteswap.h>
10 #include <stdlib.h>
11 #include <stdarg.h>
12 #include <limits.h>
13 #include <inttypes.h>
14 #include <assert.h>
15 #include <unistd.h>
16 #include <errno.h>
17 #include <string.h>
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <netinet/in.h>
21 #include <arpa/inet.h>
22
23 #ifndef DISABLE_PTHREADS
24 #include <pthread.h>
25 #endif
26
27 /*****************************************************************************/
28
29 #if __BYTE_ORDER == __BIG_ENDIAN
30 #define ntohll(x) (x)
31 #elif __BYTE_ORDER == __LITTLE_ENDIAN
32 #define ntohll(x) bswap_64((x))
33 #endif
34 #define htonll(x) ntohll(x)
35
36 /*****************************************************************************/
37
38 #define _NL_STRINGIFY_ARG(contents) #contents
39 #define _NL_STRINGIFY(macro_or_string) _NL_STRINGIFY_ARG(macro_or_string)
40
41 /*****************************************************************************/
42
43 #if defined(__GNUC__)
44 #define _NL_PRAGMA_WARNING_DO(warning) \
45 _NL_STRINGIFY(GCC diagnostic ignored warning)
46 #elif defined(__clang__)
47 #define _NL_PRAGMA_WARNING_DO(warning) \
48 _NL_STRINGIFY(clang diagnostic ignored warning)
49 #endif
50
51 /* you can only suppress a specific warning that the compiler
52 * understands. Otherwise you will get another compiler warning
53 * about invalid pragma option.
54 * It's not that bad however, because gcc and clang often have the
55 * same name for the same warning. */
56
57 #if defined(__GNUC__) && \
58 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
59 #define _NL_PRAGMA_WARNING_DISABLE(warning) \
60 _Pragma("GCC diagnostic push") \
61 _Pragma(_NL_PRAGMA_WARNING_DO("-Wpragmas")) \
62 _Pragma(_NL_PRAGMA_WARNING_DO(warning))
63 #elif defined(__clang__)
64 #define _NL_PRAGMA_WARNING_DISABLE(warning) \
65 _Pragma("clang diagnostic push") \
66 _Pragma(_NL_PRAGMA_WARNING_DO("-Wunknown-warning-option")) \
67 _Pragma(_NL_PRAGMA_WARNING_DO(warning))
68 #else
69 #define _NL_PRAGMA_WARNING_DISABLE(warning)
70 #endif
71
72 #if defined(__GNUC__) && \
73 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
74 #define _NL_PRAGMA_WARNING_REENABLE _Pragma("GCC diagnostic pop")
75 #elif defined(__clang__)
76 #define _NL_PRAGMA_WARNING_REENABLE _Pragma("clang diagnostic pop")
77 #else
78 #define _NL_PRAGMA_WARNING_REENABLE
79 #endif
80
81 /*****************************************************************************/
82
83 #define _nl_packed __attribute__((__packed__))
84 #define _nl_unused __attribute__((__unused__))
85 #define _nl_always_inline __attribute__((__always_inline__))
86 #define _nl_used __attribute__((__used__))
87 #define _nl_pure __attribute__((__pure__))
88 #define _nl_const __attribute__((__const__))
89 #define _nl_noreturn __attribute__((__noreturn__))
90 #define _nl_warn_unused_result __attribute__((__warn_unused_result__))
91 #define _nl_printf(a, b) __attribute__((__format__(__printf__, a, b)))
92 #define _nl_align(s) __attribute__((__aligned__(s)))
93 #define _nl_section(s) __attribute__((__section__(s)))
94 #define _nl_alignof(type) __alignof(type)
95 #define _nl_alignas(type) _nl_align(_nl_alignof(type))
96 #define _nl_deprecated(msg) __attribute__((__deprecated__(msg)))
97 #define _nl_init __attribute__((constructor))
98 #define _nl_exit __attribute__((destructor))
99 #define _nl_auto(fcn) __attribute__((__cleanup__(fcn)))
100
101 /*****************************************************************************/
102
103 #ifdef thread_local
104 #define _nl_thread_local thread_local
105 /*
106 * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__
107 * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769
108 */
109 #elif __STDC_VERSION__ >= 201112L && \
110 !(defined(__STDC_NO_THREADS__) || \
111 (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && \
112 __GLIBC_MINOR__ < 16))
113 #define _nl_thread_local _Thread_local
114 #else
115 #define _nl_thread_local __thread
116 #endif
117
118 /*****************************************************************************/
119
120 #define _NL_STATIC_ASSERT(cond) ((void)sizeof(char[(cond) ? 1 : -1]))
121
122 /*****************************************************************************/
123
124 #if defined(NL_MORE_ASSERTS) && NL_MORE_ASSERTS > 0
125 #define _nl_assert(cond) assert(cond)
126 #else
127 #define _nl_assert(cond) \
128 do { \
129 if (0) { \
130 assert(cond); \
131 } \
132 } while (0)
133 #endif
134
135 #define _nl_assert_not_reached() assert(0)
136
137 /*****************************************************************************/
138
139 #define _NL_BIT(n) (1ull << (n))
140
141 /*****************************************************************************/
142
143 #define _NL_PASTE_ARGS(identifier1, identifier2) identifier1##identifier2
144 #define _NL_PASTE(identifier1, identifier2) \
145 _NL_PASTE_ARGS(identifier1, identifier2)
146
147 /* Taken from systemd's UNIQ_T and UNIQ macros. */
148
149 #define _NL_UNIQ_T(x, uniq) _NL_PASTE(__unique_prefix_, _NL_PASTE(x, uniq))
150 #define _NL_UNIQ __COUNTER__
151
152 /*****************************************************************************/
153
154 #define _nl_assert_addr_family_or_unspec(addr_family) \
155 do { \
156 typeof(addr_family) _addr_family = (addr_family); \
157 \
158 _nl_assert(_addr_family == AF_UNSPEC || \
159 _addr_family == AF_INET || \
160 _addr_family == AF_INET6); \
161 } while (0)
162
163 #define _nl_assert_addr_family(addr_family) \
164 do { \
165 typeof(addr_family) _addr_family = (addr_family); \
166 \
167 _nl_assert(_addr_family == AF_INET || \
168 _addr_family == AF_INET6); \
169 } while (0)
170
171 /*****************************************************************************/
172
173 #define _NL_SWAP(pa, pb) \
174 do { \
175 typeof(*(pa)) *_pa = (pa); \
176 typeof(*(pb)) *_pb = (pb); \
177 typeof(*_pa) _tmp; \
178 \
179 _nl_assert(_pa); \
180 _nl_assert(_pb); \
181 _tmp = *_pa; \
182 *_pa = *_pb; \
183 *_pb = _tmp; \
184 } while (0)
185
186 /*****************************************************************************/
187
188 #define _NL_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0]))
189
190 #define ARRAY_SIZE(arr) _NL_N_ELEMENTS(arr)
191
192 /*****************************************************************************/
193
194 /* This is also defined in stddef.h */
195 #ifndef offsetof
196 #define offsetof(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER)
197 #endif
198
199 /*****************************************************************************/
200
_nl_ptr_to_uintptr(const void * p)201 static inline uintptr_t _nl_ptr_to_uintptr(const void *p)
202 {
203 /* in C, pointers can only be compared (with less-than or greater-than) under certain
204 * circumstances. Since uintptr_t is supposed to be able to represent the pointer
205 * as a plain integer and also support to convert the integer back to the pointer,
206 * it should be safer to compare the pointers directly.
207 *
208 * Of course, this function isn't very useful beyond that its use makes it clear
209 * that we want to compare pointers by value, which otherwise may not be valid. */
210 return (uintptr_t)p;
211 }
212
213 /*****************************************************************************/
214
_nl_strcmp0(const char * s1,const char * s2)215 static inline int _nl_strcmp0(const char *s1, const char *s2)
216 {
217 int c;
218
219 /* like g_strcmp0(), but this is inlinable.
220 *
221 * Also, it is guaranteed to return either -1, 0, or 1. */
222 if (s1 == s2)
223 return 0;
224 if (!s1)
225 return -1;
226 if (!s2)
227 return 1;
228 c = strcmp(s1, s2);
229 if (c < 0)
230 return -1;
231 if (c > 0)
232 return 1;
233 return 0;
234 }
235
_nl_streq(const char * a,const char * b)236 static inline bool _nl_streq(const char *a, const char *b)
237 {
238 return !strcmp(a, b);
239 }
240
_nl_streq0(const char * a,const char * b)241 static inline bool _nl_streq0(const char *a, const char *b)
242 {
243 return a == b || (a && b && _nl_streq(a, b));
244 }
245
_nl_memcmp(const void * s1,const void * s2,size_t n)246 static inline int _nl_memcmp(const void *s1, const void *s2, size_t n)
247 {
248 /* Workaround undefined behavior in memcmp() with NULL pointers. */
249 if (n == 0)
250 return 0;
251 _nl_assert(s1);
252 _nl_assert(s2);
253 return memcmp(s1, s2, n);
254 }
255
_nl_memeq(const void * s1,const void * s2,size_t len)256 static inline bool _nl_memeq(const void *s1, const void *s2, size_t len)
257 {
258 return _nl_memcmp(s1, s2, len) == 0;
259 }
260
_nl_memcpy(void * restrict dest,const void * restrict src,size_t n)261 static inline void *_nl_memcpy(void *restrict dest, const void *restrict src,
262 size_t n)
263 {
264 /* Workaround undefined behavior in memcpy() with NULL pointers. */
265 if (n == 0)
266 return dest;
267
268 _nl_assert(src);
269 return memcpy(dest, src, n);
270 }
271
272 /*****************************************************************************/
273
274 #define _NL_INT_IS_SIGNED(arg) (!(((typeof(arg))-1) > 0))
275
276 #define _NL_INT_SAME_SIGNEDNESS(arg1, arg2) \
277 (_NL_INT_IS_SIGNED(arg1) == _NL_INT_IS_SIGNED(arg2))
278
279 /*****************************************************************************/
280
281 /* glib's MIN()/MAX() macros don't have function-like behavior, in that they evaluate
282 * the argument possibly twice.
283 *
284 * Taken from systemd's MIN()/MAX() macros. */
285
286 #define _NL_MIN(a, b) __NL_MIN(_NL_UNIQ, a, _NL_UNIQ, b)
287 #define __NL_MIN(aq, a, bq, b) \
288 ({ \
289 typeof(a) _NL_UNIQ_T(A, aq) = (a); \
290 typeof(b) _NL_UNIQ_T(B, bq) = (b); \
291 \
292 _NL_STATIC_ASSERT(_NL_INT_SAME_SIGNEDNESS(_NL_UNIQ_T(A, aq), \
293 _NL_UNIQ_T(B, bq))); \
294 \
295 ((_NL_UNIQ_T(A, aq) < _NL_UNIQ_T(B, bq)) ? _NL_UNIQ_T(A, aq) : \
296 _NL_UNIQ_T(B, bq)); \
297 })
298
299 #define _NL_MAX(a, b) __NL_MAX(_NL_UNIQ, a, _NL_UNIQ, b)
300 #define __NL_MAX(aq, a, bq, b) \
301 ({ \
302 typeof(a) _NL_UNIQ_T(A, aq) = (a); \
303 typeof(b) _NL_UNIQ_T(B, bq) = (b); \
304 \
305 _NL_STATIC_ASSERT(_NL_INT_SAME_SIGNEDNESS(_NL_UNIQ_T(A, aq), \
306 _NL_UNIQ_T(B, bq))); \
307 \
308 ((_NL_UNIQ_T(A, aq) > _NL_UNIQ_T(B, bq)) ? _NL_UNIQ_T(A, aq) : \
309 _NL_UNIQ_T(B, bq)); \
310 })
311
312 #define _NL_CLAMP(x, low, high) \
313 __NL_CLAMP(_NL_UNIQ, x, _NL_UNIQ, low, _NL_UNIQ, high)
314 #define __NL_CLAMP(xq, x, lowq, low, highq, high) \
315 ({ \
316 typeof(x) _NL_UNIQ_T(X, xq) = (x); \
317 typeof(low) _NL_UNIQ_T(LOW, lowq) = (low); \
318 typeof(high) _NL_UNIQ_T(HIGH, highq) = (high); \
319 \
320 _NL_STATIC_ASSERT(_NL_INT_SAME_SIGNEDNESS( \
321 _NL_UNIQ_T(X, xq), _NL_UNIQ_T(LOW, lowq))); \
322 _NL_STATIC_ASSERT(_NL_INT_SAME_SIGNEDNESS( \
323 _NL_UNIQ_T(X, xq), _NL_UNIQ_T(HIGH, highq))); \
324 \
325 ((_NL_UNIQ_T(X, xq) > _NL_UNIQ_T(HIGH, highq)) ? \
326 _NL_UNIQ_T(HIGH, highq) : \
327 (_NL_UNIQ_T(X, xq) < _NL_UNIQ_T(LOW, lowq)) ? \
328 _NL_UNIQ_T(LOW, lowq) : \
329 _NL_UNIQ_T(X, xq)); \
330 })
331
332 #define _NL_MAX_WITH_CMP(cmp, a, b) \
333 ({ \
334 typeof(a) _a = (a); \
335 typeof(b) _b = (b); \
336 \
337 (((cmp(_a, _b)) >= 0) ? _a : _b); \
338 })
339
340 /* evaluates to (void) if _A or _B are not constant or of different types */
341 #define _NL_CONST_MAX(_A, _B) \
342 (__builtin_choose_expr( \
343 (__builtin_constant_p(_A) && __builtin_constant_p(_B) && \
344 __builtin_types_compatible_p(typeof(_A), typeof(_B))), \
345 ((_A) > (_B)) ? (_A) : (_B), ((void)0)))
346
347 /*****************************************************************************/
348
349 #define _NL_CMP_RETURN(c) \
350 do { \
351 const int _cc = (c); \
352 \
353 if (_cc) \
354 return _cc < 0 ? -1 : 1; \
355 } while (0)
356
357 #define _NL_CMP_RETURN_DIRECT(c) \
358 /* Usually we want that our CMP functions return strictly
359 * -1, 0, or 1. _NL_CMP_RETURN_DIRECT() is like _NL_CMP_RETURN(),
360 * except, it does not clamp the integer value. */ \
361 do { \
362 const int _cc = (c); \
363 \
364 if (_cc) \
365 return _cc; \
366 } while (0)
367
368 #define _NL_CMP_SELF(a, b) \
369 do { \
370 typeof(a) _a = (a); \
371 typeof(b) _b = (b); \
372 \
373 if (_a == _b) \
374 return 0; \
375 if (!_a) \
376 return -1; \
377 if (!_b) \
378 return 1; \
379 } while (0)
380
381 /*****************************************************************************/
382
383 #define _NL_CMP_DIRECT(a, b) \
384 do { \
385 typeof(a) _a = (a); \
386 typeof(b) _b = (b); \
387 \
388 _NL_STATIC_ASSERT(_NL_INT_SAME_SIGNEDNESS(_a, _b)); \
389 \
390 if (_a != _b) \
391 return (_a < _b) ? -1 : 1; \
392 } while (0)
393
394 #define _NL_CMP_DIRECT_UNSAFE(a, b) \
395 /* This variant is "unsafe", because it evaluates the arguments more then once.
396 * This is only useful for bitfields, for which typeof() doesn't work.
397 * Don't use otherwise. */ \
398 do { \
399 if ((a) != (b)) \
400 return ((a) < (b)) ? -1 : 1; \
401 } while (0)
402
403 /* In the general case, direct pointer comparison is undefined behavior in C.
404 * Avoid that by casting pointers to void* and then to uintptr_t. This comparison
405 * is not really meaningful, except that it provides some kind of stable sort order
406 * between pointers (that can otherwise not be compared). */
407 #define _NL_CMP_DIRECT_PTR(a, b) \
408 _NL_CMP_DIRECT(_nl_ptr_to_uintptr(a), _nl_ptr_to_uintptr(b))
409
410 #define _NL_CMP_DIRECT_BOOL(a, b) _NL_CMP_DIRECT(!!(a), !!(b))
411
412 #define _NL_CMP_DIRECT_MEMCMP(a, b, size) \
413 _NL_CMP_RETURN(_nl_memcmp((a), (b), (size)))
414
415 #define _NL_CMP_DIRECT_STRCMP(a, b) _NL_CMP_RETURN_DIRECT(strcmp((a), (b)))
416
417 #define _NL_CMP_DIRECT_STRCMP0(a, b) \
418 _NL_CMP_RETURN_DIRECT(_nl_strcmp0((a), (b)))
419
420 #define _NL_CMP_DIRECT_STR_INTERNED(a, b) \
421 /* This is interned strings, which are first checked for equality only using pointer
422 * comparison. Only in case of differences, the sort order is still determined by strcmp(). */ \
423 do { \
424 const char *const _a = (a); \
425 const char *const _b = (b); \
426 \
427 if (_a != _b) \
428 _NL_CMP_RETURN_DIRECT(_nl_strcmp0(_a, _b)); \
429 } while (0)
430
431 #define _NL_CMP_DIRECT_IN6ADDR(a, b) \
432 do { \
433 const struct in6_addr *const _a = (a); \
434 const struct in6_addr *const _b = (b); \
435 \
436 _NL_CMP_RETURN(memcmp(_a, _b, sizeof(struct in6_addr))); \
437 } while (0)
438
439 /*****************************************************************************/
440
441 #define _NL_CMP_FIELD(a, b, field) _NL_CMP_DIRECT(((a)->field), ((b)->field))
442
443 #define _NL_CMP_FIELD_UNSAFE(a, b, field) \
444 /* This variant is "unsafe", because it evaluates the arguments more then once.
445 * This is only useful for bitfields, for which typeof() doesn't work.
446 * Don't use otherwise. */ \
447 _NL_CMP_DIRECT_UNSAFE(((a)->field), ((b)->field))
448
449 #define _NL_CMP_FIELD_BOOL(a, b, field) \
450 _NL_CMP_DIRECT_BOOL(((a)->field), ((b)->field))
451
452 #define _NL_CMP_FIELD_STR(a, b, field) \
453 _NL_CMP_DIRECT_STRCMP(((a)->field), ((b)->field))
454
455 #define _NL_CMP_FIELD_STR0(a, b, field) \
456 _NL_CMP_DIRECT_STRCMP0(((a)->field), ((b)->field))
457
458 #define _NL_CMP_FIELD_STR_INTERNED(a, b, field) \
459 _NL_CMP_DIRECT_STR_INTERNED(((a)->field), ((b)->field))
460
461 #define _NL_CMP_FIELD_MEMCMP_LEN(a, b, field, len) \
462 _NL_CMP_DIRECT_MEMCMP(&((a)->field), &((b)->field), \
463 _NL_MIN(len, sizeof((a)->field)))
464
465 #define _NL_CMP_FIELD_MEMCMP(a, b, field) \
466 _NL_CMP_DIRECT_MEMCMP(&((a)->field), &((b)->field), sizeof((a)->field))
467
468 #define _NL_CMP_FIELD_IN6ADDR(a, b, field) \
469 _NL_CMP_DIRECT_IN6ADDR(&((a)->field), &((b)->field))
470
471 /*****************************************************************************/
472
473 /* internal macro to calculate the size of a struct @type up to (and including) @field.
474 * this will be used for .minlen policy fields, so that we require only a field of up
475 * to the given size. */
476 #define _nl_offsetofend(type, field) \
477 (offsetof(type, field) + sizeof(((type *)NULL)->field))
478
479 /*****************************************************************************/
480
481 #define _nl_clear_pointer(pp, destroy) \
482 ({ \
483 __typeof__(*(pp)) *_pp = (pp); \
484 __typeof__(*_pp) _p; \
485 int _changed = 0; \
486 \
487 if (_pp && (_p = *_pp)) { \
488 _nl_unused const void *const _p_check_is_pointer = _p; \
489 \
490 *_pp = NULL; \
491 \
492 (destroy)(_p); \
493 \
494 _changed = 1; \
495 } \
496 _changed; \
497 })
498
499 #define _nl_clear_free(pp) _nl_clear_pointer(pp, free)
500
501 #define _nl_steal_pointer(pp) \
502 ({ \
503 __typeof__(*(pp)) *const _pp = (pp); \
504 __typeof__(*_pp) _p = NULL; \
505 \
506 if (_pp && (_p = *_pp)) { \
507 *_pp = NULL; \
508 } \
509 \
510 _p; \
511 })
512
513 /*****************************************************************************/
514
515 #define _nl_malloc_maybe_a(alloca_maxlen, bytes, to_free) \
516 ({ \
517 const size_t _bytes = (bytes); \
518 __typeof__(to_free) _to_free = (to_free); \
519 __typeof__(*_to_free) _ptr; \
520 \
521 _NL_STATIC_ASSERT((alloca_maxlen) <= 500); \
522 _nl_assert(_to_free && !*_to_free); \
523 \
524 if (_bytes <= (alloca_maxlen)) { \
525 _ptr = alloca(_bytes); \
526 } else { \
527 _ptr = malloc(_bytes); \
528 *_to_free = _ptr; \
529 }; \
530 \
531 _ptr; \
532 })
533
534 /*****************************************************************************/
535
_nl_strncpy_trunc(char * dst,const char * src,size_t len)536 static inline char *_nl_strncpy_trunc(char *dst, const char *src, size_t len)
537 {
538 /* we don't use/reimplement strlcpy(), because we want the fill-all-with-NUL
539 * behavior of strncpy(). This is just strncpy() with gracefully handling truncation
540 * (and disabling the "-Wstringop-truncation" warning).
541 *
542 * Note that truncation is silently accepted.
543 */
544
545 _NL_PRAGMA_WARNING_DISABLE("-Wstringop-truncation");
546 _NL_PRAGMA_WARNING_DISABLE("-Wstringop-overflow");
547
548 if (len > 0) {
549 _nl_assert(dst);
550 _nl_assert(src);
551
552 strncpy(dst, src, len);
553
554 dst[len - 1] = '\0';
555 }
556
557 _NL_PRAGMA_WARNING_REENABLE;
558 _NL_PRAGMA_WARNING_REENABLE;
559
560 return dst;
561 }
562
_nl_strncpy_assert(char * dst,const char * src,size_t len)563 static inline char *_nl_strncpy_assert(char *dst, const char *src, size_t len)
564 {
565 /* we don't use/reimplement strlcpy(), because we want the fill-all-with-NUL
566 * behavior of strncpy(). This is just strncpy() with assertion against truncation
567 * (and disabling the "-Wstringop-truncation" warning).
568 *
569 * Note that truncation is still a bug and there is an _nl_assert()
570 * against that.
571 */
572
573 _NL_PRAGMA_WARNING_DISABLE("-Wstringop-truncation");
574 _NL_PRAGMA_WARNING_DISABLE("-Wstringop-overflow");
575
576 if (len > 0) {
577 _nl_assert(dst);
578 _nl_assert(src);
579
580 strncpy(dst, src, len);
581
582 _nl_assert(dst[len - 1] == '\0');
583
584 dst[len - 1] = '\0';
585 }
586
587 _NL_PRAGMA_WARNING_REENABLE;
588 _NL_PRAGMA_WARNING_REENABLE;
589
590 return dst;
591 }
592
593 #define _NL_RETURN_ON_ERR(cmd) \
594 do { \
595 int _err; \
596 \
597 _err = (cmd); \
598 if (_err < 0) \
599 return _err; \
600 } while (0)
601
602 #define _NL_RETURN_E_ON_ERR(e, cmd) \
603 do { \
604 int _err; \
605 \
606 _err = (cmd); \
607 if (_err < 0) { \
608 _NL_STATIC_ASSERT((e) > 0); \
609 return -(e); \
610 } \
611 } while (0)
612
613 /* _NL_RETURN_ON_PUT_ERR() shall only be used with a put command (nla_put or nlmsg_append).
614 * These commands can either fail with a regular error code (which gets propagated)
615 * or with -NLE_NOMEM. However, they don't really try to allocate memory, so we don't
616 * want to propagate -NLE_NOMEM. Instead, we coerce such failure to -NLE_MSGSIZE. */
617 #define _NL_RETURN_ON_PUT_ERR(put_cmd) \
618 do { \
619 int _err; \
620 \
621 _err = (put_cmd); \
622 if (_err < 0) { \
623 if (_err == -NLE_NOMEM) { \
624 /* nla_put() returns -NLE_NOMEM in case of out of buffer size. We don't
625 * want to propagate that error and map it to -NLE_MSGSIZE. */ \
626 return -NLE_MSGSIZE; \
627 } \
628 /* any other error can only be due to invalid parameters. Propagate the
629 * error, however also assert that it cannot be reached. */ \
630 _nl_assert_not_reached(); \
631 return _err; \
632 } else \
633 _nl_assert(_err == 0); \
634 } while (0)
635
_nl_close(int fd)636 static inline int _nl_close(int fd)
637 {
638 int r;
639
640 r = close(fd);
641 _nl_assert(r == 0 || fd < 0 || errno != EBADF);
642 return r;
643 }
644
_nl_memdup(const void * ptr,size_t len)645 static inline void *_nl_memdup(const void *ptr, size_t len)
646 {
647 void *p;
648
649 if (len == 0) {
650 /* malloc() leaves it implementation defined whether to return NULL.
651 * Callers rely on returning NULL if len is zero. */
652 return NULL;
653 }
654
655 p = malloc(len);
656 if (!p)
657 return NULL;
658 memcpy(p, ptr, len);
659 return p;
660 }
661
662 #define _nl_memdup_ptr(ptr) ((__typeof__(ptr))_nl_memdup((ptr), sizeof(*(ptr))))
663
664 /*****************************************************************************/
665
_nl_addr_family_to_size(int addr_family)666 static inline size_t _nl_addr_family_to_size(int addr_family)
667 {
668 if (addr_family == AF_INET)
669 return sizeof(in_addr_t);
670 if (addr_family == AF_INET6)
671 return sizeof(struct in6_addr);
672 return 0;
673 }
674
675 /*****************************************************************************/
676
677 typedef union {
678 in_addr_t addr4;
679 struct in_addr a4;
680 struct in6_addr a6;
681 } _NLIPAddr;
682
_nl_inet_ntop(int addr_family,const void * addr,char * buf)683 static inline char *_nl_inet_ntop(int addr_family, const void *addr, char *buf)
684 {
685 char *r;
686
687 _nl_assert_addr_family(addr_family);
688 _nl_assert(addr);
689
690 /* inet_ntop() is documented to fail, but if we pass a known address family
691 * and a suitably large buffer, it cannot. Assert for that. */
692
693 r = (char *)inet_ntop(addr_family, addr, buf,
694 (addr_family == AF_INET) ? INET_ADDRSTRLEN :
695 INET6_ADDRSTRLEN);
696 _nl_assert(r == buf);
697 _nl_assert(strlen(r) < ((addr_family == AF_INET) ? INET_ADDRSTRLEN :
698 INET6_ADDRSTRLEN));
699
700 return r;
701 }
702
_nl_inet_ntop_dup(int addr_family,const void * addr)703 static inline char *_nl_inet_ntop_dup(int addr_family, const void *addr)
704 {
705 return (char *)_nl_inet_ntop(addr_family, addr,
706 malloc((addr_family == AF_INET) ?
707 INET_ADDRSTRLEN :
708 INET6_ADDRSTRLEN));
709 }
710
711 /*****************************************************************************/
712
713 #define _NL_AUTO_DEFINE_FCN_VOID0(CastType, name, func) \
714 static inline void name(void *v) \
715 { \
716 if (*((CastType *)v)) \
717 func(*((CastType *)v)); \
718 } \
719 struct _nl_dummy_for_tailing_semicolon
720
721 #define _NL_AUTO_DEFINE_FCN_STRUCT(CastType, name, func) \
722 static inline void name(CastType *v) \
723 { \
724 if (v) \
725 func(v); \
726 } \
727 struct _nl_dummy_for_tailing_semicolon
728
729 #define _NL_AUTO_DEFINE_FCN_TYPED0(CastType, name, func) \
730 static inline void name(CastType *v) \
731 { \
732 if (*v) \
733 func(*v); \
734 } \
735 struct _nl_dummy_for_tailing_semicolon
736
737 #define _NL_AUTO_DEFINE_FCN_INDIRECT0(CastType, name, func) \
738 static inline void name(CastType *v) \
739 { \
740 if (*v) \
741 func(v); \
742 } \
743 struct _nl_dummy_for_tailing_semicolon
744
745 #define _nl_auto_free _nl_auto(_nl_auto_free_fcn)
746 _NL_AUTO_DEFINE_FCN_VOID0(void *, _nl_auto_free_fcn, free);
747
748 /*****************************************************************************/
749
750 #define NSEC_PER_SEC 1000000000L
751
752 struct trans_tbl {
753 uint64_t i;
754 const char *a;
755 };
756
757 #define __ADD(id, name) { .i = id, .a = #name }
758
759 #define BUG() \
760 do { \
761 fprintf(stderr, "BUG at file position %s:%d:%s\n", __FILE__, \
762 __LINE__, __func__); \
763 assert(0); \
764 } while (0)
765
766 #define BUG_ON(condition) \
767 do { \
768 if (condition) \
769 BUG(); \
770 } while (0)
771
772 #define APPBUG(msg) \
773 do { \
774 fprintf(stderr, "APPLICATION BUG: %s:%d:%s: %s\n", __FILE__, \
775 __LINE__, __func__, msg); \
776 assert(0); \
777 } while (0)
778
779 /*****************************************************************************/
780
781 #ifndef DISABLE_PTHREADS
782 #define NL_LOCK(NAME) pthread_mutex_t(NAME) = PTHREAD_MUTEX_INITIALIZER
783 #define NL_RW_LOCK(NAME) pthread_rwlock_t(NAME) = PTHREAD_RWLOCK_INITIALIZER
784
nl_lock(pthread_mutex_t * lock)785 static inline void nl_lock(pthread_mutex_t *lock)
786 {
787 pthread_mutex_lock(lock);
788 }
789
nl_unlock(pthread_mutex_t * lock)790 static inline void nl_unlock(pthread_mutex_t *lock)
791 {
792 pthread_mutex_unlock(lock);
793 }
794
nl_read_lock(pthread_rwlock_t * lock)795 static inline void nl_read_lock(pthread_rwlock_t *lock)
796 {
797 pthread_rwlock_rdlock(lock);
798 }
799
nl_read_unlock(pthread_rwlock_t * lock)800 static inline void nl_read_unlock(pthread_rwlock_t *lock)
801 {
802 pthread_rwlock_unlock(lock);
803 }
804
nl_write_lock(pthread_rwlock_t * lock)805 static inline void nl_write_lock(pthread_rwlock_t *lock)
806 {
807 pthread_rwlock_wrlock(lock);
808 }
809
nl_write_unlock(pthread_rwlock_t * lock)810 static inline void nl_write_unlock(pthread_rwlock_t *lock)
811 {
812 pthread_rwlock_unlock(lock);
813 }
814
815 #else
816 #define NL_LOCK(NAME) int __unused_lock_##NAME _nl_unused
817 #define NL_RW_LOCK(NAME) int __unused_lock_##NAME _nl_unused
818
819 #define nl_lock(LOCK) \
820 do { \
821 } while (0)
822 #define nl_unlock(LOCK) \
823 do { \
824 } while (0)
825 #define nl_read_lock(LOCK) \
826 do { \
827 } while (0)
828 #define nl_read_unlock(LOCK) \
829 do { \
830 } while (0)
831 #define nl_write_lock(LOCK) \
832 do { \
833 } while (0)
834 #define nl_write_unlock(LOCK) \
835 do { \
836 } while (0)
837 #endif
838
839 #endif /* __NETLINK_BASE_NL_BASE_UTILS_H__ */
840