Files
DragonOS/kernel/src/net/socket/netlink/route/message/attr/addr.rs
T
火花 50a70e9424 feat(net): 桥接网络支持 (#1287)
* feat: 新增veth和bridge结构体,尚未详细测试

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(net): 完善一下已有的bridge以及veth设备,增加一些调试信息

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(net): 完善veth网卡驱动,能通过测例;简单修改vridge设备,尚未测试

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(routing): 简单添加路由子系统,尚未完成

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(veth): 增加veth默认对端路由

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(socket): 恢复udp socket中的wait_queue等待

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(net): 补充bridge的实现

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(bridge): 更改测试程序

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 重命名测试程序

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 更改veth&beidge测试程序的toml

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 暂时添加route_iface以及route_table

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: draft router

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 实现简单的路由功能,未详细测试

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 添加netlink框架,内核相应的处理逻辑以及读取写入用户空间尚未完成

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(netlink): 完善netlink的读写部分,增加addr的内核处理逻辑

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 移动routing的位置

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 补充netlink的阻塞等待逻辑&&fmt

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(netns): 添加网络命名空间

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(netns): 删除全局路由,使用当前netns下的路由

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(netlink): 将netlink socket移入netns中

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 完成netlink addr消息的支持,增加测试程序

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(netlink): 消除一些warning

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* fix: 新建netns时插入loopback网卡到设备列表

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 将veth和bridge测试程序改用C完成

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(gdb): 增加gdb debug可选项

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* fix: 修复SockAddrIn结构体中的sin_addr字节序问题,确保正确处理IPv4地址

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 手糊实现路由功能,后续需要更改事件驱动

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(netlink): 补充getlink方法以及相关结构体

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* Refactor network driver interfaces and introduce NAPI support

- Removed the default_iface parameter.
- Introduced a new NAPI module to manage network polling and scheduling.
- Updated the Iface trait to include a napi_struct method for NAPI support.
- Modified Veth network interfaces to integrate with the new NAPI structure.
- Refactored the Router implementation to remove unnecessary polling threads and wait queues.
- Updated NetNamespace to manage a list of bridge devices.
- Cleaned up various unused methods and comments across network-related files.

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 将virtio网卡的处理逻辑移动进ksoftirqd中

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(netlink): 暂时为多播消息添加allow unused,消除warning

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(nat): 实现SNAT和DNAT

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(epoll): 更改epoll唤醒判断的逻辑,支持socket加入epoll

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 修改test_bind,防止爆内存

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 添加一个路由todo信息

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* fix: rebase主线之后修改冲突

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: fmt

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 清除无用日志

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 补充一个panic信息

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 将kernel文件夹重命名为kern

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: 删除netlink测试程序中的linux/netlink.h头文件

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

---------

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
2025-10-30 01:55:04 +08:00

126 lines
3.8 KiB
Rust

use crate::net::socket::netlink::{message::attr::Attribute, route::message::attr::IFNAME_SIZE};
use alloc::ffi::CString;
use system_error::SystemError;
#[derive(Debug, Clone, Copy)]
#[repr(u16)]
#[expect(non_camel_case_types)]
#[expect(clippy::upper_case_acronyms)]
enum AddrAttrClass {
UNSPEC = 0,
ADDRESS = 1,
LOCAL = 2,
LABEL = 3,
BROADCAST = 4,
ANYCAST = 5,
CACHEINFO = 6,
MULTICAST = 7,
FLAGS = 8,
RT_PRIORITY = 9,
TARGET_NETNSID = 10,
}
impl TryFrom<u16> for AddrAttrClass {
type Error = SystemError;
fn try_from(value: u16) -> Result<Self, Self::Error> {
match value {
0 => Ok(AddrAttrClass::UNSPEC),
1 => Ok(AddrAttrClass::ADDRESS),
2 => Ok(AddrAttrClass::LOCAL),
3 => Ok(AddrAttrClass::LABEL),
4 => Ok(AddrAttrClass::BROADCAST),
5 => Ok(AddrAttrClass::ANYCAST),
6 => Ok(AddrAttrClass::CACHEINFO),
7 => Ok(AddrAttrClass::MULTICAST),
8 => Ok(AddrAttrClass::FLAGS),
9 => Ok(AddrAttrClass::RT_PRIORITY),
10 => Ok(AddrAttrClass::TARGET_NETNSID),
_ => Err(SystemError::EINVAL),
}
}
}
#[derive(Debug)]
pub enum AddrAttr {
Address([u8; 4]),
Local([u8; 4]),
Label(CString),
}
impl AddrAttr {
fn class(&self) -> AddrAttrClass {
match self {
AddrAttr::Address(_) => AddrAttrClass::ADDRESS,
AddrAttr::Local(_) => AddrAttrClass::LOCAL,
AddrAttr::Label(_) => AddrAttrClass::LABEL,
}
}
}
impl Attribute for AddrAttr {
fn type_(&self) -> u16 {
self.class() as u16
}
fn payload_as_bytes(&self) -> &[u8] {
match self {
AddrAttr::Address(addr) => addr.as_ref(),
AddrAttr::Local(addr) => addr.as_ref(),
AddrAttr::Label(label) => label.to_bytes_with_nul(),
}
}
fn read_from_buf(
header: &crate::net::socket::netlink::message::attr::CAttrHeader,
payload_buf: &[u8],
) -> Result<Option<Self>, SystemError>
where
Self: Sized,
{
let payload_len = header.payload_len();
// TODO: Currently, `IS_NET_BYTEORDER_MASK` and `IS_NESTED_MASK` are ignored.
let Ok(addr_class) = AddrAttrClass::try_from(header.type_()) else {
//reader.skip_some(payload_len);
return Ok(None);
};
// 拷贝payload_buf到本地变量,避免生命周期问题
let buf = &payload_buf[..payload_len.min(payload_buf.len())];
let res = match (addr_class, buf.len()) {
(AddrAttrClass::ADDRESS, 4) => {
let mut arr = [0u8; 4];
arr.copy_from_slice(&buf[0..4]);
AddrAttr::Address(arr)
}
(AddrAttrClass::LOCAL, 4) => {
let mut arr = [0u8; 4];
arr.copy_from_slice(&buf[0..4]);
AddrAttr::Local(arr)
}
(AddrAttrClass::LABEL, 1..=IFNAME_SIZE) => {
// 查找第一个0字节作为结尾,否则用全部
let nul_pos = buf.iter().position(|&b| b == 0).unwrap_or(buf.len());
let cstr = CString::new(&buf[..nul_pos]).map_err(|_| SystemError::EINVAL)?;
AddrAttr::Label(cstr)
}
(AddrAttrClass::ADDRESS | AddrAttrClass::LOCAL | AddrAttrClass::LABEL, _) => {
log::warn!(
"address attribute `{:?}` contains invalid payload",
addr_class
);
return Err(SystemError::EINVAL);
}
(_, _) => {
log::warn!("address attribute `{:?}` is not supported", addr_class);
// reader.skip_some(payload_len);
return Ok(None);
}
};
Ok(Some(res))
}
}