如何玩轉(zhuǎn)linux內(nèi)核netlink通信機(jī)制,從這三點(diǎn)入手!
一、什么是Netlink通信機(jī)制
Netlink套接字是用以實(shí)現(xiàn)用戶進(jìn)程與內(nèi)核進(jìn)程通信的一種特殊的進(jìn)程間通信(IPC) ,也是網(wǎng)絡(luò)應(yīng)用程序與內(nèi)核通信的最常用的接口。
Netlink 是一種特殊的 socket,它是 Linux 所特有的,類似于 BSD 中的AF_ROUTE 但又遠(yuǎn)比它的功能強(qiáng)大,目前在Linux 內(nèi)核中使用netlink 進(jìn)行應(yīng)用與內(nèi)核通信的應(yīng)用很多; 包括:路由 daemon(NETLINK_ROUTE),用戶態(tài) socket 協(xié)議(NETLINK_USERSOCK),防火墻(NETLINK_FIREWALL),netfilter 子系統(tǒng)(NETLINK_NETFILTER),內(nèi)核事件向用戶態(tài)通知(NETLINK_KOBJECT_UEVENT),通用 netlink(NETLINK_GENERIC)等。
Netlink 是一種在內(nèi)核與用戶應(yīng)用間進(jìn)行雙向數(shù)據(jù)傳輸?shù)姆浅:玫姆绞?,用戶態(tài)應(yīng)用使用標(biāo)準(zhǔn)的 socket API 就可以使用 netlink 提供的強(qiáng)大功能,內(nèi)核態(tài)需要使用專門的內(nèi)核 API 來(lái)使用 netlink。
Netlink 相對(duì)于系統(tǒng)調(diào)用,ioctl 以及 /proc文件系統(tǒng)而言具有以下優(yōu)點(diǎn):
netlink使用簡(jiǎn)單,只需要在include/linux/netlink.h中增加一個(gè)新類型的 netlink 協(xié)議定義即可,(如 #define NETLINK_TEST 20 然后,內(nèi)核和用戶態(tài)應(yīng)用就可以立即通過(guò) socket API 使用該 netlink 協(xié)議類型進(jìn)行數(shù)據(jù)交換);
netlink是一種異步通信機(jī)制,在內(nèi)核與用戶態(tài)應(yīng)用之間傳遞的消息保存在socket緩存隊(duì)列中,發(fā)送消息只是把消息保存在接收者的socket的接收隊(duì)列,而不需要等待接收者收到消息;
使用 netlink 的內(nèi)核部分可以采用模塊的方式實(shí)現(xiàn),使用 netlink 的應(yīng)用部分和內(nèi)核部分沒(méi)有編譯時(shí)依賴; netlink 支持多播,內(nèi)核模塊或應(yīng)用可以把消息多播給一個(gè)netlink組,屬于該neilink 組的任何內(nèi)核模塊或應(yīng)用都能接收到該消息,內(nèi)核事件向用戶態(tài)的通知機(jī)制就使用了這一特性;
內(nèi)核可以使用 netlink 首先發(fā)起會(huì)話;
二、Netlink常用數(shù)據(jù)結(jié)構(gòu)及函數(shù)
用戶態(tài)應(yīng)用使用標(biāo)準(zhǔn)的 socket API有(sendto()),recvfrom(); sendmsg(), recvmsg())
下面簡(jiǎn)單介紹幾種NETLINK用戶態(tài)通信的常用數(shù)據(jù)結(jié)構(gòu)
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個(gè)人覺(jué)得比較好的學(xué)習(xí)書(shū)籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。?!前100名進(jìn)群領(lǐng)取,額外贈(zèng)送一份價(jià)值699的內(nèi)核資料包(含視頻教程、電子書(shū)、實(shí)戰(zhàn)項(xiàng)目及代碼)??


?
1、用戶態(tài)數(shù)據(jù)結(jié)構(gòu)
Netlink通信跟常用UDP Socket通信類似:
struct sockaddr_nl 是netlink通信地址跟普通socket struct sockaddr_in類似
struct sockaddr_nl結(jié)構(gòu):
struct nlmsghd結(jié)構(gòu):
nlmsg_len:整個(gè)netlink消息的長(zhǎng)度(包含消息頭);
nlmsg_type:消息狀態(tài),內(nèi)核在include/uapi/linux/netlink.h中定義了以下4種通用的消息類型,它們分別是:
3. nlmsg_flags:消息標(biāo)記,它們用以表示消息的類型,如下
4. nlmsg_seq:消息序列號(hào),用以將消息排隊(duì),有些類似TCP協(xié)議中的序號(hào)(不完全一樣),但是netlink的這個(gè)字段是可選的,不強(qiáng)制使用;
5. nlmsg_pid:發(fā)送端口的ID號(hào),對(duì)于內(nèi)核來(lái)說(shuō)該值就是0,對(duì)于用戶進(jìn)程來(lái)說(shuō)就是其socket所綁定的ID號(hào)。
struct msghdr 結(jié)構(gòu)體
2、netlink 內(nèi)核數(shù)據(jù)結(jié)構(gòu)、常用宏及函數(shù):
netlink消息類型:
netlink常用宏:
netlink 內(nèi)核常用函數(shù):
netlink_kernel_create內(nèi)核函數(shù)用于創(chuàng)建 內(nèi)核socket用用戶態(tài)通信
單播netlink_unicast()和 多播netlink_broadcast()
三、netlink實(shí)例
(1)用戶態(tài)程序 (sendto(), recvfrom())
Netlink 內(nèi)核模塊代碼:
Makeflie:
運(yùn)行結(jié)果:
首先將編譯出來(lái)的Netlink內(nèi)核模塊插入到系統(tǒng)當(dāng)中(insmod netlink_test.ko)可以看到如下:
接著運(yùn)行應(yīng)用程序:./a.out
