Skip to content

Commit e6b2cb7

Browse files
committed
WIP: NLA_HDRLEN is missing
1 parent e0ad809 commit e6b2cb7

File tree

5 files changed

+118
-15
lines changed

5 files changed

+118
-15
lines changed

Diff for: drivers/net/dummy_rs.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#![no_std]
1212
#![feature(allocator_api, global_asm)]
1313

14-
use kernel::prelude::*;
14+
use kernel::{net::netlink::{NlAttrVec, NlExtAck}, prelude::*};
1515
use kernel::net::prelude::*;
1616
use kernel::net::device;
1717

@@ -60,6 +60,15 @@ fn setup(dev: &mut NetDevice<DummyRsDev>) {
6060
dev.set_mtu(0, 0);
6161
}
6262

63+
fn validate(tb: &NlAttrVec, data: &NlAttrVec, ext_ack: &NlExtAck) -> KernelResult<()> {
64+
if let Some(addr) = tb.get(kernel::bindings::IFLA_ADDRESS) {
65+
if addr.nla_len() != kernel::binding::ETH_ALEN {
66+
return Err(0)
67+
}
68+
}
69+
Ok(())
70+
}
71+
6372
rtnl_link_ops! {
6473
kind: b"dummy_rs",
6574
type: DummyRsDev,
@@ -79,7 +88,8 @@ impl KernelModule for RustNetDummy {
7988
pr_info!("Rust Network Dummy with {} pseudo devices\n", numdummies.read(&lock));
8089
}
8190

82-
let dev = NetDevice::new(DummyRsDev, kernel::cstr!("dummyrs%d"), kernel::net::device::NetNameAssingType::Enum, 1, 1)?;
91+
let mut dev = NetDevice::new(DummyRsDev, kernel::cstr!("dummyrs%d"), kernel::net::device::NetNameAssingType::Enum, 1, 1)?;
92+
dev.set_rtnl_ops( unsafe { &dummy_rs_rtnl_link_ops });
8393

8494
if let Err(e) = dev.register() {
8595
pr_warn!("could not register: {}", e.to_kernel_errno());
@@ -122,9 +132,8 @@ impl NetDeviceAdapter for DummyRsDev {
122132

123133
fn setup(dev: &mut NetDevice<Self>) {
124134
pr_info!("called netdev_setup");
125-
//dev.rtnl_link_ops = unsafe { &dummy_rs_rtnl_link_ops as *const kernel::bindings::rtnl_link_ops as *mut _ };
126-
dev.set_rtnl_ops( unsafe { &dummy_rs_rtnl_link_ops });
127-
135+
setup(dev);
136+
//dev.set_rtnl_ops( unsafe { &dummy_rs_rtnl_link_ops });
128137
}
129138
}
130139

Diff for: rust/generate_rust_analyzer.sh

+5-5
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function generate_crate() {
2121
module=$2
2222
member=${3:-"true"}
2323
cfg=${4:-$(generate_cfgs)}
24-
deps=${5:-'[{"crate":0,"name":"core"},{"crate":2,"name":"alloc"},{"crate":3,"name":"kernel"}]'}
24+
deps=${5:-'[{"crate":0,"name":"core"},{"crate":2,"name":"alloc"},{"crate":4,"name":"kernel"}]'}
2525
extra=${EXTRA:-""}
2626

2727
echo "{
@@ -43,9 +43,6 @@ function generate_kernel() {
4343
generate_crate "alloc" "${lib_src}/alloc/src/lib.rs" "false" "[]" \
4444
'[{"crate":0,"name":"core"},{"crate":1,"name":"compiler_builtins"}]'
4545
echo ","
46-
EXTRA=$dylib_and_extra generate_crate "kernel" "${srctree}/rust/kernel/lib.rs" "true" "$(generate_cfgs)" \
47-
'[{"crate":0,"name":"core"},{"crate":2,"name":"alloc"}]'
48-
echo ","
4946
echo '{
5047
"display_name":"module",
5148
"root_module":"'${srctree}'/rust/module.rs",
@@ -54,7 +51,10 @@ function generate_kernel() {
5451
"deps": [],
5552
"cfg": []
5653
},'
57-
generate_crate "module" "${srctree}/rust/module.rs"
54+
EXTRA=$dylib_and_extra generate_crate "kernel" "${srctree}/rust/kernel/lib.rs" "true" "$(generate_cfgs)" \
55+
'[{"crate":0,"name":"core"},{"crate":2,"name":"alloc"},{"crate":3,"name":"module"}]'
56+
#echo ","
57+
#generate_crate "module" "${srctree}/rust/module.rs"
5858
echo ","
5959
}
6060

Diff for: rust/kernel/net/device.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -76,21 +76,26 @@ unsafe impl<T: NetDeviceAdapter> Sync for NetDevice<T> {}
7676

7777
impl<T: NetDeviceAdapter> NetDevice<T> {
7878
pub fn new(priv_data: T, format_name: CStr<'static>, name_assign_type: NetNameAssingType, txqs: u32, rxqs: u32) -> KernelResult<Self> {
79+
let _lock = RtnlLock::lock();
80+
// Lock is hold
81+
let dev = unsafe { Self::new_locked(priv_data, format_name, name_assign_type, txqs, rxqs) };
82+
dev
83+
}
84+
85+
pub unsafe fn new_locked(priv_data: T, format_name: CStr<'static>, name_assign_type: NetNameAssingType, txqs: u32, rxqs: u32) -> KernelResult<Self> {
7986
// TODO: check for {t,r}xqs bigger 0
8087
let size = mem::size_of::<T>() as i32;
8188

8289
// Safety: TODO
83-
let ptr = unsafe { bindings::alloc_netdev_mqs(size, format_name.as_ptr() as _, name_assign_type as u8, Some(setup_netdev_callback::<T>), txqs, rxqs) };
90+
let ptr = bindings::alloc_netdev_mqs(size, format_name.as_ptr() as _, name_assign_type as u8, Some(setup_netdev_callback::<T>), txqs, rxqs);
8491
if ptr.is_null() {
8592
return Err(Error::ENOMEM);
8693
}
8794

8895
if size != 0 {
8996
// Safety: T is valid and dest is created by alloc_netdev_mqs
90-
unsafe {
91-
let dest = rust_helper_netdev_priv(ptr) as *mut T;
92-
ptr::write(dest, priv_data);
93-
}
97+
let dest = rust_helper_netdev_priv(ptr) as *mut T;
98+
ptr::write(dest, priv_data);
9499
}
95100

96101
Ok(Self {

Diff for: rust/kernel/net/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
pub mod device;
33
pub mod ethtool;
44
pub mod rtnl;
5+
pub mod netlink;
56

67
#[doc(inline)]
78
pub use module::rtnl_link_ops;

Diff for: rust/kernel/net/netlink.rs

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
use alloc::vec::Vec;
3+
use core::ops::{Deref, DerefMut};
4+
5+
use crate::{bindings, linked_list::Wrapper};
6+
use crate::{c_types, CStr};
7+
use crate::error::{Error, KernelResult};
8+
use crate::sync::Lock;
9+
use crate::user_ptr::{UserSlicePtr, UserSlicePtrReader, UserSlicePtrWriter};
10+
11+
use super::device::{NetDeviceAdapter, NetDevice};
12+
13+
14+
/*#[repr(C)]
15+
pub struct NlAttr {
16+
nla_len: u16,
17+
nla_type: u16,
18+
}*/
19+
pub struct NlAttr(*const bindings::nlattr);
20+
21+
impl NlAttr {
22+
pub fn is_null(&self) -> bool {
23+
self.0.is_null()
24+
}
25+
26+
pub fn nla_len(&self) -> u16 {
27+
if self.is_null() {
28+
return 0;
29+
}
30+
31+
// NO-PANIC: self is valid and not null
32+
let nlattr = self.0.as_ref().unwrap();
33+
nlattr.nla_len - bindings::NLA_HDRLEN
34+
}
35+
36+
/// Constructs a new [`struct nlattr`] wrapper.
37+
///
38+
/// # Safety
39+
///
40+
/// The pointer `ptr` must be non-null and valid for the lifetime of the object.
41+
pub unsafe fn from_ptr(ptr: *const bindings::nlattr) -> Self {
42+
Self(ptr)
43+
}
44+
/*pub unsafe fn from_ptr(ptr: *const bindings::nlattr) -> &'static mut Self {
45+
(ptr as *mut NlAttr).as_mut().unwrap()
46+
}*/
47+
}
48+
49+
pub struct NlExtAck(*const bindings::netlink_ext_ack);
50+
51+
impl NlExtAck {
52+
/// Constructs a new [`struct netlink_ext_ack`] wrapper.
53+
///
54+
/// # Safety
55+
///
56+
/// The pointer `ptr` must be non-null and valid for the lifetime of the object.
57+
pub unsafe fn from_ptr(ptr: *const bindings::netlink_ext_ack) -> Self {
58+
Self(ptr)
59+
}
60+
}
61+
62+
pub struct NlAttrVec<'a>(&'a mut [NlAttr]);
63+
64+
impl<'a> NlAttrVec<'a> {
65+
pub fn get(&self, offset: u32) -> Option<NlAttr> {
66+
if offset > bindings::__IFLA_MAX {
67+
return None;
68+
}
69+
70+
let nlattr = self.0[offset as usize];
71+
if nlattr.is_null() {
72+
None
73+
} else {
74+
Some(nlattr)
75+
}
76+
}
77+
78+
/// Constructs a new [`struct nlattr[]`] wrapper.
79+
///
80+
/// # Safety
81+
///
82+
/// The pointer `ptr` must be non-null and valid for the lifetime of the object.
83+
/// The pointer `ptr` must be valid for the size of `__IFLA_MAX` * `mem::size_of<NlAttr>`
84+
pub unsafe fn from_ptr(ptr: *const bindings::nlattr) -> Self {
85+
// TODO: is this correct?
86+
Self(core::slice::from_raw_parts_mut(ptr as *mut NlAttr, bindings::__IFLA_MAX as usize))
87+
}
88+
}

0 commit comments

Comments
 (0)