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 <[EMAIL PROTECTED]> 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");