Generic netlink

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I try to use the generic netlink functionalities in a kernel module.

I looked the doc http://www.linux-foundation.org/en/Net:Generic_Netlink_HOWTO and the source code of kernel/taskstats.c in the kernel.
I tried to reproduce the example of the doc (look in the attached file) but it doesn't work.

I work on a 2.6.23 kernel and on two different architectures, a classic x86 pc and a armv5b board.
On the PC the genlmsg_multicast function return an error (-3) and the system crash totally in the next 5 sec (hard reboot).
On the arm board, the genlmsg_put function return the NULL value, but the module is unload and the system stay stable.

Can you help me ?
Doude.
#include <linux/kernel.h>
#include <linux/module.h>
#include <net/sock.h>
#include <linux/netlink.h>
#include <linux/version.h>

#include <linux/rtnetlink.h>
#include <net/genetlink.h>

enum {
	DOC_EXMPL_C_UNSPEC = 0,
	DOC_EXMPL_C_ECHO,
	__DOC_EXMPL_C_MAX,
};
#define DOC_EXMPL_C_MAX (__DOC_EXMPL_C_MAX - 1)

enum {
	DOC_EXMPL_A_UNSPEC = 0,
	DOC_EXMPL_A_MSG,
	__DOC_EXMPL_A_MAX,
};
#define DOC_EXMPL_A_MAX (__DOC_EXMPL_A_MAX - 1)

static struct genl_family doc_exmpl_gnl_family = {
       .id = GENL_ID_GENERATE,
       .name = "DOC_EXMPL",
       .version = 1,
       .maxattr = DOC_EXMPL_A_MAX,
};

static struct nla_policy doc_exmpl_genl_policy[DOC_EXMPL_A_MAX+1] __read_mostly = {
     [DOC_EXMPL_A_MSG] = { .type = NLA_NUL_STRING },
};

static int doc_exmpl_echo(struct sk_buff *skb, struct genl_info *info)
{
	return 0;
}

static struct genl_ops doc_exmpl_gnl_ops_echo = {
       .cmd = DOC_EXMPL_C_ECHO,
       .policy = doc_exmpl_genl_policy,
       .doit = doc_exmpl_echo,
};

int send(void) {
	struct sk_buff *skb;
	int rc = 0;
	void *msg_head;

	skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (skb == NULL) {
		printk("error on genlmsg_new\n");
		return -ENOMEM;
	}

	/* create the message headers */
	msg_head = genlmsg_put(skb, 0, 0, &doc_exmpl_gnl_family, 0, DOC_EXMPL_C_ECHO);
	if (msg_head == NULL) {
		printk("error on genlmsg_put\n");
		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) {
		printk("error on nla_put_string\n");
		goto failure;
	}

	/* finalize the message */
	genlmsg_end(skb, msg_head);
	
	rc = genlmsg_multicast(skb, 0, 1, 0);
	if (rc != 0) {
		printk("error on genlmsg_multicast\n");
		goto failure;
	}

	return rc;

failure:
	printk("Failure\n");
	nlmsg_free(skb);
	genl_unregister_family(&doc_exmpl_gnl_family);
	return rc;

}

int init_mod(void) {
	int err = 0;

	err = genl_register_family(&doc_exmpl_gnl_family);
	if (err < 0) {
		printk("Error register family\n");
		return err;
	}

	printk("Family id : %i\n", doc_exmpl_gnl_family.id);
	
	if((err = genl_register_ops(&doc_exmpl_gnl_family, &doc_exmpl_gnl_ops_echo)) < 0) {
		genl_unregister_family(&doc_exmpl_gnl_family);
		printk("error register ops \n");
		return err;
	}

	return send();
}

static void __exit exit_mod(void) {
	genl_unregister_family(&doc_exmpl_gnl_family);

	printk(KERN_INFO "Goodbye\n");
}

module_init(init_mod);
module_exit(exit_mod);

MODULE_LICENSE("GPL");


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux