日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

netlink怎么读_ovs源码阅读--netlink使用

發布時間:2025/3/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 netlink怎么读_ovs源码阅读--netlink使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

netlink

netlink socket是一種用于用戶態進程和內核態進程之間的通信機制。它通過為內核模塊提供一組特殊的API,并為用戶程序提供了一組標準的socket接口的方式,實現了全雙工的通訊連接。

特點:

雙向傳輸,異步通信

用戶空間中使用標準socket API

內核空間中使用專門的API

支持多播

可由內核端發起通信

支持32種協議類型

netlink僅支持32種協議類型,這在實際應用中可能并不足夠,因此產生了generic netlink(以下簡稱為genl),

generic netlink支持1023個子協議號,彌補了netlink協議類型較少的缺陷。

通信架構

Netlink子系統:所有genl通信的基礎,Netlink子系統中收到的所有Generic類型的netlink數據都被送到genl總線上;從內核發出的數據也經由genl總線送至netlink子系統,再打包送至用戶空間

Generic Netlink控制器:作為內核的一部分,負責動態地分配genl通道(即genl family id),并管理genl任務,genl控制器是一個特殊的genl內核用戶,它負責監聽genl bus上的通信通道

genl通信建立在一系列的通信通道的基礎上,每個genl family對應多個通道,這些通道由genl控制器動態分配

相關結構體

genl family

Generic Netlink是基于客戶端-服務端模型的通信機制,服務端注冊family(family是對genl服務的各項定義的集合),控制器和客戶端都通過已注冊的信息與服務端通信。

//genl_family主要字段

struct genl_family

{

unsigned intid;//family id

unsigned int hdrsize; //用戶自定議頭部長度

char name[GENL_NAMSIZ]; //family名,要求不同的family使用不同的名字

unsigned int version;//版本

unsigned int maxattr;//最大attr類型數,使用netlink標準的attr來傳輸數據

genl_ops *ops;// 操作集合

};

genl_ops

定義了netlink family相關的操作

// genl_ops主要字段

struct genl_ops

{

u8 cmd;//命令名,用于識別genl_ops

unsigned int flags;//設置屬性

struct nla_policy *policy; //定義了attr規則,genl在觸發事件處理程序之前,會用其進行attr校驗

int (*doit)(struct sk_buff *skb, struct genl_info *info);

int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb);

};

doit:回調函數,在generic netlink收到數據時觸發,運行在進程上下文

dumpit:回調函數,當genl_ops的flag標志被添加了NLM_F_DUMP以后,每次收到genl消息即會回觸發這個函數

dumpit與doit的區別是:dumpit的第一個參數skb不會攜帶從客戶端發來的數據。相反地,開發者應該在skb中填入需要傳給客戶端的數據,skb中攜帶的數據會被自動送到客戶端。只要dumpit的返回值大于0,dumpit函數就會再次被調用,并被要求在skb中填入數據。當服務端沒有數據要傳給客戶端時,dumpit要返回0。如果函數中出錯,要求返回一個負值。

nal_policy

定義了attr規則

struct nla_policy

{

u16 type;//attr中的數據類型

u16 len;//如果在type字段配置的是字符串有關的值,要把len設置為字符串的最大長度

};

genl_info

內核在接收到用戶的genetlink消息后,會對消息解析并封裝成genl_info結構

struct genl_info

{

u32 snd_seq; //發送序號

u32 snd_pid; //發送客戶端的PID

struct nlmsghdr * nlhdr; //netlink header的指針

struct genlmsghdr * genlhdr; //genl頭部的指針(即family頭部)

void * userhdr; //用戶自定義頭部指針

struct nlattr ** attrs; //如果定義了genl_ops->policy,保存被policy過濾以后的結果

};

Generic Netlink服務端(內核)初始化

這里以OVS中packet的處理為例:

1. 定義family

//定義packet family

static struct genl_family dp_packet_genl_family __ro_after_init = {

.hdrsize = sizeof(struct ovs_header),

.name = OVS_PACKET_FAMILY,

.version = OVS_PACKET_VERSION,

.maxattr = OVS_PACKET_ATTR_MAX,

.netnsok = true,

.parallel_ops = true,

.ops = dp_packet_genl_ops, //操作集合

.n_ops = ARRAY_SIZE(dp_packet_genl_ops),

.module = THIS_MODULE,

};

2. 定義operation

// 定義packet family 的操作 --- packet類型的操作只支持OVS_PACKET_CMD_EXECUTE

static struct genl_ops dp_packet_genl_ops[] = {

{ .cmd = OVS_PACKET_CMD_EXECUTE,

.flags = GENL_UNS_ADMIN_PERM,

.policy = packet_policy,

.doit = ovs_packet_cmd_execute //接受數據包時,調用ovs_packet_cmd_execute進行處理

}

};

// 定義packet family 的過濾規則

static const struct nla_policy packet_policy[OVS_PACKET_ATTR_MAX + 1] = {

[OVS_PACKET_ATTR_PACKET] = { .len = ETH_HLEN },

[OVS_PACKET_ATTR_KEY] = { .type = NLA_NESTED },

[OVS_PACKET_ATTR_ACTIONS] = { .type = NLA_NESTED },

[OVS_PACKET_ATTR_PROBE] = { .type = NLA_FLAG },

[OVS_PACKET_ATTR_MRU] = { .type = NLA_U16 },

};

3. 注冊family

genl_register_family(&dp_packet_genl_family);

Generic Netlink客戶端(用戶空間)初始化

struct sockaddr_nl saddr;

int sock;

sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); //創建一個netlink類型的socket

if (sock < 0) {

return -1;

}

memset(&saddr, 0, sizeof(saddr));

saddr.nl_family = AF_NETLINK;

saddr.nl_pid = getpid();//獲取family id

if (bind(sock, (struct sockaddr*)&saddr, sizeof(saddr)) < 0) {//綁定

printf("bind fail!\n");

close(*p_sock);

return -1;

}

內核空間接受發送數據

接受數據:內核端一旦收到generic netlink數據,會觸發doit函數運行,通過回調函數進行處理

發送數據:將數據打包好之后,可通過單播(genlmsg_unicast)或多播()的形式進行發送

用戶空間接受發送數據

接受數據:調用recv函數即可完成從內核來的數據的接收

發送數據:調用sendto來發送數據

netlink收發數據—以ovs中packet為例

參考內容

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的netlink怎么读_ovs源码阅读--netlink使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。