Add netlink socket skeleton

master
Jiajie Chen 6 years ago
parent 58932e0bee
commit 6335597897

@ -1,4 +1,3 @@
use alloc::boxed::Box;
use alloc::string::String;
use alloc::sync::Arc;
use core::cmp::min;

@ -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::*;

@ -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;

@ -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;

@ -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;

@ -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<Endpoint>) -> 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<dyn Socket> {
Box::new(self.clone())
}
}
fn get_ephemeral_port() -> u16 {
// TODO selects non-conflict high port
static mut EPHEMERAL_PORT: u16 = 0;

@ -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<dyn Socket> = 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::<u16>() + size_of::<SockAddrNl>() {
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,
}

Loading…
Cancel
Save