diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index bb74065..0c0b6e9 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -333,7 +333,7 @@ dependencies = [ "rcore-memory 0.1.0", "rcore-thread 0.1.0 (git+https://github.com/rcore-os/rcore-thread)", "riscv 0.5.0 (git+https://github.com/rcore-os/riscv)", - "smoltcp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smoltcp 0.5.0 (git+https://github.com/rcore-os/smoltcp)", "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "uart_16550 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "volatile 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -443,7 +443,7 @@ dependencies = [ [[package]] name = "smoltcp" version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" +source = "git+https://github.com/rcore-os/smoltcp#107d299b41a8f8cc370e3105dda38acc33609483" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -647,7 +647,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum skeptic 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "061203a849117b0f7090baf8157aa91dac30545208fbb85166ac58b4ca33d89c" -"checksum smoltcp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fef582369edb298c6c41319a544ca9c4e83622f226055ccfcb35974fbb55ed34" +"checksum smoltcp 0.5.0 (git+https://github.com/rcore-os/smoltcp)" = "" "checksum spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ceac490aa12c567115b40b7b7fceca03a6c9d53d5defea066123debc83c5dc1f" "checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" "checksum static_assertions 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "389ce475f424f267dbed6479cbd8f126c5e1afb053b0acdaa019c74305fc65d1" diff --git a/kernel/Makefile b/kernel/Makefile index e4bec12..c47efc1 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -62,8 +62,7 @@ endif ### qemu options ### qemu_opts := \ -smp cores=$(smp) -qemu_net_opts := \ - -netdev type=tap,id=net0,script=no,downscript=no +qemu_net_opts := ifeq ($(arch), x86_64) qemu_opts += \ @@ -76,6 +75,7 @@ qemu_opts += \ -device isa-debug-exit ifeq ($(pci_passthru), ) qemu_net_opts += \ + -netdev type=tap,id=net0,script=no,downscript=no \ -device e1000e,netdev=net0 else qemu_opts += \ @@ -96,6 +96,7 @@ qemu_opts += \ -drive file=$(SFSIMG),format=qcow2,id=sfs \ -device virtio-blk-device,drive=sfs qemu_net_opts += \ + -netdev type=tap,id=net0,script=no,downscript=no \ -device virtio-net-device,netdev=net0 else ifeq ($(arch), riscv64) @@ -105,6 +106,7 @@ qemu_opts += \ -drive file=$(SFSIMG),format=qcow2,id=sfs \ -device virtio-blk-device,drive=sfs qemu_net_opts += \ + -netdev type=tap,id=net0,script=no,downscript=no \ -device virtio-net-device,netdev=net0 else ifeq ($(arch), aarch64) diff --git a/kernel/src/drivers/bus/pci.rs b/kernel/src/drivers/bus/pci.rs index 1f76b3e..4da0626 100644 --- a/kernel/src/drivers/bus/pci.rs +++ b/kernel/src/drivers/bus/pci.rs @@ -132,9 +132,11 @@ pub fn init_driver(dev: &PCIDevice) { active_table().map_if_not_exists(KERNEL_OFFSET + current_addr, current_addr); current_addr = current_addr + PAGE_SIZE; } - PCI_DRIVERS - .lock() - .insert(dev.loc, ixgbe::ixgbe_init(name, irq, vaddr, len as usize)); + let index = NET_DRIVERS.read().len(); + PCI_DRIVERS.lock().insert( + dev.loc, + ixgbe::ixgbe_init(name, irq, vaddr, len as usize, index), + ); } } (0x8086, 0x2922) => { diff --git a/kernel/src/drivers/mod.rs b/kernel/src/drivers/mod.rs index c9c0cd5..661cfb6 100644 --- a/kernel/src/drivers/mod.rs +++ b/kernel/src/drivers/mod.rs @@ -3,7 +3,7 @@ use alloc::sync::Arc; use alloc::vec::Vec; use lazy_static::lazy_static; -use smoltcp::wire::{EthernetAddress, Ipv4Address}; +use smoltcp::wire::{EthernetAddress, IpAddress, Ipv4Address}; use spin::RwLock; use crate::sync::Condvar; @@ -71,6 +71,11 @@ pub trait Driver: Send + Sync { unimplemented!("not a net driver") } + // get mac address from ip address in arp table + fn get_arp(&self, ip: IpAddress) -> Option { + unimplemented!("not a net driver") + } + // block related drivers should implement these fn read_block(&self, block_id: usize, buf: &mut [u8]) -> bool { unimplemented!("not a block driver") diff --git a/kernel/src/drivers/net/e1000.rs b/kernel/src/drivers/net/e1000.rs index 39a9133..9bd3625 100644 --- a/kernel/src/drivers/net/e1000.rs +++ b/kernel/src/drivers/net/e1000.rs @@ -150,7 +150,6 @@ impl Driver for E1000Interface { } } - // send an ethernet frame, only use it when necessary fn send(&self, data: &[u8]) -> Option { use smoltcp::phy::TxToken; let token = E1000TxToken(self.driver.clone()); @@ -166,6 +165,12 @@ impl Driver for E1000Interface { None } } + + fn get_arp(&self, ip: IpAddress) -> Option { + let iface = self.iface.lock(); + let cache = iface.neighbor_cache(); + cache.lookup_pure(&ip, Instant::from_millis(0)) + } } #[repr(C)] @@ -493,7 +498,7 @@ pub fn e1000_init(name: String, irq: Option, header: usize, size: usize, in .neighbor_cache(neighbor_cache) .finalize(); - info!("e1000 interface {} has addr 10.0.{}.2/24", name, index); + info!("e1000 interface {} up with addr 10.0.{}.2/24", name, index); let e1000_iface = E1000Interface { iface: Mutex::new(iface), driver: net_driver.clone(), diff --git a/kernel/src/drivers/net/ixgbe.rs b/kernel/src/drivers/net/ixgbe.rs index 7e289f7..98eab21 100644 --- a/kernel/src/drivers/net/ixgbe.rs +++ b/kernel/src/drivers/net/ixgbe.rs @@ -100,6 +100,12 @@ impl Driver for IXGBEInterface { } } } + + fn get_arp(&self, ip: IpAddress) -> Option { + let iface = self.iface.lock(); + let cache = iface.neighbor_cache(); + cache.lookup_pure(&ip, Instant::from_millis(0)) + } } pub struct IXGBERxToken(Vec); pub struct IXGBETxToken(IXGBEDriver); @@ -171,6 +177,7 @@ pub fn ixgbe_init( irq: Option, header: usize, size: usize, + index: usize, ) -> Arc { let _ = FlagsGuard::no_irq_region(); let ixgbe = ixgbe::IXGBEDriver::init(Provider::new(), header, size); @@ -185,12 +192,9 @@ pub fn ixgbe_init( mtu: 1500, }; - let ip_addrs = [IpCidr::new(IpAddress::v4(10, 0, 0, 2), 24)]; + let ip_addrs = [IpCidr::new(IpAddress::v4(10, 0, index as u8, 2), 24)]; let neighbor_cache = NeighborCache::new(BTreeMap::new()); - let mut routes = Routes::new(BTreeMap::new()); - routes - .add_default_ipv4_route(Ipv4Address::new(10, 0, 0, 1)) - .unwrap(); + let routes = Routes::new(BTreeMap::new()); let mut iface = EthernetInterfaceBuilder::new(net_driver.clone()) .ethernet_addr(ethernet_addr) .ip_addrs(ip_addrs) @@ -198,7 +202,7 @@ pub fn ixgbe_init( .routes(routes) .finalize(); - info!("ixgbe: interface {} up", &name); + info!("ixgbe interface {} up with addr 10.0.{}.2/24", name, index); let ixgbe_iface = IXGBEInterface { iface: Mutex::new(iface), diff --git a/kernel/src/net/structs.rs b/kernel/src/net/structs.rs index 0331219..28f4970 100644 --- a/kernel/src/net/structs.rs +++ b/kernel/src/net/structs.rs @@ -505,7 +505,7 @@ impl Socket for UdpSocketState { // SIOCGARP 0x8954 => { // FIXME: check addr - let req = unsafe { &mut *(request as *mut ArpReq) }; + let req = unsafe { &mut *(arg1 as *mut ArpReq) }; if let AddressFamily::Internet = AddressFamily::from(req.arp_pa.family) { let name = req.arp_dev.as_ptr(); let ifname = unsafe { util::from_cstr(name) }; @@ -518,6 +518,14 @@ impl Socket for UdpSocketState { for iface in NET_DRIVERS.read().iter() { if iface.get_ifname() == ifname { debug!("get arp matched ifname {}", ifname); + return match iface.get_arp(addr) { + Some(mac) => { + // TODO: update flags + req.arp_ha.data[0..6].copy_from_slice(mac.as_bytes()); + Ok(0) + } + None => Err(SysError::ENOENT), + }; } } Err(SysError::ENOENT) diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 5f7d547..73e9d53 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -474,7 +474,7 @@ pub fn sys_dup2(fd1: usize, fd2: usize) -> SysResult { pub fn sys_ioctl(fd: usize, request: usize, arg1: usize, arg2: usize, arg3: usize) -> SysResult { info!( - "ioctl: fd:{}, request:{}, args: {} {} {}", + "ioctl: fd: {}, request: {}, args: {} {} {}", fd, request, arg1, arg2, arg3 ); let mut proc = process(); diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 658992e..70ba552 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -70,10 +70,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { warn!("sys_sigprocmask is unimplemented"); Ok(0) } - SYS_IOCTL => { - warn!("sys_ioctl is unimplemented"); - Ok(0) - } + SYS_IOCTL => sys_ioctl(args[0], args[1], args[2], args[3], args[4]), SYS_PREAD64 => sys_pread(args[0], args[1] as *mut u8, args[2], args[3]), SYS_PWRITE64 => sys_pwrite(args[0], args[1] as *const u8, args[2], args[3]), SYS_READV => sys_readv(args[0], args[1] as *const IoVec, args[2]),