标签:
1. Registering a family
Registering a family is including four steps: define the family, define operations, register the family, register the operations.
/* attributes */
enum {
DOC_EXMPL_A_UNSPEC,
DOC_EXMPL_A_MSG,
__DOC_EXMPL_A_MAX,
};
#define DOC_EXMPL_A_MAX (__DOC_EXMPL_A_MAX - 1)
/* attribute policy */
static struct nla_policy doc_exmpl_genl_policy[DOC_EXMPL_A_MAX + 1] = {
[DOC_EXMPL_A_MSG] = { .type = NLA_NUL_STRING },
};
/* family definition */
static struct genl_family doc_exmpl_genl_family = {
.id = GENL_ID_GENERATE,
.hdrsize = 0,
.name = "DOC_EXMPL",
.version = 1,
.maxattr = DOC_EXMPL_A_MAX,
};
We define a new family and the family recognizes a single attribute, DOC_EXMPL_A_MSG, which is a NULL terminated string. The GENL_ID_GENERATE macro/constant is really just the value 0x0 and it signifies that we want the Generic Netlink controller to assign the channel number when we register the family.
/* handler */
static int doc_exmpl_echo(struct sk_buff *skb, struct genl_info *info)
{
/* message handling code goes here;
return 0 on success, negative value on failure
*/
}
/* commands */
enum {
DOC_EXMPL_C_UNSPEC,
DOC_EXMPL_C_ECHO,
__DOC_EXMPL_C_MAX,
};
#define DOC_EXMPL_C_MAX (__DOC_EXMPL_C_MAX - 1)
/* operation definition */
static struct genl_ops doc_exmpl_genl_ops_echo = {
.cmd = DOC_EXMPL_C_ECHO,
.flags = 0,
.policy = doc_exmpl_genl_policy,
.dumpit = NULL,
};
Here we defined a single operation, DOC_EXMPL_C_ECHO, which uses the Netlink attribute policy we defined above. Once registered, this particular operation would call the doc_exmpl_echo() function whenever a DOC_EXMPL_C_ECHO message is sent to the DOC_EXMPL family over the Generic Netlink bus.
int rc;
rc = genl_register_family(&doc_exmpl_gnl_family);
if (rc != 0)
goto failure;
This call registers the new family name with the Generic Netlink mechanism and requests a new channel number which is stored in the genl_family struct, replacing the GENL_ID_GENERATE value.
int rc;
rc = genl_register_ops(&doc_exmpl_gnl_family, &doc_exmpl_gnl_ops_echo);
if (rc != 0)
goto failure;
This call registers the DOC_EXMPL_C_ECHO operation in association with the DOC_EXMPL family. After this, other Generic Netlink users can now issue DOC_EXMPL_C_ECHO commands and they will be handled as desired.
2. Kernel communication
struct sk_buff *skb;
skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
if (skb == NULL)
goto failure;
NLMSG_GOODSIZE is a good value to use when you don‘t know the size of the message buffer at the time of allocation. The genlmsg_new() function automatically adds space for the Netlink and Generic Netlink message headers.
int rc;
void *msg_head;
/* create the message headers */
msg_head = genlmsg_put(skb, pid, seq, type, 0, flags, DOC_EXMPL_C_ECHO, 1);
if (msg_head == NULL) {
rc = -ENOMEM;
goto failure;
}
/* add a DOC_EXMPL_A_MSG attribute */
rc = nla_put_string(skb, DOC_EXMPL_A_MSG, "Generic Netlink Rocks");
if (rc != 0)
goto failure;
/* finalize the message */
genlmsg_end(skb, msg_head);
The genlmsg_put() function creates the required Netlink and Generic Netlink message headers, populating them with the given values; The nla_put_string() function is a standard Netlink attribute which adds a string attribute to the end of the Netlink message. The genlmsg_end() function updates the Netlink message header once the message payload has been finalized.
int rc; rc = genlmsg_unicast(skb, pid); if (rc != 0) goto failure;
标签:
原文地址:http://www.cnblogs.com/memo-store/p/5529050.html