Skip to content

Commit

Permalink
feat(net): Temporarily completed user space testing of netlink/uevent (
Browse files Browse the repository at this point in the history
…#926)

* add netlink todo directory

* save the work 2 another system workplace

* save the work 2 another system workplace

* add the demo of netlink_create and locate the kobject_uevent\kobject_uevent_env

* add the uevent directory and demo of kobject_uevent and kobject_uevent_env

* delete sth else in target

* handle existing errors, ready for the next period of dev

* 阶段性提交,完成了kobjectuevent_env的部分逻辑,接下来需要实现uevent_ops结构体的转写

* 调整uevent_suppress和subsystem,修改分支日志打印信息

* 调整uevent_suppress和subsystem,修改分支日志打印信息

* 在kset中引入了KsetUeventOps的trait,待实现

* 阶段性提交, 基本完成了处理kset的uevent_ops相关逻辑,新增一个trait和一个结构体,正在逐步完善kobject_uevent_env

* 阶段性提交:完善大部分kobject_uevent_env函数的功能

* add_uevent_var,kobject_uevent_net_broadcast,zap_modalias_env,完善其他细节的逻辑

* 阶段性提交,开始逐渐深入与netlink

* 阶段性提交,重构netlinktable和netlinksocket

* replace kdebug with log::info!

* 理清了sock和ueventsock的关系,重构了一部分原来的代码

* 阶段性提交,新增了几个函数,进一步完善了netlink

* 阶段性提交,新增了Sk_Buff封装了一层PacketBuffer,需要解决mc_list迭代器实现方案和PacketBuffer提供的接口不足的问题

* 初步解决mc_list迭代问题和consume_skb

* fmt

* 同步更改

* asy to antoher workplace

* 初步解决现有代码中所有权和生命周期等问题

* fix nlk_sk and init test for uevent

* 初步在driver中成功调用kobject_uevent()进行测试,标记需要发送uevent的地方

* ipml socket for netlinksock

* 阶段性提交,完善netlink_proto相关内容

* 阶段性提交,初步实现netlink_add_usersock_entry等

* 实现netlink_proto_init()

* add NetProtoFamily and NetlinkFamulyOps

* 修复mprotect系统调用未正确设置vm_flags的错误 (#847)

* fix(time): modify update wall time (#836)

更改了时间子系统的update_wall_time函数,通过读取当前周期数,计算delta值进行更新,而不是通过传入delta值进行更新

* chore: 调整triagebot.toml以适应新的组织架构 (#848)

* netlink_insert大体框架,遇到nlk无法修改的问题

* doc: 完善README.md (#849)

* doc: 完善README.md

* chore: 更新sphinx相关配置,适应read the docs的更新 (#850)

根据read the docs在7月15日blog,进行此修改

https://about.readthedocs.com/blog/2024/07/addons-by-default/

* 完善netlink_insert 和 netlink_lookup

* feat(driver/net): 实现Loopback网卡接口 (#845)

* 初步实现loopback设备

* fix: build-scripts和tools目录下的make check指定工具链版本 (#861)

* fix: tcp poll没有正确处理posix socket的listen状态的问题 (#859)

* chore: 将工具链更新到2024-07-23 (#864)

* chore: 将工具链更新到2024-07-23

* 考虑更换Sk_Buffer实现,留档原有方案

* feat(fs): add eventfd syscall support (#858)

* feat(fs): add eventfd syscall support

* 更换Sk_Buffer实现

* refactor: 删除过时的va-pa转换函数,改为统一使用MMArch (#862)

* 需要解决Arc内部可变性问题

* 解决sk:Arc内部可变性问题

* 默认nightly-2024-07-23 & config改为config.toml (#872)

* fix: 修复由于升级到2024-07-23工具链之后,某些机器上面内核运行一直fault的问题。 (#870)

* fix: 修复由于升级到2024-07-23工具链之后,某些机器上面内核运行一直fault的问题。

* 基本实现netlink单播,todo回调函数

* remove unused import

* 考虑是否引入回调函数,补充sockflags

* updates test-uevent

* add endpoint and complete to_endpoint function for NetLinkEndpoint

* feat(cred): 初步实现Cred (#846)

* 初步实现Cred

* 添加seteuid和setegid

* 添加cred测试程序

* 修改Cred::fscmp返回结果为CredFsCmp枚举

* 完善root用户相关信息

* fix: 修复键盘码解析器没能正确处理类似ctrl C的控制字符的问题 (#877)

* fix: 修复键盘码解析器没能正确处理类似ctrl C的控制字符的问题

* fix: 解决ntty潜在的panic问题

* success to call NetlinkSock bind fn and add a fn into Socket trait

* modify handle in NetlinkSock

* fix af_netlink problems in the new branch reported by RA

* updates test-uevent

* add netlink_send adn  netlink_recv

* fix bind

* fix sth

* fix var type

* 初步完成了netlink/uevent在用户空间的创建、绑定和读写测试,下一步是内核中kobject/kset相关的调用调试和uevent文件挂载到sysfs中的需求

* restore recvfrom parameter

---------

Co-authored-by: val213 <[email protected]>
Co-authored-by: MemoryShore <[email protected]>
Co-authored-by: 黄铭涛 <[email protected]>
Co-authored-by: LoGin <[email protected]>
Co-authored-by: SMALLC <[email protected]>
Co-authored-by: linfeng <[email protected]>
Co-authored-by: Jomo <[email protected]>
  • Loading branch information
8 people authored Sep 18, 2024
1 parent 8a254f0 commit 11dad02
Show file tree
Hide file tree
Showing 10 changed files with 213 additions and 119 deletions.
76 changes: 37 additions & 39 deletions kernel/src/net/socket/netlink/af_netlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use crate::time::timer::schedule_timeout;
use crate::{libs::rwlock::RwLock, syscall::Syscall};
use alloc::{boxed::Box, vec::Vec};

use crate::net::socket::{AddressFamily, Endpoint, MessageFlag, Socket};
use crate::net::socket::{AddressFamily, Endpoint, Inode, MessageFlag, Socket};
use lazy_static::lazy_static;

use super::callback::NetlinkCallback;
Expand Down Expand Up @@ -90,7 +90,6 @@ impl<'a> Iterator for HListHeadIter<'a> {
}
}
///
///
#[derive(Clone)]
pub struct NetlinkTable {
hash: HashMap<u32, Arc<Mutex<Box<dyn NetlinkSocket>>>>,
Expand Down Expand Up @@ -207,37 +206,30 @@ fn netlink_proto_init() -> Result<(), SystemError> {
// rtnetlink_init();
Ok(())
}
// 等待重构
///
pub trait NetProtoFamily {
fn create(socket: &mut dyn Socket, protocol: i32, _kern: bool) -> Result<(), Error>;
}
///

pub struct NetlinkFamulyOps {
family: AddressFamily,
// owner: Module,
}

impl NetProtoFamily for NetlinkFamulyOps {
// https://code.dragonos.org.cn/s?refs=netlink_create&project=linux-6.1.9
/// netlink_create() 创建一个netlink套接字
fn create(socket: &mut dyn Socket, protocol: i32, _kern: bool) -> Result<(), Error> {
// 假设我们有一个类型来跟踪协议最大值
const MAX_LINKS: i32 = 1024;
// if socket.type_ != SocketType::Raw && socket.type_ != SocketType::Dgram {
// return Err(Error::SocketTypeNotSupported);
// }
if !(0..MAX_LINKS).contains(&protocol) {
// todo: 这里不符合规范,后续待修改为 SystemError
return Err(Error::ProtocolNotSupported);
}
// 安全的数组索引封装
let protocol = protocol as usize;
// 这里简化了锁和模块加载逻辑
// 假设成功加载了模块和相关函数
Ok(())
}
}
// impl NetProtoFamily for NetlinkFamulyOps {
// // https://code.dragonos.org.cn/s?refs=netlink_create&project=linux-6.1.9
// /// netlink_create() 创建一个netlink套接字
// fn create(socket: &mut dyn Socket, protocol: i32, _kern: bool) -> Result<(), Error> {
// // 假设我们有一个类型来跟踪协议最大值
// const MAX_LINKS: i32 = 1024;
// // if socket.type_ != SocketType::Raw && socket.type_ != SocketType::Dgram {
// // return Err(Error::SocketTypeNotSupported);
// // }
// if !(0..MAX_LINKS).contains(&protocol) {
// // todo: 这里不符合规范,后续待修改为 SystemError
// return Err(Error::ProtocolNotSupported);
// }
// // 安全的数组索引封装
// let protocol = protocol as usize;
// Ok(())
// }
// }

lazy_static! {
static ref NETLINK_FAMILY_OPS: NetlinkFamulyOps = NetlinkFamulyOps {
Expand Down Expand Up @@ -299,10 +291,10 @@ fn netlink_insert(sk: Arc<Mutex<Box<dyn NetlinkSocket>>>, portid: u32) -> Result

Ok(())
}
///
fn netlink_bind(
sock: Arc<Mutex<Box<dyn NetlinkSocket>>>,
addr: &SockAddrNl,
addr_len: usize,
) -> Result<(), SystemError> {
log::info!("netlink_bind here!");
let sk = Arc::clone(&sock);
Expand All @@ -317,10 +309,6 @@ fn netlink_bind(
let mut groups: u32;
let mut bound: bool;

if addr_len < mem::size_of::<SockAddrNl>() {
return Err(SystemError::EINVAL);
}

if nladdr.nl_family != AddressFamily::Netlink {
return Err(SystemError::EINVAL);
}
Expand Down Expand Up @@ -390,6 +378,7 @@ fn netlink_bind(
Ok(())
}


// TODO: net namespace支持
// https://code.dragonos.org.cn/xref/linux-6.1.9/net/netlink/af_netlink.c#532
/// 在 netlink_table 中查找 netlink 套接字
Expand Down Expand Up @@ -481,17 +470,19 @@ impl Socket for NetlinkSock {
match _endpoint {
Endpoint::Netlink(netlinkendpoint) => {
let addr = netlinkendpoint.addr;
let addr_len = netlinkendpoint.addr_len;
let sock: Arc<Mutex<Box<dyn NetlinkSocket>>> =
Arc::new(Mutex::new(Box::new(self.clone())));
netlink_bind(sock, &addr, addr_len);
let _ = netlink_bind(sock, &addr);
}
_ => {
return Err(SystemError::EINVAL);
}
}
Ok(())
}
fn close(&self) -> Result<(), SystemError>{
Ok(())
}
fn listen(&self, _backlog: usize) -> Result<(), SystemError> {
todo!()
}
Expand All @@ -513,6 +504,7 @@ impl Socket for NetlinkSock {
flags: MessageFlag,
address: Endpoint,
) -> Result<usize, SystemError> {
log::debug!("NetlinkSock send_to");
return self.netlink_send(buffer, address);
}
// 借用 recv_from 的接口模拟netlink_recvmsg的功能
Expand All @@ -522,7 +514,8 @@ impl Socket for NetlinkSock {
flags: MessageFlag,
address: Option<Endpoint>,
) -> Result<(usize, Endpoint), SystemError> {
return self.netlink_recv(msg, msg.len(), flags);
log::debug!("NetlinkSock recv_from");
return self.netlink_recv(msg, flags);
}
fn send_buffer_size(&self) -> usize {
log::warn!("send_buffer_size is implemented to 0");
Expand Down Expand Up @@ -675,13 +668,16 @@ impl NetlinkSock {
/// ## 备注
/// netlink套接字在创建的过程中(具体是在 netlink_create 开头),已经和 netlink_ops (socket层netlink协议族的通用操作集合)关联,其中注册的 sendmsg 回调就是指向本函数
fn netlink_send(&self, data: &[u8], address: Endpoint) -> Result<usize, SystemError> {
log::info!("netlink_send: data: {:?}", data);
// 一个有效的 Netlink 消息至少应该包含一个消息头
if data.len() < size_of::<NLmsghdr>() {
log::warn!("netlink_send: data too short, len: {}", data.len());
return Err(SystemError::EINVAL);
}
#[allow(unsafe_code)]
let header = unsafe { &*(data.as_ptr() as *const NLmsghdr) };
if header.nlmsg_len as usize > data.len() {
log::warn!("netlink_send: data too short, nlmsg_len: {}", header.nlmsg_len);
return Err(SystemError::ENAVAIL);
}
// let message_type = NLmsgType::from(header.nlmsg_type);
Expand All @@ -698,6 +694,8 @@ impl NetlinkSock {
};
// 将新消息头序列化到 msg 中
msg.push_ext(new_header);
// 将消息体数据追加到 msg 中
msg.extend_from_slice(data);
// 确保 msg 的长度按照 4 字节对齐
msg.align4();
// msg 的开头设置消息长度。
Expand All @@ -717,7 +715,6 @@ impl NetlinkSock {
fn netlink_recv(
&self,
msg: &mut [u8],
len: usize,
flags: MessageFlag,
) -> Result<(usize, Endpoint), SystemError> {
let mut copied: usize = 0;
Expand All @@ -726,11 +723,12 @@ impl NetlinkSock {

// 判断是否是带外消息,如果是带外消息,直接返回错误码
if flags == MessageFlag::OOB {
log::warn!("netlink_recv: OOB message is not supported");
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}

// 计算实际要复制的数据长度,不能超过 msg_from 的长度 或 msg 缓冲区的长度
let actual_len = msg_kernel.len().min(len);
let actual_len = msg_kernel.len().min(msg.len());

if !msg_kernel.is_empty() {
msg[..actual_len].copy_from_slice(&msg_kernel[..actual_len]);
Expand All @@ -747,10 +745,10 @@ impl NetlinkSock {
nl_pid: self.portid,
nl_groups: 0,
},
addr_len: mem::size_of::<SockAddrNl>(),
});

// 返回复制的字节数和端点信息
log::debug!("netlink_recv: copied: {}, endpoint: {:?}", copied, endpoint);
Ok((copied, endpoint))
}
// // let skb:SkBuff = skb_recv_datagram(sk, &nlk, &mut copied, &err, &ret);
Expand Down
7 changes: 3 additions & 4 deletions kernel/src/net/socket/netlink/endpoint.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use crate::net::syscall::SockAddrNl;
#[derive(Debug, Clone)]
pub struct NetlinkEndpoint {
pub addr: SockAddrNl,
pub addr_len: usize,
pub addr: SockAddrNl
}
impl NetlinkEndpoint {
pub fn new(addr: SockAddrNl, addr_len: usize) -> Self {
NetlinkEndpoint { addr, addr_len }
pub fn new(addr: SockAddrNl) -> Self {
NetlinkEndpoint { addr}
}
}
30 changes: 30 additions & 0 deletions kernel/src/net/socket/netlink/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
use alloc::sync::Arc;
use netlink::NETLINK_KOBJECT_UEVENT;
use system_error::SystemError;

use crate::driver::base::uevent::KobjUeventEnv;

use super::{family, inet::datagram, Inode, Socket, Type};

//https://code.dragonos.org.cn/xref/linux-6.1.9/net/netlink/
/*
.. - -
Expand All @@ -17,3 +25,25 @@ pub mod netlink;
pub mod netlink_proto;
pub mod skbuff;
pub mod sock;

pub struct Netlink;

impl family::Family for Netlink {
fn socket(stype: Type, _protocol: u32) -> Result<Arc<Inode>, SystemError> {
let socket = create_netlink_socket(_protocol)?;
Ok(Inode::new(socket))
}
}

fn create_netlink_socket(
_protocol: u32,
) -> Result<Arc<dyn Socket>, SystemError> {
match _protocol as usize {
NETLINK_KOBJECT_UEVENT => {
Ok(Arc::new(af_netlink::NetlinkSock::new()))
}
_ => {
Err(SystemError::EPROTONOSUPPORT)
}
}
}
2 changes: 0 additions & 2 deletions kernel/src/net/socket/netlink/netlink_diag.rs

This file was deleted.

6 changes: 0 additions & 6 deletions kernel/src/net/socket/netlink/netlink_socket.rs

This file was deleted.

4 changes: 1 addition & 3 deletions kernel/src/net/socket/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ pub fn create_socket(
todo!("AF_INET6 unimplemented");
}
AF::Unix => socket::unix::Unix::socket(socket_type, protocol)?,
AF::Netlink => {
todo!("AF_NETLINK unimplemented");
}
AF::Netlink => {socket::netlink::Netlink::socket(socket_type, protocol)?}
_ => {
todo!("unsupport address family");
}
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/net/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ impl Syscall {
unsafe { addrlen.as_ref() }.ok_or(EINVAL)?.clone(),
)?)
};

log::debug!("call the recvfrom syscall");
let (n, endpoint) = match socket.recv_from(buf, flags, address){
Ok((n,endpoint))=>(n,endpoint),
Err(err)=>{
Expand Down
15 changes: 13 additions & 2 deletions kernel/src/net/syscall_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ impl SockAddr {
AddressFamily::Netlink => {
// TODO: support netlink socket
let addr: SockAddrNl = addr.addr_nl;
return Ok(Endpoint::Netlink(NetlinkEndpoint::new(addr, len as usize)));
return Ok(Endpoint::Netlink(NetlinkEndpoint::new(addr)));
}
_ => {
return Err(SystemError::EINVAL);
Expand Down Expand Up @@ -246,7 +246,18 @@ impl From<Endpoint> for SockAddr {
};

return SockAddr { addr_ll };
}
},

Endpoint::Netlink(netlink_endpoint) => {
let addr_nl = SockAddrNl {
nl_family: AddressFamily::Netlink,
nl_pad: 0,
nl_pid: netlink_endpoint.addr.nl_pid,
nl_groups: netlink_endpoint.addr.nl_groups,
};

return SockAddr { addr_nl };
},

_ => {
// todo: support other endpoint, like Netlink...
Expand Down
Loading

0 comments on commit 11dad02

Please sign in to comment.