From b850a6420372779f23f25469f8fe187043d6d310 Mon Sep 17 00:00:00 2001 From: ZCShou <72115@163.com> Date: Wed, 10 Jun 2026 11:24:30 +0800 Subject: [PATCH 01/11] refactor(ax-net): unify network stack into single net/ax-net crate, remove legacy axnet and axnet-ng --- Cargo.lock | 23 +- Cargo.toml | 7 +- .../april-2026-retrospective.md | 2 +- .../may-2026-retrospective.md | 4 +- docs/docs/architecture/arceos.md | 6 +- docs/docs/architecture/rdrive-rdif.md | 8 +- docs/docs/components/crates/ax-errno.md | 4 +- docs/docs/components/crates/ax-fs-ng.md | 4 +- docs/docs/components/crates/ax-io.md | 6 +- docs/docs/components/crates/ax-lazyinit.md | 2 +- docs/docs/components/crates/ax-net-ng.md | 153 ----- docs/docs/components/crates/ax-net.md | 262 ++------ docs/docs/components/crates/ax-sync.md | 4 +- docs/docs/components/crates/ax-task.md | 2 +- docs/docs/components/crates/axfs-ng-vfs.md | 12 +- docs/docs/components/crates/axpoll.md | 8 +- docs/docs/components/crates/bwbench-client.md | 15 +- docs/docs/components/crates/smoltcp-fuzz.md | 2 +- docs/docs/components/crates/smoltcp.md | 24 +- docs/docs/components/crates/starry-kernel.md | 6 +- docs/docs/components/layers.md | 38 +- docs/docs/components/overview.md | 3 +- docs/docs/debug/lock-usage-followups.md | 2 +- docs/docs/development/arceos.md | 15 +- docs/docs/development/starryos.md | 2 +- docs/qperf-virtio-optimization-report.md | 4 +- .../axnet-ng => net/ax-net}/CHANGELOG.md | 22 +- .../axnet-ng => net/ax-net}/Cargo.toml | 2 +- .../axnet-ng => net/ax-net}/src/consts.rs | 1 + .../ax-net}/src/device/driver.rs | 0 .../ax-net}/src/device/ethernet.rs | 0 .../ax-net}/src/device/loopback.rs | 0 .../axnet-ng => net/ax-net}/src/device/mod.rs | 0 .../ax-net}/src/device/vsock.rs | 0 .../axnet-ng => net/ax-net}/src/general.rs | 0 .../axnet-ng => net/ax-net}/src/lib.rs | 111 +++- .../ax-net}/src/listen_table.rs | 0 .../axnet-ng => net/ax-net}/src/options.rs | 0 .../axnet-ng => net/ax-net}/src/raw.rs | 0 .../axnet-ng => net/ax-net}/src/router.rs | 0 .../axnet-ng => net/ax-net}/src/service.rs | 7 + .../axnet-ng => net/ax-net}/src/socket.rs | 0 .../axnet-ng => net/ax-net}/src/state.rs | 0 .../axnet-ng => net/ax-net}/src/tcp.rs | 0 .../axnet-ng => net/ax-net}/src/udp.rs | 0 .../axnet-ng => net/ax-net}/src/unix/dgram.rs | 0 .../axnet-ng => net/ax-net}/src/unix/mod.rs | 0 .../ax-net}/src/unix/stream.rs | 0 .../ax-net}/src/vsock/connection_manager.rs | 0 .../axnet-ng => net/ax-net}/src/vsock/mod.rs | 0 .../ax-net}/src/vsock/stream.rs | 0 .../axnet-ng => net/ax-net}/src/wrapper.rs | 0 os/StarryOS/kernel/CHANGELOG.md | 4 +- os/StarryOS/kernel/Cargo.toml | 4 +- os/arceos/api/arceos_api/Cargo.toml | 1 + os/arceos/api/arceos_api/src/imp/net.rs | 100 ++- os/arceos/api/arceos_posix_api/Cargo.toml | 1 + os/arceos/api/arceos_posix_api/src/imp/net.rs | 122 ++-- os/arceos/api/axfeat/Cargo.toml | 2 - os/arceos/modules/axnet/CHANGELOG.md | 43 -- os/arceos/modules/axnet/Cargo.toml | 50 -- os/arceos/modules/axnet/src/lib.rs | 59 -- .../modules/axnet/src/smoltcp_impl/addr.rs | 4 - .../modules/axnet/src/smoltcp_impl/bench.rs | 68 -- .../modules/axnet/src/smoltcp_impl/dns.rs | 92 --- .../axnet/src/smoltcp_impl/listen_table.rs | 164 ----- .../modules/axnet/src/smoltcp_impl/mod.rs | 354 ----------- .../modules/axnet/src/smoltcp_impl/tcp.rs | 590 ------------------ .../modules/axnet/src/smoltcp_impl/udp.rs | 299 --------- os/arceos/modules/axruntime/CHANGELOG.md | 4 +- os/arceos/modules/axruntime/Cargo.toml | 6 +- os/arceos/modules/axruntime/src/devices.rs | 53 +- os/arceos/modules/axruntime/src/lib.rs | 6 +- os/arceos/tools/bwbench_client/README.md | 17 +- p.md | 333 ++++++++++ scripts/axbuild/CHANGELOG.md | 2 +- scripts/test/std_crates.csv | 1 - 77 files changed, 788 insertions(+), 2352 deletions(-) delete mode 100644 docs/docs/components/crates/ax-net-ng.md rename {os/arceos/modules/axnet-ng => net/ax-net}/CHANGELOG.md (75%) rename {os/arceos/modules/axnet-ng => net/ax-net}/Cargo.toml (98%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/consts.rs (96%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/device/driver.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/device/ethernet.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/device/loopback.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/device/mod.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/device/vsock.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/general.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/lib.rs (68%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/listen_table.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/options.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/raw.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/router.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/service.rs (98%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/socket.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/state.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/tcp.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/udp.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/unix/dgram.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/unix/mod.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/unix/stream.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/vsock/connection_manager.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/vsock/mod.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/vsock/stream.rs (100%) rename {os/arceos/modules/axnet-ng => net/ax-net}/src/wrapper.rs (100%) delete mode 100644 os/arceos/modules/axnet/CHANGELOG.md delete mode 100644 os/arceos/modules/axnet/Cargo.toml delete mode 100644 os/arceos/modules/axnet/src/lib.rs delete mode 100644 os/arceos/modules/axnet/src/smoltcp_impl/addr.rs delete mode 100644 os/arceos/modules/axnet/src/smoltcp_impl/bench.rs delete mode 100644 os/arceos/modules/axnet/src/smoltcp_impl/dns.rs delete mode 100644 os/arceos/modules/axnet/src/smoltcp_impl/listen_table.rs delete mode 100644 os/arceos/modules/axnet/src/smoltcp_impl/mod.rs delete mode 100644 os/arceos/modules/axnet/src/smoltcp_impl/tcp.rs delete mode 100644 os/arceos/modules/axnet/src/smoltcp_impl/udp.rs create mode 100644 p.md diff --git a/Cargo.lock b/Cargo.lock index 6d73128057..23e3201301 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -529,6 +529,7 @@ dependencies = [ "ax-runtime", "ax-sync", "ax-task", + "axpoll", ] [[package]] @@ -738,7 +739,6 @@ dependencies = [ "ax-kspin", "ax-log", "ax-net", - "ax-net-ng", "ax-runtime", "ax-sync", "ax-task", @@ -972,23 +972,6 @@ dependencies = [ [[package]] name = "ax-net" -version = "0.5.16" -dependencies = [ - "ax-errno 0.6.0", - "ax-hal", - "ax-io", - "ax-lazyinit", - "ax-net-ng", - "ax-sync", - "ax-task", - "cfg-if", - "log", - "smoltcp 0.13.1", - "spin 0.12.0", -] - -[[package]] -name = "ax-net-ng" version = "0.7.1" dependencies = [ "async-channel", @@ -1164,6 +1147,7 @@ dependencies = [ "ax-runtime", "ax-sync", "ax-task", + "axpoll", "bindgen 0.72.1", "flatten_objects", "scope-local", @@ -1198,7 +1182,6 @@ dependencies = [ "ax-memory-addr", "ax-mm", "ax-net", - "ax-net-ng", "ax-percpu", "ax-plat", "ax-task", @@ -7670,7 +7653,7 @@ dependencies = [ "ax-memory-addr", "ax-memory-set", "ax-mm", - "ax-net-ng", + "ax-net", "ax-page-table-multiarch", "ax-percpu", "ax-runtime", diff --git a/Cargo.toml b/Cargo.toml index 5477900b0b..4d8b48cf1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -98,8 +98,7 @@ members = [ "os/arceos/modules/axipi", "os/arceos/modules/axlog", "os/arceos/modules/axmm", - "os/arceos/modules/axnet", - "os/arceos/modules/axnet-ng", + "net/ax-net", "os/arceos/modules/axruntime", "os/arceos/modules/axsync", "os/arceos/modules/axtask", @@ -171,8 +170,8 @@ ax-memory-addr = { version = "0.6.9", path = "memory/memory_addr" } ax-memory-set = { version = "0.6.10", path = "memory/memory_set" } axpanic = { version = "0.1.0", path = "components/axpanic" } ax-mm = { version = "0.5.17", path = "os/arceos/modules/axmm" } -ax-net = { version = "0.5.16", path = "os/arceos/modules/axnet" } -ax-net-ng = { version = "0.7.1", path = "os/arceos/modules/axnet-ng" } +ax-net = { version = "0.7.1", path = "net/ax-net" } +axnet = { version = "0.7.1", package = "ax-net", path = "net/ax-net" } ax-page-table-entry = { version = "0.8.10", path = "memory/page_table_entry" } ax-page-table-multiarch = { version = "0.8.12", path = "memory/page_table_multiarch" } ax-percpu = { version = "0.4.13", path = "components/percpu/percpu" } diff --git a/docs/blog/2026/05-12-april-2026-retrospective/april-2026-retrospective.md b/docs/blog/2026/05-12-april-2026-retrospective/april-2026-retrospective.md index 1632dab325..fee76ab7ce 100644 --- a/docs/blog/2026/05-12-april-2026-retrospective/april-2026-retrospective.md +++ b/docs/blog/2026/05-12-april-2026-retrospective/april-2026-retrospective.md @@ -115,7 +115,7 @@ Rootfs 处理也经历了模块化重构。我们将共享的 rootfs 辅助函 4 月初最重大的工程是将整个工作区中所有 crate 的名称统一到 `ax-*` 前缀规范下,在 4 月 7-8 日集中完成。此次重命名覆盖了 ArceOS 所有核心模块,涉及数百个文件中的引用更新: - 内核基础设施:`axhal` → `ax-hal`、`axtask` → `ax-task`、`axmm` → `ax-mm`、`axsync` → `ax-sync`、`axdma` → `ax-dma` -- 驱动与设备:`axdriver` → `ax-driver`、`axnet` → `ax-net`、`axnet-ng` → `ax-net-ng`、`axinput` → `ax-input`、`axdisplay` → `ax-display` +- 驱动与设备:`axdriver` → `ax-driver`、`axnet` → `ax-net`、`axnet` → `ax-net`、`axinput` → `ax-input`、`axdisplay` → `ax-display` - 文件系统:`axfs` → `ax-fs`、`axfs-ng` → `ax-fs-ng` - 运行时与配置:`axruntime` → `ax-runtime`、`axconfig` → `ax-config`、`axplat` → `ax-plat` - 标准库与 POSIX:`axstd` → `ax-std`、`axlibc` → `ax-libc`、`arceos_api` → `ax-api`、`arceos_posix_api` → `ax-posix-api` diff --git a/docs/blog/2026/06-01-may-2026-retrospective/may-2026-retrospective.md b/docs/blog/2026/06-01-may-2026-retrospective/may-2026-retrospective.md index 4be1c86701..a74f88f727 100644 --- a/docs/blog/2026/06-01-may-2026-retrospective/may-2026-retrospective.md +++ b/docs/blog/2026/06-01-may-2026-retrospective/may-2026-retrospective.md @@ -112,10 +112,10 @@ ArceOS 本月继续加强运行时错误发现能力。lockdep 扩展了 task-he ### 网络栈与 POSIX 行为 -网络栈方面,`ax-net` 迁移到 crates.io 版本的 smoltcp,并在后续同步到 smoltcp 0.13.1。`ax-net-ng` 新增 ICMP raw socket 支持,并修复 TCP send 后未轮询接口导致 epoll waiter 无法被及时唤醒的问题。随后,socket option、ARP pending queue、SIOCGIFINDEX/FIONREAD 等行为也继续向 Linux 兼容语义靠拢。 +网络栈方面,`ax-net` 迁移到 crates.io 版本的 smoltcp,并在后续同步到 smoltcp 0.13.1。`ax-net` 新增 ICMP raw socket 支持,并修复 TCP send 后未轮询接口导致 epoll waiter 无法被及时唤醒的问题。随后,socket option、ARP pending queue、SIOCGIFINDEX/FIONREAD 等行为也继续向 Linux 兼容语义靠拢。 - [PR #410](https://github.com/rcore-os/tgoskits/pull/410) — `ax-net` 迁移到 crates.io smoltcp(周睿) -- [PR #368](https://github.com/rcore-os/tgoskits/pull/368) — `ax-net-ng` ICMP raw socket 支持(sunhaosheng) +- [PR #368](https://github.com/rcore-os/tgoskits/pull/368) — `ax-net` ICMP raw socket 支持(sunhaosheng) - [PR #485](https://github.com/rcore-os/tgoskits/pull/485) — TCP send 后轮询接口以唤醒 epoll waiter(CharlieV) - [PR #884](https://github.com/rcore-os/tgoskits/pull/884) — `SO_TYPE`、`SO_PROTOCOL`、`SO_DOMAIN` socket option 支持(取地址符) - [PR #911](https://github.com/rcore-os/tgoskits/pull/911) — ARP pending queue drain 与 cache TTL/capacity 调整(Feiran Qin) diff --git a/docs/docs/architecture/arceos.md b/docs/docs/architecture/arceos.md index da40281ba0..6fd36811e8 100644 --- a/docs/docs/architecture/arceos.md +++ b/docs/docs/architecture/arceos.md @@ -93,8 +93,7 @@ ArceOS 的 17 个模块按重要性分为两类:四个必选模块构成最小 | `ax-driver` | `ax-driver` | 设备探测与驱动初始化(virtio、AHCI、SDMMC 等) | | `ax-fs` | `fs` | 文件系统(FAT、ramfs、ext4) | | `ax-fs-ng` | `fs-ng` | 下一代文件系统(FAT、ext4,带 LRU 缓存) | -| `ax-net` | `net` | 网络栈(基于 smoltcp) | -| `ax-net-ng` | `net-ng` | 下一代网络栈(异步感知,基于 smoltcp) | +| `ax-net` | `net` | 统一网络栈(TCP/UDP/raw/Unix/vsock/DNS/DHCP,基于 smoltcp) | | `ax-display` | `display` | 图形显示(帧缓冲) | | `ax-input` | `input` | 输入设备管理 | | `ax-dma` | `dma` | DMA 内存分配与管理(依赖 `paging`) | @@ -114,11 +113,10 @@ ArceOS 的 17 个模块按重要性分为两类:四个必选模块构成最小 | `ax-sync` | `modules/axsync` | mutex 等同步原语 | `ax-task`、任意并发模块 | | `ax-driver` | `modules/axdriver` | 设备探测与驱动初始化 | `ax-fs`、`ax-net`、`ax-display` | | `ax-fs` | `modules/axfs` | 文件系统挂载、文件/目录 API | `ax-driver` | -| `ax-net` | `modules/axnet` | 网络栈、socket 抽象 | `ax-driver` | +| `ax-net` | `net/ax-net` | 统一网络栈、socket 抽象 | `rd-net`、`rdif-vsock`、`smoltcp` | | `axconfig` | `modules/axconfig` | 构建期常量与目标参数 | 所有模块 | | `ax-log` | `modules/axlog` | 多级日志与格式化输出 | 所有模块 | | `ax-fs-ng` | `modules/axfs-ng` | 下一代文件系统 | `ax-driver` | -| `ax-net-ng` | `modules/axnet-ng` | 下一代网络栈 | `ax-driver` | | `ax-dma` | `modules/axdma` | DMA 内存分配与管理 | `ax-runtime`、`ax-mm` | | `ax-ipi` | `modules/axipi` | 处理器间中断管理 | `ax-hal` | | `ax-input` | `modules/axinput` | 输入设备管理与事件分发 | `ax-driver` | diff --git a/docs/docs/architecture/rdrive-rdif.md b/docs/docs/architecture/rdrive-rdif.md index ae55321fea..2a01665ff5 100644 --- a/docs/docs/architecture/rdrive-rdif.md +++ b/docs/docs/architecture/rdrive-rdif.md @@ -69,7 +69,7 @@ flowchart TB subgraph Consumers["消费方"] Runtime["ax-runtime"] Fs["ax-fs / ax-fs-ng"] - Net["ax-net / ax-net-ng"] + Net["ax-net / ax-net"] Starry["starry-kernel"] Axvisor["axvisor"] end @@ -351,7 +351,7 @@ Phase 3: block volume service Phase 4: NET / NET-NG 硬切 -- `ax-net` / `ax-net-ng` 从 `AxNetDevice` 切到 `rd-net` 或 net service。 +- `ax-net` / `ax-net` 从 `AxNetDevice` 切到 `rd-net` 或 net service。 - DHCP/static IP policy 留在 net service 或 NET/NET-NG,不回到 platform glue。 Phase 5: display / input / vsock 硬切 @@ -388,7 +388,7 @@ yarn build cargo xtask clippy --package rdrive cargo xtask clippy --package ax-runtime cargo xtask clippy --package ax-fs-ng -cargo xtask clippy --package ax-net-ng +cargo xtask clippy --package ax-net cargo xtask clippy --package starry-kernel cargo xtask clippy --package axvisor ``` @@ -406,6 +406,6 @@ rg "rdrive::get_|rdrive::get_one|rdrive::get_list" os/arceos/modules os/StarryOS - StarryOS QEMU smoke。 - ext4 rootfs 启动与读写。 -- `net-ng` / DHCP。 +- `net` / DHCP。 - aarch64 QEMU 动态平台配置。 - Axvisor QEMU / GIC / `rdif-intc` 路径。 diff --git a/docs/docs/components/crates/ax-errno.md b/docs/docs/components/crates/ax-errno.md index 4f1c18c55b..263aa9e08f 100644 --- a/docs/docs/components/crates/ax-errno.md +++ b/docs/docs/components/crates/ax-errno.md @@ -67,7 +67,7 @@ flowchart TD ### 使用场景 - `AxErrorKind` / `AxError`:在 `ax-alloc`、`ax-mm`、`ax-net`、`ax-fs`、`ax-task` 等模块里高频使用。 -- `LinuxError`:在 `ax-libc`、`ax-posix-api`、`ax-net-ng` 的 POSIX 兼容路径中直接使用。 +- `LinuxError`:在 `ax-libc`、`ax-posix-api`、`ax-net` 的 POSIX 兼容路径中直接使用。 - `ax_err!` / `ax_err_type!`:在 `axvisor`、`ax-net`、`ax-std`、`ax-task` 等代码里广泛出现。 - `canonicalize()`:适合把兼容层传回来的 Linux 错误重新折叠到内核内部语义。 @@ -86,7 +86,7 @@ graph LR ax_errno --> ax-allocator["ax-allocator"] ax_errno --> axio["ax-io"] ax_errno --> ax-mm["ax-mm"] - ax_errno --> ax-net["ax-net/ax-net-ng"] + ax_errno --> ax-net["ax-net/ax-net"] ax_errno --> ax-api["ax-api"] ax_errno --> arceos_posix["ax-posix-api"] ax_errno --> starry_kernel["starry-kernel"] diff --git a/docs/docs/components/crates/ax-fs-ng.md b/docs/docs/components/crates/ax-fs-ng.md index 0aa3365ff6..6bce6a4b36 100644 --- a/docs/docs/components/crates/ax-fs-ng.md +++ b/docs/docs/components/crates/ax-fs-ng.md @@ -41,7 +41,7 @@ graph LR current --> axpoll["axpoll"] current --> ax-sync["ax-sync"] ax_feat["ax-feat"] --> current - ax_net_ng["ax-net-ng"] --> current + ax_net["ax-net"] --> current ax_runtime["ax-runtime"] --> current starry_kernel["starry-kernel"] --> current ``` @@ -74,7 +74,7 @@ graph LR ### 3.3 被依赖情况 - `ax-feat` -- `ax-net-ng` +- `ax-net` - `ax-runtime` - `starry-kernel` diff --git a/docs/docs/components/crates/ax-io.md b/docs/docs/components/crates/ax-io.md index 43a614d5eb..eb4e3a022d 100644 --- a/docs/docs/components/crates/ax-io.md +++ b/docs/docs/components/crates/ax-io.md @@ -52,7 +52,7 @@ - `IoBuf::remaining()`:当前还剩多少字节可读 - `IoBufMut::remaining_mut()`:当前还剩多少空间可写 -这不是新的 I/O 模型,而是给通用 trait 层补上一点对内核路径很实用的容量语义。`ax-net-ng` 的发送/接收接口、部分文件与缓冲区适配器都会消费这类信息。 +这不是新的 I/O 模型,而是给通用 trait 层补上一点对内核路径很实用的容量语义。`ax-net` 的发送/接收接口、部分文件与缓冲区适配器都会消费这类信息。 ### 1.5 `alloc` feature 的边界 @@ -93,7 +93,7 @@ 1. `ax_std::io` 直接重导出 `axio` 的 trait 与类型,把它包装成 ArceOS 应用看到的 `std::io` 风格接口。 2. `ax-fs`、`ax-fs-ng` 的文件对象实现 `Read` / `Write` / `Seek`,复用统一的缓冲器和默认读写逻辑。 -3. `ax-net`、`ax-net-ng` 以及更上层 socket 封装使用 `axio` 作为同步收发 trait 的公共接口。 +3. `ax-net`、`ax-net` 以及更上层 socket 封装使用 `axio` 作为同步收发 trait 的公共接口。 4. `ax-api`、`ax-posix-api`、StarryOS 的 `FileLike`/用户缓冲访问对象通过 `axio` 收敛系统调用读写路径。 ### 2.3 `PollState` 的实际使用位置 @@ -130,7 +130,7 @@ - `ax-std`、`ax-libc` - `ax-api`、`ax-posix-api` - `ax-fs`、`ax-fs-ng` -- `ax-net`、`ax-net-ng` +- `ax-net`、`ax-net` - StarryOS 的文件、网络、pipe、用户态缓冲访问和系统调用包装层 ### 3.3 跨层关系 diff --git a/docs/docs/components/crates/ax-lazyinit.md b/docs/docs/components/crates/ax-lazyinit.md index 243540c811..796cce052a 100644 --- a/docs/docs/components/crates/ax-lazyinit.md +++ b/docs/docs/components/crates/ax-lazyinit.md @@ -75,7 +75,7 @@ graph LR ax_lazyinit --> ax-mm["ax-mm"] ax_lazyinit --> ax-ipi["ax-ipi"] ax_lazyinit --> ax-fs["ax-fs / ax-fs-ng"] - ax_lazyinit --> ax-net["ax-net / ax-net-ng"] + ax_lazyinit --> ax-net["ax-net / ax-net"] ax_lazyinit --> ax-display["ax-display"] ax_lazyinit --> ax-input["ax-input"] ax_lazyinit --> axplat["多个 axplat 平台 crate"] diff --git a/docs/docs/components/crates/ax-net-ng.md b/docs/docs/components/crates/ax-net-ng.md deleted file mode 100644 index 5bd6b0da83..0000000000 --- a/docs/docs/components/crates/ax-net-ng.md +++ /dev/null @@ -1,153 +0,0 @@ -# `ax-net-ng` - -> 路径:`os/arceos/modules/axnet-ng` -> 类型:库 crate -> 分层:ArceOS 层 / ArceOS 内核模块 -> 版本:`0.5.0` -> 文档依据:当前仓库源码、`Cargo.toml` 与 未检测到 crate 层 README - -`ax-net-ng` 的核心定位是:ArceOS network module - -## 架构设计 -- 目录角色:ArceOS 内核模块 -- crate 形态:库 crate -- 工作区位置:子工作区 `os/arceos` -- feature 视角:主要通过 `vsock` 控制编译期能力装配。 -- 关键数据结构:可直接观察到的关键数据结构/对象包括 `ListenTableEntryInner`、`ListenTable`、`UnixCredentials`、`Rule`、`RouteTable`、`Router`、`GetSocketOption`、`SetSocketOption`、`SocketAddrEx`、`Shutdown` 等(另有 8 个关键类型/对象)。 - -### 模块结构 -- `consts`:内部子模块 -- `device`:设备抽象、枚举与访问封装 -- `general`:内部子模块 -- `listen_table`:内部子模块 -- `options`:内部子模块 -- `router`:内部子模块 -- `service`:内部子模块 -- `socket`:socket 状态机与收发接口 - -### 核心机制 -- socket 状态机与连接管理 -- 虚拟 socket 通道管理 - -## 核心功能 -- 功能定位:ArceOS network module -- 对外接口:从源码可见的主要公开入口包括 `init_network`、`init_vsock`、`poll_interfaces`、`new`、`nonblocking`、`reuse_address`、`send_timeout`、`recv_timeout`、`ListenTableEntryInner`、`ListenTable` 等(另有 11 个公开入口)。 -- 典型使用场景:主要作为仓库中的专用支撑 crate 被上层组件调用。 -- 关键调用链示例:按当前源码布局,常见入口/初始化链可概括为 `init_network()` -> `init_vsock()` -> `poll_interfaces()` -> `register_waker()` -> `new()`。 - -## 依赖关系 -```mermaid -graph LR - current["ax-net-ng"] - current --> axconfig["ax-config"] - current --> ax-driver["ax-driver"] - current --> ax_errno["ax-errno"] - current --> axfs_ng["ax-fs-ng"] - current --> axfs_ng_vfs["axfs-ng-vfs"] - current --> ax-hal["ax-hal"] - current --> axio["ax-io"] - current --> axpoll["axpoll"] - ax_runtime["ax-runtime"] --> current - starry_kernel["starry-kernel"] --> current -``` - -### 直接依赖 -- `axconfig` -- `ax-driver` -- `ax-errno` -- `ax-fs-ng` -- `axfs-ng-vfs` -- `ax-hal` -- `axio` -- `axpoll` -- `ax-sync` -- `ax-task` -- `smoltcp` - -### 间接依赖 -- `ax-arm-pl031` -- `axaddrspace` -- `ax-alloc` -- `axallocator` -- `axbacktrace` -- `ax-config-gen` -- `ax-config-macros` -- `ax-cpu` -- `ax-dma` -- `rdrive` -- `rd-net` -- 另外还有 `38` 个同类项未在此展开 - -### 3.3 被依赖情况 -- `ax-runtime` -- `starry-kernel` - -### 被依赖情况 -- `arceos-affinity` -- `arceos-display` -- `arceos-exception` -- `arceos-fs-shell` -- `arceos-irq` -- `arceos-memtest` -- `arceos-net-echoserver` -- `arceos-net-httpclient` -- `arceos-net-httpserver` -- `arceos-net-udpserver` -- `arceos-parallel` -- `arceos-priority` -- 另外还有 `17` 个同类项未在此展开 - -### 外部依赖 -- `async-channel` -- `async-trait` -- `bitflags` -- `cfg-if` -- `enum_dispatch` -- `event-listener` -- `hashbrown` -- `lazy_static` -- `log` -- `ringbuf` -- `spin` - -## 开发指南 -### 接入方式 -```toml -[dependencies] -ax-net-ng = { workspace = true } - -# 如果在仓库外独立验证,也可以显式绑定本地路径: -# ax-net-ng = { path = "os/arceos/modules/axnet-ng" } -``` - -### 初始化 -1. 在 `Cargo.toml` 中接入该 crate,并根据需要开启相关 feature。 -2. 若 crate 暴露初始化入口,优先调用 `init`/`new`/`build`/`start` 类函数建立上下文。 -3. 在最小消费者路径上验证公开 API、错误分支与资源回收行为。 - -### API 使用 -- 优先关注函数入口:`init_network`、`init_vsock`、`poll_interfaces`、`new`、`nonblocking`、`reuse_address`、`send_timeout`、`recv_timeout` 等(另有 23 项)。 -- 上下文/对象类型通常从 `ListenTableEntryInner`、`ListenTable`、`UnixCredentials`、`Rule`、`RouteTable`、`Router` 等(另有 7 项) 等结构开始。 - -## 测试 -### 测试覆盖 -- 当前 crate 目录中未发现显式 `tests/`/`benches/`/`fuzz/` 入口,更可能依赖上层系统集成测试或跨 crate 回归。 - -### 单元测试 -- 建议覆盖公开 API、状态转换和异常分支。 - -### 集成测试 -- 建议补充最小消费者路径,验证该 crate 在真实调用链中可用。 - -### 覆盖率 -- 覆盖率建议:公开 API、边界条件和关键错误处理路径需要显式覆盖。 - -## 跨项目定位 -### ArceOS -`ax-net-ng` 直接位于 `os/arceos/` 目录树中,是 ArceOS 工程本体的一部分,承担 ArceOS 内核模块。 - -### StarryOS -`ax-net-ng` 不在 StarryOS 目录内部,但被 `starry-kernel` 等 StarryOS crate 直接依赖,说明它是该系统的共享构件或底层服务。 - -### Axvisor -`ax-net-ng` 主要通过 `axvisor` 等上层 crate 被 Axvisor 间接复用,通常处于更底层的公共依赖层。 diff --git a/docs/docs/components/crates/ax-net.md b/docs/docs/components/crates/ax-net.md index 034fc6f93e..7475040d4c 100644 --- a/docs/docs/components/crates/ax-net.md +++ b/docs/docs/components/crates/ax-net.md @@ -1,222 +1,92 @@ # `ax-net` -> 路径:`os/arceos/modules/axnet` +> 路径:`net/ax-net` > 类型:库 crate -> 分层:ArceOS 层 / 第一代 IP 网络模块 -> 版本:`0.3.0-preview.3` -> 文档依据:`Cargo.toml`、`src/lib.rs`、`src/smoltcp_impl/mod.rs`、`src/smoltcp_impl/tcp.rs`、`src/smoltcp_impl/udp.rs`、`src/smoltcp_impl/dns.rs`、`src/smoltcp_impl/listen_table.rs`、`src/smoltcp_impl/bench.rs`、`os/arceos/modules/axruntime/src/lib.rs`、`os/arceos/api/ax-api/src/imp/net.rs`、`os/arceos/api/arceos_posix_api/src/imp/net.rs` +> 分层:根目录通用网络子系统 +> 版本:`0.7.1` +> 文档依据:`net/ax-net/Cargo.toml`、`net/ax-net/src/lib.rs`、`net/ax-net/src/socket.rs`、`net/ax-net/src/tcp.rs`、`net/ax-net/src/udp.rs`、`net/ax-net/src/raw.rs`、`net/ax-net/src/unix/*`、`net/ax-net/src/vsock/*`、`net/ax-net/src/service.rs`、`net/ax-net/src/router.rs` -`ax-net` 是 ArceOS 老一代网络封装层。它围绕 `smoltcp` 构建一个全局、单接口、同步阻塞风格的 IP socket API,把 TCP、UDP 和 DNS 能力接到 ArceOS 运行时与 API 层上。它关心的是“把一块 NIC 和一份 `smoltcp` 实例变成可用的系统网络能力”,而不是构建跨地址族、跨设备、跨等待模型的通用 socket 服务框架。 - -最核心的边界是:`ax-net` 只是第一代 IP 网络包装层,不是统一 socket 服务层。它的重点是 TCP/UDP/DNS over IP,而不是 Unix domain socket、vsock、复杂路由服务或细粒度事件管理。 +`ax-net` 是仓库唯一的网络栈 crate。它位于根目录 `net/ax-net`,同时服务 ArceOS、StarryOS 以及后续其他系统。旧的 ArceOS-local 网络实现已经不再作为可用入口存在;所有网络 feature 都收敛到 `net`。 ## 架构设计 -### 设计定位 - -`ax-net` 的设计目标非常直接:把 `smoltcp` 变成 ArceOS 可直接消费的同步网络 API。当前实现采用三层收敛: - -- 设备层:从 `ax-driver` 取出一个 `AxNetDevice`,直接适配成 `smoltcp::phy::Device` -- 接口层:使用单个全局 `InterfaceWrapper` 管理唯一网络接口 `eth0` -- socket 层:提供同步的 `TcpSocket`、`UdpSocket` 和 `dns_query()` - -这是一种典型的早期内核集成模型:单 NIC、全局状态、围绕一个 `smoltcp::Interface` 运转。 - -### 模块结构 - -`ax-net` 的主要实现集中在 `smoltcp_impl`: - -| 模块 | 作用 | -| --- | --- | -| `mod.rs` | 全局接口、`SocketSet`、设备适配、轮询主线 | -| `tcp.rs` | TCP socket 的同步封装、连接、监听、接受 | -| `udp.rs` | UDP socket 的绑定、连接、收发与轮询 | -| `dns.rs` | 基于 `smoltcp::socket::dns` 的同步 DNS 查询 | -| `listen_table.rs` | TCP 监听队列表,在首个 SYN 到来时预创建 socket | -| `bench.rs` | 原始帧发送/接收吞吐基准入口 | -| `addr.rs` | 地址类型辅助 | - -### 1.3 初始化模型与全局对象 - -`src/lib.rs` 暴露的入口非常少,但已经把整个设计说透了: - -- `init_network(net_devs)`:从设备容器里取第一个 NIC 作为 `eth0` -- `poll_interfaces()`:推动底层 `smoltcp` 协议栈前进 -- `TcpSocket` / `UdpSocket` / `dns_query()`:供上层实际使用 -- `bench_transmit()` / `bench_receive()`:导出带宽基准路径 - -内部关键全局对象包括: - -- `ETH0`:唯一网络接口 -- `SOCKET_SET`:全局 `smoltcp::SocketSet` -- `LISTEN_TABLE`:监听端口到 SYN 队列的映射 - -这组对象共同说明:`ax-net` 不是多实例、按命名空间拆分的服务,而是一个单体式全局网络模块。 - -### 1.4 设备与接口模型 +`ax-net` 内部分成五层: -`smoltcp_impl/mod.rs` 中的 `DeviceWrapper` 直接把 `AxNetDevice` 适配给 `smoltcp`,并把介质类型固定为 `Medium::Ethernet`。这意味着: - -- `smoltcp` 直接面对以太网设备,不经过更高一级的路由器抽象 -- 发包、收包、tx/rx buffer 回收都由驱动对象承担 -- 接口地址和默认网关依赖 `AX_IP` / `AX_GW` 环境变量 -- 默认 DNS 服务器写死为 `8.8.8.8` - -这一模型足够简单,也正因此不承担多设备转发、loopback 独立建模或更复杂的路由策略。 - -### 1.5 TCP 监听队列的特别设计 - -`listen_table.rs` 与 `RxToken::preprocess()` 组合出 `ax-net` 最有代表性的实现细节:当底层收到首个 TCP SYN 时,`snoop_tcp_packet()` 会提前在 `SocketSet` 中创建一个监听对应的新 socket,并把 handle 塞入端口对应的 SYN 队列。等上层 `accept()` 时,再从队列中取出已经建立连接的 handle。 - -这不是额外的协议实现,而是为了在保持同步 `accept()` 语义的同时,适配 `smoltcp` 原生 socket 集合工作方式。 - -### 1.6 与 `ax-net-ng` 的代际差异 - -| 维度 | `ax-net` | `ax-net-ng` | +| 层次 | 主要模块 | 职责 | | --- | --- | --- | -| 总体定位 | 第一代同步 IP 网络模块 | 第二代统一 socket 服务层 | -| 地址族 | IP/TCP/UDP/DNS | IP + Unix domain + vsock | -| 设备视图 | `smoltcp` 直接面对 Ethernet 设备 | `Router`/`Device` 先做路由、loopback、ARP,再把 IP 包交给 `smoltcp` | -| readiness 语义 | `ax_io::PollState` | `axpoll::IoEvents` | -| 等待方式 | 轮询接口并 `yield_now()` | `poll_io` + waker + timeout | -| 主要消费者 | `ax-api`、`ax-posix-api`、老一代 ArceOS 路径 | `ax-runtime net-ng` 与 StarryOS 主 socket 层 | - -所以,`ax-net` 不是“`ax-net-ng` 的轻量别名”,而是更早一代、边界更窄的 IP 网络封装。 - -## 核心功能 - -### 功能概览 - -- 初始化单个网络接口并配置 IP / 默认网关 -- 提供同步 `TcpSocket` 与 `UdpSocket` -- 提供同步 `dns_query()` 能力 -- 通过 `poll_interfaces()` 驱动 `smoltcp` 协议栈前进 -- 提供原始帧吞吐基准入口,供系统级性能验证使用 - -### 2.2 同步阻塞模型 - -`ax-net` 的阻塞语义不是建立在独立事件层之上,而是建立在“反复推动协议栈 + 让出 CPU”之上: - -1. 先调用 `smoltcp` 的 nonblocking socket API -2. 若当前不可完成,则返回 `AxError::WouldBlock` -3. 在 blocking 模式下,循环调用 `poll_interfaces()` 并穿插 `ax-task::yield_now()` -4. 条件满足后再返回真实结果 +| public facade | `lib.rs` | 暴露初始化、轮询、socket、设备和状态查询 API | +| socket abstraction | `socket.rs`、`options.rs`、`general.rs` | 定义 `Socket`、`SocketOps`、`SocketAddrEx`、socket option、nonblocking/timeout 等公共语义 | +| address-family implementations | `tcp.rs`、`udp.rs`、`raw.rs`、`unix/`、`vsock/` | 实现 TCP、UDP、raw ICMP、Unix domain socket 和可选 vsock | +| protocol service | `service.rs`、`router.rs`、`wrapper.rs`、`listen_table.rs`、`state.rs` | 管理 smoltcp interface、SocketSet、路由、DHCP/DNS 状态和 waker | +| device adaptation | `device/` | 将 `rd-net` / `rdif-vsock` 设备接入网络栈,不包含具体硬件驱动 | -这意味着 `ax-net` 的“阻塞”本质上是一种同步轮询式阻塞,而不是基于 `axpoll` 的等待/唤醒模型。 +`router`、`service`、`wrapper`、`listen_table`、`state` 默认保持 crate-private,外部系统不应绑定这些内部实现细节。 -### 2.3 上层调用关系 +## Public API -仓库里的主要调用链很明确: +运行时初始化入口: -- `ax-runtime` 在启用老一代 `net` 路径时调用 `axnet::init_network(all_devices.net)` -- `ax-api` 直接导出 TCP、UDP、DNS 与 `ax_poll_interfaces()` -- `ax-posix-api` 用它实现 socket、`select`、`epoll` 等 POSIX 兼容接口 -- `ax-std` 再经由更高层 API 把网络能力暴露给 ArceOS 应用 +- `init_network(net_devs)`:由 `ax-runtime` 调用,接入 Ethernet 设备、loopback、router、smoltcp service,并完成静态网络或 DHCP 初始化。 +- `init_vsock(vsock_devs)`:在 `vsock` feature 下启用,由 `ax-runtime` 调用。 +- `poll_interfaces()`:推动收包、发包、协议状态机和 readiness 更新。 -与之相对,当运行时选择 `net-ng` 时,初始化入口会切换到 `axnet_ng::init_network()`,这正好体现了两代实现的并存关系。 +socket 入口: -### 2.4 与带宽基准工具的关系 +- `tcp::TcpSocket` +- `udp::UdpSocket` +- `raw` +- `unix` +- `vsock`(可选) +- `Socket`、`SocketOps`、`SocketAddrEx`、`SendOptions`、`RecvOptions`、`Shutdown` +- `options::{Configurable, GetSocketOption, SetSocketOption, TcpInfo, UnixCredentials}` -`bench_transmit()` / `bench_receive()` 直接走 `DeviceWrapper` 中的原始帧收发基准逻辑: +设备与状态查询: -- 发送侧会构造固定 1500 字节帧,并把 EtherType 置为 IPv4 -- 接收侧只统计收到的字节数 +- `EthernetDeviceList`、`EthernetDriver`、`RdNetDriver` 等设备适配类型。 +- `arp_entries()`:查询 ARP 状态。 +- `dns_query(name)`:基于 smoltcp DNS socket 的正式 DNS 查询 API。 +- `dns_servers()`:只读查询当前 DNS server 列表。 -它们不是普通 socket API,而是给系统带宽基准使用的专门入口,设计上就是为了和宿主机侧 `bwbench-client` 配对验证吞吐。 +## 网络配置 -### 2.5 关键边界 +`ax-net` 支持静态网络和 DHCP: -- `ax-net` 不重新实现 TCP/IP 协议状态机,真正的协议引擎仍然是 `smoltcp` -- `ax-net` 不提供 Unix domain socket、vsock 或统一地址族抽象 -- `ax-net` 不提供细粒度事件注册机制;它只向上暴露 `PollState` -- `ax-net` 不是应用级 HTTP/DNS 客户端库,而是更低层的网络原语层 +- 当 `AX_IP` 和 `AX_GW` 都存在时,使用静态 IP / 网关配置。 +- 否则启用 DHCP。 +- DNS server 优先使用 DHCP 下发值;其次使用静态 `AX_DNS`。 +- 如果没有 DNS server,`dns_query()` 返回错误,不硬编码默认 DNS。 ## 依赖关系 -### 直接依赖 +直接依赖: | 依赖 | 作用 | | --- | --- | -| `ax-driver` | 提供 NIC 设备对象 | -| `ax-hal` | 提供时间接口,驱动 `smoltcp::Instant` | -| `axio` | 提供 `PollState` 与通用 I/O trait | -| `ax-sync` / `spin` / `ax-lazyinit` | 管理全局接口、`SocketSet` 与监听表 | -| `ax-task` | blocking 路径中的 `yield_now()` 与任务协作 | -| `smoltcp` | 真正的 TCP/UDP/DNS/IP 协议实现 | - -### 3.2 主要直接消费者 - -| 消费者 | 使用方式 | -| --- | --- | -| `ax-runtime` | 在老一代 `net` 路径中初始化网络子系统 | -| `ax-api` | 暴露 ArceOS 级 TCP/UDP/DNS 接口 | -| `ax-posix-api` | 实现 POSIX 风格 socket 与多路复用路径 | -| `ax-feat` | 通过 feature 传播把网络能力装入最终镜像 | - -### 3.3 与样例程序的关系 - -虽然 `arceos-httpclient`、`arceos-httpserver` 不直接依赖 `ax-net` 的源码 API,但它们经由 `ax-std`、`ax-api`、`ax-runtime` 间接走的正是这条网络装配链。因此,这些示例更适合作为 `ax-net` 的系统行为样例,而不是 `ax-net` 自身的 API 示例。 - -## 开发指南 - -### 4.1 依赖方式 - -```toml -[dependencies] -axnet = { workspace = true } -``` - -在实际系统镜像里,更常见的接入方式不是手动直接依赖,而是通过 `ax-runtime` / `ax-feat` / `ax-api` 的 feature 传播把它装进系统。 - -### 4.2 修改时必须同步检查的前提 - -1. 当前实现只取第一个 NIC 作为 `eth0`。 -2. 接口地址和网关来自 `AX_IP` / `AX_GW`。 -3. `smoltcp` 看到的是 `Medium::Ethernet` 设备,而不是更高层 IP 设备。 -4. 监听队列依赖 `RxToken::preprocess()` 对首个 SYN 进行预处理。 -5. DNS 服务器默认固定为 `8.8.8.8`。 - -只要改动触碰这些前提,就已经不是简单 bugfix,而是在改变整个一代网络模块的边界。 - -### 4.3 高风险改动点 - -- `listen_table.rs`:直接影响 `accept()` 是否能拿到正确连接 -- TCP/UDP 的 blocking 路径:影响 blocking / nonblocking 行为和 CPU 让出策略 -- `dns.rs`:当前是同步轮询实现,容易受 socket 生命周期与超时处理影响 -- `bench.rs`:与宿主机基准工具的口径绑定较紧,不能按普通 socket 功能随意改 - -## 测试 - -### 5.1 当前测试现状 - -`ax-net` 目录内没有独立的 crate 内 `tests/`。它的正确性主要依赖系统级验证: - -- `ax-api` / `ax-posix-api` 的网络调用路径 -- 启用 `net` 的 ArceOS 示例与应用 -- 宿主机侧网络连通和吞吐验证 - -### 5.2 建议重点 - -- 至少验证一条 TCP client、一条 TCP server、一条 UDP 收发和一条 DNS 查询 -- 修改监听或接收路径时,必须覆盖 `listen` / `accept` / `shutdown` 回归 -- 修改带宽基准相关逻辑时,要同时验证与 `bwbench-client` 的对端行为 - -### 5.3 推荐集成验证 - -- 用 `arceos-httpclient` / `arceos-httpserver` 验证 TCP 主路径 -- 用 POSIX socket 调用路径验证 `ax-posix-api` -- 用 `bench_transmit` / `bench_receive` + `bwbench-client` 验证吞吐基准路径 - -## 跨项目定位 - -### ArceOS - -`ax-net` 是 ArceOS 老一代网络装配链的重要组成部分。它直接服务 `ax-api`、`ax-posix-api` 和运行时 `net` 路径,是早期同步 IP 网络能力的核心封装。 - -### StarryOS - -当前仓库中的 StarryOS 并不直接使用这个 `ax-net` crate。相反,`os/StarryOS/Cargo.toml` 与 `os/StarryOS/kernel/Cargo.toml` 都把依赖名 `ax-net` 绑定到了 `package = "ax-net-ng"`,说明 StarryOS 已经切换到第二代网络层。 - -### Axvisor - -当前没有看到 Axvisor 直接消费 `ax-net` 的证据。即便存在间接复用,也更可能经由 ArceOS 公共 API 层,而不是把这个老一代同步网络模块当成独立基础设施。 +| `smoltcp` | TCP/IP、DHCP、DNS 等协议核心 | +| `axpoll` | readiness、waker 与 `Pollable` 语义 | +| `ax-task` | 阻塞等待、超时、后台任务 | +| `ax-sync` / `ax-kspin` | 锁与同步 | +| `ax-io` | I/O buffer 与读写抽象 | +| `ax-errno` | `AxError` / `AxResult` | +| `ax-config` | `AX_IP`、`AX_GW`、`AX_DNS` 等构建期配置 | +| `ax-hal` | 时间等底层能力 | +| `ax-fs-ng` / `axfs-ng-vfs` | Unix domain socket 路径绑定 | +| `rd-net` | Ethernet queue/DMA 设备抽象 | +| `rdif-vsock` | 可选 vsock 设备抽象 | + +主要消费者: + +- `ax-runtime`:网络和 vsock 初始化。 +- `ax-feat`:`net` / `vsock` feature 装配。 +- `ax-api`、`ax-posix-api`:ArceOS 网络 API 和 POSIX socket 路径。 +- `ax-std`、`ax-libc`:通过上层 API 间接消费网络能力。 +- `starry-kernel`:Linux syscall socket 底层实现。 + +具体网卡驱动、VirtIO/PCI 探测和 DMA 策略仍属于 `drivers/` 与 `ax-driver`;StarryOS 的 `AF_PACKET`、`AF_NETLINK`、Linux sockaddr 编解码和 ioctl 细节仍属于 StarryOS Linux ABI 层。 + +## 测试建议 + +- `cargo xtask clippy --package ax-net` +- ArceOS TCP/UDP/DNS 示例与测试。 +- StarryOS TCP/UDP、epoll、AF_UNIX、raw ICMP、vsock build 测试。 +- DHCP/QEMU user networking 场景,确认 `eth0`、默认路由和 DNS server 获取正常。 diff --git a/docs/docs/components/crates/ax-sync.md b/docs/docs/components/crates/ax-sync.md index cbd89ac0ae..36b5203919 100644 --- a/docs/docs/components/crates/ax-sync.md +++ b/docs/docs/components/crates/ax-sync.md @@ -117,7 +117,7 @@ graph LR ax-sync --> ax-posix-api["ax-posix-api"] ax-sync --> ax-display["ax-display"] ax-sync --> ax-input["ax-input"] - ax-sync --> ax-net["ax-net / ax-net-ng"] + ax-sync --> ax-net["ax-net / ax-net"] ax-sync --> starry_kernel["starry-kernel"] ``` @@ -130,7 +130,7 @@ graph LR ### 主要消费者 - `ax-api`:在 `multitask` 路径下把 `RawMutex` 作为公开类型再导出。 - `ax-posix-api`:用于 pipe、fs、net、pthread mutex 等路径。 -- `ax-net` / `ax-net-ng`、`ax-input`、`ax-display`、`ax-fs-ng`:用 `Mutex` 保护全局状态或共享对象。 +- `ax-net` / `ax-net`、`ax-input`、`ax-display`、`ax-fs-ng`:用 `Mutex` 保护全局状态或共享对象。 - `starry-kernel`:大量复用 `ax-sync::Mutex`,同时与 `spin::SpinNoIrq` 并存。 ### 3.3 间接消费者 diff --git a/docs/docs/components/crates/ax-task.md b/docs/docs/components/crates/ax-task.md index cd177a3191..2a152a3e16 100644 --- a/docs/docs/components/crates/ax-task.md +++ b/docs/docs/components/crates/ax-task.md @@ -149,7 +149,7 @@ graph LR - `ax-sync`:基于 `ax-task` 的阻塞/唤醒机制构建锁和同步原语。 - `ax-api`、`ax-posix-api`:把任务、睡眠、等待队列等能力对外暴露。 - `starry-kernel`:在 Linux 兼容线程模型上直接复用 `ax-task`。 -- `ax-net`、`ax-net-ng`:在网络栈阻塞/异步路径上复用调度与等待能力。 +- `ax-net`、`ax-net`:在网络栈阻塞/异步路径上复用调度与等待能力。 ## 开发指南 ### 接入方式 diff --git a/docs/docs/components/crates/axfs-ng-vfs.md b/docs/docs/components/crates/axfs-ng-vfs.md index 7a9e606401..ca5cf1bdb7 100644 --- a/docs/docs/components/crates/axfs-ng-vfs.md +++ b/docs/docs/components/crates/axfs-ng-vfs.md @@ -4,7 +4,7 @@ > 类型:库 crate > 分层:组件层 / 可复用基础组件 > 版本:`0.1.1` -> 文档依据:`Cargo.toml`、`src/lib.rs`、`src/fs.rs`、`src/mount.rs`、`src/node/mod.rs`、`src/node/dir.rs`、`src/node/file.rs`、`src/path.rs`、`src/types.rs`、`os/arceos/modules/axfs-ng/src/highlevel/file.rs`、`os/arceos/modules/axnet-ng/src/unix/mod.rs`、`os/StarryOS/kernel/src/pseudofs/mod.rs` +> 文档依据:`Cargo.toml`、`src/lib.rs`、`src/fs.rs`、`src/mount.rs`、`src/node/mod.rs`、`src/node/dir.rs`、`src/node/file.rs`、`src/path.rs`、`src/types.rs`、`os/arceos/modules/axfs-ng/src/highlevel/file.rs`、`net/ax-net/src/unix/mod.rs`、`os/StarryOS/kernel/src/pseudofs/mod.rs` `axfs-ng-vfs` 是新文件系统栈真正的核心抽象层。它不是老 `axfs_vfs` 那种“只有一组 trait 的薄接口”,而是完整拥有 `Filesystem`、`Mountpoint`、`Location`、`DirEntry`、元数据模型、目录项缓存、挂载图与路径语义的对象模型库。 @@ -16,7 +16,7 @@ - 对具体文件系统实现者:提供 `FilesystemOps`、`DirNodeOps`、`FileNodeOps` 三组 trait,作为 ext4、FAT、tmpfs、devfs、procfs 等后端的落点。 - 对高层文件接口:提供 `Location`、`Mountpoint`、`Metadata`、`NodeFlags`、`Path`/`PathBuf` 等“有状态对象”,让上层不必自己重新维护挂载树或路径解析。 -- 对跨项目消费者:ArceOS 的 `ax-fs-ng`、`ax-net-ng` 的 Unix socket、StarryOS 的 pseudofs 都可以在同一套节点语义上工作。 +- 对跨项目消费者:ArceOS 的 `ax-fs-ng`、`ax-net` 的 Unix socket、StarryOS 的 pseudofs 都可以在同一套节点语义上工作。 ### 模块结构 - `src/fs.rs`:定义 `FilesystemOps`、`Filesystem` 和 `StatFs`。这是“一个文件系统实例”的外部门面。 @@ -61,7 +61,7 @@ graph TD `DirEntry::user_data()`/`Location::user_data()` 暴露了一个 `TypeMap`。这不是装饰性接口: - `ax_fs_ng::CachedFile` 会把共享页缓存状态挂在这里。 -- `ax-net-ng` 的 Unix socket 会把 `BindSlot` 挂在 socket 节点上。 +- `ax-net` 的 Unix socket 会把 `BindSlot` 挂在 socket 节点上。 也就是说,它是新栈跨层协作的重要扩展点。 @@ -91,7 +91,7 @@ graph TD ### 使用场景 - `ax-fs-ng` 用它组织 ext4/FAT 根文件系统、任务局部 cwd 与页缓存共享。 -- `ax-net-ng` 用它把 Unix socket 地址映射到文件节点。 +- `ax-net` 用它把 Unix socket 地址映射到文件节点。 - StarryOS 用它实现 `tmpfs`、`devfs`、`procfs`、`sysfs` 一类 pseudofs,并支撑文件系统调用层。 ## 依赖关系 @@ -101,7 +101,7 @@ graph LR axpoll["axpoll"] --> current current --> axfs_ng["ax-fs-ng"] - current --> ax-net_ng["ax-net-ng"] + current --> ax-net_ng["ax-net"] current --> starry_pseudofs["StarryOS pseudofs / file layer"] ``` @@ -112,7 +112,7 @@ graph LR ### 主要消费者 - `ax-fs-ng`:最主要的高层消费者。 -- `ax-net-ng`:把 socket 地址空间接到文件系统对象模型里。 +- `ax-net`:把 socket 地址空间接到文件系统对象模型里。 - StarryOS:在 pseudofs、文件描述符层和设备节点模型中大量使用。 ### 3.3 关键边界关系 diff --git a/docs/docs/components/crates/axpoll.md b/docs/docs/components/crates/axpoll.md index d74e25856b..a7a85ea5c0 100644 --- a/docs/docs/components/crates/axpoll.md +++ b/docs/docs/components/crates/axpoll.md @@ -85,7 +85,7 @@ 当前仓库中直接依赖 `axpoll` 的关键路径包括: - `ax-task`:把同步 nonblocking I/O 封装成可等待 future -- `ax-net-ng`:为 TCP、UDP、Unix domain socket、vsock、loopback 设备提供统一 readiness 语义 +- `ax-net`:为 TCP、UDP、Unix domain socket、vsock、loopback 设备提供统一 readiness 语义 - `ax-fs-ng` / `axfs-ng-vfs`:为文件节点暴露可轮询事件 - StarryOS 内核:为 `FileLike`、pipe、TTY、socket、eventfd、epoll 等对象复用同一套等待协议 @@ -122,7 +122,7 @@ | 消费者 | 使用方式 | | --- | --- | | `ax-task` | 通过 `poll_io()`、IRQ waker 等机制消费 `Pollable` 与 `PollSet` | -| `ax-net-ng` | 为不同地址族 socket 与设备统一事件位和 waker 注册 | +| `ax-net` | 为不同地址族 socket 与设备统一事件位和 waker 注册 | | `ax-fs-ng` | 让文件节点支持统一 readiness 协议 | | StarryOS 内核 | 作为 fd 世界底层的 readiness glue 层 | @@ -140,7 +140,7 @@ axpoll = { workspace = true } 1. `poll()` 中只读当前状态,不要在这里阻塞或睡眠。 2. `register()` 中只保存/转发 waker;真正的 `wake()` 必须发生在状态变化点。 3. 如果对象有不同类型的唤醒源,优先按读、写、关闭、异常分开组织 `PollSet`。 -4. 如果对象本身有 IRQ 或设备事件来源,可参考 `ax-task` 与 `ax-net-ng` 的做法,把底层事件桥接到 `PollSet`。 +4. 如果对象本身有 IRQ 或设备事件来源,可参考 `ax-task` 与 `ax-net` 的做法,把底层事件桥接到 `PollSet`。 ### 4.3 修改实现时的风险点 @@ -175,7 +175,7 @@ cargo test -p axpoll ### ArceOS -在 ArceOS 中,`axpoll` 处在同步 nonblocking I/O 与任务等待之间,是 `ax-task`、`ax-net-ng`、`ax-fs-ng` 的公共 readiness glue 层。 +在 ArceOS 中,`axpoll` 处在同步 nonblocking I/O 与任务等待之间,是 `ax-task`、`ax-net`、`ax-fs-ng` 的公共 readiness glue 层。 ### StarryOS diff --git a/docs/docs/components/crates/bwbench-client.md b/docs/docs/components/crates/bwbench-client.md index 70afe36fd6..608eaf9b7c 100644 --- a/docs/docs/components/crates/bwbench-client.md +++ b/docs/docs/components/crates/bwbench-client.md @@ -4,7 +4,7 @@ > 类型:二进制 crate > 分层:ArceOS 层 / 宿主机配套工具 > 版本:`0.1.0` -> 文档依据:`Cargo.toml`、`README.md`、`src/main.rs`、`src/device.rs`、`os/arceos/modules/ax-net/src/smoltcp_impl/bench.rs` +> 文档依据:`Cargo.toml`、`README.md`、`src/main.rs`、`src/device.rs` `bwbench-client` 是一个运行在 Linux 宿主机上的原始以太网带宽对测工具。它通过 `AF_PACKET` raw socket 直接向指定网卡或 tap 设备发送/接收帧,并按秒输出吞吐统计。它不是 ArceOS 镜像里的应用,也不是可复用网络库;它的真实定位是给 ArceOS 网络基准路径提供一个宿主机侧对端。 @@ -76,14 +76,9 @@ ### 2.3 与 ArceOS 侧基准的关系 -`README.md` 明确把它描述成与 ArceOS 带宽基准配对使用的宿主工具,并给出了 tap 设备示例。当前仓库中,能直接对上的客体侧入口是: +`README.md` 明确把它描述成与 ArceOS 带宽基准配对使用的宿主工具,并给出了 tap 设备示例。当前统一网络栈不再把网络设备 benchmark 入口作为 `ax-net` public API 暴露;如果后续仍需要客体侧带宽基准,应放到独立工具或测试套件中,而不是重新放回核心网络栈。 -- `ax-net::bench_transmit()` -- `ax-net::bench_receive()` - -也就是说,这个工具真正的使命是充当这些基准入口的宿主机对端。 - -需要特别说明的是:`README.md` 里提到的 `make A=apps/net/bwbench ...` 来自更早期的应用组织方式;在当前仓库快照里,直接能对应上的仍是 `ax-net` 中的基准函数,而不是独立存在于同目录的 ArceOS 应用源码。 +需要特别说明的是:`README.md` 里提到的 `make A=apps/net/bwbench ...` 来自更早期的应用组织方式;在当前仓库快照里,它只能作为宿主机侧 raw frame 工具保留。 ### 2.4 关键边界 @@ -105,7 +100,7 @@ `bwbench-client` 没有直接依赖仓库内其他 crate。它与仓库的关系主要体现在“测试配对”上: - 宿主机侧:`bwbench-client` -- 客体侧:`ax-net::bench_transmit()` / `bench_receive()` +- 客体侧:独立 benchmark 应用或测试套件,当前不属于 `ax-net` public API ### 3.3 跨层关系 @@ -113,7 +108,7 @@ | --- | --- | | `bwbench-client` | 宿主机 raw socket 基准工具 | | Linux raw socket | 提供二层帧收发能力 | -| ArceOS `ax-net` 基准入口 | 提供客体侧发送/接收对端 | +| ArceOS benchmark 应用或测试套件 | 提供客体侧发送/接收对端 | ## 开发指南 diff --git a/docs/docs/components/crates/smoltcp-fuzz.md b/docs/docs/components/crates/smoltcp-fuzz.md index 523095324f..57dc158cad 100644 --- a/docs/docs/components/crates/smoltcp-fuzz.md +++ b/docs/docs/components/crates/smoltcp-fuzz.md @@ -90,7 +90,7 @@ ### 2.3 关键边界 -- `smoltcp-fuzz` 不验证 `ax-net` / `ax-net-ng` 的系统 socket 语义 +- `smoltcp-fuzz` 不验证 `ax-net` / `ax-net` 的系统 socket 语义 - `smoltcp-fuzz` 不负责系统级连通性回归 - `smoltcp-fuzz` 主要关注解析健壮性、repr/emit 一致性以及部分协议状态机面对畸形输入时的鲁棒性 diff --git a/docs/docs/components/crates/smoltcp.md b/docs/docs/components/crates/smoltcp.md index ec1722d5b2..79df2fa99d 100644 --- a/docs/docs/components/crates/smoltcp.md +++ b/docs/docs/components/crates/smoltcp.md @@ -6,7 +6,7 @@ > 版本:`0.13.0`(crates.io) > 文档依据:`Cargo.toml`、`README.md`、`src/lib.rs`、`tests/netsim.rs`、`examples/*`、`benches/bench.rs`、`fuzz/fuzz_targets/*` -`smoltcp` 是仓库中引入并维护的一份独立 TCP/IP 协议栈源码。它提供的是事件驱动的协议状态机、接口层、设备抽象和报文表示,而不是 ArceOS/StarryOS 直接面向系统调用或应用的网络模块。在本仓库里,真正把它接到驱动、等待模型、地址族抽象和系统接口上的,是 `ax-net` 与 `ax-net-ng`。 +`smoltcp` 是仓库中引入并维护的一份独立 TCP/IP 协议栈源码。它提供的是事件驱动的协议状态机、接口层、设备抽象和报文表示,而不是 ArceOS/StarryOS 直接面向系统调用或应用的网络模块。在本仓库里,真正把它接到驱动、等待模型、地址族抽象和系统接口上的,是 `ax-net` 与 `ax-net`。 最关键的边界是:`smoltcp` 负责协议与报文,不负责操作系统策略。路由装配、阻塞/非阻塞等待、超时、Unix socket、vsock、文件描述符映射与系统调用兼容,都不属于它的职责。 @@ -49,7 +49,7 @@ ### 1.4 在本仓库中的实际启用方式 -`ax-net` 和 `ax-net-ng` 都没有使用 `smoltcp` 的默认 feature,而是显式打开了一组更贴近内核场景的能力: +`ax-net` 和 `ax-net` 都没有使用 `smoltcp` 的默认 feature,而是显式打开了一组更贴近内核场景的能力: - `alloc` - `log` @@ -66,7 +66,7 @@ 这说明在本仓库里,`smoltcp` 的定位不是 host-side 演示库,而是内核内 IP/TCP/UDP 协议引擎。 -### 1.5 与 `ax-net` / `ax-net-ng` 的边界 +### 1.5 与 `ax-net` / `ax-net` 的边界 在 ArceOS / StarryOS 中,`smoltcp` 的职责到以下范围为止: @@ -76,7 +76,7 @@ - 不提供 `bind` / `accept4` / `sendmsg` 一类系统接口语义 - 不理解 `axpoll`、`ax-task`、`ax-fs-ng`、Unix socket、vsock 这些系统层概念 -因此,`ax-net` / `ax-net-ng` 不是“薄薄一层壳”,而是在把协议栈本体接到操作系统语义上。 +因此,`ax-net` / `ax-net` 不是“薄薄一层壳”,而是在把协议栈本体接到操作系统语义上。 ## 核心功能 @@ -93,9 +93,9 @@ 本仓库中的真实调用链可以概括为: 1. `ax-driver` 暴露 NIC 或更高层网络设备 -2. `ax-net` / `ax-net-ng` 将其适配成 `smoltcp::phy::Device` +2. `ax-net` / `ax-net` 将其适配成 `smoltcp::phy::Device` 3. `smoltcp::iface::Interface` 与 `SocketSet` 负责推进协议状态机 -4. `ax-net` / `ax-net-ng` 把 `smoltcp` socket 封装成系统友好的同步 socket 接口 +4. `ax-net` / `ax-net` 把 `smoltcp` socket 封装成系统友好的同步 socket 接口 5. `ax-api`、`ax-posix-api`、StarryOS socket 子系统继续向上暴露用户可见语义 ### 2.3 质量保障资产也是实现的一部分 @@ -135,7 +135,7 @@ | 消费者 | 使用方式 | | --- | --- | | `ax-net` | 第一代 IP socket 封装 | -| `ax-net-ng` | 第二代统一 socket 服务层中的 IP 协议引擎 | +| `ax-net` | 第二代统一 socket 服务层中的 IP 协议引擎 | | `smoltcp-fuzz` | 直接针对本仓库这份协议栈源码做 fuzz 验证 | ### 3.3 与上层模块的职责边界 @@ -144,7 +144,7 @@ | --- | --- | | `smoltcp` | 协议状态机、报文解析/构造、接口轮询模型 | | `ax-net` | 把 `smoltcp` 封装成第一代同步 TCP/UDP/DNS 接口 | -| `ax-net-ng` | 在 `smoltcp` 之上实现统一 socket 语义、路由、Unix/vsock、poll/waker | +| `ax-net` | 在 `smoltcp` 之上实现统一 socket 语义、路由、Unix/vsock、poll/waker | ## 开发指南 @@ -157,7 +157,7 @@ smoltcp = { version = "0.12", default-features = false, features = ["alloc"] } ``` -但在本仓库中,更常见的做法不是让业务代码直接依赖 `smoltcp`,而是通过 `ax-net` / `ax-net-ng` 间接消费。 +但在本仓库中,更常见的做法不是让业务代码直接依赖 `smoltcp`,而是通过 `ax-net` / `ax-net` 间接消费。 ### 4.2 修改前先判断自己在动哪一层 @@ -192,7 +192,7 @@ smoltcp = { version = "0.12", default-features = false, features = ["alloc"] } - 协议或报文层改动优先补单元测试与 fuzz corpus - 接口层改动至少跑一条 netsim 回归 - 修改编译期参数或 feature 时,同时检查默认组合与 ArceOS 实际使用组合 -- 若变更会影响 `ax-net` / `ax-net-ng`,还必须补系统级回归 +- 若变更会影响 `ax-net` / `ax-net`,还必须补系统级回归 ### 5.3 推荐验证命令 @@ -207,11 +207,11 @@ cargo test -p smoltcp --test netsim --features _netsim ### ArceOS -在 ArceOS 中,`smoltcp` 不是用户直接面对的网络 API,而是 `ax-net` / `ax-net-ng` 下方的协议引擎。它决定 TCP/UDP/DNS/IP 行为,但不直接决定系统调用或应用接口语义。 +在 ArceOS 中,`smoltcp` 不是用户直接面对的网络 API,而是 `ax-net` / `ax-net` 下方的协议引擎。它决定 TCP/UDP/DNS/IP 行为,但不直接决定系统调用或应用接口语义。 ### StarryOS -StarryOS 同样不会把 `smoltcp` 直接暴露给上层,而是通过 `ax-net-ng` 间接使用它。对 StarryOS 来说,`smoltcp` 是主 socket 子系统下方的协议核心,而不是 socket 子系统本身。 +StarryOS 同样不会把 `smoltcp` 直接暴露给上层,而是通过 `ax-net` 间接使用它。对 StarryOS 来说,`smoltcp` 是主 socket 子系统下方的协议核心,而不是 socket 子系统本身。 ### Axvisor diff --git a/docs/docs/components/crates/starry-kernel.md b/docs/docs/components/crates/starry-kernel.md index 8e460dc944..3897ba8491 100644 --- a/docs/docs/components/crates/starry-kernel.md +++ b/docs/docs/components/crates/starry-kernel.md @@ -120,7 +120,7 @@ graph LR ax-task["ax-task"] --> starry ax-mm["ax-mm"] --> starry ax-fs["ax-fs-ng / axfs-ng-vfs"] --> starry - ax-net["ax-net-ng"] --> starry + ax-net["ax-net"] --> starry starry_process["starry-process"] --> starry starry_signal["starry-signal"] --> starry starry_vm["starry-vm"] --> starry @@ -130,11 +130,11 @@ graph LR ``` ### 直接依赖 -- `ax-feat`:把 `uspace`、`multitask`、`sched-rr`、`fs-ng-ext4`、`net-ng` 等能力一次性装配到内核。 +- `ax-feat`:把 `uspace`、`multitask`、`sched-rr`、`fs-ng-ext4`、`net` 等能力一次性装配到内核。 - `ax-hal`:用户态上下文、页表、trap、时间与控制台基础能力。 - `ax-task`:底层线程调度、`TaskExt` 和阻塞/唤醒机制。 - `ax-fs-ng`、`axfs-ng-vfs`:文件系统与路径解析。 -- `ax-net-ng`:网络与 socket 路径的底层支撑。 +- `ax-net`:网络与 socket 路径的底层支撑。 - `starry-process`、`starry-signal`、`starry-vm`:分别承接进程模型、信号模型和用户内存安全访问。 ### 主要消费者 diff --git a/docs/docs/components/layers.md b/docs/docs/components/layers.md index 16333ec8a9..7e1aad72af 100644 --- a/docs/docs/components/layers.md +++ b/docs/docs/components/layers.md @@ -27,10 +27,10 @@ flowchart TB L12["层级 12
堆叠层(依赖更底层 crate)
`ax-runtime`"] classDef ls12 fill:#e1bee7,stroke:#6a1b9a,stroke-width:2px,color:#000 class L12 ls12 - L11["层级 11
堆叠层(依赖更底层 crate)
`ax-net-ng`"] + L11["层级 11
堆叠层(依赖更底层 crate)
`ax-net`"] classDef ls11 fill:#ffe0b2,stroke:#ef6c00,stroke-width:2px,color:#000 class L11 ls11 - L10["层级 10
堆叠层(依赖更底层 crate)
`ax-display`、`ax-fs`、`ax-fs-ng`、`ax-input`、`ax-net`"] + L10["层级 10
堆叠层(依赖更底层 crate)
`ax-display`、`ax-fs`、`ax-fs-ng`、`ax-input`"] classDef ls10 fill:#fff9c4,stroke:#f9a825,stroke-width:2px,color:#000 class L10 ls10 L9["层级 9
堆叠层(依赖更底层 crate)
`ax-driver`"] @@ -178,8 +178,7 @@ flowchart TB | 10 | 堆叠层 | ArceOS 层 | `ax-fs` | `0.5.0` | `os/arceos/modules/axfs` | | 10 | 堆叠层 | ArceOS 层 | `ax-fs-ng` | `0.5.0` | `os/arceos/modules/axfs-ng` | | 10 | 堆叠层 | ArceOS 层 | `ax-input` | `0.5.0` | `os/arceos/modules/axinput` | -| 10 | 堆叠层 | ArceOS 层 | `ax-net` | `0.5.0` | `os/arceos/modules/axnet` | -| 11 | 堆叠层 | ArceOS 层 | `ax-net-ng` | `0.5.0` | `os/arceos/modules/axnet-ng` | +| 11 | 堆叠层 | 组件层 | `ax-net` | `0.7.1` | `net/ax-net` | | 12 | 堆叠层 | ArceOS 层 | `ax-runtime` | `0.5.0` | `os/arceos/modules/axruntime` | | 13 | 堆叠层 | ArceOS 层 | `ax-feat` | `0.5.0` | `os/arceos/api/axfeat` | | 14 | 堆叠层 | ArceOS 层 | `ax-api` | `0.5.0` | `os/arceos/api/arceos_api` | @@ -227,7 +226,7 @@ flowchart TB | 8 | 2 | `ax-dma` `ax-sync` | | 9 | 1 | `ax-driver` | | 10 | 5 | `ax-display` `ax-fs` `ax-fs-ng` `ax-input` `ax-net` | -| 11 | 1 | `ax-net-ng` | +| 11 | 1 | `ax-net` | | 12 | 1 | `ax-runtime` | | 13 | 1 | `ax-feat` | | 14 | 3 | `ax-api` `ax-posix-api` `starry-kernel` | @@ -264,7 +263,7 @@ flowchart TB | `ax-allocator` | 1 | Various allocator algorithms in a unified interfa… | `ax-errno` `bitmap-allocator` | `ax-alloc` `ax-dma` | | `ax-api` | 14 | Public APIs and types for ArceOS modules | `ax-alloc` `ax-config` `ax-display` `ax-dma` `ax-driver` `ax-errno` `ax-feat` `ax-fs` `ax-hal` `ax-io` `ax-ipi` `ax-log` `ax-mm` `ax-net` `ax-runtime` `ax-sync` `ax-task` | `ax-std` | | `ax-cap-access` | 0 | Provide basic capability-based access control to … | — | `ax-fs` | -| `ax-config` | 2 | Platform-specific constants and parameters for Ar… | `ax-config-macros` | `ax-api` `ax-dma` `ax-driver` `ax-feat` `ax-hal` `ax-ipi` `ax-net-ng` `ax-posix-api` `ax-runtime` `ax-task` `axvisor` `starry-kernel` | +| `ax-config` | 2 | Platform-specific constants and parameters for Ar… | `ax-config-macros` | `ax-api` `ax-dma` `ax-driver` `ax-feat` `ax-hal` `ax-ipi` `ax-net` `ax-posix-api` `ax-runtime` `ax-task` `axvisor` `starry-kernel` | | `ax-config-gen` | 0 | A TOML-based configuration generation tool for Ar… | — | `ax-config-macros` | | `ax-config-macros` | 1 | Procedural macros for converting TOML format conf… | `ax-config-gen` | `ax-config` `ax-plat-loongarch64-qemu-virt` `axplat-dyn` | | `ax-cpu` | 3 | Privileged instruction and structure abstractions… | `ax-lazyinit` `ax-memory-addr` `ax-page-table-entry` `ax-page-table-multiarch` `ax-percpu` `axbacktrace` | `ax-hal` `ax-plat-loongarch64-qemu-virt` `axplat-dyn` `starry-signal` | @@ -275,15 +274,15 @@ flowchart TB | `ax-ctor-bare-macros` | 0 | Macros for registering constructor functions for … | — | `ax-ctor-bare` | | `ax-display` | 10 | ArceOS graphics module | `ax-driver` `ax-lazyinit` `ax-sync` | `ax-api` `ax-feat` `ax-runtime` `starry-kernel` | | `ax-dma` | 8 | ArceOS global DMA allocator | `ax-alloc` `ax-allocator` `ax-config` `ax-hal` `ax-kspin` `ax-memory-addr` `ax-mm` | `ax-api` `ax-driver` | -| `ax-driver` | 9 | ArceOS device drivers | `anyhow` `ax-alloc` `ax-crate-interface` `ax-dma` `ax-errno` `ax-kernel-guard` `ax-kspin` `axklib` `dma-api` `mmio-api` `rdrive` `rd-net` `rdif-*` `virtio-drivers` | `ax-api` `ax-display` `ax-feat` `ax-fs` `ax-fs-ng` `ax-input` `ax-net` `ax-net-ng` `ax-runtime` `starry-kernel` | -| `ax-errno` | 0 | Generic error code representation. | — | `arm_vcpu` `arm_vgic` `ax-alloc` `ax-allocator` `ax-api` `ax-driver` `ax-fs` `ax-fs-ng` `ax-fs-vfs` `ax-io` `ax-libc` `ax-memory-set` `ax-mm` `ax-net` `ax-net-ng` `ax-page-table-multiarch` `ax-posix-api` `ax-std` `ax-task` `axaddrspace` `axdevice` `axdevice_base` `axfs-ng-vfs` `axhvc` `axklib` `axplat-dyn` `axvcpu` `axvisor` `axvm` `axvmconfig` `riscv_vcpu` `riscv_vplic` `starry-kernel` `starry-vm` `x86_vcpu` `x86_vlapic` | +| `ax-driver` | 9 | ArceOS device drivers | `anyhow` `ax-alloc` `ax-crate-interface` `ax-dma` `ax-errno` `ax-kernel-guard` `ax-kspin` `axklib` `dma-api` `mmio-api` `rdrive` `rd-net` `rdif-*` `virtio-drivers` | `ax-api` `ax-display` `ax-feat` `ax-fs` `ax-fs-ng` `ax-input` `ax-net` `ax-net` `ax-runtime` `starry-kernel` | +| `ax-errno` | 0 | Generic error code representation. | — | `arm_vcpu` `arm_vgic` `ax-alloc` `ax-allocator` `ax-api` `ax-driver` `ax-fs` `ax-fs-ng` `ax-fs-vfs` `ax-io` `ax-libc` `ax-memory-set` `ax-mm` `ax-net` `ax-net` `ax-page-table-multiarch` `ax-posix-api` `ax-std` `ax-task` `axaddrspace` `axdevice` `axdevice_base` `axfs-ng-vfs` `axhvc` `axklib` `axplat-dyn` `axvcpu` `axvisor` `axvm` `axvmconfig` `riscv_vcpu` `riscv_vplic` `starry-kernel` `starry-vm` `x86_vcpu` `x86_vlapic` | | `ax-feat` | 13 | Top-level feature selection for ArceOS | `ax-alloc` `ax-config` `ax-display` `ax-driver` `ax-fs` `ax-fs-ng` `ax-hal` `ax-input` `ax-ipi` `ax-kspin` `ax-log` `ax-net` `ax-runtime` `ax-sync` `ax-task` `axbacktrace` | `ax-api` `ax-libc` `ax-posix-api` `ax-std` `starry-kernel` `starryos` `starryos-test` | | `ax-fs` | 10 | ArceOS filesystem module | `ax-cap-access` `ax-driver` `ax-errno` `ax-fs-devfs` `ax-fs-ramfs` `ax-fs-vfs` `ax-hal` `ax-io` `ax-lazyinit` `rsext4` | `ax-api` `ax-feat` `ax-posix-api` `ax-runtime` | | `ax-fs-devfs` | 2 | Device filesystem used by ArceOS | `ax-fs-vfs` | `ax-fs` | -| `ax-fs-ng` | 10 | ArceOS filesystem module | `ax-alloc` `ax-driver` `ax-errno` `ax-hal` `ax-io` `ax-kspin` `ax-sync` `axfs-ng-vfs` `axpoll` `scope-local` | `ax-feat` `ax-net-ng` `ax-runtime` `starry-kernel` | +| `ax-fs-ng` | 10 | ArceOS filesystem module | `ax-alloc` `ax-driver` `ax-errno` `ax-hal` `ax-io` `ax-kspin` `ax-sync` `axfs-ng-vfs` `axpoll` `scope-local` | `ax-feat` `ax-net` `ax-runtime` `starry-kernel` | | `ax-fs-ramfs` | 2 | RAM filesystem used by ArceOS | `ax-fs-vfs` | `arceos-fs-shell` `ax-fs` | | `ax-fs-vfs` | 1 | Virtual filesystem interfaces used by ArceOS | `ax-errno` | `arceos-fs-shell` `ax-fs` `ax-fs-devfs` `ax-fs-ramfs` | -| `ax-hal` | 6 | ArceOS hardware abstraction layer, provides unifi… | `ax-alloc` `ax-config` `ax-cpu` `ax-kernel-guard` `ax-memory-addr` `ax-page-table-multiarch` `ax-percpu` `ax-plat` `ax-plat-loongarch64-qemu-virt` `axplat-dyn` | `ax-api` `ax-dma` `ax-driver` `ax-feat` `ax-fs` `ax-fs-ng` `ax-ipi` `ax-mm` `ax-net` `ax-net-ng` `ax-posix-api` `ax-runtime` `ax-task` `axvisor` `starry-kernel` | +| `ax-hal` | 6 | ArceOS hardware abstraction layer, provides unifi… | `ax-alloc` `ax-config` `ax-cpu` `ax-kernel-guard` `ax-memory-addr` `ax-page-table-multiarch` `ax-percpu` `ax-plat` `ax-plat-loongarch64-qemu-virt` `axplat-dyn` | `ax-api` `ax-dma` `ax-driver` `ax-feat` `ax-fs` `ax-fs-ng` `ax-ipi` `ax-mm` `ax-net` `ax-net` `ax-posix-api` `ax-runtime` `ax-task` `axvisor` `starry-kernel` | | `ax-handler-table` | 0 | A lock-free table of event handlers | — | `ax-plat` | | `arceos-helloworld` | 16 | ArceOS 示例程序 | `ax-std` | — | | `arceos-helloworld-myplat` | 16 | ArceOS 示例程序 | `ax-plat-loongarch64-qemu-virt` `ax-std` | — | @@ -291,7 +290,7 @@ flowchart TB | `arceos-httpserver` | 16 | Simple HTTP server. Benchmark with Apache HTTP se… | `ax-std` | — | | `ax-input` | 10 | Input device management for ArceOS | `ax-driver` `ax-lazyinit` `ax-sync` | `ax-feat` `ax-runtime` `starry-kernel` | | `ax-int-ratio` | 0 | The type of ratios represented by two integers. | — | — | -| `ax-io` | 1 | `std::io` for `no_std` environment | `ax-errno` | `ax-api` `ax-fs` `ax-fs-ng` `ax-libc` `ax-net` `ax-net-ng` `ax-posix-api` `ax-std` `starry-kernel` | +| `ax-io` | 1 | `std::io` for `no_std` environment | `ax-errno` | `ax-api` `ax-fs` `ax-fs-ng` `ax-libc` `ax-net` `ax-net` `ax-posix-api` `ax-std` `starry-kernel` | | `ax-ipi` | 7 | ArceOS IPI management module | `ax-config` `ax-hal` `ax-kspin` `ax-lazyinit` `ax-percpu` | `ax-api` `ax-feat` `ax-runtime` | | `ax-kernel-guard` | 1 | RAII wrappers to create a critical section with l… | `ax-crate-interface` | `ax-hal` `ax-kspin` `ax-percpu` `ax-task` `axvisor` `starry-kernel` | | `ax-kspin` | 2 | Spinlocks used for kernel space that can disable … | `ax-kernel-guard` | `ax-alloc` `ax-dma` `ax-feat` `ax-fs-ng` `ax-ipi` `ax-log` `ax-mm` `ax-plat` `ax-plat-loongarch64-qemu-virt` `ax-std` `ax-sync` `ax-task` `axvisor` `starry-kernel` `starry-process` `starry-signal` | @@ -302,8 +301,7 @@ flowchart TB | `ax-memory-addr` | 0 | Wrappers and helper functions for physical and vi… | — | `arm_vgic` `ax-alloc` `ax-cpu` `ax-dma` `ax-hal` `ax-memory-set` `ax-mm` `ax-page-table-entry` `ax-page-table-multiarch` `ax-plat` `ax-task` `axaddrspace` `axdevice` `axklib` `axplat-dyn` `axvcpu` `axvisor` `axvisor_api` `axvm` `riscv_vcpu` `starry-kernel` `x86_vcpu` `x86_vlapic` | | `ax-memory-set` | 1 | Data structures and operations for managing memor… | `ax-errno` `ax-memory-addr` | `ax-mm` `axaddrspace` `starry-kernel` | | `ax-mm` | 7 | ArceOS virtual memory management module | `ax-alloc` `ax-errno` `ax-hal` `ax-kspin` `ax-lazyinit` `ax-memory-addr` `ax-memory-set` `ax-page-table-multiarch` | `ax-api` `ax-dma` `ax-runtime` `starry-kernel` | -| `ax-net` | 10 | ArceOS network module | `ax-driver` `ax-errno` `ax-hal` `ax-io` `ax-lazyinit` `ax-sync` `ax-task` `smoltcp` | `ax-api` `ax-feat` `ax-posix-api` `ax-runtime` | -| `ax-net-ng` | 11 | ArceOS network module | `ax-config` `ax-driver` `ax-errno` `ax-fs-ng` `ax-hal` `ax-io` `ax-sync` `ax-task` `axfs-ng-vfs` `axpoll` `smoltcp` | `ax-runtime` `starry-kernel` | +| `ax-net` | 11 | Unified network stack | `ax-config` `ax-errno` `ax-fs-ng` `ax-hal` `ax-io` `ax-sync` `ax-task` `axfs-ng-vfs` `axpoll` `rd-net` `smoltcp` | `ax-api` `ax-feat` `ax-posix-api` `ax-runtime` `starry-kernel` | | `ax-page-table-entry` | 1 | Page table entry definition for various hardware … | `ax-memory-addr` | `ax-cpu` `ax-page-table-multiarch` `ax-plat-loongarch64-qemu-virt` `axaddrspace` `axvisor` `axvm` `riscv_vcpu` `x86_vcpu` | | `ax-page-table-multiarch` | 2 | Generic page table structures for various hardwar… | `ax-errno` `ax-memory-addr` `ax-page-table-entry` | `ax-cpu` `ax-hal` `ax-mm` `axaddrspace` `axvisor` `axvm` `starry-kernel` | | `ax-percpu` | 2 | Define and access per-CPU data structures | `ax-kernel-guard` `ax-percpu-macros` | `arm_vcpu` `ax-alloc` `ax-cpu` `ax-hal` `ax-ipi` `ax-plat` `ax-runtime` `ax-task` `axplat-dyn` `axvcpu` `axvisor` `axvm` `scope-local` `starry-kernel` | @@ -313,23 +311,23 @@ flowchart TB | `ax-plat-macros` | 1 | Procedural macros for the `axplat` crate | `ax-crate-interface` | `ax-plat` | | `ax-posix-api` | 14 | POSIX-compatible APIs for ArceOS modules | `ax-alloc` `ax-config` `ax-errno` `ax-feat` `ax-fs` `ax-hal` `ax-io` `ax-log` `ax-net` `ax-runtime` `ax-sync` `ax-task` `scope-local` | `ax-libc` | | `ax-riscv-plic` | 0 | RISC-V platform-level interrupt controller (PLIC)… | — | — | -| `ax-runtime` | 12 | Runtime library of ArceOS | `ax-alloc` `ax-config` `ax-crate-interface` `ax-ctor-bare` `ax-display` `ax-driver` `ax-fs` `ax-fs-ng` `ax-hal` `ax-input` `ax-ipi` `ax-log` `ax-mm` `ax-net` `ax-net-ng` `ax-percpu` `ax-plat` `ax-task` `axbacktrace` `axklib` | `ax-api` `ax-feat` `ax-posix-api` `starry-kernel` | +| `ax-runtime` | 12 | Runtime library of ArceOS | `ax-alloc` `ax-config` `ax-crate-interface` `ax-ctor-bare` `ax-display` `ax-driver` `ax-fs` `ax-fs-ng` `ax-hal` `ax-input` `ax-ipi` `ax-log` `ax-mm` `ax-net` `ax-net` `ax-percpu` `ax-plat` `ax-task` `axbacktrace` `axklib` | `ax-api` `ax-feat` `ax-posix-api` `starry-kernel` | | `ax-sched` | 1 | Various scheduler algorithms in a unified interfa… | `ax-linked-list-r4l` | `ax-task` | | `arceos-shell` | 16 | ArceOS 示例程序 | `ax-std` | — | | `ax-std` | 15 | ArceOS user library with an interface similar to … | `ax-api` `ax-errno` `ax-feat` `ax-io` `ax-kspin` `ax-lazyinit` | `arceos-affinity` `arceos-display` `arceos-exception` `arceos-fs-shell` `arceos-irq` `arceos-memtest` `arceos-net-echoserver` `arceos-net-httpclient` `arceos-net-httpserver` `arceos-net-udpserver` `arceos-parallel` `arceos-priority` `arceos-sleep` `arceos-tls` `arceos-wait-queue` `arceos-yield` `arceos-helloworld` `arceos-helloworld-myplat` `arceos-httpclient` `arceos-httpserver` `arceos-shell` `axvisor` | -| `ax-sync` | 8 | ArceOS synchronization primitives | `ax-kspin` `ax-task` | `ax-api` `ax-display` `ax-feat` `ax-fs-ng` `ax-input` `ax-net` `ax-net-ng` `ax-posix-api` `starry-kernel` | -| `ax-task` | 7 | ArceOS task management module | `ax-config` `ax-cpumask` `ax-crate-interface` `ax-errno` `ax-hal` `ax-kernel-guard` `ax-kspin` `ax-lazyinit` `ax-memory-addr` `ax-percpu` `ax-sched` `ax-timer-list` `axpoll` | `ax-api` `ax-feat` `ax-net` `ax-net-ng` `ax-posix-api` `ax-runtime` `ax-sync` `starry-kernel` | +| `ax-sync` | 8 | ArceOS synchronization primitives | `ax-kspin` `ax-task` | `ax-api` `ax-display` `ax-feat` `ax-fs-ng` `ax-input` `ax-net` `ax-net` `ax-posix-api` `starry-kernel` | +| `ax-task` | 7 | ArceOS task management module | `ax-config` `ax-cpumask` `ax-crate-interface` `ax-errno` `ax-hal` `ax-kernel-guard` `ax-kspin` `ax-lazyinit` `ax-memory-addr` `ax-percpu` `ax-sched` `ax-timer-list` `axpoll` | `ax-api` `ax-feat` `ax-net` `ax-net` `ax-posix-api` `ax-runtime` `ax-sync` `starry-kernel` | | `ax-timer-list` | 0 | A list of timed events that will be triggered seq… | — | `ax-task` `axvisor` | | `axaddrspace` | 3 | ArceOS-Hypervisor guest address space management … | `ax-errno` `ax-lazyinit` `ax-memory-addr` `ax-memory-set` `ax-page-table-entry` `ax-page-table-multiarch` | `arm_vcpu` `arm_vgic` `axdevice` `axdevice_base` `axvcpu` `axvisor` `axvisor_api` `axvm` `riscv_vcpu` `riscv_vplic` `x86_vcpu` `x86_vlapic` | | `axbacktrace` | 0 | Backtrace for ArceOS | — | `ax-alloc` `ax-cpu` `ax-feat` `ax-runtime` `starry-kernel` | | `axbuild` | 2 | An OS build lib toolkit used by arceos | `axvmconfig` | `axvisor` `starryos` `tg-xtask` | | `axdevice` | 6 | A reusable, OS-agnostic device abstraction layer … | `arm_vgic` `ax-errno` `ax-memory-addr` `axaddrspace` `axdevice_base` `axvmconfig` `riscv_vplic` | `axvisor` `axvm` | | `axdevice_base` | 4 | Basic traits and structures for emulated devices … | `ax-errno` `axaddrspace` `axvmconfig` | `arm_vcpu` `arm_vgic` `axdevice` `axvisor` `axvm` `riscv_vplic` `x86_vcpu` `x86_vlapic` | -| `axfs-ng-vfs` | 1 | Virtual filesystem layer for ArceOS | `ax-errno` `axpoll` | `ax-fs-ng` `ax-net-ng` `starry-kernel` | +| `axfs-ng-vfs` | 1 | Virtual filesystem layer for ArceOS | `ax-errno` `axpoll` | `ax-fs-ng` `ax-net` `starry-kernel` | | `axhvc` | 1 | AxVisor HyperCall definitions for guest-hyperviso… | `ax-errno` | `axvisor` | | `axklib` | 1 | Small kernel-helper abstractions used across the … | `ax-errno` `ax-memory-addr` | `ax-runtime` `axplat-dyn` `axvisor` | | `axplat-dyn` | 4 | A dynamic platform module for ArceOS, providing r… | `ax-cpu` `ax-driver` `ax-errno` `ax-memory-addr` `ax-percpu` `ax-plat` `axklib` `rdrive` `somehal` | `ax-driver` `ax-hal` | -| `axpoll` | 0 | A library for polling I/O events and waking up ta… | — | `ax-fs-ng` `ax-net-ng` `ax-task` `axfs-ng-vfs` `starry-kernel` | +| `axpoll` | 0 | A library for polling I/O events and waking up ta… | — | `ax-fs-ng` `ax-net` `ax-task` `axfs-ng-vfs` `starry-kernel` | | `axvcpu` | 5 | Virtual CPU abstraction for ArceOS hypervisor | `ax-errno` `ax-memory-addr` `ax-percpu` `axaddrspace` `axvisor_api` | `arm_vcpu` `axvisor` `axvm` `riscv_vcpu` `x86_vcpu` | | `axvisor` | 16 | A lightweight type-1 hypervisor based on ArceOS | `ax-config` `ax-cpumask` `ax-crate-interface` `ax-errno` `ax-hal` `ax-kernel-guard` `ax-kspin` `ax-lazyinit` `ax-memory-addr` `ax-page-table-entry` `ax-page-table-multiarch` `ax-percpu` `ax-std` `ax-timer-list` `axaddrspace` `axbuild` `axdevice` `axdevice_base` `axhvc` `axklib` `axvcpu` `axvisor_api` `axvm` `riscv_vcpu` `riscv_vplic` | — | | `axvisor_api` | 4 | Basic API for components of the Hypervisor on Arc… | `ax-cpumask` `ax-crate-interface` `ax-memory-addr` `axaddrspace` `axvisor_api_proc` | `arm_vcpu` `arm_vgic` `axvcpu` `axvisor` `axvm` `riscv_vcpu` `riscv_vplic` `x86_vcpu` `x86_vlapic` | @@ -351,9 +349,9 @@ flowchart TB | `riscv_vplic` | 5 | RISCV Virtual PLIC implementation. | `ax-errno` `axaddrspace` `axdevice_base` `axvisor_api` `riscv-h` | `axdevice` `axvisor` | | `rsext4` | 0 | A lightweight ext4 file system. | — | `ax-fs` | | `scope-local` | 3 | Scope local storage | `ax-percpu` | `ax-fs-ng` `ax-posix-api` `starry-kernel` | -| `smoltcp` | 0 | A TCP/IP stack designed for bare-metal, real-time… | — | `ax-net` `ax-net-ng` `smoltcp-fuzz` | +| `smoltcp` | 0 | A TCP/IP stack designed for bare-metal, real-time… | — | `ax-net` `ax-net` `smoltcp-fuzz` | | `smoltcp-fuzz` | 1 | 可复用基础组件 | `smoltcp` | — | -| `starry-kernel` | 14 | A Linux-compatible OS kernel built on ArceOS unik… | `ax-alloc` `ax-config` `ax-display` `ax-driver` `ax-errno` `ax-feat` `ax-fs-ng` `ax-hal` `ax-input` `ax-io` `ax-kernel-guard` `ax-kspin` `ax-log` `ax-memory-addr` `ax-memory-set` `ax-mm` `ax-net-ng` `ax-page-table-multiarch` `ax-percpu` `ax-runtime` `ax-sync` `ax-task` `axbacktrace` `axfs-ng-vfs` `axpoll` `scope-local` `starry-process` `starry-signal` `starry-vm` | `starryos` `starryos-test` | +| `starry-kernel` | 14 | A Linux-compatible OS kernel built on ArceOS unik… | `ax-alloc` `ax-config` `ax-display` `ax-driver` `ax-errno` `ax-feat` `ax-fs-ng` `ax-hal` `ax-input` `ax-io` `ax-kernel-guard` `ax-kspin` `ax-log` `ax-memory-addr` `ax-memory-set` `ax-mm` `ax-net` `ax-page-table-multiarch` `ax-percpu` `ax-runtime` `ax-sync` `ax-task` `axbacktrace` `axfs-ng-vfs` `axpoll` `scope-local` `starry-process` `starry-signal` `starry-vm` | `starryos` `starryos-test` | | `starry-process` | 3 | Process management for Starry OS | `ax-kspin` `ax-lazyinit` | `starry-kernel` | | `starry-signal` | 4 | Signal management library for Starry OS | `ax-cpu` `ax-kspin` `starry-vm` | `starry-kernel` | | `starry-vm` | 1 | Virtual memory management library for Starry OS | `ax-errno` | `starry-kernel` `starry-signal` | diff --git a/docs/docs/components/overview.md b/docs/docs/components/overview.md index 077f0b8e9b..4ecfb76710 100644 --- a/docs/docs/components/overview.md +++ b/docs/docs/components/overview.md @@ -150,8 +150,7 @@ flowchart TB | `ax-memory-addr` | 组件层 | `memory/memory_addr` | 0 | 24 | [查看](crates/ax-memory-addr) | | `ax-memory-set` | 组件层 | `memory/memory_set` | 2 | 3 | [查看](crates/ax-memory-set) | | `ax-mm` | ArceOS 层 | `os/arceos/modules/axmm` | 8 | 4 | [查看](crates/ax-mm) | -| `ax-net` | ArceOS 层 | `os/arceos/modules/axnet` | 8 | 4 | [查看](crates/ax-net) | -| `ax-net-ng` | ArceOS 层 | `os/arceos/modules/axnet-ng` | 11 | 2 | [查看](crates/ax-net-ng) | +| `ax-net` | 组件层 | `net/ax-net` | 11 | 6 | [查看](crates/ax-net) | | `ax-page-table-entry` | 组件层 | `memory/page_table_entry` | 1 | 12 | [查看](crates/ax-page-table-entry) | | `ax-page-table-multiarch` | 组件层 | `memory/page_table_multiarch` | 3 | 7 | [查看](crates/ax-page-table-multiarch) | | `ax-percpu` | 组件层 | `components/percpu/percpu` | 2 | 17 | [查看](crates/ax-percpu) | diff --git a/docs/docs/debug/lock-usage-followups.md b/docs/docs/debug/lock-usage-followups.md index 0a49079a67..ce2140c410 100644 --- a/docs/docs/debug/lock-usage-followups.md +++ b/docs/docs/debug/lock-usage-followups.md @@ -53,7 +53,7 @@ sidebar_label: "锁使用问题跟踪" | `os/StarryOS/kernel/src/pseudofs/dev/loop_block.rs` | loop block cache blocks 使用 `SpinNoIrq`。 | 当前临界区主要是 bounded memory copy,风险可控;但它处在 ext4 block-device 回调路径上,不能在锁内做 VFS writeback 或分配。 | 继续保持锁内只做内存拷贝。若以后增加 writeback、动态扩容或 VFS 调用,必须重新设计。 | | `os/StarryOS/kernel/src/pseudofs/dev/tty/terminal/mod.rs` | `window_size`、`termios` 使用 `SpinNoIrq`;job-control `session` / `foreground` 已合并为一个短状态锁。 | ioctl 路径先完成用户内存访问,再短暂持锁更新值;job-control 不再存在 `foreground -> session` 和 `session -> foreground` 的相反加锁顺序。 | 保持“copy user 在锁外,锁内只拷贝小对象”的规则。job-control 复合状态继续用单锁保护,`PollSet::wake()` 放在锁外执行。 | | `os/StarryOS/kernel/src/pseudofs/dev/tty/pty.rs` | PTY producer 使用 `SpinNoIrq`。 | 当前只在锁内 `push_slice` 到 4 KiB ring buffer,wake 在锁外。风险较低。 | 保持短临界区。若未来 writer 可从 IRQ 直接进入或 buffer 需要扩容,应重新评估。 | -| `os/arceos/modules/axnet-ng/src/unix/mod.rs` | 已调整为从 VFS `user_data` 中 clone `Arc` 后释放 guard,再调用 transport。 | 旧问题是持 VFS `SpinNoIrq` guard 调用 socket transport,内部再拿 sleepable socket mutex。 | 保持现有边界。新增 path socket 操作时禁止把 transport callback 放在 VFS user_data guard 内执行。 | +| `net/ax-net/src/unix/mod.rs` | 已调整为从 VFS `user_data` 中 clone `Arc` 后释放 guard,再调用 transport。 | 旧问题是持 VFS `SpinNoIrq` guard 调用 socket transport,内部再拿 sleepable socket mutex。 | 保持现有边界。新增 path socket 操作时禁止把 transport callback 放在 VFS user_data guard 内执行。 | | `os/StarryOS/kernel/src/file/netlink.rs` 和 `os/StarryOS/kernel/src/file/packet.rs` | 已调整为锁内取出消息或包,锁外 copy 到用户缓冲区。 | 旧问题是持 `SpinNoIrq` 时写用户内存,page fault 路径要求 IRQ enabled。 | 保持“队列状态锁内移动数据,用户内存访问锁外执行”的规则。 | | `os/arceos/modules/axfs-ng/src/highlevel/file.rs` | 仍有 `spin::RwLock`,包括 `GLOBAL_CACHED_FILES` 和 `append_lock`。 | `spin::RwLock` 仍不属于 lockdep-aware `ax-kspin` / `ax-sync` 路径。`append_lock` 是历史记录中明确延期的 RwLock 设计问题。 | 近期不引入新 RwLock。先确认是否必须读写分离;不必须的点评估 mutex 化,必须的点保留并记录风险。 | | `os/StarryOS/kernel/src/file/mod.rs`、`task/mod.rs`、`task/ops.rs` 等 | 仍有若干 `spin::RwLock`;`file/signalfd.rs` 的 signal mask 已改成 `SpinNoIrq`。 | 剩余 RwLock 还不在 lockdep 统一可见范围内,且可能参与 FD table、task 状态等运行时路径。signalfd mask 只是单个可拷贝 bitset,当前不需要外部 `spin::RwLock`。 | 按运行时重要性分批审计:能 mutex 化的先 mutex 化;不能 mutex 化的先冻结新增使用,不把 RwLock 作为近期替换目标。后续若实现项目自有、lockdep-aware 的 RwLock,再评估 signalfd mask 是否值得恢复读写分离。 | diff --git a/docs/docs/development/arceos.md b/docs/docs/development/arceos.md index b0a38af732..7ce855d7c4 100644 --- a/docs/docs/development/arceos.md +++ b/docs/docs/development/arceos.md @@ -50,13 +50,11 @@ sudo apt install qemu-system-arm qemu-system-riscv64 qemu-system-x86 ``` os/arceos/ -├── modules/ # 内核模块(17 个) +├── modules/ # 内核模块 │ ├── axhal/ # 硬件抽象层 │ ├── axtask/ # 任务/线程管理 + 调度器 │ ├── axalloc/ # 内存分配器 │ ├── axdriver/ # 统一设备驱动框架 -│ ├── axnet/ # 网络(legacy, smoltcp) -│ ├── axnet-ng/ # 网络(next-gen) │ ├── axfs/ # 文件系统(legacy) │ ├── axfs-ng/ # 文件系统(next-gen, ext4/fat) │ ├── axlog/ # 多级日志 @@ -76,6 +74,9 @@ os/arceos/ │ ├── axstd/ # Rust std 风格接口 │ └── axlibc/ # C libc 接口 +net/ +└── ax-net/ # 统一网络栈(TCP/UDP/raw/Unix/vsock/DNS/DHCP) + apps/arceos/ ├── helloworld/ ├── httpserver/ @@ -127,8 +128,8 @@ pub unsafe fn rust_main() { ax_task::init_scheduler(); #[cfg(feature = "fs-ng")] ax_fs_ng::init_filesystems(/* ... */); - #[cfg(feature = "net-ng")] - ax_net_ng::init_network(/* ... */); + #[cfg(feature = "net")] + ax_net::init_network(/* ... */); // ... main(); } @@ -260,7 +261,7 @@ net = ["alloc", "paging", "ax-driver/virtio-net", "dep:ax-net", "ax-runtime/net" | 基础 crate(`axerrno`, `kspin`, `page_table_multiarch`) | `cargo test -p ` | `cargo xtask arceos qemu --package arceos-helloworld --arch riscv64` | | HAL(`axhal`) | `cargo xtask arceos qemu --package arceos-helloworld --arch aarch64` | 多架构验证 | | 调度器(`axtask`) | `cargo xtask arceos qemu --package arceos-helloworld --arch riscv64` | `cargo xtask arceos test qemu --target riscv64gc-unknown-none-elf` | -| 网络(`axnet` / `axnet-ng`) | `cargo xtask arceos qemu --package arceos-httpserver --arch aarch64 --net` | 检查 TCP 连接和吞吐 | +| 网络(`axnet` / `axnet`) | `cargo xtask arceos qemu --package arceos-httpserver --arch aarch64 --net` | 检查 TCP 连接和吞吐 | | 文件系统(`axfs` / `axfs-ng`) | `cargo xtask arceos qemu --package arceos-shell --arch aarch64 --blk` | 检查文件读写 | | 驱动(`axdriver`) | `cargo xtask arceos qemu --package arceos-helloworld --arch aarch64` | 启用对应设备 `--blk` / `--net` | @@ -357,7 +358,7 @@ C 应用覆盖由 `test-suit/arceos/c` 维护;`apps/arceos` 只保留 Rust std |----------|-------------------|---------| | 最小运行 | `ax-std` | `--package arceos-helloworld` | | 多任务 | `multitask` | 在应用 Cargo.toml 中启用 | -| 网络 | `net` 或 `net-ng` | `--package arceos-httpserver` | +| 网络 | `net` | `--package arceos-httpserver` | | 文件系统 | `fs` 或 `fs-ng` | `--package arceos-shell` | | 多核 | `smp` | `--arch aarch64` + `SMP=4` | | PCI 设备 | `bus-pci` | 默认 | diff --git a/docs/docs/development/starryos.md b/docs/docs/development/starryos.md index 26211268ed..1973890311 100644 --- a/docs/docs/development/starryos.md +++ b/docs/docs/development/starryos.md @@ -117,7 +117,7 @@ StarryOS 专用组件(位于 `components/`): | `rknpu` | Rockchip NPU 驱动 | | `vsock` | VSOCK 支持 | -内核默认启用:`fp-simd`, `irq`, `uspace`, `page-alloc-4g`, `alloc-slab`, `multitask`, `task-ext`, `sched-rr`, `rtc`, `fs-ng-ext4`, `net-ng`。 +内核默认启用:`fp-simd`, `irq`, `uspace`, `page-alloc-4g`, `alloc-slab`, `multitask`, `task-ext`, `sched-rr`, `rtc`, `fs-ng-ext4`, `net`。 ### 3.3 KCOV 暂不引入 diff --git a/docs/qperf-virtio-optimization-report.md b/docs/qperf-virtio-optimization-report.md index 09fb7fd267..af9d124bbb 100644 --- a/docs/qperf-virtio-optimization-report.md +++ b/docs/qperf-virtio-optimization-report.md @@ -76,7 +76,7 @@ VSOCK 路径有三层锁嵌套,是所有 VirtIO 设备中锁竞争最严重的 #### 3.1.1 全局设备锁 ```rust -// os/arceos/modules/axnet-ng/src/device/vsock.rs:15 +// net/ax-net/src/device/vsock.rs:15 static VSOCK_DEVICE: Mutex> = Mutex::new(None); static PENDING_EVENTS: Mutex> = Mutex::new(VecDeque::new()); ``` @@ -86,7 +86,7 @@ static PENDING_EVENTS: Mutex> = Mutex::new(VecDeque:: #### 3.1.2 全局连接管理器锁 ```rust -// os/arceos/modules/axnet-ng/src/vsock/connection_manager.rs:536 +// net/ax-net/src/vsock/connection_manager.rs:536 pub static VSOCK_CONN_MANAGER: Mutex = ...; ``` diff --git a/os/arceos/modules/axnet-ng/CHANGELOG.md b/net/ax-net/CHANGELOG.md similarity index 75% rename from os/arceos/modules/axnet-ng/CHANGELOG.md rename to net/ax-net/CHANGELOG.md index ef7e758938..9d77cc2295 100644 --- a/os/arceos/modules/axnet-ng/CHANGELOG.md +++ b/net/ax-net/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [0.7.1](https://github.com/rcore-os/tgoskits/compare/ax-net-ng-v0.7.0...ax-net-ng-v0.7.1) - 2026-06-09 +## [0.7.1](https://github.com/rcore-os/tgoskits/compare/ax-net-v0.7.0...ax-net-v0.7.1) - 2026-06-09 ### Added @@ -15,16 +15,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - *(starry-kernel)* implement TCP_INFO sockopt ([#1044](https://github.com/rcore-os/tgoskits/pull/1044)) - *(vfs)* pass uid/gid through creation path to filesystem nodes ([#1097](https://github.com/rcore-os/tgoskits/pull/1097)) -## [0.7.0](https://github.com/rcore-os/tgoskits/compare/ax-net-ng-v0.6.1...ax-net-ng-v0.7.0) - 2026-06-03 +## [0.7.0](https://github.com/rcore-os/tgoskits/compare/ax-net-v0.6.1...ax-net-v0.7.0) - 2026-06-03 ### Added - *(irq)* introduce shared IRQ framework ([#1065](https://github.com/rcore-os/tgoskits/pull/1065)) -- *(axnet-ng)* implement SO_TYPE, SO_PROTOCOL, SO_DOMAIN socket options ([#884](https://github.com/rcore-os/tgoskits/pull/884)) +- *(axnet)* implement SO_TYPE, SO_PROTOCOL, SO_DOMAIN socket options ([#884](https://github.com/rcore-os/tgoskits/pull/884)) ### Fixed -- *(ax-net-ng)* drain entire ARP-pending queue, lift cache TTL and capacity ([#911](https://github.com/rcore-os/tgoskits/pull/911)) +- *(ax-net)* drain entire ARP-pending queue, lift cache TTL and capacity ([#911](https://github.com/rcore-os/tgoskits/pull/911)) - *(starry-kernel)* support TCP socket FIONREAD ([#869](https://github.com/rcore-os/tgoskits/pull/869)) - *(repo)* migrate spin usage to ax-kspin ([#861](https://github.com/rcore-os/tgoskits/pull/861)) @@ -33,13 +33,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - *(deps)* update spin 0.10→0.12, ostool 0.19→0.21 ([#978](https://github.com/rcore-os/tgoskits/pull/978)) - *(drivers)* split shared driver stack from ArceOS ([#831](https://github.com/rcore-os/tgoskits/pull/831)) -## [0.6.1](https://github.com/rcore-os/tgoskits/compare/ax-net-ng-v0.6.0...ax-net-ng-v0.6.1) - 2026-05-22 +## [0.6.1](https://github.com/rcore-os/tgoskits/compare/ax-net-v0.6.0...ax-net-v0.6.1) - 2026-05-22 ### Other - updated the following local packages: ax-errno, axfs-ng-vfs, ax-hal, ax-task, ax-fs-ng, ax-io, ax-driver, ax-sync -## [0.6.0](https://github.com/rcore-os/tgoskits/compare/ax-net-ng-v0.5.13...ax-net-ng-v0.6.0) - 2026-05-19 +## [0.6.0](https://github.com/rcore-os/tgoskits/compare/ax-net-v0.5.13...ax-net-v0.6.0) - 2026-05-19 ### Fixed @@ -47,22 +47,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - *(starry)* weston bringup fixes + IRQ wakers + AF_UNIX cmsg byte marks ([#509](https://github.com/rcore-os/tgoskits/pull/509)) - *(unix-stream,poll_io)* non-blocking accept, peer EOF, waker registration ([#697](https://github.com/rcore-os/tgoskits/pull/697)) -## [0.5.13](https://github.com/rcore-os/tgoskits/compare/ax-net-ng-v0.5.12...ax-net-ng-v0.5.13) - 2026-05-15 +## [0.5.13](https://github.com/rcore-os/tgoskits/compare/ax-net-v0.5.12...ax-net-v0.5.13) - 2026-05-15 ### Added - *(realtek-rtl8125)* complete OrangePi board bringup ([#404](https://github.com/rcore-os/tgoskits/pull/404)) -- *(ax-net-ng)* add ICMP raw socket support ([#368](https://github.com/rcore-os/tgoskits/pull/368)) +- *(ax-net)* add ICMP raw socket support ([#368](https://github.com/rcore-os/tgoskits/pull/368)) - *(net)* migrate ax-net to crates.io smoltcp ([#410](https://github.com/rcore-os/tgoskits/pull/410)) - *(runtime)* extend IRQ, RTC, and tty event support ([#287](https://github.com/rcore-os/tgoskits/pull/287)) ### Fixed -- *(ax-net-ng)* route connected socket wakeups by peer ([#583](https://github.com/rcore-os/tgoskits/pull/583)) +- *(ax-net)* route connected socket wakeups by peer ([#583](https://github.com/rcore-os/tgoskits/pull/583)) - *(starry-kernel)* close CLI compatibility gaps ([#524](https://github.com/rcore-os/tgoskits/pull/524)) - UDP recv returns EAGAIN on unconnected socket, sendto dispatches loopback ([#529](https://github.com/rcore-os/tgoskits/pull/529)) - *(proc)* expose arp table for busybox arp ([#480](https://github.com/rcore-os/tgoskits/pull/480)) -- *(axnet-ng)* call poll_interfaces() after TCP send to wake epoll waiters ([#485](https://github.com/rcore-os/tgoskits/pull/485)) +- *(axnet)* call poll_interfaces() after TCP send to wake epoll waiters ([#485](https://github.com/rcore-os/tgoskits/pull/485)) - *(arceos)* adjust dynamic platform and network integration - implement close_all_fds function and enhance pipe and syscall handling ([#305](https://github.com/rcore-os/tgoskits/pull/305)) @@ -74,7 +74,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - *(kernel)* remove unused user interpreter base constants and clean up socket handling ([#421](https://github.com/rcore-os/tgoskits/pull/421)) - *(starry)* drop outdated and unmaintained stuffs ([#353](https://github.com/rcore-os/tgoskits/pull/353)) -## [0.5.12](https://github.com/rcore-os/tgoskits/compare/ax-net-ng-v0.5.11...ax-net-ng-v0.5.12) - 2026-04-27 +## [0.5.12](https://github.com/rcore-os/tgoskits/compare/ax-net-v0.5.11...ax-net-v0.5.12) - 2026-04-27 ### Fixed diff --git a/os/arceos/modules/axnet-ng/Cargo.toml b/net/ax-net/Cargo.toml similarity index 98% rename from os/arceos/modules/axnet-ng/Cargo.toml rename to net/ax-net/Cargo.toml index 5ce4c66750..7957ee20ce 100644 --- a/os/arceos/modules/axnet-ng/Cargo.toml +++ b/net/ax-net/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "ax-net-ng" +name = "ax-net" version = "0.7.1" repository = "https://github.com/rcore-os/tgoskits" edition.workspace = true diff --git a/os/arceos/modules/axnet-ng/src/consts.rs b/net/ax-net/src/consts.rs similarity index 96% rename from os/arceos/modules/axnet-ng/src/consts.rs rename to net/ax-net/src/consts.rs index ae4fcc40a9..e2d77d0042 100644 --- a/os/arceos/modules/axnet-ng/src/consts.rs +++ b/net/ax-net/src/consts.rs @@ -9,6 +9,7 @@ macro_rules! env_or_default { pub const IP: &str = env_or_default!("AX_IP"); pub const GATEWAY: &str = env_or_default!("AX_GW"); +pub const DNS: &str = env_or_default!("AX_DNS"); pub const IP_PREFIX: u8 = 24; pub const STANDARD_MTU: usize = 1500; diff --git a/os/arceos/modules/axnet-ng/src/device/driver.rs b/net/ax-net/src/device/driver.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/device/driver.rs rename to net/ax-net/src/device/driver.rs diff --git a/os/arceos/modules/axnet-ng/src/device/ethernet.rs b/net/ax-net/src/device/ethernet.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/device/ethernet.rs rename to net/ax-net/src/device/ethernet.rs diff --git a/os/arceos/modules/axnet-ng/src/device/loopback.rs b/net/ax-net/src/device/loopback.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/device/loopback.rs rename to net/ax-net/src/device/loopback.rs diff --git a/os/arceos/modules/axnet-ng/src/device/mod.rs b/net/ax-net/src/device/mod.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/device/mod.rs rename to net/ax-net/src/device/mod.rs diff --git a/os/arceos/modules/axnet-ng/src/device/vsock.rs b/net/ax-net/src/device/vsock.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/device/vsock.rs rename to net/ax-net/src/device/vsock.rs diff --git a/os/arceos/modules/axnet-ng/src/general.rs b/net/ax-net/src/general.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/general.rs rename to net/ax-net/src/general.rs diff --git a/os/arceos/modules/axnet-ng/src/lib.rs b/net/ax-net/src/lib.rs similarity index 68% rename from os/arceos/modules/axnet-ng/src/lib.rs rename to net/ax-net/src/lib.rs index 2bac0b558e..b176203c38 100644 --- a/os/arceos/modules/axnet-ng/src/lib.rs +++ b/net/ax-net/src/lib.rs @@ -1,13 +1,15 @@ -//! [ArceOS](https://github.com/rcore-os/arceos) network module. +//! Unified network stack for TGOSKits systems. //! -//! It provides unified networking primitives for TCP/UDP communication -//! using various underlying network stacks. Currently, only [smoltcp] is -//! supported. +//! It provides TCP, UDP, raw IPv4/ICMP, Unix domain socket, optional vsock, +//! DNS, DHCP, and readiness primitives on top of [smoltcp] and shared device +//! interfaces. //! //! # Organization //! -//! - [`tcp::TcpSocket`]: A TCP socket that provides POSIX-like APIs. -//! - [`udp::UdpSocket`]: A UDP socket that provides POSIX-like APIs. +//! - [`tcp::TcpSocket`]: TCP socket implementation. +//! - [`udp::UdpSocket`]: UDP socket implementation. +//! - [`raw`]: raw socket support. +//! - [`unix`]: Unix domain socket support. //! //! [smoltcp]: https://github.com/smoltcp-rs/smoltcp @@ -42,20 +44,25 @@ pub mod unix; pub mod vsock; mod wrapper; -use alloc::{borrow::ToOwned, boxed::Box, vec::Vec}; +use alloc::{borrow::ToOwned, boxed::Box, vec, vec::Vec}; use core::{ + net::IpAddr, sync::atomic::{AtomicBool, Ordering}, time::Duration, }; +use ax_errno::{AxError, AxResult, ax_err_type}; use ax_sync::Mutex; -use smoltcp::wire::{EthernetAddress, Ipv4Address, Ipv4Cidr}; +use smoltcp::{ + socket::dns::{self, GetQueryResultError, StartQueryError}, + wire::{DnsQueryType, EthernetAddress, IpAddress, Ipv4Address, Ipv4Cidr}, +}; use spin::{LazyLock, Once}; #[cfg(feature = "vsock")] pub use self::device::{VsockDevice, VsockDeviceList}; use self::{ - consts::{GATEWAY, IP, IP_PREFIX}, + consts::{DNS, GATEWAY, IP, IP_PREFIX}, device::{EthernetDevice, LoopbackDevice}, listen_table::ListenTable, router::{Router, Rule}, @@ -206,6 +213,92 @@ pub fn arp_entries() -> Vec { get_service().arp_entries() } +pub fn dns_servers() -> Vec { + let servers = get_service().dns_servers(); + if servers.is_empty() { + static_dns_servers() + } else { + servers + } +} + +pub fn dns_query(name: &str) -> AxResult> { + let servers = dns_servers(); + if servers.is_empty() { + return Err(ax_err_type!(NotFound, "no DNS server configured")); + } + + let servers = servers.into_iter().map(IpAddress::Ipv4).collect::>(); + let handle = SOCKET_SET.add(dns::Socket::new(&servers, vec![])); + DnsSocketGuard(handle).query(name, DnsQueryType::A) +} + +struct DnsSocketGuard(smoltcp::iface::SocketHandle); + +impl DnsSocketGuard { + fn query(&self, name: &str, query_type: DnsQueryType) -> AxResult> { + let query_handle = { + let mut service = get_service(); + let mut sockets = SOCKET_SET.inner.lock(); + sockets.get_mut::(self.0).start_query( + service.iface.context(), + name, + query_type, + ) + } + .map_err(|err| match err { + StartQueryError::NoFreeSlot => { + ax_err_type!(ResourceBusy, "DNS query failed: no free slot") + } + StartQueryError::InvalidName => { + ax_err_type!(InvalidInput, "DNS query failed: invalid name") + } + StartQueryError::NameTooLong => { + ax_err_type!(InvalidInput, "DNS query failed: name too long") + } + })?; + + loop { + poll_interfaces(); + match SOCKET_SET.with_socket_mut::(self.0, |socket| { + socket + .get_query_result(query_handle) + .map_err(|err| match err { + GetQueryResultError::Pending => AxError::WouldBlock, + GetQueryResultError::Failed => { + ax_err_type!(ConnectionRefused, "DNS query failed") + } + }) + }) { + Ok(addrs) => { + return Ok(addrs.into_iter().map(IpAddr::from).collect()); + } + Err(AxError::WouldBlock) => ax_task::yield_now(), + Err(err) => return Err(err), + } + } + } +} + +impl Drop for DnsSocketGuard { + fn drop(&mut self) { + SOCKET_SET.remove(self.0); + } +} + +fn static_dns_servers() -> Vec { + DNS.split(',') + .filter_map(|server| { + let server = server.trim(); + (!server.is_empty()).then(|| { + server + .parse() + .unwrap_or_else(|_| panic!("Invalid DNS server address: {server}")) + }) + }) + .collect() +} + fn dhcp_bootstrap() { for _ in 0..DHCP_BOOTSTRAP_ATTEMPTS { poll_interfaces(); diff --git a/os/arceos/modules/axnet-ng/src/listen_table.rs b/net/ax-net/src/listen_table.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/listen_table.rs rename to net/ax-net/src/listen_table.rs diff --git a/os/arceos/modules/axnet-ng/src/options.rs b/net/ax-net/src/options.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/options.rs rename to net/ax-net/src/options.rs diff --git a/os/arceos/modules/axnet-ng/src/raw.rs b/net/ax-net/src/raw.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/raw.rs rename to net/ax-net/src/raw.rs diff --git a/os/arceos/modules/axnet-ng/src/router.rs b/net/ax-net/src/router.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/router.rs rename to net/ax-net/src/router.rs diff --git a/os/arceos/modules/axnet-ng/src/service.rs b/net/ax-net/src/service.rs similarity index 98% rename from os/arceos/modules/axnet-ng/src/service.rs rename to net/ax-net/src/service.rs index 79d89a4d7a..e5636c90b7 100644 --- a/os/arceos/modules/axnet-ng/src/service.rs +++ b/net/ax-net/src/service.rs @@ -222,6 +222,13 @@ impl Service { .is_some_and(|state| state.address.is_some()) } + pub fn dns_servers(&self) -> Vec { + self.dhcp + .as_ref() + .map(|state| state.dns_servers.clone()) + .unwrap_or_default() + } + pub fn poll(&mut self, sockets: &mut SocketSet) -> bool { let timestamp = now(); let mut dhcp_events = Vec::new(); diff --git a/os/arceos/modules/axnet-ng/src/socket.rs b/net/ax-net/src/socket.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/socket.rs rename to net/ax-net/src/socket.rs diff --git a/os/arceos/modules/axnet-ng/src/state.rs b/net/ax-net/src/state.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/state.rs rename to net/ax-net/src/state.rs diff --git a/os/arceos/modules/axnet-ng/src/tcp.rs b/net/ax-net/src/tcp.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/tcp.rs rename to net/ax-net/src/tcp.rs diff --git a/os/arceos/modules/axnet-ng/src/udp.rs b/net/ax-net/src/udp.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/udp.rs rename to net/ax-net/src/udp.rs diff --git a/os/arceos/modules/axnet-ng/src/unix/dgram.rs b/net/ax-net/src/unix/dgram.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/unix/dgram.rs rename to net/ax-net/src/unix/dgram.rs diff --git a/os/arceos/modules/axnet-ng/src/unix/mod.rs b/net/ax-net/src/unix/mod.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/unix/mod.rs rename to net/ax-net/src/unix/mod.rs diff --git a/os/arceos/modules/axnet-ng/src/unix/stream.rs b/net/ax-net/src/unix/stream.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/unix/stream.rs rename to net/ax-net/src/unix/stream.rs diff --git a/os/arceos/modules/axnet-ng/src/vsock/connection_manager.rs b/net/ax-net/src/vsock/connection_manager.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/vsock/connection_manager.rs rename to net/ax-net/src/vsock/connection_manager.rs diff --git a/os/arceos/modules/axnet-ng/src/vsock/mod.rs b/net/ax-net/src/vsock/mod.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/vsock/mod.rs rename to net/ax-net/src/vsock/mod.rs diff --git a/os/arceos/modules/axnet-ng/src/vsock/stream.rs b/net/ax-net/src/vsock/stream.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/vsock/stream.rs rename to net/ax-net/src/vsock/stream.rs diff --git a/os/arceos/modules/axnet-ng/src/wrapper.rs b/net/ax-net/src/wrapper.rs similarity index 100% rename from os/arceos/modules/axnet-ng/src/wrapper.rs rename to net/ax-net/src/wrapper.rs diff --git a/os/StarryOS/kernel/CHANGELOG.md b/os/StarryOS/kernel/CHANGELOG.md index ed96a3fe7e..7d1ec94b21 100644 --- a/os/StarryOS/kernel/CHANGELOG.md +++ b/os/StarryOS/kernel/CHANGELOG.md @@ -71,7 +71,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - *(starry-task)* implement sys_getcpu ([#924](https://github.com/rcore-os/tgoskits/pull/924)) - *(starry-kernel)* add inotifywait support ([#894](https://github.com/rcore-os/tgoskits/pull/894)) - *(starry)* add userspace test for prlimit64 syscall ([#801](https://github.com/rcore-os/tgoskits/pull/801)) -- *(axnet-ng)* implement SO_TYPE, SO_PROTOCOL, SO_DOMAIN socket options ([#884](https://github.com/rcore-os/tgoskits/pull/884)) +- *(axnet)* implement SO_TYPE, SO_PROTOCOL, SO_DOMAIN socket options ([#884](https://github.com/rcore-os/tgoskits/pull/884)) - *(starry-kernel)* implement xattr syscall stubs for rsext4 ([#882](https://github.com/rcore-os/tgoskits/pull/882)) - *(starry-kernel)* add /proc/self/statm and /proc/loadavg, add procps test ([#853](https://github.com/rcore-os/tgoskits/pull/853)) - *(starry)* expose dumpable in procfs status and complete uid/gid tests ([#757](https://github.com/rcore-os/tgoskits/pull/757)) @@ -202,7 +202,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - feat(vfork) + fix(execve): implement vfork parent blocking and fix exec under CLONE_VM ([#377](https://github.com/rcore-os/tgoskits/pull/377)) - *(starry)* implement mremap ([#205](https://github.com/rcore-os/tgoskits/pull/205)) - *(mm)* track backend split metadata and generate real /proc maps output ([#306](https://github.com/rcore-os/tgoskits/pull/306)) -- *(ax-net-ng)* add ICMP raw socket support ([#368](https://github.com/rcore-os/tgoskits/pull/368)) +- *(ax-net)* add ICMP raw socket support ([#368](https://github.com/rcore-os/tgoskits/pull/368)) - *(net)* migrate ax-net to crates.io smoltcp ([#410](https://github.com/rcore-os/tgoskits/pull/410)) - *(runtime)* extend IRQ, RTC, and tty event support ([#287](https://github.com/rcore-os/tgoskits/pull/287)) - *(console)* add interrupt-driven console input ([#343](https://github.com/rcore-os/tgoskits/pull/343)) diff --git a/os/StarryOS/kernel/Cargo.toml b/os/StarryOS/kernel/Cargo.toml index 286f4df557..02fe5b625b 100644 --- a/os/StarryOS/kernel/Cargo.toml +++ b/os/StarryOS/kernel/Cargo.toml @@ -51,7 +51,7 @@ ax-feat = { workspace = true, features = [ "rtc", "fs-ng-ext4", - "net-ng", + "net", ] } ax-alloc = { workspace = true } @@ -65,7 +65,7 @@ ax-input = { workspace = true, optional = true } ax-lazyinit.workspace = true ax-log.workspace = true ax-mm.workspace = true -axnet = { version = "0.7.1", path = "../../arceos/modules/axnet-ng", package = "ax-net-ng" } +axnet = { workspace = true } ax-driver = { workspace = true, features = ["usb"] } axklib = { workspace = true, optional = true } axplat-dyn = { workspace = true, optional = true } diff --git a/os/arceos/api/arceos_api/Cargo.toml b/os/arceos/api/arceos_api/Cargo.toml index 87b99a5275..dd8d736a99 100644 --- a/os/arceos/api/arceos_api/Cargo.toml +++ b/os/arceos/api/arceos_api/Cargo.toml @@ -39,6 +39,7 @@ ax-ipi = { workspace = true, optional = true } ax-log.workspace = true ax-mm = { workspace = true, optional = true } ax-net = { workspace = true, optional = true } +axpoll.workspace = true ax-runtime.workspace = true ax-sync.workspace = true ax-task = { workspace = true, optional = true } diff --git a/os/arceos/api/arceos_api/src/imp/net.rs b/os/arceos/api/arceos_api/src/imp/net.rs index 2931680752..c18807103a 100644 --- a/os/arceos/api/arceos_api/src/imp/net.rs +++ b/os/arceos/api/arceos_api/src/imp/net.rs @@ -1,6 +1,12 @@ use crate::io::AxPollState; use ax_errno::AxResult; -use ax_net::{UdpSocket, TcpSocket}; +use ax_net::{ + RecvFlags, RecvOptions, SendOptions, Shutdown, Socket, SocketAddrEx, SocketOps, + options::{Configurable, SetSocketOption}, + tcp::TcpSocket, + udp::UdpSocket, +}; +use axpoll::{IoEvents, Pollable}; use core::net::{IpAddr, SocketAddr}; /// A handle to a TCP socket. @@ -18,50 +24,54 @@ pub fn ax_tcp_socket() -> AxTcpSocketHandle { } pub fn ax_tcp_socket_addr(socket: &AxTcpSocketHandle) -> AxResult { - socket.0.local_addr() + into_ip_addr(socket.0.local_addr()?) } pub fn ax_tcp_peer_addr(socket: &AxTcpSocketHandle) -> AxResult { - socket.0.peer_addr() + into_ip_addr(socket.0.peer_addr()?) } pub fn ax_tcp_set_nonblocking(socket: &AxTcpSocketHandle, nonblocking: bool) -> AxResult { - socket.0.set_nonblocking(nonblocking); - Ok(()) + socket + .0 + .set_option(SetSocketOption::NonBlocking(&nonblocking)) } pub fn ax_tcp_connect(socket: &AxTcpSocketHandle, addr: SocketAddr) -> AxResult { - socket.0.connect(addr) + socket.0.connect(SocketAddrEx::Ip(addr)) } pub fn ax_tcp_bind(socket: &AxTcpSocketHandle, addr: SocketAddr) -> AxResult { - socket.0.bind(addr) + socket.0.bind(SocketAddrEx::Ip(addr)) } -pub fn ax_tcp_listen(socket: &AxTcpSocketHandle, _backlog: usize) -> AxResult { - socket.0.listen() +pub fn ax_tcp_listen(socket: &AxTcpSocketHandle, backlog: usize) -> AxResult { + socket.0.listen(backlog) } pub fn ax_tcp_accept(socket: &AxTcpSocketHandle) -> AxResult<(AxTcpSocketHandle, SocketAddr)> { let new_sock = socket.0.accept()?; - let addr = new_sock.peer_addr()?; - Ok((AxTcpSocketHandle(new_sock), addr)) + let Socket::Tcp(new_sock) = new_sock else { + unreachable!("TCP listener accepted a non-TCP socket"); + }; + let addr = into_ip_addr(new_sock.peer_addr()?)?; + Ok((AxTcpSocketHandle(*new_sock), addr)) } pub fn ax_tcp_send(socket: &AxTcpSocketHandle, buf: &[u8]) -> AxResult { - socket.0.send(buf) + socket.0.send(buf, SendOptions::default()) } pub fn ax_tcp_recv(socket: &AxTcpSocketHandle, buf: &mut [u8]) -> AxResult { - socket.0.recv(buf) + socket.0.recv(buf, RecvOptions::default()) } pub fn ax_tcp_poll(socket: &AxTcpSocketHandle) -> AxResult { - socket.0.poll() + Ok(poll_state(socket.0.poll())) } pub fn ax_tcp_shutdown(socket: &AxTcpSocketHandle) -> AxResult { - socket.0.shutdown() + socket.0.shutdown(Shutdown::Both) } //////////////////////////////////////////////////////////////////////////////// @@ -73,48 +83,72 @@ pub fn ax_udp_socket() -> AxUdpSocketHandle { } pub fn ax_udp_socket_addr(socket: &AxUdpSocketHandle) -> AxResult { - socket.0.local_addr() + into_ip_addr(socket.0.local_addr()?) } pub fn ax_udp_peer_addr(socket: &AxUdpSocketHandle) -> AxResult { - socket.0.peer_addr() + into_ip_addr(socket.0.peer_addr()?) } pub fn ax_udp_set_nonblocking(socket: &AxUdpSocketHandle, nonblocking: bool) -> AxResult { - socket.0.set_nonblocking(nonblocking); - Ok(()) + socket + .0 + .set_option(SetSocketOption::NonBlocking(&nonblocking)) } pub fn ax_udp_bind(socket: &AxUdpSocketHandle, addr: SocketAddr) -> AxResult { - socket.0.bind(addr) + socket.0.bind(SocketAddrEx::Ip(addr)) } pub fn ax_udp_recv_from(socket: &AxUdpSocketHandle, buf: &mut [u8]) -> AxResult<(usize, SocketAddr)> { - socket.0.recv_from(buf) + let mut from = SocketAddrEx::Ip("0.0.0.0:0".parse().unwrap()); + let len = socket.0.recv( + buf, + RecvOptions { + from: Some(&mut from), + ..RecvOptions::default() + }, + )?; + Ok((len, into_ip_addr(from)?)) } pub fn ax_udp_peek_from(socket: &AxUdpSocketHandle, buf: &mut [u8]) -> AxResult<(usize, SocketAddr)> { - socket.0.peek_from(buf) + let mut from = SocketAddrEx::Ip("0.0.0.0:0".parse().unwrap()); + let len = socket.0.recv( + buf, + RecvOptions { + from: Some(&mut from), + flags: RecvFlags::PEEK, + ..RecvOptions::default() + }, + )?; + Ok((len, into_ip_addr(from)?)) } pub fn ax_udp_send_to(socket: &AxUdpSocketHandle, buf: &[u8], addr: SocketAddr) -> AxResult { - socket.0.send_to(buf, addr) + socket.0.send( + buf, + SendOptions { + to: Some(SocketAddrEx::Ip(addr)), + ..SendOptions::default() + }, + ) } pub fn ax_udp_connect(socket: &AxUdpSocketHandle, addr: SocketAddr) -> AxResult { - socket.0.connect(addr) + socket.0.connect(SocketAddrEx::Ip(addr)) } pub fn ax_udp_send(socket: &AxUdpSocketHandle, buf: &[u8]) -> AxResult { - socket.0.send(buf) + socket.0.send(buf, SendOptions::default()) } pub fn ax_udp_recv(socket: &AxUdpSocketHandle, buf: &mut [u8]) -> AxResult { - socket.0.recv(buf) + socket.0.recv(buf, RecvOptions::default()) } pub fn ax_udp_poll(socket: &AxUdpSocketHandle) -> AxResult { - socket.0.poll() + Ok(poll_state(socket.0.poll())) } //////////////////////////////////////////////////////////////////////////////// @@ -129,3 +163,15 @@ pub fn ax_poll_interfaces() -> AxResult { ax_net::poll_interfaces(); Ok(()) } + +fn into_ip_addr(addr: SocketAddrEx) -> AxResult { + addr.into_ip() +} + +fn poll_state(events: IoEvents) -> AxPollState { + AxPollState { + readable: events.intersects(IoEvents::IN | IoEvents::RDHUP | IoEvents::HUP), + writable: events.contains(IoEvents::OUT), + readiness_version: 0, + } +} diff --git a/os/arceos/api/arceos_posix_api/Cargo.toml b/os/arceos/api/arceos_posix_api/Cargo.toml index fecb4be721..c5b663e41e 100644 --- a/os/arceos/api/arceos_posix_api/Cargo.toml +++ b/os/arceos/api/arceos_posix_api/Cargo.toml @@ -48,6 +48,7 @@ ax-task = { workspace = true, optional = true } # Other crates ax-errno.workspace = true ax-io.workspace = true +axpoll.workspace = true flatten_objects = "0.2" scope-local = { workspace = true, optional = true } spin.workspace = true diff --git a/os/arceos/api/arceos_posix_api/src/imp/net.rs b/os/arceos/api/arceos_posix_api/src/imp/net.rs index cdb8276e65..cfbe5ff877 100644 --- a/os/arceos/api/arceos_posix_api/src/imp/net.rs +++ b/os/arceos/api/arceos_posix_api/src/imp/net.rs @@ -7,8 +7,14 @@ use core::{ use ax_errno::{LinuxError, LinuxResult}; use ax_io::PollState; -use ax_net::{TcpSocket, UdpSocket}; +use ax_net::{ + RecvOptions, SendOptions, Shutdown, SocketAddrEx, SocketOps, + options::{Configurable, SetSocketOption}, + tcp::TcpSocket, + udp::UdpSocket, +}; use ax_sync::Mutex; +use axpoll::{IoEvents, Pollable}; use super::fd_ops::FileLike; use crate::{ctypes, utils::char_ptr_to_str}; @@ -32,57 +38,63 @@ impl Socket { fn send(&self, buf: &[u8]) -> LinuxResult { match self { - Socket::Udp(udpsocket) => Ok(udpsocket.lock().send(buf)?), - Socket::Tcp(tcpsocket) => Ok(tcpsocket.lock().send(buf)?), + Socket::Udp(udpsocket) => Ok(udpsocket.lock().send(buf, SendOptions::default())?), + Socket::Tcp(tcpsocket) => Ok(tcpsocket.lock().send(buf, SendOptions::default())?), } } fn recv(&self, buf: &mut [u8]) -> LinuxResult { match self { - Socket::Udp(udpsocket) => Ok(udpsocket.lock().recv_from(buf).map(|e| e.0)?), - Socket::Tcp(tcpsocket) => Ok(tcpsocket.lock().recv(buf)?), + Socket::Udp(udpsocket) => Ok(udpsocket.lock().recv(buf, RecvOptions::default())?), + Socket::Tcp(tcpsocket) => Ok(tcpsocket.lock().recv(buf, RecvOptions::default())?), } } pub fn poll(&self) -> LinuxResult { match self { - Socket::Udp(udpsocket) => Ok(udpsocket.lock().poll()?), - Socket::Tcp(tcpsocket) => Ok(tcpsocket.lock().poll()?), + Socket::Udp(udpsocket) => Ok(poll_state(udpsocket.lock().poll())), + Socket::Tcp(tcpsocket) => Ok(poll_state(tcpsocket.lock().poll())), } } fn local_addr(&self) -> LinuxResult { match self { - Socket::Udp(udpsocket) => Ok(udpsocket.lock().local_addr()?), - Socket::Tcp(tcpsocket) => Ok(tcpsocket.lock().local_addr()?), + Socket::Udp(udpsocket) => Ok(into_ip_addr(udpsocket.lock().local_addr()?)?), + Socket::Tcp(tcpsocket) => Ok(into_ip_addr(tcpsocket.lock().local_addr()?)?), } } fn peer_addr(&self) -> LinuxResult { match self { - Socket::Udp(udpsocket) => Ok(udpsocket.lock().peer_addr()?), - Socket::Tcp(tcpsocket) => Ok(tcpsocket.lock().peer_addr()?), + Socket::Udp(udpsocket) => Ok(into_ip_addr(udpsocket.lock().peer_addr()?)?), + Socket::Tcp(tcpsocket) => Ok(into_ip_addr(tcpsocket.lock().peer_addr()?)?), } } fn bind(&self, addr: SocketAddr) -> LinuxResult { match self { - Socket::Udp(udpsocket) => Ok(udpsocket.lock().bind(addr)?), - Socket::Tcp(tcpsocket) => Ok(tcpsocket.lock().bind(addr)?), + Socket::Udp(udpsocket) => Ok(udpsocket.lock().bind(SocketAddrEx::Ip(addr))?), + Socket::Tcp(tcpsocket) => Ok(tcpsocket.lock().bind(SocketAddrEx::Ip(addr))?), } } fn connect(&self, addr: SocketAddr) -> LinuxResult { match self { - Socket::Udp(udpsocket) => Ok(udpsocket.lock().connect(addr)?), - Socket::Tcp(tcpsocket) => Ok(tcpsocket.lock().connect(addr)?), + Socket::Udp(udpsocket) => Ok(udpsocket.lock().connect(SocketAddrEx::Ip(addr))?), + Socket::Tcp(tcpsocket) => Ok(tcpsocket.lock().connect(SocketAddrEx::Ip(addr))?), } } fn sendto(&self, buf: &[u8], addr: SocketAddr) -> LinuxResult { match self { // diff: must bind before sendto - Socket::Udp(udpsocket) => Ok(udpsocket.lock().send_to(buf, addr)?), + Socket::Udp(udpsocket) => Ok(udpsocket.lock().send( + buf, + SendOptions { + to: Some(SocketAddrEx::Ip(addr)), + ..SendOptions::default() + }, + )?), Socket::Tcp(_) => Err(LinuxError::EISCONN), } } @@ -90,25 +102,39 @@ impl Socket { fn recvfrom(&self, buf: &mut [u8]) -> LinuxResult<(usize, Option)> { match self { // diff: must bind before recvfrom - Socket::Udp(udpsocket) => Ok(udpsocket - .lock() - .recv_from(buf) - .map(|res| (res.0, Some(res.1)))?), - Socket::Tcp(tcpsocket) => Ok(tcpsocket.lock().recv(buf).map(|res| (res, None))?), + Socket::Udp(udpsocket) => { + let mut from = SocketAddrEx::Ip(SocketAddr::from(([0, 0, 0, 0], 0))); + let len = udpsocket.lock().recv( + buf, + RecvOptions { + from: Some(&mut from), + ..RecvOptions::default() + }, + )?; + Ok((len, Some(into_ip_addr(from)?))) + } + Socket::Tcp(tcpsocket) => { + Ok((tcpsocket.lock().recv(buf, RecvOptions::default())?, None)) + } } } - fn listen(&self) -> LinuxResult { + fn listen(&self, backlog: usize) -> LinuxResult { match self { Socket::Udp(_) => Err(LinuxError::EOPNOTSUPP), - Socket::Tcp(tcpsocket) => Ok(tcpsocket.lock().listen()?), + Socket::Tcp(tcpsocket) => Ok(tcpsocket.lock().listen(backlog)?), } } fn accept(&self) -> LinuxResult { match self { Socket::Udp(_) => Err(LinuxError::EOPNOTSUPP), - Socket::Tcp(tcpsocket) => Ok(tcpsocket.lock().accept()?), + Socket::Tcp(tcpsocket) => { + let ax_net::Socket::Tcp(socket) = tcpsocket.lock().accept()? else { + unreachable!("TCP listener accepted a non-TCP socket"); + }; + Ok(*socket) + } } } @@ -117,14 +143,14 @@ impl Socket { Socket::Udp(udpsocket) => { let udpsocket = udpsocket.lock(); udpsocket.peer_addr()?; - udpsocket.shutdown()?; + udpsocket.shutdown(Shutdown::Both)?; Ok(()) } Socket::Tcp(tcpsocket) => { let tcpsocket = tcpsocket.lock(); tcpsocket.peer_addr()?; - tcpsocket.shutdown()?; + tcpsocket.shutdown(Shutdown::Both)?; Ok(()) } } @@ -132,11 +158,12 @@ impl Socket { fn set_reuseaddr(&self, reuse: bool) -> LinuxResult { match self { - Socket::Udp(_) => Err(LinuxError::ENOPROTOOPT), - Socket::Tcp(tcpsocket) => { - tcpsocket.lock().set_reuseaddr(reuse); - Ok(()) - } + Socket::Udp(udpsocket) => Ok(udpsocket + .lock() + .set_option(SetSocketOption::ReuseAddress(&reuse))?), + Socket::Tcp(tcpsocket) => Ok(tcpsocket + .lock() + .set_option(SetSocketOption::ReuseAddress(&reuse))?), } } } @@ -174,10 +201,13 @@ impl FileLike for Socket { fn set_nonblocking(&self, nonblock: bool) -> LinuxResult { match self { - Socket::Udp(udpsocket) => udpsocket.lock().set_nonblocking(nonblock), - Socket::Tcp(tcpsocket) => tcpsocket.lock().set_nonblocking(nonblock), + Socket::Udp(udpsocket) => Ok(udpsocket + .lock() + .set_option(SetSocketOption::NonBlocking(&nonblock))?), + Socket::Tcp(tcpsocket) => Ok(tcpsocket + .lock() + .set_option(SetSocketOption::NonBlocking(&nonblock))?), } - Ok(()) } } @@ -197,6 +227,18 @@ impl From for ctypes::sockaddr_in { } } +fn into_ip_addr(addr: SocketAddrEx) -> LinuxResult { + Ok(addr.into_ip()?) +} + +fn poll_state(events: IoEvents) -> PollState { + PollState { + readable: events.intersects(IoEvents::IN | IoEvents::RDHUP | IoEvents::HUP), + writable: events.contains(IoEvents::OUT), + readiness_version: 0, + } +} + impl From for SocketAddrV4 { fn from(addr: ctypes::sockaddr_in) -> SocketAddrV4 { SocketAddrV4::new( @@ -401,13 +443,13 @@ pub fn sys_recv( /// Listen for connections on a socket /// /// Return 0 if success. -pub fn sys_listen( - socket_fd: c_int, - backlog: c_int, // currently not used -) -> c_int { +pub fn sys_listen(socket_fd: c_int, backlog: c_int) -> c_int { debug!("sys_listen <= {socket_fd} {backlog}"); syscall_body!(sys_listen, { - Socket::from_fd(socket_fd)?.listen()?; + if backlog < 0 && backlog != -1 { + return Err(LinuxError::EINVAL); + } + Socket::from_fd(socket_fd)?.listen(backlog as usize)?; Ok(0) }) } @@ -430,7 +472,7 @@ pub unsafe fn sys_accept( } let socket = Socket::from_fd(socket_fd)?; let new_socket = socket.accept()?; - let addr = new_socket.peer_addr()?; + let addr = into_ip_addr(new_socket.peer_addr()?)?; let new_fd = Socket::add_to_fd_table(Socket::Tcp(Mutex::new(new_socket)))?; unsafe { (*socket_addr, *socket_len) = into_sockaddr(addr); diff --git a/os/arceos/api/axfeat/Cargo.toml b/os/arceos/api/axfeat/Cargo.toml index dfdbfaa2b2..2b507f1b81 100644 --- a/os/arceos/api/axfeat/Cargo.toml +++ b/os/arceos/api/axfeat/Cargo.toml @@ -80,7 +80,6 @@ net = [ "dep:ax-net", "ax-runtime/net", ] -net-ng = ["paging", "irq", "multitask", "dep:ax-net-ng", "ax-runtime/net-ng"] vsock = ["ax-runtime/vsock"] # Display @@ -117,7 +116,6 @@ ax-input = { workspace = true, optional = true } ax-ipi = { workspace = true, optional = true } ax-log.workspace = true ax-net = { workspace = true, optional = true } -ax-net-ng = { workspace = true, optional = true } ax-runtime.workspace = true ax-sync = { workspace = true, optional = true } ax-task = { workspace = true, optional = true } diff --git a/os/arceos/modules/axnet/CHANGELOG.md b/os/arceos/modules/axnet/CHANGELOG.md deleted file mode 100644 index 5812705e10..0000000000 --- a/os/arceos/modules/axnet/CHANGELOG.md +++ /dev/null @@ -1,43 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -## [0.5.16](https://github.com/rcore-os/tgoskits/compare/ax-net-v0.5.15...ax-net-v0.5.16) - 2026-06-09 - -### Added - -- *(ax-posix-api)* improve ArceOS epoll semantics ([#1034](https://github.com/rcore-os/tgoskits/pull/1034)) - -## [0.5.15](https://github.com/rcore-os/tgoskits/compare/ax-net-v0.5.14...ax-net-v0.5.15) - 2026-06-03 - -### Fixed - -- *(arceos)* address lockdep test issues ([#1009](https://github.com/rcore-os/tgoskits/pull/1009)) - -### Other - -- *(drivers)* split shared driver stack from ArceOS ([#831](https://github.com/rcore-os/tgoskits/pull/831)) - -## [0.5.14](https://github.com/rcore-os/tgoskits/compare/ax-net-v0.5.13...ax-net-v0.5.14) - 2026-05-22 - -### Other - -- updated the following local packages: ax-errno, ax-hal, ax-task, ax-io, ax-driver, ax-sync - -## [0.5.13](https://github.com/rcore-os/tgoskits/compare/ax-net-v0.5.12...ax-net-v0.5.13) - 2026-05-19 - -### Other - -- updated the following local packages: ax-errno, ax-driver, ax-task, ax-io, ax-hal, ax-sync - -## [0.5.12](https://github.com/rcore-os/tgoskits/compare/ax-net-v0.5.11...ax-net-v0.5.12) - 2026-05-15 - -### Added - -- support sys_setsockopt -- *(net)* migrate ax-net to crates.io smoltcp ([#410](https://github.com/rcore-os/tgoskits/pull/410)) diff --git a/os/arceos/modules/axnet/Cargo.toml b/os/arceos/modules/axnet/Cargo.toml deleted file mode 100644 index 299a51326c..0000000000 --- a/os/arceos/modules/axnet/Cargo.toml +++ /dev/null @@ -1,50 +0,0 @@ -[package] -name = "ax-net" -version = "0.5.16" -repository = "https://github.com/rcore-os/tgoskits" -edition.workspace = true -authors = [ - "Yuekai Jia ", - "ChengXiang Qi ", -] -description = "ArceOS network module" -license.workspace = true - -[features] -smoltcp = ["dep:smoltcp"] -default = ["smoltcp"] -vsock = [] - -[dependencies] -ax-errno.workspace = true -ax-hal.workspace = true -ax-io.workspace = true -ax-sync.workspace = true -ax-task.workspace = true -ax-net-ng.workspace = true -cfg-if.workspace = true -ax-lazyinit.workspace = true -log.workspace = true -spin.workspace = true - -[dependencies.smoltcp] -workspace = true -optional = true -features = [ - "alloc", - "log", # no std - "async", - "medium-ethernet", - "medium-ip", - "proto-ipv4", - "proto-ipv6", - "socket-raw", - "socket-icmp", - "socket-udp", - "socket-tcp", - "socket-dhcpv4", - "socket-dns", - # "fragmentation-buffer-size-65536", "proto-ipv4-fragmentation", - # "reassembly-buffer-size-65536", "reassembly-buffer-count-32", - # "assembler-max-segment-count-32", -] diff --git a/os/arceos/modules/axnet/src/lib.rs b/os/arceos/modules/axnet/src/lib.rs deleted file mode 100644 index c6a5ce8705..0000000000 --- a/os/arceos/modules/axnet/src/lib.rs +++ /dev/null @@ -1,59 +0,0 @@ -//! [ArceOS](https://github.com/arceos-org/arceos) network module. -//! -//! It provides unified networking primitives for TCP/UDP communication -//! using various underlying network stacks. Currently, only [smoltcp] is -//! supported. -//! -//! # Organization -//! -//! - [`TcpSocket`]: A TCP socket that provides POSIX-like APIs. -//! - [`UdpSocket`]: A UDP socket that provides POSIX-like APIs. -//! - [`dns_query`]: Function for DNS query. -//! -//! # Cargo Features -//! -//! - `smoltcp`: Use [smoltcp] as the underlying network stack. This is enabled -//! by default. -//! -//! [smoltcp]: https://github.com/smoltcp-rs/smoltcp - -#![no_std] - -extern crate alloc; -#[cfg(feature = "smoltcp")] -#[macro_use] -extern crate log; - -#[cfg(feature = "smoltcp")] -use alloc::{boxed::Box, vec::Vec}; - -cfg_if::cfg_if! { - if #[cfg(feature = "smoltcp")] { - mod smoltcp_impl; - use smoltcp_impl as net_impl; - } -} - -#[cfg(feature = "smoltcp")] -pub use ax_net_ng::{ - EthernetDriver, NetDeviceError, NetDeviceResult, NetIrqEvents, NetRxBuffer, NetTxBuffer, - RdNetDriver, -}; - -#[cfg(feature = "smoltcp")] -pub use self::net_impl::{ - TcpSocket, UdpSocket, bench_receive, bench_transmit, dns_query, poll_interfaces, -}; - -/// Initializes the network subsystem by NIC devices. -#[cfg(feature = "smoltcp")] -pub fn init_network(mut net_devs: Vec>) { - info!("Initialize network subsystem..."); - - if let Some(dev) = net_devs.pop() { - info!(" use NIC 0: {:?}", dev.device_name()); - net_impl::init(dev); - } else { - warn!(" No network device found!"); - } -} diff --git a/os/arceos/modules/axnet/src/smoltcp_impl/addr.rs b/os/arceos/modules/axnet/src/smoltcp_impl/addr.rs deleted file mode 100644 index 7ceaf1a09d..0000000000 --- a/os/arceos/modules/axnet/src/smoltcp_impl/addr.rs +++ /dev/null @@ -1,4 +0,0 @@ -use smoltcp::wire::{IpAddress, IpEndpoint}; - -pub const UNSPECIFIED_IP: IpAddress = IpAddress::v4(0, 0, 0, 0); -pub const UNSPECIFIED_ENDPOINT: IpEndpoint = IpEndpoint::new(UNSPECIFIED_IP, 0); diff --git a/os/arceos/modules/axnet/src/smoltcp_impl/bench.rs b/os/arceos/modules/axnet/src/smoltcp_impl/bench.rs deleted file mode 100644 index 1cf1a2d7f5..0000000000 --- a/os/arceos/modules/axnet/src/smoltcp_impl/bench.rs +++ /dev/null @@ -1,68 +0,0 @@ -use smoltcp::phy::{Device, RxToken, TxToken}; - -use super::{AxNetRxToken, AxNetTxToken, DeviceWrapper, InterfaceWrapper, STANDARD_MTU}; - -const GB: usize = 1000 * MB; -const MB: usize = 1000 * KB; -const KB: usize = 1000; - -impl DeviceWrapper { - pub fn bench_transmit_bandwidth(&mut self) { - // 10 Gb - const MAX_SEND_BYTES: usize = 10 * GB; - let mut send_bytes: usize = 0; - let mut past_send_bytes: usize = 0; - let mut past_time = InterfaceWrapper::current_time(); - - // Send bytes - while send_bytes < MAX_SEND_BYTES { - if let Some(tx_token) = self.transmit(InterfaceWrapper::current_time()) { - AxNetTxToken::consume(tx_token, STANDARD_MTU, |tx_buf| { - tx_buf[0..12].fill(1); - // ether type: IPv4 - tx_buf[12..14].copy_from_slice(&[0x08, 0x00]); - tx_buf[14..STANDARD_MTU].fill(1); - }); - send_bytes += STANDARD_MTU; - } - - let current_time = InterfaceWrapper::current_time(); - if (current_time - past_time).secs() == 1 { - let gb = ((send_bytes - past_send_bytes) * 8) / GB; - let mb = (((send_bytes - past_send_bytes) * 8) % GB) / MB; - let gib = (send_bytes - past_send_bytes) / GB; - let mib = ((send_bytes - past_send_bytes) % GB) / MB; - info!("Transmit: {gib}.{mib:03}GBytes, Bandwidth: {gb}.{mb:03}Gbits/sec."); - past_time = current_time; - past_send_bytes = send_bytes; - } - } - } - - pub fn bench_receive_bandwidth(&mut self) { - // 10 Gb - const MAX_RECEIVE_BYTES: usize = 10 * GB; - let mut receive_bytes: usize = 0; - let mut past_receive_bytes: usize = 0; - let mut past_time = InterfaceWrapper::current_time(); - // Receive bytes - while receive_bytes < MAX_RECEIVE_BYTES { - if let Some(rx_token) = self.receive(InterfaceWrapper::current_time()) { - AxNetRxToken::consume(rx_token.0, |rx_buf| { - receive_bytes += rx_buf.len(); - }); - } - - let current_time = InterfaceWrapper::current_time(); - if (current_time - past_time).secs() == 1 { - let gb = ((receive_bytes - past_receive_bytes) * 8) / GB; - let mb = (((receive_bytes - past_receive_bytes) * 8) % GB) / MB; - let gib = (receive_bytes - past_receive_bytes) / GB; - let mib = ((receive_bytes - past_receive_bytes) % GB) / MB; - info!("Receive: {gib}.{mib:03}GBytes, Bandwidth: {gb}.{mb:03}Gbits/sec."); - past_time = current_time; - past_receive_bytes = receive_bytes; - } - } - } -} diff --git a/os/arceos/modules/axnet/src/smoltcp_impl/dns.rs b/os/arceos/modules/axnet/src/smoltcp_impl/dns.rs deleted file mode 100644 index 2b62b09b1e..0000000000 --- a/os/arceos/modules/axnet/src/smoltcp_impl/dns.rs +++ /dev/null @@ -1,92 +0,0 @@ -use alloc::vec::Vec; -use core::net::IpAddr; - -use ax_errno::{AxError, AxResult, ax_err_type}; -use smoltcp::{ - iface::SocketHandle, - socket::dns::{self, GetQueryResultError, StartQueryError}, - wire::DnsQueryType, -}; - -use super::{ETH0, SOCKET_SET, SocketSetWrapper}; - -/// A DNS socket. -struct DnsSocket { - handle: Option, -} - -impl DnsSocket { - #[allow(clippy::new_without_default)] - /// Creates a new DNS socket. - pub fn new() -> Self { - let socket = SocketSetWrapper::new_dns_socket(); - let handle = Some(SOCKET_SET.add(socket)); - Self { handle } - } - - #[allow(dead_code)] - /// Update the list of DNS servers, will replace all existing servers. - pub fn update_servers(self, servers: &[smoltcp::wire::IpAddress]) { - SOCKET_SET.with_socket_mut::(self.handle.unwrap(), |socket| { - socket.update_servers(servers) - }); - } - - /// Query a address with given DNS query type. - pub fn query(&self, name: &str, query_type: DnsQueryType) -> AxResult> { - // let local_addr = self.local_addr.unwrap_or_else(f); - let handle = self.handle.ok_or_else(|| ax_err_type!(InvalidInput))?; - let query_handle = { - let mut iface = ETH0.iface.lock(); - SOCKET_SET.with_socket_mut::(handle, |socket| { - socket.start_query(iface.context(), name, query_type) - }) - } - .map_err(|e| match e { - StartQueryError::NoFreeSlot => { - ax_err_type!(ResourceBusy, "socket query() failed: no free slot") - } - StartQueryError::InvalidName => { - ax_err_type!(InvalidInput, "socket query() failed: invalid name") - } - StartQueryError::NameTooLong => { - ax_err_type!(InvalidInput, "socket query() failed: too long name") - } - })?; - loop { - SOCKET_SET.poll_interfaces(); - match SOCKET_SET.with_socket_mut::(handle, |socket| { - socket.get_query_result(query_handle).map_err(|e| match e { - GetQueryResultError::Pending => AxError::WouldBlock, - GetQueryResultError::Failed => { - ax_err_type!(ConnectionRefused, "socket query() failed") - } - }) - }) { - Ok(n) => { - let mut res = Vec::with_capacity(n.capacity()); - for ip in n { - res.push(IpAddr::from(ip)) - } - return Ok(res); - } - Err(AxError::WouldBlock) => ax_task::yield_now(), - Err(e) => return Err(e), - } - } - } -} - -impl Drop for DnsSocket { - fn drop(&mut self) { - if let Some(handle) = self.handle { - SOCKET_SET.remove(handle); - } - } -} - -/// Public function for DNS query. -pub fn dns_query(name: &str) -> AxResult> { - let socket = DnsSocket::new(); - socket.query(name, DnsQueryType::A) -} diff --git a/os/arceos/modules/axnet/src/smoltcp_impl/listen_table.rs b/os/arceos/modules/axnet/src/smoltcp_impl/listen_table.rs deleted file mode 100644 index 845f5e7752..0000000000 --- a/os/arceos/modules/axnet/src/smoltcp_impl/listen_table.rs +++ /dev/null @@ -1,164 +0,0 @@ -use alloc::{boxed::Box, collections::VecDeque}; -use core::ops::{Deref, DerefMut}; - -use ax_errno::{AxError, AxResult, ax_err}; -use ax_sync::Mutex; -use smoltcp::{ - iface::{SocketHandle, SocketSet}, - socket::tcp::{self, State}, - wire::{IpAddress, IpEndpoint, IpListenEndpoint}, -}; - -use super::{LISTEN_QUEUE_SIZE, SOCKET_SET, SocketSetWrapper}; - -const PORT_NUM: usize = 65536; - -struct ListenTableEntry { - listen_endpoint: IpListenEndpoint, - syn_queue: VecDeque, -} - -impl ListenTableEntry { - pub fn new(listen_endpoint: IpListenEndpoint) -> Self { - Self { - listen_endpoint, - syn_queue: VecDeque::with_capacity(LISTEN_QUEUE_SIZE), - } - } - - #[inline] - fn can_accept(&self, dst: IpAddress) -> bool { - match self.listen_endpoint.addr { - Some(addr) => addr == dst, - None => true, - } - } -} - -impl Drop for ListenTableEntry { - fn drop(&mut self) { - for &handle in &self.syn_queue { - SOCKET_SET.remove(handle); - } - } -} - -pub struct ListenTable { - tcp: Box<[Mutex>>]>, -} - -impl ListenTable { - pub fn new() -> Self { - let tcp = unsafe { - let mut buf = Box::new_uninit_slice(PORT_NUM); - for i in 0..PORT_NUM { - buf[i].write(Mutex::new(None)); - } - buf.assume_init() - }; - Self { tcp } - } - - pub fn can_listen(&self, port: u16) -> bool { - self.tcp[port as usize].lock().is_none() - } - - pub fn listen(&self, listen_endpoint: IpListenEndpoint) -> AxResult { - let port = listen_endpoint.port; - assert_ne!(port, 0); - let mut entry = self.tcp[port as usize].lock(); - if entry.is_none() { - *entry = Some(Box::new(ListenTableEntry::new(listen_endpoint))); - Ok(()) - } else { - ax_err!(AddrInUse, "socket listen() failed") - } - } - - pub fn unlisten(&self, port: u16) { - debug!("TCP socket unlisten on {port}"); - let entry = self.tcp[port as usize].lock().take(); - drop(entry); - } - - pub fn can_accept(&self, port: u16) -> AxResult { - SOCKET_SET.with_socket_set_mut(|sockets| { - if let Some(entry) = self.tcp[port as usize].lock().deref() { - Ok(entry - .syn_queue - .iter() - .any(|&handle| is_connected(sockets, handle))) - } else { - ax_err!(InvalidInput, "socket accept() failed: not listen") - } - }) - } - - pub fn accept(&self, port: u16) -> AxResult<(SocketHandle, (IpEndpoint, IpEndpoint))> { - SOCKET_SET.with_socket_set_mut(|sockets| { - if let Some(entry) = self.tcp[port as usize].lock().deref_mut() { - let syn_queue = &mut entry.syn_queue; - let (idx, addr_tuple) = syn_queue - .iter() - .enumerate() - .find_map(|(idx, &handle)| { - is_connected(sockets, handle) - .then(|| (idx, get_addr_tuple(sockets, handle))) - }) - .ok_or(AxError::WouldBlock)?; // wait for connection - if idx > 0 { - warn!( - "slow SYN queue enumeration: index = {}, len = {}!", - idx, - syn_queue.len() - ); - } - let handle = syn_queue.swap_remove_front(idx).unwrap(); - Ok((handle, addr_tuple)) - } else { - ax_err!(InvalidInput, "socket accept() failed: not listen") - } - }) - } - - pub fn incoming_tcp_packet( - &self, - src: IpEndpoint, - dst: IpEndpoint, - sockets: &mut SocketSet<'_>, - ) { - if let Some(entry) = self.tcp[dst.port as usize].lock().deref_mut() { - if !entry.can_accept(dst.addr) { - // not listening on this address - return; - } - if entry.syn_queue.len() >= LISTEN_QUEUE_SIZE { - // SYN queue is full, drop the packet - warn!("SYN queue overflow!"); - return; - } - let mut socket = SocketSetWrapper::new_tcp_socket(); - if socket.listen(entry.listen_endpoint).is_ok() { - let handle = sockets.add(socket); - debug!( - "TCP socket {}: prepare for connection {} -> {}", - handle, src, entry.listen_endpoint - ); - entry.syn_queue.push_back(handle); - } - } - } -} - -fn is_connected(sockets: &SocketSet<'_>, handle: SocketHandle) -> bool { - let socket = sockets.get::(handle); - !matches!(socket.state(), State::Listen | State::SynReceived) -} - -fn get_addr_tuple(sockets: &SocketSet<'_>, handle: SocketHandle) -> (IpEndpoint, IpEndpoint) { - let socket = sockets.get::(handle); - ( - socket.local_endpoint().unwrap(), - socket.remote_endpoint().unwrap(), - ) -} diff --git a/os/arceos/modules/axnet/src/smoltcp_impl/mod.rs b/os/arceos/modules/axnet/src/smoltcp_impl/mod.rs deleted file mode 100644 index cd321f682c..0000000000 --- a/os/arceos/modules/axnet/src/smoltcp_impl/mod.rs +++ /dev/null @@ -1,354 +0,0 @@ -mod addr; -mod bench; -mod dns; -mod listen_table; -mod tcp; -mod udp; - -use alloc::{boxed::Box, vec}; -use core::{cell::RefCell, ops::DerefMut}; - -use ax_hal::time::{NANOS_PER_MICROS, wall_time_nanos}; -use ax_lazyinit::LazyInit; -use ax_net_ng::{EthernetDriver, NetDeviceError, NetRxBuffer}; -use ax_sync::Mutex; -use smoltcp::{ - iface::{Config, Interface, SocketHandle, SocketSet}, - phy::{Device, DeviceCapabilities, Medium, RxToken, TxToken}, - socket::{self, AnySocket}, - time::Instant, - wire::{EthernetAddress, HardwareAddress, IpAddress, IpCidr}, -}; - -use self::listen_table::ListenTable; -pub use self::{dns::dns_query, tcp::TcpSocket, udp::UdpSocket}; - -macro_rules! env_or_default { - ($key:literal) => { - match option_env!($key) { - Some(val) => val, - None => "", - } - }; -} - -const IP: &str = env_or_default!("AX_IP"); -const GATEWAY: &str = env_or_default!("AX_GW"); -const DNS_SERVER: &str = "8.8.8.8"; -const IP_PREFIX: u8 = 24; - -const STANDARD_MTU: usize = 1500; - -const RANDOM_SEED: u64 = 0xA2CE_05A2_CE05_A2CE; - -const TCP_RX_BUF_LEN: usize = 64 * 1024; -const TCP_TX_BUF_LEN: usize = 64 * 1024; -const UDP_RX_BUF_LEN: usize = 64 * 1024; -const UDP_TX_BUF_LEN: usize = 64 * 1024; -const LISTEN_QUEUE_SIZE: usize = 512; - -static LISTEN_TABLE: LazyInit = LazyInit::new(); -static SOCKET_SET: LazyInit = LazyInit::new(); -static ETH0: LazyInit = LazyInit::new(); - -struct SocketSetWrapper<'a>(Mutex>); - -struct DeviceWrapper { - inner: RefCell>, - sockets_for_preprocess: Option, -} - -struct InterfaceWrapper { - name: &'static str, - ether_addr: EthernetAddress, - dev: Mutex, - iface: Mutex, -} - -impl<'a> SocketSetWrapper<'a> { - fn new() -> Self { - Self(Mutex::new(SocketSet::new(vec![]))) - } - - pub fn new_tcp_socket() -> socket::tcp::Socket<'a> { - let tcp_rx_buffer = socket::tcp::SocketBuffer::new(vec![0; TCP_RX_BUF_LEN]); - let tcp_tx_buffer = socket::tcp::SocketBuffer::new(vec![0; TCP_TX_BUF_LEN]); - socket::tcp::Socket::new(tcp_rx_buffer, tcp_tx_buffer) - } - - pub fn new_udp_socket() -> socket::udp::Socket<'a> { - let udp_rx_buffer = socket::udp::PacketBuffer::new( - vec![socket::udp::PacketMetadata::EMPTY; 8], - vec![0; UDP_RX_BUF_LEN], - ); - let udp_tx_buffer = socket::udp::PacketBuffer::new( - vec![socket::udp::PacketMetadata::EMPTY; 8], - vec![0; UDP_TX_BUF_LEN], - ); - socket::udp::Socket::new(udp_rx_buffer, udp_tx_buffer) - } - - pub fn new_dns_socket() -> socket::dns::Socket<'a> { - let server_addr = DNS_SERVER.parse().expect("invalid DNS server address"); - socket::dns::Socket::new(&[server_addr], vec![]) - } - - pub fn add>(&self, socket: T) -> SocketHandle { - let handle = self.0.lock().add(socket); - debug!("socket {handle}: created"); - handle - } - - pub fn with_socket, R, F>(&self, handle: SocketHandle, f: F) -> R - where - F: FnOnce(&T) -> R, - { - let set = self.0.lock(); - let socket = set.get(handle); - f(socket) - } - - pub fn with_socket_mut, R, F>(&self, handle: SocketHandle, f: F) -> R - where - F: FnOnce(&mut T) -> R, - { - let mut set = self.0.lock(); - let socket = set.get_mut(handle); - f(socket) - } - - pub fn with_socket_set_mut(&self, f: F) -> R - where - F: FnOnce(&mut SocketSet<'a>) -> R, - { - let mut set = self.0.lock(); - f(&mut set) - } - - pub fn poll_interfaces(&self) { - ETH0.poll(&self.0); - } - - pub fn remove(&self, handle: SocketHandle) { - self.0.lock().remove(handle); - debug!("socket {handle}: destroyed"); - } -} - -impl InterfaceWrapper { - fn new(name: &'static str, dev: Box, ether_addr: EthernetAddress) -> Self { - let mut config = Config::new(HardwareAddress::Ethernet(ether_addr)); - config.random_seed = RANDOM_SEED; - - let mut dev = DeviceWrapper::new(dev); - let iface = Mutex::new(Interface::new(config, &mut dev, Self::current_time())); - Self { - name, - ether_addr, - dev: Mutex::new(dev), - iface, - } - } - - fn current_time() -> Instant { - Instant::from_micros_const((wall_time_nanos() / NANOS_PER_MICROS) as i64) - } - - pub fn name(&self) -> &str { - self.name - } - - pub fn ethernet_address(&self) -> EthernetAddress { - self.ether_addr - } - - pub fn setup_ip_addr(&self, ip: IpAddress, prefix_len: u8) { - let mut iface = self.iface.lock(); - iface.update_ip_addrs(|ip_addrs| { - ip_addrs.push(IpCidr::new(ip, prefix_len)).unwrap(); - }); - } - - pub fn setup_gateway(&self, gateway: IpAddress) { - let mut iface = self.iface.lock(); - match gateway { - IpAddress::Ipv4(v4) => iface.routes_mut().add_default_ipv4_route(v4).unwrap(), - IpAddress::Ipv6(v6) => iface.routes_mut().add_default_ipv6_route(v6).unwrap(), - }; - } - - pub fn poll(&self, sockets: &Mutex) { - let mut dev = self.dev.lock(); - let mut iface = self.iface.lock(); - let mut sockets = sockets.lock(); - let timestamp = Self::current_time(); - dev.set_sockets_for_preprocess(Some(&mut *sockets as *mut SocketSet<'_> as usize)); - iface.poll(timestamp, dev.deref_mut(), &mut sockets); - dev.set_sockets_for_preprocess(None); - } -} - -impl DeviceWrapper { - fn new(inner: Box) -> Self { - Self { - inner: RefCell::new(inner), - sockets_for_preprocess: None, - } - } - - fn set_sockets_for_preprocess(&mut self, sockets: Option) { - self.sockets_for_preprocess = sockets; - } -} - -impl Device for DeviceWrapper { - type RxToken<'a> - = AxNetRxToken<'a> - where - Self: 'a; - type TxToken<'a> - = AxNetTxToken<'a> - where - Self: 'a; - - fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { - let mut dev = self.inner.borrow_mut(); - if let Err(e) = dev.recycle_tx_buffers() { - warn!("recycle_tx_buffers failed: {e:?}"); - return None; - } - - let rx_buf = match dev.receive() { - Ok(buf) => buf, - Err(err) => { - if !matches!(err, NetDeviceError::Again) { - warn!("receive failed: {err:?}"); - } - return None; - } - }; - Some(( - AxNetRxToken(&self.inner, rx_buf, self.sockets_for_preprocess), - AxNetTxToken(&self.inner), - )) - } - - fn transmit(&mut self, _timestamp: Instant) -> Option> { - let mut dev = self.inner.borrow_mut(); - if let Err(e) = dev.recycle_tx_buffers() { - warn!("recycle_tx_buffers failed: {e:?}"); - return None; - } - Some(AxNetTxToken(&self.inner)) - } - - fn capabilities(&self) -> DeviceCapabilities { - let mut caps = DeviceCapabilities::default(); - caps.max_transmission_unit = 1514; - caps.max_burst_size = None; - caps.medium = Medium::Ethernet; - caps - } -} - -struct AxNetRxToken<'a>( - &'a RefCell>, - Box, - Option, -); -struct AxNetTxToken<'a>(&'a RefCell>); - -impl RxToken for AxNetRxToken<'_> { - fn consume(self, f: F) -> R - where - F: FnOnce(&[u8]) -> R, - { - let mut rx_buf = self.1; - trace!( - "RECV {} bytes: {:02X?}", - rx_buf.packet_len(), - rx_buf.packet() - ); - if let Some(sockets) = self.2 { - // SAFETY: InterfaceWrapper::poll installs this pointer only for the - // duration of iface.poll(), and RxToken::consume is called - // synchronously before the packet is handed to smoltcp sockets. - unsafe { - snoop_tcp_packet(rx_buf.packet(), &mut *(sockets as *mut SocketSet<'_>)).ok(); - } - } - let result = f(rx_buf.packet()); - self.0.borrow_mut().recycle_rx_buffer(&mut *rx_buf).unwrap(); - result - } -} - -impl TxToken for AxNetTxToken<'_> { - fn consume(self, len: usize, f: F) -> R - where - F: FnOnce(&mut [u8]) -> R, - { - let mut dev = self.0.borrow_mut(); - let mut tx_buf = dev.alloc_tx_buffer(len).unwrap(); - let ret = f(tx_buf.packet_mut()); - trace!("SEND {} bytes: {:02X?}", len, tx_buf.packet()); - dev.transmit(&mut *tx_buf).unwrap(); - ret - } -} - -fn snoop_tcp_packet(buf: &[u8], sockets: &mut SocketSet<'_>) -> Result<(), smoltcp::wire::Error> { - use smoltcp::wire::{EthernetFrame, IpProtocol, Ipv4Packet, TcpPacket}; - - let ether_frame = EthernetFrame::new_checked(buf)?; - let ipv4_packet = Ipv4Packet::new_checked(ether_frame.payload())?; - - if ipv4_packet.next_header() == IpProtocol::Tcp { - let tcp_packet = TcpPacket::new_checked(ipv4_packet.payload())?; - let src_addr = (ipv4_packet.src_addr(), tcp_packet.src_port()).into(); - let dst_addr = (ipv4_packet.dst_addr(), tcp_packet.dst_port()).into(); - let is_first = tcp_packet.syn() && !tcp_packet.ack(); - if is_first { - // create a socket for the first incoming TCP packet, as the later accept() returns. - LISTEN_TABLE.incoming_tcp_packet(src_addr, dst_addr, sockets); - } - } - Ok(()) -} - -/// Poll the network stack. -/// -/// It may receive packets from the NIC and process them, and transmit queued -/// packets to the NIC. -pub fn poll_interfaces() { - SOCKET_SET.poll_interfaces(); -} - -/// Benchmark raw socket transmit bandwidth. -pub fn bench_transmit() { - ETH0.dev.lock().bench_transmit_bandwidth(); -} - -/// Benchmark raw socket receive bandwidth. -pub fn bench_receive() { - ETH0.dev.lock().bench_receive_bandwidth(); -} - -pub(crate) fn init(net_dev: Box) { - let ether_addr = EthernetAddress(net_dev.mac_address()); - let eth0 = InterfaceWrapper::new("eth0", net_dev, ether_addr); - - let ip = IP.parse().expect("invalid IP address"); - let gateway = GATEWAY.parse().expect("invalid gateway IP address"); - eth0.setup_ip_addr(ip, IP_PREFIX); - eth0.setup_gateway(gateway); - - ETH0.init_once(eth0); - SOCKET_SET.init_once(SocketSetWrapper::new()); - LISTEN_TABLE.init_once(ListenTable::new()); - - info!("created net interface {:?}:", ETH0.name()); - info!(" ether: {}", ETH0.ethernet_address()); - info!(" ip: {ip}/{IP_PREFIX}"); - info!(" gateway: {gateway}"); -} diff --git a/os/arceos/modules/axnet/src/smoltcp_impl/tcp.rs b/os/arceos/modules/axnet/src/smoltcp_impl/tcp.rs deleted file mode 100644 index e02df49f77..0000000000 --- a/os/arceos/modules/axnet/src/smoltcp_impl/tcp.rs +++ /dev/null @@ -1,590 +0,0 @@ -use core::{ - cell::UnsafeCell, - net::SocketAddr, - sync::atomic::{AtomicBool, AtomicU8, Ordering}, -}; - -use ax_errno::{AxError, AxResult, ax_err, ax_err_type}; -use ax_io::PollState; -use ax_sync::Mutex; -use smoltcp::{ - iface::SocketHandle, - socket::tcp::{self, ConnectError, State}, - wire::{IpEndpoint, IpListenEndpoint}, -}; - -use super::{ETH0, LISTEN_TABLE, SOCKET_SET, SocketSetWrapper, addr::UNSPECIFIED_ENDPOINT}; - -// State transitions: -// CLOSED -(connect)-> BUSY -> CONNECTING -> CONNECTED -(shutdown)-> BUSY -> CLOSED -// | -// |-(listen)-> BUSY -> LISTENING -(shutdown)-> BUSY -> CLOSED -// | -// -(bind)-> BUSY -> CLOSED -const STATE_CLOSED: u8 = 0; -const STATE_BUSY: u8 = 1; -const STATE_CONNECTING: u8 = 2; -const STATE_CONNECTED: u8 = 3; -const STATE_LISTENING: u8 = 4; - -/// A TCP socket that provides POSIX-like APIs. -/// -/// - [`connect`] is for TCP clients. -/// - [`bind`], [`listen`], and [`accept`] are for TCP servers. -/// - Other methods are for both TCP clients and servers. -/// -/// [`connect`]: TcpSocket::connect -/// [`bind`]: TcpSocket::bind -/// [`listen`]: TcpSocket::listen -/// [`accept`]: TcpSocket::accept -pub struct TcpSocket { - state: AtomicU8, - handle: UnsafeCell>, - local_addr: UnsafeCell, - peer_addr: UnsafeCell, - nonblock: AtomicBool, - reuse_addr: AtomicBool, -} - -unsafe impl Sync for TcpSocket {} - -impl Default for TcpSocket { - fn default() -> Self { - Self::new() - } -} - -impl TcpSocket { - /// Creates a new TCP socket. - pub const fn new() -> Self { - Self { - state: AtomicU8::new(STATE_CLOSED), - handle: UnsafeCell::new(None), - local_addr: UnsafeCell::new(UNSPECIFIED_ENDPOINT), - peer_addr: UnsafeCell::new(UNSPECIFIED_ENDPOINT), - nonblock: AtomicBool::new(false), - reuse_addr: AtomicBool::new(false), - } - } - - /// Creates a new TCP socket that is already connected. - const fn new_connected( - handle: SocketHandle, - local_addr: IpEndpoint, - peer_addr: IpEndpoint, - ) -> Self { - Self { - state: AtomicU8::new(STATE_CONNECTED), - handle: UnsafeCell::new(Some(handle)), - local_addr: UnsafeCell::new(local_addr), - peer_addr: UnsafeCell::new(peer_addr), - nonblock: AtomicBool::new(false), - reuse_addr: AtomicBool::new(false), - } - } - - /// Returns the local address and port, or - /// [`Err(NotConnected)`](AxError::NotConnected) if not connected. - pub fn local_addr(&self) -> AxResult { - match self.get_state() { - STATE_CONNECTED | STATE_LISTENING => { - Ok(SocketAddr::from(unsafe { self.local_addr.get().read() })) - } - _ => Err(AxError::NotConnected), - } - } - - /// Returns the remote address and port, or - /// [`Err(NotConnected)`](AxError::NotConnected) if not connected. - pub fn peer_addr(&self) -> AxResult { - match self.get_state() { - STATE_CONNECTED | STATE_LISTENING => { - Ok(SocketAddr::from(unsafe { self.peer_addr.get().read() })) - } - _ => Err(AxError::NotConnected), - } - } - - /// Returns whether this socket is in nonblocking mode. - #[inline] - pub fn is_nonblocking(&self) -> bool { - self.nonblock.load(Ordering::Acquire) - } - - /// Moves this TCP stream into or out of nonblocking mode. - /// - /// This will result in `read`, `write`, `recv` and `send` operations - /// becoming nonblocking, i.e., immediately returning from their calls. - /// If the IO operation is successful, `Ok` is returned and no further - /// action is required. If the IO operation could not be completed and needs - /// to be retried, an error with kind [`Err(WouldBlock)`](AxError::WouldBlock) is - /// returned. - #[inline] - pub fn set_nonblocking(&self, nonblocking: bool) { - self.nonblock.store(nonblocking, Ordering::Release); - } - - /// Returns whether SO_REUSEADDR behavior is enabled. - #[inline] - pub fn is_reuse_addr(&self) -> bool { - self.reuse_addr.load(Ordering::Acquire) - } - - /// Enables or disables SO_REUSEADDR behavior. - #[inline] - pub fn set_reuseaddr(&self, reuse: bool) { - self.reuse_addr.store(reuse, Ordering::Release); - } - - /// Connects to the given address and port. - /// - /// The local port is generated automatically. - pub fn connect(&self, remote_addr: SocketAddr) -> AxResult { - self.update_state(STATE_CLOSED, STATE_CONNECTING, || { - // SAFETY: no other threads can read or write these fields. - let handle = unsafe { self.handle.get().read() } - .unwrap_or_else(|| SOCKET_SET.add(SocketSetWrapper::new_tcp_socket())); - - // TODO: check remote addr unreachable - let bound_endpoint = self.bound_endpoint()?; - let mut iface = ETH0.iface.lock(); - let (local_endpoint, remote_endpoint) = SOCKET_SET - .with_socket_mut::(handle, |socket| { - socket - .connect(iface.context(), remote_addr, bound_endpoint) - .or_else(|e| match e { - ConnectError::InvalidState => { - ax_err!(BadState, "socket connect() failed") - } - ConnectError::Unaddressable => { - ax_err!(ConnectionRefused, "socket connect() failed") - } - })?; - AxResult::Ok(( - socket.local_endpoint().unwrap(), - socket.remote_endpoint().unwrap(), - )) - })?; - unsafe { - // SAFETY: no other threads can read or write these fields as we - // have changed the state to `BUSY`. - self.local_addr.get().write(local_endpoint); - self.peer_addr.get().write(remote_endpoint); - self.handle.get().write(Some(handle)); - } - Ok(()) - }) - .unwrap_or_else(|_| ax_err!(AlreadyExists, "socket connect() failed: already connected"))?; // EISCONN - - // Here our state must be `CONNECTING`, and only one thread can run here. - if self.is_nonblocking() { - Err(AxError::WouldBlock) - } else { - self.block_on(|| { - let PollState { writable, .. } = self.poll_connect()?; - if !writable { - Err(AxError::WouldBlock) - } else if self.get_state() == STATE_CONNECTED { - Ok(()) - } else { - ax_err!(ConnectionRefused, "socket connect() failed") - } - }) - } - } - - /// Binds an unbound socket to the given address and port. - /// - /// If the given port is 0, it generates one automatically. - /// - /// It must be called before [`listen`](Self::listen) and - /// [`accept`](Self::accept). - pub fn bind(&self, mut local_addr: SocketAddr) -> AxResult { - self.update_state(STATE_CLOSED, STATE_CLOSED, || { - // TODO: check addr is available - if local_addr.port() == 0 { - local_addr.set_port(get_ephemeral_port()?); - } - // SAFETY: no other threads can read or write `self.local_addr` as we - // have changed the state to `BUSY`. - unsafe { - let old = self.local_addr.get().read(); - if old != UNSPECIFIED_ENDPOINT { - return ax_err!(InvalidInput, "socket bind() failed: already bound"); - } - self.local_addr.get().write(IpEndpoint::from(local_addr)); - } - Ok(()) - }) - .unwrap_or_else(|_| ax_err!(InvalidInput, "socket bind() failed: already bound")) - } - - /// Starts listening on the bound address and port. - /// - /// It must be called after [`bind`](Self::bind) and before - /// [`accept`](Self::accept). - pub fn listen(&self) -> AxResult { - self.update_state(STATE_CLOSED, STATE_LISTENING, || { - let bound_endpoint = self.bound_endpoint()?; - unsafe { - (*self.local_addr.get()).port = bound_endpoint.port; - } - LISTEN_TABLE.listen(bound_endpoint)?; - debug!("TCP socket listening on {bound_endpoint}"); - Ok(()) - }) - .unwrap_or(Ok(())) // ignore simultaneous `listen`s. - } - - /// Accepts a new connection. - /// - /// This function will block the calling thread until a new TCP connection - /// is established. When established, a new [`TcpSocket`] is returned. - /// - /// It must be called after [`bind`](Self::bind) and [`listen`](Self::listen). - pub fn accept(&self) -> AxResult { - if !self.is_listening() { - return ax_err!(InvalidInput, "socket accept() failed: not listen"); - } - - // SAFETY: `self.local_addr` should be initialized after `bind()`. - let local_port = unsafe { self.local_addr.get().read().port }; - self.block_on(|| { - let (handle, (local_addr, peer_addr)) = LISTEN_TABLE.accept(local_port)?; - debug!("TCP socket accepted a new connection {peer_addr}"); - Ok(TcpSocket::new_connected(handle, local_addr, peer_addr)) - }) - } - - /// Close the connection. - pub fn shutdown(&self) -> AxResult { - // stream - self.update_state(STATE_CONNECTED, STATE_CLOSED, || { - // SAFETY: `self.handle` should be initialized in a connected socket, and - // no other threads can read or write it. - let handle = unsafe { self.handle.get().read().unwrap() }; - SOCKET_SET.with_socket_mut::(handle, |socket| { - debug!("TCP socket {handle}: shutting down"); - socket.close(); - }); - unsafe { self.local_addr.get().write(UNSPECIFIED_ENDPOINT) }; // clear bound address - SOCKET_SET.poll_interfaces(); - Ok(()) - }) - .unwrap_or(Ok(()))?; - - // listener - self.update_state(STATE_LISTENING, STATE_CLOSED, || { - // SAFETY: `self.local_addr` should be initialized in a listening socket, - // and no other threads can read or write it. - let local_port = unsafe { self.local_addr.get().read().port }; - unsafe { self.local_addr.get().write(UNSPECIFIED_ENDPOINT) }; // clear bound address - LISTEN_TABLE.unlisten(local_port); - SOCKET_SET.poll_interfaces(); - Ok(()) - }) - .unwrap_or(Ok(()))?; - - // ignore for other states - Ok(()) - } - - /// Receives data from the socket, stores it in the given buffer. - pub fn recv(&self, buf: &mut [u8]) -> AxResult { - if self.is_connecting() { - return Err(AxError::WouldBlock); - } else if !self.is_connected() { - return ax_err!(NotConnected, "socket recv() failed"); - } - - // SAFETY: `self.handle` should be initialized in a connected socket. - let handle = unsafe { self.handle.get().read().unwrap() }; - self.block_on(|| { - SOCKET_SET.with_socket_mut::(handle, |socket| { - if !socket.is_active() { - // not open - ax_err!(ConnectionRefused, "socket recv() failed") - } else if !socket.may_recv() { - // connection closed - Ok(0) - } else if socket.recv_queue() > 0 { - // data available - // TODO: use socket.recv(|buf| {...}) - let len = socket - .recv_slice(buf) - .map_err(|_| ax_err_type!(BadState, "socket recv() failed"))?; - Ok(len) - } else { - // no more data - Err(AxError::WouldBlock) - } - }) - }) - } - - /// Transmits data in the given buffer. - pub fn send(&self, buf: &[u8]) -> AxResult { - if self.is_connecting() { - return Err(AxError::WouldBlock); - } else if !self.is_connected() { - return ax_err!(NotConnected, "socket send() failed"); - } - - // SAFETY: `self.handle` should be initialized in a connected socket. - let handle = unsafe { self.handle.get().read().unwrap() }; - self.block_on(|| { - SOCKET_SET.with_socket_mut::(handle, |socket| { - if !socket.is_active() || !socket.may_send() { - // closed by remote - ax_err!(ConnectionReset, "socket send() failed") - } else if socket.can_send() { - // connected, and the tx buffer is not full - // TODO: use socket.send(|buf| {...}) - let len = socket - .send_slice(buf) - .map_err(|_| ax_err_type!(BadState, "socket send() failed"))?; - Ok(len) - } else { - // tx buffer is full - Err(AxError::WouldBlock) - } - }) - }) - } - - /// Whether the socket is readable or writable. - pub fn poll(&self) -> AxResult { - match self.get_state() { - STATE_CONNECTING => self.poll_connect(), - STATE_CONNECTED => self.poll_stream(), - STATE_LISTENING => self.poll_listener(), - _ => Ok(PollState { - readable: false, - writable: false, - readiness_version: 0, - }), - } - } - - /// Checks if Nagle's algorithm is enabled for this TCP socket. - pub fn nodelay(&self) -> AxResult { - if let Some(h) = unsafe { self.handle.get().read() } { - Ok(SOCKET_SET.with_socket::(h, |socket| socket.nagle_enabled())) - } else { - ax_err!(NotConnected, "socket is not connected") - } - } - - /// Enables or disables Nagle's algorithm for this TCP socket. - pub fn set_nodelay(&self, enabled: bool) -> AxResult<()> { - if let Some(h) = unsafe { self.handle.get().read() } { - SOCKET_SET.with_socket_mut::(h, |socket| { - socket.set_nagle_enabled(enabled); - }); - Ok(()) - } else { - ax_err!(NotConnected, "socket is not connected") - } - } - - /// Returns the maximum capacity of the receive buffer in bytes. - pub fn recv_capacity(&self) -> AxResult { - if let Some(h) = unsafe { self.handle.get().read() } { - Ok(SOCKET_SET.with_socket::(h, |socket| socket.recv_capacity())) - } else { - ax_err!(NotConnected, "socket is not connected") - } - } - - /// Returns the maximum capacity of the send buffer in bytes. - pub fn send_capacity(&self) -> AxResult { - if let Some(h) = unsafe { self.handle.get().read() } { - Ok(SOCKET_SET.with_socket::(h, |socket| socket.send_capacity())) - } else { - ax_err!(NotConnected, "socket is not connected") - } - } -} - -/// Private methods -impl TcpSocket { - #[inline] - fn get_state(&self) -> u8 { - self.state.load(Ordering::Acquire) - } - - #[inline] - fn set_state(&self, state: u8) { - self.state.store(state, Ordering::Release); - } - - /// Update the state of the socket atomically. - /// - /// If the current state is `expect`, it first changes the state to `STATE_BUSY`, - /// then calls the given function. If the function returns `Ok`, it changes the - /// state to `new`, otherwise it changes the state back to `expect`. - /// - /// It returns `Ok` if the current state is `expect`, otherwise it returns - /// the current state in `Err`. - fn update_state(&self, expect: u8, new: u8, f: F) -> Result, u8> - where - F: FnOnce() -> AxResult, - { - match self - .state - .compare_exchange(expect, STATE_BUSY, Ordering::Acquire, Ordering::Acquire) - { - Ok(_) => { - let res = f(); - if res.is_ok() { - self.set_state(new); - } else { - self.set_state(expect); - } - Ok(res) - } - Err(old) => Err(old), - } - } - - #[inline] - fn is_connecting(&self) -> bool { - self.get_state() == STATE_CONNECTING - } - - #[inline] - fn is_connected(&self) -> bool { - self.get_state() == STATE_CONNECTED - } - - #[inline] - fn is_listening(&self) -> bool { - self.get_state() == STATE_LISTENING - } - - fn bound_endpoint(&self) -> AxResult { - // SAFETY: no other threads can read or write `self.local_addr`. - let local_addr = unsafe { self.local_addr.get().read() }; - let port = if local_addr.port != 0 { - local_addr.port - } else { - get_ephemeral_port()? - }; - assert_ne!(port, 0); - let addr = if !local_addr.addr.is_unspecified() { - Some(local_addr.addr) - } else { - None - }; - Ok(IpListenEndpoint { addr, port }) - } - - fn poll_connect(&self) -> AxResult { - // SAFETY: `self.handle` should be initialized above. - let handle = unsafe { self.handle.get().read().unwrap() }; - let writable = - SOCKET_SET.with_socket::(handle, |socket| match socket.state() { - State::SynSent => false, // wait for connection - State::Established => { - self.set_state(STATE_CONNECTED); // connected - debug!( - "TCP socket {}: connected to {}", - handle, - socket.remote_endpoint().unwrap(), - ); - true - } - _ => { - unsafe { - self.local_addr.get().write(UNSPECIFIED_ENDPOINT); - self.peer_addr.get().write(UNSPECIFIED_ENDPOINT); - } - self.set_state(STATE_CLOSED); // connection failed - true - } - }); - Ok(PollState { - readable: false, - writable, - readiness_version: 0, - }) - } - - fn poll_stream(&self) -> AxResult { - // SAFETY: `self.handle` should be initialized in a connected socket. - let handle = unsafe { self.handle.get().read().unwrap() }; - SOCKET_SET.with_socket::(handle, |socket| { - Ok(PollState { - readable: !socket.may_recv() || socket.can_recv(), - writable: !socket.may_send() || socket.can_send(), - readiness_version: 0, - }) - }) - } - - fn poll_listener(&self) -> AxResult { - // SAFETY: `self.local_addr` should be initialized in a listening socket. - let local_addr = unsafe { self.local_addr.get().read() }; - Ok(PollState { - readable: LISTEN_TABLE.can_accept(local_addr.port)?, - writable: false, - readiness_version: 0, - }) - } - - /// Block the current thread until the given function completes or fails. - /// - /// If the socket is non-blocking, it calls the function once and returns - /// immediately. Otherwise, it may call the function multiple times if it - /// returns [`Err(WouldBlock)`](AxError::WouldBlock). - fn block_on(&self, mut f: F) -> AxResult - where - F: FnMut() -> AxResult, - { - if self.is_nonblocking() { - f() - } else { - loop { - SOCKET_SET.poll_interfaces(); - match f() { - Ok(t) => return Ok(t), - Err(AxError::WouldBlock) => ax_task::yield_now(), - Err(e) => return Err(e), - } - } - } - } -} - -impl Drop for TcpSocket { - fn drop(&mut self) { - self.shutdown().ok(); - // Safe because we have mut reference to `self`. - if let Some(handle) = unsafe { self.handle.get().read() } { - SOCKET_SET.remove(handle); - } - } -} - -fn get_ephemeral_port() -> AxResult { - const PORT_START: u16 = 0xc000; - const PORT_END: u16 = 0xffff; - static CURR: Mutex = Mutex::new(PORT_START); - - let mut curr = CURR.lock(); - let mut tries = 0; - // TODO: more robust - while tries <= PORT_END - PORT_START { - let port = *curr; - if *curr == PORT_END { - *curr = PORT_START; - } else { - *curr += 1; - } - if LISTEN_TABLE.can_listen(port) { - return Ok(port); - } - tries += 1; - } - ax_err!(AddrInUse, "no available ports!") -} diff --git a/os/arceos/modules/axnet/src/smoltcp_impl/udp.rs b/os/arceos/modules/axnet/src/smoltcp_impl/udp.rs deleted file mode 100644 index 4f47c6e5fe..0000000000 --- a/os/arceos/modules/axnet/src/smoltcp_impl/udp.rs +++ /dev/null @@ -1,299 +0,0 @@ -use core::{ - net::SocketAddr, - sync::atomic::{AtomicBool, Ordering}, -}; - -use ax_errno::{AxError, AxResult, ax_err, ax_err_type}; -use ax_io::PollState; -use ax_sync::Mutex; -use smoltcp::{ - iface::SocketHandle, - socket::udp::{self, BindError, SendError}, - wire::{IpEndpoint, IpListenEndpoint}, -}; -use spin::RwLock; - -use super::{SOCKET_SET, SocketSetWrapper, addr::UNSPECIFIED_ENDPOINT}; - -/// A UDP socket that provides POSIX-like APIs. -pub struct UdpSocket { - handle: SocketHandle, - local_addr: RwLock>, - peer_addr: RwLock>, - nonblock: AtomicBool, -} - -impl UdpSocket { - /// Creates a new UDP socket. - #[allow(clippy::new_without_default)] - pub fn new() -> Self { - let socket = SocketSetWrapper::new_udp_socket(); - let handle = SOCKET_SET.add(socket); - Self { - handle, - local_addr: RwLock::new(None), - peer_addr: RwLock::new(None), - nonblock: AtomicBool::new(false), - } - } - - /// Returns the local address and port, or - /// [`Err(NotConnected)`](AxError::NotConnected) if not connected. - pub fn local_addr(&self) -> AxResult { - match self.local_addr.try_read() { - Some(addr) => addr.map(Into::into).ok_or(AxError::NotConnected), - None => Err(AxError::NotConnected), - } - } - - /// Returns the remote address and port, or - /// [`Err(NotConnected)`](AxError::NotConnected) if not connected. - pub fn peer_addr(&self) -> AxResult { - self.remote_endpoint().map(Into::into) - } - - /// Returns whether this socket is in nonblocking mode. - #[inline] - pub fn is_nonblocking(&self) -> bool { - self.nonblock.load(Ordering::Acquire) - } - - /// Moves this UDP socket into or out of nonblocking mode. - /// - /// This will result in `recv`, `recv_from`, `send`, and `send_to` - /// operations becoming nonblocking, i.e., immediately returning from their - /// calls. If the IO operation is successful, `Ok` is returned and no - /// further action is required. If the IO operation could not be completed - /// and needs to be retried, an error with kind - /// [`Err(WouldBlock)`](AxError::WouldBlock) is returned. - #[inline] - pub fn set_nonblocking(&self, nonblocking: bool) { - self.nonblock.store(nonblocking, Ordering::Release); - } - - /// Binds an unbound socket to the given address and port. - /// - /// It must be called before [`send_to`](Self::send_to) and - /// [`recv_from`](Self::recv_from). - pub fn bind(&self, mut local_addr: SocketAddr) -> AxResult { - let mut self_local_addr = self.local_addr.write(); - - if local_addr.port() == 0 { - local_addr.set_port(get_ephemeral_port()?); - } - if self_local_addr.is_some() { - return ax_err!(InvalidInput, "socket bind() failed: already bound"); - } - - let local_endpoint = IpEndpoint::from(local_addr); - let endpoint = IpListenEndpoint { - addr: (!local_endpoint.addr.is_unspecified()).then_some(local_endpoint.addr), - port: local_endpoint.port, - }; - SOCKET_SET.with_socket_mut::(self.handle, |socket| { - socket.bind(endpoint).or_else(|e| match e { - BindError::InvalidState => ax_err!(AlreadyExists, "socket bind() failed"), - BindError::Unaddressable => ax_err!(InvalidInput, "socket bind() failed"), - }) - })?; - - *self_local_addr = Some(local_endpoint); - debug!("UDP socket {}: bound on {}", self.handle, endpoint); - Ok(()) - } - - /// Sends data on the socket to the given address. On success, returns the - /// number of bytes written. - pub fn send_to(&self, buf: &[u8], remote_addr: SocketAddr) -> AxResult { - if remote_addr.port() == 0 || remote_addr.ip().is_unspecified() { - return ax_err!(InvalidInput, "socket send_to() failed: invalid address"); - } - self.send_impl(buf, IpEndpoint::from(remote_addr)) - } - - /// Receives a single datagram message on the socket. On success, returns - /// the number of bytes read and the origin. - pub fn recv_from(&self, buf: &mut [u8]) -> AxResult<(usize, SocketAddr)> { - self.recv_impl(|socket| match socket.recv_slice(buf) { - Ok((len, meta)) => Ok((len, SocketAddr::from(meta.endpoint))), - Err(_) => ax_err!(BadState, "socket recv_from() failed"), - }) - } - - /// Receives a single datagram message on the socket, without removing it from - /// the queue. On success, returns the number of bytes read and the origin. - pub fn peek_from(&self, buf: &mut [u8]) -> AxResult<(usize, SocketAddr)> { - self.recv_impl(|socket| match socket.peek_slice(buf) { - Ok((len, meta)) => Ok((len, SocketAddr::from(meta.endpoint))), - Err(_) => ax_err!(BadState, "socket recv_from() failed"), - }) - } - - /// Connects this UDP socket to a remote address, allowing the `send` and - /// `recv` to be used to send data and also applies filters to only receive - /// data from the specified address. - /// - /// The local port will be generated automatically if the socket is not bound. - /// It must be called before [`send`](Self::send) and - /// [`recv`](Self::recv). - pub fn connect(&self, addr: SocketAddr) -> AxResult { - let mut self_peer_addr = self.peer_addr.write(); - - if self.local_addr.read().is_none() { - self.bind(SocketAddr::from(UNSPECIFIED_ENDPOINT))?; - } - - *self_peer_addr = Some(IpEndpoint::from(addr)); - debug!("UDP socket {}: connected to {}", self.handle, addr); - Ok(()) - } - - /// Sends data on the socket to the remote address to which it is connected. - pub fn send(&self, buf: &[u8]) -> AxResult { - let remote_endpoint = self.remote_endpoint()?; - self.send_impl(buf, remote_endpoint) - } - - /// Receives a single datagram message on the socket from the remote address - /// to which it is connected. On success, returns the number of bytes read. - pub fn recv(&self, buf: &mut [u8]) -> AxResult { - let remote_endpoint = self.remote_endpoint()?; - self.recv_impl(|socket| { - let (len, meta) = socket - .recv_slice(buf) - .map_err(|_| ax_err_type!(BadState, "socket recv() failed"))?; - if !remote_endpoint.addr.is_unspecified() && remote_endpoint.addr != meta.endpoint.addr - { - return Err(AxError::WouldBlock); - } - if remote_endpoint.port != 0 && remote_endpoint.port != meta.endpoint.port { - return Err(AxError::WouldBlock); - } - Ok(len) - }) - } - - /// Close the socket. - pub fn shutdown(&self) -> AxResult { - SOCKET_SET.with_socket_mut::(self.handle, |socket| { - debug!("UDP socket {}: shutting down", self.handle); - socket.close(); - }); - SOCKET_SET.poll_interfaces(); - Ok(()) - } - - /// Whether the socket is readable or writable. - pub fn poll(&self) -> AxResult { - if self.local_addr.read().is_none() { - return Ok(PollState { - readable: false, - writable: false, - readiness_version: 0, - }); - } - SOCKET_SET.with_socket_mut::(self.handle, |socket| { - Ok(PollState { - readable: socket.can_recv(), - writable: socket.can_send(), - readiness_version: 0, - }) - }) - } -} - -/// Private methods -impl UdpSocket { - fn remote_endpoint(&self) -> AxResult { - match self.peer_addr.try_read() { - Some(addr) => addr.ok_or(AxError::NotConnected), - None => Err(AxError::NotConnected), - } - } - - fn send_impl(&self, buf: &[u8], remote_endpoint: IpEndpoint) -> AxResult { - if self.local_addr.read().is_none() { - return ax_err!(NotConnected, "socket send() failed"); - } - - self.block_on(|| { - SOCKET_SET.with_socket_mut::(self.handle, |socket| { - if socket.can_send() { - socket - .send_slice(buf, remote_endpoint) - .map_err(|e| match e { - SendError::BufferFull => AxError::WouldBlock, - SendError::Unaddressable => { - ax_err_type!(ConnectionRefused, "socket send() failed") - } - })?; - Ok(buf.len()) - } else { - // tx buffer is full - Err(AxError::WouldBlock) - } - }) - }) - } - - fn recv_impl(&self, mut op: F) -> AxResult - where - F: FnMut(&mut udp::Socket) -> AxResult, - { - if self.local_addr.read().is_none() { - return ax_err!(NotConnected, "socket send() failed"); - } - - self.block_on(|| { - SOCKET_SET.with_socket_mut::(self.handle, |socket| { - if socket.can_recv() { - // data available - op(socket) - } else { - // no more data - Err(AxError::WouldBlock) - } - }) - }) - } - - fn block_on(&self, mut f: F) -> AxResult - where - F: FnMut() -> AxResult, - { - if self.is_nonblocking() { - f() - } else { - loop { - SOCKET_SET.poll_interfaces(); - match f() { - Ok(t) => return Ok(t), - Err(AxError::WouldBlock) => ax_task::yield_now(), - Err(e) => return Err(e), - } - } - } - } -} - -impl Drop for UdpSocket { - fn drop(&mut self) { - self.shutdown().ok(); - SOCKET_SET.remove(self.handle); - } -} - -fn get_ephemeral_port() -> AxResult { - const PORT_START: u16 = 0xc000; - const PORT_END: u16 = 0xffff; - static CURR: Mutex = Mutex::new(PORT_START); - let mut curr = CURR.lock(); - - let port = *curr; - if *curr == PORT_END { - *curr = PORT_START; - } else { - *curr += 1; - } - Ok(port) -} diff --git a/os/arceos/modules/axruntime/CHANGELOG.md b/os/arceos/modules/axruntime/CHANGELOG.md index 457724eed2..89d2cb4294 100644 --- a/os/arceos/modules/axruntime/CHANGELOG.md +++ b/os/arceos/modules/axruntime/CHANGELOG.md @@ -51,13 +51,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Other -- updated the following local packages: ax-alloc, ax-driver, ax-task, ax-net-ng, axklib, ax-hal, ax-mm, ax-display, ax-fs, ax-fs-ng, ax-input, ax-ipi, ax-net +- updated the following local packages: ax-alloc, ax-driver, ax-task, ax-net, axklib, ax-hal, ax-mm, ax-display, ax-fs, ax-fs-ng, ax-input, ax-ipi, ax-net ## [0.5.14](https://github.com/rcore-os/tgoskits/compare/ax-runtime-v0.5.13...ax-runtime-v0.5.14) - 2026-05-15 ### Other -- updated the following local packages: axbacktrace, ax-alloc, ax-config, ax-hal, ax-mm, ax-fs, ax-fs-ng, ax-log, ax-net, ax-net-ng, ax-plat, ax-driver, ax-task, ax-display, ax-input, ax-ipi +- updated the following local packages: axbacktrace, ax-alloc, ax-config, ax-hal, ax-mm, ax-fs, ax-fs-ng, ax-log, ax-net, ax-net, ax-plat, ax-driver, ax-task, ax-display, ax-input, ax-ipi ## [0.5.12](https://github.com/rcore-os/tgoskits/compare/ax-runtime-v0.5.11...ax-runtime-v0.5.12) - 2026-04-27 diff --git a/os/arceos/modules/axruntime/Cargo.toml b/os/arceos/modules/axruntime/Cargo.toml index c8a5afdba8..c50cb2bbeb 100644 --- a/os/arceos/modules/axruntime/Cargo.toml +++ b/os/arceos/modules/axruntime/Cargo.toml @@ -57,9 +57,8 @@ fs-ng = [ fs-ng-ext4 = ["fs-ng", "ax-fs-ng/ext4"] fs-ng-fat = ["fs-ng", "ax-fs-ng/fat"] input = ["dep:ax-input", "ax-driver/input"] -net = ["dep:ax-net", "ax-driver/net"] -net-ng = ["dep:ax-net-ng", "dep:rd-net", "dep:spin", "dep:axklib", "ax-driver/net"] -vsock = ["net-ng", "ax-net-ng/vsock", "ax-driver/vsock"] +net = ["dep:ax-net", "dep:rd-net", "dep:spin", "dep:axklib", "ax-driver/net"] +vsock = ["net", "ax-net/vsock", "ax-driver/vsock"] [dependencies] ax-alloc = {workspace = true} @@ -79,7 +78,6 @@ ax-log = {workspace = true} ax-memory-addr = {workspace = true} ax-mm = {workspace = true, optional = true} ax-net = {workspace = true, optional = true} -ax-net-ng = {workspace = true, optional = true} ax-percpu = {workspace = true, optional = true} ax-plat = {workspace = true} ax-task = {workspace = true, optional = true} diff --git a/os/arceos/modules/axruntime/src/devices.rs b/os/arceos/modules/axruntime/src/devices.rs index 9f9ded95df..f53ecbc50e 100644 --- a/os/arceos/modules/axruntime/src/devices.rs +++ b/os/arceos/modules/axruntime/src/devices.rs @@ -89,22 +89,17 @@ pub(crate) fn init_static_input() { ax_input::init_input(devices); } -#[cfg(all(feature = "net", not(feature = "net-ng"), feature = "plat-dyn"))] +#[cfg(all(feature = "net", feature = "plat-dyn"))] pub(crate) fn init_dyn_net() { ax_net::init_network(take_dyn_net_drivers()); } -#[cfg(all(feature = "net", not(feature = "net-ng"), not(feature = "plat-dyn")))] +#[cfg(all(feature = "net", not(feature = "plat-dyn")))] pub(crate) fn init_static_net() { ax_net::init_network(take_static_net_drivers()); } -#[cfg(all(feature = "net-ng", feature = "plat-dyn"))] -pub(crate) fn init_dyn_net_ng() { - ax_net_ng::init_network(take_dyn_net_ng_drivers()); -} - -#[cfg(all(feature = "net", not(feature = "net-ng"), not(feature = "plat-dyn")))] +#[cfg(all(feature = "net", not(feature = "plat-dyn")))] pub(crate) fn take_static_net_drivers() -> alloc::vec::Vec> { let mut devices = alloc::vec::Vec::new(); @@ -119,41 +114,25 @@ pub(crate) fn take_static_net_drivers() devices } -#[cfg(all(feature = "net-ng", not(feature = "plat-dyn")))] -pub(crate) fn take_static_net_ng_drivers() --> alloc::vec::Vec> { - let mut devices = alloc::vec::Vec::new(); - for dev in rdrive::get_list::() { - let (net, name, irq_num) = ax_driver::net::take_rd_net_device(dev) - .unwrap_or_else(|err| panic!("failed to open static net device: {err:?}")); - let driver = ax_net_ng::RdNetDriver::new(name, net, irq_num) - .unwrap_or_else(|err| panic!("failed to adapt static net device: {err:?}")); - devices.push( - alloc::boxed::Box::new(driver) as alloc::boxed::Box - ); - } - devices -} - #[cfg(all(feature = "vsock", feature = "plat-dyn"))] pub(crate) fn init_dyn_vsock() { if !rdrive::is_initialized() { - ax_net_ng::init_vsock(alloc::vec::Vec::new()); + ax_net::init_vsock(alloc::vec::Vec::new()); return; } let devices = ax_driver::vsock::take_vsock_devices() .unwrap_or_else(|err| panic!("failed to open vsock devices: {err:?}")); - ax_net_ng::init_vsock(devices); + ax_net::init_vsock(devices); } #[cfg(all(feature = "vsock", not(feature = "plat-dyn")))] pub(crate) fn init_static_vsock() { let devices = ax_driver::vsock::take_vsock_devices() .unwrap_or_else(|err| panic!("failed to open static vsock devices: {err:?}")); - ax_net_ng::init_vsock(devices); + ax_net::init_vsock(devices); } -#[cfg(all(feature = "net", not(feature = "net-ng"), feature = "plat-dyn"))] +#[cfg(all(feature = "net", feature = "plat-dyn"))] fn take_dyn_net_drivers() -> alloc::vec::Vec> { if !rdrive::is_initialized() { return alloc::vec::Vec::new(); @@ -170,24 +149,6 @@ fn take_dyn_net_drivers() -> alloc::vec::Vec alloc::vec::Vec> { - if !rdrive::is_initialized() { - return alloc::vec::Vec::new(); - } - let mut devices = alloc::vec::Vec::new(); - for dev in rdrive::get_list::() { - let (net, name, irq_num) = ax_driver::net::take_rd_net_device(dev) - .unwrap_or_else(|err| panic!("failed to open net device: {err:?}")); - let driver = ax_net_ng::RdNetDriver::new(name, net, irq_num) - .unwrap_or_else(|err| panic!("failed to adapt net device: {err:?}")); - devices.push( - alloc::boxed::Box::new(driver) as alloc::boxed::Box - ); - } - devices -} - #[cfg(all(feature = "fs", not(feature = "fs-ng")))] struct FsBlockDevice { _irq: Option, diff --git a/os/arceos/modules/axruntime/src/lib.rs b/os/arceos/modules/axruntime/src/lib.rs index 0fc3a1bf99..63e305c150 100644 --- a/os/arceos/modules/axruntime/src/lib.rs +++ b/os/arceos/modules/axruntime/src/lib.rs @@ -304,11 +304,7 @@ pub fn rust_main(cpu_id: usize, arg: usize) -> ! { devices::init_static_input(); cfg_if::cfg_if! { - if #[cfg(all(feature = "net-ng", feature = "plat-dyn"))] { - devices::init_dyn_net_ng(); - } else if #[cfg(all(feature = "net-ng", not(feature = "plat-dyn")))] { - ax_net_ng::init_network(devices::take_static_net_ng_drivers()); - } else if #[cfg(all(feature = "net", feature = "plat-dyn"))] { + if #[cfg(all(feature = "net", feature = "plat-dyn"))] { devices::init_dyn_net(); } else if #[cfg(all(feature = "net", not(feature = "plat-dyn")))] { devices::init_static_net(); diff --git a/os/arceos/tools/bwbench_client/README.md b/os/arceos/tools/bwbench_client/README.md index 0d447ccc0f..b9d0a982fe 100644 --- a/os/arceos/tools/bwbench_client/README.md +++ b/os/arceos/tools/bwbench_client/README.md @@ -11,13 +11,9 @@ sudo ./target/release/bwbench_client [sender|receiver] [interface] By reading the source code, you can control the behavior of the benchmark by modifying constants such as `MAX_BYTES`. -In arceos: - -```shell -make A=apps/net/bwbench LOG=info NET=y run -``` - -By default, arceos `bebench` uses `bench_transmit`. You can uncomment the line and add `bench_receive`, but please note that currently only one of either `bench_transmit` or `bench_receive` is allowed to be enabled. +The matching ArceOS-side benchmark entry is no longer part of the core `ax-net` +public API. If a guest-side raw-frame benchmark is needed, keep it as a +separate app or test-suit case instead of wiring it back into the network stack. ## Example: benchmark bandwidth of QEMU tap netdev @@ -30,8 +26,5 @@ sudo ./scripts/net/qemu-tap-ifup.sh enp8s0 sudo ./target/release/bwbench_client [sender|receiver] tap0 ``` -In arceos: - -```shell -make A=apps/net/bwbench LOG=info NET=y NET_DEV=tap run -``` +On the guest side, run a dedicated raw-frame benchmark app or test case that +matches the selected sender/receiver mode. diff --git a/p.md b/p.md new file mode 100644 index 0000000000..e7dd2ee1ee --- /dev/null +++ b/p.md @@ -0,0 +1,333 @@ +# 统一网络模块为 `ax-net` 的方案 + +## 1. 背景 + +当前仓库存在两套网络 crate: + +- `ax-net`:老一代 ArceOS 网络模块,提供 `TcpSocket`、`UdpSocket`、`dns_query`、`poll_interfaces`、`bench_*`,主要被 `ax-api`、`ax-posix-api`、`axstd`、`axlibc` 使用。 +- `ax-net-ng`:实际更完整的新网络栈,支持 TCP、UDP、raw ICMP、Unix domain socket、vsock、loopback、router、DHCP、socket options、poll/waker,StarryOS 已经通过依赖别名 `axnet = { package = "ax-net-ng" }` 使用它。 + +当前问题: + +- `ax-runtime`、`ax-feat` 同时保留 `net` 和 `net-ng` 两套 feature/初始化路径。 +- `ax-net` 又依赖 `ax-net-ng` 的驱动适配类型,形成“旧 API 壳 + 新组件片段”的混合状态。 +- StarryOS 的对外依赖名是 `axnet`,但真实 package 是 `ax-net-ng`,命名和架构不一致。 +- ArceOS 公共 API 仍走旧 `ax-net`,无法获得 `ax-net-ng` 的完整 socket 能力。 + +目标: + +- 仅保留 `ax-net` 作为唯一网络 crate/package。 +- 在仓库根目录新增 `net/ax-net`,以当前 `ax-net-ng` 为主体实现统一网络栈,并以清晰、统一的新 API 作为唯一对外接口。 +- 移除 `os/arceos/modules/axnet` 和 `os/arceos/modules/axnet-ng` 两个 ArceOS-local 网络 crate,删除对应 workspace dependency、feature 路径和 runtime 分支。 +- 统一 ArceOS 与 StarryOS 的网络能力入口,降低重复实现和 feature 组合风险。 +- 将网络栈从 ArceOS modules 目录中提升为根目录通用组件,使其成为 ArceOS、StarryOS 以及后续其他系统可复用的统一 net 支持。 +- 不保留旧 `ax-net` 的兼容 wrapper、旧 feature alias 或旧 benchmark stub;所有调用方在本轮同步迁移到统一 API。 + +## 2. 修改方案 + +### 2.1 总体架构 + +**目录位置**:`net/ax-net/` +- 在仓库根目录新增 `net/` 顶层目录,其中放置 `ax-net/` 网络模块 +- 理由:网络栈作为跨 ArceOS、StarryOS、Axvisor 的核心基础设施,足够重要,值得独立的顶层目录 +- 与 `drivers/`、`platforms/`、`components/` 等平级,突出其作为独立网络子系统的地位 + +重构后的 `ax-net` 本身分为五层:设备适配层、协议服务层、socket 抽象层、地址族实现层、公开入口层。 + +```text +net/ax-net + public facade + -> lib.rs + -> init_network / init_vsock / poll_interfaces + -> public socket, option, device, status APIs + + socket abstraction + -> socket.rs: Socket, SocketOps, SocketAddrEx, SendOptions, RecvOptions + -> options.rs: Configurable, GetSocketOption, SetSocketOption + -> general.rs: common nonblocking, timeout, protocol/domain/type state + + address-family implementations + -> tcp.rs + -> udp.rs + -> raw.rs + -> unix/ + -> vsock/ + + protocol service + -> service.rs: smoltcp Interface owner, DHCP, DNS server state, waker registration + -> router.rs: route table, device dispatch, packet rx/tx path + -> listen_table.rs: TCP listen/accept queue + -> wrapper.rs: smoltcp SocketSet access + -> state.rs: socket state transitions + + device adaptation + -> device/driver.rs: rd-net -> ax-net EthernetDriver adapter + -> device/ethernet.rs: Ethernet device implementation + -> device/loopback.rs: loopback device + -> device/vsock.rs: rdif-vsock integration +``` + +落地目录: + +```text +net/ + ax-net/ + Cargo.toml + src/ + lib.rs + device/ + router.rs + service.rs + socket.rs + tcp.rs + udp.rs + raw.rs + unix/ + vsock/ + options.rs + wrapper.rs + listen_table.rs + state.rs +``` + +内部边界: + +- `lib.rs` 只做 facade、初始化入口和必要 re-export,不承载协议状态机逻辑。 +- `socket.rs` 定义跨地址族统一抽象;TCP、UDP、raw、Unix、vsock 都实现同一组 `SocketOps` / `Pollable` / `Configurable` 语义。 +- `service.rs` 和 `router.rs` 是协议服务核心,负责把 smoltcp、路由、设备和 waker 串起来。 +- `device/` 只负责把 `rd-net` / `rdif-vsock` 设备接入网络栈,不包含具体硬件驱动。 +- `router`、`service`、`wrapper`、`listen_table`、`state` 默认 crate-private,避免外部系统绑定内部实现细节。 +- 将当前 `ax-net-ng` 的实现作为 `net/ax-net` 主体。 +- 删除旧 `os/arceos/modules/axnet/src/smoltcp_impl` 的 TCP/UDP/listen table/router/DNS/benchmark 实现。 +- 删除 `os/arceos/modules/axnet` 和 `os/arceos/modules/axnet-ng` 目录,避免 ArceOS modules 下继续存在网络栈实现。 +- 不迁移旧 `ax-net` 的 `smoltcp_impl`、旧 DNS socket wrapper、旧 `bench_transmit()` / `bench_receive()`;需要这些能力的调用方必须改到新 API 或独立工具。 + +### 2.2 依赖关系 + +`ax-net` 依赖的组件: + +```text +ax-net + -> smoltcp TCP/IP 协议栈 + -> axpoll readiness / Pollable / waker 语义 + -> ax-task 阻塞等待、任务调度、DHCP/vsock 后台任务 + -> ax-sync / ax-kspin 锁与同步原语 + -> ax-io Read/Write/IoBuf 抽象 + -> ax-errno AxError / AxResult / LinuxError 映射 + -> ax-config IP、网关、前缀等构建期配置 + -> ax-hal 时间等底层能力 + -> ax-fs-ng / axfs-ng-vfs Unix domain socket 路径绑定 + -> rd-net Ethernet queue/DMA 设备抽象 + -> rdif-vsock 可选,vsock 设备抽象 +``` + +依赖 `ax-net` 的组件: + +```text +ax-runtime + -> ax-net 网络和 vsock 初始化 + +ax-feat + -> ax-net net/vsock feature 装配 + +ax-api + -> ax-net ArceOS Rust API 网络入口 + +ax-posix-api + -> ax-net ArceOS POSIX socket 入口 + +ax-std / ax-libc + -> ax-api / ax-posix-api + -> ax-net 间接使用统一网络栈 + +starry-kernel + -> ax-net Linux syscall socket 底层实现 + +apps / test-suit + -> ax-std / ax-libc / starry-kernel + -> ax-net 间接验证统一网络栈 +``` + +不属于 `ax-net` 依赖方向的内容: + +- `ax-driver` 不依赖 `ax-net`,只负责注册 `rd-net::Net` 和 `rdif-vsock::Interface`。 +- 具体网卡/vsock 驱动位于 `drivers/`,不进入 `net/ax-net`。 +- StarryOS 的 `AF_PACKET`、`AF_NETLINK`、Linux `sockaddr` 编解码、`ioctl(SIOCGIF*)`、syscall errno 细节保留在 `os/StarryOS/`。 +- `os/arceos/modules/axnet`、`os/arceos/modules/axnet-ng` 从 workspace members 和 dependencies 中删除。 + +### 2.3 对外 API 设计 + +统一后的 `ax-net` 对外 API 分为三类:运行时初始化 API、socket API、设备/状态查询 API。 + +运行时初始化 API: + +- `pub fn init_network(net_devs: EthernetDeviceList)`:由 `ax-runtime` 调用,完成 loopback、eth0、router、smoltcp service、DHCP/static IP 初始化。 +- `#[cfg(feature = "vsock")] pub fn init_vsock(vsock_devs: VsockDeviceList)`:由 `ax-runtime` 调用,注册 vsock 设备并启动 vsock 事件处理。 +- `pub fn poll_interfaces()`:推动网络栈收包、发包、协议状态机和 socket readiness 更新;供 runtime、poll/select/epoll 和 OS 适配层显式调用。 + +socket API: + +- `pub mod tcp`,公开 `tcp::TcpSocket`。 +- `pub mod udp`,公开 `udp::UdpSocket`。 +- `pub mod raw`,公开 raw IPv4/ICMP socket 能力。 +- `pub mod unix`,公开 Unix domain socket 地址、stream/dgram transport 与 `UnixSocket`。 +- `#[cfg(feature = "vsock")] pub mod vsock`,公开 vsock 地址、stream transport 与 `VsockSocket`。 +- `pub use socket::{Socket, SocketAddrEx, SocketOps, SendOptions, RecvOptions, SendFlags, RecvFlags, Shutdown, CMsgData}`,作为 StarryOS syscall 层和未来其他 OS 兼容层的统一 socket 抽象。 +- `pub mod options`,公开 `Configurable`、`GetSocketOption`、`SetSocketOption`、`TcpInfo`、`UnixCredentials` 等 socket option 类型。 + +设备和状态查询 API: + +- `pub use device::{EthernetDeviceList, EthernetDriver, NetRxBuffer, NetTxBuffer, NetDeviceError, NetDeviceResult, NetIrqEvents, RdNetDriver}`,供 `ax-runtime` 将 `ax-driver` 暴露的 `rd-net` 设备适配进 `ax-net`。 +- `#[cfg(feature = "vsock")] pub use device::{VsockDevice, VsockDeviceList}`。 +- `pub fn arp_entries() -> Vec`,供 `/proc/net/arp`、诊断工具或系统兼容层查询 ARP 状态。 +- `pub fn dns_query(name: &str) -> AxResult>`,正式 DNS 域名解析 API,供 `ax-api`、`axstd::net::ToSocketAddrs` 和 POSIX `getaddrinfo` 路径使用。 +- `pub fn dns_servers() -> Vec`,查询当前配置的 DNS server 列表,仅供诊断使用。 + +不作为 `ax-net` 对外 API 的内容: + +- `AF_PACKET`、`AF_NETLINK`、Linux `sockaddr` 编解码、`ioctl(SIOCGIF*)`、syscall errno 细节仍属于 StarryOS Linux ABI 层。 +- 具体网卡驱动、PCI/VirtIO 设备探测、DMA mapping 策略仍属于 `drivers/` 和 `ax-driver`。 +- 旧 `ax-net` 的阻塞式 inherent methods、旧 DNS wrapper、旧 benchmark 入口不进入新 `ax-net` 公共 API。 +- `router`、`service`、`wrapper`、`listen_table`、`state` 默认保持 crate-private,除非有明确跨 OS 复用需求。 + +### 2.4 ArceOS 调用方迁移 + +旧 ArceOS 上层直接调用 `TcpSocket` / `UdpSocket` 的 inherent methods。统一后不在 `ax-net` 中保留这套旧方法,而是迁移 ArceOS 调用方使用统一 socket API。 + +迁移原则: + +- `ax-api::net` 从旧 handle wrapper 迁移为基于 `ax_net::{SocketOps, SocketAddrEx, SendOptions, RecvOptions, Shutdown}` 的实现。 +- `ax-posix-api::imp::net` 不再直接依赖旧 `TcpSocket`/`UdpSocket` 方法,改为与 StarryOS 类似的统一 `Socket`/`SocketOps` 调用模型。 +- `axstd::net` 和 `axlibc::net` 保持面向应用的 API 不变,但其底层实现通过 `ax-api` / `ax-posix-api` 迁移到新 `ax-net`。 +- TCP/UDP 阻塞、非阻塞、poll 状态统一由 `Pollable`、`Configurable` 和 `axpoll` 语义提供,不再维护旧轮询式阻塞路径。 +- `ax-api::net::ax_dns_query()` 改为调用 `ax_net::dns_query()`;`dns_query()` 是新 `ax-net` 的正式 DNS API,不是旧 `smoltcp_impl` DNS wrapper 的兼容保留。 + +### 2.5 feature 设计 + +统一后只保留语义主 feature: + +- `ax-feat/net`:启用统一 `ax-net`。 +- `ax-runtime/net`:启用 `dep:ax-net`、`dep:rd-net`、`dep:spin`、`dep:axklib`、`ax-driver/net`。 +- `ax-feat/vsock`:启用 `ax-runtime/vsock`。 +- `ax-runtime/vsock`:启用 `net`、`ax-net/vsock`、`ax-driver/vsock`。 +- `ax-net/vsock`:启用 `dep:rdif-vsock`。 +- `axstd/net`、`axlibc/net`、`ax-api/net`、`ax-posix-api/net`:继续依赖 `ax-feat/net` 和 `ax-net`。 + +处理旧 feature: + +- 彻底删除 `net-ng` feature,不保留 alias、不保留 deprecated 兼容入口。 +- 所有仓库内配置、Cargo.toml、文档、测试统一改为 `net`。 +- 任何残留的 `net-ng` 引用都视为本轮重构必须修复的编译错误。 + +### 2.6 Cargo 与调用方修改 + +Workspace: + +- 新增 workspace member `net/ax-net`。 +- 删除 workspace members `os/arceos/modules/axnet` 和 `os/arceos/modules/axnet-ng`。 +- 将 workspace dependency `ax-net` 改为 `path = "net/ax-net"`。 +- 新增 workspace dependency alias `axnet = { package = "ax-net", path = "net/ax-net", ... }`,供 StarryOS 在不改 `use axnet::...` 的前提下继承统一网络栈。 +- 删除 workspace dependency `ax-net-ng`。 +- `ax-net` 版本可提升到当前 `ax-net-ng` 的版本线或项目约定的新版本。 + +ArceOS: + +- `ax-feat` 删除 `dep:ax-net-ng` 的真实依赖路径。 +- `ax-runtime` 删除 `init_dyn_net_ng`、`take_*_net_ng_drivers` 分支,所有网络初始化走 `ax_net`。 +- `ax-api` / `ax-posix-api` 迁移为使用 `ax-net` 新统一 API,不保留旧 socket handle 到旧方法的适配层。 +- `axstd` / `axlibc` 面向应用的公开 API 可保持不变,但内部必须通过迁移后的 `ax-api` / `ax-posix-api` 工作。 + +StarryOS: + +- `os/StarryOS/kernel/Cargo.toml`(package name: `starry-kernel`)改为: + - `axnet = { workspace = true }`(继承 workspace dependency alias,真实 package 为 `ax-net`) + - feature 从 `ax-feat/net-ng` 改为 `ax-feat/net` + - `vsock` 继续通过 `ax-feat/vsock` +- StarryOS syscall 代码中的 `use axnet::...` 保持不变。 + +测试与应用配置: + +- `test-suit/starryos/**/build-*.toml` 中的 `starry-kernel/vsock` 保持。 +- `ax-driver/virtio-net`、`ax-driver/virtio-socket` 保持。 +- 若出现显式 `net-ng` 配置,全部改为 `net`。 +- QEMU `virtio-net-pci` 和 `-netdev user` 配置不变。 + +### 2.7 DNS 与 DHCP + +**关键发现**:当前已有依赖 DNS 的功能,必须在本轮实现以避免功能退化: +- `axstd::net::ToSocketAddrs` 中 `(&str, u16)` 需要 DNS 解析 +- `ax-api::net::ax_dns_query()` 被 `axstd` 依赖 +- `apps/arceos/httpclient` 在 `feature = "dns"` 下使用域名连接 + +**本轮实现方案(必须完成)**: + +1. **保留 DNS 查询功能,迁移实现** + - 在 `net/ax-net/src/lib.rs` 中提供正式 public API:`pub fn dns_query(name: &str) -> AxResult>` + - 基于 smoltcp 的 DNS socket 功能实现(`socket-dns` feature 已启用) + - 复用旧 DNS 查询流程,但重写实现以接入新的 `SocketSetWrapper`、`Service` 和动态 DNS server 列表,不迁移旧 `ETH0` / 旧 `SOCKET_SET` 结构 + - 使用 DHCP 获取的 DNS server 或静态配置的 DNS server + +2. **DNS server 配置管理** + - `ax-net` 内部维护 DNS server 列表(从 DHCP 或显式静态配置获取) + - 新增静态 DNS 配置项,例如 `AX_DNS`,接入 `ax-config` 或 `consts.rs` + - 可提供查询接口:`pub fn dns_servers() -> Vec`,仅作为诊断 API,不作为 resolver 配置修改入口 + - DNS server 来源优先级: + - DHCP 获取的 DNS server(优先) + - 显式静态 DNS 配置 + - 无配置时查询返回错误,不硬编码默认值 + +3. **DHCP 支持** + - 保持 `ax-net-ng` 已有的 DHCP 实现(DHCP client、自动获取 IP/gateway/DNS) + - 初始化时按配置选择静态网络或 DHCP:`AX_IP` 和 `AX_GW` 都存在时使用静态网络,否则启用 DHCP + - DHCP bootstrap 超时保持 warning 行为,不新增隐式静态回退;如果需要 DHCP 失败回退静态配置,应作为额外设计单独实现 + +4. **API 映射** + - `ax-api::net::ax_dns_query()` → `ax_net::dns_query()` + - `axstd::net::ToSocketAddrs` 继续通过 `ax_api::net::ax_dns_query()` 工作 + - 不改变上层 API,只替换底层实现 + +**迁移注意事项**: +- 旧实现位于 `os/arceos/modules/axnet/src/smoltcp_impl/dns.rs`,仅作为 DNS query 流程参考,不完整搬迁旧结构 +- 测试覆盖:`apps/arceos/httpclient` 的 `dns` feature 必须能正常工作 +- 如果 smoltcp DNS socket 实现不足,需要在本轮补充完整 + +**不在本轮范围**: +- 复杂的 DNS 缓存机制(可选优化) +- IPv6 DNS(AAAA 记录) +- 自定义 DNS resolver 配置(`/etc/resolv.conf` 等) + +## 3. 测试方案 + +必须运行: + +- `cargo fmt` +- `cargo xtask clippy --package ax-net` +- `cargo xtask clippy --package ax-runtime` +- `cargo xtask clippy --package ax-feat` +- `cargo xtask clippy --package ax-api` +- `cargo xtask clippy --package ax-posix-api` +- `cargo xtask clippy --package ax-std` +- `cargo xtask clippy --package ax-libc` +- `cargo xtask clippy --package starry-kernel` + +功能验证: + +- ArceOS `net-loopback` 测试:确认 `axstd::net::{TcpListener,TcpStream,UdpSocket}` 仍可用。 +- ArceOS `httpserver` / `httpclient` QEMU:确认 ArceOS 上层已迁移到新 `ax-net` API。 +- **ArceOS `httpclient` DNS 测试**:使用 `--features dns` 运行,确认域名解析功能正常(`ToSocketAddrs` 和 `ax_dns_query` 工作)。 +- StarryOS socket dataplane 测试:TCP/UDP bind/connect/send/recv。 +- StarryOS epoll network 测试:确认 `axpoll` waker 路径未破坏。 +- StarryOS AF_UNIX SCM_RIGHTS/socketpair 测试。 +- StarryOS raw ICMP/packet socket/netlink 测试。 +- StarryOS vsock build 测试,至少覆盖 `starry-kernel/vsock + ax-driver/virtio-socket` 的编译。 +- DHCP/QEMU user networking 场景:确认 `eth0` 初始化、默认路由、DNS server 获取不退化。 + +## 4. 遗留问题 + +- `bench_transmit()` / `bench_receive()`:旧入口不迁入新 `ax-net`;若仍需要网络设备 benchmark,应单独放到 tools 或 test-suit,不进入核心网络栈 API。 +- DNS:本轮必须迁移 `dns_query()` 实现,保持现有功能不退化;DNS 缓存、IPv6 AAAA 记录、自定义 resolver 配置等高级特性不在本轮范围。 +- IPv6:StarryOS syscall 层支持 AF_INET6 入口,但实际会映射到 IPv4;统一网络栈仍以 IPv4 为主,完整 IPv6 支持不在本轮范围。 +- 多 NIC:新栈已有 router/device 抽象,但初始化仍主要使用 `eth0`;多网卡策略、接口命名、真实 MAC 查询给 StarryOS ioctl 使用可后续增强。 +- `net-ng` 名称清理:本轮必须删除代码、Cargo feature、测试配置和文档中的 `net-ng` 入口;若第三方分支仍依赖该 feature,需要自行迁移到 `net`。 +- ArceOS modules 路径清理:本轮必须删除 `os/arceos/modules/axnet` 和 `os/arceos/modules/axnet-ng` 作为网络栈承载目录,后续网络栈实现只允许位于 `net/ax-net`。 +- StarryOS `AF_PACKET` 和 `AF_NETLINK` 仍在 StarryOS 层,不迁入 `ax-net`;它们是 Linux 兼容层的一部分,不属于通用 ArceOS 网络栈。 diff --git a/scripts/axbuild/CHANGELOG.md b/scripts/axbuild/CHANGELOG.md index 257b480b67..4bb2a9a6e8 100644 --- a/scripts/axbuild/CHANGELOG.md +++ b/scripts/axbuild/CHANGELOG.md @@ -117,7 +117,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - *(starryos/procfs)* implement /proc/stat, /proc/cpuinfo, /proc/uptime; fix /proc/meminfo and sysinfo() ([#452](https://github.com/rcore-os/tgoskits/pull/452)) - *(axbuild)* support Starry board examples - *(realtek-rtl8125)* complete OrangePi board bringup ([#404](https://github.com/rcore-os/tgoskits/pull/404)) -- *(ax-net-ng)* add ICMP raw socket support ([#368](https://github.com/rcore-os/tgoskits/pull/368)) +- *(ax-net)* add ICMP raw socket support ([#368](https://github.com/rcore-os/tgoskits/pull/368)) - *(lockdep)* extend lockdep with task-held tracking and qemu regression coverage ([#415](https://github.com/rcore-os/tgoskits/pull/415)) - *(runtime)* extend IRQ, RTC, and tty event support ([#287](https://github.com/rcore-os/tgoskits/pull/287)) - *(rockchip-soc)* migrate RK3588 clocks ([#384](https://github.com/rcore-os/tgoskits/pull/384)) diff --git a/scripts/test/std_crates.csv b/scripts/test/std_crates.csv index 703dc8b42c..3241dd4852 100644 --- a/scripts/test/std_crates.csv +++ b/scripts/test/std_crates.csv @@ -47,7 +47,6 @@ ax-input ax-ipi ax-log ax-net -ax-net-ng ax-runtime ax-feat ax-api From bf9b2f2a697726a2dcad59824951294b5da26f1a Mon Sep 17 00:00:00 2001 From: ZCShou <72115@163.com> Date: Wed, 10 Jun 2026 14:33:37 +0800 Subject: [PATCH 02/11] refactor(ax-net): decouple network config and Unix namespace from ax-fs-ng --- Cargo.lock | 5 +- net/ax-net/Cargo.toml | 5 +- net/ax-net/src/config.rs | 21 ++ net/ax-net/src/consts.rs | 14 - net/ax-net/src/lib.rs | 98 ++++-- net/ax-net/src/unix/dgram.rs | 9 +- net/ax-net/src/unix/mod.rs | 44 +-- net/ax-net/src/unix/namespace.rs | 41 +++ os/arceos/modules/axruntime/Cargo.toml | 5 +- os/arceos/modules/axruntime/src/devices.rs | 62 +++- os/arceos/modules/axruntime/src/lib.rs | 3 + os/arceos/modules/axruntime/src/unix_ns.rs | 61 ++++ p.md | 333 --------------------- 13 files changed, 283 insertions(+), 418 deletions(-) create mode 100644 net/ax-net/src/config.rs create mode 100644 net/ax-net/src/unix/namespace.rs create mode 100644 os/arceos/modules/axruntime/src/unix_ns.rs delete mode 100644 p.md diff --git a/Cargo.lock b/Cargo.lock index 23e3201301..49cedd8f62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -976,15 +976,12 @@ version = "0.7.1" dependencies = [ "async-channel", "async-trait", - "ax-config", "ax-errno 0.6.0", - "ax-fs-ng", "ax-hal", "ax-io", "ax-kspin", "ax-sync", "ax-task", - "axfs-ng-vfs", "axpoll", "bitflags 2.13.0", "cfg-if", @@ -1186,6 +1183,7 @@ dependencies = [ "ax-plat", "ax-task", "axbacktrace", + "axfs-ng-vfs", "axklib", "axpanic", "cfg-if", @@ -1193,6 +1191,7 @@ dependencies = [ "indoc", "rd-net", "rdrive", + "smoltcp 0.13.1", "spin 0.12.0", ] diff --git a/net/ax-net/Cargo.toml b/net/ax-net/Cargo.toml index 7957ee20ce..9c945a61db 100644 --- a/net/ax-net/Cargo.toml +++ b/net/ax-net/Cargo.toml @@ -4,7 +4,7 @@ version = "0.7.1" repository = "https://github.com/rcore-os/tgoskits" edition.workspace = true authors = ["Mivik "] -description = "ArceOS network module" +description = "Unified network stack for TGOSKits (ArceOS, StarryOS, Axvisor)" license.workspace = true [features] @@ -13,10 +13,7 @@ vsock = ["dep:rdif-vsock"] [dependencies] async-channel = { version = "2.5", default-features = false } async-trait = "0.1" -ax-config = { workspace = true } ax-errno = { workspace = true } -ax-fs-ng = { workspace = true } -axfs-ng-vfs = { workspace = true } ax-hal = { workspace = true } ax-io = { workspace = true } ax-kspin = { workspace = true } diff --git a/net/ax-net/src/config.rs b/net/ax-net/src/config.rs new file mode 100644 index 0000000000..e922a907cb --- /dev/null +++ b/net/ax-net/src/config.rs @@ -0,0 +1,21 @@ +use smoltcp::wire::{Ipv4Address, Ipv4Cidr}; +use alloc::vec::Vec; + +/// Network initialization configuration. +#[derive(Debug, Clone, Default)] +pub struct NetworkConfig { + /// Static IP configuration. If None, DHCP will be used. + pub static_ip: Option, + /// DNS servers. + /// + /// - In **static IP mode**: these are the primary DNS servers. + /// - In **DHCP mode**: these are fallback servers, used only if DHCP doesn't provide DNS servers. + pub dns_servers: Vec, +} + +/// Static IP configuration. +#[derive(Debug, Clone)] +pub struct StaticIpConfig { + pub ip: Ipv4Cidr, + pub gateway: Ipv4Address, +} diff --git a/net/ax-net/src/consts.rs b/net/ax-net/src/consts.rs index e2d77d0042..441b928977 100644 --- a/net/ax-net/src/consts.rs +++ b/net/ax-net/src/consts.rs @@ -1,17 +1,3 @@ -macro_rules! env_or_default { - ($key:literal) => { - match option_env!($key) { - Some(val) => val, - None => "", - } - }; -} - -pub const IP: &str = env_or_default!("AX_IP"); -pub const GATEWAY: &str = env_or_default!("AX_GW"); -pub const DNS: &str = env_or_default!("AX_DNS"); -pub const IP_PREFIX: u8 = 24; - pub const STANDARD_MTU: usize = 1500; pub const TCP_RX_BUF_LEN: usize = 64 * 1024; diff --git a/net/ax-net/src/lib.rs b/net/ax-net/src/lib.rs index b176203c38..3ed122083d 100644 --- a/net/ax-net/src/lib.rs +++ b/net/ax-net/src/lib.rs @@ -21,6 +21,7 @@ extern crate alloc; #[cfg(test)] extern crate std; +mod config; mod consts; mod device; mod general; @@ -62,7 +63,6 @@ use spin::{LazyLock, Once}; #[cfg(feature = "vsock")] pub use self::device::{VsockDevice, VsockDeviceList}; use self::{ - consts::{DNS, GATEWAY, IP, IP_PREFIX}, device::{EthernetDevice, LoopbackDevice}, listen_table::ListenTable, router::{Router, Rule}, @@ -70,6 +70,7 @@ use self::{ wrapper::SocketSetWrapper, }; pub use self::{ + config::{NetworkConfig, StaticIpConfig}, device::{ ArpEntry, EthernetDeviceList, EthernetDriver, NetDeviceError, NetDeviceResult, NetIrqEvents, NetRxBuffer, NetTxBuffer, RdNetDriver, @@ -80,6 +81,7 @@ pub use self::{ static LISTEN_TABLE: LazyLock = LazyLock::new(ListenTable::new); static SOCKET_SET: LazyLock = LazyLock::new(SocketSetWrapper::new); +static CONFIG: Once> = Once::new(); static SERVICE: Once> = Once::new(); static POLLING_INTERFACES: AtomicBool = AtomicBool::new(false); static POLL_AGAIN: AtomicBool = AtomicBool::new(false); @@ -95,9 +97,38 @@ fn get_service() -> ax_sync::MutexGuard<'static, Service> { } /// Initializes the network subsystem by NIC devices. -pub fn init_network(mut net_devs: EthernetDeviceList) { +/// +/// # Panics +/// +/// Panics if called more than once, or if the configuration contains invalid values. +pub fn init_network(mut net_devs: EthernetDeviceList, config: NetworkConfig) { + if CONFIG.get().is_some() { + panic!("init_network() called more than once"); + } + info!("Initialize network subsystem..."); + // Validate configuration + if let Some(ref static_cfg) = config.static_ip { + if static_cfg.ip.address().is_unspecified() { + panic!("Invalid static IP: unspecified address"); + } + if static_cfg.ip.prefix_len() > 32 { + panic!("Invalid static IP: prefix length > 32"); + } + if static_cfg.gateway.is_unspecified() { + panic!("Invalid gateway: unspecified address"); + } + } + for (i, dns) in config.dns_servers.iter().enumerate() { + if dns.is_unspecified() { + panic!("Invalid DNS server at index {}: unspecified address", i); + } + } + + // Store configuration + CONFIG.call_once(|| Mutex::new(config.clone())); + let mut router = Router::new(); let lo_dev = router.add_device(Box::new(LoopbackDevice::new())); @@ -109,7 +140,6 @@ pub fn init_network(mut net_devs: EthernetDeviceList) { lo_ip.address().into(), )); - let static_network = !IP.is_empty() && !GATEWAY.is_empty(); let mut dhcp_dev = None; let mut dhcp_mac = None; @@ -118,8 +148,7 @@ pub fn init_network(mut net_devs: EthernetDeviceList) { info!(" use NIC 0: {:?}", dev.device_name()); let eth0_address = EthernetAddress(dev.mac_address()); - let eth0_ip = static_network - .then(|| Ipv4Cidr::new(IP.parse().expect("Invalid IPv4 address"), IP_PREFIX)); + let eth0_ip = config.static_ip.as_ref().map(|cfg| cfg.ip); let eth0_dev = router.add_device(Box::new(EthernetDevice::new( "eth0".to_owned(), @@ -129,17 +158,16 @@ pub fn init_network(mut net_devs: EthernetDeviceList) { info!("eth0:"); info!(" mac: {}", eth0_address); - if let Some(eth0_ip) = eth0_ip { - let gateway = GATEWAY.parse().expect("Invalid gateway address"); + if let Some(static_cfg) = &config.static_ip { router.add_rule(Rule::new( Ipv4Cidr::new(Ipv4Address::UNSPECIFIED, 0).into(), - Some(gateway), + Some(static_cfg.gateway.into()), eth0_dev, - eth0_ip.address().into(), + static_cfg.ip.address().into(), )); info!(" mode: static"); - info!(" ip: {}", eth0_ip); - info!(" gw: {}", gateway); + info!(" ip: {}", static_cfg.ip); + info!(" gw: {}", static_cfg.gateway); } else { dhcp_dev = Some(eth0_dev); dhcp_mac = Some(eth0_address); @@ -213,16 +241,27 @@ pub fn arp_entries() -> Vec { get_service().arp_entries() } +/// Returns the list of configured DNS servers. +/// +/// Priority: DHCP-provided servers take precedence over statically configured servers. +/// If DHCP hasn't provided servers, falls back to the servers from `NetworkConfig`. pub fn dns_servers() -> Vec { let servers = get_service().dns_servers(); if servers.is_empty() { - static_dns_servers() + configured_dns_servers() } else { servers } } + +const DNS_DEFAULT_TIMEOUT: Duration = Duration::from_secs(5); + pub fn dns_query(name: &str) -> AxResult> { + dns_query_timeout(name, DNS_DEFAULT_TIMEOUT) +} + +pub fn dns_query_timeout(name: &str, timeout: Duration) -> AxResult> { let servers = dns_servers(); if servers.is_empty() { return Err(ax_err_type!(NotFound, "no DNS server configured")); @@ -230,13 +269,18 @@ pub fn dns_query(name: &str) -> AxResult> { let servers = servers.into_iter().map(IpAddress::Ipv4).collect::>(); let handle = SOCKET_SET.add(dns::Socket::new(&servers, vec![])); - DnsSocketGuard(handle).query(name, DnsQueryType::A) + DnsSocketGuard(handle).query_timeout(name, DnsQueryType::A, timeout) } struct DnsSocketGuard(smoltcp::iface::SocketHandle); impl DnsSocketGuard { - fn query(&self, name: &str, query_type: DnsQueryType) -> AxResult> { + fn query_timeout( + &self, + name: &str, + query_type: DnsQueryType, + timeout: Duration, + ) -> AxResult> { let query_handle = { let mut service = get_service(); let mut sockets = SOCKET_SET.inner.lock(); @@ -258,6 +302,9 @@ impl DnsSocketGuard { } })?; + let start_time = ax_hal::time::monotonic_time_nanos(); + let deadline = start_time.saturating_add(timeout.as_nanos() as u64); + loop { poll_interfaces(); match SOCKET_SET.with_socket_mut::(self.0, |socket| { @@ -273,7 +320,12 @@ impl DnsSocketGuard { Ok(addrs) => { return Ok(addrs.into_iter().map(IpAddr::from).collect()); } - Err(AxError::WouldBlock) => ax_task::yield_now(), + Err(AxError::WouldBlock) => { + if ax_hal::time::monotonic_time_nanos() >= deadline { + return Err(ax_err_type!(TimedOut, "DNS query timed out")); + } + ax_task::yield_now(); + } Err(err) => return Err(err), } } @@ -286,17 +338,11 @@ impl Drop for DnsSocketGuard { } } -fn static_dns_servers() -> Vec { - DNS.split(',') - .filter_map(|server| { - let server = server.trim(); - (!server.is_empty()).then(|| { - server - .parse() - .unwrap_or_else(|_| panic!("Invalid DNS server address: {server}")) - }) - }) - .collect() +fn configured_dns_servers() -> Vec { + CONFIG + .get() + .map(|cfg| cfg.lock().dns_servers.clone()) + .unwrap_or_default() } fn dhcp_bootstrap() { diff --git a/net/ax-net/src/unix/dgram.rs b/net/ax-net/src/unix/dgram.rs index 34d28b7abc..f77ff2b44d 100644 --- a/net/ax-net/src/unix/dgram.rs +++ b/net/ax-net/src/unix/dgram.rs @@ -184,7 +184,14 @@ impl TransportOps for DgramTransport { fn send(&self, mut src: impl Read, options: SendOptions) -> AxResult { let mut message = Vec::new(); - src.read_to_end(&mut message)?; + let mut buf = [0u8; 4096]; + loop { + match src.read(&mut buf) { + Ok(0) => break, + Ok(n) => message.extend_from_slice(&buf[..n]), + Err(e) => return Err(e), + } + } let len = message.len(); let packet = Packet { data: message, diff --git a/net/ax-net/src/unix/mod.rs b/net/ax-net/src/unix/mod.rs index 730df48a4a..c301f9fa29 100644 --- a/net/ax-net/src/unix/mod.rs +++ b/net/ax-net/src/unix/mod.rs @@ -1,22 +1,21 @@ pub(crate) mod dgram; pub(crate) mod stream; +pub mod namespace; use alloc::{boxed::Box, sync::Arc}; use core::task::Context; use async_trait::async_trait; use ax_errno::{AxError, AxResult}; -use ax_fs_ng::{FS_CONTEXT, OpenOptions}; use ax_io::{IoBuf, Read, Write}; use ax_sync::Mutex; use ax_task::future::{block_on, poll_io}; -use axfs_ng_vfs::NodeType; use axpoll::{IoEvents, Pollable}; use enum_dispatch::enum_dispatch; use hashbrown::HashMap; use spin::LazyLock; -pub use self::{dgram::DgramTransport, stream::StreamTransport}; +pub use self::{dgram::DgramTransport, namespace::{UnixNamespace, register_unix_namespace}, stream::StreamTransport}; use crate::{ RecvOptions, SendOptions, Shutdown, Socket, SocketAddrEx, SocketOps, options::{Configurable, GetSocketOption, SetSocketOption}, @@ -111,20 +110,10 @@ pub(crate) fn with_slot( } } UnixSocketAddr::Path(path) => { - let loc = FS_CONTEXT.lock().resolve(path.as_ref())?; - if loc.metadata()?.node_type != NodeType::Socket { - return Err(AxError::NotASocket); - } - let slot = { - // `DirEntry::user_data()` is protected by a SpinNoIrq guard. - // Drop it before running transport code, which may take - // sleepable socket mutexes. - let user_data = loc.user_data(); - user_data - .get::() - .ok_or(AxError::ConnectionRefused)? - }; - f(slot.as_ref()) + namespace::with_namespace(|ns| { + let slot = ns.resolve(path.as_ref())?; + f(slot.as_ref()) + }) } } } @@ -139,23 +128,10 @@ fn with_slot_or_insert( f(binds.entry(name.clone()).or_default()) } UnixSocketAddr::Path(path) => { - let loc = OpenOptions::new() - .write(true) - .create(true) - .node_type(NodeType::Socket) - .open(&FS_CONTEXT.lock(), path.as_ref())? - .into_location(); - if loc.metadata()?.node_type != NodeType::Socket { - return Err(AxError::NotASocket); - } - let slot = { - // `DirEntry::user_data()` is protected by a SpinNoIrq guard. - // Drop it before running transport code, which may take - // sleepable socket mutexes. - let mut user_data = loc.user_data(); - user_data.get_or_insert_with(BindSlot::default) - }; - f(slot.as_ref()) + namespace::with_namespace(|ns| { + let slot = ns.bind(path.as_ref())?; + f(slot.as_ref()) + }) } } } diff --git a/net/ax-net/src/unix/namespace.rs b/net/ax-net/src/unix/namespace.rs new file mode 100644 index 0000000000..aa96e49c6a --- /dev/null +++ b/net/ax-net/src/unix/namespace.rs @@ -0,0 +1,41 @@ +use alloc::{boxed::Box, sync::Arc}; +use ax_errno::{AxResult, ax_err_type}; + +use super::BindSlot; + +/// Path-based Unix socket namespace provider. +/// +/// Provides filesystem backing for Unix domain socket path bindings. +/// Abstract namespace sockets are handled separately within ax-net. +pub trait UnixNamespace: Send + Sync { + /// Resolve an existing socket path binding. + fn resolve(&self, path: &str) -> AxResult>; + + /// Create or get a socket path binding. + fn bind(&self, path: &str) -> AxResult>; + + /// Remove a socket path binding. + fn unbind(&self, path: &str) -> AxResult<()>; +} + +static UNIX_NS: spin::Once> = spin::Once::new(); + +/// Register Unix namespace provider. +/// +/// Must be called before using path-based Unix sockets. +pub fn register_unix_namespace(ns: impl UnixNamespace + 'static) { + UNIX_NS.call_once(|| Box::new(ns)); +} + +/// Access the registered Unix namespace. +/// +/// Returns `AxError::Unsupported` if no filesystem-backed namespace is available. +pub(crate) fn with_namespace(f: impl FnOnce(&dyn UnixNamespace) -> AxResult) -> AxResult { + match UNIX_NS.get() { + Some(ns) => f(&**ns), + None => Err(ax_err_type!( + Unsupported, + "Unix socket path operations require filesystem support (enable 'fs' or 'fs-ng' feature)" + )), + } +} diff --git a/os/arceos/modules/axruntime/Cargo.toml b/os/arceos/modules/axruntime/Cargo.toml index c50cb2bbeb..3e1522dda2 100644 --- a/os/arceos/modules/axruntime/Cargo.toml +++ b/os/arceos/modules/axruntime/Cargo.toml @@ -50,6 +50,7 @@ fs = [ fs-ng = [ "dep:ax-errno", "dep:ax-fs-ng", + "dep:axfs-ng-vfs", "dep:spin", "dep:axklib", "ax-driver/block", @@ -57,7 +58,7 @@ fs-ng = [ fs-ng-ext4 = ["fs-ng", "ax-fs-ng/ext4"] fs-ng-fat = ["fs-ng", "ax-fs-ng/fat"] input = ["dep:ax-input", "ax-driver/input"] -net = ["dep:ax-net", "dep:rd-net", "dep:spin", "dep:axklib", "ax-driver/net"] +net = ["dep:ax-net", "dep:rd-net", "dep:smoltcp", "dep:spin", "dep:axklib", "ax-driver/net"] vsock = ["net", "ax-net/vsock", "ax-driver/vsock"] [dependencies] @@ -70,6 +71,7 @@ ax-driver = {workspace = true} ax-errno = {workspace = true, optional = true} ax-fs = {workspace = true, optional = true} ax-fs-ng = {workspace = true, optional = true} +axfs-ng-vfs = {workspace = true, optional = true} ax-hal = {workspace = true} ax-input = {workspace = true, optional = true} ax-ipi = {workspace = true, optional = true} @@ -89,4 +91,5 @@ chrono = {version = "0.4", default-features = false} indoc = "2" rd-net = { workspace = true, optional = true } rdrive.workspace = true +smoltcp = { workspace = true, optional = true } spin = {workspace = true, optional = true} diff --git a/os/arceos/modules/axruntime/src/devices.rs b/os/arceos/modules/axruntime/src/devices.rs index f53ecbc50e..2eb40f00e9 100644 --- a/os/arceos/modules/axruntime/src/devices.rs +++ b/os/arceos/modules/axruntime/src/devices.rs @@ -91,12 +91,70 @@ pub(crate) fn init_static_input() { #[cfg(all(feature = "net", feature = "plat-dyn"))] pub(crate) fn init_dyn_net() { - ax_net::init_network(take_dyn_net_drivers()); + register_unix_namespace(); + let config = parse_network_config(); + ax_net::init_network(take_dyn_net_drivers(), config); } #[cfg(all(feature = "net", not(feature = "plat-dyn")))] pub(crate) fn init_static_net() { - ax_net::init_network(take_static_net_drivers()); + register_unix_namespace(); + let config = parse_network_config(); + ax_net::init_network(take_static_net_drivers(), config); +} + +#[cfg(all(feature = "net", any(feature = "fs", feature = "fs-ng")))] +fn register_unix_namespace() { + ax_net::unix::register_unix_namespace(crate::unix_ns::AxFsUnixNamespace); +} + +#[cfg(all(feature = "net", not(any(feature = "fs", feature = "fs-ng"))))] +fn register_unix_namespace() { + // No filesystem, Unix socket namespace not available +} + +#[cfg(feature = "net")] +fn parse_network_config() -> ax_net::NetworkConfig { + use smoltcp::wire::Ipv4Cidr; + + macro_rules! env_or_default { + ($key:literal) => { + match option_env!($key) { + Some(val) => val, + None => "", + } + }; + } + + const IP: &str = env_or_default!("AX_IP"); + const GATEWAY: &str = env_or_default!("AX_GW"); + const DNS: &str = env_or_default!("AX_DNS"); + + let static_ip = if !IP.is_empty() && !GATEWAY.is_empty() { + Some(ax_net::StaticIpConfig { + ip: Ipv4Cidr::new( + IP.parse().expect("Invalid AX_IP"), + 24, + ), + gateway: GATEWAY.parse().expect("Invalid AX_GW"), + }) + } else { + None + }; + + let dns_servers = DNS + .split(',') + .filter(|s| !s.trim().is_empty()) + .map(|s| { + let s = s.trim(); + s.parse().unwrap_or_else(|_| panic!("Invalid DNS server address: {}", s)) + }) + .collect(); + + ax_net::NetworkConfig { + static_ip, + dns_servers, + } } #[cfg(all(feature = "net", not(feature = "plat-dyn")))] diff --git a/os/arceos/modules/axruntime/src/lib.rs b/os/arceos/modules/axruntime/src/lib.rs index 63e305c150..5aa76f44c7 100644 --- a/os/arceos/modules/axruntime/src/lib.rs +++ b/os/arceos/modules/axruntime/src/lib.rs @@ -52,6 +52,9 @@ mod block; mod devices; mod registers; +#[cfg(all(feature = "net", any(feature = "fs", feature = "fs-ng")))] +mod unix_ns; + pub use ax_hal as hal; #[cfg(feature = "smp")] diff --git a/os/arceos/modules/axruntime/src/unix_ns.rs b/os/arceos/modules/axruntime/src/unix_ns.rs new file mode 100644 index 0000000000..77676efd10 --- /dev/null +++ b/os/arceos/modules/axruntime/src/unix_ns.rs @@ -0,0 +1,61 @@ +#[cfg(all(feature = "net", feature = "fs-ng"))] +pub(crate) struct AxFsUnixNamespace; + +#[cfg(all(feature = "net", feature = "fs-ng"))] +impl ax_net::unix::UnixNamespace for AxFsUnixNamespace { + fn resolve(&self, path: &str) -> ax_errno::AxResult> { + use ax_errno::AxError; + use ax_fs_ng::FS_CONTEXT; + use axfs_ng_vfs::NodeType; + + let loc = FS_CONTEXT.lock().resolve(path)?; + if loc.metadata()?.node_type != NodeType::Socket { + return Err(AxError::NotASocket); + } + loc.user_data() + .get::() + .ok_or(ax_errno::AxError::ConnectionRefused) + } + + fn bind(&self, path: &str) -> ax_errno::AxResult> { + use ax_errno::AxError; + use ax_fs_ng::{FS_CONTEXT, OpenOptions}; + use axfs_ng_vfs::NodeType; + + let loc = OpenOptions::new() + .write(true) + .create(true) + .node_type(NodeType::Socket) + .open(&FS_CONTEXT.lock(), path)? + .into_location(); + + if loc.metadata()?.node_type != NodeType::Socket { + return Err(AxError::NotASocket); + } + + Ok(loc.user_data().get_or_insert_with(Default::default)) + } + + fn unbind(&self, path: &str) -> ax_errno::AxResult<()> { + use ax_fs_ng::FS_CONTEXT; + FS_CONTEXT.lock().remove_file(path) + } +} + +#[cfg(all(feature = "net", feature = "fs", not(feature = "fs-ng")))] +pub(crate) struct AxFsUnixNamespace; + +#[cfg(all(feature = "net", feature = "fs", not(feature = "fs-ng")))] +impl ax_net::unix::UnixNamespace for AxFsUnixNamespace { + fn resolve(&self, _path: &str) -> ax_errno::AxResult> { + Err(ax_errno::AxError::Unsupported) + } + + fn bind(&self, _path: &str) -> ax_errno::AxResult> { + Err(ax_errno::AxError::Unsupported) + } + + fn unbind(&self, path: &str) -> ax_errno::AxResult<()> { + ax_fs::api::remove_file(path) + } +} diff --git a/p.md b/p.md deleted file mode 100644 index e7dd2ee1ee..0000000000 --- a/p.md +++ /dev/null @@ -1,333 +0,0 @@ -# 统一网络模块为 `ax-net` 的方案 - -## 1. 背景 - -当前仓库存在两套网络 crate: - -- `ax-net`:老一代 ArceOS 网络模块,提供 `TcpSocket`、`UdpSocket`、`dns_query`、`poll_interfaces`、`bench_*`,主要被 `ax-api`、`ax-posix-api`、`axstd`、`axlibc` 使用。 -- `ax-net-ng`:实际更完整的新网络栈,支持 TCP、UDP、raw ICMP、Unix domain socket、vsock、loopback、router、DHCP、socket options、poll/waker,StarryOS 已经通过依赖别名 `axnet = { package = "ax-net-ng" }` 使用它。 - -当前问题: - -- `ax-runtime`、`ax-feat` 同时保留 `net` 和 `net-ng` 两套 feature/初始化路径。 -- `ax-net` 又依赖 `ax-net-ng` 的驱动适配类型,形成“旧 API 壳 + 新组件片段”的混合状态。 -- StarryOS 的对外依赖名是 `axnet`,但真实 package 是 `ax-net-ng`,命名和架构不一致。 -- ArceOS 公共 API 仍走旧 `ax-net`,无法获得 `ax-net-ng` 的完整 socket 能力。 - -目标: - -- 仅保留 `ax-net` 作为唯一网络 crate/package。 -- 在仓库根目录新增 `net/ax-net`,以当前 `ax-net-ng` 为主体实现统一网络栈,并以清晰、统一的新 API 作为唯一对外接口。 -- 移除 `os/arceos/modules/axnet` 和 `os/arceos/modules/axnet-ng` 两个 ArceOS-local 网络 crate,删除对应 workspace dependency、feature 路径和 runtime 分支。 -- 统一 ArceOS 与 StarryOS 的网络能力入口,降低重复实现和 feature 组合风险。 -- 将网络栈从 ArceOS modules 目录中提升为根目录通用组件,使其成为 ArceOS、StarryOS 以及后续其他系统可复用的统一 net 支持。 -- 不保留旧 `ax-net` 的兼容 wrapper、旧 feature alias 或旧 benchmark stub;所有调用方在本轮同步迁移到统一 API。 - -## 2. 修改方案 - -### 2.1 总体架构 - -**目录位置**:`net/ax-net/` -- 在仓库根目录新增 `net/` 顶层目录,其中放置 `ax-net/` 网络模块 -- 理由:网络栈作为跨 ArceOS、StarryOS、Axvisor 的核心基础设施,足够重要,值得独立的顶层目录 -- 与 `drivers/`、`platforms/`、`components/` 等平级,突出其作为独立网络子系统的地位 - -重构后的 `ax-net` 本身分为五层:设备适配层、协议服务层、socket 抽象层、地址族实现层、公开入口层。 - -```text -net/ax-net - public facade - -> lib.rs - -> init_network / init_vsock / poll_interfaces - -> public socket, option, device, status APIs - - socket abstraction - -> socket.rs: Socket, SocketOps, SocketAddrEx, SendOptions, RecvOptions - -> options.rs: Configurable, GetSocketOption, SetSocketOption - -> general.rs: common nonblocking, timeout, protocol/domain/type state - - address-family implementations - -> tcp.rs - -> udp.rs - -> raw.rs - -> unix/ - -> vsock/ - - protocol service - -> service.rs: smoltcp Interface owner, DHCP, DNS server state, waker registration - -> router.rs: route table, device dispatch, packet rx/tx path - -> listen_table.rs: TCP listen/accept queue - -> wrapper.rs: smoltcp SocketSet access - -> state.rs: socket state transitions - - device adaptation - -> device/driver.rs: rd-net -> ax-net EthernetDriver adapter - -> device/ethernet.rs: Ethernet device implementation - -> device/loopback.rs: loopback device - -> device/vsock.rs: rdif-vsock integration -``` - -落地目录: - -```text -net/ - ax-net/ - Cargo.toml - src/ - lib.rs - device/ - router.rs - service.rs - socket.rs - tcp.rs - udp.rs - raw.rs - unix/ - vsock/ - options.rs - wrapper.rs - listen_table.rs - state.rs -``` - -内部边界: - -- `lib.rs` 只做 facade、初始化入口和必要 re-export,不承载协议状态机逻辑。 -- `socket.rs` 定义跨地址族统一抽象;TCP、UDP、raw、Unix、vsock 都实现同一组 `SocketOps` / `Pollable` / `Configurable` 语义。 -- `service.rs` 和 `router.rs` 是协议服务核心,负责把 smoltcp、路由、设备和 waker 串起来。 -- `device/` 只负责把 `rd-net` / `rdif-vsock` 设备接入网络栈,不包含具体硬件驱动。 -- `router`、`service`、`wrapper`、`listen_table`、`state` 默认 crate-private,避免外部系统绑定内部实现细节。 -- 将当前 `ax-net-ng` 的实现作为 `net/ax-net` 主体。 -- 删除旧 `os/arceos/modules/axnet/src/smoltcp_impl` 的 TCP/UDP/listen table/router/DNS/benchmark 实现。 -- 删除 `os/arceos/modules/axnet` 和 `os/arceos/modules/axnet-ng` 目录,避免 ArceOS modules 下继续存在网络栈实现。 -- 不迁移旧 `ax-net` 的 `smoltcp_impl`、旧 DNS socket wrapper、旧 `bench_transmit()` / `bench_receive()`;需要这些能力的调用方必须改到新 API 或独立工具。 - -### 2.2 依赖关系 - -`ax-net` 依赖的组件: - -```text -ax-net - -> smoltcp TCP/IP 协议栈 - -> axpoll readiness / Pollable / waker 语义 - -> ax-task 阻塞等待、任务调度、DHCP/vsock 后台任务 - -> ax-sync / ax-kspin 锁与同步原语 - -> ax-io Read/Write/IoBuf 抽象 - -> ax-errno AxError / AxResult / LinuxError 映射 - -> ax-config IP、网关、前缀等构建期配置 - -> ax-hal 时间等底层能力 - -> ax-fs-ng / axfs-ng-vfs Unix domain socket 路径绑定 - -> rd-net Ethernet queue/DMA 设备抽象 - -> rdif-vsock 可选,vsock 设备抽象 -``` - -依赖 `ax-net` 的组件: - -```text -ax-runtime - -> ax-net 网络和 vsock 初始化 - -ax-feat - -> ax-net net/vsock feature 装配 - -ax-api - -> ax-net ArceOS Rust API 网络入口 - -ax-posix-api - -> ax-net ArceOS POSIX socket 入口 - -ax-std / ax-libc - -> ax-api / ax-posix-api - -> ax-net 间接使用统一网络栈 - -starry-kernel - -> ax-net Linux syscall socket 底层实现 - -apps / test-suit - -> ax-std / ax-libc / starry-kernel - -> ax-net 间接验证统一网络栈 -``` - -不属于 `ax-net` 依赖方向的内容: - -- `ax-driver` 不依赖 `ax-net`,只负责注册 `rd-net::Net` 和 `rdif-vsock::Interface`。 -- 具体网卡/vsock 驱动位于 `drivers/`,不进入 `net/ax-net`。 -- StarryOS 的 `AF_PACKET`、`AF_NETLINK`、Linux `sockaddr` 编解码、`ioctl(SIOCGIF*)`、syscall errno 细节保留在 `os/StarryOS/`。 -- `os/arceos/modules/axnet`、`os/arceos/modules/axnet-ng` 从 workspace members 和 dependencies 中删除。 - -### 2.3 对外 API 设计 - -统一后的 `ax-net` 对外 API 分为三类:运行时初始化 API、socket API、设备/状态查询 API。 - -运行时初始化 API: - -- `pub fn init_network(net_devs: EthernetDeviceList)`:由 `ax-runtime` 调用,完成 loopback、eth0、router、smoltcp service、DHCP/static IP 初始化。 -- `#[cfg(feature = "vsock")] pub fn init_vsock(vsock_devs: VsockDeviceList)`:由 `ax-runtime` 调用,注册 vsock 设备并启动 vsock 事件处理。 -- `pub fn poll_interfaces()`:推动网络栈收包、发包、协议状态机和 socket readiness 更新;供 runtime、poll/select/epoll 和 OS 适配层显式调用。 - -socket API: - -- `pub mod tcp`,公开 `tcp::TcpSocket`。 -- `pub mod udp`,公开 `udp::UdpSocket`。 -- `pub mod raw`,公开 raw IPv4/ICMP socket 能力。 -- `pub mod unix`,公开 Unix domain socket 地址、stream/dgram transport 与 `UnixSocket`。 -- `#[cfg(feature = "vsock")] pub mod vsock`,公开 vsock 地址、stream transport 与 `VsockSocket`。 -- `pub use socket::{Socket, SocketAddrEx, SocketOps, SendOptions, RecvOptions, SendFlags, RecvFlags, Shutdown, CMsgData}`,作为 StarryOS syscall 层和未来其他 OS 兼容层的统一 socket 抽象。 -- `pub mod options`,公开 `Configurable`、`GetSocketOption`、`SetSocketOption`、`TcpInfo`、`UnixCredentials` 等 socket option 类型。 - -设备和状态查询 API: - -- `pub use device::{EthernetDeviceList, EthernetDriver, NetRxBuffer, NetTxBuffer, NetDeviceError, NetDeviceResult, NetIrqEvents, RdNetDriver}`,供 `ax-runtime` 将 `ax-driver` 暴露的 `rd-net` 设备适配进 `ax-net`。 -- `#[cfg(feature = "vsock")] pub use device::{VsockDevice, VsockDeviceList}`。 -- `pub fn arp_entries() -> Vec`,供 `/proc/net/arp`、诊断工具或系统兼容层查询 ARP 状态。 -- `pub fn dns_query(name: &str) -> AxResult>`,正式 DNS 域名解析 API,供 `ax-api`、`axstd::net::ToSocketAddrs` 和 POSIX `getaddrinfo` 路径使用。 -- `pub fn dns_servers() -> Vec`,查询当前配置的 DNS server 列表,仅供诊断使用。 - -不作为 `ax-net` 对外 API 的内容: - -- `AF_PACKET`、`AF_NETLINK`、Linux `sockaddr` 编解码、`ioctl(SIOCGIF*)`、syscall errno 细节仍属于 StarryOS Linux ABI 层。 -- 具体网卡驱动、PCI/VirtIO 设备探测、DMA mapping 策略仍属于 `drivers/` 和 `ax-driver`。 -- 旧 `ax-net` 的阻塞式 inherent methods、旧 DNS wrapper、旧 benchmark 入口不进入新 `ax-net` 公共 API。 -- `router`、`service`、`wrapper`、`listen_table`、`state` 默认保持 crate-private,除非有明确跨 OS 复用需求。 - -### 2.4 ArceOS 调用方迁移 - -旧 ArceOS 上层直接调用 `TcpSocket` / `UdpSocket` 的 inherent methods。统一后不在 `ax-net` 中保留这套旧方法,而是迁移 ArceOS 调用方使用统一 socket API。 - -迁移原则: - -- `ax-api::net` 从旧 handle wrapper 迁移为基于 `ax_net::{SocketOps, SocketAddrEx, SendOptions, RecvOptions, Shutdown}` 的实现。 -- `ax-posix-api::imp::net` 不再直接依赖旧 `TcpSocket`/`UdpSocket` 方法,改为与 StarryOS 类似的统一 `Socket`/`SocketOps` 调用模型。 -- `axstd::net` 和 `axlibc::net` 保持面向应用的 API 不变,但其底层实现通过 `ax-api` / `ax-posix-api` 迁移到新 `ax-net`。 -- TCP/UDP 阻塞、非阻塞、poll 状态统一由 `Pollable`、`Configurable` 和 `axpoll` 语义提供,不再维护旧轮询式阻塞路径。 -- `ax-api::net::ax_dns_query()` 改为调用 `ax_net::dns_query()`;`dns_query()` 是新 `ax-net` 的正式 DNS API,不是旧 `smoltcp_impl` DNS wrapper 的兼容保留。 - -### 2.5 feature 设计 - -统一后只保留语义主 feature: - -- `ax-feat/net`:启用统一 `ax-net`。 -- `ax-runtime/net`:启用 `dep:ax-net`、`dep:rd-net`、`dep:spin`、`dep:axklib`、`ax-driver/net`。 -- `ax-feat/vsock`:启用 `ax-runtime/vsock`。 -- `ax-runtime/vsock`:启用 `net`、`ax-net/vsock`、`ax-driver/vsock`。 -- `ax-net/vsock`:启用 `dep:rdif-vsock`。 -- `axstd/net`、`axlibc/net`、`ax-api/net`、`ax-posix-api/net`:继续依赖 `ax-feat/net` 和 `ax-net`。 - -处理旧 feature: - -- 彻底删除 `net-ng` feature,不保留 alias、不保留 deprecated 兼容入口。 -- 所有仓库内配置、Cargo.toml、文档、测试统一改为 `net`。 -- 任何残留的 `net-ng` 引用都视为本轮重构必须修复的编译错误。 - -### 2.6 Cargo 与调用方修改 - -Workspace: - -- 新增 workspace member `net/ax-net`。 -- 删除 workspace members `os/arceos/modules/axnet` 和 `os/arceos/modules/axnet-ng`。 -- 将 workspace dependency `ax-net` 改为 `path = "net/ax-net"`。 -- 新增 workspace dependency alias `axnet = { package = "ax-net", path = "net/ax-net", ... }`,供 StarryOS 在不改 `use axnet::...` 的前提下继承统一网络栈。 -- 删除 workspace dependency `ax-net-ng`。 -- `ax-net` 版本可提升到当前 `ax-net-ng` 的版本线或项目约定的新版本。 - -ArceOS: - -- `ax-feat` 删除 `dep:ax-net-ng` 的真实依赖路径。 -- `ax-runtime` 删除 `init_dyn_net_ng`、`take_*_net_ng_drivers` 分支,所有网络初始化走 `ax_net`。 -- `ax-api` / `ax-posix-api` 迁移为使用 `ax-net` 新统一 API,不保留旧 socket handle 到旧方法的适配层。 -- `axstd` / `axlibc` 面向应用的公开 API 可保持不变,但内部必须通过迁移后的 `ax-api` / `ax-posix-api` 工作。 - -StarryOS: - -- `os/StarryOS/kernel/Cargo.toml`(package name: `starry-kernel`)改为: - - `axnet = { workspace = true }`(继承 workspace dependency alias,真实 package 为 `ax-net`) - - feature 从 `ax-feat/net-ng` 改为 `ax-feat/net` - - `vsock` 继续通过 `ax-feat/vsock` -- StarryOS syscall 代码中的 `use axnet::...` 保持不变。 - -测试与应用配置: - -- `test-suit/starryos/**/build-*.toml` 中的 `starry-kernel/vsock` 保持。 -- `ax-driver/virtio-net`、`ax-driver/virtio-socket` 保持。 -- 若出现显式 `net-ng` 配置,全部改为 `net`。 -- QEMU `virtio-net-pci` 和 `-netdev user` 配置不变。 - -### 2.7 DNS 与 DHCP - -**关键发现**:当前已有依赖 DNS 的功能,必须在本轮实现以避免功能退化: -- `axstd::net::ToSocketAddrs` 中 `(&str, u16)` 需要 DNS 解析 -- `ax-api::net::ax_dns_query()` 被 `axstd` 依赖 -- `apps/arceos/httpclient` 在 `feature = "dns"` 下使用域名连接 - -**本轮实现方案(必须完成)**: - -1. **保留 DNS 查询功能,迁移实现** - - 在 `net/ax-net/src/lib.rs` 中提供正式 public API:`pub fn dns_query(name: &str) -> AxResult>` - - 基于 smoltcp 的 DNS socket 功能实现(`socket-dns` feature 已启用) - - 复用旧 DNS 查询流程,但重写实现以接入新的 `SocketSetWrapper`、`Service` 和动态 DNS server 列表,不迁移旧 `ETH0` / 旧 `SOCKET_SET` 结构 - - 使用 DHCP 获取的 DNS server 或静态配置的 DNS server - -2. **DNS server 配置管理** - - `ax-net` 内部维护 DNS server 列表(从 DHCP 或显式静态配置获取) - - 新增静态 DNS 配置项,例如 `AX_DNS`,接入 `ax-config` 或 `consts.rs` - - 可提供查询接口:`pub fn dns_servers() -> Vec`,仅作为诊断 API,不作为 resolver 配置修改入口 - - DNS server 来源优先级: - - DHCP 获取的 DNS server(优先) - - 显式静态 DNS 配置 - - 无配置时查询返回错误,不硬编码默认值 - -3. **DHCP 支持** - - 保持 `ax-net-ng` 已有的 DHCP 实现(DHCP client、自动获取 IP/gateway/DNS) - - 初始化时按配置选择静态网络或 DHCP:`AX_IP` 和 `AX_GW` 都存在时使用静态网络,否则启用 DHCP - - DHCP bootstrap 超时保持 warning 行为,不新增隐式静态回退;如果需要 DHCP 失败回退静态配置,应作为额外设计单独实现 - -4. **API 映射** - - `ax-api::net::ax_dns_query()` → `ax_net::dns_query()` - - `axstd::net::ToSocketAddrs` 继续通过 `ax_api::net::ax_dns_query()` 工作 - - 不改变上层 API,只替换底层实现 - -**迁移注意事项**: -- 旧实现位于 `os/arceos/modules/axnet/src/smoltcp_impl/dns.rs`,仅作为 DNS query 流程参考,不完整搬迁旧结构 -- 测试覆盖:`apps/arceos/httpclient` 的 `dns` feature 必须能正常工作 -- 如果 smoltcp DNS socket 实现不足,需要在本轮补充完整 - -**不在本轮范围**: -- 复杂的 DNS 缓存机制(可选优化) -- IPv6 DNS(AAAA 记录) -- 自定义 DNS resolver 配置(`/etc/resolv.conf` 等) - -## 3. 测试方案 - -必须运行: - -- `cargo fmt` -- `cargo xtask clippy --package ax-net` -- `cargo xtask clippy --package ax-runtime` -- `cargo xtask clippy --package ax-feat` -- `cargo xtask clippy --package ax-api` -- `cargo xtask clippy --package ax-posix-api` -- `cargo xtask clippy --package ax-std` -- `cargo xtask clippy --package ax-libc` -- `cargo xtask clippy --package starry-kernel` - -功能验证: - -- ArceOS `net-loopback` 测试:确认 `axstd::net::{TcpListener,TcpStream,UdpSocket}` 仍可用。 -- ArceOS `httpserver` / `httpclient` QEMU:确认 ArceOS 上层已迁移到新 `ax-net` API。 -- **ArceOS `httpclient` DNS 测试**:使用 `--features dns` 运行,确认域名解析功能正常(`ToSocketAddrs` 和 `ax_dns_query` 工作)。 -- StarryOS socket dataplane 测试:TCP/UDP bind/connect/send/recv。 -- StarryOS epoll network 测试:确认 `axpoll` waker 路径未破坏。 -- StarryOS AF_UNIX SCM_RIGHTS/socketpair 测试。 -- StarryOS raw ICMP/packet socket/netlink 测试。 -- StarryOS vsock build 测试,至少覆盖 `starry-kernel/vsock + ax-driver/virtio-socket` 的编译。 -- DHCP/QEMU user networking 场景:确认 `eth0` 初始化、默认路由、DNS server 获取不退化。 - -## 4. 遗留问题 - -- `bench_transmit()` / `bench_receive()`:旧入口不迁入新 `ax-net`;若仍需要网络设备 benchmark,应单独放到 tools 或 test-suit,不进入核心网络栈 API。 -- DNS:本轮必须迁移 `dns_query()` 实现,保持现有功能不退化;DNS 缓存、IPv6 AAAA 记录、自定义 resolver 配置等高级特性不在本轮范围。 -- IPv6:StarryOS syscall 层支持 AF_INET6 入口,但实际会映射到 IPv4;统一网络栈仍以 IPv4 为主,完整 IPv6 支持不在本轮范围。 -- 多 NIC:新栈已有 router/device 抽象,但初始化仍主要使用 `eth0`;多网卡策略、接口命名、真实 MAC 查询给 StarryOS ioctl 使用可后续增强。 -- `net-ng` 名称清理:本轮必须删除代码、Cargo feature、测试配置和文档中的 `net-ng` 入口;若第三方分支仍依赖该 feature,需要自行迁移到 `net`。 -- ArceOS modules 路径清理:本轮必须删除 `os/arceos/modules/axnet` 和 `os/arceos/modules/axnet-ng` 作为网络栈承载目录,后续网络栈实现只允许位于 `net/ax-net`。 -- StarryOS `AF_PACKET` 和 `AF_NETLINK` 仍在 StarryOS 层,不迁入 `ax-net`;它们是 Linux 兼容层的一部分,不属于通用 ArceOS 网络栈。 From 6e8c62acf66b41bb80f9b606bb193ccd5db1d0cc Mon Sep 17 00:00:00 2001 From: ZCShou <72115@163.com> Date: Wed, 10 Jun 2026 14:36:25 +0800 Subject: [PATCH 03/11] style(ax-net): apply rustfmt formatting and reorder imports --- net/ax-net/src/config.rs | 3 ++- net/ax-net/src/lib.rs | 15 ++++++------ net/ax-net/src/unix/mod.rs | 28 +++++++++++----------- net/ax-net/src/unix/namespace.rs | 4 +++- os/arceos/modules/axruntime/src/devices.rs | 8 +++---- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/net/ax-net/src/config.rs b/net/ax-net/src/config.rs index e922a907cb..fd30ca18c0 100644 --- a/net/ax-net/src/config.rs +++ b/net/ax-net/src/config.rs @@ -1,6 +1,7 @@ -use smoltcp::wire::{Ipv4Address, Ipv4Cidr}; use alloc::vec::Vec; +use smoltcp::wire::{Ipv4Address, Ipv4Cidr}; + /// Network initialization configuration. #[derive(Debug, Clone, Default)] pub struct NetworkConfig { diff --git a/net/ax-net/src/lib.rs b/net/ax-net/src/lib.rs index 3ed122083d..ffce962d30 100644 --- a/net/ax-net/src/lib.rs +++ b/net/ax-net/src/lib.rs @@ -62,13 +62,6 @@ use spin::{LazyLock, Once}; #[cfg(feature = "vsock")] pub use self::device::{VsockDevice, VsockDeviceList}; -use self::{ - device::{EthernetDevice, LoopbackDevice}, - listen_table::ListenTable, - router::{Router, Rule}, - service::Service, - wrapper::SocketSetWrapper, -}; pub use self::{ config::{NetworkConfig, StaticIpConfig}, device::{ @@ -77,6 +70,13 @@ pub use self::{ }, socket::*, }; +use self::{ + device::{EthernetDevice, LoopbackDevice}, + listen_table::ListenTable, + router::{Router, Rule}, + service::Service, + wrapper::SocketSetWrapper, +}; static LISTEN_TABLE: LazyLock = LazyLock::new(ListenTable::new); static SOCKET_SET: LazyLock = LazyLock::new(SocketSetWrapper::new); @@ -254,7 +254,6 @@ pub fn dns_servers() -> Vec { } } - const DNS_DEFAULT_TIMEOUT: Duration = Duration::from_secs(5); pub fn dns_query(name: &str) -> AxResult> { diff --git a/net/ax-net/src/unix/mod.rs b/net/ax-net/src/unix/mod.rs index c301f9fa29..e8645897ee 100644 --- a/net/ax-net/src/unix/mod.rs +++ b/net/ax-net/src/unix/mod.rs @@ -1,6 +1,6 @@ pub(crate) mod dgram; -pub(crate) mod stream; pub mod namespace; +pub(crate) mod stream; use alloc::{boxed::Box, sync::Arc}; use core::task::Context; @@ -15,7 +15,11 @@ use enum_dispatch::enum_dispatch; use hashbrown::HashMap; use spin::LazyLock; -pub use self::{dgram::DgramTransport, namespace::{UnixNamespace, register_unix_namespace}, stream::StreamTransport}; +pub use self::{ + dgram::DgramTransport, + namespace::{UnixNamespace, register_unix_namespace}, + stream::StreamTransport, +}; use crate::{ RecvOptions, SendOptions, Shutdown, Socket, SocketAddrEx, SocketOps, options::{Configurable, GetSocketOption, SetSocketOption}, @@ -109,12 +113,10 @@ pub(crate) fn with_slot( Err(AxError::NotFound) } } - UnixSocketAddr::Path(path) => { - namespace::with_namespace(|ns| { - let slot = ns.resolve(path.as_ref())?; - f(slot.as_ref()) - }) - } + UnixSocketAddr::Path(path) => namespace::with_namespace(|ns| { + let slot = ns.resolve(path.as_ref())?; + f(slot.as_ref()) + }), } } fn with_slot_or_insert( @@ -127,12 +129,10 @@ fn with_slot_or_insert( let mut binds = ABSTRACT_BINDS.lock(); f(binds.entry(name.clone()).or_default()) } - UnixSocketAddr::Path(path) => { - namespace::with_namespace(|ns| { - let slot = ns.bind(path.as_ref())?; - f(slot.as_ref()) - }) - } + UnixSocketAddr::Path(path) => namespace::with_namespace(|ns| { + let slot = ns.bind(path.as_ref())?; + f(slot.as_ref()) + }), } } diff --git a/net/ax-net/src/unix/namespace.rs b/net/ax-net/src/unix/namespace.rs index aa96e49c6a..e39c8ff5d7 100644 --- a/net/ax-net/src/unix/namespace.rs +++ b/net/ax-net/src/unix/namespace.rs @@ -1,4 +1,5 @@ use alloc::{boxed::Box, sync::Arc}; + use ax_errno::{AxResult, ax_err_type}; use super::BindSlot; @@ -35,7 +36,8 @@ pub(crate) fn with_namespace(f: impl FnOnce(&dyn UnixNamespace) -> AxResult f(&**ns), None => Err(ax_err_type!( Unsupported, - "Unix socket path operations require filesystem support (enable 'fs' or 'fs-ng' feature)" + "Unix socket path operations require filesystem support (enable 'fs' or 'fs-ng' \ + feature)" )), } } diff --git a/os/arceos/modules/axruntime/src/devices.rs b/os/arceos/modules/axruntime/src/devices.rs index 2eb40f00e9..8080b54cd3 100644 --- a/os/arceos/modules/axruntime/src/devices.rs +++ b/os/arceos/modules/axruntime/src/devices.rs @@ -132,10 +132,7 @@ fn parse_network_config() -> ax_net::NetworkConfig { let static_ip = if !IP.is_empty() && !GATEWAY.is_empty() { Some(ax_net::StaticIpConfig { - ip: Ipv4Cidr::new( - IP.parse().expect("Invalid AX_IP"), - 24, - ), + ip: Ipv4Cidr::new(IP.parse().expect("Invalid AX_IP"), 24), gateway: GATEWAY.parse().expect("Invalid AX_GW"), }) } else { @@ -147,7 +144,8 @@ fn parse_network_config() -> ax_net::NetworkConfig { .filter(|s| !s.trim().is_empty()) .map(|s| { let s = s.trim(); - s.parse().unwrap_or_else(|_| panic!("Invalid DNS server address: {}", s)) + s.parse() + .unwrap_or_else(|_| panic!("Invalid DNS server address: {}", s)) }) .collect(); From a73e0883a4bde6a05aeb30099e4e661ad4354c95 Mon Sep 17 00:00:00 2001 From: ZCShou <72115@163.com> Date: Wed, 10 Jun 2026 15:15:36 +0800 Subject: [PATCH 04/11] fix(ax-net): drain TCP receive queue in bulk instead of single recv --- net/ax-net/src/tcp.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/net/ax-net/src/tcp.rs b/net/ax-net/src/tcp.rs index f4a2c7e94c..a1596d6995 100644 --- a/net/ax-net/src/tcp.rs +++ b/net/ax-net/src/tcp.rs @@ -527,13 +527,21 @@ impl SocketOps for TcpSocket { .map_err(|_| ax_err_type!(NotConnected, "not connected?"))?, ) } else { - socket - .recv(|buf| { - let result = dst.write(buf); - let len = result.unwrap_or(0); - (len, result) - }) - .map_err(|_| ax_err_type!(NotConnected, "not connected?"))? + let mut total = 0; + while socket.recv_queue() > 0 && dst.remaining_mut() > 0 { + let len = socket + .recv(|buf| { + let result = dst.write(buf); + let len = result.unwrap_or(0); + (len, result) + }) + .map_err(|_| ax_err_type!(NotConnected, "not connected?"))??; + if len == 0 { + break; + } + total += len; + } + Ok(total) } } else if !socket.may_recv() { Ok(0) From 434a46e42b70e6e697e240c5507bf1d3123e7ef7 Mon Sep 17 00:00:00 2001 From: ZCShou <72115@163.com> Date: Wed, 10 Jun 2026 16:13:10 +0800 Subject: [PATCH 05/11] fix(ax-net): safe timeout nanos conversion and remove legacy fs Unix namespace --- net/ax-net/src/lib.rs | 3 ++- net/ax-net/src/tcp.rs | 4 ++++ os/arceos/modules/axruntime/src/devices.rs | 6 +++--- os/arceos/modules/axruntime/src/unix_ns.rs | 18 ------------------ 4 files changed, 9 insertions(+), 22 deletions(-) diff --git a/net/ax-net/src/lib.rs b/net/ax-net/src/lib.rs index ffce962d30..557380c0ea 100644 --- a/net/ax-net/src/lib.rs +++ b/net/ax-net/src/lib.rs @@ -302,7 +302,8 @@ impl DnsSocketGuard { })?; let start_time = ax_hal::time::monotonic_time_nanos(); - let deadline = start_time.saturating_add(timeout.as_nanos() as u64); + let timeout_ns = u64::try_from(timeout.as_nanos()).unwrap_or(u64::MAX); + let deadline = start_time.saturating_add(timeout_ns); loop { poll_interfaces(); diff --git a/net/ax-net/src/tcp.rs b/net/ax-net/src/tcp.rs index a1596d6995..66ce5e4c4e 100644 --- a/net/ax-net/src/tcp.rs +++ b/net/ax-net/src/tcp.rs @@ -527,6 +527,10 @@ impl SocketOps for TcpSocket { .map_err(|_| ax_err_type!(NotConnected, "not connected?"))?, ) } else { + // Drain currently available bytes from RX queue without waiting. + // This loop copies across smoltcp's internal buffer segments to fill + // the user buffer with as many bytes as are ready, but does not block + // waiting for more data to arrive. let mut total = 0; while socket.recv_queue() > 0 && dst.remaining_mut() > 0 { let len = socket diff --git a/os/arceos/modules/axruntime/src/devices.rs b/os/arceos/modules/axruntime/src/devices.rs index 8080b54cd3..a2c44e717a 100644 --- a/os/arceos/modules/axruntime/src/devices.rs +++ b/os/arceos/modules/axruntime/src/devices.rs @@ -103,14 +103,14 @@ pub(crate) fn init_static_net() { ax_net::init_network(take_static_net_drivers(), config); } -#[cfg(all(feature = "net", any(feature = "fs", feature = "fs-ng")))] +#[cfg(all(feature = "net", feature = "fs-ng"))] fn register_unix_namespace() { ax_net::unix::register_unix_namespace(crate::unix_ns::AxFsUnixNamespace); } -#[cfg(all(feature = "net", not(any(feature = "fs", feature = "fs-ng"))))] +#[cfg(all(feature = "net", not(feature = "fs-ng")))] fn register_unix_namespace() { - // No filesystem, Unix socket namespace not available + // Path-based Unix sockets require fs-ng namespace support } #[cfg(feature = "net")] diff --git a/os/arceos/modules/axruntime/src/unix_ns.rs b/os/arceos/modules/axruntime/src/unix_ns.rs index 77676efd10..dd4647a7b8 100644 --- a/os/arceos/modules/axruntime/src/unix_ns.rs +++ b/os/arceos/modules/axruntime/src/unix_ns.rs @@ -41,21 +41,3 @@ impl ax_net::unix::UnixNamespace for AxFsUnixNamespace { FS_CONTEXT.lock().remove_file(path) } } - -#[cfg(all(feature = "net", feature = "fs", not(feature = "fs-ng")))] -pub(crate) struct AxFsUnixNamespace; - -#[cfg(all(feature = "net", feature = "fs", not(feature = "fs-ng")))] -impl ax_net::unix::UnixNamespace for AxFsUnixNamespace { - fn resolve(&self, _path: &str) -> ax_errno::AxResult> { - Err(ax_errno::AxError::Unsupported) - } - - fn bind(&self, _path: &str) -> ax_errno::AxResult> { - Err(ax_errno::AxError::Unsupported) - } - - fn unbind(&self, path: &str) -> ax_errno::AxResult<()> { - ax_fs::api::remove_file(path) - } -} From 9f06fdf66ac3ecd257684d5766ca3c2617ca0a13 Mon Sep 17 00:00:00 2001 From: ZCShou <72115@163.com> Date: Wed, 10 Jun 2026 16:34:53 +0800 Subject: [PATCH 06/11] refactor(ax-net): remove smoltcp dependency from axruntime and config types --- Cargo.lock | 1 - net/ax-net/src/config.rs | 10 ++--- net/ax-net/src/lib.rs | 49 ++++++++++------------ net/ax-net/src/service.rs | 15 +++++-- net/ax-net/src/unix/namespace.rs | 3 +- os/arceos/modules/axruntime/Cargo.toml | 3 +- os/arceos/modules/axruntime/src/devices.rs | 5 +-- 7 files changed, 44 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 49cedd8f62..da6e54c03a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1191,7 +1191,6 @@ dependencies = [ "indoc", "rd-net", "rdrive", - "smoltcp 0.13.1", "spin 0.12.0", ] diff --git a/net/ax-net/src/config.rs b/net/ax-net/src/config.rs index fd30ca18c0..2cb7695ea7 100644 --- a/net/ax-net/src/config.rs +++ b/net/ax-net/src/config.rs @@ -1,6 +1,5 @@ use alloc::vec::Vec; - -use smoltcp::wire::{Ipv4Address, Ipv4Cidr}; +use core::net::Ipv4Addr; /// Network initialization configuration. #[derive(Debug, Clone, Default)] @@ -11,12 +10,13 @@ pub struct NetworkConfig { /// /// - In **static IP mode**: these are the primary DNS servers. /// - In **DHCP mode**: these are fallback servers, used only if DHCP doesn't provide DNS servers. - pub dns_servers: Vec, + pub dns_servers: Vec, } /// Static IP configuration. #[derive(Debug, Clone)] pub struct StaticIpConfig { - pub ip: Ipv4Cidr, - pub gateway: Ipv4Address, + pub ip: Ipv4Addr, + pub prefix_len: u8, + pub gateway: Ipv4Addr, } diff --git a/net/ax-net/src/lib.rs b/net/ax-net/src/lib.rs index 557380c0ea..123b2aaaae 100644 --- a/net/ax-net/src/lib.rs +++ b/net/ax-net/src/lib.rs @@ -68,7 +68,10 @@ pub use self::{ ArpEntry, EthernetDeviceList, EthernetDriver, NetDeviceError, NetDeviceResult, NetIrqEvents, NetRxBuffer, NetTxBuffer, RdNetDriver, }, - socket::*, + socket::{ + CMsgData, RecvFlags, RecvOptions, SendFlags, SendOptions, Shutdown, Socket, SocketAddrEx, + SocketOps, + }, }; use self::{ device::{EthernetDevice, LoopbackDevice}, @@ -81,7 +84,6 @@ use self::{ static LISTEN_TABLE: LazyLock = LazyLock::new(ListenTable::new); static SOCKET_SET: LazyLock = LazyLock::new(SocketSetWrapper::new); -static CONFIG: Once> = Once::new(); static SERVICE: Once> = Once::new(); static POLLING_INTERFACES: AtomicBool = AtomicBool::new(false); static POLL_AGAIN: AtomicBool = AtomicBool::new(false); @@ -102,7 +104,7 @@ fn get_service() -> ax_sync::MutexGuard<'static, Service> { /// /// Panics if called more than once, or if the configuration contains invalid values. pub fn init_network(mut net_devs: EthernetDeviceList, config: NetworkConfig) { - if CONFIG.get().is_some() { + if SERVICE.get().is_some() { panic!("init_network() called more than once"); } @@ -110,10 +112,10 @@ pub fn init_network(mut net_devs: EthernetDeviceList, config: NetworkConfig) { // Validate configuration if let Some(ref static_cfg) = config.static_ip { - if static_cfg.ip.address().is_unspecified() { + if static_cfg.ip.is_unspecified() { panic!("Invalid static IP: unspecified address"); } - if static_cfg.ip.prefix_len() > 32 { + if static_cfg.prefix_len > 32 { panic!("Invalid static IP: prefix length > 32"); } if static_cfg.gateway.is_unspecified() { @@ -126,8 +128,12 @@ pub fn init_network(mut net_devs: EthernetDeviceList, config: NetworkConfig) { } } - // Store configuration - CONFIG.call_once(|| Mutex::new(config.clone())); + // Convert DNS servers to smoltcp types + let static_dns: Vec = config + .dns_servers + .iter() + .map(|addr| Ipv4Address::from(addr.octets())) + .collect(); let mut router = Router::new(); let lo_dev = router.add_device(Box::new(LoopbackDevice::new())); @@ -148,7 +154,10 @@ pub fn init_network(mut net_devs: EthernetDeviceList, config: NetworkConfig) { info!(" use NIC 0: {:?}", dev.device_name()); let eth0_address = EthernetAddress(dev.mac_address()); - let eth0_ip = config.static_ip.as_ref().map(|cfg| cfg.ip); + let eth0_ip = config + .static_ip + .as_ref() + .map(|cfg| Ipv4Cidr::new(Ipv4Address::from(cfg.ip.octets()), cfg.prefix_len)); let eth0_dev = router.add_device(Box::new(EthernetDevice::new( "eth0".to_owned(), @@ -161,12 +170,12 @@ pub fn init_network(mut net_devs: EthernetDeviceList, config: NetworkConfig) { if let Some(static_cfg) = &config.static_ip { router.add_rule(Rule::new( Ipv4Cidr::new(Ipv4Address::UNSPECIFIED, 0).into(), - Some(static_cfg.gateway.into()), + Some(Ipv4Address::from(static_cfg.gateway.octets()).into()), eth0_dev, - static_cfg.ip.address().into(), + Ipv4Address::from(static_cfg.ip.octets()).into(), )); info!(" mode: static"); - info!(" ip: {}", static_cfg.ip); + info!(" ip: {}/{}", static_cfg.ip, static_cfg.prefix_len); info!(" gw: {}", static_cfg.gateway); } else { dhcp_dev = Some(eth0_dev); @@ -184,7 +193,7 @@ pub fn init_network(mut net_devs: EthernetDeviceList, config: NetworkConfig) { info!("Device: {}", dev.name()); } - let mut service = Service::new(router); + let mut service = Service::new(router, static_dns); service.iface.update_ip_addrs(|ip_addrs| { ip_addrs.push(lo_ip.into()).unwrap(); if let Some(eth0_ip) = eth0_ip { @@ -246,12 +255,7 @@ pub fn arp_entries() -> Vec { /// Priority: DHCP-provided servers take precedence over statically configured servers. /// If DHCP hasn't provided servers, falls back to the servers from `NetworkConfig`. pub fn dns_servers() -> Vec { - let servers = get_service().dns_servers(); - if servers.is_empty() { - configured_dns_servers() - } else { - servers - } + get_service().dns_servers() } const DNS_DEFAULT_TIMEOUT: Duration = Duration::from_secs(5); @@ -338,13 +342,6 @@ impl Drop for DnsSocketGuard { } } -fn configured_dns_servers() -> Vec { - CONFIG - .get() - .map(|cfg| cfg.lock().dns_servers.clone()) - .unwrap_or_default() -} - fn dhcp_bootstrap() { for _ in 0..DHCP_BOOTSTRAP_ATTEMPTS { poll_interfaces(); @@ -405,7 +402,7 @@ pub(crate) mod test_support { IpAddress::Ipv4(PEER_ADDR), )); - let mut service = Service::new(router); + let mut service = Service::new(router, Vec::new()); service.iface.update_ip_addrs(|ip_addrs| { ip_addrs.push(local_cidr.into()).unwrap(); ip_addrs.push(peer_cidr.into()).unwrap(); diff --git a/net/ax-net/src/service.rs b/net/ax-net/src/service.rs index e5636c90b7..6647df7c24 100644 --- a/net/ax-net/src/service.rs +++ b/net/ax-net/src/service.rs @@ -28,6 +28,7 @@ pub struct Service { router: Router, timeout: Option + Send>>>, dhcp: Option, + static_dns: Vec, } struct DhcpState { @@ -195,7 +196,7 @@ impl DhcpState { } } impl Service { - pub fn new(mut router: Router) -> Self { + pub fn new(mut router: Router, static_dns: Vec) -> Self { let config = smoltcp::iface::Config::new(HardwareAddress::Ip); let iface = Interface::new(config, &mut router, now()); @@ -204,6 +205,7 @@ impl Service { router, timeout: None, dhcp: None, + static_dns, } } @@ -223,10 +225,17 @@ impl Service { } pub fn dns_servers(&self) -> Vec { - self.dhcp + let dhcp_dns = self + .dhcp .as_ref() .map(|state| state.dns_servers.clone()) - .unwrap_or_default() + .unwrap_or_default(); + + if !dhcp_dns.is_empty() { + dhcp_dns + } else { + self.static_dns.clone() + } } pub fn poll(&mut self, sockets: &mut SocketSet) -> bool { diff --git a/net/ax-net/src/unix/namespace.rs b/net/ax-net/src/unix/namespace.rs index e39c8ff5d7..7a012570a3 100644 --- a/net/ax-net/src/unix/namespace.rs +++ b/net/ax-net/src/unix/namespace.rs @@ -36,8 +36,7 @@ pub(crate) fn with_namespace(f: impl FnOnce(&dyn UnixNamespace) -> AxResult f(&**ns), None => Err(ax_err_type!( Unsupported, - "Unix socket path operations require filesystem support (enable 'fs' or 'fs-ng' \ - feature)" + "Unix socket path operations require filesystem support (enable 'fs-ng' feature)" )), } } diff --git a/os/arceos/modules/axruntime/Cargo.toml b/os/arceos/modules/axruntime/Cargo.toml index 3e1522dda2..f741999a88 100644 --- a/os/arceos/modules/axruntime/Cargo.toml +++ b/os/arceos/modules/axruntime/Cargo.toml @@ -58,7 +58,7 @@ fs-ng = [ fs-ng-ext4 = ["fs-ng", "ax-fs-ng/ext4"] fs-ng-fat = ["fs-ng", "ax-fs-ng/fat"] input = ["dep:ax-input", "ax-driver/input"] -net = ["dep:ax-net", "dep:rd-net", "dep:smoltcp", "dep:spin", "dep:axklib", "ax-driver/net"] +net = ["dep:ax-net", "dep:rd-net", "dep:spin", "dep:axklib", "ax-driver/net"] vsock = ["net", "ax-net/vsock", "ax-driver/vsock"] [dependencies] @@ -91,5 +91,4 @@ chrono = {version = "0.4", default-features = false} indoc = "2" rd-net = { workspace = true, optional = true } rdrive.workspace = true -smoltcp = { workspace = true, optional = true } spin = {workspace = true, optional = true} diff --git a/os/arceos/modules/axruntime/src/devices.rs b/os/arceos/modules/axruntime/src/devices.rs index a2c44e717a..af40e57264 100644 --- a/os/arceos/modules/axruntime/src/devices.rs +++ b/os/arceos/modules/axruntime/src/devices.rs @@ -115,8 +115,6 @@ fn register_unix_namespace() { #[cfg(feature = "net")] fn parse_network_config() -> ax_net::NetworkConfig { - use smoltcp::wire::Ipv4Cidr; - macro_rules! env_or_default { ($key:literal) => { match option_env!($key) { @@ -132,7 +130,8 @@ fn parse_network_config() -> ax_net::NetworkConfig { let static_ip = if !IP.is_empty() && !GATEWAY.is_empty() { Some(ax_net::StaticIpConfig { - ip: Ipv4Cidr::new(IP.parse().expect("Invalid AX_IP"), 24), + ip: IP.parse().expect("Invalid AX_IP"), + prefix_len: 24, gateway: GATEWAY.parse().expect("Invalid AX_GW"), }) } else { From 527e86a9b3e162dc8bd486f794b0e82c2971b1f2 Mon Sep 17 00:00:00 2001 From: ZCShou <72115@163.com> Date: Wed, 10 Jun 2026 17:07:03 +0800 Subject: [PATCH 07/11] fix(ax-net): add missing Vec import in test_support module --- net/ax-net/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ax-net/src/lib.rs b/net/ax-net/src/lib.rs index 123b2aaaae..14aa329f27 100644 --- a/net/ax-net/src/lib.rs +++ b/net/ax-net/src/lib.rs @@ -355,7 +355,7 @@ fn dhcp_bootstrap() { #[cfg(test)] pub(crate) mod test_support { - use alloc::boxed::Box; + use alloc::{boxed::Box, vec::Vec}; use std::sync::{Mutex as StdMutex, MutexGuard, Once}; use ax_sync::Mutex; From 0a6d263920b0ab856e58aaed19665c1ca7633e7f Mon Sep 17 00:00:00 2001 From: ZCShou <72115@163.com> Date: Thu, 11 Jun 2026 10:03:27 +0800 Subject: [PATCH 08/11] refactor(ax-net): removed unused IP gateway and other configurations --- test-suit/arceos/c/build-aarch64-unknown-none-softfloat.toml | 3 --- .../arceos/c/build-loongarch64-unknown-none-softfloat.toml | 3 --- test-suit/arceos/c/build-riscv64gc-unknown-none-elf.toml | 3 --- test-suit/arceos/c/build-x86_64-unknown-none.toml | 3 --- .../arceos/rust/build-aarch64-unknown-none-softfloat.toml | 2 -- .../arceos/rust/build-loongarch64-unknown-none-softfloat.toml | 2 -- test-suit/arceos/rust/build-riscv64gc-unknown-none-elf.toml | 2 -- test-suit/arceos/rust/build-x86_64-unknown-none.toml | 2 -- .../build-aarch64-unknown-none-softfloat.toml | 1 - .../board-phytiumpi/build-aarch64-unknown-none-softfloat.toml | 1 - .../board-rdk-s100/build-aarch64-unknown-none-softfloat.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - .../normal/qemu/build-aarch64-unknown-none-softfloat.toml | 1 - .../normal/qemu/build-loongarch64-unknown-none-softfloat.toml | 1 - .../axvisor/normal/qemu/build-riscv64gc-unknown-none-elf.toml | 1 - .../axvisor/normal/qemu/build-x86_64-unknown-none-svm.toml | 1 - .../axvisor/normal/qemu/build-x86_64-unknown-none-vmx.toml | 1 - .../axvisor/uefi/qemu-nimbos/build-x86_64-unknown-none.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - .../qemu-smp1/build-aarch64-unknown-none-softfloat.toml | 1 - .../qemu-smp1/build-loongarch64-unknown-none-softfloat.toml | 1 - .../starryos/qemu-smp1/build-riscv64gc-unknown-none-elf.toml | 1 - test-suit/starryos/qemu-smp1/build-x86_64-unknown-none.toml | 1 - .../qemu-smp4/build-aarch64-unknown-none-softfloat.toml | 1 - .../qemu-smp4/build-loongarch64-unknown-none-softfloat.toml | 1 - .../starryos/qemu-smp4/build-riscv64gc-unknown-none-elf.toml | 1 - test-suit/starryos/qemu-smp4/build-x86_64-unknown-none.toml | 1 - 28 files changed, 40 deletions(-) diff --git a/test-suit/arceos/c/build-aarch64-unknown-none-softfloat.toml b/test-suit/arceos/c/build-aarch64-unknown-none-softfloat.toml index 4cfae4d3f2..3765ebafc4 100644 --- a/test-suit/arceos/c/build-aarch64-unknown-none-softfloat.toml +++ b/test-suit/arceos/c/build-aarch64-unknown-none-softfloat.toml @@ -15,6 +15,3 @@ log = "Info" max_cpu_num = 4 plat_dyn = true -[env] -AX_GW = "10.0.2.2" -AX_IP = "10.0.2.15" diff --git a/test-suit/arceos/c/build-loongarch64-unknown-none-softfloat.toml b/test-suit/arceos/c/build-loongarch64-unknown-none-softfloat.toml index 5ebb035e53..d9dedc8148 100644 --- a/test-suit/arceos/c/build-loongarch64-unknown-none-softfloat.toml +++ b/test-suit/arceos/c/build-loongarch64-unknown-none-softfloat.toml @@ -14,6 +14,3 @@ features = [ log = "Info" max_cpu_num = 4 -[env] -AX_GW = "10.0.2.2" -AX_IP = "10.0.2.15" diff --git a/test-suit/arceos/c/build-riscv64gc-unknown-none-elf.toml b/test-suit/arceos/c/build-riscv64gc-unknown-none-elf.toml index 96aa88605a..0627281da6 100644 --- a/test-suit/arceos/c/build-riscv64gc-unknown-none-elf.toml +++ b/test-suit/arceos/c/build-riscv64gc-unknown-none-elf.toml @@ -14,6 +14,3 @@ log = "Info" max_cpu_num = 4 plat_dyn = true -[env] -AX_GW = "10.0.2.2" -AX_IP = "10.0.2.15" diff --git a/test-suit/arceos/c/build-x86_64-unknown-none.toml b/test-suit/arceos/c/build-x86_64-unknown-none.toml index 96aa88605a..0627281da6 100644 --- a/test-suit/arceos/c/build-x86_64-unknown-none.toml +++ b/test-suit/arceos/c/build-x86_64-unknown-none.toml @@ -14,6 +14,3 @@ log = "Info" max_cpu_num = 4 plat_dyn = true -[env] -AX_GW = "10.0.2.2" -AX_IP = "10.0.2.15" diff --git a/test-suit/arceos/rust/build-aarch64-unknown-none-softfloat.toml b/test-suit/arceos/rust/build-aarch64-unknown-none-softfloat.toml index 200c01b15a..c5559449e5 100644 --- a/test-suit/arceos/rust/build-aarch64-unknown-none-softfloat.toml +++ b/test-suit/arceos/rust/build-aarch64-unknown-none-softfloat.toml @@ -5,7 +5,5 @@ log = "Info" max_cpu_num = 4 [env] -AX_GW = "10.0.2.2" -AX_IP = "10.0.2.15" BACKTRACE = "y" DWARF = "y" diff --git a/test-suit/arceos/rust/build-loongarch64-unknown-none-softfloat.toml b/test-suit/arceos/rust/build-loongarch64-unknown-none-softfloat.toml index e7116b6113..9272d677c5 100644 --- a/test-suit/arceos/rust/build-loongarch64-unknown-none-softfloat.toml +++ b/test-suit/arceos/rust/build-loongarch64-unknown-none-softfloat.toml @@ -6,7 +6,5 @@ log = "Info" max_cpu_num = 4 [env] -AX_GW = "10.0.2.2" -AX_IP = "10.0.2.15" BACKTRACE = "y" DWARF = "y" diff --git a/test-suit/arceos/rust/build-riscv64gc-unknown-none-elf.toml b/test-suit/arceos/rust/build-riscv64gc-unknown-none-elf.toml index b8bc1c602d..c6e49016db 100644 --- a/test-suit/arceos/rust/build-riscv64gc-unknown-none-elf.toml +++ b/test-suit/arceos/rust/build-riscv64gc-unknown-none-elf.toml @@ -3,7 +3,5 @@ log = "Info" max_cpu_num = 4 [env] -AX_GW = "10.0.2.2" -AX_IP = "10.0.2.15" BACKTRACE = "y" DWARF = "y" diff --git a/test-suit/arceos/rust/build-x86_64-unknown-none.toml b/test-suit/arceos/rust/build-x86_64-unknown-none.toml index 0d6bd3c44d..91f947ca9d 100644 --- a/test-suit/arceos/rust/build-x86_64-unknown-none.toml +++ b/test-suit/arceos/rust/build-x86_64-unknown-none.toml @@ -4,7 +4,5 @@ max_cpu_num = 4 plat_dyn = true [env] -AX_GW = "10.0.2.2" -AX_IP = "10.0.2.15" BACKTRACE = "y" DWARF = "y" diff --git a/test-suit/axvisor/normal/board-orangepi-5-plus/build-aarch64-unknown-none-softfloat.toml b/test-suit/axvisor/normal/board-orangepi-5-plus/build-aarch64-unknown-none-softfloat.toml index 2c5e5ea0bb..a7e39df1a9 100644 --- a/test-suit/axvisor/normal/board-orangepi-5-plus/build-aarch64-unknown-none-softfloat.toml +++ b/test-suit/axvisor/normal/board-orangepi-5-plus/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } features = [ "sdmmc", "rockchip-soc", diff --git a/test-suit/axvisor/normal/board-phytiumpi/build-aarch64-unknown-none-softfloat.toml b/test-suit/axvisor/normal/board-phytiumpi/build-aarch64-unknown-none-softfloat.toml index 228b9b5c1b..d0a6e74bdf 100644 --- a/test-suit/axvisor/normal/board-phytiumpi/build-aarch64-unknown-none-softfloat.toml +++ b/test-suit/axvisor/normal/board-phytiumpi/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } features = [ "fs", "phytium-mci", diff --git a/test-suit/axvisor/normal/board-rdk-s100/build-aarch64-unknown-none-softfloat.toml b/test-suit/axvisor/normal/board-rdk-s100/build-aarch64-unknown-none-softfloat.toml index e0b01c642d..53e5c86e0a 100644 --- a/test-suit/axvisor/normal/board-rdk-s100/build-aarch64-unknown-none-softfloat.toml +++ b/test-suit/axvisor/normal/board-rdk-s100/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } features = [ "ept-level-4", ] diff --git a/test-suit/axvisor/normal/board-roc-rk3568-pc/build-aarch64-unknown-none-softfloat.toml b/test-suit/axvisor/normal/board-roc-rk3568-pc/build-aarch64-unknown-none-softfloat.toml index 8ec7635bf3..089d66da64 100644 --- a/test-suit/axvisor/normal/board-roc-rk3568-pc/build-aarch64-unknown-none-softfloat.toml +++ b/test-suit/axvisor/normal/board-roc-rk3568-pc/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } features = [ "rockchip-sdhci", "rockchip-soc", diff --git a/test-suit/axvisor/normal/qemu/build-aarch64-unknown-none-softfloat.toml b/test-suit/axvisor/normal/qemu/build-aarch64-unknown-none-softfloat.toml index 6b1f2d5b29..e03329cb94 100644 --- a/test-suit/axvisor/normal/qemu/build-aarch64-unknown-none-softfloat.toml +++ b/test-suit/axvisor/normal/qemu/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } features = [ "ept-level-4", "ax-driver/virtio-blk", diff --git a/test-suit/axvisor/normal/qemu/build-loongarch64-unknown-none-softfloat.toml b/test-suit/axvisor/normal/qemu/build-loongarch64-unknown-none-softfloat.toml index 1e7fa7e04b..40f32d2aeb 100644 --- a/test-suit/axvisor/normal/qemu/build-loongarch64-unknown-none-softfloat.toml +++ b/test-suit/axvisor/normal/qemu/build-loongarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-driver/virtio-blk", "ax-driver/plat-static", diff --git a/test-suit/axvisor/normal/qemu/build-riscv64gc-unknown-none-elf.toml b/test-suit/axvisor/normal/qemu/build-riscv64gc-unknown-none-elf.toml index 1d973b490f..54d4a2453f 100644 --- a/test-suit/axvisor/normal/qemu/build-riscv64gc-unknown-none-elf.toml +++ b/test-suit/axvisor/normal/qemu/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } features = [ "ax-driver/virtio-blk", "ept-level-4", diff --git a/test-suit/axvisor/normal/qemu/build-x86_64-unknown-none-svm.toml b/test-suit/axvisor/normal/qemu/build-x86_64-unknown-none-svm.toml index fedc7b6baf..aad1792d10 100644 --- a/test-suit/axvisor/normal/qemu/build-x86_64-unknown-none-svm.toml +++ b/test-suit/axvisor/normal/qemu/build-x86_64-unknown-none-svm.toml @@ -1,4 +1,3 @@ -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } features = [ "ax-driver/virtio-blk", "fs", diff --git a/test-suit/axvisor/normal/qemu/build-x86_64-unknown-none-vmx.toml b/test-suit/axvisor/normal/qemu/build-x86_64-unknown-none-vmx.toml index 84fba77b91..856447cf04 100644 --- a/test-suit/axvisor/normal/qemu/build-x86_64-unknown-none-vmx.toml +++ b/test-suit/axvisor/normal/qemu/build-x86_64-unknown-none-vmx.toml @@ -1,4 +1,3 @@ -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } features = [ "ax-driver/virtio-blk", "ept-level-4", diff --git a/test-suit/axvisor/uefi/qemu-nimbos/build-x86_64-unknown-none.toml b/test-suit/axvisor/uefi/qemu-nimbos/build-x86_64-unknown-none.toml index 9bd7322f0b..3a4fd6303a 100644 --- a/test-suit/axvisor/uefi/qemu-nimbos/build-x86_64-unknown-none.toml +++ b/test-suit/axvisor/uefi/qemu-nimbos/build-x86_64-unknown-none.toml @@ -1,4 +1,3 @@ -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } features = [ "ax-driver/virtio-blk", "ept-level-4", diff --git a/test-suit/starryos/board-licheerv-nano-sg2002/build-riscv64gc-unknown-none-elf.toml b/test-suit/starryos/board-licheerv-nano-sg2002/build-riscv64gc-unknown-none-elf.toml index 5d1445e2fb..7653e5aa55 100644 --- a/test-suit/starryos/board-licheerv-nano-sg2002/build-riscv64gc-unknown-none-elf.toml +++ b/test-suit/starryos/board-licheerv-nano-sg2002/build-riscv64gc-unknown-none-elf.toml @@ -1,6 +1,5 @@ # Build-time config template for StarryOS on SG2002. target = "riscv64gc-unknown-none-elf" -env = {} features = [ "starry-kernel/sg2002", "axplat-dyn/thead-mae", diff --git a/test-suit/starryos/board-orangepi-5-plus/build-aarch64-unknown-none-softfloat.toml b/test-suit/starryos/board-orangepi-5-plus/build-aarch64-unknown-none-softfloat.toml index 3a3a986c62..3afd7029ea 100644 --- a/test-suit/starryos/board-orangepi-5-plus/build-aarch64-unknown-none-softfloat.toml +++ b/test-suit/starryos/board-orangepi-5-plus/build-aarch64-unknown-none-softfloat.toml @@ -1,7 +1,6 @@ # Build-time config template for StarryOS on Orange Pi 5 Plus. target = "aarch64-unknown-none-softfloat" # Runtime U-Boot settings live in `orangepi-5-plus-uboot.toml`. -env = {} features = [ "ax-driver/list-pci-devices", "ax-driver/rk3588-pcie", diff --git a/test-suit/starryos/qemu-smp1/build-aarch64-unknown-none-softfloat.toml b/test-suit/starryos/qemu-smp1/build-aarch64-unknown-none-softfloat.toml index ab894fa753..f8208d96d8 100644 --- a/test-suit/starryos/qemu-smp1/build-aarch64-unknown-none-softfloat.toml +++ b/test-suit/starryos/qemu-smp1/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/test-suit/starryos/qemu-smp1/build-loongarch64-unknown-none-softfloat.toml b/test-suit/starryos/qemu-smp1/build-loongarch64-unknown-none-softfloat.toml index b6e12457d5..6ed865c6e1 100644 --- a/test-suit/starryos/qemu-smp1/build-loongarch64-unknown-none-softfloat.toml +++ b/test-suit/starryos/qemu-smp1/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/test-suit/starryos/qemu-smp1/build-riscv64gc-unknown-none-elf.toml b/test-suit/starryos/qemu-smp1/build-riscv64gc-unknown-none-elf.toml index b2e43b5c44..e04592a40a 100644 --- a/test-suit/starryos/qemu-smp1/build-riscv64gc-unknown-none-elf.toml +++ b/test-suit/starryos/qemu-smp1/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/rtc", "ax-driver/serial", diff --git a/test-suit/starryos/qemu-smp1/build-x86_64-unknown-none.toml b/test-suit/starryos/qemu-smp1/build-x86_64-unknown-none.toml index c0a13184ac..3100c648fb 100644 --- a/test-suit/starryos/qemu-smp1/build-x86_64-unknown-none.toml +++ b/test-suit/starryos/qemu-smp1/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/test-suit/starryos/qemu-smp4/build-aarch64-unknown-none-softfloat.toml b/test-suit/starryos/qemu-smp4/build-aarch64-unknown-none-softfloat.toml index 972d749a8a..a7f4e3dfab 100644 --- a/test-suit/starryos/qemu-smp4/build-aarch64-unknown-none-softfloat.toml +++ b/test-suit/starryos/qemu-smp4/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/test-suit/starryos/qemu-smp4/build-loongarch64-unknown-none-softfloat.toml b/test-suit/starryos/qemu-smp4/build-loongarch64-unknown-none-softfloat.toml index fb74bee24c..dd131724b4 100644 --- a/test-suit/starryos/qemu-smp4/build-loongarch64-unknown-none-softfloat.toml +++ b/test-suit/starryos/qemu-smp4/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/test-suit/starryos/qemu-smp4/build-riscv64gc-unknown-none-elf.toml b/test-suit/starryos/qemu-smp4/build-riscv64gc-unknown-none-elf.toml index 97f12de562..5c0776a3da 100644 --- a/test-suit/starryos/qemu-smp4/build-riscv64gc-unknown-none-elf.toml +++ b/test-suit/starryos/qemu-smp4/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/rtc", "ax-driver/serial", diff --git a/test-suit/starryos/qemu-smp4/build-x86_64-unknown-none.toml b/test-suit/starryos/qemu-smp4/build-x86_64-unknown-none.toml index d011f5668f..844177089a 100644 --- a/test-suit/starryos/qemu-smp4/build-x86_64-unknown-none.toml +++ b/test-suit/starryos/qemu-smp4/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", From 96aad923392cdfc47fc5307d7b6fe98846e968a5 Mon Sep 17 00:00:00 2001 From: ZCShou <72115@163.com> Date: Thu, 11 Jun 2026 10:15:14 +0800 Subject: [PATCH 09/11] refactor(ax-net): fix removed unused IP gateway and other configurations --- scripts/axbuild/src/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/axbuild/src/build.rs b/scripts/axbuild/src/build.rs index 9d7f2dce32..71df4c1228 100644 --- a/scripts/axbuild/src/build.rs +++ b/scripts/axbuild/src/build.rs @@ -85,6 +85,7 @@ impl AxFeaturePrefixFamily { #[derive(Debug, Clone, JsonSchema, Deserialize, Serialize, PartialEq)] pub struct BuildInfo { /// Environment variables to set during the build. + #[serde(default, skip_serializing_if = "HashMap::is_empty")] pub env: HashMap, /// Cargo features to enable. pub features: Vec, From ef3dd649c658afc654adc1f10869744b94da1229 Mon Sep 17 00:00:00 2001 From: ZCShou <72115@163.com> Date: Thu, 11 Jun 2026 11:54:20 +0800 Subject: [PATCH 10/11] refactor(ax-net): fix IP env --- .../build-aarch64-unknown-none-softfloat.toml | 4 -- ...ld-loongarch64-unknown-none-softfloat.toml | 4 -- .../build-riscv64gc-unknown-none-elf.toml | 4 -- apps/arceos/build-x86_64-unknown-none.toml | 3 -- .../claw-code/build-x86_64-unknown-none.toml | 1 - .../codex-cli/build-x86_64-unknown-none.toml | 1 - .../build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../diffutils/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../ebpf/kret/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../mytrace/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../profile/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../build-x86_64-unknown-none.toml | 1 - .../ebpf/upb/build-x86_64-unknown-none.toml | 1 - .../ffmpeg/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../gcc/build-riscv64gc-unknown-none-elf.toml | 1 - .../starry/gcc/build-x86_64-unknown-none.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../git/build-riscv64gc-unknown-none-elf.toml | 1 - .../starry/git/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../build-x86_64-unknown-none.toml | 1 - .../jcode/build-x86_64-unknown-none.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../llama-cpp/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../mariadb/build-x86_64-unknown-none.toml | 1 - .../mosquitto/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../build-x86_64-unknown-none.toml | 1 - .../mysql/build-x86_64-unknown-none.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../nginx/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../openrc/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../openssh/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - .../build-x86_64-unknown-none.toml | 1 - .../starry/pip/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../postgresql/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../qemu/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 2 +- ...ld-loongarch64-unknown-none-softfloat.toml | 2 +- .../build-riscv64gc-unknown-none-elf.toml | 2 +- .../build-x86_64-unknown-none.toml | 2 +- .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../qemu/nvme/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../redis/build-x86_64-unknown-none.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../git-https/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../git-remote/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../git-rename/build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../git/build-riscv64gc-unknown-none-elf.toml | 1 - .../stress/git/build-x86_64-unknown-none.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../build-x86_64-unknown-none.toml | 1 - .../build-aarch64-unknown-none-softfloat.toml | 1 - ...ld-loongarch64-unknown-none-softfloat.toml | 1 - .../build-riscv64gc-unknown-none-elf.toml | 1 - .../build-x86_64-unknown-none.toml | 1 - net/ax-net/src/config.rs | 9 ++++ net/ax-net/src/lib.rs | 6 ++- net/ax-net/src/router.rs | 26 +++++++++++ net/ax-net/src/service.rs | 8 +++- os/StarryOS/kernel/src/file/net.rs | 43 +++++++++---------- os/StarryOS/kernel/src/file/packet.rs | 39 +++-------------- scripts/axbuild/src/build.rs | 25 ++++++++--- 131 files changed, 97 insertions(+), 198 deletions(-) diff --git a/apps/arceos/build-aarch64-unknown-none-softfloat.toml b/apps/arceos/build-aarch64-unknown-none-softfloat.toml index d23dc6bf50..975af06170 100644 --- a/apps/arceos/build-aarch64-unknown-none-softfloat.toml +++ b/apps/arceos/build-aarch64-unknown-none-softfloat.toml @@ -2,7 +2,3 @@ features = [] log = "Info" max_cpu_num = 1 plat_dyn = true - -[env] -AX_GW = "10.0.2.2" -AX_IP = "10.0.2.15" diff --git a/apps/arceos/build-loongarch64-unknown-none-softfloat.toml b/apps/arceos/build-loongarch64-unknown-none-softfloat.toml index 3b060cfc2d..10596d7efe 100644 --- a/apps/arceos/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/arceos/build-loongarch64-unknown-none-softfloat.toml @@ -3,7 +3,3 @@ features = [ ] log = "Info" max_cpu_num = 1 - -[env] -AX_GW = "10.0.2.2" -AX_IP = "10.0.2.15" diff --git a/apps/arceos/build-riscv64gc-unknown-none-elf.toml b/apps/arceos/build-riscv64gc-unknown-none-elf.toml index d23dc6bf50..975af06170 100644 --- a/apps/arceos/build-riscv64gc-unknown-none-elf.toml +++ b/apps/arceos/build-riscv64gc-unknown-none-elf.toml @@ -2,7 +2,3 @@ features = [] log = "Info" max_cpu_num = 1 plat_dyn = true - -[env] -AX_GW = "10.0.2.2" -AX_IP = "10.0.2.15" diff --git a/apps/arceos/build-x86_64-unknown-none.toml b/apps/arceos/build-x86_64-unknown-none.toml index ad417dfc24..2a01e777a4 100644 --- a/apps/arceos/build-x86_64-unknown-none.toml +++ b/apps/arceos/build-x86_64-unknown-none.toml @@ -4,6 +4,3 @@ log = "Info" max_cpu_num = 1 plat_dyn = true -[env] -AX_GW = "10.0.2.2" -AX_IP = "10.0.2.15" diff --git a/apps/starry/claw-code/build-x86_64-unknown-none.toml b/apps/starry/claw-code/build-x86_64-unknown-none.toml index 69285236dd..495b9b162d 100644 --- a/apps/starry/claw-code/build-x86_64-unknown-none.toml +++ b/apps/starry/claw-code/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = {} log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/codex-cli/build-x86_64-unknown-none.toml b/apps/starry/codex-cli/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/codex-cli/build-x86_64-unknown-none.toml +++ b/apps/starry/codex-cli/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/deepseek-tui/build-x86_64-unknown-none.toml b/apps/starry/deepseek-tui/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/deepseek-tui/build-x86_64-unknown-none.toml +++ b/apps/starry/deepseek-tui/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/diffutils/build-aarch64-unknown-none-softfloat.toml b/apps/starry/diffutils/build-aarch64-unknown-none-softfloat.toml index 5764a5aba9..e717532f46 100644 --- a/apps/starry/diffutils/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/diffutils/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "qemu", "ax-driver/virtio-blk", diff --git a/apps/starry/diffutils/build-riscv64gc-unknown-none-elf.toml b/apps/starry/diffutils/build-riscv64gc-unknown-none-elf.toml index a5d9bbb2ed..011d71b654 100644 --- a/apps/starry/diffutils/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/diffutils/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/diffutils/build-x86_64-unknown-none.toml b/apps/starry/diffutils/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/diffutils/build-x86_64-unknown-none.toml +++ b/apps/starry/diffutils/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/ebpf/kret/build-aarch64-unknown-none-softfloat.toml b/apps/starry/ebpf/kret/build-aarch64-unknown-none-softfloat.toml index d3aa7dc1a6..e3ee034bdf 100644 --- a/apps/starry/ebpf/kret/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/ebpf/kret/build-aarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "aarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "qemu", diff --git a/apps/starry/ebpf/kret/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/ebpf/kret/build-loongarch64-unknown-none-softfloat.toml index b6e12457d5..6ed865c6e1 100644 --- a/apps/starry/ebpf/kret/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/ebpf/kret/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/ebpf/kret/build-riscv64gc-unknown-none-elf.toml b/apps/starry/ebpf/kret/build-riscv64gc-unknown-none-elf.toml index a5d9bbb2ed..011d71b654 100644 --- a/apps/starry/ebpf/kret/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/ebpf/kret/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/ebpf/kret/build-x86_64-unknown-none.toml b/apps/starry/ebpf/kret/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/ebpf/kret/build-x86_64-unknown-none.toml +++ b/apps/starry/ebpf/kret/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/ebpf/mytrace/build-aarch64-unknown-none-softfloat.toml b/apps/starry/ebpf/mytrace/build-aarch64-unknown-none-softfloat.toml index d3aa7dc1a6..e3ee034bdf 100644 --- a/apps/starry/ebpf/mytrace/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/ebpf/mytrace/build-aarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "aarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "qemu", diff --git a/apps/starry/ebpf/mytrace/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/ebpf/mytrace/build-loongarch64-unknown-none-softfloat.toml index b6e12457d5..6ed865c6e1 100644 --- a/apps/starry/ebpf/mytrace/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/ebpf/mytrace/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/ebpf/mytrace/build-riscv64gc-unknown-none-elf.toml b/apps/starry/ebpf/mytrace/build-riscv64gc-unknown-none-elf.toml index a5d9bbb2ed..011d71b654 100644 --- a/apps/starry/ebpf/mytrace/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/ebpf/mytrace/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/ebpf/mytrace/build-x86_64-unknown-none.toml b/apps/starry/ebpf/mytrace/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/ebpf/mytrace/build-x86_64-unknown-none.toml +++ b/apps/starry/ebpf/mytrace/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/ebpf/profile/build-aarch64-unknown-none-softfloat.toml b/apps/starry/ebpf/profile/build-aarch64-unknown-none-softfloat.toml index d3aa7dc1a6..e3ee034bdf 100644 --- a/apps/starry/ebpf/profile/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/ebpf/profile/build-aarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "aarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "qemu", diff --git a/apps/starry/ebpf/profile/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/ebpf/profile/build-loongarch64-unknown-none-softfloat.toml index b6e12457d5..6ed865c6e1 100644 --- a/apps/starry/ebpf/profile/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/ebpf/profile/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/ebpf/profile/build-riscv64gc-unknown-none-elf.toml b/apps/starry/ebpf/profile/build-riscv64gc-unknown-none-elf.toml index a5d9bbb2ed..011d71b654 100644 --- a/apps/starry/ebpf/profile/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/ebpf/profile/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/ebpf/profile/build-x86_64-unknown-none.toml b/apps/starry/ebpf/profile/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/ebpf/profile/build-x86_64-unknown-none.toml +++ b/apps/starry/ebpf/profile/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/ebpf/sched_trace/build-aarch64-unknown-none-softfloat.toml b/apps/starry/ebpf/sched_trace/build-aarch64-unknown-none-softfloat.toml index d3aa7dc1a6..e3ee034bdf 100644 --- a/apps/starry/ebpf/sched_trace/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/ebpf/sched_trace/build-aarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "aarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "qemu", diff --git a/apps/starry/ebpf/sched_trace/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/ebpf/sched_trace/build-loongarch64-unknown-none-softfloat.toml index b6e12457d5..6ed865c6e1 100644 --- a/apps/starry/ebpf/sched_trace/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/ebpf/sched_trace/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/ebpf/sched_trace/build-riscv64gc-unknown-none-elf.toml b/apps/starry/ebpf/sched_trace/build-riscv64gc-unknown-none-elf.toml index a5d9bbb2ed..011d71b654 100644 --- a/apps/starry/ebpf/sched_trace/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/ebpf/sched_trace/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/ebpf/sched_trace/build-x86_64-unknown-none.toml b/apps/starry/ebpf/sched_trace/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/ebpf/sched_trace/build-x86_64-unknown-none.toml +++ b/apps/starry/ebpf/sched_trace/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/ebpf/syscall_count/build-aarch64-unknown-none-softfloat.toml b/apps/starry/ebpf/syscall_count/build-aarch64-unknown-none-softfloat.toml index d3aa7dc1a6..e3ee034bdf 100644 --- a/apps/starry/ebpf/syscall_count/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/ebpf/syscall_count/build-aarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "aarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "qemu", diff --git a/apps/starry/ebpf/syscall_count/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/ebpf/syscall_count/build-loongarch64-unknown-none-softfloat.toml index b6e12457d5..6ed865c6e1 100644 --- a/apps/starry/ebpf/syscall_count/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/ebpf/syscall_count/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/ebpf/syscall_count/build-riscv64gc-unknown-none-elf.toml b/apps/starry/ebpf/syscall_count/build-riscv64gc-unknown-none-elf.toml index a5d9bbb2ed..011d71b654 100644 --- a/apps/starry/ebpf/syscall_count/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/ebpf/syscall_count/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/ebpf/syscall_count/build-x86_64-unknown-none.toml b/apps/starry/ebpf/syscall_count/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/ebpf/syscall_count/build-x86_64-unknown-none.toml +++ b/apps/starry/ebpf/syscall_count/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/ebpf/upb/build-x86_64-unknown-none.toml b/apps/starry/ebpf/upb/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/ebpf/upb/build-x86_64-unknown-none.toml +++ b/apps/starry/ebpf/upb/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/ffmpeg/build-x86_64-unknown-none.toml b/apps/starry/ffmpeg/build-x86_64-unknown-none.toml index 3173417cb3..ddc60195c8 100644 --- a/apps/starry/ffmpeg/build-x86_64-unknown-none.toml +++ b/apps/starry/ffmpeg/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/gcc/build-aarch64-unknown-none-softfloat.toml b/apps/starry/gcc/build-aarch64-unknown-none-softfloat.toml index b9c5247007..c1ba32be4f 100644 --- a/apps/starry/gcc/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/gcc/build-aarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "aarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "qemu", diff --git a/apps/starry/gcc/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/gcc/build-loongarch64-unknown-none-softfloat.toml index 407544ec74..f41e75fa04 100644 --- a/apps/starry/gcc/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/gcc/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/defplat", diff --git a/apps/starry/gcc/build-riscv64gc-unknown-none-elf.toml b/apps/starry/gcc/build-riscv64gc-unknown-none-elf.toml index 7f949700c8..4bb72445cb 100644 --- a/apps/starry/gcc/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/gcc/build-riscv64gc-unknown-none-elf.toml @@ -1,5 +1,4 @@ target = "riscv64gc-unknown-none-elf" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-feat/display", diff --git a/apps/starry/gcc/build-x86_64-unknown-none.toml b/apps/starry/gcc/build-x86_64-unknown-none.toml index 3e7b8895e7..7a891efdf5 100644 --- a/apps/starry/gcc/build-x86_64-unknown-none.toml +++ b/apps/starry/gcc/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/gdb-smoke/build-riscv64gc-unknown-none-elf.toml b/apps/starry/gdb-smoke/build-riscv64gc-unknown-none-elf.toml index a5d9bbb2ed..011d71b654 100644 --- a/apps/starry/gdb-smoke/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/gdb-smoke/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/git/build-aarch64-unknown-none-softfloat.toml b/apps/starry/git/build-aarch64-unknown-none-softfloat.toml index d3aa7dc1a6..e3ee034bdf 100644 --- a/apps/starry/git/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/git/build-aarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "aarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "qemu", diff --git a/apps/starry/git/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/git/build-loongarch64-unknown-none-softfloat.toml index b6e12457d5..6ed865c6e1 100644 --- a/apps/starry/git/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/git/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/git/build-riscv64gc-unknown-none-elf.toml b/apps/starry/git/build-riscv64gc-unknown-none-elf.toml index a5d9bbb2ed..011d71b654 100644 --- a/apps/starry/git/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/git/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/git/build-x86_64-unknown-none.toml b/apps/starry/git/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/git/build-x86_64-unknown-none.toml +++ b/apps/starry/git/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/glibc-dynamic-smoke/build-aarch64-unknown-none-softfloat.toml b/apps/starry/glibc-dynamic-smoke/build-aarch64-unknown-none-softfloat.toml index 10f1dae198..647fdbe086 100755 --- a/apps/starry/glibc-dynamic-smoke/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/glibc-dynamic-smoke/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-hal/aarch64-qemu-virt", "qemu", diff --git a/apps/starry/glibc-dynamic-smoke/build-riscv64gc-unknown-none-elf.toml b/apps/starry/glibc-dynamic-smoke/build-riscv64gc-unknown-none-elf.toml index 3307976592..083a7b18f4 100755 --- a/apps/starry/glibc-dynamic-smoke/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/glibc-dynamic-smoke/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-hal/riscv64-qemu-virt", "qemu", diff --git a/apps/starry/glibc-dynamic-smoke/build-x86_64-unknown-none.toml b/apps/starry/glibc-dynamic-smoke/build-x86_64-unknown-none.toml index d4108b7805..496d269c00 100755 --- a/apps/starry/glibc-dynamic-smoke/build-x86_64-unknown-none.toml +++ b/apps/starry/glibc-dynamic-smoke/build-x86_64-unknown-none.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-driver/virtio-blk", "ax-driver/virtio-net", diff --git a/apps/starry/jcode/build-x86_64-unknown-none.toml b/apps/starry/jcode/build-x86_64-unknown-none.toml index 3e7b8895e7..7a891efdf5 100644 --- a/apps/starry/jcode/build-x86_64-unknown-none.toml +++ b/apps/starry/jcode/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/k230-kpu-nncase/build-riscv64gc-unknown-none-elf.toml b/apps/starry/k230-kpu-nncase/build-riscv64gc-unknown-none-elf.toml index 11bab0c39f..01b0740c11 100644 --- a/apps/starry/k230-kpu-nncase/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/k230-kpu-nncase/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {} features = [ "k230", ] diff --git a/apps/starry/k230-qemu/qemu-k230/build-riscv64gc-unknown-none-elf.toml b/apps/starry/k230-qemu/qemu-k230/build-riscv64gc-unknown-none-elf.toml index 11bab0c39f..01b0740c11 100644 --- a/apps/starry/k230-qemu/qemu-k230/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/k230-qemu/qemu-k230/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {} features = [ "k230", ] diff --git a/apps/starry/llama-cpp/build-aarch64-unknown-none-softfloat.toml b/apps/starry/llama-cpp/build-aarch64-unknown-none-softfloat.toml index 5764a5aba9..e717532f46 100644 --- a/apps/starry/llama-cpp/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/llama-cpp/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "qemu", "ax-driver/virtio-blk", diff --git a/apps/starry/llama-cpp/build-riscv64gc-unknown-none-elf.toml b/apps/starry/llama-cpp/build-riscv64gc-unknown-none-elf.toml index a5d9bbb2ed..011d71b654 100644 --- a/apps/starry/llama-cpp/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/llama-cpp/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/llama-cpp/build-x86_64-unknown-none.toml b/apps/starry/llama-cpp/build-x86_64-unknown-none.toml index d4108b7805..496d269c00 100644 --- a/apps/starry/llama-cpp/build-x86_64-unknown-none.toml +++ b/apps/starry/llama-cpp/build-x86_64-unknown-none.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-driver/virtio-blk", "ax-driver/virtio-net", diff --git a/apps/starry/mariadb/build-aarch64-unknown-none-softfloat.toml b/apps/starry/mariadb/build-aarch64-unknown-none-softfloat.toml index 83e115b2df..ca7d6d9c19 100644 --- a/apps/starry/mariadb/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/mariadb/build-aarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "aarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } axconfig_overrides = ["plat.phys-memory-size=0x4000_0000"] log = "Warn" features = [ diff --git a/apps/starry/mariadb/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/mariadb/build-loongarch64-unknown-none-softfloat.toml index d03318eee1..b6dcf0bca3 100644 --- a/apps/starry/mariadb/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/mariadb/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } axconfig_overrides = ["plat.phys-memory-size=0x4000_0000"] log = "Warn" features = [ diff --git a/apps/starry/mariadb/build-riscv64gc-unknown-none-elf.toml b/apps/starry/mariadb/build-riscv64gc-unknown-none-elf.toml index 4a30d36fb6..42b6ebd2e6 100644 --- a/apps/starry/mariadb/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/mariadb/build-riscv64gc-unknown-none-elf.toml @@ -1,5 +1,4 @@ target = "riscv64gc-unknown-none-elf" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } axconfig_overrides = ["plat.phys-memory-size=0x4000_0000"] log = "Warn" features = [ diff --git a/apps/starry/mariadb/build-x86_64-unknown-none.toml b/apps/starry/mariadb/build-x86_64-unknown-none.toml index 141561c4e2..0392726d9b 100644 --- a/apps/starry/mariadb/build-x86_64-unknown-none.toml +++ b/apps/starry/mariadb/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } axconfig_overrides = ["plat.phys-memory-size=0x4000_0000"] log = "Warn" features = [ diff --git a/apps/starry/mosquitto/build-x86_64-unknown-none.toml b/apps/starry/mosquitto/build-x86_64-unknown-none.toml index 3173417cb3..ddc60195c8 100644 --- a/apps/starry/mosquitto/build-x86_64-unknown-none.toml +++ b/apps/starry/mosquitto/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/musl-dynamic-smoke/build-aarch64-unknown-none-softfloat.toml b/apps/starry/musl-dynamic-smoke/build-aarch64-unknown-none-softfloat.toml index 10f1dae198..647fdbe086 100755 --- a/apps/starry/musl-dynamic-smoke/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/musl-dynamic-smoke/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-hal/aarch64-qemu-virt", "qemu", diff --git a/apps/starry/musl-dynamic-smoke/build-riscv64gc-unknown-none-elf.toml b/apps/starry/musl-dynamic-smoke/build-riscv64gc-unknown-none-elf.toml index 3307976592..083a7b18f4 100755 --- a/apps/starry/musl-dynamic-smoke/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/musl-dynamic-smoke/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-hal/riscv64-qemu-virt", "qemu", diff --git a/apps/starry/musl-dynamic-smoke/build-x86_64-unknown-none.toml b/apps/starry/musl-dynamic-smoke/build-x86_64-unknown-none.toml index d4108b7805..496d269c00 100755 --- a/apps/starry/musl-dynamic-smoke/build-x86_64-unknown-none.toml +++ b/apps/starry/musl-dynamic-smoke/build-x86_64-unknown-none.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-driver/virtio-blk", "ax-driver/virtio-net", diff --git a/apps/starry/mysql/build-x86_64-unknown-none.toml b/apps/starry/mysql/build-x86_64-unknown-none.toml index dad0f44aa6..e6b4a715dc 100644 --- a/apps/starry/mysql/build-x86_64-unknown-none.toml +++ b/apps/starry/mysql/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } axconfig_overrides = ["plat.phys-memory-size=0x8000_0000"] log = "Warn" features = [ diff --git a/apps/starry/nginx/build-riscv64gc-unknown-none-elf.toml b/apps/starry/nginx/build-riscv64gc-unknown-none-elf.toml index fbda37b759..9bc2175f97 100644 --- a/apps/starry/nginx/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/nginx/build-riscv64gc-unknown-none-elf.toml @@ -1,5 +1,4 @@ target = "riscv64gc-unknown-none-elf" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-feat/rtc", diff --git a/apps/starry/nginx/build-x86_64-unknown-none.toml b/apps/starry/nginx/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/nginx/build-x86_64-unknown-none.toml +++ b/apps/starry/nginx/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/openrc/build-aarch64-unknown-none-softfloat.toml b/apps/starry/openrc/build-aarch64-unknown-none-softfloat.toml index d3aa7dc1a6..e3ee034bdf 100644 --- a/apps/starry/openrc/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/openrc/build-aarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "aarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "qemu", diff --git a/apps/starry/openrc/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/openrc/build-loongarch64-unknown-none-softfloat.toml index b6e12457d5..6ed865c6e1 100644 --- a/apps/starry/openrc/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/openrc/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/openrc/build-riscv64gc-unknown-none-elf.toml b/apps/starry/openrc/build-riscv64gc-unknown-none-elf.toml index a5d9bbb2ed..011d71b654 100644 --- a/apps/starry/openrc/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/openrc/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/openrc/build-x86_64-unknown-none.toml b/apps/starry/openrc/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/openrc/build-x86_64-unknown-none.toml +++ b/apps/starry/openrc/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/openssh/build-aarch64-unknown-none-softfloat.toml b/apps/starry/openssh/build-aarch64-unknown-none-softfloat.toml index d3aa7dc1a6..e3ee034bdf 100644 --- a/apps/starry/openssh/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/openssh/build-aarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "aarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "qemu", diff --git a/apps/starry/openssh/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/openssh/build-loongarch64-unknown-none-softfloat.toml index b6e12457d5..6ed865c6e1 100644 --- a/apps/starry/openssh/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/openssh/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/openssh/build-riscv64gc-unknown-none-elf.toml b/apps/starry/openssh/build-riscv64gc-unknown-none-elf.toml index a5d9bbb2ed..011d71b654 100644 --- a/apps/starry/openssh/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/openssh/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/openssh/build-x86_64-unknown-none.toml b/apps/starry/openssh/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/openssh/build-x86_64-unknown-none.toml +++ b/apps/starry/openssh/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/orangepi-5-plus-uvc-rknn/build-aarch64-unknown-none-softfloat.toml b/apps/starry/orangepi-5-plus-uvc-rknn/build-aarch64-unknown-none-softfloat.toml index 97f221b4a9..e873a0b10e 100644 --- a/apps/starry/orangepi-5-plus-uvc-rknn/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/orangepi-5-plus-uvc-rknn/build-aarch64-unknown-none-softfloat.toml @@ -1,6 +1,5 @@ # Build-time config for the Orange Pi 5 Plus UVC + RKNN Starry example. target = "aarch64-unknown-none-softfloat" -env = {} features = [ "ax-driver/irq", "ax-driver/list-pci-devices", diff --git a/apps/starry/orangepi-5-plus-uvc/build-aarch64-unknown-none-softfloat.toml b/apps/starry/orangepi-5-plus-uvc/build-aarch64-unknown-none-softfloat.toml index ef3f84f4a4..ef2422bece 100644 --- a/apps/starry/orangepi-5-plus-uvc/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/orangepi-5-plus-uvc/build-aarch64-unknown-none-softfloat.toml @@ -1,6 +1,5 @@ # Build-time config for the Orange Pi 5 Plus UVC Starry example. target = "aarch64-unknown-none-softfloat" -env = {} features = [ "ax-driver/rockchip-soc", "ax-driver/rockchip-dwc-xhci", diff --git a/apps/starry/picoclaw-cli/build-x86_64-unknown-none.toml b/apps/starry/picoclaw-cli/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/picoclaw-cli/build-x86_64-unknown-none.toml +++ b/apps/starry/picoclaw-cli/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/pip/build-x86_64-unknown-none.toml b/apps/starry/pip/build-x86_64-unknown-none.toml index 3173417cb3..ddc60195c8 100644 --- a/apps/starry/pip/build-x86_64-unknown-none.toml +++ b/apps/starry/pip/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/postgresql/build-aarch64-unknown-none-softfloat.toml b/apps/starry/postgresql/build-aarch64-unknown-none-softfloat.toml index 70722d076c..61763407e3 100644 --- a/apps/starry/postgresql/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/postgresql/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} axconfig_overrides = ["plat.phys-memory-size=0x4000_0000"] features = [ "ax-feat/display", diff --git a/apps/starry/postgresql/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/postgresql/build-loongarch64-unknown-none-softfloat.toml index 1124d2b986..b6dcf0bca3 100644 --- a/apps/starry/postgresql/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/postgresql/build-loongarch64-unknown-none-softfloat.toml @@ -1,6 +1,5 @@ target = "loongarch64-unknown-none-softfloat" axconfig_overrides = ["plat.phys-memory-size=0x4000_0000"] -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/postgresql/build-riscv64gc-unknown-none-elf.toml b/apps/starry/postgresql/build-riscv64gc-unknown-none-elf.toml index e9bead9e43..5dd2f65c56 100644 --- a/apps/starry/postgresql/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/postgresql/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} axconfig_overrides = ["plat.phys-memory-size=0x4000_0000"] features = [ "ax-feat/rtc", diff --git a/apps/starry/postgresql/build-x86_64-unknown-none.toml b/apps/starry/postgresql/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/postgresql/build-x86_64-unknown-none.toml +++ b/apps/starry/postgresql/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/qemu/build-aarch64-unknown-none-softfloat.toml b/apps/starry/qemu/build-aarch64-unknown-none-softfloat.toml index e48af09331..e31256e836 100644 --- a/apps/starry/qemu/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/qemu/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/qemu/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/qemu/build-loongarch64-unknown-none-softfloat.toml index b6e12457d5..6ed865c6e1 100644 --- a/apps/starry/qemu/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/qemu/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/qemu/build-riscv64gc-unknown-none-elf.toml b/apps/starry/qemu/build-riscv64gc-unknown-none-elf.toml index a5d9bbb2ed..011d71b654 100644 --- a/apps/starry/qemu/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/qemu/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/qemu/build-x86_64-unknown-none.toml b/apps/starry/qemu/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/qemu/build-x86_64-unknown-none.toml +++ b/apps/starry/qemu/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/qemu/memtrack-backtrace/build-aarch64-unknown-none-softfloat.toml b/apps/starry/qemu/memtrack-backtrace/build-aarch64-unknown-none-softfloat.toml index 78cee2dcff..e436597ee0 100644 --- a/apps/starry/qemu/memtrack-backtrace/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/qemu/memtrack-backtrace/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,4 @@ -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2", BACKTRACE = "y" } +env = { BACKTRACE = "y" } features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/qemu/memtrack-backtrace/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/qemu/memtrack-backtrace/build-loongarch64-unknown-none-softfloat.toml index 491b54f0ec..ab8e94993f 100644 --- a/apps/starry/qemu/memtrack-backtrace/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/qemu/memtrack-backtrace/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,5 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2", BACKTRACE = "y" } +env = { BACKTRACE = "y" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/qemu/memtrack-backtrace/build-riscv64gc-unknown-none-elf.toml b/apps/starry/qemu/memtrack-backtrace/build-riscv64gc-unknown-none-elf.toml index 76b131dcd9..fa9e01848f 100644 --- a/apps/starry/qemu/memtrack-backtrace/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/qemu/memtrack-backtrace/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,4 @@ -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2", BACKTRACE = "y" } +env = { BACKTRACE = "y" } features = [ "ax-feat/rtc", "ax-driver/serial", diff --git a/apps/starry/qemu/memtrack-backtrace/build-x86_64-unknown-none.toml b/apps/starry/qemu/memtrack-backtrace/build-x86_64-unknown-none.toml index 1c91478352..4343122c74 100644 --- a/apps/starry/qemu/memtrack-backtrace/build-x86_64-unknown-none.toml +++ b/apps/starry/qemu/memtrack-backtrace/build-x86_64-unknown-none.toml @@ -1,5 +1,5 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2", BACKTRACE = "y" } +env = { BACKTRACE = "y" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/qemu/nvme/build-aarch64-unknown-none-softfloat.toml b/apps/starry/qemu/nvme/build-aarch64-unknown-none-softfloat.toml index 9099cefce8..7a0437e523 100644 --- a/apps/starry/qemu/nvme/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/qemu/nvme/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "qemu", "ax-driver/plat-dyn", diff --git a/apps/starry/qemu/nvme/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/qemu/nvme/build-loongarch64-unknown-none-softfloat.toml index 396d5f286c..43e94f48e7 100644 --- a/apps/starry/qemu/nvme/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/qemu/nvme/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = {} log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/qemu/nvme/build-riscv64gc-unknown-none-elf.toml b/apps/starry/qemu/nvme/build-riscv64gc-unknown-none-elf.toml index 8bd6b28530..8daff402b7 100644 --- a/apps/starry/qemu/nvme/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/qemu/nvme/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/qemu/nvme/build-x86_64-unknown-none.toml b/apps/starry/qemu/nvme/build-x86_64-unknown-none.toml index 93bd6e1924..75f2644dfa 100644 --- a/apps/starry/qemu/nvme/build-x86_64-unknown-none.toml +++ b/apps/starry/qemu/nvme/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = {} log = "Warn" features = [ "ax-driver/nvme", diff --git a/apps/starry/redis/build-aarch64-unknown-none-softfloat.toml b/apps/starry/redis/build-aarch64-unknown-none-softfloat.toml index d3aa7dc1a6..e3ee034bdf 100644 --- a/apps/starry/redis/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/redis/build-aarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "aarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "qemu", diff --git a/apps/starry/redis/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/redis/build-loongarch64-unknown-none-softfloat.toml index b6e12457d5..6ed865c6e1 100644 --- a/apps/starry/redis/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/redis/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/redis/build-riscv64gc-unknown-none-elf.toml b/apps/starry/redis/build-riscv64gc-unknown-none-elf.toml index a5d9bbb2ed..011d71b654 100644 --- a/apps/starry/redis/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/redis/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/redis/build-x86_64-unknown-none.toml b/apps/starry/redis/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/redis/build-x86_64-unknown-none.toml +++ b/apps/starry/redis/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/selfhost/build-riscv64gc-unknown-none-elf.toml b/apps/starry/selfhost/build-riscv64gc-unknown-none-elf.toml index 388ceb47f5..4308fc2c70 100644 --- a/apps/starry/selfhost/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/selfhost/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-hal/riscv64-qemu-virt", "qemu", diff --git a/apps/starry/static-pie-test/build-riscv64gc-unknown-none-elf.toml b/apps/starry/static-pie-test/build-riscv64gc-unknown-none-elf.toml index a5d9bbb2ed..011d71b654 100644 --- a/apps/starry/static-pie-test/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/static-pie-test/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/stress/git-https/build-aarch64-unknown-none-softfloat.toml b/apps/starry/stress/git-https/build-aarch64-unknown-none-softfloat.toml index 0878dbe366..e31256e836 100644 --- a/apps/starry/stress/git-https/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/stress/git-https/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/stress/git-https/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/stress/git-https/build-loongarch64-unknown-none-softfloat.toml index b6e12457d5..6ed865c6e1 100644 --- a/apps/starry/stress/git-https/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/stress/git-https/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/stress/git-https/build-riscv64gc-unknown-none-elf.toml b/apps/starry/stress/git-https/build-riscv64gc-unknown-none-elf.toml index f1d9b9f7f9..cf0378656d 100644 --- a/apps/starry/stress/git-https/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/stress/git-https/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } features = [ "ax-feat/rtc", "ax-driver/serial", diff --git a/apps/starry/stress/git-https/build-x86_64-unknown-none.toml b/apps/starry/stress/git-https/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/stress/git-https/build-x86_64-unknown-none.toml +++ b/apps/starry/stress/git-https/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/stress/git-remote/build-aarch64-unknown-none-softfloat.toml b/apps/starry/stress/git-remote/build-aarch64-unknown-none-softfloat.toml index 8133cd47ab..a59bca0711 100644 --- a/apps/starry/stress/git-remote/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/stress/git-remote/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/stress/git-remote/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/stress/git-remote/build-loongarch64-unknown-none-softfloat.toml index b6e12457d5..6ed865c6e1 100644 --- a/apps/starry/stress/git-remote/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/stress/git-remote/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/stress/git-remote/build-riscv64gc-unknown-none-elf.toml b/apps/starry/stress/git-remote/build-riscv64gc-unknown-none-elf.toml index c6efc0a779..5e50b6b016 100644 --- a/apps/starry/stress/git-remote/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/stress/git-remote/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } features = [ "ax-feat/rtc", "ax-driver/rtc", diff --git a/apps/starry/stress/git-remote/build-x86_64-unknown-none.toml b/apps/starry/stress/git-remote/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/stress/git-remote/build-x86_64-unknown-none.toml +++ b/apps/starry/stress/git-remote/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/stress/git-rename/build-aarch64-unknown-none-softfloat.toml b/apps/starry/stress/git-rename/build-aarch64-unknown-none-softfloat.toml index cace6e7cee..098b0b21c4 100644 --- a/apps/starry/stress/git-rename/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/stress/git-rename/build-aarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "aarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-feat/display", diff --git a/apps/starry/stress/git-rename/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/stress/git-rename/build-loongarch64-unknown-none-softfloat.toml index b6e12457d5..6ed865c6e1 100644 --- a/apps/starry/stress/git-rename/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/stress/git-rename/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/stress/git-rename/build-riscv64gc-unknown-none-elf.toml b/apps/starry/stress/git-rename/build-riscv64gc-unknown-none-elf.toml index e6b038e3b3..9bcd8abf0c 100644 --- a/apps/starry/stress/git-rename/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/stress/git-rename/build-riscv64gc-unknown-none-elf.toml @@ -1,5 +1,4 @@ target = "riscv64gc-unknown-none-elf" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-feat/display", diff --git a/apps/starry/stress/git-rename/build-x86_64-unknown-none.toml b/apps/starry/stress/git-rename/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/stress/git-rename/build-x86_64-unknown-none.toml +++ b/apps/starry/stress/git-rename/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/stress/git/build-aarch64-unknown-none-softfloat.toml b/apps/starry/stress/git/build-aarch64-unknown-none-softfloat.toml index cace6e7cee..098b0b21c4 100644 --- a/apps/starry/stress/git/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/stress/git/build-aarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "aarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-feat/display", diff --git a/apps/starry/stress/git/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/stress/git/build-loongarch64-unknown-none-softfloat.toml index b6e12457d5..6ed865c6e1 100644 --- a/apps/starry/stress/git/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/stress/git/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/stress/git/build-riscv64gc-unknown-none-elf.toml b/apps/starry/stress/git/build-riscv64gc-unknown-none-elf.toml index e6b038e3b3..9bcd8abf0c 100644 --- a/apps/starry/stress/git/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/stress/git/build-riscv64gc-unknown-none-elf.toml @@ -1,5 +1,4 @@ target = "riscv64gc-unknown-none-elf" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-feat/display", diff --git a/apps/starry/stress/git/build-x86_64-unknown-none.toml b/apps/starry/stress/git/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/stress/git/build-x86_64-unknown-none.toml +++ b/apps/starry/stress/git/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/stress/openssl-loongarch/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/stress/openssl-loongarch/build-loongarch64-unknown-none-softfloat.toml index b6e12457d5..6ed865c6e1 100644 --- a/apps/starry/stress/openssl-loongarch/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/stress/openssl-loongarch/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/stress/sqlite3-deep/build-aarch64-unknown-none-softfloat.toml b/apps/starry/stress/sqlite3-deep/build-aarch64-unknown-none-softfloat.toml index f7cea5a393..e1d8a058b0 100644 --- a/apps/starry/stress/sqlite3-deep/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/stress/sqlite3-deep/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "qemu", "ax-driver/virtio-blk", diff --git a/apps/starry/stress/sqlite3-deep/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/stress/sqlite3-deep/build-loongarch64-unknown-none-softfloat.toml index c86176a471..5e68eb70d5 100644 --- a/apps/starry/stress/sqlite3-deep/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/stress/sqlite3-deep/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/stress/sqlite3-deep/build-riscv64gc-unknown-none-elf.toml b/apps/starry/stress/sqlite3-deep/build-riscv64gc-unknown-none-elf.toml index a5d9bbb2ed..011d71b654 100644 --- a/apps/starry/stress/sqlite3-deep/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/stress/sqlite3-deep/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/stress/sqlite3-deep/build-x86_64-unknown-none.toml b/apps/starry/stress/sqlite3-deep/build-x86_64-unknown-none.toml index f62d08b0b4..9e8663e016 100644 --- a/apps/starry/stress/sqlite3-deep/build-x86_64-unknown-none.toml +++ b/apps/starry/stress/sqlite3-deep/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/stress/sqlite3-smoke/build-aarch64-unknown-none-softfloat.toml b/apps/starry/stress/sqlite3-smoke/build-aarch64-unknown-none-softfloat.toml index f7cea5a393..e1d8a058b0 100644 --- a/apps/starry/stress/sqlite3-smoke/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/stress/sqlite3-smoke/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "qemu", "ax-driver/virtio-blk", diff --git a/apps/starry/stress/sqlite3-smoke/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/stress/sqlite3-smoke/build-loongarch64-unknown-none-softfloat.toml index c86176a471..5e68eb70d5 100644 --- a/apps/starry/stress/sqlite3-smoke/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/stress/sqlite3-smoke/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-hal/loongarch64-qemu-virt", diff --git a/apps/starry/stress/sqlite3-smoke/build-riscv64gc-unknown-none-elf.toml b/apps/starry/stress/sqlite3-smoke/build-riscv64gc-unknown-none-elf.toml index a5d9bbb2ed..011d71b654 100644 --- a/apps/starry/stress/sqlite3-smoke/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/stress/sqlite3-smoke/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} features = [ "ax-feat/display", "ax-feat/rtc", diff --git a/apps/starry/stress/sqlite3-smoke/build-x86_64-unknown-none.toml b/apps/starry/stress/sqlite3-smoke/build-x86_64-unknown-none.toml index f62d08b0b4..9e8663e016 100644 --- a/apps/starry/stress/sqlite3-smoke/build-x86_64-unknown-none.toml +++ b/apps/starry/stress/sqlite3-smoke/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/apps/starry/stress/stress-ng-0/build-aarch64-unknown-none-softfloat.toml b/apps/starry/stress/stress-ng-0/build-aarch64-unknown-none-softfloat.toml index 70722d076c..61763407e3 100644 --- a/apps/starry/stress/stress-ng-0/build-aarch64-unknown-none-softfloat.toml +++ b/apps/starry/stress/stress-ng-0/build-aarch64-unknown-none-softfloat.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} axconfig_overrides = ["plat.phys-memory-size=0x4000_0000"] features = [ "ax-feat/display", diff --git a/apps/starry/stress/stress-ng-0/build-loongarch64-unknown-none-softfloat.toml b/apps/starry/stress/stress-ng-0/build-loongarch64-unknown-none-softfloat.toml index d03318eee1..b6dcf0bca3 100644 --- a/apps/starry/stress/stress-ng-0/build-loongarch64-unknown-none-softfloat.toml +++ b/apps/starry/stress/stress-ng-0/build-loongarch64-unknown-none-softfloat.toml @@ -1,5 +1,4 @@ target = "loongarch64-unknown-none-softfloat" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } axconfig_overrides = ["plat.phys-memory-size=0x4000_0000"] log = "Warn" features = [ diff --git a/apps/starry/stress/stress-ng-0/build-riscv64gc-unknown-none-elf.toml b/apps/starry/stress/stress-ng-0/build-riscv64gc-unknown-none-elf.toml index e9bead9e43..5dd2f65c56 100644 --- a/apps/starry/stress/stress-ng-0/build-riscv64gc-unknown-none-elf.toml +++ b/apps/starry/stress/stress-ng-0/build-riscv64gc-unknown-none-elf.toml @@ -1,4 +1,3 @@ -env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"} axconfig_overrides = ["plat.phys-memory-size=0x4000_0000"] features = [ "ax-feat/rtc", diff --git a/apps/starry/stress/stress-ng-0/build-x86_64-unknown-none.toml b/apps/starry/stress/stress-ng-0/build-x86_64-unknown-none.toml index fc678caaa9..495b9b162d 100644 --- a/apps/starry/stress/stress-ng-0/build-x86_64-unknown-none.toml +++ b/apps/starry/stress/stress-ng-0/build-x86_64-unknown-none.toml @@ -1,5 +1,4 @@ target = "x86_64-unknown-none" -env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" } log = "Warn" features = [ "ax-driver/virtio-blk", diff --git a/net/ax-net/src/config.rs b/net/ax-net/src/config.rs index 2cb7695ea7..149361f04f 100644 --- a/net/ax-net/src/config.rs +++ b/net/ax-net/src/config.rs @@ -1,6 +1,8 @@ use alloc::vec::Vec; use core::net::Ipv4Addr; +use smoltcp::wire::{Ipv4Address, Ipv4Cidr}; + /// Network initialization configuration. #[derive(Debug, Clone, Default)] pub struct NetworkConfig { @@ -20,3 +22,10 @@ pub struct StaticIpConfig { pub prefix_len: u8, pub gateway: Ipv4Addr, } + +/// Runtime IPv4 configuration of a network interface. +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub struct Ipv4InterfaceConfig { + pub address: Ipv4Cidr, + pub gateway: Option, +} diff --git a/net/ax-net/src/lib.rs b/net/ax-net/src/lib.rs index 14aa329f27..a4444022cb 100644 --- a/net/ax-net/src/lib.rs +++ b/net/ax-net/src/lib.rs @@ -63,7 +63,7 @@ use spin::{LazyLock, Once}; #[cfg(feature = "vsock")] pub use self::device::{VsockDevice, VsockDeviceList}; pub use self::{ - config::{NetworkConfig, StaticIpConfig}, + config::{Ipv4InterfaceConfig, NetworkConfig, StaticIpConfig}, device::{ ArpEntry, EthernetDeviceList, EthernetDriver, NetDeviceError, NetDeviceResult, NetIrqEvents, NetRxBuffer, NetTxBuffer, RdNetDriver, @@ -250,6 +250,10 @@ pub fn arp_entries() -> Vec { get_service().arp_entries() } +pub fn eth0_ipv4_config() -> Option { + get_service().eth0_ipv4_config() +} + /// Returns the list of configured DNS servers. /// /// Priority: DHCP-provided servers take precedence over statically configured servers. diff --git a/net/ax-net/src/router.rs b/net/ax-net/src/router.rs index 8b974ec53d..aab831dd10 100644 --- a/net/ax-net/src/router.rs +++ b/net/ax-net/src/router.rs @@ -13,6 +13,7 @@ use smoltcp::{ use crate::{ LISTEN_TABLE, + config::Ipv4InterfaceConfig, consts::{SOCKET_BUFFER_SIZE, STANDARD_MTU}, device::{ArpEntry, Device}, }; @@ -165,6 +166,31 @@ impl Router { entries } + pub fn ipv4_config_for_dev(&self, dev: usize) -> Option { + self.table.rules.iter().find_map(|rule| match rule.filter { + IpCidr::Ipv4(address) if rule.dev == dev && address.prefix_len() != 0 => { + Some(Ipv4InterfaceConfig { + address, + gateway: self.table.rules.iter().find_map(|default_rule| { + matches!( + default_rule.filter, + IpCidr::Ipv4(filter) + if default_rule.dev == dev + && filter.address() == Ipv4Address::UNSPECIFIED + && filter.prefix_len() == 0 + ) + .then(|| match default_rule.via { + Some(IpAddress::Ipv4(gateway)) => Some(gateway), + _ => None, + }) + .flatten() + }), + }) + } + _ => None, + }) + } + pub fn dispatch(&mut self, timestamp: Instant) -> bool { let mut poll_next = false; while let Ok(((), packet)) = self.tx_buffer.dequeue() { diff --git a/net/ax-net/src/service.rs b/net/ax-net/src/service.rs index 6647df7c24..9dd522242c 100644 --- a/net/ax-net/src/service.rs +++ b/net/ax-net/src/service.rs @@ -17,7 +17,9 @@ use smoltcp::{ }, }; -use crate::{SOCKET_SET, consts::STANDARD_MTU, device::ArpEntry, router::Router}; +use crate::{ + SOCKET_SET, config::Ipv4InterfaceConfig, consts::STANDARD_MTU, device::ArpEntry, router::Router, +}; fn now() -> Instant { Instant::from_micros_const((wall_time_nanos() / NANOS_PER_MICROS) as i64) @@ -343,6 +345,10 @@ impl Service { self.router.arp_entries(now()) } + pub fn eth0_ipv4_config(&self) -> Option { + self.router.ipv4_config_for_dev(1) + } + pub fn device_mask_for(&self, endpoint: &IpListenEndpoint) -> u32 { match endpoint.addr { Some(addr) => self diff --git a/os/StarryOS/kernel/src/file/net.rs b/os/StarryOS/kernel/src/file/net.rs index 210a76235d..1924f25b8c 100644 --- a/os/StarryOS/kernel/src/file/net.rs +++ b/os/StarryOS/kernel/src/file/net.rs @@ -82,24 +82,25 @@ enum NetInterface { Loopback, } -fn configured_eth0_ipv4() -> [u8; 4] { - parse_ipv4_addr(option_env!("AX_IP").unwrap_or("10.0.2.15")).unwrap_or([10, 0, 2, 15]) +fn eth0_ipv4_config() -> AxResult { + axnet::eth0_ipv4_config().ok_or(AxError::NoSuchDevice) } -fn parse_ipv4_addr(value: &str) -> Option<[u8; 4]> { - let mut addr = [0; 4]; - let mut parts = value.split('.'); - for octet in &mut addr { - let part = parts.next()?; - if part.is_empty() { - return None; - } - *octet = part.parse().ok()?; - } - if parts.next().is_some() { - return None; +fn eth0_ipv4_addr() -> AxResult<[u8; 4]> { + Ok(eth0_ipv4_config()?.address.address().octets()) +} + +fn ipv4_netmask(prefix_len: u8) -> [u8; 4] { + if prefix_len == 0 { + return [0; 4]; } - Some(addr) + (!0u32 << (32 - prefix_len)).to_be_bytes() +} + +fn ipv4_broadcast(config: axnet::Ipv4InterfaceConfig) -> [u8; 4] { + let ip = u32::from_be_bytes(config.address.address().octets()); + let mask = u32::from_be_bytes(ipv4_netmask(config.address.prefix_len())); + (ip | !mask).to_be_bytes() } fn read_user_bytes(ptr: *const u8) -> AxResult<[u8; N]> { @@ -162,7 +163,7 @@ fn write_eth0_ifconf(arg: usize) -> AxResult<()> { if buf != 0 { let mut written = 0; if in_root_net_ns() && ifc_len >= IFREQ_COMPAT_LEN as i32 { - write_ifconf_entry(buf, written, ETH0_NAME, configured_eth0_ipv4())?; + write_ifconf_entry(buf, written, ETH0_NAME, eth0_ipv4_addr()?)?; written += IFREQ_COMPAT_LEN; } if ifc_len >= (written + IFREQ_COMPAT_LEN) as i32 { @@ -266,7 +267,7 @@ impl FileLike for Socket { } SIOCGIFADDR => { let addr = match read_ifreq_interface(arg)? { - NetInterface::Eth0 => configured_eth0_ipv4(), + NetInterface::Eth0 => eth0_ipv4_addr()?, NetInterface::Loopback => [127, 0, 0, 1], }; write_ifreq_sockaddr(arg, addr)?; @@ -280,18 +281,14 @@ impl FileLike for Socket { } SIOCGIFBRDADDR => { let addr = match read_ifreq_interface(arg)? { - NetInterface::Eth0 => { - let mut addr = configured_eth0_ipv4(); - addr[3] = 255; - addr - } + NetInterface::Eth0 => ipv4_broadcast(eth0_ipv4_config()?), NetInterface::Loopback => [127, 0, 0, 1], }; write_ifreq_sockaddr(arg, addr)?; } SIOCGIFNETMASK => { let addr = match read_ifreq_interface(arg)? { - NetInterface::Eth0 => [255, 255, 255, 0], + NetInterface::Eth0 => ipv4_netmask(eth0_ipv4_config()?.address.prefix_len()), NetInterface::Loopback => [255, 0, 0, 0], }; write_ifreq_sockaddr(arg, addr)?; diff --git a/os/StarryOS/kernel/src/file/packet.rs b/os/StarryOS/kernel/src/file/packet.rs index dfade47fe0..f3b5bebbfb 100644 --- a/os/StarryOS/kernel/src/file/packet.rs +++ b/os/StarryOS/kernel/src/file/packet.rs @@ -28,8 +28,6 @@ use crate::{ }; const ETH0_NAME: &[u8] = b"eth0"; const SYNTHETIC_PEER_HWADDR: [u8; 6] = [0x02, 0x00, 0x00, 0x00, 0x00, 0x02]; -const UNSPEC_IPV4: [u8; 4] = [0, 0, 0, 0]; - const ARPHRD_ETHER: u16 = 1; const ETH_P_IP: u16 = 0x0800; const ETH_P_ARP: u16 = 0x0806; @@ -205,21 +203,14 @@ fn build_arp_reply(request: &[u8]) -> Option { let request_sender_protocol: [u8; 4] = request[14..18].try_into().ok()?; let request_target_protocol: [u8; 4] = request[24..28].try_into().ok()?; - let modeled_peer_protocol = configured_peer_ipv4()?; - if request_target_protocol != modeled_peer_protocol { - return None; - } - if let Some(local_protocol) = configured_eth0_ipv4() - && request_sender_protocol != local_protocol - && request_sender_protocol != UNSPEC_IPV4 - { + if !is_modeled_peer_ipv4(request_target_protocol) { return None; } let mut reply = request.to_vec(); reply[6..8].copy_from_slice(&ARPOP_REPLY.to_be_bytes()); reply[8..14].copy_from_slice(&SYNTHETIC_PEER_HWADDR); - reply[14..18].copy_from_slice(&modeled_peer_protocol); + reply[14..18].copy_from_slice(&request_target_protocol); reply[18..24].copy_from_slice(&request[8..14]); reply[24..28].copy_from_slice(&request_sender_protocol); @@ -229,28 +220,10 @@ fn build_arp_reply(request: &[u8]) -> Option { Some(PacketFrame { data: reply, from }) } -fn configured_eth0_ipv4() -> Option<[u8; 4]> { - parse_ipv4_addr(option_env!("AX_IP")?) -} - -fn configured_peer_ipv4() -> Option<[u8; 4]> { - parse_ipv4_addr(option_env!("AX_GW")?) -} - -fn parse_ipv4_addr(value: &str) -> Option<[u8; 4]> { - let mut addr = [0; 4]; - let mut parts = value.split('.'); - for octet in &mut addr { - let part = parts.next()?; - if part.is_empty() { - return None; - } - *octet = part.parse().ok()?; - } - if parts.next().is_some() { - return None; - } - Some(addr) +fn is_modeled_peer_ipv4(ip: [u8; 4]) -> bool { + axnet::eth0_ipv4_config() + .and_then(|config| config.gateway) + .is_some_and(|gateway| gateway.octets() == ip) } fn read_user_bytes(ptr: *const u8) -> AxResult<[u8; N]> { diff --git a/scripts/axbuild/src/build.rs b/scripts/axbuild/src/build.rs index 71df4c1228..b8ee05d563 100644 --- a/scripts/axbuild/src/build.rs +++ b/scripts/axbuild/src/build.rs @@ -481,12 +481,8 @@ impl BuildInfo { impl Default for BuildInfo { fn default() -> Self { - let mut env = HashMap::new(); - env.insert("AX_IP".to_string(), "10.0.2.15".to_string()); - env.insert("AX_GW".to_string(), "10.0.2.2".to_string()); - Self { - env, + env: HashMap::new(), log: LogLevel::Warn, features: vec!["ax-std".to_string()], max_cpu_num: None, @@ -2086,6 +2082,25 @@ mod tests { assert!(build_info_enables_backtrace(&info)); } + #[test] + fn build_info_defaults_to_empty_env() { + let info = BuildInfo::default(); + assert!(info.env.is_empty()); + } + + #[test] + fn build_info_accepts_missing_env() { + let info: BuildInfo = toml::from_str( + r#" +features = [] +log = "Info" +"#, + ) + .unwrap(); + + assert!(info.env.is_empty()); + } + #[test] fn toolchain_rustflags_preserves_debug_and_backtrace_env() { let env = HashMap::from([("DWARF".to_string(), "1".to_string())]); From c276cb6593128ddf6a5ef3753df5c08765e3913e Mon Sep 17 00:00:00 2001 From: ZCShou <72115@163.com> Date: Thu, 11 Jun 2026 12:04:17 +0800 Subject: [PATCH 11/11] refactor(ax-net): optimize static ip or dynamic ip --- os/arceos/modules/axruntime/src/devices.rs | 38 +++++++++++++++++----- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/os/arceos/modules/axruntime/src/devices.rs b/os/arceos/modules/axruntime/src/devices.rs index af40e57264..2f38022a69 100644 --- a/os/arceos/modules/axruntime/src/devices.rs +++ b/os/arceos/modules/axruntime/src/devices.rs @@ -126,16 +126,38 @@ fn parse_network_config() -> ax_net::NetworkConfig { const IP: &str = env_or_default!("AX_IP"); const GATEWAY: &str = env_or_default!("AX_GW"); + const PREFIX_LEN: &str = env_or_default!("AX_PREFIX_LEN"); const DNS: &str = env_or_default!("AX_DNS"); - let static_ip = if !IP.is_empty() && !GATEWAY.is_empty() { - Some(ax_net::StaticIpConfig { - ip: IP.parse().expect("Invalid AX_IP"), - prefix_len: 24, - gateway: GATEWAY.parse().expect("Invalid AX_GW"), - }) - } else { - None + let ip = IP.trim(); + let gateway = GATEWAY.trim(); + let prefix_len = PREFIX_LEN.trim(); + + let static_ip = match (!ip.is_empty(), !gateway.is_empty()) { + (false, false) => { + if !prefix_len.is_empty() { + panic!("AX_PREFIX_LEN requires AX_IP and AX_GW"); + } + None + } + (true, true) => { + let prefix_len = if prefix_len.is_empty() { + 24 + } else { + prefix_len.parse().expect("Invalid AX_PREFIX_LEN") + }; + if prefix_len > 32 { + panic!("Invalid AX_PREFIX_LEN: prefix length > 32"); + } + Some(ax_net::StaticIpConfig { + ip: ip.parse().expect("Invalid AX_IP"), + prefix_len, + gateway: gateway.parse().expect("Invalid AX_GW"), + }) + } + _ => { + panic!("AX_IP and AX_GW must be configured together"); + } }; let dns_servers = DNS