Who can give me the latest netlink programming sam

2019-01-23 00:09发布

I'm writing a Linux driver using netlink to communicate between user space and kernel space. But I can't find some useful materials, because the netlink has changed from Linux kernel >=2.6.24. Who can give me some suggestions about how to create a netlink socket. Thanks in advance!

2条回答
一纸荒年 Trace。
2楼-- · 2019-01-23 00:40

The code below demonstrates the basics of sending data from a user space application to a kernel module using netlink. This code works on Linux 2.6.28.9 with the git version (ef8ba32) of libnl. For more details, check out the libnl documentation and the code for iw which extensively uses netlink.

Kernel

#include <linux/kernel.h>
#include <linux/module.h>

#include <net/sock.h>
#include <net/netlink.h>

#define MY_MSG_TYPE (0x10 + 2)  // + 2 is arbitrary. same value for kern/usr

static struct sock *my_nl_sock;

DEFINE_MUTEX(my_mutex);

static int
my_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
    int type;
    char *data;

    type = nlh->nlmsg_type;
    if (type != MY_MSG_TYPE) {
        printk("%s: expect %#x got %#x\n", __func__, MY_MSG_TYPE, type);
        return -EINVAL;
    }

    data = NLMSG_DATA(nlh);
    printk("%s: %02x %02x %02x %02x %02x %02x %02x %02x\n", __func__,
            data[0], data[1], data[2], data[3],
            data[4], data[5], data[6], data[7]);
    return 0;
}

static void
my_nl_rcv_msg(struct sk_buff *skb)
{
    mutex_lock(&my_mutex);
    netlink_rcv_skb(skb, &my_rcv_msg);
    mutex_unlock(&my_mutex);
}

static int
my_init(void)
{
    my_nl_sock = netlink_kernel_create(&init_net, NETLINK_USERSOCK, 0,
            my_nl_rcv_msg, NULL, THIS_MODULE);
    if (!my_nl_sock) {
        printk(KERN_ERR "%s: receive handler registration failed\n", __func__);
        return -ENOMEM;
    }

    return 0;
}

static void
my_exit(void)
{
    if (my_nl_sock) {
        netlink_kernel_release(my_nl_sock);
    }
}

module_init(my_init);
module_exit(my_exit);

User Space

#include <stdio.h>
#include <stdlib.h>

#include <netlink/netlink.h>

#define MY_MSG_TYPE (0x10 + 2)  // + 2 is arbitrary but is the same for kern/usr
int
main(int argc, char *argv[])
{
    struct nl_sock *nls;
    char msg[] = { 0xde, 0xad, 0xbe, 0xef, 0x90, 0x0d, 0xbe, 0xef };
    int ret;

    nls = nl_socket_alloc();
    if (!nls) {
        printf("bad nl_socket_alloc\n");
        return EXIT_FAILURE;
    }

    ret = nl_connect(nls, NETLINK_USERSOCK);
    if (ret < 0) {
        nl_perror(ret, "nl_connect");
        nl_socket_free(nls);
        return EXIT_FAILURE;
    }

    ret = nl_send_simple(nls, MY_MSG_TYPE, 0, msg, sizeof(msg));
    if (ret < 0) {
        nl_perror(ret, "nl_send_simple");
        nl_close(nls);
        nl_socket_free(nls);
        return EXIT_FAILURE;
    } else {
        printf("sent %d bytes\n", ret);
    }

    nl_close(nls);
    nl_socket_free(nls);

    return EXIT_SUCCESS;
}
查看更多
兄弟一词,经得起流年.
3楼-- · 2019-01-23 00:54

I have been away of kernel programming from some time now. So I can't give you a direct example on what changes have been introduced. I can tell you how I got to understand the netlink functions and how to use them, reading code. Especially code from NetworkManager or the wireless extensions (iwlib), since that was my area of focus 2 years ago. Those OSS projects always are on top on changes on the kernel and their code is not difficult to understand.

查看更多
登录 后发表回答