]> granicus.if.org Git - libnl/commitdiff
genl: updates to API reference documentation
authorThomas Graf <tgraf@redhat.com>
Thu, 31 May 2012 11:11:48 +0000 (13:11 +0200)
committerThomas Graf <tgraf@redhat.com>
Thu, 31 May 2012 11:11:48 +0000 (13:11 +0200)
include/netlink/genl/ctrl.h
include/netlink/genl/family.h
include/netlink/genl/genl.h
include/netlink/genl/mngt.h
lib/genl/ctrl.c
lib/genl/family.c
lib/genl/genl.c
lib/genl/mngt.c

index 26a0a9967b47dfe8ab503e92369ad7712eb425e5..017b8fdfc5b0011a60fcb9b891ccd5c7d1ebeb69 100644 (file)
@@ -6,7 +6,7 @@
  *     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>
  */
 
 #ifndef NETLINK_GENL_CTRL_H_
index 721dc13d621bd49bf6e15839c77c09efb88e9de3..5432b5945681b449fe096cd7586dcfb7dc0e3d5c 100644 (file)
@@ -6,7 +6,7 @@
  *     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>
  */
 
 #ifndef NETLINK_GENL_FAMILY_H_
@@ -25,25 +25,19 @@ extern struct genl_family * genl_family_alloc(void);
 extern void                    genl_family_put(struct genl_family *);
 
 extern unsigned int            genl_family_get_id(struct genl_family *);
-extern void                    genl_family_set_id(struct genl_family *,
-                                                  unsigned int);
+extern void                    genl_family_set_id(struct genl_family *, unsigned int);
 extern char *                  genl_family_get_name(struct genl_family *);
-extern void                    genl_family_set_name(struct genl_family *,
-                                                    const char *name);
+extern void                    genl_family_set_name(struct genl_family *, const char *);
 extern uint8_t                 genl_family_get_version(struct genl_family *);
-extern void                    genl_family_set_version(struct genl_family *,
-                                                       uint8_t);
+extern void                    genl_family_set_version(struct genl_family *, uint8_t);
 extern uint32_t                        genl_family_get_hdrsize(struct genl_family *);
-extern void                    genl_family_set_hdrsize(struct genl_family *,
-                                                       uint32_t);
+extern void                    genl_family_set_hdrsize(struct genl_family *, uint32_t);
 extern uint32_t                        genl_family_get_maxattr(struct genl_family *);
-extern void                    genl_family_set_maxattr(struct genl_family *,
-                                                       uint32_t);
+extern void                    genl_family_set_maxattr(struct genl_family *, uint32_t);
 
-extern int                     genl_family_add_op(struct genl_family *,
-                                                  int, int);
-extern int                     genl_family_add_grp(struct genl_family *,
-                                       uint32_t , const char *);
+extern int                     genl_family_add_op(struct genl_family *, int, int);
+extern int                     genl_family_add_grp(struct genl_family *, uint32_t ,
+                                                   const char *);
 
 
 #ifdef __cplusplus
index 364a4718c6048dbf530deb8fa1df8be43ea98a72..a2da94350d4f867dbce2d0eb5d0cfdd2afc8d81f 100644 (file)
@@ -6,7 +6,7 @@
  *     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>
  */
 
 #ifndef NETLINK_GENL_H_
@@ -32,6 +32,8 @@ 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 struct genlmsghdr *
+                       genlmsg_hdr(struct nlmsghdr *);
 extern void *          genlmsg_data(const struct genlmsghdr *);
 extern int             genlmsg_len(const struct genlmsghdr *);
 extern struct nlattr * genlmsg_attrdata(const struct genlmsghdr *, int);
index 8b0244f2cca13a7c3c13c851830a57e3608b09b4..18d3866b81418d1744b7dcad6da7c7ca9b417303 100644 (file)
@@ -6,7 +6,7 @@
  *     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>
  */
 
 #ifndef NETLINK_GENL_MNGT_H_
@@ -22,57 +22,124 @@ extern "C" {
 
 struct nl_cache_ops;
 
+/**
+ * @ingroup genl_mngt
+ * @struct genl_info netlink/genl/mngt.h
+ *
+ * Informative structure passed on to message parser callbacks
+ *
+ * This structure is passed on to all message parser callbacks and contains
+ * information about the sender of the message as well as pointers to all
+ * relevant sections of the parsed message.
+ *
+ * @see genl_cmd::c_msg_parser
+ */
 struct genl_info
 {
+       /** Socket address of sender */
        struct sockaddr_nl *    who;
+
+       /** Pointer to Netlink message header */
        struct nlmsghdr *       nlh;
+
+       /** Pointer to Generic Netlink message header */
        struct genlmsghdr *     genlhdr;
+
+       /** Pointer to user header */
        void *                  userhdr;
+
+       /** Pointer to array of parsed attributes */
        struct nlattr **        attrs;
 };
 
 /**
  * @ingroup genl_mngt
- * Generic Netlink Command
+ * @struct genl_cmd netlink/genl/mngt.h
+ *
+ * Definition of a Generic Netlink command.
+ *
+ * This structure is used to define the list of available commands on the
+ * receiving side.
+ *
+ * @par Example:
+ * @code
+ * 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" ,
+ *     },
+ * };
+ *
+ * static struct genl_ops my_genl_ops = {
+ *     [...]
+ *     .o_cmds                 = foo_cmds,
+ *     .o_ncmds                = ARRAY_SIZE(foo_cmds),
+ * };
+ * @endcode
  */
 struct genl_cmd
 {
-       /** Unique command identifier */
+       /** Numeric command identifier (required) */
        int                     c_id;
 
-       /** Name/description of command */
+       /** Human readable name  (required) */
        char *                  c_name;
 
-       /**
-        * Maximum attribute identifier, must be provided if
-        * a message parser is available.
-        */
+       /** Maximum attribute identifier that the command is prepared to handle. */
        int                     c_maxattr;
 
+       /** Called whenever a message for this command is received */
        int                   (*c_msg_parser)(struct nl_cache_ops *,
                                              struct genl_cmd *,
                                              struct genl_info *, void *);
 
-       /**
-        * Attribute validation policy (optional)
-        */
+       /** Attribute validation policy, enforced before the callback is called */
        struct nla_policy *     c_attr_policy;
 };
 
 /**
  * @ingroup genl_mngt
- * Generic Netlink Operations
+ * @struct genl_ops netlink/genl/mngt.h
+ *
+ * Definition of a Generic Netlink family
+ *
+ * @see genl_cmd
  */
 struct genl_ops
 {
        int                     o_family;
+
+       /** Numeric identifier, automatically resolved by genl_mngt_resolve() */
        int                     o_id;
+
+       /** Human readable name, used to resolve to numeric identifier */
        char *                  o_name;
+
+       /**
+        * If registered via genl_register(), will point to the related
+        * cache operations.
+        */
        struct nl_cache_ops *   o_cache_ops;
+
+       /**
+        * Can point to an array of generic netlink commands definitions.
+        */
        struct genl_cmd *       o_cmds;
+
+       /** Size of \c o_cmds array */
        int                     o_ncmds;
 
-       /* linked list of all genl cache operations */
+       /**
+        * @private
+        * Used internally to link together all registered operations.
+        */
        struct nl_list_head     o_list;
 };
 
index 107a4fa0f67ef0dfc8c79ea1c9e789ad1d087660..ddb7603bffe88eae174a54e14ad33b3c15838839 100644 (file)
@@ -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 */
 
 /** @} */
index ebeebcbfa2f59d1c74beb680c81e42275ccc2354..64b98cdb8021b166fb4a32ba745c8ef3203ee240 100644 (file)
@@ -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;
index 6e6a76476c8616e4a32105e42a346abaab22de69..efe199627b2fcea34ef5b88632356ab3031f3c12 100644 (file)
 /**
  * @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
  * @{
  */
 
 #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;
 
index 963d497e2d49d90c9679da064ba603da5ff6e680..fd1aa03bfdd5acb45b5b7769a685215582efe310 100644 (file)
@@ -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:
 
 /** @} */
 
-
 /** @} */