标签:
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