Netlink 内核实现分析 4

netlink 库函数:

http://www.infradead.org/~tgr/libnl/doc/core.html#core_netlink_fundamentals

#define NETLINK_TEST            (31)

static
int s_send_ack_to_test(struct lua_nl_ack *ack)
{
    struct sk_buff *nl_skb;
    struct nlmsghdr *nlh;

    int ret;
    int len = sizeof(*ack);

    nl_skb = nlmsg_new(len, GFP_ATOMIC);
    if (!nl_skb) {
        pr_err("netlink: nlmsg_new fail\n");
        return -1;
    }

    nlh = nlmsg_put(nl_skb, 0, 0, NETLINK_WNS, len, 0);
    if(nlh == NULL) {
        pr_err("netlink: nlmsg_put fail\n");
        nlmsg_free(nl_skb);
        return -1;
    }

    memcpy(nlmsg_data(nlh), (void *)ack, len);
    ret = netlink_unicast(nlsk, nl_skb, NETLINK_WNS_LUA, MSG_DONTWAIT);

    return ret;
}

static
void test_input_cb(struct sk_buff *skb)
{
    struct nlmsghdr *nlh = NULL;
    struct lua_nl_req *req = NULL;
    struct lua_nl_ack ack;

    nlh = (struct nlmsghdr *)skb->data;

    if (NLMSG_OK(nlh, skb->len) && skb->len >= NLMSG_HDRLEN + sizeof(struct lua_nl_req)) {
        req = (struct lua_nl_req *)NLMSG_DATA(nlh);

        (void)s_get_ip_mac(req, &ack);

        if (s_send_ack_to_test(&ack) < 0) {
            pr_err("netlink: s_send_ack_to_lua error\n");
        }

        //TODO: netlink消息失败的情况需要再仔细考虑下,可能导致阻塞

    }
    else {
        pr_err("netlink: parameters error\n");
    }

    return ;
}

static struct netlink_kernel_cfg cfg = {
    .input = test_input_cb,
};

static
int s_init_netlink()
{
    nlsk = netlink_kernel_create(&init_net, NETLINK_TEST, THIS_MODULE, &cfg);
    if (!nlsk) {
        pr_err("netlink: init fail\n");
        return -1;
    }

    return 0;
}

原文地址:https://www.cnblogs.com/codestack/p/10850608.html

时间: 2024-10-21 20:54:52

Netlink 内核实现分析 4的相关文章

Netlink 内核实现分析(二):通信

在前一篇博文<Netlink 内核实现分析(一):创建>中已经较为具体的分析了Linux内核netlink子系统的初始化流程.内核netlink套接字的创建.应用层netlink套接字的创建和绑定流程,本文来具体的分析一下内核是怎样实现netlink消息在内核和应用进程之间全双工异步通信的. 一.netlink通信数据结构 1.netlink消息报头:struct nlmsghdr struct nlmsghdr { __u32 nlmsg_len; /* Length of message

驱动相关的内核代码分析

arch\arm\include\asm\Io.h #define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force   *)(a)) #define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force   *)(a) = (v)) 注:(volatile unsigned int __force   *)指针强制转换为unsigne

linux 内核源代码分析 - 获取数组的大小

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 測试程序: #include<stdio.h> #include<stdlib.h> struct dev { int a; char b; float c; }; struct dev devs[]= { { 1,'a',7.0, }, { 1,'a',7.0, }, { 1,'a',7.0, }, }; int main() { printf("int is %d \

第3阶段——内核启动分析之start_kernel初始化函数(5)

内核启动分析之start_kernel初始化函数(init/main.c) stext函数启动内核后,就开始进入start_kernel初始化各个函数, 下面只是浅尝辄止的描述一下函数的功能,很多函数真正理解需要对linux相关体系有很深的了解后才能明白 代码如下: asmlinkage void __init start_kernel(void) { char * command_line; extern struct kernel_param __start___param[], __sto

Linux内核源代码分析方法

Linux内核源代码分析方法   一.内核源代码之我见 Linux内核代码的庞大令不少人"望而生畏",也正由于如此,使得人们对Linux的了解仅处于泛泛的层次.假设想透析Linux,深入操作系统的本质,阅读内核源代码是最有效的途径.我们都知道,想成为优秀的程序猿,须要大量的实践和代码的编写.编程固然重要,可是往往仅仅编程的人非常easy把自己局限在自己的知识领域内.假设要扩展自己知识的广度,我们须要多接触其它人编写的代码,尤其是水平比我们更高的人编写的代码.通过这样的途径,我们能够跳出

Linux内核Crash分析

转载自:http://linux.cn/article-3475-1.html 在工作中经常会遇到一些内核crash的情况,本文就是根据内核出现crash后的打印信息,对其进行了分析,使用的内核版本为:Linux2.6.32. 每一个进程的生命周期内,其生命周期的范围为几毫秒到几个月.一般都是和内核有交互,例如用户空间程序使用系统调用进入内核空间.这时使用的不再是用户空 间的栈空间,使用对应的内核栈空间.对每一个进程来说,Linux内核都会把两个不同的数据结构紧凑的存放在一个单独为进程分配的存储

UC/OS-II内核调度分析

一.内核概述: 多任务系统中,内核负责管理各个任务,或者说为每个任务分配CPU时间,并且负责任务之间的通讯.内核提供的基本服务是任务切换.之所以使用实时内 核可以大大简化应用系统的设计,是因为实时内核允许将应用分成若干个任务,由实时内核来管理它们.内核本身也增加了应用程序的额外负荷,代码空间增加 ROM的用量,内核本身的数据结构增加了RAM的用量.但更主要的是,每个任务要有自己的栈空间,这一块吃起内存来是相当厉害的.内核本身对CPU的占用 时间一般在2到5个百分点之间. UC/OS-II有一个精

简单的时间片轮转多道程序内核的分析

学号后三位:256 原创作品,转载请注明出处.参考资料: https://github.com/mengning/linuxkernel/issues/2 1.mykernel部署 使用实验楼的虚拟机打开shell 依次输入如下指令: cd LinuxKernel/linux-3.9.4 rm -rf mykernel patch -p1 < ../mykernel_for_linux3.9.4sc.patch make allnoconfig make qemu -kernel arch/x8

内核通信之Netlink源码分析-用户内核通信原理3

2017-07-06 上节主讲了用户层通过netlink和内核交互的详细过程,本节分析下用户层接收数据的过程-- 有了之前基础知识的介绍,用户层接收数据只涉及到一个核心调用readmsg(), 其他的就不多介绍了,不太明白的请参考之前的文章,我们还是重点看下内核究竟在背后做了什么!该函数在内核对应于read_msg系统调用 SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags) { i