Forum Programmation.c Generic Netlink

Posté par  .
Étiquettes : aucune
0
13
nov.
2007
Salut,


J'essaye de me servir des fonctionnalités de la Generic Netlink pour dialoguer entre mon module noyau et des processus utilisateurs.


Je me suis inspirer de la doc http://www.linux-foundation.org/en/Net:Generic_Netlink_HOWTO et de code du noyau (taskstats.c, acpi.c) pour reproduire un exemple de base avant de l'incorporer dans mon module.
Mais je n'arrive pas à faire fonctionner cet exemple de base :



#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",
};

struct test {
char name[15];
u32 num;
};

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

size = nla_total_size(0);
printk("size = %i\n", size);

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 */
rc = genlmsg_end(skb, msg_head);
if (rc < 0) {
printk("error on genlmsg_end\n");
goto failure;
}

rc = genlmsg_multicast(skb, 0, event_mcgrp_echo.id, GFP_KERNEL);
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;
}

err = send();

return err;
}

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");


Je travail avec un noyau 2.6.23 et sur deux architecture différentes (x86, armv5b)


Sur le x86, la fonction "genlmsg_multicast" me retourne l'erreur ESRCH


Sur la carte arm, la fonction "genlmsg_put" retourne une pointeur NULL.


Une idée du problème, un oublis ... ?

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.