Skip to content

Commit

Permalink
socket: support rtnl_dump_ifinfo for netlink route
Browse files Browse the repository at this point in the history
Signed-off-by: rayylee <rayylee@foxmail.com>
  • Loading branch information
hbuxiaofei committed Apr 10, 2024
1 parent 4abb99d commit f84ba78
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 38 deletions.
18 changes: 14 additions & 4 deletions ulib/axstarry/src/syscall_fs/ctype/eventfd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@ use axerrno::{AxError, AxResult};
use axfs::api::{FileIO, FileIOType, SeekFrom};
use axsync::Mutex;
use axtask::yield_now;
use axlog::error;

pub struct EventfdFile {
pub inner: Arc<Mutex<EventfdFileInner>>,
}

struct EventfdCtx {
count: u64,
flags: u32,
}

impl EventfdCtx {
pub fn new() -> Self {
pub fn new(count: u64, flags: u32) -> Self {
Self {
count: 0,
count,
flags,
}
}
}
Expand All @@ -27,17 +30,18 @@ pub struct EventfdFileInner {
}

impl EventfdFile {
pub fn new() -> Self {
pub fn new(count: u64, flags: u32) -> Self {
Self {
inner: Arc::new(Mutex::new(EventfdFileInner {
ctx: EventfdCtx::new(),
ctx: EventfdCtx::new(count, flags),
})),
}
}
}

impl FileIO for EventfdFile {
fn read(&self, buf: &mut [u8]) -> AxResult<usize> {
error!(">>> eventfd read start");
let mut cnt = 0;
loop {
let mut inner = self.inner.lock();
Expand All @@ -53,13 +57,19 @@ impl FileIO for EventfdFile {
let bytes = cnt.to_ne_bytes();
buf.copy_from_slice(&bytes);

error!(">>> eventfd read over");

Ok(size_of::<u64>())
}
fn write(&self, buf: &[u8]) -> AxResult<usize> {
error!(">>> eventfd write start");

let mut inner = self.inner.lock();
let ucnt: u64 = u64::from_ne_bytes(buf.try_into().unwrap());
inner.ctx.count += ucnt;

error!(">>> eventfd write over");

Ok(size_of::<u64>())
}
fn flush(&self) -> AxResult {
Expand Down
10 changes: 8 additions & 2 deletions ulib/axstarry/src/syscall_fs/imp/eventfd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@ extern crate alloc;
use alloc::sync::Arc;
use crate::{SyscallError, SyscallResult};
use axprocess::current_process;
use axlog::error;

use crate::syscall_fs::ctype::eventfd::{EventfdFile};

pub fn syscall_eventfd2(_args: [usize; 6]) -> SyscallResult {
let file = EventfdFile::new();
pub fn syscall_eventfd2(args: [usize; 6]) -> SyscallResult {
let initval = args[0];
let flags = args[1];

error!(">>> syscall eventfd called");

let file = EventfdFile::new(initval as u64, flags as u32);
let process = current_process();
let mut fd_table = process.fd_manager.fd_table.lock();
if let Ok(num) = process.alloc_fd(&mut fd_table) {
Expand Down
11 changes: 8 additions & 3 deletions ulib/axstarry/src/syscall_net/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ pub fn syscall_sendto(args: [usize; 6]) -> SyscallResult {
let inner = socket.inner.lock();
let send_result = match &*inner {
SocketInner::Udp(s) => {
error!(">>> udp sendto ");
// udp socket not bound
if s.local_addr().is_err() {
s.bind(into_core_sockaddr(SocketAddr::new_ipv4(
Expand All @@ -341,6 +342,7 @@ pub fn syscall_sendto(args: [usize; 6]) -> SyscallResult {
}
}
SocketInner::Tcp(s) => {
error!(">>> tcp sendto ");
if addr.is_some() {
return Err(SyscallError::EISCONN);
}
Expand All @@ -352,17 +354,17 @@ pub fn syscall_sendto(args: [usize; 6]) -> SyscallResult {
s.send(buf)
}
SocketInner::Netlink(s) => {
let ans = s.send(buf);
error!(">>> netlink sendto ");
// let ans = s.send(buf);
let buf_ptr: *const u8 = buf.as_ptr();
let nlh_ptr: *mut NlMsgHdr = buf_ptr as *mut NlMsgHdr;
let nlh: &mut NlMsgHdr = unsafe {
&mut *nlh_ptr
};
error!(">>> nlmsg: {:?}", nlh);
if nlh.nlmsg_flags > 0 {
netlink_ack(&s, nlh);
}
ans
Ok(buf.len())
}
};

Expand Down Expand Up @@ -455,6 +457,9 @@ pub fn syscall_set_sock_opt(args: [usize; 6]) -> SyscallResult {
let opt_name = args[2];
let opt_value = args[3] as *const u8;
let opt_len = args[4] as u32;

error!("syscall setsockopt called ...");

let Ok(level) = SocketOptionLevel::try_from(level) else {
error!("[setsockopt()] level {level} not supported");
unimplemented!();
Expand Down
39 changes: 33 additions & 6 deletions ulib/axstarry/src/syscall_net/netlink.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use alloc::vec::Vec;
use super::rtnetlink::*;
use axnet::NetlinkSocket;
use axlog::error;
use num_enum::TryFromPrimitive;
use super::rtnetlink::*;

Expand Down Expand Up @@ -47,16 +47,43 @@ pub fn netlink_ack(sk: &NetlinkSocket, nlh: &mut NlMsgHdr)
// (nlh)->nlmsg_len <= (len))

if let Ok(msg_type) = RtmType::try_from(nlh.nlmsg_type) {
if msg_type == RtmType::RTM_GETLINK || msg_type == RtmType::RTM_GETADDR {
if msg_type == RtmType::RTM_GETLINK {
let mut skb = SkBuff::new();
let _ = rtnl_getlink( &mut skb, nlh);
error!(">>> recv nlmsg_len:{} skb: {:?}", nlh.nlmsg_len, skb.get_data());
let _ = sk.fill_tx(skb.get_data());
// let _ = sk.fill_tx(skb.get_data());

let mut skb_done = SkBuff::new();
nlmsg_put(&mut skb_done, 0, nlh.nlmsg_seq + 1, 0x3, 0, 0); // NLMSG_DONE 0x3
// let _ = sk.fill_tx(skb_done.get_data());

let tx_buf1 = skb.get_data();
let tx_buf2 = skb_done.get_data();

let mut combined_vec = Vec::new();
combined_vec.extend_from_slice(tx_buf1);
combined_vec.extend_from_slice(tx_buf2);

let combined_slice: &[u8] = &combined_vec;
let _ = sk.fill_tx( combined_slice);
} else if msg_type == RtmType::RTM_GETADDR {
let mut skb = SkBuff::new();
let _ = rtnl_dump_ifinfo( &mut skb, nlh);
// let _ = sk.fill_tx(skb.get_data());

let mut skb_done = SkBuff::new();
nlmsg_put(&mut skb_done, 0, nlh.nlmsg_seq + 1, 0x3, 4, 0); // NLMSG_DONE 0x3
let _ = sk.fill_tx(skb_done.get_data());
}
// let _ = sk.fill_tx(skb_done.get_data());

let tx_buf1 = skb.get_data();
let tx_buf2 = skb_done.get_data();

let mut combined_vec = Vec::new();
combined_vec.extend_from_slice(tx_buf1);
combined_vec.extend_from_slice(tx_buf2);

let combined_slice: &[u8] = &combined_vec;
let _ = sk.fill_tx( combined_slice);
}
};
}

Expand Down
67 changes: 58 additions & 9 deletions ulib/axstarry/src/syscall_net/rtnetlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ use alloc::{vec, vec::Vec};
use axerrno::{AxError, AxResult};
use num_enum::TryFromPrimitive;

macro_rules! netlink_align {
($len:expr) => {
(($len + 3) & !3)
};
}

#[derive(TryFromPrimitive, PartialEq, Eq, Clone, Debug)]
#[repr(u16)]
#[allow(non_camel_case_types)]
Expand Down Expand Up @@ -32,6 +38,20 @@ pub enum IflaSpec {
IFLA_COST = 8,
}

#[derive(TryFromPrimitive, PartialEq, Eq, Clone, Debug)]
#[repr(u16)]
#[allow(non_camel_case_types)]
pub enum IfaSpec {
IFA_UNSPEC = 0,
IFA_ADDRESS = 1,
IFA_LOCAL = 2,
IFA_LABEL = 3,
IFA_BROADCAST = 4,
IFA_ANYCAST = 5,
IFA_CACHEINFO = 6,
IFA_MULTICAST = 7,
}

pub struct SkBuff {
payload: Vec<u8>,
len: usize,
Expand Down Expand Up @@ -94,6 +114,7 @@ impl SkBuff {


#[derive(PartialEq, Eq, Copy, Clone, Debug, Default)]
#[repr(align(4))]
#[repr(C)]
pub struct NlMsgHdr {
pub nlmsg_len: u32,
Expand Down Expand Up @@ -169,6 +190,13 @@ struct RtnlLinkStats {
}

fn nlmsg_end(skb: &mut SkBuff, nlh: &mut NlMsgHdr) -> usize {
let len = skb.length();
let align = netlink_align!(len) - len;
if align > 0 {
let v: Vec<u8> = vec![0; align];
skb.push_data(&v);
}

nlh.nlmsg_len = skb.length() as u32;

let ptr: *const u8 = skb.get_data().as_ptr();
Expand All @@ -181,11 +209,11 @@ fn nlmsg_end(skb: &mut SkBuff, nlh: &mut NlMsgHdr) -> usize {
skb.length()
}

fn nla_put_u8(skb: &mut SkBuff, attrtype: IflaSpec, buf: &[u8]) {
fn nla_put_u8(skb: &mut SkBuff, attrtype: u16, buf: &[u8]) {
let mut rtattr = RtAddr {
..Default::default()
};
rtattr.rta_type = attrtype as u16;
rtattr.rta_type = attrtype;
rtattr.rta_len = core::mem::size_of::<RtAddr>() as u16 + buf.len() as u16;

let ptr = &rtattr as *const RtAddr as *const u8;
Expand All @@ -197,12 +225,12 @@ fn nla_put_u8(skb: &mut SkBuff, attrtype: IflaSpec, buf: &[u8]) {
skb.skb_put(buf);
}

fn nla_put_u32(skb: &mut SkBuff, attrtype: IflaSpec, value: u32) {
fn nla_put_u32(skb: &mut SkBuff, attrtype: u16, value: u32) {
let bytes: [u8; 4] = value.to_ne_bytes();
nla_put_u8(skb, attrtype, &bytes);
}

fn nla_put_string(skb: &mut SkBuff, attrtype: IflaSpec, s: &str) {
fn nla_put_string(skb: &mut SkBuff, attrtype: u16, s: &str) {
let bytes = s.as_bytes();
nla_put_u8(skb, attrtype, &bytes);
}
Expand All @@ -222,7 +250,7 @@ pub fn nlmsg_put(skb: &mut SkBuff, portid: u32, seq: u32, ty: u16, len: u32, fla
};
skb.skb_put(nlh_buf);

let v: Vec<u8> = vec![0; len as usize];
let v: Vec<u8> = vec![0; netlink_align!(len) as usize];
skb.skb_put(&v[..]);
}

Expand All @@ -244,9 +272,9 @@ pub fn rtnl_getlink(skb: &mut SkBuff, nlh: &mut NlMsgHdr) -> AxResult {
};
skb.skb_put(ifinfomsg_buf);

nla_put_string(skb, IflaSpec::IFLA_IFNAME, "eth0");
nla_put_string(skb, IflaSpec::IFLA_IFNAME as u16, "eth0");

nla_put_u32(skb, IflaSpec::IFLA_MTU, 1500);
nla_put_u32(skb, IflaSpec::IFLA_MTU as u16, 1500);

let mut link_state = RtnlLinkStats {
..Default::default()
Expand All @@ -259,16 +287,37 @@ pub fn rtnl_getlink(skb: &mut SkBuff, nlh: &mut NlMsgHdr) -> AxResult {
let link_state_buf = unsafe {
core::slice::from_raw_parts(ptr, core::mem::size_of::<RtnlLinkStats>())
};
nla_put_u8(skb, IflaSpec::IFLA_STATS, &link_state_buf);
nla_put_u8(skb, IflaSpec::IFLA_STATS as u16, &link_state_buf);

let mac: [u8; 6] = [0x00, 0x0c, 0x29, 0xe9, 0xf2, 0x2e];
nla_put_u8(skb, IflaSpec::IFLA_ADDRESS, &mac);
nla_put_u8(skb, IflaSpec::IFLA_ADDRESS as u16, &mac);

nlmsg_end(skb, nlh);

Ok(())
}

pub fn rtnl_dump_ifinfo(skb: &mut SkBuff, nlh: &mut NlMsgHdr) -> AxResult {
nlh.nlmsg_type = RtmType::RTM_NEWADDR as u16;
let ptr = nlh as *const NlMsgHdr as *const u8;
let nlh_buf = unsafe {
core::slice::from_raw_parts(ptr, core::mem::size_of::<NlMsgHdr>())
};
skb.skb_put(nlh_buf);

let ifaddrmsg = IfAddrMsg {
..Default::default()
};
let ptr = &ifaddrmsg as *const IfAddrMsg as *const u8;
let ifaddrmsg_buf = unsafe {
core::slice::from_raw_parts(ptr, core::mem::size_of::<IfAddrMsg>())
};
skb.skb_put(ifaddrmsg_buf);

nla_put_string(skb, IfaSpec::IFA_LABEL as u16, "eth0");
nla_put_u32(skb, IfaSpec::IFA_ADDRESS as u16, 0);

nlmsg_end(skb, nlh);

Ok(())
}
Loading

0 comments on commit f84ba78

Please sign in to comment.