I tried this code from the acpi source but the problem still the same. I register the multicast group with "genl_register_mc_group" function and it works but the genlmsg_put function return NULL value on the arm board and the genlmsg_multicast function return ESRCH error on a x86 pc. On Nov 12, 2007 10:59 PM, Paul Moore <paul.moore@xxxxxx> wrote: > > On Monday 12 November 2007 11:47:04 am Edouard Thuleau wrote: > > 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. > > You might want to look at the ACPI code for some examples, a quick look at the > code shows that it uses Generic Netlink and multicast messages. > > -- > paul moore > linux security @ hp >
#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 genl_multicast_group event_mcgrp_echo = { .name = "mc_group_echo", }; int send(void) { struct sk_buff *skb; int rc = 0, size; void *msg_head; size = nla_total_size(0); skb = genlmsg_new(size, 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; } */ /* finalize the message */ genlmsg_end(skb, msg_head); rc = genlmsg_multicast(skb, 0, event_mcgrp_echo.id, GFP_ATOMIC); if (rc != 0) { printk("error on genlmsg_multicast %i\n", rc); 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); err = genl_register_mc_group(&doc_exmpl_gnl_family, &event_mcgrp_echo); if (err) { genl_unregister_family(&doc_exmpl_gnl_family); printk("error register multicast group \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");