Re: Netlink Socket: trouble while using netlink_broadcast

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

 



On Wed, Apr 15, 2009 at 8:32 PM, Thierry <chocapiiic.tiery@xxxxxxxxx> wrote:
> Hi,
>
>
> I have tried 3 solutions:
>
> 1. using nlh = (struct nlmsghdr *) skb_put(skb,
> NLMSG_SPACE(MAX_PAYLOAD)); instead of  nlh = (struct nlmsghdr
> *)skb->data;
> No kernel panic, but doesn't work (it is just like before)
>
> 2. with skb_copy_expand and skb_push like in the second example you
> gave me, No kernel panic, but doesn't work (juste like before)
>
> 3. with the example of wwrap.c (your last idea), doest compile, or kernel panic
> But i don't really now what I should put in *message type* argument in
>  NLMSG_PUT.
> My code for last solution is bellow.
>
> If never you have others ideas.
>
> Thierry
>
>
>

Have to debug one step at a time.   My first observation is that u did
not put the NLMSG_DONE as the type for your netlink message, which is
needed for last message.

Another hint possibly is due to alignment problem:

Yours is:

nlh = (struct nlmsghdr *) skb_put(skb, NLMSG_SPACE(MAX_PAYLOAD))

but kernel source showed something like this:

nlh = (struct nlmsghdr *) skb_put(skb, NLMSG_ALIGN(size))

might have to play around with different problem solving.........


> ------
>
>
>        struct sk_buff *skb = NULL;
>        struct nlmsghdr *nlh = NULL;
>        int err;
>        int size;
>        unsigned char * old_tail;
>        char * pos = NULL;
>        size = NLMSG_SPACE(MAX_PAYLOAD);
>        u32 pid;
>
>        //Creation de la netlink socket <=> socket()
>        nl_sk = netlink_kernel_create(NETLINK_IB, GROUP_IB, nl_ib_data_ready,
> THIS_MODULE);
>
>        skb = alloc_skb(NLMSG_SPACE(MAX_PAYLOAD),GFP_KERNEL);
>
> if (skb == NULL)
> {
>        printk(KERN_ALERT "erreur\n");
>        return;
> }
>        old_tail = skb -> tail;
>        //nlh = (struct nlmsghdr *)skb->data;
>        nlh = NLMSG_PUT(skb, 0, 0, 0, size-sizeof(*nlh));
>        int len = sizeof("Message du kernel =(");
>        pos = NLMSG_DATA(len);
>        memset(pos,0,len);
>
>        nlh->nlmsg_pid = 0; //Depuis le noyau
>        nlh->nlmsg_flags = 0;
>
>        strcpy(NLMSG_DATA(nlh), "Message du kernel =(");
>        NETLINK_CB(skb).pid = 0;
>        NETLINK_CB(skb).dst_pid = 0; //Multicast
>        NETLINK_CB(skb).dst_group = GROUP_IB;
>        nlh->nlmsg_len = skb->tail - old_tail;
>
>        //Envoi des donnees
>        printk( KERN_ALERT "j'envoi els donnees\n");
>         err = netlink_broadcast(nl_sk, skb, 0, GROUP_IB, GFP_KERNEL);
>
>
> On Fri, Apr 10, 2009 at 2:29 PM, Peter Teoh <htmldeveloper@xxxxxxxxx> wrote:
>> On Fri, Apr 10, 2009 at 4:12 AM, Thierry <chocapiiic.tiery@xxxxxxxxx> wrote:
>>> Hi,
>>>
>>> I have tried to change groupId, with different value, but there should
>>> be somethings wrong: the userspace prgm doesn't receive message.
>>> I would like to know if there is a plugin for tcpdump or an way of
>>> capture trafic on netlink socket, just like usual network socket in
>>> order to see were is my problem: in kernel space code or userspace
>>> code.
>>> My program code is attached, with english commit (sorry for last mail).
>>> I have also tried my code on differents kernel (redhat 4.4 with kernel
>>> 2.6.9-42.ELsmp, centos52 kernel 2.6.18-92.1.22).
>>>
>>> If there is other ways to send information from kernel space to user space...
>>> My aim is to capture data trafic from infiniband and dump trafic, for
>>> example in a netlink socket. Then I will be able with a userspace code
>>> to translate informations in .cap files.
>>> Thats why I think netlink_broadcast is a good idea.
>>>
>>> I will be always looking at kernelnewbie mailinglsit for several month,
>>>
>>> Regards,
>>>
>>> Thierry
>>>
>>>
>>>
>>> --------------
>>> kernel-level code
>>>
>>>
>>> #include <linux/config.h>
>>> #include <linux/socket.h>
>>> #include <linux/kernel.h>
>>> #include <linux/module.h>
>>> #include <linux/netlink.h>
>>> #include <net/sock.h>
>>>
>>> #define NETLINK_IB 24
>>> #define MAX_PAYLOAD 1024
>>> #define GROUP_IB 59
>>>
>>>
>>> static struct sock *nl_sk = NULL;
>>>
>>> static void nl_ib_data_ready (struct sock *sk, int len)
>>> {
>>>        wake_up_interruptible(sk->sk_sleep);
>>> }
>>>
>>> static void netlink_ib_open()
>>> {
>>>        struct sk_buff *skb = NULL;
>>>        struct nlmsghdr *nlh = NULL;
>>>        int err;
>>>        u32 pid;
>>>
>>>        //Socket_create
>>>        nl_sk = netlink_kernel_create(NETLINK_IB, GROUP_IB, nl_ib_data_ready,
>>> THIS_MODULE);
>>>
>>>        skb = alloc_skb(NLMSG_SPACE(MAX_PAYLOAD),GFP_KERNEL);
>>>        nlh = (struct nlmsghdr *)skb->data;
>>>
>>>        nlh->nlmsg_len =  NLMSG_SPACE(MAX_PAYLOAD);
>>>        nlh->nlmsg_pid = 0; //from kernel
>>>        nlh->nlmsg_flags = 0;
>>>
>>>        strcpy(NLMSG_DATA(nlh), "Message from kernel ");
>>>        NETLINK_CB(skb).pid = 0;
>>>        NETLINK_CB(skb).dst_pid = 0; //Multicast
>>>        NETLINK_CB(skb).dst_group = GROUP_IB;
>>>
>>>        //data send
>>>        printk( KERN_ALERT "data sent\n");
>>>        netlink_broadcast(nl_sk, skb, 0, GROUP_IB, GFP_KERNEL);
>>>        sock_release(nl_sk->sk_socket);
>>> }
>>
>> check this out:
>>
>> http://www.linuxjournal.com/article/7356
>>
>> read the comment, amazingly, someone else HAVE EXACTLY THE SAME
>> PROBLEM as yours, and his comment:
>>
>> ========================
>>
>> here is missed one importang thing:
>>
>> before strcpy we should call
>>
>> skb_put(skb, NLMSG_SPACE(MAX_PAYLOAD))
>>
>> or change
>>
>>
>> nlh = (struct nlmsghdr *)skb->data;
>> nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
>> nlh->nlmsg_pid = 0; /* from kernel */
>> nlh->nlmsg_flags = 0;
>>
>> ==========================
>>
>> and looking into kernel source:
>>
>>        s = skb_copy_expand(skb, 8, 0, GFP_ATOMIC);
>>        skb_push(s, 8);
>>        s->data[0] = 'z';
>>        s->data[1] = 'y';
>>        s->data[2] = 'd';
>>        s->data[3] = 'a';
>>        s->data[4] = 's';
>>        printk("len1=%d, len2=%d", skb->len, s->len);
>>        netlink_broadcast(rtnl, s, 0, RTMGRP_LINK, GFP_ATOMIC);
>>
>>
>> and this:
>>
>>        /*ÌîдÊý¾Ý±¨Ïà¹ØÐÅÏ¢*/
>>        nlh = NLMSG_PUT(skb, 0, 0, WAI_K_MSG, size-sizeof(*nlh));
>>        pos = NLMSG_DATA(nlh);
>>        memset(pos, 0, len);
>>
>>        /*´«Êäµ½Óû§¿Õ¼äµÄÊý¾Ý*/
>>        memcpy(pos, msg,  len);
>>        /*¼ÆËã¾­¹ý×Ö½Ú¶ÔÆäºóµÄÊý¾Ýʵ¼Ê³¤¶È*/
>>        nlh->nlmsg_len = skb->tail - old_tail;
>>        NETLINK_CB(skb).dst_group = COMMTYPE_GROUP;
>>        netlink_broadcast(netlink_sk, skb, 0, COMMTYPE_GROUP, GFP_ATOMIC);
>>
>> all having the same pattern as the comment.
>>
>> Hopefully this helps.
>>
>> --
>> Regards,
>> Peter Teoh
>>
>



-- 
Regards,
Peter Teoh

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ



[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