自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

內(nèi)核通信之 Netlink 源碼分析和實(shí)例分析

系統(tǒng) Linux
這幾天在看 ipvs 相關(guān)代碼的時(shí)候又遇到了 netlink 的事情,所以這兩天花了點(diǎn)時(shí)間重新把 netlink 的事情梳理了一下。

 

[[335268]]

本文轉(zhuǎn)載自微信公眾號(hào)「黑光技術(shù)」,作者h(yuǎn)elight 。轉(zhuǎn)載本文請(qǐng)聯(lián)系黑光技術(shù)公眾號(hào)。

前言

這幾天在看 ipvs 相關(guān)代碼的時(shí)候又遇到了 netlink 的事情,所以這兩天花了點(diǎn)時(shí)間重新把 netlink 的事情梳理了一下。

什么是 netlink

linux 內(nèi)核一直存在的一個(gè)嚴(yán)重問(wèn)題就是內(nèi)核態(tài)和用戶(hù)態(tài)的交互的問(wèn)題,對(duì)于這個(gè)問(wèn)題內(nèi)核大佬們一直在研究各種方法,想讓內(nèi)核和用戶(hù)態(tài)交互能夠安全高效的進(jìn)行。如系統(tǒng)調(diào)用,proc,sysfs等內(nèi)存文件系統(tǒng),但是這些方式一般都比較簡(jiǎn)單,只能在用戶(hù)空間輪詢(xún)?cè)L問(wèn)內(nèi)核的變化,內(nèi)核的變化無(wú)法主動(dòng)的推送出來(lái)。

而 netlink 的出現(xiàn)比較好的解決了這個(gè)問(wèn)題,而且 netlink 還有以下一些優(yōu)勢(shì):

  1. 可以直接使用 socket 套接字的 API 進(jìn)行內(nèi)核和用戶(hù)態(tài)的通信,開(kāi)發(fā)使用上相對(duì)簡(jiǎn)單了很多。
  2. 利用內(nèi)核協(xié)議棧有了緩沖隊(duì)列,是一種異步通信機(jī)制。
  3. 可以是內(nèi)核和用戶(hù)態(tài)的雙向通信,內(nèi)核可以主動(dòng)向用戶(hù)態(tài)進(jìn)程發(fā)送消息。這個(gè)是以往通信方式不具備的。
  4. 針對(duì)同一個(gè)協(xié)議類(lèi)型的所有用戶(hù)進(jìn)程,內(nèi)核可以廣播消息給所有的進(jìn)程,也可以指定進(jìn)程 pid 進(jìn)行消息發(fā)送。

目前 netlink 的這種機(jī)制被廣泛使用在各種場(chǎng)景中,在 Linux 內(nèi)核中使用 netlink 進(jìn)行應(yīng)用與內(nèi)核通信的應(yīng)用很多; 包括:路由 daemon(NETLINK_ROUTE),用戶(hù)態(tài) socket 協(xié)議(NETLINK_USERSOCK),防火墻(NETLINK_FIREWALL),netfilter 子系統(tǒng)(NETLINK_NETFILTER),內(nèi)核事件向用戶(hù)態(tài)通知(NETLINK_KOBJECT_UEVENT)等。具體支持的類(lèi)型可以查看這個(gè)文件 include/uapi/linux/netlink.h。

netlink 內(nèi)核代碼走讀

netlink 內(nèi)核相關(guān)文件介紹

netlink 的內(nèi)核代碼在內(nèi)核代碼的 net/netlink/ 目錄下,我目前看的是 5.7.10 的內(nèi)核版本,netlink 內(nèi)核相關(guān)的文件不多,還是比較清晰的:

  1. helightxu@  ~/open_code/linux-5.7.10  ls net/netlink 
  2. config      Makefile     af_netlink.c af_netlink.h diag.c       genetlink.c 
  3. helightxu@  ~/open_code/linux-5.7.10  
文件 描述
af_netlink.c 和 af_netlink.h: 是 netlink 的核心文件,這個(gè)也是下面詳細(xì)走讀的內(nèi)容。
diag.c 對(duì) netlink sock 進(jìn)行監(jiān)控,可以插入到內(nèi)核或者從內(nèi)核中卸載
genetlink.c 這個(gè)可以看作是 netlink 的升級(jí)版本,或者說(shuō)是一種高層封裝。

注:

  1. genetlink.c 額外說(shuō)明:netlink 默認(rèn)支持了 30 多種的場(chǎng)景,但是對(duì)于其它場(chǎng)景并沒(méi)有具體定義,這個(gè)時(shí)候這種通用封裝就有了很大的好處,可以在不改動(dòng)內(nèi)核的前提下進(jìn)行應(yīng)用場(chǎng)景擴(kuò)展,這部分內(nèi)容可以看這個(gè) wiki:https://wiki.linuxfoundation.org/networking/generic_netlink_howto 

還有一個(gè)頭文件是在 include 目錄,如下所示,這個(gè)頭文件是一些輔助函數(shù)、宏定義和相關(guān)數(shù)據(jù)結(jié)構(gòu),大家學(xué)習(xí)的同學(xué)一定要看這個(gè)文件,它里面的注釋非常詳細(xì)。這些注釋對(duì)理解 netlink 的消息結(jié)構(gòu)非常有用,建議可以詳細(xì)看看。

  1. helightxu@  ~/open_code/linux-5.7.10  ls include/net/netlink.h 

af_netlink.c 代碼走讀

在 af_netlink.c 這個(gè)文件的最下面有一行代碼:

  1. core_initcall(netlink_proto_init); 

這段代碼的意思是什么呢?通過(guò)看這個(gè)代碼最終的實(shí)現(xiàn)可以看出,就是告訴編譯器把 netlink_proto_init 這個(gè)函數(shù)放入到最終編譯出來(lái)二進(jìn)制文件的 .init 段中,內(nèi)核在啟動(dòng)的時(shí)候會(huì)從這個(gè)端里面的函數(shù)挨個(gè)的執(zhí)行。這里也就是說(shuō) netlink 是內(nèi)核默認(rèn)就直接支持的,是原生內(nèi)核的一部分(這里其實(shí)想和內(nèi)核的動(dòng)態(tài)插拔模塊區(qū)別)。

在 netlink_proto_init 函數(shù)中最關(guān)鍵的一行代碼就是下面最后一行,把 netlink 的協(xié)議族注冊(cè)到網(wǎng)絡(luò)協(xié)議棧中去。

  1. static const struct net_proto_family netlink_family_ops = { 
  2.     .family = PF_NETLINK, 
  3.     .create = netlink_create, 
  4.     .owner  = THIS_MODULE,  /* for consistency 8) */ 
  5. }; 
  6. ... 
  7. sock_register(&netlink_family_ops); 

PF_NETLINK 是表示 netlink 的協(xié)議族,在后面我們?cè)诳蛻?hù)端創(chuàng)建 netlink socket 的時(shí)候就要用到這個(gè)東東。如下面的代碼,代碼來(lái)自我的測(cè)試代碼 https://github.com/helight/kernel_modules/tree/master/netlink_test 中的客戶(hù)端代碼,可以看出:PF_NETLINK 表示我們所用的就是 netlink 的協(xié)議,SOCK_RAW 表示我們使用的是原始協(xié)議包,NETLINK_USER 這個(gè)我們自己定義的一個(gè)協(xié)議字段。netlink 我們前面說(shuō)了有 30 多種應(yīng)用場(chǎng)景,這些都已經(jīng)在內(nèi)核代碼中固定了,所以在客戶(hù)端使用的時(shí)候會(huì)指定這個(gè)字段來(lái)表示和內(nèi)核中的那個(gè)應(yīng)用場(chǎng)景的函數(shù)模塊進(jìn)行交互。

  1. //int socket(int domain, int type, int protocol); 
  2.     sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER); 

sock_register 這個(gè)函數(shù)的作用主要就是注冊(cè) PF_NETLINK 這個(gè)協(xié)議類(lèi)型到內(nèi)核中,讓內(nèi)核認(rèn)識(shí)這個(gè)協(xié)議,在內(nèi)核網(wǎng)絡(luò)協(xié)議中建立 socket 的時(shí)候知道該使用那個(gè)協(xié)議為它提供操作支持。

注冊(cè)了之后內(nèi)核就支持了 netlink 協(xié)議了,接下來(lái)就是內(nèi)核中創(chuàng)建監(jiān)聽(tīng) socket,用戶(hù)態(tài)創(chuàng)建鏈接 socket 了。

netlink 用戶(hù)態(tài)和內(nèi)核交互過(guò)程

這里我簡(jiǎn)單畫(huà)一個(gè)圖來(lái)表示一下,socket 通信主要有 2 個(gè)操作對(duì)象:server 端和 client 端。netlink 的操作原理是這樣的:

對(duì)象 所處位置 -
server 端 內(nèi)核中 -
client 端 用戶(hù)態(tài)進(jìn)程 -

netlink 關(guān)鍵數(shù)據(jù)結(jié)構(gòu)和函數(shù)

sockaddr_nl 協(xié)議套接字

netlink 的地址表示由 sockaddr_nl 負(fù)責(zé)

  1. struct sockaddr_nl { 
  2.     __kernel_sa_family_t    nl_family;    /* AF_NETLINK    */ 
  3.     unsigned short          nl_pad;        /* zero        */ 
  4.     __u32                   nl_pid;        /* port ID 這個(gè)一般是進(jìn)程id */ 
  5.     __u32                   nl_groups;    /* multicast groups mask */ 
  6. }; 

nl_family 制定了協(xié)議族,netlink 有自己獨(dú)立的值:AF_NETLINK,nl_pid 一般取為進(jìn)程 pid。nl_groups 用以多播,當(dāng)不需要多播時(shí),該字段為 0。

nlmsghdr 消息體

netlink 消息是作為套接字緩沖區(qū) sk_buff 的數(shù)據(jù)部分傳遞的,其消息本身又分為頭部和數(shù)據(jù)。頭部為:

  1. struct nlmsghdr { 
  2.     __u32        nlmsg_len;    /* Length of message including header */ 
  3.     __u16        nlmsg_type;    /* Message content */ 
  4.     __u16        nlmsg_flags;    /* Additional flags */ 
  5.     __u32        nlmsg_seq;    /* Sequence number */ 
  6.     __u32        nlmsg_pid;    /* Sending process port ID */ 
  7. }; 

nlmsg_len 為消息的長(zhǎng)度,包含該頭部在內(nèi)。nlmsg_pid 為發(fā)送進(jìn)程的端口 ID,這個(gè)用戶(hù)可以自定義,一般也是使用進(jìn)程 pid。

msghdr 用戶(hù)態(tài)系發(fā)送消息體

使用 sendmsg 和 recvmsg 函數(shù)進(jìn)行發(fā)送和接收消息,使用的消息體是這個(gè)樣子的。

  1. struct iovec {                    /* Scatter/gather array items */ 
  2.     void  *iov_base;              /* Starting address */ 
  3.     size_t iov_len;               /* Number of bytes to transfer */ 
  4. }; 
  5. /* 
  6. iov_base: iov_base 指向數(shù)據(jù)包緩沖區(qū),即參數(shù) buff,iov_len 是 buff 的長(zhǎng)度。 
  7. msghdr 中允許一次傳遞多個(gè) buff,以數(shù)組的形式組織在 msg_iov 中,msg_iovlen 就記錄數(shù)組的長(zhǎng)度 (即有多少個(gè)buff) 
  8. */ 
  9. struct msghdr { 
  10.     void    *    msg_name;    /* Socket name            */ 
  11.     int          msg_namelen;    /* Length of name        */ 
  12.     struct iovec *    msg_iov;    /* Data blocks            */ 
  13.     __kernel_size_t   msg_iovlen;    /* Number of blocks        */ 
  14.     void     *         msg_control;    /* Per protocol magic (eg BSD file descriptor passing) */ 
  15.     __kernel_size_t    msg_controllen;    /* Length of cmsg list */ 
  16.     unsigned int      msg_flags; 
  17. }; 
  18. /* 
  19.    msg_name:數(shù)據(jù)的目的地址,網(wǎng)絡(luò)包指向 sockaddr_in, netlink 則指向 sockaddr_nl; 
  20.    msg_namelen: msg_name 所代表的地址長(zhǎng)度 
  21.    msg_iov: 指向的是緩沖區(qū)數(shù)組 
  22.    msg_iovlen: 緩沖區(qū)數(shù)組長(zhǎng)度 
  23.    msg_control: 輔助數(shù)據(jù),控制信息(發(fā)送任何的控制信息) 
  24.    msg_controllen: 輔助信息長(zhǎng)度 
  25.    msg_flags: 消息標(biāo)識(shí) 
  26. */ 

邏輯結(jié)構(gòu)如下:

socket 也是一種特殊的文件,通過(guò) VFS 的接口同樣可以對(duì)其進(jìn)行使用管理。socket 本身就需要實(shí)現(xiàn)文件系統(tǒng)的相應(yīng)接口,有自己的操作方法集。

netlink 常用宏

  1. #define NLMSG_ALIGNTO   4U/* 宏 NLMSG_ALIGN(len) 用于得到不小于len且字節(jié)對(duì)齊的最小數(shù)值 */ 
  2. #define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) ) 
  3. /* Netlink 頭部長(zhǎng)度 */ 
  4. #define NLMSG_HDRLEN     ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr))) 
  5. /* 計(jì)算消息數(shù)據(jù) len 的真實(shí)消息長(zhǎng)度(消息體 + 消息頭)*/ 
  6. #define NLMSG_LENGTH(len) ((len) + NLMSG_HDRLEN) 
  7. /* 宏 NLMSG_SPACE(len) 返回不小于 NLMSG_LENGTH(len) 且字節(jié)對(duì)齊的最小數(shù)值 */ 
  8. #define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len)) 
  9. /* 宏 NLMSG_DATA(nlh) 用于取得消息的數(shù)據(jù)部分的首地址,設(shè)置和讀取消息數(shù)據(jù)部分時(shí)需要使用該宏 */ 
  10. #define NLMSG_DATA(nlh)  ((void*)(((char*)nlh) + NLMSG_LENGTH(0))) 
  11. /* 宏 NLMSG_NEXT(nlh,len) 用于得到下一個(gè)消息的首地址, 同時(shí) len 變?yōu)槭S嘞⒌拈L(zhǎng)度 */ 
  12. #define NLMSG_NEXT(nlh,len)  ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \                  (struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len))) 
  13. /* 判斷消息是否 >len */ 
  14. #define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \               (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \               (nlh)->nlmsg_len <= (len)) 
  15. /* NLMSG_PAYLOAD(nlh,len) 用于返回 payload 的長(zhǎng)度*/ 
  16. #define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len))) 

netlink 內(nèi)核常用函數(shù)

netlink_kernel_create

這個(gè)內(nèi)核函數(shù)用于創(chuàng)建內(nèi)核 socket,以提供和用戶(hù)態(tài)通信

  1. static inline struct sock * 
  2. netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg) 
  3. /* 
  4.     net: 指向所在的網(wǎng)絡(luò)命名空間, 默認(rèn)傳入的是 &init_net (不需要定義);  定義在 net_namespace.c(extern struct net init_net); 
  5.     unit: netlink 協(xié)議類(lèi)型 
  6.     cfg:  cfg 存放的是 netlink 內(nèi)核配置參數(shù)(如下) 
  7. */ 
  8.  
  9. /* optional Netlink kernel configuration parameters */ 
  10. struct netlink_kernel_cfg { 
  11.     unsigned int    groups; 
  12.     unsigned int    flags; 
  13.     void        (*input)(struct sk_buff *skb); /* input 回調(diào)函數(shù) */ 
  14.     struct mutex    *cb_mutex; 
  15.     void        (*bind)(int group); 
  16.     bool        (*compare)(struct net *net, struct sock *sk); 
  17. }; 

單播函數(shù) netlink_unicast() 和多播函數(shù) netlink_broadcast()

  1. /* 來(lái)發(fā)送單播消息 */ 
  2. extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 portid, int nonblock); 
  3. /* ssk: netlink socket 
  4.    skb: skb buff 指針 
  5.    portid:通信的端口號(hào) 
  6.    nonblock:表示該函數(shù)是否為非阻塞,如果為1,該函數(shù)將在沒(méi)有接收緩存可利用時(shí)立即返回,而如果為 0,該函數(shù)在沒(méi)有接收緩存可利用 定時(shí)睡眠 
  7. */ 
  8.  
  9. /* 用來(lái)發(fā)送多播消息 */ 
  10. extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 portid, 
  11.                  __u32 group, gfp_t allocation); 
  12. /* ssk: 同上(對(duì)應(yīng) netlink_kernel_create 返回值)、 
  13.    skb: 內(nèi)核 skb buff 
  14.    portid:端口id 
  15.    group: 是所有目標(biāo)多播組對(duì)應(yīng)掩碼的"OR"操作的。 
  16.    allocation: 指定內(nèi)核內(nèi)存分配方式,通常 GFP_ATOMIC 用于中斷上下文,而 GFP_KERNEL 用于其他場(chǎng)合。 
  17.                 這個(gè)參數(shù)的存在是因?yàn)樵?nbsp;API 可能需要分配一個(gè)或多個(gè)緩沖區(qū)來(lái)對(duì)多播消息進(jìn)行 clone。 
  18. */ 

測(cè)試?yán)哟a

netlink 內(nèi)核建立 socket 過(guò)程

內(nèi)核的代碼非常簡(jiǎn)單,這里給出了核心代碼,就這么多,接收函數(shù)中直接打印了接收到的消息。

  1. #include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <net/sock.h>#include <asm/types.h>#include <linux/netlink.h>#include <linux/skbuff.h> 
  2. #define NETLINK_XUX           31       /* testing */   
  3. static struct sock *xux_sock = NULL
  4.  
  5. // 接收消息的回調(diào)函數(shù),接收參數(shù)是 sk_buff 
  6. static void recv_netlink(struct sk_buff *skb) 
  7.     struct nlmsghdr *nlh; 
  8.     nlh = nlmsg_hdr(skb); // 取得消息體 
  9.     printk("receive data from user process: %s", (char *)NLMSG_DATA(nlh)); // 打印接收的數(shù)據(jù)內(nèi)容 
  10.  
  11.     ... 
  12.  
  13. int __init init_link(void) 
  14.     struct netlink_kernel_cfg cfg = { 
  15.         .input = recv_netlink, 
  16.     }; 
  17.     xux_sock = netlink_kernel_create(&init_net, NETLINK_XUX, &cfg); // 創(chuàng)建內(nèi)核 socket 
  18.     if (!xux_sock){ 
  19.         printk("cannot initialize netlink socket"); 
  20.         return -1; 
  21.     } 
  22.      
  23.     printk("Init OK!\n"); 
  24.     return 0; 

netlink 用戶(hù)態(tài)建立鏈接和收發(fā)信息

  1. ... // 上面的就省了 
  2. #define NETLINK_USER 31  //self defined 
  3. #define MAX_PAYLOAD 1024 /* maximum payload size*/ 
  4. struct sockaddr_nl src_addr, dest_addr; 
  5. struct nlmsghdr *nlh = NULL
  6. struct msghdr msg; 
  7. struct iovec iov; 
  8. int sock_fd; 
  9.  
  10. int main(int args, char *argv[]) 
  11.     sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER); // 建立 socket 
  12.  
  13.     if(sock_fd < 0) 
  14.         return -1; 
  15.  
  16.     memset(&src_addr, 0, sizeof(src_addr)); 
  17.     src_addr.nl_family = AF_NETLINK; 
  18.     src_addr.nl_pid = getpid(); /* 當(dāng)前進(jìn)程的 pid */ 
  19.  
  20.     if(bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr))){ // 和指定協(xié)議進(jìn)行 socket 綁定 
  21.         perror("bind() error\n"); 
  22.         close(skfd); 
  23.         return -1; 
  24.     } 
  25.  
  26.     memset(&dest_addr, 0, sizeof(dest_addr)); 
  27.     dest_addr.nl_family = AF_NETLINK; 
  28.     dest_addr.nl_pid = 0;       /* For Linux Kernel */ 
  29.     dest_addr.nl_groups = 0;    /* unicast */ 
  30.  
  31.     nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); 
  32.     memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); 
  33.     nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); 
  34.     nlh->nlmsg_pid = getpid();  //self pid 
  35.     nlh->nlmsg_flags = 0; 
  36.     // 拷貝信息到發(fā)送緩沖中 
  37.     strcpy(NLMSG_DATA(nlh), "Hello this is a msg from userspace"); 
  38.     // 構(gòu)造發(fā)送消息體 
  39.     iov.iov_base = (void *)nlh;         //iov -> nlh 
  40.     iov.iov_len = nlh->nlmsg_len; 
  41.     msg.msg_name = (void *)&dest_addr; 
  42.     msg.msg_namelen = sizeof(dest_addr); 
  43.     msg.msg_iov = &iov;  // iov 中存放 netlink 消息頭和消息數(shù)據(jù) 
  44.     msg.msg_iovlen = 1; 
  45.  
  46.     printf("Sending message to kernel\n"); 
  47.  
  48.     int ret = sendmsg(sock_fd, &msg, 0);  // 發(fā)送消息到內(nèi)核 
  49.     printf("send ret: %d\n", ret); 
  50.  
  51.     printf("Waiting for message from kernel\n"); 
  52.  
  53.     /* 從內(nèi)核接收消息 */ 
  54.     recvmsg(sock_fd, &msg, 0); 
  55.     printf("Received message payload: %s\n", NLMSG_DATA(nlh));  // 打印接收到的消息 
  56.  
  57.     close(sock_fd); 
  58.     return 0; 

以上代碼在我的個(gè)人倉(cāng)庫(kù)中都有,如果有興趣可以 clone 下來(lái)自己測(cè)試玩耍一遍。代碼倉(cāng)庫(kù):https://github.com/helight/kernel_modules/tree/master/netlink_test 。

總結(jié)

netlink 目前感覺(jué)還是一個(gè)比較好用的內(nèi)核和用戶(hù)空間的交互方式,但是也是有他的使用場(chǎng)景,適合用戶(hù)空間和內(nèi)核空間主動(dòng)交互的場(chǎng)景。

但是在單機(jī)場(chǎng)景下,大多數(shù)的主動(dòng)權(quán)在用戶(hù)進(jìn)程,用戶(hù)進(jìn)程寫(xiě)數(shù)據(jù)到內(nèi)核,用戶(hù)進(jìn)程主動(dòng)讀取內(nèi)核數(shù)據(jù)。這兩種場(chǎng)景覆蓋了內(nèi)核的絕大多數(shù)場(chǎng)景。

在內(nèi)核要主動(dòng)的場(chǎng)景下,netlink 就比較適合。我能想到的就是內(nèi)核數(shù)據(jù)審計(jì),安全觸發(fā)等,這類(lèi)場(chǎng)景下內(nèi)核可以實(shí)時(shí)的告知用戶(hù)進(jìn)程內(nèi)核發(fā)生的情況。

我是在看 ipvs 的代碼時(shí)候看到了里面有 netlink 的使用,發(fā)現(xiàn)早期 iptables 就是使用 netlink 來(lái)下發(fā)配置指令的,內(nèi)核中 netfilter 和 iptables 中還有這部分的代碼,今天也順便下載大致走讀了一遍,大家可以搜索 NETLINK 這個(gè)關(guān)鍵字來(lái)看。但是 iptables 后來(lái)的代碼中沒(méi)有使用這樣的方式,而是采用了一個(gè)叫做 iptc 的庫(kù),其核心思路還是使用 setsockops 的方式,最終還是 copy_from_user。不過(guò)這種方式對(duì)于 iptables 這種配置下發(fā)的場(chǎng)景來(lái)說(shuō)還是非常實(shí)用的。

最后大家如果對(duì)這方面有興趣的可以找我一起再研究研究,我也想繼續(xù)在深入看看,但是目前沒(méi)有太好的場(chǎng)景。

明天開(kāi)始走讀 kubernetes 的代碼,大家有興趣的也可以一起來(lái)交流。

參考

https://www.cnblogs.com/x_wukong/p/5920437.html

 

 

責(zé)任編輯:武曉燕 來(lái)源: 黑光技術(shù)
相關(guān)推薦

2010-06-11 14:31:08

通信協(xié)議

2011-05-26 10:05:48

MongoDB

2015-08-10 15:12:27

Java實(shí)例源碼分析

2021-12-15 15:03:51

Linux內(nèi)核調(diào)度

2022-03-11 20:23:14

鴻蒙源碼分析進(jìn)程管理

2022-01-06 07:06:52

KubernetesResourceAPI

2011-05-26 16:18:51

Mongodb

2022-01-10 15:31:44

鴻蒙HarmonyOS應(yīng)用

2022-01-12 10:50:23

鴻蒙HarmonyOS應(yīng)用

2017-03-17 15:05:05

Linux內(nèi)核源碼do_fork

2023-02-26 08:42:10

源碼demouseEffect

2012-09-20 10:07:29

Nginx源碼分析Web服務(wù)器

2021-07-06 09:29:38

Cobar源碼AST

2021-03-23 09:17:58

SpringMVCHttpServletJavaEE

2024-06-13 07:55:19

2023-04-28 08:42:08

Linux內(nèi)核SPI驅(qū)動(dòng)

2010-03-22 09:52:30

Server Sock

2010-09-03 10:33:38

ppp內(nèi)核

2020-10-30 08:35:23

Java Virtua

2021-12-01 15:59:22

鴻蒙HarmonyOS應(yīng)用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)