linux netlink多播组问题

来源:互联网 发布:淘宝代购怎么那么便宜 编辑:程序博客网 时间:2024/06/08 06:37
  

 经过了三天的苦战,终于把netlink广播组的问题给解决了,现写一下心得,方便以后查找,同时也帮助需要解决此问题的同道中人……

 问题现象:

       设定netlink广播组后,应用层向内核发送数据,内核可以收到,但是内核通过netlink_broadcast向应用层发送时,返回-3,表示没有socket在监听。

       应用层关键代码大致如下:

int nl_init(int mod_id){   int                sock_fd = 0;   struct sockaddr_nl src_addr;

   sock_fd = socket(PF_NETLINK,SOCK_RAW,NETLINK_TEST/*24*/);

   memset(&src_addr,0,sizeof(src_addr));   src_addr.nl_family = AF_NETLINK;   src_addr.nl_pid = getpid();   src_addr.nl_groups = mod_id;   bind(sock_fd,(struct sockaddr *)&src_addr,sizeof(src_addr));

   return sock_fd;}

 

 

 

用红色字体标注的地方时关键代码,这个nl_groups字段很有意思,它表示多播组的掩码(注意,是掩码,不是多播组的组号);就这个字段我查了无数的资料,大多都是设置成0或者1,而且也没有说为什么,有的甚至就直接说“不清楚这个字段,一般设置成0,通过pid来通讯”。没办法,网上没有自能自己搞定了,我只能慢慢试了(中间死机无数次),最终,在内核的af_netlink.c中让我看到了一个netlink_group_mask函数,我觉得有希望了,但是还不清楚这个函数用在什么地方(或者是用在那一端,或者两端都用),我只好再次一点一点的试验,最终终于解决了多播组掩码的问题,最终代码如下:
static int netlink_group_mask(int group){ return group ? 1 << (group - 1) : 0;}

int nl_init(int mod_id){   int                sock_fd = 0;   struct sockaddr_nl src_addr;

   sock_fd = socket(PF_NETLINK,SOCK_RAW,NETLINK_TEST/*24*/);

   memset(&src_addr,0,sizeof(src_addr));   src_addr.nl_family = AF_NETLINK;   src_addr.nl_pid = getpid();   src_addr.nl_groups = netlink_group_mask(mod_id);   bind(sock_fd,(struct sockaddr *)&src_addr,sizeof(src_addr));

   return sock_fd;

}
内核发送代码:
netlink_broadcast(hsk, skb, 0, mod_id, GFP_ATOMIC)
原创粉丝点击