1. Generic Netlink 的數據結構
首先, Generic Netlink是按照Family管理的,內核的其它模塊或子系統可以向它注冊自己的Family. 所有的Family會存放在一張Hash鏈表上。
注冊Family:
- #define NLMSG_MIN_TYPE 0x10 /* < 0x10: reserved control messages */
- #define GENL_ID_GENERATE 0
- #define GENL_ID_CTRL NLMSG_MIN_TYPE
- #define GENL_MIN_ID NLMSG_MIN_TYPE
- #define GENL_MAX_ID 1023
如果Family ID是GENL_ID_GENERATE(被定義為0),則表示由系統自動分配ID,否則表示指定固定ID。 指定的ID必須在大於0x10並小於等於1023. 0x10被預留給CTRL_FAMILY.
自動分配ID的方法是從0x10開始找到第一個未被分配的ID。
可見Family ID是全局唯一的。
Family在Hash表上的位置由ID決定, ID & 0x0F, 也就是ID的低四Bit決定
Family name最好也是全局唯一的, 在genl_family_find_byname(char *name)函數中可見它是找到第一個匹配的name就返回的。
Family的maxattr:根據maxattr的值給struct nlattr ** attrbuf; 分配相應大小的內存。nlattr的作用後面會講到。
每個Family都會有一個operations的列表,可以調用genl_register_ops()函數把各個ops添加到famliy 的ops_list;鏈表中。每個ops都有一個cmd和相應的Handler.
每個Family通常也都會有一個mc_group的列表。
每個mc_group都隸屬於一個Famliy, 同一個Family內的mc_group不能有相同的name,
Name是由用戶指定的,但是ID是由系統分配的,在genl_register_mc_group()函數裡面會分配ID
分配ID的方法是:在起始地址為mc_groups的內存地方設置一個bitmap, bit0初始化為1, 然後尋找第一個為零的Bit,該Bit的位置即為mc_group的ID, 並把該Bit置為1
這個Bitmap初始化時只有32Bit空間,隨著Group數目的增多會動態增大。
可見:mc_group的ID是全局唯一的。