diff options
author | Thomas Graf <tgraf@redhat.com> | 2012-05-31 11:11:48 (GMT) |
---|---|---|
committer | Thomas Graf <tgraf@redhat.com> | 2012-05-31 11:11:48 (GMT) |
commit | 0b70de5155ba74f152ebece230659e7890cccbd9 (patch) | |
tree | a15e0d5c150ca8a03036b19467e2990fa4b77370 /lib/genl | |
parent | d733f8a0a65a817d16ebaa1a8f5ad1330682b489 (diff) | |
download | libnl-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.c | 129 | ||||
-rw-r--r-- | lib/genl/family.c | 102 | ||||
-rw-r--r-- | lib/genl/genl.c | 281 | ||||
-rw-r--r-- | lib/genl/mngt.c | 118 |
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: /** @} */ - /** @} */ |