Skip to content

Commit

Permalink
socket: add rtnetlink.rs for netlink route
Browse files Browse the repository at this point in the history
Signed-off-by: rayylee <[email protected]>
  • Loading branch information
hbuxiaofei committed Apr 8, 2024
1 parent 3de6536 commit 6843d0d
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 33 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion modules/axnet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ documentation = "https://rcore-os.github.io/arceos/axnet/index.html"

[features]
smoltcp = []
num_enum = []

# 启用ip协议与否
ip = []

default = ["smoltcp"]
default = ["smoltcp", "num_enum"]

[dependencies]
log = "0.4"
Expand All @@ -30,6 +31,10 @@ axtask = { path = "../axtask" }
axdriver = { path = "../axdriver", features = ["net"] }
axio = { path = "../../crates/axio" }

[dependencies.num_enum]
version = "0.5.11"
default-features = false

[dependencies.smoltcp]
git = "https://github.com/rcore-os/smoltcp.git"
rev = "2ade274"
Expand Down
2 changes: 1 addition & 1 deletion modules/axnet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub use smoltcp::time::Duration;
pub use smoltcp::wire::{IpAddress as IpAddr, IpEndpoint, Ipv4Address as Ipv4Addr};

mod netlink;
pub use netlink::NetlinkSocket;
pub use netlink::{NetlinkSocket, NetlinkProto};

use axdriver::{prelude::*, AxDeviceContainer};

Expand Down
37 changes: 33 additions & 4 deletions modules/axnet/src/netlink.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use num_enum::TryFromPrimitive;
extern crate alloc;
use alloc::sync::Arc;
use alloc::collections::VecDeque;
Expand All @@ -6,6 +7,30 @@ use core::cmp::min;
use axsync::Mutex;
use axerrno::AxResult;

#[derive(TryFromPrimitive, PartialEq, Eq, Clone, Debug)]
#[repr(usize)]
#[allow(non_camel_case_types)]
pub enum NetlinkProto {
/// Routing/device hook
NETLINK_ROUTE = 0,
/// Unused number
NETLINK_UNUSED = 1,
/// Reserved for user mode socket protocols
NETLINK_USERSOCK = 2,
/// Unused number, formerly ip_queu
NETLINK_FIREWALL = 3,
/// socket monitoring
NETLINK_SOCK_DIAG = 4,
/// netfilter/iptables ULOG
NETLINK_NFLOG = 5,
/// auditing
NETLINK_AUDIT = 9,
/// netfilter subsystem
NETLINK_NETFILTER = 12,
MAX_LINKS = 32,
}


struct NetlinkBuffer<T> {
buffer: VecDeque<T>,
capacity: usize,
Expand Down Expand Up @@ -40,23 +65,27 @@ impl<T> NetlinkBuffer<T> {
}

pub struct NetlinkSocket {
pub protocol: NetlinkProto,
pub nl_groups: u32,
pub nl_pid: u32,
rx_buffer: Arc<Mutex<NetlinkBuffer<u8>>>,
tx_buffer: Arc<Mutex<NetlinkBuffer<u8>>>,
pub nl_groups: u32,
}

impl NetlinkSocket {
pub fn new() -> Self {
pub fn new(protocol: NetlinkProto) -> Self {
NetlinkSocket {
protocol,
nl_groups: 64, // RTNLGRP_MAX ?
nl_pid: 0,
rx_buffer: Arc::new(Mutex::new(NetlinkBuffer::new(1024))),
tx_buffer: Arc::new(Mutex::new(NetlinkBuffer::new(1024))),
nl_groups: 0,
}
}

pub fn bind(&mut self, groups: u32) -> AxResult {
self.nl_groups = groups;
Ok(())
Ok(())
}

pub fn send(&self, buf: &[u8]) -> AxResult<usize> {
Expand Down
23 changes: 20 additions & 3 deletions ulib/axstarry/src/syscall_net/imp.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! 相关系统调用的具体实现
extern crate alloc;
use super::socket::*;
use super::netlink::*;
use super::rtnetlink::*;
use core::slice::{from_raw_parts, from_raw_parts_mut};

use alloc::sync::Arc;
Expand All @@ -21,7 +23,7 @@ pub const SOCKET_TYPE_MASK: usize = 0xFF;
pub fn syscall_socket(args: [usize; 6]) -> SyscallResult {
let domain = args[0];
let s_type = args[1];
let _protocol = args[2];
let protocol = args[2];
let Ok(domain) = Domain::try_from(domain) else {
error!("[socket()] Address Family not supported: {domain}");
// return ErrorNo::EAFNOSUPPORT as isize;
Expand All @@ -31,7 +33,7 @@ pub fn syscall_socket(args: [usize; 6]) -> SyscallResult {
// return ErrorNo::EINVAL as isize;
return Err(SyscallError::EINVAL);
};
let mut socket = Socket::new(domain, socket_type);
let mut socket = Socket::new(domain, socket_type, protocol);
if s_type & SOCK_NONBLOCK != 0 {
socket.set_nonblocking(true)
}
Expand Down Expand Up @@ -350,7 +352,22 @@ pub fn syscall_sendto(args: [usize; 6]) -> SyscallResult {
s.send(buf)
}
SocketInner::Netlink(s) => {
s.send(buf)
let ans = s.send(buf);
let addr = buf.as_ptr() as *const u16;
let nlh = unsafe {
NlMsgHdr {
nlmsg_len: *(addr as *const u32),
nlmsg_type: *(addr.add(2) as *const u16),
nlmsg_flags: *(addr.add(3) as *const u16),
nlmsg_seq: *(addr.add(4) as *const u32),
nlmsg_pid: *(addr.add(6) as *const u32),
}
};
error!(">>> nlmsg: {:?}", nlh);
if nlh.nlmsg_flags > 0 {
netlink_ack(&s, &nlh);
}
ans
}
};

Expand Down
2 changes: 1 addition & 1 deletion ulib/axstarry/src/syscall_net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mod net_syscall_id;
pub use net_syscall_id::NetSyscallId::{self, *};

mod netlink;
pub use netlink::netlink_unicast;
mod rtnetlink;

/// 进行 syscall 的分发
pub fn net_syscall(syscall_id: net_syscall_id::NetSyscallId, args: [usize; 6]) -> SyscallResult {
Expand Down
21 changes: 5 additions & 16 deletions ulib/axstarry/src/syscall_net/netlink.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
use axprocess::current_process;
use super::socket::{Socket, SocketInner};
use super::rtnetlink::*;
use axnet::NetlinkSocket;

pub fn netlink_unicast()
pub fn netlink_ack(sk: &NetlinkSocket, nlh: &NlMsgHdr)
{
let process = current_process();
let fd_table = process.fd_manager.fd_table.lock();

// # define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \
// (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \
// (nlh)->nlmsg_len <= (len))
Expand All @@ -19,17 +16,9 @@ pub fn netlink_unicast()
buffer[9] = 68; // 'D'
buffer[10] = 69; // 'E'

for i in 0..fd_table.len() {
if let Some(file) = fd_table[i].as_ref() {
if let Some(s_file) = file.as_any().downcast_ref::<Socket>() {
let inner = s_file.inner.lock();
if let SocketInner::Netlink(s) = &*inner {
let _ = s.fill_tx(&buffer);
}
}
}
if nlh.nlmsg_type == 18 || nlh.nlmsg_type == 20 {
let _ = sk.fill_tx(&buffer);
}

}


Expand Down
82 changes: 82 additions & 0 deletions ulib/axstarry/src/syscall_net/rtnetlink.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
extern crate alloc;
use alloc::{string::String, string::ToString, collections::BTreeMap, vec::Vec};

use axerrno::{AxError, AxResult};


pub struct SkBuff {
payload: Vec<u8>,
len: usize,
}

impl SkBuff {
pub fn new() -> SkBuff {
SkBuff {
payload: Vec::new(),
len: 0,
}
}

pub fn push_data(&mut self, data: &[u8]) {
self.payload.extend_from_slice(data);
self.len += data.len();
}

pub fn get_data(&self) -> &[u8] {
self.payload.as_slice()
}

pub fn length(&self) -> usize {
self.len
}
}


impl SkBuff {
pub fn skb_put(&mut self, data: &[u8]) {
self.push_data(data);
}

pub fn skb_pull(&mut self, len: usize) -> Option<Vec<u8>> {
if self.len < len {
None
} else {
let mut removed = Vec::with_capacity(len);
removed.extend(self.payload.drain(..len));
self.len -= len;
Some(removed)
}
}

pub fn skb_push(&mut self, data: &[u8]) {
let mut new_payload = Vec::with_capacity(data.len() + self.payload.len());
new_payload.extend_from_slice(data);
new_payload.append(&mut self.payload);
self.payload = new_payload;
self.len += data.len();
}

pub fn skb_trim(&mut self, len: usize) {
if self.len > len {
self.payload.truncate(len);
self.len = len;
}
}
}


#[derive(PartialEq, Eq, Clone, Debug)]
#[repr(C)]
pub struct NlMsgHdr {
pub nlmsg_len: u32,
pub nlmsg_type: u16,
pub nlmsg_flags: u16,
pub nlmsg_seq: u32,
pub nlmsg_pid: u32,
}

type FnPtr = fn(&mut SkBuff, &mut NlMsgHdr);

pub fn rtnl_getlink(skb: &mut SkBuff, nlh: &mut NlMsgHdr) -> AxResult {
Ok(())
}
19 changes: 12 additions & 7 deletions ulib/axstarry/src/syscall_net/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@ use axfs::api::{FileIO, FileIOType, OpenFlags, Read, Write};
use axlog::{warn, error};
use axnet::{
from_core_sockaddr, into_core_sockaddr, poll_interfaces, IpAddr, SocketAddr, TcpSocket,
UdpSocket, NetlinkSocket,
UdpSocket, NetlinkSocket, NetlinkProto,
};
use axsync::Mutex;
use num_enum::TryFromPrimitive;

use crate::TimeVal;

use super::netlink::netlink_unicast;

pub const SOCKET_TYPE_MASK: usize = 0xFF;

#[derive(TryFromPrimitive, Clone)]
Expand Down Expand Up @@ -373,6 +371,7 @@ impl TcpSocketOption {
pub struct Socket {
domain: Domain,
socket_type: SocketType,
protocol: usize,

/// Type of the socket protocol used
pub inner: Mutex<SocketInner>,
Expand Down Expand Up @@ -443,19 +442,25 @@ impl Socket {
*self.congestion.lock() = congestion;
}

/// Create a new socket with the given domain and socket type.
pub fn new(domain: Domain, socket_type: SocketType) -> Self {
/// Create a new socket with the given domain, socket type and protocol.
pub fn new(domain: Domain, socket_type: SocketType, protocol: usize) -> Self {
let inner = match socket_type {
SocketType::SOCK_STREAM | SocketType::SOCK_SEQPACKET => {
SocketInner::Tcp(TcpSocket::new())
}
SocketType::SOCK_DGRAM => SocketInner::Udp(UdpSocket::new()),
SocketType::SOCK_RAW => SocketInner::Netlink(NetlinkSocket::new()),
SocketType::SOCK_RAW => {
let Ok(proto) = NetlinkProto::try_from(protocol) else {
unimplemented!()
};
SocketInner::Netlink(NetlinkSocket::new(proto))
}
_ => unimplemented!(),
};
Self {
domain,
socket_type,
protocol,
inner: Mutex::new(inner),
close_exec: false,
recv_timeout: Mutex::new(None),
Expand Down Expand Up @@ -570,6 +575,7 @@ impl Socket {
Self {
domain: self.domain.clone(),
socket_type: self.socket_type.clone(),
protocol: self.protocol,
inner: Mutex::new(SocketInner::Tcp(new_socket)),
close_exec: false,
recv_timeout: Mutex::new(None),
Expand Down Expand Up @@ -616,7 +622,6 @@ impl Socket {

/// let the socket receive data and write it to the given buffer
pub fn recv_from(&self, buf: &mut [u8]) -> AxResult<(usize, SocketAddr)> {
netlink_unicast();
let inner = self.inner.lock();
match &*inner {
SocketInner::Tcp(s) => {
Expand Down

0 comments on commit 6843d0d

Please sign in to comment.