netlink.rs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. use alloc::{
  2. boxed::Box,
  3. slice,
  4. sync::{Arc, Weak},
  5. vec::Vec,
  6. };
  7. use system_error::SystemError;
  8. //定义Netlink消息的结构体,如NLmsghdr和geNLmsghdr(拓展的netlink消息头),以及用于封包和解包消息的函数。
  9. //参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/netlink.h
  10. // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
  11. // Ensure the header is only included once
  12. use crate::libs::mutex::Mutex;
  13. use core::mem;
  14. use super::af_netlink::{
  15. netlink_insert, Listeners, NetlinkFlags, NetlinkSock, NetlinkSocket, NL_TABLE,
  16. };
  17. // Netlink protocol family
  18. pub const NETLINK_ROUTE: usize = 0;
  19. pub const NETLINK_UNUSED: usize = 1;
  20. pub const NETLINK_USERSOCK: usize = 2;
  21. pub const NETLINK_FIREWALL: usize = 3;
  22. pub const NETLINK_SOCK_DIAG: usize = 4;
  23. pub const NETLINK_NFLOG: usize = 5;
  24. pub const NETLINK_XFRM: usize = 6;
  25. pub const NETLINK_SELINUX: usize = 7;
  26. pub const NETLINK_ISCSI: usize = 8;
  27. pub const NETLINK_AUDIT: usize = 9;
  28. pub const NETLINK_FIB_LOOKUP: usize = 10;
  29. pub const NETLINK_CONNECTOR: usize = 11;
  30. pub const NETLINK_NETFILTER: usize = 12;
  31. pub const NETLINK_IP6_FW: usize = 13;
  32. pub const NETLINK_DNRTMSG: usize = 14;
  33. // implemente uevent needed
  34. pub const NETLINK_KOBJECT_UEVENT: usize = 15;
  35. pub const NETLINK_GENERIC: usize = 16;
  36. // pub const NETLINK_DM : usize = 17; // Assuming DM Events is unused, not defined
  37. pub const NETLINK_SCSITRANSPORT: usize = 18;
  38. pub const NETLINK_ECRYPTFS: usize = 19;
  39. pub const NETLINK_RDMA: usize = 20;
  40. pub const NETLINK_CRYPTO: usize = 21;
  41. pub const NETLINK_SMC: usize = 22;
  42. //pub const NETLINK_INET_DIAG = NETLINK_SOCK_DIAG;
  43. pub const NETLINK_INET_DIAG: usize = 4;
  44. pub const MAX_LINKS: usize = 32;
  45. pub const NL_CFG_F_NONROOT_RECV: u32 = 1 << 0;
  46. pub const NL_CFG_F_NONROOT_SEND: u32 = 1 << 1;
  47. bitflags! {
  48. /// 四种通用的消息类型 nlmsg_type
  49. pub struct NLmsgType: u8 {
  50. /* Nothing. */
  51. const NLMSG_NOOP = 0x1;
  52. /* Error */
  53. const NLMSG_ERROR = 0x2;
  54. /* End of a dump */
  55. const NLMSG_DONE = 0x3;
  56. /* Data lost */
  57. const NLMSG_OVERRUN = 0x4;
  58. }
  59. //消息标记 nlmsg_flags
  60. // const NLM_F_REQUEST = 1; /* It is request message. */
  61. // const NLM_F_MULTI = 2; /* Multipart message, terminated by NLMSG_DONE */
  62. // const NLM_F_ACK = 4; /* Reply with ack, with zero or error code */
  63. // const NLM_F_ECHO = 8; /* Echo this request */
  64. // const NLM_F_DUMP_INTR = 16; /* Dump was inconsistent due to sequence change */
  65. pub struct NLmsgFlags: u16 {
  66. /* Flags values */
  67. const NLM_F_REQUEST = 0x01;
  68. const NLM_F_MULTI = 0x02;
  69. const NLM_F_ACK = 0x04;
  70. const NLM_F_ECHO = 0x08;
  71. const NLM_F_DUMP_INTR = 0x10;
  72. const NLM_F_DUMP_FILTERED = 0x20;
  73. /* Modifiers to GET request */
  74. const NLM_F_ROOT = 0x100; /* specify tree root */
  75. const NLM_F_MATCH = 0x200; /* return all matching */
  76. const NLM_F_ATOMIC = 0x400; /* atomic GET */
  77. //const NLM_F_DUMP = NLM_F_ROOT | NLM_F_MATCH;
  78. const NLM_F_DUMP = 0x100 | 0x200;
  79. /* Modifiers to NEW request */
  80. const NLM_F_REPLACE = 0x100; /* Override existing */
  81. const NLM_F_EXCL = 0x200; /* Do not touch, if it exists */
  82. const NLM_F_CREATE = 0x400; /* Create, if it does not exist */
  83. const NLM_F_APPEND = 0x800; /* Add to end of list */
  84. /* Modifiers to DELETE request */
  85. const NLM_F_NONREC = 0x100; /* Do not delete recursively */
  86. /* Flags for ACK message */
  87. const NLM_F_CAPPED = 0x100; /* request was capped */
  88. const NLM_F_ACK_TLVS = 0x200; /* extended ACK TVLs were included */
  89. }
  90. }
  91. /// netlink消息报头
  92. /**
  93. * struct NLmsghdr - fixed format metadata header of Netlink messages
  94. * @nlmsg_len: Length of message including header
  95. * @nlmsg_type: Message content type
  96. * @nlmsg_flags: Additional flags
  97. * @nlmsg_seq: Sequence number
  98. * @nlmsg_pid: Sending process port ID
  99. */
  100. pub struct NLmsghdr {
  101. pub nlmsg_len: usize,
  102. pub nlmsg_type: NLmsgType,
  103. pub nlmsg_flags: NLmsgFlags,
  104. pub nlmsg_seq: u32,
  105. pub nlmsg_pid: u32,
  106. }
  107. const NLMSG_ALIGNTO: usize = 4;
  108. #[derive(Debug, PartialEq, Copy, Clone)]
  109. pub enum NetlinkState {
  110. NetlinkUnconnected = 0,
  111. NetlinkConnected,
  112. NETLINK_S_CONGESTED = 2,
  113. }
  114. fn nlmsg_align(len: usize) -> usize {
  115. (len + NLMSG_ALIGNTO - 1) & !(NLMSG_ALIGNTO - 1)
  116. }
  117. fn nlmsg_hdrlen() -> usize {
  118. nlmsg_align(mem::size_of::<NLmsghdr>())
  119. }
  120. fn nlmsg_length(len: usize) -> usize {
  121. len + nlmsg_hdrlen()
  122. }
  123. fn nlmsg_space(len: usize) -> usize {
  124. nlmsg_align(nlmsg_length(len))
  125. }
  126. unsafe fn nlmsg_data(nlh: &NLmsghdr) -> *mut u8 {
  127. ((nlh as *const NLmsghdr) as *mut u8).add(nlmsg_length(0))
  128. }
  129. unsafe fn nlmsg_next(nlh: *mut NLmsghdr, len: usize) -> *mut NLmsghdr {
  130. let nlmsg_len = (*nlh).nlmsg_len;
  131. let new_len = len - nlmsg_align(nlmsg_len);
  132. nlh.add(nlmsg_align(nlmsg_len))
  133. }
  134. fn nlmsg_ok(nlh: &NLmsghdr, len: usize) -> bool {
  135. len >= nlmsg_hdrlen() && nlh.nlmsg_len >= nlmsg_hdrlen() && nlh.nlmsg_len <= len
  136. }
  137. fn nlmsg_payload(nlh: &NLmsghdr, len: usize) -> usize {
  138. nlh.nlmsg_len - nlmsg_space(len)
  139. }
  140. // 定义类型别名来简化闭包类型的定义
  141. type InputCallback = Arc<dyn FnMut() + Send + Sync>;
  142. type BindCallback = Arc<dyn Fn(i32) -> i32 + Send + Sync>;
  143. type UnbindCallback = Arc<dyn Fn(i32) -> i32 + Send + Sync>;
  144. type CompareCallback = Arc<dyn Fn(&NetlinkSock) -> bool + Send + Sync>;
  145. /// 该结构包含了内核netlink的可选参数:
  146. #[derive(Default)]
  147. pub struct NetlinkKernelCfg {
  148. pub groups: u32,
  149. pub flags: u32,
  150. pub input: Option<InputCallback>,
  151. pub bind: Option<BindCallback>,
  152. pub unbind: Option<UnbindCallback>,
  153. pub compare: Option<CompareCallback>,
  154. }
  155. impl NetlinkKernelCfg {
  156. pub fn new() -> Self {
  157. NetlinkKernelCfg {
  158. groups: 32,
  159. flags: 0,
  160. input: None,
  161. bind: None,
  162. unbind: None,
  163. compare: None,
  164. }
  165. }
  166. pub fn set_input<F>(&mut self, callback: F)
  167. where
  168. F: FnMut() + Send + Sync + 'static,
  169. {
  170. self.input = Some(Arc::new(callback));
  171. }
  172. pub fn set_bind<F>(&mut self, callback: F)
  173. where
  174. F: Fn(i32) -> i32 + Send + Sync + 'static,
  175. {
  176. self.bind = Some(Arc::new(callback));
  177. }
  178. pub fn set_unbind<F>(&mut self, callback: F)
  179. where
  180. F: Fn(i32) -> i32 + Send + Sync + 'static,
  181. {
  182. self.unbind = Some(Arc::new(callback));
  183. }
  184. pub fn set_compare<F>(&mut self, callback: F)
  185. where
  186. F: Fn(&NetlinkSock) -> bool + Send + Sync + 'static,
  187. {
  188. self.compare = Some(Arc::new(callback));
  189. }
  190. }
  191. //https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/netlink.h#229
  192. //netlink属性头
  193. struct NLattr {
  194. nla_len: u16,
  195. nla_type: u16,
  196. }
  197. pub trait VecExt {
  198. fn align4(&mut self);
  199. fn push_ext<T: Sized>(&mut self, data: T);
  200. fn set_ext<T: Sized>(&mut self, offset: usize, data: T);
  201. }
  202. impl VecExt for Vec<u8> {
  203. fn align4(&mut self) {
  204. let len = (self.len() + 3) & !3;
  205. if len > self.len() {
  206. self.resize(len, 0);
  207. }
  208. }
  209. fn push_ext<T: Sized>(&mut self, data: T) {
  210. #[allow(unsafe_code)]
  211. let bytes =
  212. unsafe { slice::from_raw_parts(&data as *const T as *const u8, size_of::<T>()) };
  213. for byte in bytes {
  214. self.push(*byte);
  215. }
  216. }
  217. fn set_ext<T: Sized>(&mut self, offset: usize, data: T) {
  218. if self.len() < offset + size_of::<T>() {
  219. self.resize(offset + size_of::<T>(), 0);
  220. }
  221. #[allow(unsafe_code)]
  222. let bytes =
  223. unsafe { slice::from_raw_parts(&data as *const T as *const u8, size_of::<T>()) };
  224. self[offset..(bytes.len() + offset)].copy_from_slice(bytes);
  225. }
  226. }
  227. // todo: net namespace
  228. pub fn netlink_kernel_create(
  229. unit: usize,
  230. cfg: Option<NetlinkKernelCfg>,
  231. ) -> Result<NetlinkSock, SystemError> {
  232. // THIS_MODULE
  233. let mut nlk: NetlinkSock = NetlinkSock::new();
  234. let sk: Arc<Mutex<Box<dyn NetlinkSocket>>> = Arc::new(Mutex::new(Box::new(nlk.clone())));
  235. let groups: u32;
  236. if unit >= MAX_LINKS {
  237. return Err(SystemError::EINVAL);
  238. }
  239. __netlink_create(&mut nlk, unit, 1).expect("__netlink_create failed");
  240. if let Some(cfg) = cfg.as_ref() {
  241. if cfg.groups < 32 {
  242. groups = 32;
  243. } else {
  244. groups = cfg.groups;
  245. }
  246. } else {
  247. groups = 32;
  248. }
  249. let listeners = Listeners::new();
  250. // todo:设计和实现回调函数
  251. // sk.sk_data_read = netlink_data_ready;
  252. // if cfg.is_some() && cfg.unwrap().input.is_some(){
  253. // nlk.netlink_rcv = cfg.unwrap().input;
  254. // }
  255. netlink_insert(sk, 0).expect("netlink_insert failed");
  256. nlk.flags |= NetlinkFlags::NETLINK_F_KERNEL_SOCKET.bits();
  257. let mut nl_table = NL_TABLE.write();
  258. if nl_table[unit].get_registered() == 0 {
  259. nl_table[unit].set_groups(groups);
  260. if let Some(cfg) = cfg.as_ref() {
  261. nl_table[unit].bind = cfg.bind.clone();
  262. nl_table[unit].unbind = cfg.unbind.clone();
  263. nl_table[unit].set_flags(cfg.flags);
  264. if cfg.compare.is_some() {
  265. nl_table[unit].compare = cfg.compare.clone();
  266. }
  267. nl_table[unit].set_registered(1);
  268. } else {
  269. drop(listeners);
  270. let registered = nl_table[unit].get_registered();
  271. nl_table[unit].set_registered(registered + 1);
  272. }
  273. }
  274. return Ok(nlk);
  275. }
  276. fn __netlink_create(nlk: &mut NetlinkSock, unit: usize, kern: usize) -> Result<i32, SystemError> {
  277. // 其他的初始化配置参数
  278. nlk.flags = kern as u32;
  279. nlk.protocol = unit;
  280. return Ok(0);
  281. }
  282. pub fn sk_data_ready(nlk: Arc<NetlinkSock>) -> Result<(), SystemError> {
  283. // 唤醒
  284. return Ok(());
  285. }