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