美文网首页
什么是netlink?

什么是netlink?

作者: _invincible_ | 来源:发表于2020-12-17 19:57 被阅读0次

本文主要目的是初步认识netlink,并用尽量少的API实现了一个R3-R0通信的demo

概述

$ man 7 netlink
NAME         top
       netlink - communication between kernel and user space (AF_NETLINK)
SYNOPSIS         top
       #include <asm/types.h>
       #include <sys/socket.h>
       #include <linux/netlink.h>

       netlink_socket = socket(AF_NETLINK, socket_type, netlink_family);
DESCRIPTION         top
       Netlink is used to transfer information between the kernel and user-
       space processes.  
...
  • R0和R3之间通讯的机制
  • R3程序通过socket使用

基本使用

用户态 (Ring3)

API 列表
struct nlmsghdr
struct sockaddr_nl
NLMSG_DATA

socket
bind
sendto
recvfrom
API 细节

创建AF_NETLINK socket

#include <asm/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>

netlink_socket = socket(AF_NETLINK, socket_type, netlink_family);

socket_type: 
  Both SOCK_RAW and SOCK_DGRAM are valid values for socket_type.  
  However, the netlink protocol does not distinguish between datagram and raw sockets.

netlink_family:
  NETLINK_GENERIC
  ...
  NETLINK_TEST (self-defined: 22~31)
/* netlink_family共32个,0~21由系统占用,自定义的范围在22~31 */

Netlink消息头

struct nlmsghdr {
  __u32 nlmsg_len;    /* Length of message including header */
  __u16 nlmsg_type;   /* Type of message content */
  __u16 nlmsg_flags;  /* Additional flags */
  __u32 nlmsg_seq;    /* Sequence number */
  __u32 nlmsg_pid;    /* Sender port ID */
};

Netlink通信地址格式

struct sockaddr_nl {
  sa_family_t     nl_family;  /* AF_NETLINK */
  unsigned short  nl_pad;     /* Zero */
  pid_t           nl_pid;     /* Port ID */
  __u32           nl_groups;  /* Multicast groups mask */
};

通信相关API

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);

数据处理相关API

int NLMSG_SPACE(size_t len);
Return  the  number of bytes that a netlink message with payload of len would occupy.
              
void *NLMSG_DATA(struct nlmsghdr *nlh);
Return a pointer to the payload associated with the passed nlmsghdr.

内核模块 ( Ring0 )

API 列表
struct netlink_kernel_cfg
struct sk_buff
struct nlmsghdr

netlink_kernel_create
netlink_kernel_release


nlmsg_new
nlmsg_put
nlmsg_data
netlink_unicast

API 细节

用于配置回调函数

struct netlink_kernel_cfg {
        unsigned int    groups;
        unsigned int    flags;
        void            (*input)(struct sk_buff *skb);
        struct mutex    *cb_mutex;
        int             (*bind)(struct net *net, int group);
        void            (*unbind)(struct net *net, int group);
        bool            (*compare)(struct net *net, struct sock *sk);
};

input:
  callbacks for receive and send netlink messages

创建和销毁netlink_socket

static inline struct sock *
netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg)

void netlink_kernel_release(struct sock *sk)

创建netlink message

/**
 * nlmsg_new - Allocate a new netlink message
 * @payload: size of the message payload
 * @flags: the type of memory to allocate.
 *
 * Use NLMSG_DEFAULT_SIZE if the size of the payload isn't known
 * and a good default is needed.
 */
static inline struct sk_buff *nlmsg_new(size_t payload, gfp_t flags)

将netlink message添加的 skb

/**
 * nlmsg_put - Add a new netlink message to an skb
 * @skb: socket buffer to store message in
 * @portid: netlink PORTID of requesting application
 * @seq: sequence number of message
 * @type: message type
 * @payload: length of message payload
 * @flags: message flags
 *
 * Returns NULL if the tailroom of the skb is insufficient to store
 * the message header and payload.
 */
static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, int type, int payload, int flags)

剔除nlmsg header获取message部分指针

/**
 * nlmsg_data - head of message payload
 * @nlh: netlink message header
 */
static inline void *nlmsg_data(const struct nlmsghdr *nlh)

通过unicast发送到user 进程

int netlink_unicast(struct sock *ssk, struct sk_buff *skb, u32 portid, int nonblock)

Demo

git clone https://github.com/invincible1900/linux-kernel-study.git

cd linux-kernel-study/netlink/netlink/demo1/kernel && make
insmod nl.ko

cd ../user && make
./nl
dmesg |tail

rmmod nl
cd ../../../../../ && rm -r linux-kernel-study

参考

man 7 netlink
man 3 netlink

相关文章

网友评论

      本文标题:什么是netlink?

      本文链接:https://www.haomeiwen.com/subject/geqogktx.html