Hi,
it is always the same :'(
I have looked into kernel sources, and there is also somethings
strange: in source code of netlink_kernel_create:
if (group <32)
group = 32;
This lines were not present in kernel 2.6.9.
I am also wondering if there isn't somethings wrong with listenners:
there are some tests on *has listenners*.
Actually, I get theses errors:
For kernel code: netlink broadcast return -3, No such process.
User code: can't bind: errot -3.
I have put one programs, who works when using unicast instead of
broadcast, GROUP_IB set to 0, and I fix manually pid of the
user-level program.
When I changed unicast to broadcast, and I set GROUP_IB to an other
value, I get the errors.
Thierry
----------
kernel code:
#include <linux/autoconf.h>
#include <linux/socket.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netlink.h>
#include <net/sock.h>
#include <net/netlink.h>
#define MAX_PAYLOAD 1024
#define NETLINK_IB 24
#define GROUP_IB 1
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;
nl_sk = netlink_kernel_create(NETLINK_IB, GROUP_IB, nl_ib_data_ready,
THIS_MODULE);
if (nl_sk == NULL) {
printk(KERN_ALERT "Error during netlink_kernel_create");
}
skb = alloc_skb(NLMSG_SPACE(MAX_PAYLOAD),GFP_KERNEL);
nlh = (struct nlmsghdr *)skb->data;
nlh = skb_put(skb, NLMSG_ALIGN(1024));
nlh->nlmsg_pid = 0; // Send from kernel
nlh->nlmsg_flags = 0;
strcpy(NLMSG_DATA(nlh), "Greeting from kernel!");
NETLINK_CB(skb).pid = 0;
NETLINK_CB(skb).dst_pid = 0; //Multicast
NETLINK_CB(skb).dst_group = GROUP_IB;// 0 if unicast
printk( KERN_ALERT "Sending data...\n");
//err = netlink_unicast(nl_sk, skb, 6992, GFP_KERNEL);
err = netlink_broadcast(nl_sk, skb, 0, GROUP_IB, GFP_KERNEL);
if (err<0) {
printk(KERN_ALERT "Error during netlink_broadcast: %i\n",err);
if (err == -3) {
printk(KERN_ALERT "No such process\n");
}
}
goto out;
nlmsg_failure:
printk(KERN_ALERT "Erreuuuur nlmsg_failure\n");
out:
sock_release(nl_sk->sk_socket);
}
static int __init netlink_ib_module_init(void)
{
printk(KERN_INFO "Init netlink_ib module\n");
netlink_ib_open();
return 0;
}
static void __exit netlink_ib_module_exit(void)
{
printk(KERN_INFO "Unloading netlink_ib module\n");
}
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Kernel/User socket for IB support");
module_init(netlink_ib_module_init);
module_exit(netlink_ib_module_exit);
---------
usercode
#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
#include <linux/netlink.h>
#define NETLINK_IB 24
#define GROUP_IB 1
#define MAX_PAYLOAD 1024
struct sockaddr_nl src_addr, dst_addr;
struct nlmsghdr *nlh = NULL;
struct msghdr msg;
struct iovec iov;
int sock_fd;
int main(int argc, char ** argv)
{
int err;
sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_IB);
if (sock_fd<0) {
char s[BUFSIZ];
sprintf( s, "%s: can't assign fd for socket", argv[0] );
perror(s);
return -1;
}
//memset(&src_addr, 0, sizeof(src_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pad = 0;
src_addr.nl_pid = getpid();
src_addr.nl_groups = GROUP_IB; // Multicast
err = bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));
if (err<0) {
char s[BUFSIZ];
sprintf( s, "%s: can't bind socket (%d)", argv[0], sock_fd );
perror(s);
return -1;
}
memset(&dst_addr, 0, sizeof(dst_addr));
nlh = (struct nlhmsghdr *) malloc(NLMSG_SPACE(MAX_PAYLOAD));
memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
iov.iov_base = (void *)nlh;
iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD);
msg.msg_name = (void *)&dst_addr;
msg.msg_namelen = sizeof(dst_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
printf("Waiting for messages from kernel...\n");
recvmsg(sock_fd, &msg, 0);
printf("Message : %s\n", NLMSG_DATA(nlh));
close(sock_fd);
return 0;
}
On Thu, Apr 16, 2009 at 5:25 AM, Peter Teoh <[email protected]> wrote:
> 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 <[email protected]> wrote:
>> On Wed, Apr 15, 2009 at 8:32 PM, Thierry <[email protected]> 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 <[email protected]> wrote:
>>>> On Fri, Apr 10, 2009 at 4:12 AM, Thierry <[email protected]>
>>>> 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 [email protected]
Please read the FAQ at http://kernelnewbies.org/FAQ