162306a36Sopenharmony_ci/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci/*
462306a36Sopenharmony_ci * Common user-facing libbpf helpers.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (c) 2019 Facebook
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#ifndef __LIBBPF_LIBBPF_COMMON_H
1062306a36Sopenharmony_ci#define __LIBBPF_LIBBPF_COMMON_H
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <string.h>
1362306a36Sopenharmony_ci#include "libbpf_version.h"
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#ifndef LIBBPF_API
1662306a36Sopenharmony_ci#define LIBBPF_API __attribute__((visibility("default")))
1762306a36Sopenharmony_ci#endif
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#define LIBBPF_DEPRECATED(msg) __attribute__((deprecated(msg)))
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/* Mark a symbol as deprecated when libbpf version is >= {major}.{minor} */
2262306a36Sopenharmony_ci#define LIBBPF_DEPRECATED_SINCE(major, minor, msg)			    \
2362306a36Sopenharmony_ci	__LIBBPF_MARK_DEPRECATED_ ## major ## _ ## minor		    \
2462306a36Sopenharmony_ci		(LIBBPF_DEPRECATED("libbpf v" # major "." # minor "+: " msg))
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#define __LIBBPF_CURRENT_VERSION_GEQ(major, minor)			    \
2762306a36Sopenharmony_ci	(LIBBPF_MAJOR_VERSION > (major) ||				    \
2862306a36Sopenharmony_ci	 (LIBBPF_MAJOR_VERSION == (major) && LIBBPF_MINOR_VERSION >= (minor)))
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci/* Add checks for other versions below when planning deprecation of API symbols
3162306a36Sopenharmony_ci * with the LIBBPF_DEPRECATED_SINCE macro.
3262306a36Sopenharmony_ci */
3362306a36Sopenharmony_ci#if __LIBBPF_CURRENT_VERSION_GEQ(1, 0)
3462306a36Sopenharmony_ci#define __LIBBPF_MARK_DEPRECATED_1_0(X) X
3562306a36Sopenharmony_ci#else
3662306a36Sopenharmony_ci#define __LIBBPF_MARK_DEPRECATED_1_0(X)
3762306a36Sopenharmony_ci#endif
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci/* This set of internal macros allows to do "function overloading" based on
4062306a36Sopenharmony_ci * number of arguments provided by used in backwards-compatible way during the
4162306a36Sopenharmony_ci * transition to libbpf 1.0
4262306a36Sopenharmony_ci * It's ugly but necessary evil that will be cleaned up when we get to 1.0.
4362306a36Sopenharmony_ci * See bpf_prog_load() overload for example.
4462306a36Sopenharmony_ci */
4562306a36Sopenharmony_ci#define ___libbpf_cat(A, B) A ## B
4662306a36Sopenharmony_ci#define ___libbpf_select(NAME, NUM) ___libbpf_cat(NAME, NUM)
4762306a36Sopenharmony_ci#define ___libbpf_nth(_1, _2, _3, _4, _5, _6, N, ...) N
4862306a36Sopenharmony_ci#define ___libbpf_cnt(...) ___libbpf_nth(__VA_ARGS__, 6, 5, 4, 3, 2, 1)
4962306a36Sopenharmony_ci#define ___libbpf_overload(NAME, ...) ___libbpf_select(NAME, ___libbpf_cnt(__VA_ARGS__))(__VA_ARGS__)
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci/* Helper macro to declare and initialize libbpf options struct
5262306a36Sopenharmony_ci *
5362306a36Sopenharmony_ci * This dance with uninitialized declaration, followed by memset to zero,
5462306a36Sopenharmony_ci * followed by assignment using compound literal syntax is done to preserve
5562306a36Sopenharmony_ci * ability to use a nice struct field initialization syntax and **hopefully**
5662306a36Sopenharmony_ci * have all the padding bytes initialized to zero. It's not guaranteed though,
5762306a36Sopenharmony_ci * when copying literal, that compiler won't copy garbage in literal's padding
5862306a36Sopenharmony_ci * bytes, but that's the best way I've found and it seems to work in practice.
5962306a36Sopenharmony_ci *
6062306a36Sopenharmony_ci * Macro declares opts struct of given type and name, zero-initializes,
6162306a36Sopenharmony_ci * including any extra padding, it with memset() and then assigns initial
6262306a36Sopenharmony_ci * values provided by users in struct initializer-syntax as varargs.
6362306a36Sopenharmony_ci */
6462306a36Sopenharmony_ci#define LIBBPF_OPTS(TYPE, NAME, ...)					    \
6562306a36Sopenharmony_ci	struct TYPE NAME = ({ 						    \
6662306a36Sopenharmony_ci		memset(&NAME, 0, sizeof(struct TYPE));			    \
6762306a36Sopenharmony_ci		(struct TYPE) {						    \
6862306a36Sopenharmony_ci			.sz = sizeof(struct TYPE),			    \
6962306a36Sopenharmony_ci			__VA_ARGS__					    \
7062306a36Sopenharmony_ci		};							    \
7162306a36Sopenharmony_ci	})
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci/* Helper macro to clear and optionally reinitialize libbpf options struct
7462306a36Sopenharmony_ci *
7562306a36Sopenharmony_ci * Small helper macro to reset all fields and to reinitialize the common
7662306a36Sopenharmony_ci * structure size member. Values provided by users in struct initializer-
7762306a36Sopenharmony_ci * syntax as varargs can be provided as well to reinitialize options struct
7862306a36Sopenharmony_ci * specific members.
7962306a36Sopenharmony_ci */
8062306a36Sopenharmony_ci#define LIBBPF_OPTS_RESET(NAME, ...)					    \
8162306a36Sopenharmony_ci	do {								    \
8262306a36Sopenharmony_ci		typeof(NAME) ___##NAME = ({ 				    \
8362306a36Sopenharmony_ci			memset(&___##NAME, 0, sizeof(NAME));		    \
8462306a36Sopenharmony_ci			(typeof(NAME)) {				    \
8562306a36Sopenharmony_ci				.sz = sizeof(NAME),			    \
8662306a36Sopenharmony_ci				__VA_ARGS__				    \
8762306a36Sopenharmony_ci			};						    \
8862306a36Sopenharmony_ci		});							    \
8962306a36Sopenharmony_ci		memcpy(&NAME, &___##NAME, sizeof(NAME));		    \
9062306a36Sopenharmony_ci	} while (0)
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci#endif /* __LIBBPF_LIBBPF_COMMON_H */
93