Кто может дать мне последние примеры программирования netlink? - PullRequest
1 голос
/ 14 мая 2009

Я пишу драйвер Linux, использующий netlink для связи между пространством пользователя и пространством ядра. Но я не могу найти некоторые полезные материалы, потому что netlink изменился с ядра Linux> = 2.6.24. Кто может дать мне несколько советов о том, как создать сокет netlink. Заранее спасибо!

Ответы [ 2 ]

6 голосов
/ 22 июня 2009

Приведенный ниже код демонстрирует основы отправки данных из приложения пользовательского пространства в модуль ядра с использованием netlink. Этот код работает в Linux 2.6.28.9 с версией git (ef8ba32) libnl . Для получения более подробной информации, ознакомьтесь с документацией libnl и кодом для iw , который широко использует 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);

Пространство пользователя

#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;
}
0 голосов
/ 20 мая 2009

Я уже давно не занимаюсь программированием ядра. Поэтому я не могу дать вам прямой пример того, какие изменения были внесены. Я могу рассказать вам, как я понял функции netlink и как их использовать, читая код. Особенно код от NetworkManager или беспроводных расширений (iwlib), так как это было моей областью внимания 2 года назад. Эти проекты OSS всегда находятся на вершине изменений в ядре, и их код не сложен для понимания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...