diff options
Diffstat (limited to 'package/libs/libnl-tiny/src/include/netlink')
22 files changed, 3410 insertions, 0 deletions
diff --git a/package/libs/libnl-tiny/src/include/netlink/addr.h b/package/libs/libnl-tiny/src/include/netlink/addr.h new file mode 100644 index 0000000000..cc3d201f97 --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/addr.h @@ -0,0 +1,69 @@ +/* + * netlink/addr.h Abstract Address + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_ADDR_H_ +#define NETLINK_ADDR_H_ + +#include <netlink/netlink.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct nl_addr; + +/* Creation */ +extern struct nl_addr * nl_addr_alloc(size_t); +extern struct nl_addr * nl_addr_alloc_attr(struct nlattr *, int); +extern struct nl_addr * nl_addr_build(int, void *, size_t); +extern int nl_addr_parse(const char *, int, struct nl_addr **); +extern struct nl_addr * nl_addr_clone(struct nl_addr *); + +/* Destroyage */ +extern void nl_addr_destroy(struct nl_addr *); + +/* Usage Management */ +extern struct nl_addr * nl_addr_get(struct nl_addr *); +extern void nl_addr_put(struct nl_addr *); +extern int nl_addr_shared(struct nl_addr *); + +extern int nl_addr_cmp(struct nl_addr *, struct nl_addr *); +extern int nl_addr_cmp_prefix(struct nl_addr *, struct nl_addr *); +extern int nl_addr_iszero(struct nl_addr *); +extern int nl_addr_valid(char *, int); +extern int nl_addr_guess_family(struct nl_addr *); +extern int nl_addr_fill_sockaddr(struct nl_addr *, + struct sockaddr *, socklen_t *); +extern int nl_addr_info(struct nl_addr *, struct addrinfo **); +extern int nl_addr_resolve(struct nl_addr *addr, char *host, size_t hostlen); + +/* Access Functions */ +extern void nl_addr_set_family(struct nl_addr *, int); +extern int nl_addr_get_family(struct nl_addr *); +extern int nl_addr_set_binary_addr(struct nl_addr *, void *, + size_t); +extern void * nl_addr_get_binary_addr(struct nl_addr *); +extern unsigned int nl_addr_get_len(struct nl_addr *); +extern void nl_addr_set_prefixlen(struct nl_addr *, int); +extern unsigned int nl_addr_get_prefixlen(struct nl_addr *); + +/* Address Family Translations */ +extern char * nl_af2str(int, char *, size_t); +extern int nl_str2af(const char *); + +/* Translations to Strings */ +extern char * nl_addr2str(struct nl_addr *, char *, size_t); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/attr.h b/package/libs/libnl-tiny/src/include/netlink/attr.h new file mode 100644 index 0000000000..3b56a82dc6 --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/attr.h @@ -0,0 +1,726 @@ +/* + * netlink/attr.h Netlink Attributes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_ATTR_H_ +#define NETLINK_ATTR_H_ + +#include <netlink/netlink.h> +#include <netlink/object.h> +#include <netlink/addr.h> +#include <netlink/data.h> +#include <netlink/msg.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct nl_msg; + +/** + * @name Basic Attribute Data Types + * @{ + */ + + /** + * @ingroup attr + * Basic attribute data types + * + * See \ref attr_datatypes for more details. + */ +enum { + NLA_UNSPEC, /**< Unspecified type, binary data chunk */ + NLA_U8, /**< 8 bit integer */ + NLA_U16, /**< 16 bit integer */ + NLA_U32, /**< 32 bit integer */ + NLA_U64, /**< 64 bit integer */ + NLA_STRING, /**< NUL terminated character string */ + NLA_FLAG, /**< Flag */ + NLA_MSECS, /**< Micro seconds (64bit) */ + NLA_NESTED, /**< Nested attributes */ + __NLA_TYPE_MAX, +}; + +#define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1) + +/** @} */ + +/** + * @ingroup attr + * Attribute validation policy. + * + * See \ref attr_datatypes for more details. + */ +struct nla_policy { + /** Type of attribute or NLA_UNSPEC */ + uint16_t type; + + /** Minimal length of payload required */ + uint16_t minlen; + + /** Maximal length of payload allowed */ + uint16_t maxlen; +}; + +/* Attribute parsing */ +extern int nla_ok(const struct nlattr *, int); +extern struct nlattr * nla_next(const struct nlattr *, int *); +extern int nla_parse(struct nlattr **, int, struct nlattr *, + int, struct nla_policy *); +extern int nla_validate(struct nlattr *, int, int, + struct nla_policy *); +extern struct nlattr * nla_find(struct nlattr *, int, int); + +/* Unspecific attribute */ +extern struct nlattr * nla_reserve(struct nl_msg *, int, int); +extern int nla_put(struct nl_msg *, int, int, const void *); + +/** + * nlmsg_find_attr - find a specific attribute in a netlink message + * @arg nlh netlink message header + * @arg hdrlen length of familiy specific header + * @arg attrtype type of attribute to look for + * + * Returns the first attribute which matches the specified type. + */ +static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh, int hdrlen, int attrtype) +{ + return nla_find(nlmsg_attrdata(nlh, hdrlen), + nlmsg_attrlen(nlh, hdrlen), attrtype); +} + + +/** + * Return size of attribute whithout padding. + * @arg payload Payload length of attribute. + * + * @code + * <-------- nla_attr_size(payload) ---------> + * +------------------+- - -+- - - - - - - - - +- - -+ + * | Attribute Header | Pad | Payload | Pad | + * +------------------+- - -+- - - - - - - - - +- - -+ + * @endcode + * + * @return Size of attribute in bytes without padding. + */ +static inline int nla_attr_size(int payload) +{ + return NLA_HDRLEN + payload; +} + +/** + * Return size of attribute including padding. + * @arg payload Payload length of attribute. + * + * @code + * <----------- nla_total_size(payload) -----------> + * +------------------+- - -+- - - - - - - - - +- - -+ + * | Attribute Header | Pad | Payload | Pad | + * +------------------+- - -+- - - - - - - - - +- - -+ + * @endcode + * + * @return Size of attribute in bytes. + */ +static inline int nla_total_size(int payload) +{ + return NLA_ALIGN(nla_attr_size(payload)); +} + +/** + * Return length of padding at the tail of the attribute. + * @arg payload Payload length of attribute. + * + * @code + * +------------------+- - -+- - - - - - - - - +- - -+ + * | Attribute Header | Pad | Payload | Pad | + * +------------------+- - -+- - - - - - - - - +- - -+ + * <---> + * @endcode + * + * @return Length of padding in bytes. + */ +static inline int nla_padlen(int payload) +{ + return nla_total_size(payload) - nla_attr_size(payload); +} + +/** + * Return type of the attribute. + * @arg nla Attribute. + * + * @return Type of attribute. + */ +static inline int nla_type(const struct nlattr *nla) +{ + return nla->nla_type & NLA_TYPE_MASK; +} + +/** + * Return pointer to the payload section. + * @arg nla Attribute. + * + * @return Pointer to start of payload section. + */ +static inline void *nla_data(const struct nlattr *nla) +{ + return (char *) nla + NLA_HDRLEN; +} + +/** + * Return length of the payload . + * @arg nla Attribute + * + * @return Length of payload in bytes. + */ +static inline int nla_len(const struct nlattr *nla) +{ + return nla->nla_len - NLA_HDRLEN; +} + +/** + * Copy attribute payload to another memory area. + * @arg dest Pointer to destination memory area. + * @arg src Attribute + * @arg count Number of bytes to copy at most. + * + * Note: The number of bytes copied is limited by the length of + * the attribute payload. + * + * @return The number of bytes copied to dest. + */ +static inline int nla_memcpy(void *dest, struct nlattr *src, int count) +{ + int minlen; + + if (!src) + return 0; + + minlen = min_t(int, count, nla_len(src)); + memcpy(dest, nla_data(src), minlen); + + return minlen; +} + + +/** + * Add abstract data as unspecific attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg data Abstract data object. + * + * Equivalent to nla_put() except that the length of the payload is + * derived from the abstract data object. + * + * @see nla_put + * @return 0 on success or a negative error code. + */ +static inline int nla_put_data(struct nl_msg *msg, int attrtype, struct nl_data *data) +{ + return nla_put(msg, attrtype, nl_data_get_size(data), + nl_data_get(data)); +} + +/** + * Add abstract address as unspecific attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg addr Abstract address object. + * + * @see nla_put + * @return 0 on success or a negative error code. + */ +static inline int nla_put_addr(struct nl_msg *msg, int attrtype, struct nl_addr *addr) +{ + return nla_put(msg, attrtype, nl_addr_get_len(addr), + nl_addr_get_binary_addr(addr)); +} + +/** @} */ + +/** + * @name Integer Attributes + */ + +/** + * Add 8 bit integer attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg value Numeric value to store as payload. + * + * @see nla_put + * @return 0 on success or a negative error code. + */ +static inline int nla_put_u8(struct nl_msg *msg, int attrtype, uint8_t value) +{ + return nla_put(msg, attrtype, sizeof(uint8_t), &value); +} + +/** + * Return value of 8 bit integer attribute. + * @arg nla 8 bit integer attribute + * + * @return Payload as 8 bit integer. + */ +static inline uint8_t nla_get_u8(struct nlattr *nla) +{ + return *(uint8_t *) nla_data(nla); +} + +/** + * Add 16 bit integer attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg value Numeric value to store as payload. + * + * @see nla_put + * @return 0 on success or a negative error code. + */ +static inline int nla_put_u16(struct nl_msg *msg, int attrtype, uint16_t value) +{ + return nla_put(msg, attrtype, sizeof(uint16_t), &value); +} + +/** + * Return payload of 16 bit integer attribute. + * @arg nla 16 bit integer attribute + * + * @return Payload as 16 bit integer. + */ +static inline uint16_t nla_get_u16(struct nlattr *nla) +{ + return *(uint16_t *) nla_data(nla); +} + +/** + * Add 32 bit integer attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg value Numeric value to store as payload. + * + * @see nla_put + * @return 0 on success or a negative error code. + */ +static inline int nla_put_u32(struct nl_msg *msg, int attrtype, uint32_t value) +{ + return nla_put(msg, attrtype, sizeof(uint32_t), &value); +} + +/** + * Return payload of 32 bit integer attribute. + * @arg nla 32 bit integer attribute. + * + * @return Payload as 32 bit integer. + */ +static inline uint32_t nla_get_u32(struct nlattr *nla) +{ + return *(uint32_t *) nla_data(nla); +} + +/** + * Add 64 bit integer attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg value Numeric value to store as payload. + * + * @see nla_put + * @return 0 on success or a negative error code. + */ +static inline int nla_put_u64(struct nl_msg *msg, int attrtype, uint64_t value) +{ + return nla_put(msg, attrtype, sizeof(uint64_t), &value); +} + +/** + * Return payload of u64 attribute + * @arg nla u64 netlink attribute + * + * @return Payload as 64 bit integer. + */ +static inline uint64_t nla_get_u64(struct nlattr *nla) +{ + uint64_t tmp; + + nla_memcpy(&tmp, nla, sizeof(tmp)); + + return tmp; +} + +/** + * Add string attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg str NUL terminated string. + * + * @see nla_put + * @return 0 on success or a negative error code. + */ +static inline int nla_put_string(struct nl_msg *msg, int attrtype, const char *str) +{ + return nla_put(msg, attrtype, strlen(str) + 1, str); +} + +/** + * Return payload of string attribute. + * @arg nla String attribute. + * + * @return Pointer to attribute payload. + */ +static inline char *nla_get_string(struct nlattr *nla) +{ + return (char *) nla_data(nla); +} + +static inline char *nla_strdup(struct nlattr *nla) +{ + return strdup(nla_get_string(nla)); +} + +/** @} */ + +/** + * @name Flag Attribute + */ + +/** + * Add flag netlink attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * + * @see nla_put + * @return 0 on success or a negative error code. + */ +static inline int nla_put_flag(struct nl_msg *msg, int attrtype) +{ + return nla_put(msg, attrtype, 0, NULL); +} + +/** + * Return true if flag attribute is set. + * @arg nla Flag netlink attribute. + * + * @return True if flag is set, otherwise false. + */ +static inline int nla_get_flag(struct nlattr *nla) +{ + return !!nla; +} + +/** @} */ + +/** + * @name Microseconds Attribute + */ + +/** + * Add a msecs netlink attribute to a netlink message + * @arg n netlink message + * @arg attrtype attribute type + * @arg msecs number of msecs + */ +static inline int nla_put_msecs(struct nl_msg *n, int attrtype, unsigned long msecs) +{ + return nla_put_u64(n, attrtype, msecs); +} + +/** + * Return payload of msecs attribute + * @arg nla msecs netlink attribute + * + * @return the number of milliseconds. + */ +static inline unsigned long nla_get_msecs(struct nlattr *nla) +{ + return nla_get_u64(nla); +} + +/** + * Add nested attributes to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg nested Message containing attributes to be nested. + * + * Takes the attributes found in the \a nested message and appends them + * to the message \a msg nested in a container of the type \a attrtype. + * The \a nested message may not have a family specific header. + * + * @see nla_put + * @return 0 on success or a negative error code. + */ +static inline int nla_put_nested(struct nl_msg *msg, int attrtype, struct nl_msg *nested) +{ + return nla_put(msg, attrtype, nlmsg_len(nested->nm_nlh), + nlmsg_data(nested->nm_nlh)); +} + +/** + * Start a new level of nested attributes. + * @arg msg Netlink message. + * @arg attrtype Attribute type of container. + * + * @return Pointer to container attribute. + */ +static inline struct nlattr *nla_nest_start(struct nl_msg *msg, int attrtype) +{ + struct nlattr *start = (struct nlattr *) nlmsg_tail(msg->nm_nlh); + + if (nla_put(msg, attrtype, 0, NULL) < 0) + return NULL; + + return start; +} + +/** + * Finalize nesting of attributes. + * @arg msg Netlink message. + * @arg start Container attribute as returned from nla_nest_start(). + * + * Corrects the container attribute header to include the appeneded attributes. + * + * @return 0 + */ +static inline int nla_nest_end(struct nl_msg *msg, struct nlattr *start) +{ + start->nla_len = (unsigned char *) nlmsg_tail(msg->nm_nlh) - + (unsigned char *) start; + return 0; +} + +/** + * Create attribute index based on nested attribute + * @arg tb Index array to be filled (maxtype+1 elements). + * @arg maxtype Maximum attribute type expected and accepted. + * @arg nla Nested Attribute. + * @arg policy Attribute validation policy. + * + * Feeds the stream of attributes nested into the specified attribute + * to nla_parse(). + * + * @see nla_parse + * @return 0 on success or a negative error code. + */ +static inline int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, + struct nla_policy *policy) +{ + return nla_parse(tb, maxtype, (struct nlattr *)nla_data(nla), nla_len(nla), policy); +} + +/** + * Compare attribute payload with memory area. + * @arg nla Attribute. + * @arg data Memory area to compare to. + * @arg size Number of bytes to compare. + * + * @see memcmp(3) + * @return An integer less than, equal to, or greater than zero. + */ +static inline int nla_memcmp(const struct nlattr *nla, const void *data, size_t size) +{ + int d = nla_len(nla) - size; + + if (d == 0) + d = memcmp(nla_data(nla), data, size); + + return d; +} + +/** + * Compare string attribute payload with string + * @arg nla Attribute of type NLA_STRING. + * @arg str NUL terminated string. + * + * @see strcmp(3) + * @return An integer less than, equal to, or greater than zero. + */ +static inline int nla_strcmp(const struct nlattr *nla, const char *str) +{ + int len = strlen(str) + 1; + int d = nla_len(nla) - len; + + if (d == 0) + d = memcmp(nla_data(nla), str, len); + + return d; +} + +/** + * Copy string attribute payload to a buffer. + * @arg dst Pointer to destination buffer. + * @arg nla Attribute of type NLA_STRING. + * @arg dstsize Size of destination buffer in bytes. + * + * Copies at most dstsize - 1 bytes to the destination buffer. + * The result is always a valid NUL terminated string. Unlike + * strlcpy the destination buffer is always padded out. + * + * @return The length of string attribute without the terminating NUL. + */ +static inline size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize) +{ + size_t srclen = (size_t)nla_len(nla); + char *src = (char*)nla_data(nla); + + if (srclen > 0 && src[srclen - 1] == '\0') + srclen--; + + if (dstsize > 0) { + size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen; + + memset(dst, 0, dstsize); + memcpy(dst, src, len); + } + + return srclen; +} + + +/** + * @name Attribute Construction (Exception Based) + * @{ + */ + +/** + * @ingroup attr + * Add unspecific attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg attrlen Length of attribute payload. + * @arg data Head of attribute payload. + */ +#define NLA_PUT(msg, attrtype, attrlen, data) \ + do { \ + if (nla_put(msg, attrtype, attrlen, data) < 0) \ + goto nla_put_failure; \ + } while(0) + +/** + * @ingroup attr + * Add atomic type attribute to netlink message. + * @arg msg Netlink message. + * @arg type Atomic type. + * @arg attrtype Attribute type. + * @arg value Head of attribute payload. + */ +#define NLA_PUT_TYPE(msg, type, attrtype, value) \ + do { \ + type __tmp = value; \ + NLA_PUT(msg, attrtype, sizeof(type), &__tmp); \ + } while(0) + +/** + * Add 8 bit integer attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg value Numeric value. + */ +#define NLA_PUT_U8(msg, attrtype, value) \ + NLA_PUT_TYPE(msg, uint8_t, attrtype, value) + +/** + * Add 16 bit integer attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg value Numeric value. + */ +#define NLA_PUT_U16(msg, attrtype, value) \ + NLA_PUT_TYPE(msg, uint16_t, attrtype, value) + +/** + * Add 32 bit integer attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg value Numeric value. + */ +#define NLA_PUT_U32(msg, attrtype, value) \ + NLA_PUT_TYPE(msg, uint32_t, attrtype, value) + +/** + * Add 64 bit integer attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg value Numeric value. + */ +#define NLA_PUT_U64(msg, attrtype, value) \ + NLA_PUT_TYPE(msg, uint64_t, attrtype, value) + +/** + * Add string attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg value NUL terminated character string. + */ +#define NLA_PUT_STRING(msg, attrtype, value) \ + NLA_PUT(msg, attrtype, strlen(value) + 1, value) + +/** + * Add flag attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + */ +#define NLA_PUT_FLAG(msg, attrtype) \ + NLA_PUT(msg, attrtype, 0, NULL) + +/** + * Add msecs attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg msecs Numeric value in micro seconds. + */ +#define NLA_PUT_MSECS(msg, attrtype, msecs) \ + NLA_PUT_U64(msg, attrtype, msecs) + +/** + * Add address attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg addr Abstract address object. + */ +#define NLA_PUT_ADDR(msg, attrtype, addr) \ + NLA_PUT(msg, attrtype, nl_addr_get_len(addr), \ + nl_addr_get_binary_addr(addr)) + +/** @} */ + +/** + * @name Iterators + * @{ + */ + +/** + * @ingroup attr + * Iterate over a stream of attributes + * @arg pos loop counter, set to current attribute + * @arg head head of attribute stream + * @arg len length of attribute stream + * @arg rem initialized to len, holds bytes currently remaining in stream + */ +#define nla_for_each_attr(pos, head, len, rem) \ + for (pos = head, rem = len; \ + nla_ok(pos, rem); \ + pos = nla_next(pos, &(rem))) + +/** + * @ingroup attr + * Iterate over a stream of nested attributes + * @arg pos loop counter, set to current attribute + * @arg nla attribute containing the nested attributes + * @arg rem initialized to len, holds bytes currently remaining in stream + */ +#define nla_for_each_nested(pos, nla, rem) \ + for (pos = (struct nlattr *)nla_data(nla), rem = nla_len(nla); \ + nla_ok(pos, rem); \ + pos = nla_next(pos, &(rem))) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/cache-api.h b/package/libs/libnl-tiny/src/include/netlink/cache-api.h new file mode 100644 index 0000000000..22fc449d1b --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/cache-api.h @@ -0,0 +1,199 @@ +/* + * netlink/cache-api.h Caching API + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_CACHE_API_H_ +#define NETLINK_CACHE_API_H_ + +#include <netlink/netlink.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup cache + * @defgroup cache_api Cache Implementation + * @brief + * + * @par 1) Cache Definition + * @code + * struct nl_cache_ops my_cache_ops = { + * .co_name = "route/link", + * .co_protocol = NETLINK_ROUTE, + * .co_hdrsize = sizeof(struct ifinfomsg), + * .co_obj_ops = &my_obj_ops, + * }; + * @endcode + * + * @par 2) + * @code + * // The simplest way to fill a cache is by providing a request-update + * // function which must trigger a complete dump on the kernel-side of + * // whatever the cache covers. + * static int my_request_update(struct nl_cache *cache, + * struct nl_sock *socket) + * { + * // In this example, we request a full dump of the interface table + * return nl_rtgen_request(socket, RTM_GETLINK, AF_UNSPEC, NLM_F_DUMP); + * } + * + * // The resulting netlink messages sent back will be fed into a message + * // parser one at a time. The message parser has to extract all relevant + * // information from the message and create an object reflecting the + * // contents of the message and pass it on to the parser callback function + * // provide which will add the object to the cache. + * static int my_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, + * struct nlmsghdr *nlh, struct nl_parser_param *pp) + * { + * struct my_obj *obj; + * + * obj = my_obj_alloc(); + * obj->ce_msgtype = nlh->nlmsg_type; + * + * // Parse the netlink message and continue creating the object. + * + * err = pp->pp_cb((struct nl_object *) obj, pp); + * if (err < 0) + * goto errout; + * } + * + * struct nl_cache_ops my_cache_ops = { + * ... + * .co_request_update = my_request_update, + * .co_msg_parser = my_msg_parser, + * }; + * @endcode + * + * @par 3) Notification based Updates + * @code + * // Caches can be kept up-to-date based on notifications if the kernel + * // sends out notifications whenever an object is added/removed/changed. + * // + * // It is trivial to support this, first a list of groups needs to be + * // defined which are required to join in order to receive all necessary + * // notifications. The groups are separated by address family to support + * // the common situation where a separate group is used for each address + * // family. If there is only one group, simply specify AF_UNSPEC. + * static struct nl_af_group addr_groups[] = { + * { AF_INET, RTNLGRP_IPV4_IFADDR }, + * { AF_INET6, RTNLGRP_IPV6_IFADDR }, + * { END_OF_GROUP_LIST }, + * }; + * + * // In order for the caching system to know the meaning of each message + * // type it requires a table which maps each supported message type to + * // a cache action, e.g. RTM_NEWADDR means address has been added or + * // updated, RTM_DELADDR means address has been removed. + * static struct nl_cache_ops rtnl_addr_ops = { + * ... + * .co_msgtypes = { + * { RTM_NEWADDR, NL_ACT_NEW, "new" }, + * { RTM_DELADDR, NL_ACT_DEL, "del" }, + * { RTM_GETADDR, NL_ACT_GET, "get" }, + * END_OF_MSGTYPES_LIST, + * }, + * .co_groups = addr_groups, + * }; + * + * // It is now possible to keep the cache up-to-date using the cache manager. + * @endcode + * @{ + */ + +enum { + NL_ACT_UNSPEC, + NL_ACT_NEW, + NL_ACT_DEL, + NL_ACT_GET, + NL_ACT_SET, + NL_ACT_CHANGE, + __NL_ACT_MAX, +}; + +#define NL_ACT_MAX (__NL_ACT_MAX - 1) + +#define END_OF_MSGTYPES_LIST { -1, -1, NULL } + +/** + * Message type to cache action association + */ +struct nl_msgtype +{ + /** Netlink message type */ + int mt_id; + + /** Cache action to take */ + int mt_act; + + /** Name of operation for human-readable printing */ + char * mt_name; +}; + +/** + * Address family to netlink group association + */ +struct nl_af_group +{ + /** Address family */ + int ag_family; + + /** Netlink group identifier */ + int ag_group; +}; + +#define END_OF_GROUP_LIST AF_UNSPEC, 0 + +struct nl_parser_param +{ + int (*pp_cb)(struct nl_object *, struct nl_parser_param *); + void * pp_arg; +}; + +/** + * Cache Operations + */ +struct nl_cache_ops +{ + char * co_name; + + int co_hdrsize; + int co_protocol; + struct nl_af_group * co_groups; + + /** + * Called whenever an update of the cache is required. Must send + * a request message to the kernel requesting a complete dump. + */ + int (*co_request_update)(struct nl_cache *, struct nl_sock *); + + /** + * Called whenever a message was received that needs to be parsed. + * Must parse the message and call the paser callback function + * (nl_parser_param) provided via the argument. + */ + int (*co_msg_parser)(struct nl_cache_ops *, struct sockaddr_nl *, + struct nlmsghdr *, struct nl_parser_param *); + + struct nl_object_ops * co_obj_ops; + + struct nl_cache_ops *co_next; + struct nl_cache *co_major_cache; + struct genl_ops * co_genl; + struct nl_msgtype co_msgtypes[]; +}; + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/cache.h b/package/libs/libnl-tiny/src/include/netlink/cache.h new file mode 100644 index 0000000000..09719f3a74 --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/cache.h @@ -0,0 +1,128 @@ +/* + * netlink/cache.h Caching Module + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_CACHE_H_ +#define NETLINK_CACHE_H_ + +#include <netlink/netlink.h> +#include <netlink/msg.h> +#include <netlink/utils.h> +#include <netlink/object.h> +#include <netlink/cache-api.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct nl_cache; + +typedef void (*change_func_t)(struct nl_cache *, struct nl_object *, int); + +/* Access Functions */ +extern int nl_cache_nitems(struct nl_cache *); +extern int nl_cache_nitems_filter(struct nl_cache *, + struct nl_object *); +extern struct nl_cache_ops * nl_cache_get_ops(struct nl_cache *); +extern struct nl_object * nl_cache_get_first(struct nl_cache *); +extern struct nl_object * nl_cache_get_last(struct nl_cache *); +extern struct nl_object * nl_cache_get_next(struct nl_object *); +extern struct nl_object * nl_cache_get_prev(struct nl_object *); + +extern struct nl_cache * nl_cache_alloc(struct nl_cache_ops *); +extern int nl_cache_alloc_and_fill(struct nl_cache_ops *, + struct nl_sock *, + struct nl_cache **); +extern int nl_cache_alloc_name(const char *, + struct nl_cache **); +extern struct nl_cache * nl_cache_subset(struct nl_cache *, + struct nl_object *); +extern void nl_cache_clear(struct nl_cache *); +extern void nl_cache_free(struct nl_cache *); + +/* Cache modification */ +extern int nl_cache_add(struct nl_cache *, + struct nl_object *); +extern int nl_cache_parse_and_add(struct nl_cache *, + struct nl_msg *); +extern void nl_cache_remove(struct nl_object *); +extern int nl_cache_refill(struct nl_sock *, + struct nl_cache *); +extern int nl_cache_pickup(struct nl_sock *, + struct nl_cache *); +extern int nl_cache_resync(struct nl_sock *, + struct nl_cache *, + change_func_t); +extern int nl_cache_include(struct nl_cache *, + struct nl_object *, + change_func_t); + +/* General */ +extern int nl_cache_is_empty(struct nl_cache *); +extern void nl_cache_mark_all(struct nl_cache *); + +/* Dumping */ +extern void nl_cache_dump(struct nl_cache *, + struct nl_dump_params *); +extern void nl_cache_dump_filter(struct nl_cache *, + struct nl_dump_params *, + struct nl_object *); + +/* Iterators */ +#ifdef disabled +extern void nl_cache_foreach(struct nl_cache *, + void (*cb)(struct nl_object *, + void *), + void *arg); +extern void nl_cache_foreach_filter(struct nl_cache *, + struct nl_object *, + void (*cb)(struct + nl_object *, + void *), + void *arg); +#endif + +/* --- cache management --- */ + +/* Cache type management */ +extern struct nl_cache_ops * nl_cache_ops_lookup(const char *); +extern struct nl_cache_ops * nl_cache_ops_associate(int, int); +extern struct nl_msgtype * nl_msgtype_lookup(struct nl_cache_ops *, int); +extern void nl_cache_ops_foreach(void (*cb)(struct nl_cache_ops *, void *), void *); +extern int nl_cache_mngt_register(struct nl_cache_ops *); +extern int nl_cache_mngt_unregister(struct nl_cache_ops *); + +/* Global cache provisioning/requiring */ +extern void nl_cache_mngt_provide(struct nl_cache *); +extern void nl_cache_mngt_unprovide(struct nl_cache *); +extern struct nl_cache * nl_cache_mngt_require(const char *); + +struct nl_cache_mngr; + +#define NL_AUTO_PROVIDE 1 + +extern int nl_cache_mngr_alloc(struct nl_sock *, + int, int, + struct nl_cache_mngr **); +extern int nl_cache_mngr_add(struct nl_cache_mngr *, + const char *, + change_func_t, + struct nl_cache **); +extern int nl_cache_mngr_get_fd(struct nl_cache_mngr *); +extern int nl_cache_mngr_poll(struct nl_cache_mngr *, + int); +extern int nl_cache_mngr_data_ready(struct nl_cache_mngr *); +extern void nl_cache_mngr_free(struct nl_cache_mngr *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/data.h b/package/libs/libnl-tiny/src/include/netlink/data.h new file mode 100644 index 0000000000..071159ee5b --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/data.h @@ -0,0 +1,41 @@ +/* + * netlink/data.h Abstract Data + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_DATA_H_ +#define NETLINK_DATA_H_ + +#include <netlink/netlink.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct nl_data; + +/* General */ +extern struct nl_data * nl_data_alloc(void *, size_t); +extern struct nl_data * nl_data_alloc_attr(struct nlattr *); +extern struct nl_data * nl_data_clone(struct nl_data *); +extern int nl_data_append(struct nl_data *, void *, size_t); +extern void nl_data_free(struct nl_data *); + +/* Access Functions */ +extern void * nl_data_get(struct nl_data *); +extern size_t nl_data_get_size(struct nl_data *); + +/* Misc */ +extern int nl_data_cmp(struct nl_data *, struct nl_data *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/errno.h b/package/libs/libnl-tiny/src/include/netlink/errno.h new file mode 100644 index 0000000000..0b43da02a9 --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/errno.h @@ -0,0 +1,59 @@ +/* + * netlink/errno.h Error Numbers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2008 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_ERRNO_H_ +#define NETLINK_ERRNO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define NLE_SUCCESS 0 +#define NLE_FAILURE 1 +#define NLE_INTR 2 +#define NLE_BAD_SOCK 3 +#define NLE_AGAIN 4 +#define NLE_NOMEM 5 +#define NLE_EXIST 6 +#define NLE_INVAL 7 +#define NLE_RANGE 8 +#define NLE_MSGSIZE 9 +#define NLE_OPNOTSUPP 10 +#define NLE_AF_NOSUPPORT 11 +#define NLE_OBJ_NOTFOUND 12 +#define NLE_NOATTR 13 +#define NLE_MISSING_ATTR 14 +#define NLE_AF_MISMATCH 15 +#define NLE_SEQ_MISMATCH 16 +#define NLE_MSG_OVERFLOW 17 +#define NLE_MSG_TRUNC 18 +#define NLE_NOADDR 19 +#define NLE_SRCRT_NOSUPPORT 20 +#define NLE_MSG_TOOSHORT 21 +#define NLE_MSGTYPE_NOSUPPORT 22 +#define NLE_OBJ_MISMATCH 23 +#define NLE_NOCACHE 24 +#define NLE_BUSY 25 +#define NLE_PROTO_MISMATCH 26 +#define NLE_NOACCESS 27 +#define NLE_PERM 28 + +#define NLE_MAX NLE_PERM + +extern const char * nl_geterror(int); +extern void nl_perror(int, const char *); +extern int nl_syserr2nlerr(int); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/genl/ctrl.h b/package/libs/libnl-tiny/src/include/netlink/genl/ctrl.h new file mode 100644 index 0000000000..1ae62f4480 --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/genl/ctrl.h @@ -0,0 +1,37 @@ +/* + * netlink/genl/ctrl.h Generic Netlink Controller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_GENL_CTRL_H_ +#define NETLINK_GENL_CTRL_H_ + +#include <netlink/netlink.h> +#include <netlink/cache.h> +#include <netlink/addr.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct genl_family; + +extern int genl_ctrl_alloc_cache(struct nl_sock *, + struct nl_cache **); +extern struct genl_family * genl_ctrl_search(struct nl_cache *, int); +extern struct genl_family * genl_ctrl_search_by_name(struct nl_cache *, + const char *); +extern int genl_ctrl_resolve(struct nl_sock *, + const char *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/genl/family.h b/package/libs/libnl-tiny/src/include/netlink/genl/family.h new file mode 100644 index 0000000000..0257cbe273 --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/genl/family.h @@ -0,0 +1,130 @@ +/* + * netlink/genl/family.h Generic Netlink Family + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_GENL_FAMILY_H_ +#define NETLINK_GENL_FAMILY_H_ + +#include <netlink/netlink.h> +#include <netlink/cache.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond SKIP */ +#define FAMILY_ATTR_ID 0x01 +#define FAMILY_ATTR_NAME 0x02 +#define FAMILY_ATTR_VERSION 0x04 +#define FAMILY_ATTR_HDRSIZE 0x08 +#define FAMILY_ATTR_MAXATTR 0x10 +#define FAMILY_ATTR_OPS 0x20 + + +struct genl_family +{ + NLHDR_COMMON + + uint16_t gf_id; + char gf_name[GENL_NAMSIZ]; + uint32_t gf_version; + uint32_t gf_hdrsize; + uint32_t gf_maxattr; + + struct nl_list_head gf_ops; +}; + + +extern struct genl_family * genl_family_alloc(void); +extern void genl_family_put(struct genl_family *); + +extern int genl_family_add_op(struct genl_family *, + int, int); + +/** + * @name Attributes + * @{ + */ + +static inline unsigned int genl_family_get_id(struct genl_family *family) +{ + if (family->ce_mask & FAMILY_ATTR_ID) + return family->gf_id; + else + return GENL_ID_GENERATE; +} + +static inline void genl_family_set_id(struct genl_family *family, unsigned int id) +{ + family->gf_id = id; + family->ce_mask |= FAMILY_ATTR_ID; +} + +static inline char *genl_family_get_name(struct genl_family *family) +{ + if (family->ce_mask & FAMILY_ATTR_NAME) + return family->gf_name; + else + return NULL; +} + +static inline void genl_family_set_name(struct genl_family *family, const char *name) +{ + strncpy(family->gf_name, name, GENL_NAMSIZ-1); + family->ce_mask |= FAMILY_ATTR_NAME; +} + +static inline uint8_t genl_family_get_version(struct genl_family *family) +{ + if (family->ce_mask & FAMILY_ATTR_VERSION) + return family->gf_version; + else + return 0; +} + +static inline void genl_family_set_version(struct genl_family *family, uint8_t version) +{ + family->gf_version = version; + family->ce_mask |= FAMILY_ATTR_VERSION; +} + +static inline uint32_t genl_family_get_hdrsize(struct genl_family *family) +{ + if (family->ce_mask & FAMILY_ATTR_HDRSIZE) + return family->gf_hdrsize; + else + return 0; +} + +static inline void genl_family_set_hdrsize(struct genl_family *family, uint32_t hdrsize) +{ + family->gf_hdrsize = hdrsize; + family->ce_mask |= FAMILY_ATTR_HDRSIZE; +} + +static inline uint32_t genl_family_get_maxattr(struct genl_family *family) +{ + if (family->ce_mask & FAMILY_ATTR_MAXATTR) + return family->gf_maxattr; + else + return family->gf_maxattr; +} + +static inline void genl_family_set_maxattr(struct genl_family *family, uint32_t maxattr) +{ + family->gf_maxattr = maxattr; + family->ce_mask |= FAMILY_ATTR_MAXATTR; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/genl/genl.h b/package/libs/libnl-tiny/src/include/netlink/genl/genl.h new file mode 100644 index 0000000000..3f3340cfdc --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/genl/genl.h @@ -0,0 +1,47 @@ +/* + * netlink/genl/genl.h Generic Netlink + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_GENL_H_ +#define NETLINK_GENL_H_ + +#include <netlink/netlink.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#ifdef __cplusplus +extern "C" { +#endif + +extern int genl_connect(struct nl_sock *); + +extern int genl_send_simple(struct nl_sock *, int, int, + int, int); + +extern void * genlmsg_put(struct nl_msg *, uint32_t, uint32_t, + int, int, int, uint8_t, uint8_t); + +extern int genlmsg_valid_hdr(struct nlmsghdr *, int); +extern int genlmsg_validate(struct nlmsghdr *, int, int, + struct nla_policy *); +extern int genlmsg_parse(struct nlmsghdr *, int, struct nlattr **, + int, struct nla_policy *); +extern void * genlmsg_data(const struct genlmsghdr *); +extern int genlmsg_len(const struct genlmsghdr *); +extern struct nlattr * genlmsg_attrdata(const struct genlmsghdr *, int); +extern int genlmsg_attrlen(const struct genlmsghdr *, int); + +extern char * genl_op2name(int, int, char *, size_t); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/genl/mngt.h b/package/libs/libnl-tiny/src/include/netlink/genl/mngt.h new file mode 100644 index 0000000000..8b0244f2cc --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/genl/mngt.h @@ -0,0 +1,87 @@ +/* + * netlink/genl/mngt.h Generic Netlink Management + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_GENL_MNGT_H_ +#define NETLINK_GENL_MNGT_H_ + +#include <netlink/netlink.h> +#include <netlink/attr.h> +#include <netlink/list.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct nl_cache_ops; + +struct genl_info +{ + struct sockaddr_nl * who; + struct nlmsghdr * nlh; + struct genlmsghdr * genlhdr; + void * userhdr; + struct nlattr ** attrs; +}; + +/** + * @ingroup genl_mngt + * Generic Netlink Command + */ +struct genl_cmd +{ + /** Unique command identifier */ + int c_id; + + /** Name/description of command */ + char * c_name; + + /** + * Maximum attribute identifier, must be provided if + * a message parser is available. + */ + int c_maxattr; + + int (*c_msg_parser)(struct nl_cache_ops *, + struct genl_cmd *, + struct genl_info *, void *); + + /** + * Attribute validation policy (optional) + */ + struct nla_policy * c_attr_policy; +}; + +/** + * @ingroup genl_mngt + * Generic Netlink Operations + */ +struct genl_ops +{ + int o_family; + int o_id; + char * o_name; + struct nl_cache_ops * o_cache_ops; + struct genl_cmd * o_cmds; + int o_ncmds; + + /* linked list of all genl cache operations */ + struct nl_list_head o_list; +}; + + +extern int genl_register(struct nl_cache_ops *); +extern void genl_unregister(struct nl_cache_ops *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/handlers.h b/package/libs/libnl-tiny/src/include/netlink/handlers.h new file mode 100644 index 0000000000..7fb53b4eee --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/handlers.h @@ -0,0 +1,230 @@ +/* + * netlink/handlers.c default netlink message handlers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_HANDLERS_H_ +#define NETLINK_HANDLERS_H_ + +#include <stdio.h> +#include <stdint.h> +#include <sys/types.h> +#include <netlink/netlink-compat.h> +#include <netlink/netlink-kernel.h> +#include <netlink/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct nl_sock; +struct nl_msg; +struct nl_cb; +/** + * @name Callback Typedefs + * @{ + */ + +/** + * nl_recvmsgs() callback for message processing customization + * @ingroup cb + * @arg msg netlink message being processed + * @arg arg argument passwd on through caller + */ +typedef int (*nl_recvmsg_msg_cb_t)(struct nl_msg *msg, void *arg); + +/** + * nl_recvmsgs() callback for error message processing customization + * @ingroup cb + * @arg nla netlink address of the peer + * @arg nlerr netlink error message being processed + * @arg arg argument passed on through caller + */ +typedef int (*nl_recvmsg_err_cb_t)(struct sockaddr_nl *nla, + struct nlmsgerr *nlerr, void *arg); + +/** @} */ + +/** + * Callback actions + * @ingroup cb + */ +enum nl_cb_action { + /** Proceed with wathever would come next */ + NL_OK, + /** Skip this message */ + NL_SKIP, + /** Stop parsing altogether and discard remaining messages */ + NL_STOP, +}; + +/** + * Callback kinds + * @ingroup cb + */ +enum nl_cb_kind { + /** Default handlers (quiet) */ + NL_CB_DEFAULT, + /** Verbose default handlers (error messages printed) */ + NL_CB_VERBOSE, + /** Debug handlers for debugging */ + NL_CB_DEBUG, + /** Customized handler specified by the user */ + NL_CB_CUSTOM, + __NL_CB_KIND_MAX, +}; + +#define NL_CB_KIND_MAX (__NL_CB_KIND_MAX - 1) + +/** + * Callback types + * @ingroup cb + */ +enum nl_cb_type { + /** Message is valid */ + NL_CB_VALID, + /** Last message in a series of multi part messages received */ + NL_CB_FINISH, + /** Report received that data was lost */ + NL_CB_OVERRUN, + /** Message wants to be skipped */ + NL_CB_SKIPPED, + /** Message is an acknowledge */ + NL_CB_ACK, + /** Called for every message received */ + NL_CB_MSG_IN, + /** Called for every message sent out except for nl_sendto() */ + NL_CB_MSG_OUT, + /** Message is malformed and invalid */ + NL_CB_INVALID, + /** Called instead of internal sequence number checking */ + NL_CB_SEQ_CHECK, + /** Sending of an acknowledge message has been requested */ + NL_CB_SEND_ACK, + __NL_CB_TYPE_MAX, +}; + +#define NL_CB_TYPE_MAX (__NL_CB_TYPE_MAX - 1) + +struct nl_cb +{ + nl_recvmsg_msg_cb_t cb_set[NL_CB_TYPE_MAX+1]; + void * cb_args[NL_CB_TYPE_MAX+1]; + + nl_recvmsg_err_cb_t cb_err; + void * cb_err_arg; + + /** May be used to replace nl_recvmsgs with your own implementation + * in all internal calls to nl_recvmsgs. */ + int (*cb_recvmsgs_ow)(struct nl_sock *, + struct nl_cb *); + + /** Overwrite internal calls to nl_recv, must return the number of + * octets read and allocate a buffer for the received data. */ + int (*cb_recv_ow)(struct nl_sock *, + struct sockaddr_nl *, + unsigned char **, + struct ucred **); + + /** Overwrites internal calls to nl_send, must send the netlink + * message. */ + int (*cb_send_ow)(struct nl_sock *, + struct nl_msg *); + + int cb_refcnt; +}; + + +extern struct nl_cb * nl_cb_alloc(enum nl_cb_kind); +extern struct nl_cb * nl_cb_clone(struct nl_cb *); +extern void nl_cb_put(struct nl_cb *); + +extern int nl_cb_set(struct nl_cb *, enum nl_cb_type, enum nl_cb_kind, + nl_recvmsg_msg_cb_t, void *); +extern int nl_cb_err(struct nl_cb *, enum nl_cb_kind, nl_recvmsg_err_cb_t, + void *); + +static inline struct nl_cb *nl_cb_get(struct nl_cb *cb) +{ + cb->cb_refcnt++; + + return cb; +} + +/** + * Set up a all callbacks + * @arg cb callback set + * @arg kind kind of callback + * @arg func callback function + * @arg arg argument to be passwd to callback function + * + * @return 0 on success or a negative error code + */ +static inline int nl_cb_set_all(struct nl_cb *cb, enum nl_cb_kind kind, + nl_recvmsg_msg_cb_t func, void *arg) +{ + int i, err; + + for (i = 0; i <= NL_CB_TYPE_MAX; i++) { + err = nl_cb_set(cb,(enum nl_cb_type)i, kind, func, arg); + if (err < 0) + return err; + } + + return 0; +} + + +/** + * @name Overwriting + * @{ + */ + +/** + * Overwrite internal calls to nl_recvmsgs() + * @arg cb callback set + * @arg func replacement callback for nl_recvmsgs() + */ +static inline void nl_cb_overwrite_recvmsgs(struct nl_cb *cb, + int (*func)(struct nl_sock *, struct nl_cb *)) +{ + cb->cb_recvmsgs_ow = func; +} + +/** + * Overwrite internal calls to nl_recv() + * @arg cb callback set + * @arg func replacement callback for nl_recv() + */ +static inline void nl_cb_overwrite_recv(struct nl_cb *cb, + int (*func)(struct nl_sock *, struct sockaddr_nl *, + unsigned char **, struct ucred **)) +{ + cb->cb_recv_ow = func; +} + +/** + * Overwrite internal calls to nl_send() + * @arg cb callback set + * @arg func replacement callback for nl_send() + */ +static inline void nl_cb_overwrite_send(struct nl_cb *cb, + int (*func)(struct nl_sock *, struct nl_msg *)) +{ + cb->cb_send_ow = func; +} + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/list.h b/package/libs/libnl-tiny/src/include/netlink/list.h new file mode 100644 index 0000000000..c6876a77f7 --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/list.h @@ -0,0 +1,88 @@ +/* + * netlink/list.h Netlink List Utilities + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_LIST_H_ +#define NETLINK_LIST_H_ + +struct nl_list_head +{ + struct nl_list_head * next; + struct nl_list_head * prev; +}; + + +static inline void __nl_list_add(struct nl_list_head *obj, + struct nl_list_head *prev, + struct nl_list_head *next) +{ + prev->next = obj; + obj->prev = prev; + next->prev = obj; + obj->next = next; +} + +static inline void nl_list_add_tail(struct nl_list_head *obj, + struct nl_list_head *head) +{ + __nl_list_add(obj, head->prev, head); +} + +static inline void nl_list_add_head(struct nl_list_head *obj, + struct nl_list_head *head) +{ + __nl_list_add(obj, head, head->next); +} + +static inline void nl_list_del(struct nl_list_head *obj) +{ + obj->next->prev = obj->prev; + obj->prev->next = obj->next; +} + +static inline int nl_list_empty(struct nl_list_head *head) +{ + return head->next == head; +} + +#define nl_container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - ((size_t) &((type *)0)->member));}) + +#define nl_list_entry(ptr, type, member) \ + nl_container_of(ptr, type, member) + +#define nl_list_at_tail(pos, head, member) \ + ((pos)->member.next == (head)) + +#define nl_list_at_head(pos, head, member) \ + ((pos)->member.prev == (head)) + +#define NL_LIST_HEAD(name) \ + struct nl_list_head name = { &(name), &(name) } + +#define nl_list_first_entry(head, type, member) \ + nl_list_entry((head)->next, type, member) + +#define nl_list_for_each_entry(pos, head, member) \ + for (pos = nl_list_entry((head)->next, typeof(*pos), member); \ + &(pos)->member != (head); \ + (pos) = nl_list_entry((pos)->member.next, typeof(*(pos)), member)) + +#define nl_list_for_each_entry_safe(pos, n, head, member) \ + for (pos = nl_list_entry((head)->next, typeof(*pos), member), \ + n = nl_list_entry(pos->member.next, typeof(*pos), member); \ + &(pos)->member != (head); \ + pos = n, n = nl_list_entry(n->member.next, typeof(*n), member)) + +#define nl_init_list_head(head) \ + do { (head)->next = (head); (head)->prev = (head); } while (0) + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/msg.h b/package/libs/libnl-tiny/src/include/netlink/msg.h new file mode 100644 index 0000000000..b3e2b0b2b9 --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/msg.h @@ -0,0 +1,308 @@ +/* + * netlink/msg.c Netlink Messages Interface + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_MSG_H_ +#define NETLINK_MSG_H_ + +#include <netlink/netlink.h> +#include <netlink/object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct nla_policy; + +#define NL_DONTPAD 0 + +/** + * @ingroup msg + * @brief + * Will cause the netlink pid to be set to the pid assigned to + * the netlink handle (socket) just before sending the message off. + * @note Requires the use of nl_send_auto_complete()! + */ +#define NL_AUTO_PID 0 + +/** + * @ingroup msg + * @brief + * May be used to refer to a sequence number which should be + * automatically set just before sending the message off. + * @note Requires the use of nl_send_auto_complete()! + */ +#define NL_AUTO_SEQ 0 + +#define NL_MSG_CRED_PRESENT 1 + +struct nl_msg +{ + int nm_protocol; + int nm_flags; + struct sockaddr_nl nm_src; + struct sockaddr_nl nm_dst; + struct ucred nm_creds; + struct nlmsghdr * nm_nlh; + size_t nm_size; + int nm_refcnt; +}; + + +struct nl_msg; +struct nl_tree; +struct ucred; + +/* message parsing */ +extern int nlmsg_ok(const struct nlmsghdr *, int); +extern struct nlmsghdr * nlmsg_next(struct nlmsghdr *, int *); +extern int nlmsg_parse(struct nlmsghdr *, int, struct nlattr **, + int, struct nla_policy *); +extern int nlmsg_validate(struct nlmsghdr *, int, int, + struct nla_policy *); + +extern struct nl_msg * nlmsg_alloc(void); +extern struct nl_msg * nlmsg_alloc_size(size_t); +extern struct nl_msg * nlmsg_alloc_simple(int, int); +extern void nlmsg_set_default_size(size_t); +extern struct nl_msg * nlmsg_inherit(struct nlmsghdr *); +extern struct nl_msg * nlmsg_convert(struct nlmsghdr *); +extern void * nlmsg_reserve(struct nl_msg *, size_t, int); +extern int nlmsg_append(struct nl_msg *, void *, size_t, int); + +extern struct nlmsghdr * nlmsg_put(struct nl_msg *, uint32_t, uint32_t, + int, int, int); +extern void nlmsg_free(struct nl_msg *); + +extern int nl_msg_parse(struct nl_msg *, + void (*cb)(struct nl_object *, void *), + void *); + +extern void nl_msg_dump(struct nl_msg *, FILE *); + +/** + * length of netlink message not including padding + * @arg payload length of message payload + */ +static inline int nlmsg_msg_size(int payload) +{ + return NLMSG_HDRLEN + payload; +} + +/** + * length of netlink message including padding + * @arg payload length of message payload + */ +static inline int nlmsg_total_size(int payload) +{ + return NLMSG_ALIGN(nlmsg_msg_size(payload)); +} + +/** + * length of padding at the message's tail + * @arg payload length of message payload + */ +static inline int nlmsg_padlen(int payload) +{ + return nlmsg_total_size(payload) - nlmsg_msg_size(payload); +} + +/** + * head of message payload + * @arg nlh netlink messsage header + */ +static inline void *nlmsg_data(const struct nlmsghdr *nlh) +{ + return (unsigned char *) nlh + NLMSG_HDRLEN; +} + +static inline void *nlmsg_tail(const struct nlmsghdr *nlh) +{ + return (unsigned char *) nlh + NLMSG_ALIGN(nlh->nlmsg_len); +} + +/** + * length of message payload + * @arg nlh netlink message header + */ +static inline int nlmsg_len(const struct nlmsghdr *nlh) +{ + return nlh->nlmsg_len - NLMSG_HDRLEN; +} + +/** + * head of attributes data + * @arg nlh netlink message header + * @arg hdrlen length of family specific header + */ +static inline struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh, int hdrlen) +{ + unsigned char *data = (unsigned char*)nlmsg_data(nlh); + return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen)); +} + +/** + * length of attributes data + * @arg nlh netlink message header + * @arg hdrlen length of family specific header + */ +static inline int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen) +{ + return nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen); +} + +static inline int nlmsg_valid_hdr(const struct nlmsghdr *nlh, int hdrlen) +{ + if (nlh->nlmsg_len < (uint)nlmsg_msg_size(hdrlen)) + return 0; + + return 1; +} + + +static inline void nlmsg_set_proto(struct nl_msg *msg, int protocol) +{ + msg->nm_protocol = protocol; +} + +static inline int nlmsg_get_proto(struct nl_msg *msg) +{ + return msg->nm_protocol; +} + +static inline size_t nlmsg_get_max_size(struct nl_msg *msg) +{ + return msg->nm_size; +} + +static inline void nlmsg_set_src(struct nl_msg *msg, struct sockaddr_nl *addr) +{ + memcpy(&msg->nm_src, addr, sizeof(*addr)); +} + +static inline struct sockaddr_nl *nlmsg_get_src(struct nl_msg *msg) +{ + return &msg->nm_src; +} + +static inline void nlmsg_set_dst(struct nl_msg *msg, struct sockaddr_nl *addr) +{ + memcpy(&msg->nm_dst, addr, sizeof(*addr)); +} + +static inline struct sockaddr_nl *nlmsg_get_dst(struct nl_msg *msg) +{ + return &msg->nm_dst; +} + +static inline void nlmsg_set_creds(struct nl_msg *msg, struct ucred *creds) +{ + memcpy(&msg->nm_creds, creds, sizeof(*creds)); + msg->nm_flags |= NL_MSG_CRED_PRESENT; +} + +static inline struct ucred *nlmsg_get_creds(struct nl_msg *msg) +{ + if (msg->nm_flags & NL_MSG_CRED_PRESENT) + return &msg->nm_creds; + return NULL; +} + +/** + * Return actual netlink message + * @arg n netlink message + * + * Returns the actual netlink message casted to the type of the netlink + * message header. + * + * @return A pointer to the netlink message. + */ +static inline struct nlmsghdr *nlmsg_hdr(struct nl_msg *n) +{ + return n->nm_nlh; +} + +/** + * Acquire a reference on a netlink message + * @arg msg message to acquire reference from + */ +static inline void nlmsg_get(struct nl_msg *msg) +{ + msg->nm_refcnt++; +} + +/** + * Expand maximum payload size of a netlink message + * @arg n Netlink message. + * @arg newlen New maximum payload size. + * + * Reallocates the payload section of a netlink message and increases + * the maximum payload size of the message. + * + * @note Any pointers pointing to old payload block will be stale and + * need to be refetched. Therfore, do not expand while constructing + * nested attributes or while reserved data blocks are held. + * + * @return 0 on success or a negative error code. + */ +static inline int nlmsg_expand(struct nl_msg *n, size_t newlen) +{ + void *tmp; + + if (newlen <= n->nm_size) + return -NLE_INVAL; + + tmp = realloc(n->nm_nlh, newlen); + if (tmp == NULL) + return -NLE_NOMEM; + + n->nm_nlh = (struct nlmsghdr*)tmp; + n->nm_size = newlen; + + return 0; +} + + +/** + * @name Iterators + * @{ + */ + +/** + * @ingroup msg + * Iterate over a stream of attributes in a message + * @arg pos loop counter, set to current attribute + * @arg nlh netlink message header + * @arg hdrlen length of family header + * @arg rem initialized to len, holds bytes currently remaining in stream + */ +#define nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \ + nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \ + nlmsg_attrlen(nlh, hdrlen), rem) + +/** + * Iterate over a stream of messages + * @arg pos loop counter, set to current message + * @arg head head of message stream + * @arg len length of message stream + * @arg rem initialized to len, holds bytes currently remaining in stream + */ +#define nlmsg_for_each_msg(pos, head, len, rem) \ + for (pos = head, rem = len; \ + nlmsg_ok(pos, rem); \ + pos = nlmsg_next(pos, &(rem))) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/netlink-compat.h b/package/libs/libnl-tiny/src/include/netlink/netlink-compat.h new file mode 100644 index 0000000000..17ec9fc8d1 --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/netlink-compat.h @@ -0,0 +1,50 @@ +/* + * netlink/netlink-compat.h Netlink Compatability + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_COMPAT_H_ +#define NETLINK_COMPAT_H_ + +#if !defined _LINUX_SOCKET_H && !defined _BITS_SOCKADDR_H +typedef unsigned short sa_family_t; +#endif + +#ifndef IFNAMSIZ +/** Maximum length of a interface name */ +#define IFNAMSIZ 16 +#endif + +/* patch 2.4.x if_arp */ +#ifndef ARPHRD_INFINIBAND +#define ARPHRD_INFINIBAND 32 +#endif + +/* patch 2.4.x eth header file */ +#ifndef ETH_P_MPLS_UC +#define ETH_P_MPLS_UC 0x8847 +#endif + +#ifndef ETH_P_MPLS_MC +#define ETH_P_MPLS_MC 0x8848 +#endif + +#ifndef ETH_P_EDP2 +#define ETH_P_EDP2 0x88A2 +#endif + +#ifndef ETH_P_HDLC +#define ETH_P_HDLC 0x0019 +#endif + +#ifndef AF_LLC +#define AF_LLC 26 +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/netlink-kernel.h b/package/libs/libnl-tiny/src/include/netlink/netlink-kernel.h new file mode 100644 index 0000000000..a0f5535664 --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/netlink-kernel.h @@ -0,0 +1,196 @@ +#ifndef __LINUX_NETLINK_H +#define __LINUX_NETLINK_H + +/** + * Netlink socket address + * @ingroup nl + */ +struct sockaddr_nl +{ + /** socket family (AF_NETLINK) */ + sa_family_t nl_family; + + /** Padding (unused) */ + unsigned short nl_pad; + + /** Unique process ID */ + uint32_t nl_pid; + + /** Multicast group subscriptions */ + uint32_t nl_groups; +}; + +/** + * Netlink message header + * @ingroup msg + */ +struct nlmsghdr +{ + /** + * Length of message including header. + */ + uint32_t nlmsg_len; + + /** + * Message type (content type) + */ + uint16_t nlmsg_type; + + /** + * Message flags + */ + uint16_t nlmsg_flags; + + /** + * Sequence number + */ + uint32_t nlmsg_seq; + + /** + * Netlink PID of the proccess sending the message. + */ + uint32_t nlmsg_pid; +}; + +/** + * @name Standard message flags + * @{ + */ + +/** + * Must be set on all request messages (typically from user space to + * kernel space). + * @ingroup msg + */ +#define NLM_F_REQUEST 1 + +/** + * Indicates the message is part of a multipart message terminated + * by NLMSG_DONE. + */ +#define NLM_F_MULTI 2 + +/** + * Request for an acknowledgment on success. + */ +#define NLM_F_ACK 4 + +/** + * Echo this request + */ +#define NLM_F_ECHO 8 + +/** @} */ + +/** + * @name Additional message flags for GET requests + * @{ + */ + +/** + * Return the complete table instead of a single entry. + * @ingroup msg + */ +#define NLM_F_ROOT 0x100 + +/** + * Return all entries matching criteria passed in message content. + */ +#define NLM_F_MATCH 0x200 + +/** + * Return an atomic snapshot of the table being referenced. This + * may require special privileges because it has the potential to + * interrupt service in the FE for a longer time. + */ +#define NLM_F_ATOMIC 0x400 + +/** + * Dump all entries + */ +#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH) + +/** @} */ + +/** + * @name Additional messsage flags for NEW requests + * @{ + */ + +/** + * Replace existing matching config object with this request. + * @ingroup msg + */ +#define NLM_F_REPLACE 0x100 + +/** + * Don't replace the config object if it already exists. + */ +#define NLM_F_EXCL 0x200 + +/** + * Create config object if it doesn't already exist. + */ +#define NLM_F_CREATE 0x400 + +/** + * Add to the end of the object list. + */ +#define NLM_F_APPEND 0x800 + +/** @} */ + +/** + * @name Standard Message types + * @{ + */ + +/** + * No operation, message must be ignored + * @ingroup msg + */ +#define NLMSG_NOOP 0x1 + +/** + * The message signals an error and the payload contains a nlmsgerr + * structure. This can be looked at as a NACK and typically it is + * from FEC to CPC. + */ +#define NLMSG_ERROR 0x2 + +/** + * Message terminates a multipart message. + */ +#define NLMSG_DONE 0x3 + +/** + * The message signals that data got lost + */ +#define NLMSG_OVERRUN 0x4 + +/** + * Lower limit of reserved message types + */ +#define NLMSG_MIN_TYPE 0x10 + +/** @} */ + +/** + * Netlink error message + * @ingroup msg + */ +struct nlmsgerr +{ + /** Error code (errno number) */ + int error; + + /** Original netlink message causing the error */ + struct nlmsghdr msg; +}; + +struct nl_pktinfo +{ + __u32 group; +}; + +#endif /* __LINUX_NETLINK_H */ diff --git a/package/libs/libnl-tiny/src/include/netlink/netlink.h b/package/libs/libnl-tiny/src/include/netlink/netlink.h new file mode 100644 index 0000000000..e06fb7f118 --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/netlink.h @@ -0,0 +1,82 @@ +/* + * netlink/netlink.h Netlink Interface + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_NETLINK_H_ +#define NETLINK_NETLINK_H_ + +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <stdlib.h> +#include <sys/poll.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/time.h> +#include <netdb.h> +#include <netlink/netlink-compat.h> +#include <linux/netlink.h> +#include <linux/genetlink.h> +#include <netlink/version.h> +#include <netlink/errno.h> +#include <netlink/types.h> +#include <netlink/handlers.h> +#include <netlink/socket.h> + +#ifdef __cplusplus +extern "C" { +#endif + +extern int nl_debug; +extern struct nl_dump_params nl_debug_dp; + +/* Connection Management */ +extern int nl_connect(struct nl_sock *, int); +extern void nl_close(struct nl_sock *); + +/* Send */ +extern int nl_sendto(struct nl_sock *, void *, size_t); +extern int nl_sendmsg(struct nl_sock *, struct nl_msg *, + struct msghdr *); +extern int nl_send(struct nl_sock *, struct nl_msg *); +extern int nl_send_auto_complete(struct nl_sock *, + struct nl_msg *); +extern int nl_send_simple(struct nl_sock *, int, int, + void *, size_t); + +/* Receive */ +extern int nl_recv(struct nl_sock *, + struct sockaddr_nl *, unsigned char **, + struct ucred **); +extern int nl_recvmsgs(struct nl_sock *sk, struct nl_cb *cb); + +extern int nl_wait_for_ack(struct nl_sock *); + +/* Netlink Family Translations */ +extern char * nl_nlfamily2str(int, char *, size_t); +extern int nl_str2nlfamily(const char *); + +/** + * Receive a set of message from a netlink socket using handlers in nl_sock. + * @arg sk Netlink socket. + * + * Calls nl_recvmsgs() with the handlers configured in the netlink socket. + */ +static inline int nl_recvmsgs_default(struct nl_sock *sk) +{ + return nl_recvmsgs(sk, sk->s_cb); +} + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/object-api.h b/package/libs/libnl-tiny/src/include/netlink/object-api.h new file mode 100644 index 0000000000..8a44fe9012 --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/object-api.h @@ -0,0 +1,331 @@ +/* + * netlink/object-api.c Object API + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2007 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_OBJECT_API_H_ +#define NETLINK_OBJECT_API_H_ + +#include <netlink/netlink.h> +#include <netlink/utils.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup object + * @defgroup object_api Object API + * @brief + * + * @par 1) Object Definition + * @code + * // Define your object starting with the common object header + * struct my_obj { + * NLHDR_COMMON + * int my_data; + * }; + * + * // Fill out the object operations structure + * struct nl_object_ops my_ops = { + * .oo_name = "my_obj", + * .oo_size = sizeof(struct my_obj), + * }; + * + * // At this point the object can be allocated, you may want to provide a + * // separate _alloc() function to ease allocting objects of this kind. + * struct nl_object *obj = nl_object_alloc(&my_ops); + * + * // And release it again... + * nl_object_put(obj); + * @endcode + * + * @par 2) Allocating additional data + * @code + * // You may require to allocate additional data and store it inside + * // object, f.e. assuming there is a field `ptr'. + * struct my_obj { + * NLHDR_COMMON + * void * ptr; + * }; + * + * // And at some point you may assign allocated data to this field: + * my_obj->ptr = calloc(1, ...); + * + * // In order to not introduce any memory leaks you have to release + * // this data again when the last reference is given back. + * static void my_obj_free_data(struct nl_object *obj) + * { + * struct my_obj *my_obj = nl_object_priv(obj); + * + * free(my_obj->ptr); + * } + * + * // Also when the object is cloned, you must ensure for your pointer + * // stay valid even if one of the clones is freed by either making + * // a clone as well or increase the reference count. + * static int my_obj_clone(struct nl_object *src, struct nl_object *dst) + * { + * struct my_obj *my_src = nl_object_priv(src); + * struct my_obj *my_dst = nl_object_priv(dst); + * + * if (src->ptr) { + * dst->ptr = calloc(1, ...); + * memcpy(dst->ptr, src->ptr, ...); + * } + * } + * + * struct nl_object_ops my_ops = { + * ... + * .oo_free_data = my_obj_free_data, + * .oo_clone = my_obj_clone, + * }; + * @endcode + * + * @par 3) Object Dumping + * @code + * static int my_obj_dump_detailed(struct nl_object *obj, + * struct nl_dump_params *params) + * { + * struct my_obj *my_obj = nl_object_priv(obj); + * + * // It is absolutely essential to use nl_dump() when printing + * // any text to make sure the dumping parameters are respected. + * nl_dump(params, "Obj Integer: %d\n", my_obj->my_int); + * + * // Before we can dump the next line, make sure to prefix + * // this line correctly. + * nl_new_line(params); + * + * // You may also split a line into multiple nl_dump() calls. + * nl_dump(params, "String: %s ", my_obj->my_string); + * nl_dump(params, "String-2: %s\n", my_obj->another_string); + * } + * + * struct nl_object_ops my_ops = { + * ... + * .oo_dump[NL_DUMP_FULL] = my_obj_dump_detailed, + * }; + * @endcode + * + * @par 4) Object Attributes + * @code + * // The concept of object attributes is optional but can ease the typical + * // case of objects that have optional attributes, e.g. a route may have a + * // nexthop assigned but it is not required to. + * + * // The first step to define your object specific bitmask listing all + * // attributes + * #define MY_ATTR_FOO (1<<0) + * #define MY_ATTR_BAR (1<<1) + * + * // When assigning an optional attribute to the object, make sure + * // to mark its availability. + * my_obj->foo = 123123; + * my_obj->ce_mask |= MY_ATTR_FOO; + * + * // At any time you may use this mask to check for the availability + * // of the attribute, e.g. while dumping + * if (my_obj->ce_mask & MY_ATTR_FOO) + * nl_dump(params, "foo %d ", my_obj->foo); + * + * // One of the big advantages of this concept is that it allows for + * // standardized comparisons which make it trivial for caches to + * // identify unique objects by use of unified comparison functions. + * // In order for it to work, your object implementation must provide + * // a comparison function and define a list of attributes which + * // combined together make an object unique. + * + * static int my_obj_compare(struct nl_object *_a, struct nl_object *_b, + * uint32_t attrs, int flags) + * { + * struct my_obj *a = nl_object_priv(_a): + * struct my_obj *b = nl_object_priv(_b): + * int diff = 0; + * + * // We help ourselves in defining our own DIFF macro which will + * // call ATTR_DIFF() on both objects which will make sure to only + * // compare the attributes if required. + * #define MY_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, MY_ATTR_##ATTR, a, b, EXPR) + * + * // Call our own diff macro for each attribute to build a bitmask + * // representing the attributes which mismatch. + * diff |= MY_DIFF(FOO, a->foo != b->foo) + * diff |= MY_DIFF(BAR, strcmp(a->bar, b->bar)) + * + * return diff; + * } + * + * // In order to identify identical objects with differing attributes + * // you must specify the attributes required to uniquely identify + * // your object. Make sure to not include too many attributes, this + * // list is used when caches look for an old version of an object. + * struct nl_object_ops my_ops = { + * ... + * .oo_id_attrs = MY_ATTR_FOO, + * .oo_compare = my_obj_compare, + * }; + * @endcode + * @{ + */ + +/** + * Common Object Header + * + * This macro must be included as first member in every object + * definition to allow objects to be cached. + */ +#define NLHDR_COMMON \ + int ce_refcnt; \ + struct nl_object_ops * ce_ops; \ + struct nl_cache * ce_cache; \ + struct nl_list_head ce_list; \ + int ce_msgtype; \ + int ce_flags; \ + uint32_t ce_mask; + +/** + * Return true if attribute is available in both objects + * @arg A an object + * @arg B another object + * @arg ATTR attribute bit + * + * @return True if the attribute is available, otherwise false is returned. + */ +#define AVAILABLE(A, B, ATTR) (((A)->ce_mask & (B)->ce_mask) & (ATTR)) + +/** + * Return true if attributes mismatch + * @arg A an object + * @arg B another object + * @arg ATTR attribute bit + * @arg EXPR Comparison expression + * + * This function will check if the attribute in question is available + * in both objects, if not this will count as a mismatch. + * + * If available the function will execute the expression which must + * return true if the attributes mismatch. + * + * @return True if the attribute mismatch, or false if they match. + */ +#define ATTR_MISMATCH(A, B, ATTR, EXPR) (!AVAILABLE(A, B, ATTR) || (EXPR)) + +/** + * Return attribute bit if attribute does not match + * @arg LIST list of attributes to be compared + * @arg ATTR attribute bit + * @arg A an object + * @arg B another object + * @arg EXPR Comparison expression + * + * This function will check if the attribute in question is available + * in both objects, if not this will count as a mismatch. + * + * If available the function will execute the expression which must + * return true if the attributes mismatch. + * + * In case the attributes mismatch, the attribute is returned, otherwise + * 0 is returned. + * + * @code + * diff |= ATTR_DIFF(attrs, MY_ATTR_FOO, a, b, a->foo != b->foo); + * @endcode + */ +#define ATTR_DIFF(LIST, ATTR, A, B, EXPR) \ +({ int diff = 0; \ + if (((LIST) & (ATTR)) && ATTR_MISMATCH(A, B, ATTR, EXPR)) \ + diff = ATTR; \ + diff; }) + +/** + * Object Operations + */ +struct nl_object; +struct nl_object_ops +{ + /** + * Unique name of object type + * + * Must be in the form family/name, e.g. "route/addr" + */ + char * oo_name; + + /** Size of object including its header */ + size_t oo_size; + + /* List of attributes needed to uniquely identify the object */ + uint32_t oo_id_attrs; + + /** + * Constructor function + * + * Will be called when a new object of this type is allocated. + * Can be used to initialize members such as lists etc. + */ + void (*oo_constructor)(struct nl_object *); + + /** + * Destructor function + * + * Will be called when an object is freed. Must free all + * resources which may have been allocated as part of this + * object. + */ + void (*oo_free_data)(struct nl_object *); + + /** + * Cloning function + * + * Will be called when an object needs to be cloned. Please + * note that the generic object code will make an exact + * copy of the object first, therefore you only need to take + * care of members which require reference counting etc. + * + * May return a negative error code to abort cloning. + */ + int (*oo_clone)(struct nl_object *, struct nl_object *); + + /** + * Dumping functions + * + * Will be called when an object is dumped. The implementations + * have to use nl_dump(), nl_dump_line(), and nl_new_line() to + * dump objects. + * + * The functions must return the number of lines printed. + */ + void (*oo_dump[NL_DUMP_MAX+1])(struct nl_object *, + struct nl_dump_params *); + + /** + * Comparison function + * + * Will be called when two objects of the same type are + * compared. It takes the two objects in question, an object + * specific bitmask defining which attributes should be + * compared and flags to control the behaviour. + * + * The function must return a bitmask with the relevant bit + * set for each attribute that mismatches. + */ + int (*oo_compare)(struct nl_object *, struct nl_object *, + uint32_t, int); + + + char *(*oo_attrs2str)(int, char *, size_t); +}; + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/object.h b/package/libs/libnl-tiny/src/include/netlink/object.h new file mode 100644 index 0000000000..8aabe7bb12 --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/object.h @@ -0,0 +1,164 @@ +/* + * netlink/object.c Generic Cacheable Object + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_OBJECT_H_ +#define NETLINK_OBJECT_H_ + +#include <netlink/netlink.h> +#include <netlink/utils.h> +#include <netlink/object-api.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define NL_OBJ_MARK 1 + +struct nl_cache; +struct nl_object; +struct nl_object_ops; + +struct nl_object +{ + NLHDR_COMMON +}; + +#define OBJ_CAST(ptr) ((struct nl_object *) (ptr)) + +/* General */ +extern struct nl_object * nl_object_alloc(struct nl_object_ops *); +extern void nl_object_free(struct nl_object *); +extern struct nl_object * nl_object_clone(struct nl_object *obj); + +#ifdef disabled + +extern int nl_object_alloc_name(const char *, + struct nl_object **); +extern void nl_object_dump(struct nl_object *, + struct nl_dump_params *); + +extern uint32_t nl_object_diff(struct nl_object *, + struct nl_object *); +extern int nl_object_match_filter(struct nl_object *, + struct nl_object *); +extern int nl_object_identical(struct nl_object *, + struct nl_object *); +extern char * nl_object_attrs2str(struct nl_object *, + uint32_t attrs, char *buf, + size_t); +#endif +/** + * Check whether this object is used by multiple users + * @arg obj object to check + * @return true or false + */ +static inline int nl_object_shared(struct nl_object *obj) +{ + return obj->ce_refcnt > 1; +} + + +static inline void nl_object_get(struct nl_object *obj) +{ + obj->ce_refcnt++; +} + +static inline void nl_object_put(struct nl_object *obj) +{ + if (!obj) + return; + + obj->ce_refcnt--; + + if (obj->ce_refcnt <= 0) + nl_object_free(obj); +} + + +/** + * @name Marks + * @{ + */ + +/** + * Add mark to object + * @arg obj Object to mark + */ +static inline void nl_object_mark(struct nl_object *obj) +{ + obj->ce_flags |= NL_OBJ_MARK; +} + +/** + * Remove mark from object + * @arg obj Object to unmark + */ +static inline void nl_object_unmark(struct nl_object *obj) +{ + obj->ce_flags &= ~NL_OBJ_MARK; +} + +/** + * Return true if object is marked + * @arg obj Object to check + * @return true if object is marked, otherwise false + */ +static inline int nl_object_is_marked(struct nl_object *obj) +{ + return (obj->ce_flags & NL_OBJ_MARK); +} + +/** @} */ + +#ifdef disabled +/** + * Return list of attributes present in an object + * @arg obj an object + * @arg buf destination buffer + * @arg len length of destination buffer + * + * @return destination buffer. + */ +static inline char *nl_object_attr_list(struct nl_object *obj, char *buf, size_t len) +{ + return nl_object_attrs2str(obj, obj->ce_mask, buf, len); +} +#endif + +/** + * @name Attributes + * @{ + */ + +static inline int nl_object_get_refcnt(struct nl_object *obj) +{ + return obj->ce_refcnt; +} + +static inline struct nl_cache *nl_object_get_cache(struct nl_object *obj) +{ + return obj->ce_cache; +} + +static inline void * nl_object_priv(struct nl_object *obj) +{ + return obj; +} + + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/socket.h b/package/libs/libnl-tiny/src/include/netlink/socket.h new file mode 100644 index 0000000000..9f7f4220aa --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/socket.h @@ -0,0 +1,221 @@ +/* + * netlink/socket.h Netlink Socket + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_SOCKET_H_ +#define NETLINK_SOCKET_H_ + +#include <netlink/types.h> +#include <netlink/handlers.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define NL_SOCK_BUFSIZE_SET (1<<0) +#define NL_SOCK_PASSCRED (1<<1) +#define NL_OWN_PORT (1<<2) +#define NL_MSG_PEEK (1<<3) +#define NL_NO_AUTO_ACK (1<<4) + +struct nl_cb; +struct nl_sock +{ + struct sockaddr_nl s_local; + struct sockaddr_nl s_peer; + int s_fd; + int s_proto; + unsigned int s_seq_next; + unsigned int s_seq_expect; + int s_flags; + struct nl_cb * s_cb; +}; + + +extern struct nl_sock * nl_socket_alloc(void); +extern struct nl_sock * nl_socket_alloc_cb(struct nl_cb *); +extern void nl_socket_free(struct nl_sock *); + +extern void nl_socket_set_local_port(struct nl_sock *, uint32_t); + +extern int nl_socket_add_memberships(struct nl_sock *, int, ...); +extern int nl_socket_drop_memberships(struct nl_sock *, int, ...); + +extern int nl_socket_set_buffer_size(struct nl_sock *, int, int); +extern int nl_socket_set_passcred(struct nl_sock *, int); +extern int nl_socket_recv_pktinfo(struct nl_sock *, int); + +extern void nl_socket_disable_seq_check(struct nl_sock *); + +extern int nl_socket_set_nonblocking(struct nl_sock *); + +/** + * Use next sequence number + * @arg sk Netlink socket. + * + * Uses the next available sequence number and increases the counter + * by one for subsequent calls. + * + * @return Unique serial sequence number + */ +static inline unsigned int nl_socket_use_seq(struct nl_sock *sk) +{ + return sk->s_seq_next++; +} + +/** + * Disable automatic request for ACK + * @arg sk Netlink socket. + * + * The default behaviour of a socket is to request an ACK for + * each message sent to allow for the caller to synchronize to + * the completion of the netlink operation. This function + * disables this behaviour and will result in requests being + * sent which will not have the NLM_F_ACK flag set automatically. + * However, it is still possible for the caller to set the + * NLM_F_ACK flag explicitely. + */ +static inline void nl_socket_disable_auto_ack(struct nl_sock *sk) +{ + sk->s_flags |= NL_NO_AUTO_ACK; +} + +/** + * Enable automatic request for ACK (default) + * @arg sk Netlink socket. + * @see nl_socket_disable_auto_ack + */ +static inline void nl_socket_enable_auto_ack(struct nl_sock *sk) +{ + sk->s_flags &= ~NL_NO_AUTO_ACK; +} + +/** + * @name Source Idenficiation + * @{ + */ + +static inline uint32_t nl_socket_get_local_port(struct nl_sock *sk) +{ + return sk->s_local.nl_pid; +} + +/** + * Join multicast groups (deprecated) + * @arg sk Netlink socket. + * @arg groups Bitmask of groups to join. + * + * This function defines the old way of joining multicast group which + * has to be done prior to calling nl_connect(). It works on any kernel + * version but is very limited as only 32 groups can be joined. + */ +static inline void nl_join_groups(struct nl_sock *sk, int groups) +{ + sk->s_local.nl_groups |= groups; +} + +/** + * @name Peer Identfication + * @{ + */ + +static inline uint32_t nl_socket_get_peer_port(struct nl_sock *sk) +{ + return sk->s_peer.nl_pid; +} + +static inline void nl_socket_set_peer_port(struct nl_sock *sk, uint32_t port) +{ + sk->s_peer.nl_pid = port; +} + +/** @} */ + +/** + * @name File Descriptor + * @{ + */ + +static inline int nl_socket_get_fd(struct nl_sock *sk) +{ + return sk->s_fd; +} + +/** + * Enable use of MSG_PEEK when reading from socket + * @arg sk Netlink socket. + */ +static inline void nl_socket_enable_msg_peek(struct nl_sock *sk) +{ + sk->s_flags |= NL_MSG_PEEK; +} + +/** + * Disable use of MSG_PEEK when reading from socket + * @arg sk Netlink socket. + */ +static inline void nl_socket_disable_msg_peek(struct nl_sock *sk) +{ + sk->s_flags &= ~NL_MSG_PEEK; +} + +/** + * @name Callback Handler + * @{ + */ + +static inline struct nl_cb *nl_socket_get_cb(struct nl_sock *sk) +{ + return nl_cb_get(sk->s_cb); +} + +static inline void nl_socket_set_cb(struct nl_sock *sk, struct nl_cb *cb) +{ + nl_cb_put(sk->s_cb); + sk->s_cb = nl_cb_get(cb); +} + +/** + * Modify the callback handler associated to the socket + * @arg sk Netlink socket. + * @arg type which type callback to set + * @arg kind kind of callback + * @arg func callback function + * @arg arg argument to be passwd to callback function + * + * @see nl_cb_set + */ +static inline int nl_socket_modify_cb(struct nl_sock *sk, enum nl_cb_type type, + enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func, + void *arg) +{ + return nl_cb_set(sk->s_cb, type, kind, func, arg); +} + +/** @} */ + +static inline int nl_socket_add_membership(struct nl_sock *sk, int group) +{ + return nl_socket_add_memberships(sk, group, 0); +} + + +static inline int nl_socket_drop_membership(struct nl_sock *sk, int group) +{ + return nl_socket_drop_memberships(sk, group, 0); +} + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/types.h b/package/libs/libnl-tiny/src/include/netlink/types.h new file mode 100644 index 0000000000..de81ace11e --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/types.h @@ -0,0 +1,121 @@ +/* + * netlink/netlink-types.h Netlink Types + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef __NETLINK_TYPES_H_ +#define __NETLINK_TYPES_H_ + +#include <stdio.h> + +/** + * Dumping types (dp_type) + * @ingroup utils + */ +enum nl_dump_type { + NL_DUMP_LINE, /**< Dump object briefly on one line */ + NL_DUMP_DETAILS, /**< Dump all attributes but no statistics */ + NL_DUMP_STATS, /**< Dump all attributes including statistics */ + NL_DUMP_ENV, /**< Dump all attribtues as env variables */ + __NL_DUMP_MAX, +}; +#define NL_DUMP_MAX (__NL_DUMP_MAX - 1) + +/** + * Dumping parameters + * @ingroup utils + */ +struct nl_dump_params +{ + /** + * Specifies the type of dump that is requested. + */ + enum nl_dump_type dp_type; + + /** + * Specifies the number of whitespaces to be put in front + * of every new line (indentation). + */ + int dp_prefix; + + /** + * Causes the cache index to be printed for each element. + */ + int dp_print_index; + + /** + * Causes each element to be prefixed with the message type. + */ + int dp_dump_msgtype; + + /** + * A callback invoked for output + * + * Passed arguments are: + * - dumping parameters + * - string to append to the output + */ + void (*dp_cb)(struct nl_dump_params *, char *); + + /** + * A callback invoked for every new line, can be used to + * customize the indentation. + * + * Passed arguments are: + * - dumping parameters + * - line number starting from 0 + */ + void (*dp_nl_cb)(struct nl_dump_params *, int); + + /** + * User data pointer, can be used to pass data to callbacks. + */ + void *dp_data; + + /** + * File descriptor the dumping output should go to + */ + FILE * dp_fd; + + /** + * Alternatively the output may be redirected into a buffer + */ + char * dp_buf; + + /** + * Length of the buffer dp_buf + */ + size_t dp_buflen; + + /** + * PRIVATE + * Set if a dump was performed prior to the actual dump handler. + */ + int dp_pre_dump; + + /** + * PRIVATE + * Owned by the current caller + */ + int dp_ivar; + + unsigned int dp_line; +}; + +#ifndef __GNUC__ +#define __extension__ +#endif + +#define min_t(type,x,y) \ + __extension__({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) +#define max_t(type,x,y) \ + __extension__({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) + + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/utils.h b/package/libs/libnl-tiny/src/include/netlink/utils.h new file mode 100644 index 0000000000..480bab6186 --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/utils.h @@ -0,0 +1,78 @@ +/* + * netlink/utils.h Utility Functions + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_UTILS_H_ +#define NETLINK_UTILS_H_ + +#include <netlink/netlink.h> +#include <netlink/list.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Probability Constants + * @{ + */ + +/** + * Lower probability limit + * @ingroup utils + */ +#define NL_PROB_MIN 0x0 + +/** + * Upper probability limit + * @ingroup utils + */ +#define NL_PROB_MAX 0xffffffff + +/** @} */ + +/* unit pretty-printing */ +extern double nl_cancel_down_bytes(unsigned long long, char **); +extern double nl_cancel_down_bits(unsigned long long, char **); +extern double nl_cancel_down_us(uint32_t, char **); + +/* generic unit translations */ +extern long nl_size2int(const char *); +extern long nl_prob2int(const char *); + +/* time translations */ +extern int nl_get_hz(void); +extern uint32_t nl_us2ticks(uint32_t); +extern uint32_t nl_ticks2us(uint32_t); +extern int nl_str2msec(const char *, uint64_t *); +extern char * nl_msec2str(uint64_t, char *, size_t); + +/* link layer protocol translations */ +extern char * nl_llproto2str(int, char *, size_t); +extern int nl_str2llproto(const char *); + +/* ethernet protocol translations */ +extern char * nl_ether_proto2str(int, char *, size_t); +extern int nl_str2ether_proto(const char *); + +/* IP protocol translations */ +extern char * nl_ip_proto2str(int, char *, size_t); +extern int nl_str2ip_proto(const char *); + +/* Dumping helpers */ +extern void nl_new_line(struct nl_dump_params *); +extern void nl_dump(struct nl_dump_params *, const char *, ...); +extern void nl_dump_line(struct nl_dump_params *, const char *, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/libs/libnl-tiny/src/include/netlink/version.h b/package/libs/libnl-tiny/src/include/netlink/version.h new file mode 100644 index 0000000000..6a316d4933 --- /dev/null +++ b/package/libs/libnl-tiny/src/include/netlink/version.h @@ -0,0 +1,18 @@ +/* + * netlink/version.h Compile Time Versioning Information + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2008 Thomas Graf <tgraf@suug.ch> + */ + +#ifndef NETLINK_VERSION_H_ +#define NETLINK_VERSION_H_ + +#define LIBNL_STRING "libnl" +#define LIBNL_VERSION "2.0" + +#endif |