genl_ctrl_resolve failure
Ali Ranjbar
aranjbar4 at gmail.com
Mon Apr 9 17:07:47 EDT 2012
I have a user space program that I thought should work, but it fails when
it calls the genl_Ctrl_resolve (see below). Can anyone help me why? I am
using the libl 3.2.7. Both user space and kernel module compile and link. I
cut and paste it here, so I maybe missing a } or something, but don't focus
on that. Like I said, both programs compile and link, so no syntax issue.
Kernel side during the init calls the genl_register_family(),
genl_register_ops(), so I don't understand why when the user space call to
genl_ctrl_resolve() failes?
#include <stdio.h>
2 #include <netlink/netlink.h>
3 #include <netlink/genetlink.h>
4 #include <netlink/genl/genl.h>
5 #include <netlink/genl/ctrl.h>
6 #include <linux/errno.h>
int clear_ctf_table() {
58 struct nl_sock *sock;
59 struct nl_msg *msg;
60 int family;
61 printf("**************Entering the USER SPACE portion***\n");
62 /* Allocate a new netlink socket in userspace */
63 sock = nl_socket_alloc();
64 if(sock == NULL) {
65 printf("couldn't allocate socket\n");
66 goto out;
67 }
68
69 /* Connect to the generic netlink socket family in the kernel */
70 if (genl_connect(sock) < 0) {
71 printf("error while connecting\n");
72 goto out;
73 }
74
75 /* obtain the family id for the CONTROL_GUARDIAN family */
76 family = genl_ctrl_resolve(sock, "generic_netlink_family_name");
77 if (family < 0) {
78 printf("error obtaining family\n");
79 goto out;
80 }
........
It fails and prints "error obtaining family"
I followed the examples given and was expecting this to work.
On the kernel side I have the following code. The module is loaded in
kernel and I see the module is loaded in kernel and init passes
Kernel side code:
#include <net/netlink.h>
#include <net/genetlink.h>
#include <linux/module.h>
#include <linux/kernel.h>
/* attributes (variables): the index in this enum is used as a reference
for the type,
* userspace application has to indicate the corresponding type
* the policy is used for security considerations
*/
enum {
DOC_GUARD_ATT_UNSPEC,
DOC_GUARD_ATT_MSG,
__DOC_GUARD_ATT_MAX,
};
#define DOC_GUARD_ATT_MAX (__DOC_GUARD_ATT_MAX - 1)
/* attribute policy: defines which attribute has which type (e.g int, char
* etc)
* possible values defined in net/netlink.h
*/
static struct nla_policy doc_exmpl_genl_policy[DOC_GUARD_ATT_MAX + 1] = {
[DOC_GUARD_ATT_MSG] = { .type = NLA_NUL_STRING },
};
#define VERSION_NR 1
/* family definition */
static struct genl_family doc_exmpl_gnl_family = {
.id = GENL_ID_GENERATE, //genetlink should generate an id
.hdrsize = 0,
.name ="generic_netlink_family_name", //the name of this
family, used by userspace application
.version = VERSION_NR, //version number
.maxattr = DOC_GUARD_ATT_MAX,
};
/* commands: enumeration of all commands (functions),
* used by userspace application to identify command to be ececuted
*/
enum {
DOC_GUARD_COMM_UNSPEC,
DOC_GUARD_COMM_ECHO,
__DOC_GUARD_COMM_MAX,
};
#define DOC_GUARD_COMM_MAX (__DOC_GUARD_COMM_MAX - 1)
/* an echo command, receives a message, prints it and sends another message
back */
int guardian_exmpl_echo(struct sk_buff *skb_2, struct genl_info *info)
#include <net/netlink.h>
#include <net/genetlink.h>
#include <linux/module.h>
#include <linux/kernel.h>
/* attributes (variables): the index in this enum is used as a reference
for the type,
* userspace application has to indicate the corresponding type
* the policy is used for security considerations
*/
enum {
DOC_GUARD_ATT_UNSPEC,
DOC_GUARD_ATT_MSG,
__DOC_GUARD_ATT_MAX,
};
#define DOC_GUARD_ATT_MAX (__DOC_GUARD_ATT_MAX - 1)
/* attribute policy: defines which attribute has which type (e.g int, char
* etc)
* possible values defined in net/netlink.h
*/
static struct nla_policy doc_exmpl_genl_policy[DOC_GUARD_ATT_MAX + 1] = {
[DOC_GUARD_ATT_MSG] = { .type = NLA_NUL_STRING },
};
#define VERSION_NR 1
/* family definition */
static struct genl_family doc_exmpl_gnl_family = {
.id = GENL_ID_GENERATE, //genetlink should generate an id
.hdrsize = 0,
.name ="generic_netlink_family_name", //the name of this
family, used by userspace application
.version = VERSION_NR, //version number
.maxattr = DOC_GUARD_ATT_MAX,
};
/* commands: enumeration of all commands (functions),
* used by userspace application to identify command to be ececuted
*/
enum {
DOC_GUARD_COMM_UNSPEC,
DOC_GUARD_COMM_ECHO,
__DOC_GUARD_COMM_MAX,
};
#define DOC_GUARD_COMM_MAX (__DOC_GUARD_COMM_MAX - 1)
/* an echo command, receives a message, prints it and sends another message
back */
int guardian_exmpl_echo(struct sk_buff *skb_2, struct genl_info *info)
{
struct nlattr *na;
struct sk_buff *skb;
int rc;
void *msg_head;
char * mydata;
if (info == NULL)
goto out;
/*for each attribute there is an index in info->attrs which points
to a nlattr structure
*in this structure the data is given
*/
na = info->attrs[DOC_GUARD_ATT_MSG];
if (na) {
mydata = (char *)nla_data(na);
if (mydata == NULL)
printk("error while receiving data\n");
else
printk("received: %s\n", mydata);
}
else
printk("no info->attrs %i\n", DOC_GUARD_ATT_MSG);
/* send a message back*/
/* allocate some memory, since the size is not yet known use
NLMSG_GOODSIZE*/
skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
if (skb == NULL)
goto out;
/* create the message headers */
/* arguments of genlmsg_put:
struct sk_buff *,
int (sending) pid,
int sequence number,
struct genl_family *,
int flags,
u8 command index (why do we need this?)
*/
msg_head = genlmsg_put(skb, 0, info->snd_seq+1,
&doc_exmpl_gnl_family, 0, DOC_GUARD_COMM_ECHO);
if (msg_head == NULL) {
rc = -ENOMEM;
goto out;
}
/* add a DOC_GUARD_ATT_MSG attribute (actual value to be sent) */
rc = nla_put_string(skb, DOC_GUARD_ATT_MSG, "hello world from
kernel space");
if (rc != 0)
goto out;
/* finalize the message */
genlmsg_end(skb, msg_head);
/* send the message back */
rc = genlmsg_unicast(skb,info->snd_pid );
if (rc != 0)
goto out;
return 0;
out:
printk("an error occured in guardian_exmpl_echo:\n");
return 0;
}
/* commands: mapping between the command enumeration and the actual
function*/
struct genl_ops doc_exmpl_gnl_ops_echo = {
.cmd = DOC_GUARD_COMM_ECHO,
.flags = 0,
.policy = doc_exmpl_genl_policy,
.doit = guardian_exmpl_echo,
.dumpit = NULL,
};
static int __init gnKernel_init(void)
{
int rc;
printk("INIT GENERIC NETLINK EXEMPLE MODULE\n");
/*register new family*/
rc = genl_register_family(&doc_exmpl_gnl_family);
if (rc != 0)
goto failure;
printk("genl_register_family passed\n");
/*register functions (commands) of the new family*/
rc = genl_register_ops(&doc_exmpl_gnl_family,
&doc_exmpl_gnl_ops_echo);
if (rc != 0){
printk("register ops: %i\n",rc);
genl_unregister_family(&doc_exmpl_gnl_family);
goto failure;
135,2-16 71%
}
printk("genl_register_ops passed\n");
return 0;
failure:
printk("an error occured while inserting the generic netlink
example module\n");
return -1;
}
static void __exit gnKernel_exit(void)
{
int ret;
printk("EXIT GENERIC NETLINK GUARDIAN EXEMPLE MODULE\n");
/*unregister the functions*/
ret = genl_unregister_ops(&doc_exmpl_gnl_family,
&doc_exmpl_gnl_ops_echo);
if(ret != 0){
printk("unregister ops: %i\n",ret);
return;
}
/*unregister the family*/
ret = genl_unregister_family(&doc_exmpl_gnl_family);
if(ret !=0){
printk("unregister family %i\n",ret);
}
}
module_init(gnKernel_init);
module_exit(gnKernel_exit);
MODULE_LICENSE("GPL");
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20120409/884e46d7/attachment.html>
More information about the libnl
mailing list