Re: Netlink Socket: trouble while using netlink_broadcast

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

 



not sure if correct or not, dst_group must always be 1 if broadcasting
is needed.   (and pid=0)

On Thu, Apr 16, 2009 at 11:23 AM, Peter Teoh <htmldeveloper@xxxxxxxxx> wrote:
> 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
>



-- 
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