summaryrefslogtreecommitdiffstats
path: root/lib/genl
diff options
context:
space:
mode:
authorThomas Graf <tgraf@redhat.com>2012-05-31 11:11:48 (GMT)
committerThomas Graf <tgraf@redhat.com>2012-05-31 11:11:48 (GMT)
commit0b70de5155ba74f152ebece230659e7890cccbd9 (patch)
treea15e0d5c150ca8a03036b19467e2990fa4b77370 /lib/genl
parentd733f8a0a65a817d16ebaa1a8f5ad1330682b489 (diff)
downloadlibnl-0b70de5155ba74f152ebece230659e7890cccbd9.zip
libnl-0b70de5155ba74f152ebece230659e7890cccbd9.tar.gz
libnl-0b70de5155ba74f152ebece230659e7890cccbd9.tar.bz2
genl: updates to API reference documentation
Diffstat (limited to 'lib/genl')
-rw-r--r--lib/genl/ctrl.c129
-rw-r--r--lib/genl/family.c102
-rw-r--r--lib/genl/genl.c281
-rw-r--r--lib/genl/mngt.c118
4 files changed, 394 insertions, 236 deletions
diff --git a/lib/genl/ctrl.c b/lib/genl/ctrl.c
index 107a4fa..ddb7603 100644
--- a/lib/genl/ctrl.c
+++ b/lib/genl/ctrl.c
@@ -6,14 +6,18 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
/**
- * @ingroup genl_mngt
- * @defgroup ctrl Controller
- * @brief
+ * @ingroup genl
+ * @defgroup genl_ctrl Controller (Resolver)
*
+ * Resolves Generic Netlink family names to numeric identifiers.
+ *
+ * The controller is a component in the kernel that resolves Generic Netlink
+ * family names to their numeric identifiers. This module provides functions
+ * to query the controller to access the resolving functionality.
* @{
*/
@@ -29,7 +33,6 @@
#define CTRL_VERSION 0x0001
static struct nl_cache_ops genl_ctrl_ops;
-/** @endcond */
static int ctrl_request_update(struct nl_cache *c, struct nl_sock *h)
{
@@ -173,27 +176,51 @@ errout:
return err;
}
+/** @endcond */
+
/**
- * @name Cache Management
+ * @name Controller Cache
+ *
+ * The controller cache allows to keep a local copy of the list of all
+ * kernel side registered Generic Netlink families to quickly resolve
+ * multiple Generic Netlink family names without requiring to communicate
+ * with the kernel for each resolving iteration.
+ *
* @{
*/
-int genl_ctrl_alloc_cache(struct nl_sock *sock, struct nl_cache **result)
+/**
+ * Allocate a new controller cache
+ * @arg sk Generic Netlink socket
+ * @arg result Pointer to store resulting cache
+ *
+ * Allocates a new cache mirroring the state of the controller and stores it
+ * in \c *result. The allocated cache will contain a list of all currently
+ * registered kernel side Generic Netlink families. The cache is meant to be
+ * used to resolve family names locally.
+ *
+ * @return 0 on success or a negative error code.
+ */
+int genl_ctrl_alloc_cache(struct nl_sock *sk, struct nl_cache **result)
{
- return nl_cache_alloc_and_fill(&genl_ctrl_ops, sock, result);
+ return nl_cache_alloc_and_fill(&genl_ctrl_ops, sk, result);
}
/**
- * Look up generic netlink family by id in the provided cache.
- * @arg cache Generic netlink family cache.
- * @arg id Family identifier.
+ * Search controller cache for a numeric address match
+ * @arg cache Controller cache
+ * @arg id Numeric family identifier.
*
- * Searches through the cache looking for a registered family
- * matching the specified identifier. The caller will own a
- * reference on the returned object which needs to be given
- * back after usage using genl_family_put().
+ * Searches a previously allocated controller cache and looks for an entry
+ * that matches the specified numeric family identifier \c id. If a match
+ * is found successfully, the reference count of the matching object is
+ * increased by one before the objet is returned.
*
- * @return Generic netlink family object or NULL if no match was found.
+ * @see genl_ctrl_alloc_cache()
+ * @see genl_ctrl_search_by_name()
+ * @see genl_family_put()
+ *
+ * @return Generic Netlink family object or NULL if no match was found.
*/
struct genl_family *genl_ctrl_search(struct nl_cache *cache, int id)
{
@@ -213,24 +240,23 @@ struct genl_family *genl_ctrl_search(struct nl_cache *cache, int id)
}
/**
- * @name Resolver
- * @{
- */
-
-/**
- * Look up generic netlink family by family name in the provided cache.
- * @arg cache Generic netlink family cache.
- * @arg name Family name.
+ * Search controller cache for a family name match
+ * @arg cache Controller cache
+ * @arg name Name of Generic Netlink family
+ *
+ * Searches a previously allocated controller cache and looks for an entry
+ * that matches the specified family \c name. If a match is found successfully,
+ * the reference count of the matching object is increased by one before the
+ * objet is returned.
*
- * Searches through the cache looking for a registered family
- * matching the specified name. The caller will own a reference
- * on the returned object which needs to be given back after
- * usage using genl_family_put().
+ * @see genl_ctrl_alloc_cache()
+ * @see genl_ctrl_search()
+ * @see genl_family_put()
*
- * @return Generic netlink family object or NULL if no match was found.
+ * @return Generic Netlink family object or NULL if no match was found.
*/
struct genl_family *genl_ctrl_search_by_name(struct nl_cache *cache,
- const char *name)
+ const char *name)
{
struct genl_family *fam;
@@ -250,14 +276,26 @@ struct genl_family *genl_ctrl_search_by_name(struct nl_cache *cache,
/** @} */
/**
- * Resolve generic netlink family name to its identifier
- * @arg sk Netlink socket.
- * @arg name Name of generic netlink family
+ * @name Direct Resolvers
*
- * Resolves the generic netlink family name to its identifer and returns
- * it.
+ * These functions communicate directly with the kernel and do not require
+ * a cache to be kept up to date.
*
- * @return A positive identifier or a negative error code.
+ * @{
+ */
+
+/**
+ * Resolve Generic Netlink family name to numeric identifier
+ * @arg sk Generic Netlink socket.
+ * @arg name Name of Generic Netlink family
+ *
+ * Resolves the Generic Netlink family name to the corresponding numeric
+ * family identifier. This function queries the kernel directly, use
+ * genl_ctrl_search_by_name() if you need to resolve multiple names.
+ *
+ * @see genl_ctrl_search_by_name()
+ *
+ * @return The numeric family identifier or a negative error code.
*/
int genl_ctrl_resolve(struct nl_sock *sk, const char *name)
{
@@ -283,7 +321,7 @@ errout:
}
static int genl_ctrl_grp_by_name(const struct genl_family *family,
- const char *grp_name)
+ const char *grp_name)
{
struct genl_family_grp *grp;
@@ -296,8 +334,19 @@ static int genl_ctrl_grp_by_name(const struct genl_family *family,
return -NLE_OBJ_NOTFOUND;
}
+/**
+ * Resolve Generic Netlink family group name
+ * @arg sk Generic Netlink socket
+ * @arg family_name Name of Generic Netlink family
+ * @arg grp_name Name of group to resolve
+ *
+ * Looks up the family object and resolves the group name to the numeric
+ * group identifier.
+ *
+ * @return Numeric group identifier or a negative error code.
+ */
int genl_ctrl_resolve_grp(struct nl_sock *sk, const char *family_name,
- const char *grp_name)
+ const char *grp_name)
{
struct nl_cache *cache;
struct genl_family *family;
@@ -322,6 +371,7 @@ errout:
/** @} */
+/** @cond SKIP */
static struct genl_cmd genl_cmds[] = {
{
.c_id = CTRL_CMD_NEWFAMILY,
@@ -353,9 +403,7 @@ static struct genl_ops genl_ops = {
.o_ncmds = ARRAY_SIZE(genl_cmds),
};
-/** @cond SKIP */
extern struct nl_object_ops genl_family_ops;
-/** @endcond */
static struct nl_cache_ops genl_ctrl_ops = {
.co_name = "genl/family",
@@ -376,5 +424,6 @@ static void __exit ctrl_exit(void)
{
genl_unregister(&genl_ctrl_ops);
}
+/** @endcond */
/** @} */
diff --git a/lib/genl/family.c b/lib/genl/family.c
index ebeebcb..64b98cd 100644
--- a/lib/genl/family.c
+++ b/lib/genl/family.c
@@ -6,13 +6,14 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
/**
- * @ingroup genl
- * @defgroup genl_family Generic Netlink Family
- * @brief
+ * @ingroup genl_ctrl
+ * @defgroup genl_family Generic Netlink Family Object
+ *
+ * Object representing a kernel side registered Generic Netlink family
*
* @{
*/
@@ -32,7 +33,6 @@
#define FAMILY_ATTR_OPS 0x20
struct nl_object_ops genl_family_ops;
-/** @endcond */
static void family_constructor(struct nl_object *c)
{
@@ -166,18 +166,32 @@ static int family_compare(struct nl_object *_a, struct nl_object *_b,
return diff;
}
-
+/** @endcond */
/**
- * @name Family Object
+ * @name Object Allocation
* @{
*/
+/**
+ * Allocate new Generic Netlink family object
+ *
+ * @return Newly allocated Generic Netlink family object or NULL.
+ */
struct genl_family *genl_family_alloc(void)
{
return (struct genl_family *) nl_object_alloc(&genl_family_ops);
}
+/**
+ * Release reference on Generic Netlink family object
+ * @arg family Generic Netlink family object
+ *
+ * Reduces the reference counter of a Generic Netlink family object by one.
+ * The object is freed after the last user has returned its reference.
+ *
+ * @see nl_object_put()
+ */
void genl_family_put(struct genl_family *family)
{
nl_object_put((struct nl_object *) family);
@@ -186,10 +200,16 @@ void genl_family_put(struct genl_family *family)
/** @} */
/**
- * @name Attributes
+ * @name Numeric Identifier
* @{
*/
+/**
+ * Return numeric identifier
+ * @arg family Generic Netlink family object
+ *
+ * @return Numeric identifier or 0 if not available.
+ */
unsigned int genl_family_get_id(struct genl_family *family)
{
if (family->ce_mask & FAMILY_ATTR_ID)
@@ -198,12 +218,30 @@ unsigned int genl_family_get_id(struct genl_family *family)
return GENL_ID_GENERATE;
}
+/**
+ * Set the numeric identifier
+ * @arg family Generic Netlink family object
+ * @arg id New numeric identifier
+ */
void genl_family_set_id(struct genl_family *family, unsigned int id)
{
family->gf_id = id;
family->ce_mask |= FAMILY_ATTR_ID;
}
+/** @} */
+
+/**
+ * @name Human Readable Name
+ * @{
+ */
+
+/**
+ * Return human readable name
+ * @arg family Generic Netlink family object
+ *
+ * @return Name of family or NULL if not available
+ */
char *genl_family_get_name(struct genl_family *family)
{
if (family->ce_mask & FAMILY_ATTR_NAME)
@@ -212,12 +250,28 @@ char *genl_family_get_name(struct genl_family *family)
return NULL;
}
+/**
+ * Set human readable name
+ * @arg family Generic Netlink family object
+ * @arg name New human readable name
+ */
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;
}
+/**
+ * @name Interface Version
+ * @{
+ */
+
+/**
+ * Return interface version
+ * @arg family Generic Netlink family object
+ *
+ * @return Interface version or 0 if not available.
+ */
uint8_t genl_family_get_version(struct genl_family *family)
{
if (family->ce_mask & FAMILY_ATTR_VERSION)
@@ -226,12 +280,30 @@ uint8_t genl_family_get_version(struct genl_family *family)
return 0;
}
+/**
+ * Set interface version
+ * @arg family Generic Netlink family object
+ * @arg version New interface version
+ */
void genl_family_set_version(struct genl_family *family, uint8_t version)
{
family->gf_version = version;
family->ce_mask |= FAMILY_ATTR_VERSION;
}
+/** @} */
+
+/**
+ * @name Header Size
+ * @{
+ */
+
+/**
+ * Return user header size expected by kernel component
+ * @arg family Generic Netlink family object
+ *
+ * @return Expected header length or 0 if not available.
+ */
uint32_t genl_family_get_hdrsize(struct genl_family *family)
{
if (family->ce_mask & FAMILY_ATTR_HDRSIZE)
@@ -246,6 +318,13 @@ void genl_family_set_hdrsize(struct genl_family *family, uint32_t hdrsize)
family->ce_mask |= FAMILY_ATTR_HDRSIZE;
}
+/** @} */
+
+/**
+ * @name Maximum Expected Attribute
+ * @{
+ */
+
uint32_t genl_family_get_maxattr(struct genl_family *family)
{
if (family->ce_mask & FAMILY_ATTR_MAXATTR)
@@ -260,6 +339,13 @@ void genl_family_set_maxattr(struct genl_family *family, uint32_t maxattr)
family->ce_mask |= FAMILY_ATTR_MAXATTR;
}
+/** @} */
+
+/**
+ * @name Operations
+ * @{
+ */
+
int genl_family_add_op(struct genl_family *family, int id, int flags)
{
struct genl_family_op *op;
diff --git a/lib/genl/genl.c b/lib/genl/genl.c
index 6e6a764..efe1996 100644
--- a/lib/genl/genl.c
+++ b/lib/genl/genl.c
@@ -12,80 +12,6 @@
/**
* @defgroup genl Generic Netlink Library (libnl-genl)
*
- * @par Message Format
- * @code
- * <------- NLMSG_ALIGN(hlen) ------> <---- NLMSG_ALIGN(len) --->
- * +----------------------------+- - -+- - - - - - - - - - -+- - -+
- * | Header | Pad | Payload | Pad |
- * | struct nlmsghdr | | | |
- * +----------------------------+- - -+- - - - - - - - - - -+- - -+
- * @endcode
- * @code
- * <-------- GENL_HDRLEN -------> <--- hdrlen -->
- * <------- genlmsg_len(ghdr) ------>
- * +------------------------+- - -+---------------+- - -+------------+
- * | Generic Netlink Header | Pad | Family Header | Pad | Attributes |
- * | struct genlmsghdr | | | | |
- * +------------------------+- - -+---------------+- - -+------------+
- * genlmsg_data(ghdr)--------------^ ^
- * genlmsg_attrdata(ghdr, hdrlen)-------------------------
- * @endcode
- *
- * @par Example
- * @code
- * #include <netlink/netlink.h>
- * #include <netlink/genl/genl.h>
- * #include <netlink/genl/ctrl.h>
- *
- * struct nl_sock *sock;
- * struct nl_msg *msg;
- * int family;
- *
- * // Allocate a new netlink socket
- * sock = nl_socket_alloc();
- *
- * // Connect to generic netlink socket on kernel side
- * genl_connect(sock);
- *
- * // Ask kernel to resolve family name to family id
- * family = genl_ctrl_resolve(sock, "generic_netlink_family_name");
- *
- * // Construct a generic netlink by allocating a new message, fill in
- * // the header and append a simple integer attribute.
- * msg = nlmsg_alloc();
- * genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_ECHO,
- * CMD_FOO_GET, FOO_VERSION);
- * nla_put_u32(msg, ATTR_FOO, 123);
- *
- * // Send message over netlink socket
- * nl_send_auto_complete(sock, msg);
- *
- * // Free message
- * nlmsg_free(msg);
- *
- * // Prepare socket to receive the answer by specifying the callback
- * // function to be called for valid messages.
- * nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, parse_cb, NULL);
- *
- * // Wait for the answer and receive it
- * nl_recvmsgs_default(sock);
- *
- * static int parse_cb(struct nl_msg *msg, void *arg)
- * {
- * struct nlmsghdr *nlh = nlmsg_hdr(msg);
- * struct nlattr *attrs[ATTR_MAX+1];
- *
- * // Validate message and parse attributes
- * genlmsg_parse(nlh, 0, attrs, ATTR_MAX, policy);
- *
- * if (attrs[ATTR_FOO]) {
- * uint32_t value = nla_get_u32(attrs[ATTR_FOO]);
- * ...
- * }
- *
- * return 0;
- * }
- * @endcode
* @{
*/
@@ -95,10 +21,27 @@
#include <netlink/utils.h>
/**
- * @name Socket Creating
+ * @name Generic Netlink Socket
* @{
*/
+/**
+ * Connect a Generic Netlink socket
+ * @arg sk Unconnected Netlink socket
+ *
+ * This function expects a struct nl_socket object previously allocated via
+ * nl_socket_alloc(). It calls nl_connect() to create the local socket file
+ * descriptor and binds the socket to the \c NETLINK_GENERIC Netlink protocol.
+ *
+ * Using this function is equivalent to:
+ * @code
+ * nl_connect(sk, NETLINK_GENERIC);
+ * @endcode
+ *
+ * @see nl_connect()
+ *
+ * @return 0 on success or a negative error code.
+ */
int genl_connect(struct nl_sock *sk)
{
return nl_connect(sk, NETLINK_GENERIC);
@@ -107,20 +50,34 @@ int genl_connect(struct nl_sock *sk)
/** @} */
/**
- * @name Sending
+ * @name Sending Data
* @{
*/
/**
- * Send trivial generic netlink message
- * @arg sk Netlink socket.
- * @arg family Generic netlink family
- * @arg cmd Command
- * @arg version Version
- * @arg flags Additional netlink message flags.
+ * Send a Generic Netlink message consisting only of a header
+ * @arg sk Generic Netlink socket
+ * @arg family Numeric family identifier
+ * @arg cmd Numeric command identifier
+ * @arg version Interface version
+ * @arg flags Additional Netlink message flags (optional)
+ *
+ * This function is a shortcut for sending a Generic Netlink message without
+ * any message payload. The message will only consist of the Netlink and
+ * Generic Netlink headers. The header is constructed based on the specified
+ * parameters and passed on to nl_send_simple() to send it on the specified
+ * socket.
*
- * Fills out a routing netlink request message and sends it out
- * using nl_send_simple().
+ * @par Example:
+ * @code
+ * #include <netlink/genl/genl.h>
+ * #include <linux/genetlink.h>
+ *
+ * err = genl_send_simple(sk, GENL_ID_CTRL, CTRL_CMD_GETFAMILY, CTRL_VERSION,
+ * NLM_F_DUMP);
+ * @endcode
+ *
+ * @see nl_send_simple()
*
* @return 0 on success or a negative error code.
*/
@@ -137,12 +94,26 @@ int genl_send_simple(struct nl_sock *sk, int family, int cmd,
/** @} */
-
/**
* @name Message Parsing
* @{
*/
+/**
+ * Validate Generic Netlink message headers
+ * @arg nlh Pointer to Netlink message header
+ * @arg hdrlen Length of user header
+ *
+ * Verifies the integrity of the Netlink and Generic Netlink headers by
+ * enforcing the following requirements:
+ * - Valid Netlink message header (nlmsg_valid_hdr())
+ * - Presence of a complete Generic Netlink header
+ * - At least \c hdrlen bytes of payload included after the generic
+ * netlink header.
+ *
+ * @return A positive integer (true) if the headers are valid or
+ * 0 (false) if not.
+ */
int genlmsg_valid_hdr(struct nlmsghdr *nlh, int hdrlen)
{
struct genlmsghdr *ghdr;
@@ -157,8 +128,28 @@ int genlmsg_valid_hdr(struct nlmsghdr *nlh, int hdrlen)
return 1;
}
+/**
+ * Validate Generic Netlink message including attributes
+ * @arg nlh Pointer to Netlink message header
+ * @arg hdrlen Length of user header
+ * @arg maxtype Maximum attribtue id expected
+ * @arg policy Attribute validation policy
+ *
+ * Verifies the validity of the Netlink and Generic Netlink headers using
+ * genlmsg_valid_hdr() and calls nla_validate() on the message payload to
+ * verify the integrity of eventual attributes.
+ *
+ * @note You may call genlmsg_parse() directly to perform validation and
+ * parsing in a single step.
+ *
+ * @see genlmsg_valid_hdr()
+ * @see nla_validate()
+ * @see genlmsg_parse()
+ *
+ * @return 0 on success or a negative error code.
+ */
int genlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype,
- struct nla_policy *policy)
+ struct nla_policy *policy)
{
struct genlmsghdr *ghdr;
@@ -170,6 +161,33 @@ int genlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype,
genlmsg_attrlen(ghdr, hdrlen), maxtype, policy);
}
+/**
+ * Parse Generic Netlink message including attributes
+ * @arg nlh Pointer to Netlink message header
+ * @arg hdrlen Length of user header
+ * @arg tb Array to store parsed attributes
+ * @arg maxtype Maximum attribute id expected
+ * @arg policy Attribute validation policy
+ *
+ * Verifies the validity of the Netlink and Generic Netlink headers using
+ * genlmsg_valid_hdr() and calls nla_parse() on the message payload to
+ * parse eventual attributes.
+ *
+ * @par Example:
+ * @code
+ * struct nlattr *attrs[MY_TYPE_MAX+1];
+ *
+ * if ((err = genlsmg_parse(nlmsg_nlh(msg), sizeof(struct my_hdr), attrs,
+ * MY_TYPE_MAX, attr_policy)) < 0)
+ * // ERROR
+ * @endcode
+ *
+ * @see genlmsg_valid_hdr()
+ * @see genlmsg_validate()
+ * @see nla_parse()
+ *
+ * @return 0 on success or a negative error code.
+ */
int genlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[],
int maxtype, struct nla_policy *policy)
{
@@ -184,29 +202,44 @@ int genlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[],
}
/**
- * Get head of message payload
- * @arg gnlh genetlink messsage header
+ * Return pointer to message payload
+ * @arg gnlh Generic Netlink message header
+ *
+ * Calculates the pointer to the message payload based on the pointer
+ * to the generic netlink message header.
+ *
+ * @note Depending on whether your own message format uses a header, the
+ * returned pointer may in fact point to the user header.
+ *
+ * @return Pointer to generic netlink message
*/
void *genlmsg_data(const struct genlmsghdr *gnlh)
{
return ((unsigned char *) gnlh + GENL_HDRLEN);
}
+
/**
- * Get lenght of message payload
- * @arg gnlh genetlink message header
+ * Return length of message payload
+ * @arg gnlh Generic Netlink message header
+ *
+ * @return Length of user payload including an eventual user header in
+ * number of bytes.
*/
int genlmsg_len(const struct genlmsghdr *gnlh)
{
- struct nlmsghdr *nlh = (struct nlmsghdr *)((unsigned char *)gnlh -
- NLMSG_HDRLEN);
+ struct nlmsghdr *nlh;
+
+ nlh = (struct nlmsghdr *)((unsigned char *) gnlh - NLMSG_HDRLEN);
return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
}
/**
- * Get head of attribute data
- * @arg gnlh generic netlink message header
- * @arg hdrlen length of family specific header
+ * Return pointer to message attributes
+ * @arg gnlh Generic Netlink message header
+ * @arg hdrlen Length of user header
+ *
+ * @return Pointer to the start of the message's attributes section.
*/
struct nlattr *genlmsg_attrdata(const struct genlmsghdr *gnlh, int hdrlen)
{
@@ -214,9 +247,12 @@ struct nlattr *genlmsg_attrdata(const struct genlmsghdr *gnlh, int hdrlen)
}
/**
- * Get length of attribute data
- * @arg gnlh generic netlink message header
- * @arg hdrlen length of family specific header
+ * Return length of message attributes
+ * @arg gnlh Generic Netlink message header
+ * @arg hdrlen Length of user header
+ *
+ * @return Length of the message section containing attributes in number
+ * of bytes.
*/
int genlmsg_attrlen(const struct genlmsghdr *gnlh, int hdrlen)
{
@@ -226,24 +262,45 @@ int genlmsg_attrlen(const struct genlmsghdr *gnlh, int hdrlen)
/** @} */
/**
- * @name Message Building
+ * @name Message Construction
* @{
*/
/**
- * Add generic netlink header to netlink message
- * @arg msg netlink message
- * @arg pid netlink process id or NL_AUTO_PID
- * @arg seq sequence number of message or NL_AUTO_SEQ
- * @arg family generic netlink family
- * @arg hdrlen length of user specific header
- * @arg flags message flags
- * @arg cmd generic netlink command
- * @arg version protocol version
- *
- * Returns pointer to user specific header.
+ * Add Generic Netlink headers to Netlink message
+ * @arg msg Netlink message object
+ * @arg port Netlink port or NL_AUTO_PORT
+ * @arg seq Sequence number of message or NL_AUTO_SEQ
+ * @arg family Numeric family identifier
+ * @arg hdrlen Length of user header
+ * @arg flags Additional Netlink message flags (optional)
+ * @arg cmd Numeric command identifier
+ * @arg version Interface version
+ *
+ * Calls nlmsg_put() on the specified message object to reserve space for
+ * the Netlink header, the Generic Netlink header, and a user header of
+ * specified length. Fills out the header fields with the specified
+ * parameters.
+ *
+ * @par Example:
+ * @code
+ * struct nl_msg *msg;
+ * struct my_hdr *user_hdr;
+ *
+ * if (!(msg = nlmsg_alloc()))
+ * // ERROR
+ *
+ * user_hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, family_id,
+ * sizeof(struct my_hdr), 0, MY_CMD_FOO, 0);
+ * if (!user_hdr)
+ * // ERROR
+ * @endcode
+ *
+ * @see nlmsg_put()
+ *
+ * Returns Pointer to user header or NULL if an error occurred.
*/
-void *genlmsg_put(struct nl_msg *msg, uint32_t pid, uint32_t seq, int family,
+void *genlmsg_put(struct nl_msg *msg, uint32_t port, uint32_t seq, int family,
int hdrlen, int flags, uint8_t cmd, uint8_t version)
{
struct nlmsghdr *nlh;
@@ -252,7 +309,7 @@ void *genlmsg_put(struct nl_msg *msg, uint32_t pid, uint32_t seq, int family,
.version = version,
};
- nlh = nlmsg_put(msg, pid, seq, family, GENL_HDRLEN + hdrlen, flags);
+ nlh = nlmsg_put(msg, port, seq, family, GENL_HDRLEN + hdrlen, flags);
if (nlh == NULL)
return NULL;
diff --git a/lib/genl/mngt.c b/lib/genl/mngt.c
index 963d497..fd1aa03 100644
--- a/lib/genl/mngt.c
+++ b/lib/genl/mngt.c
@@ -6,77 +6,15 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
/**
* @ingroup genl
- * @defgroup genl_mngt Management
+ * @defgroup genl_mngt Family and Operations Management
*
- * @par 1) Registering a generic netlink module
- * @code
- * #include <netlink/genl/mngt.h>
+ * Registering Generic Netlink Families and Commands
*
- * // First step is to define all the commands being used in
- * // particular generic netlink family. The ID and name are
- * // mandatory to be filled out. A callback function and
- * // most the attribute policy that comes with it must be
- * // defined for commands expected to be issued towards
- * // userspace.
- * static struct genl_cmd foo_cmds[] = {
- * {
- * .c_id = FOO_CMD_NEW,
- * .c_name = "NEWFOO" ,
- * .c_maxattr = FOO_ATTR_MAX,
- * .c_attr_policy = foo_policy,
- * .c_msg_parser = foo_msg_parser,
- * },
- * {
- * .c_id = FOO_CMD_DEL,
- * .c_name = "DELFOO" ,
- * },
- * };
- *
- * // The list of commands must then be integrated into a
- * // struct genl_ops serving as handle for this particular
- * // family.
- * static struct genl_ops my_genl_ops = {
- * .o_cmds = foo_cmds,
- * .o_ncmds = ARRAY_SIZE(foo_cmds),
- * };
- *
- * // Using the above struct genl_ops an arbitary number of
- * // cache handles can be associated to it.
- * //
- * // The macro GENL_HDRSIZE() must be used to specify the
- * // length of the header to automatically take headers on
- * // generic layers into account.
- * //
- * // The macro GENL_FAMILY() is used to represent the generic
- * // netlink family id.
- * static struct nl_cache_ops genl_foo_ops = {
- * .co_name = "genl/foo",
- * .co_hdrsize = GENL_HDRSIZE(sizeof(struct my_hdr)),
- * .co_msgtypes = GENL_FAMILY(GENL_ID_GENERATE, "foo"),
- * .co_genl = &my_genl_ops,
- * .co_protocol = NETLINK_GENERIC,
- * .co_request_update = foo_request_update,
- * .co_obj_ops = &genl_foo_ops,
- * };
- *
- * // Finally each cache handle for a generic netlink family
- * // must be registered using genl_register().
- * static void __init foo_init(void)
- * {
- * genl_register(&genl_foo_ops);
- * }
- *
- * // ... respectively unregsted again.
- * static void __exit foo_exit(void)
- * {
- * genl_unregister(&genl_foo_ops);
- * }
- * @endcode
* @{
*/
@@ -88,6 +26,8 @@
#include <netlink/genl/ctrl.h>
#include <netlink/utils.h>
+/** @cond SKIP */
+
static NL_LIST_HEAD(genl_ops_list);
static int genl_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
@@ -159,15 +99,18 @@ char *genl_op2name(int family, int op, char *buf, size_t len)
return NULL;
}
+/** @endcond */
/**
- * @name Register/Unregister
+ * @name Registration (Cache Based)
* @{
*/
/**
- * Register generic netlink operations
- * @arg ops cache operations
+ * Register Generic Netlink family backed cache
+ * @arg ops Cache operations definition
+ *
+ * @return 0 on success or a negative error code.
*/
int genl_register(struct nl_cache_ops *ops)
{
@@ -203,8 +146,8 @@ errout:
}
/**
- * Unregister generic netlink operations
- * @arg ops cache operations
+ * Unregister cache based Generic Netlink family
+ * @arg ops Cache operations definition
*/
void genl_unregister(struct nl_cache_ops *ops)
{
@@ -217,11 +160,7 @@ void genl_unregister(struct nl_cache_ops *ops)
/** @} */
-/**
- * @name Resolving ID/Name
- * @{
- */
-
+/** @cond SKIP */
static int __genl_ops_resolve(struct nl_cache *ctrl, struct genl_ops *ops)
{
struct genl_family *family;
@@ -236,7 +175,22 @@ static int __genl_ops_resolve(struct nl_cache *ctrl, struct genl_ops *ops)
return -NLE_OBJ_NOTFOUND;
}
+/** @endcond */
+
+/**
+ * @name Resolving the name of registered families
+ * @{
+ */
+/**
+ * Resolve a single Generic Netlink family
+ * @arg sk Generic Netlink socket
+ * @arg ops Generic Netlink family definition
+ *
+ * Resolves the family name to its numeric identifier.
+ *
+ * @return 0 on success or a negative error code.
+ */
int genl_ops_resolve(struct nl_sock *sk, struct genl_ops *ops)
{
struct nl_cache *ctrl;
@@ -252,6 +206,19 @@ errout:
return err;
}
+/**
+ * Resolve all registered Generic Netlink families
+ * @arg sk Generic Netlink socket
+ *
+ * Walks through all local Generic Netlink families that have been registered
+ * using genl_register() and resolves the name of each family to the
+ * corresponding numeric identifier.
+ *
+ * @see genl_register()
+ * @see genl_ops_resolve()
+ *
+ * @return 0 on success or a negative error code.
+ */
int genl_mngt_resolve(struct nl_sock *sk)
{
struct nl_cache *ctrl;
@@ -272,5 +239,4 @@ errout:
/** @} */
-
/** @} */