From 6335597897764f8571df75b22efa775d0276fa2a Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Sat, 6 Apr 2019 13:33:17 +0800 Subject: [PATCH] Add netlink socket skeleton --- kernel/src/drivers/block/virtio_blk.rs | 1 - kernel/src/drivers/bus/pci.rs | 1 - kernel/src/drivers/input/virtio_input.rs | 1 - kernel/src/drivers/net/e1000.rs | 1 - kernel/src/drivers/net/ixgbe.rs | 1 - kernel/src/net/structs.rs | 55 +++++++++++++++++++++++- kernel/src/syscall/net.rs | 47 ++++++++++++++------ 7 files changed, 89 insertions(+), 18 deletions(-) diff --git a/kernel/src/drivers/block/virtio_blk.rs b/kernel/src/drivers/block/virtio_blk.rs index b6cc9cb..c992aaf 100644 --- a/kernel/src/drivers/block/virtio_blk.rs +++ b/kernel/src/drivers/block/virtio_blk.rs @@ -1,4 +1,3 @@ -use alloc::boxed::Box; use alloc::string::String; use alloc::sync::Arc; use core::cmp::min; diff --git a/kernel/src/drivers/bus/pci.rs b/kernel/src/drivers/bus/pci.rs index b5fb798..c0de3bc 100644 --- a/kernel/src/drivers/bus/pci.rs +++ b/kernel/src/drivers/bus/pci.rs @@ -4,7 +4,6 @@ use crate::drivers::net::*; use crate::drivers::{Driver, DRIVERS, NET_DRIVERS}; use crate::memory::active_table; use alloc::collections::BTreeMap; -use alloc::string::String; use alloc::sync::Arc; use core::cmp::Ordering; use pci::*; diff --git a/kernel/src/drivers/input/virtio_input.rs b/kernel/src/drivers/input/virtio_input.rs index 9ff1587..fe16d45 100644 --- a/kernel/src/drivers/input/virtio_input.rs +++ b/kernel/src/drivers/input/virtio_input.rs @@ -2,7 +2,6 @@ use alloc::boxed::Box; use alloc::string::String; use alloc::sync::Arc; use alloc::vec; -use alloc::vec::Vec; use core::fmt; use core::mem::size_of; use core::mem::transmute_copy; diff --git a/kernel/src/drivers/net/e1000.rs b/kernel/src/drivers/net/e1000.rs index f51d90b..0dbcb0b 100644 --- a/kernel/src/drivers/net/e1000.rs +++ b/kernel/src/drivers/net/e1000.rs @@ -11,7 +11,6 @@ use smoltcp::phy::{self, DeviceCapabilities}; use smoltcp::time::Instant; use smoltcp::wire::*; use smoltcp::Result; -use volatile::Volatile; use isomorphic_drivers::net::ethernet::intel::e1000::E1000; use isomorphic_drivers::net::ethernet::structs::EthernetAddress as DriverEthernetAddress; diff --git a/kernel/src/drivers/net/ixgbe.rs b/kernel/src/drivers/net/ixgbe.rs index 72fd7c9..9cf4444 100644 --- a/kernel/src/drivers/net/ixgbe.rs +++ b/kernel/src/drivers/net/ixgbe.rs @@ -9,7 +9,6 @@ use alloc::collections::BTreeMap; use isomorphic_drivers::net::ethernet::intel::ixgbe; use log::*; use rcore_memory::paging::PageTable; -use rcore_memory::PAGE_SIZE; use smoltcp::iface::*; use smoltcp::phy::{self, Checksum, DeviceCapabilities}; use smoltcp::time::Instant; diff --git a/kernel/src/net/structs.rs b/kernel/src/net/structs.rs index 28f4970..4b45f65 100644 --- a/kernel/src/net/structs.rs +++ b/kernel/src/net/structs.rs @@ -21,10 +21,26 @@ impl LinkLevelEndpoint { } } +#[derive(Clone, Debug)] +pub struct NetlinkEndpoint { + port_id: u32, + multicast_groups_mask: u32, +} + +impl NetlinkEndpoint { + pub fn new(port_id: u32, multicast_groups_mask: u32) -> Self { + NetlinkEndpoint { + port_id, + multicast_groups_mask, + } + } +} + #[derive(Clone, Debug)] pub enum Endpoint { Ip(IpEndpoint), LinkLevel(LinkLevelEndpoint), + Netlink(NetlinkEndpoint), } /// Common methods that a socket must have @@ -98,8 +114,12 @@ pub struct RawSocketState { #[derive(Debug, Clone)] pub struct PacketSocketState { + // no state, only ethernet egress +} + +#[derive(Debug, Clone)] +pub struct NetlinkSocketState { // no state -// only ethernet egress } /// A wrapper for `SocketHandle`. @@ -718,6 +738,39 @@ impl Socket for PacketSocketState { } } +impl NetlinkSocketState { + pub fn new() -> Self { + NetlinkSocketState {} + } +} + +impl Socket for NetlinkSocketState { + fn read(&self, data: &mut [u8]) -> (SysResult, Endpoint) { + unimplemented!() + } + + fn write(&self, data: &[u8], _sendto_endpoint: Option) -> SysResult { + debug!("data: {:x?}", &data); + unimplemented!() + } + + fn poll(&self) -> (bool, bool, bool) { + unimplemented!() + } + + fn connect(&mut self, _endpoint: Endpoint) -> SysResult { + unimplemented!() + } + + fn bind(&mut self, _endpoint: Endpoint) -> SysResult { + Ok(0) + } + + fn box_clone(&self) -> Box { + Box::new(self.clone()) + } +} + fn get_ephemeral_port() -> u16 { // TODO selects non-conflict high port static mut EPHEMERAL_PORT: u16 = 0; diff --git a/kernel/src/syscall/net.rs b/kernel/src/syscall/net.rs index ad62598..cda2062 100644 --- a/kernel/src/syscall/net.rs +++ b/kernel/src/syscall/net.rs @@ -4,8 +4,8 @@ use super::*; use crate::drivers::SOCKET_ACTIVITY; use crate::fs::FileLike; use crate::net::{ - Endpoint, LinkLevelEndpoint, PacketSocketState, RawSocketState, Socket, TcpSocketState, - UdpSocketState, SOCKETS, + Endpoint, LinkLevelEndpoint, NetlinkEndpoint, NetlinkSocketState, PacketSocketState, + RawSocketState, Socket, TcpSocketState, UdpSocketState, SOCKETS, }; use crate::sync::{MutexGuard, SpinNoIrq, SpinNoIrqLock as Mutex}; use alloc::boxed::Box; @@ -15,24 +15,27 @@ use smoltcp::wire::*; pub fn sys_socket(domain: usize, socket_type: usize, protocol: usize) -> SysResult { let domain = AddressFamily::from(domain as u16); + let socket_type = SocketType::from(socket_type as u8 & SOCK_TYPE_MASK); info!( - "socket: domain: {:?}, socket_type: {}, protocol: {}", + "socket: domain: {:?}, socket_type: {:?}, protocol: {}", domain, socket_type, protocol ); let mut proc = process(); let socket: Box = match domain { - AddressFamily::Internet | AddressFamily::Unix => { - match SocketType::from(socket_type as u8 & SOCK_TYPE_MASK) { - SocketType::Stream => Box::new(TcpSocketState::new()), - SocketType::Datagram => Box::new(UdpSocketState::new()), - SocketType::Raw => Box::new(RawSocketState::new(protocol as u8)), - _ => return Err(SysError::EINVAL), - } - } - AddressFamily::Packet => match SocketType::from(socket_type as u8 & SOCK_TYPE_MASK) { + AddressFamily::Internet | AddressFamily::Unix => match socket_type { + SocketType::Stream => Box::new(TcpSocketState::new()), + SocketType::Datagram => Box::new(UdpSocketState::new()), + SocketType::Raw => Box::new(RawSocketState::new(protocol as u8)), + _ => return Err(SysError::EINVAL), + }, + AddressFamily::Packet => match socket_type { SocketType::Raw => Box::new(PacketSocketState::new()), _ => return Err(SysError::EINVAL), }, + AddressFamily::Netlink => match socket_type { + SocketType::Raw => Box::new(NetlinkSocketState::new()), + _ => return Err(SysError::EINVAL), + }, _ => return Err(SysError::EAFNOSUPPORT), }; let fd = proc.get_free_fd(); @@ -300,11 +303,20 @@ pub struct SockAddrLl { pub sll_addr: [u8; 8], } +// cancel alignment +#[repr(packed)] +pub struct SockAddrNl { + nl_pad: u16, + nl_pid: u32, + nl_groups: u32, +} + #[repr(C)] pub union SockAddrPayload { pub addr_in: SockAddrIn, pub addr_un: SockAddrUn, pub addr_ll: SockAddrLl, + pub addr_nl: SockAddrNl, } #[repr(C)] @@ -373,6 +385,15 @@ fn sockaddr_to_endpoint( (*addr).payload.addr_ll.sll_ifindex as usize, ))) } + AddressFamily::Netlink => { + if len < size_of::() + size_of::() { + return Err(SysError::EINVAL); + } + Ok(Endpoint::Netlink(NetlinkEndpoint::new( + (*addr).payload.addr_nl.nl_pid, + (*addr).payload.addr_nl.nl_groups, + ))) + } _ => Err(SysError::EINVAL), } } @@ -421,6 +442,8 @@ enum_with_unknown! { Unix = 1, /// Internet IP Protocol Internet = 2, + /// Netlink + Netlink = 16, /// Packet family Packet = 17, }