Skip to content

Commit

Permalink
Merge pull request #28 from wqld/feat/support-wireguard
Browse files Browse the repository at this point in the history
feat(rsln): support genl netlink
  • Loading branch information
wqld authored Mar 16, 2024
2 parents 49fff9f + 4ff9837 commit 92f3b37
Show file tree
Hide file tree
Showing 23 changed files with 383 additions and 92 deletions.
2 changes: 1 addition & 1 deletion agent/src/netlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{

use anyhow::{anyhow, Result};
use ipnet::IpNet;
use rsln::route::{
use rsln::types::{
addr::AddressBuilder,
link::{Kind, Link, LinkAttrs, VxlanAttrs},
neigh::NeighborBuilder,
Expand Down
2 changes: 1 addition & 1 deletion cni/src/command/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use nix::sched::{setns, CloneFlags};
use rand::Rng;
use rsln::{
netlink::Netlink,
route::{
types::{
addr::AddressBuilder,
link::{Kind, LinkAttrs},
routing::RoutingBuilder,
Expand Down
2 changes: 1 addition & 1 deletion cni/src/command/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use nix::sched::{setns, CloneFlags};
use reqwest::Client;
use rsln::{
netlink::Netlink,
route::{addr::AddrFamily, link::LinkAttrs},
types::{addr::AddrFamily, link::LinkAttrs},
};
use sinabro_config::Config;
use tokio::task::spawn_blocking;
Expand Down
2 changes: 1 addition & 1 deletion rsln/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rsln"
version = "0.0.1"
version = "0.0.2"
edition = "2021"
license = "Apache-2.0"
repository = "https://github.com/wqld/sinabro/tree/main/rsln"
Expand Down
13 changes: 13 additions & 0 deletions rsln/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# rsln

Implements the netlink protocol based kernel interfaces required by the sinabro project in Rust.

## Supported netlink protocols

### Netlink route

- link
- address
- route
- neighbor

### Generic netlink

- family
2 changes: 1 addition & 1 deletion rsln/src/core/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ impl Header {

#[cfg(test)]
mod tests {
use crate::route::message::{Attribute, RouteAttr};
use crate::types::message::{Attribute, RouteAttr};

use super::*;

Expand Down
26 changes: 26 additions & 0 deletions rsln/src/core/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,32 @@ impl Socket {
}
}

pub fn block(&self) -> Result<()> {
match unsafe {
libc::fcntl(
self.fd,
libc::F_SETFL,
libc::fcntl(self.fd, libc::F_GETFL, 0) & !libc::O_NONBLOCK,
)
} {
-1 => Err(Error::last_os_error()),
_ => Ok(()),
}
}

pub fn non_block(&self) -> Result<()> {
match unsafe {
libc::fcntl(
self.fd,
libc::F_SETFL,
libc::fcntl(self.fd, libc::F_GETFL, 0) | libc::O_NONBLOCK,
)
} {
-1 => Err(Error::last_os_error()),
_ => Ok(()),
}
}

pub fn send(&self, buf: &[u8]) -> Result<()> {
let (addr, addr_len) = self.sa.as_raw();

Expand Down
4 changes: 2 additions & 2 deletions rsln/src/handle/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use ipnet::IpNet;

use crate::{
core::message::Message,
route::{
types::{
addr::Address,
link::Link,
message::{AddressMessage, Attribute, RouteAttr},
Expand Down Expand Up @@ -144,8 +144,8 @@ impl AddrHandle<'_> {
#[cfg(test)]
mod tests {
use crate::{
route::{addr::AddressBuilder, link::LinkAttrs},
test_setup,
types::{addr::AddressBuilder, link::LinkAttrs},
};

#[test]
Expand Down
68 changes: 68 additions & 0 deletions rsln/src/handle/generic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use std::ops::{Deref, DerefMut};

use anyhow::{anyhow, Result};

use crate::{
core::message::Message,
handle::zero_terminated,
types::{
generic::{GenlFamilies, GenlFamily},
message::{Attribute, GenlMessage, RouteAttr},
},
};

use super::sock_handle::SocketHandle;

pub struct GenericHandle<'a> {
pub socket: &'a mut SocketHandle,
}

impl<'a> Deref for GenericHandle<'a> {
type Target = SocketHandle;

fn deref(&self) -> &Self::Target {
self.socket
}
}

impl DerefMut for GenericHandle<'_> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.socket
}
}

impl<'a> From<&'a mut SocketHandle> for GenericHandle<'a> {
fn from(socket: &'a mut SocketHandle) -> Self {
Self { socket }
}
}

impl GenericHandle<'_> {
pub fn list_family(&mut self) -> Result<GenlFamilies> {
let mut req = Message::new(libc::GENL_ID_CTRL as u16, libc::NLM_F_DUMP);
let msg = GenlMessage::get_family_message();

req.add(&msg.serialize()?);

let msgs = self.request(&mut req, 0)?;

GenlFamilies::try_from(msgs)
}

pub fn get_family(&mut self, name: &str) -> Result<GenlFamily> {
let mut req = Message::new(libc::GENL_ID_CTRL as u16, 0);
let msg = GenlMessage::get_family_message();
let family_name =
RouteAttr::new(libc::CTRL_ATTR_FAMILY_NAME as u16, &zero_terminated(name));

req.add(&msg.serialize()?);
req.add(&family_name.serialize()?);

let msgs = self.request(&mut req, 0)?;

GenlFamilies::try_from(msgs)?
.first()
.cloned()
.ok_or_else(|| anyhow!("invalid response for GENL_CTRL_CMD_GETFAMILY"))
}
}
4 changes: 2 additions & 2 deletions rsln/src/handle/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use anyhow::{anyhow, Result};

use crate::{
core::message::Message,
route::{
types::{
link::{Kind, Link, LinkAttrs},
message::{Attribute, LinkMessage, RouteAttr},
},
Expand Down Expand Up @@ -209,8 +209,8 @@ impl LinkHandle<'_> {
mod tests {
use crate::{
handle::sock_handle,
route::link::{Kind, LinkAttrs},
test_setup,
types::link::{Kind, LinkAttrs},
};

#[tokio::test]
Expand Down
1 change: 1 addition & 0 deletions rsln/src/handle/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod addr;
pub mod generic;
pub mod link;
pub mod neigh;
pub mod routing;
Expand Down
7 changes: 3 additions & 4 deletions rsln/src/handle/neigh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use anyhow::{anyhow, Result};

use crate::{
core::message::Message,
route::{
types::{
message::{Attribute, NeighborMessage, RouteAttr},
neigh::Neighbor,
},
Expand Down Expand Up @@ -78,12 +78,11 @@ impl NeighHandle<'_> {
#[cfg(test)]
mod tests {
use crate::{
parse_mac,
route::{
parse_mac, test_setup,
types::{
link::{Kind, LinkAttrs},
neigh::NeighborBuilder,
},
test_setup,
};

use super::*;
Expand Down
4 changes: 2 additions & 2 deletions rsln/src/handle/routing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use ipnet::IpNet;

use crate::{
core::message::Message,
route::{
types::{
message::{Attribute, RouteAttr, RouteMessage},
routing::Routing,
},
Expand Down Expand Up @@ -158,8 +158,8 @@ impl RouteHandle<'_> {
#[cfg(test)]
mod tests {
use crate::{
route::{link::LinkAttrs, routing::Via},
test_setup,
types::{link::LinkAttrs, routing::Via},
};

use super::*;
Expand Down
9 changes: 8 additions & 1 deletion rsln/src/handle/sock_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use anyhow::{bail, Result};

use crate::core::{message::Message, socket::Socket};

use super::{addr::AddrHandle, link::LinkHandle, neigh::NeighHandle, routing::RouteHandle};
use super::{
addr::AddrHandle, generic::GenericHandle, link::LinkHandle, neigh::NeighHandle,
routing::RouteHandle,
};

const PID_KERNEL: u32 = 0;

Expand Down Expand Up @@ -44,6 +47,10 @@ impl SocketHandle {
NeighHandle::from(self)
}

pub fn handle_generic(&mut self) -> GenericHandle<'_> {
GenericHandle::from(self)
}

pub fn request(&mut self, msg: &mut Message, res_type: u16) -> Result<Vec<Vec<u8>>> {
let next_seq = self.next_seq();
msg.header.nlmsg_seq = next_seq;
Expand Down
2 changes: 1 addition & 1 deletion rsln/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use anyhow::{anyhow, Result};
pub mod core;
pub mod handle;
pub mod netlink;
pub mod route;
pub mod types;

const RTA_MTU: u16 = 0x2;
const RTA_VIA: u16 = 18;
Expand Down
21 changes: 19 additions & 2 deletions rsln/src/netlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ use sysctl::Sysctl;

use crate::{
handle::sock_handle::SocketHandle,
route::{
types::{
addr::{AddrCmd, AddrFamily, Address},
generic::{GenlFamilies, GenlFamily},
link::{Link, LinkAttrs},
neigh::Neighbor,
routing::{Routing, RtCmd},
Expand Down Expand Up @@ -201,13 +202,29 @@ impl Netlink {
libc::NLM_F_CREATE | libc::NLM_F_REPLACE | libc::NLM_F_ACK,
)
}

pub fn genl_family_list(&mut self) -> Result<GenlFamilies> {
self.sockets
.entry(libc::NETLINK_GENERIC)
.or_insert(SocketHandle::new(libc::NETLINK_GENERIC))
.handle_generic()
.list_family()
}

pub fn genl_family_get(&mut self, name: &str) -> Result<GenlFamily> {
self.sockets
.entry(libc::NETLINK_GENERIC)
.or_insert(SocketHandle::new(libc::NETLINK_GENERIC))
.handle_generic()
.get_family(name)
}
}

#[cfg(test)]
mod tests {
use crate::{
route::link::{Kind, VxlanAttrs},
test_setup,
types::link::{Kind, VxlanAttrs},
};

use super::*;
Expand Down
6 changes: 3 additions & 3 deletions rsln/src/route/addr.rs → rsln/src/types/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,15 @@ pub struct Address {
impl From<&[u8]> for Address {
fn from(buf: &[u8]) -> Self {
let addr_msg: AddressMessage = bincode::deserialize(buf).unwrap();
let rt_attrs = RouteAttrs::from(&buf[addr_msg.len()..]);
let attrs = RouteAttrs::from(&buf[addr_msg.len()..]);

let mut addr = Self {
index: addr_msg.index,
scope: addr_msg.scope,
..Default::default()
};

for attr in rt_attrs {
for attr in attrs {
match attr.header.rta_type {
libc::IFA_ADDRESS => {
addr.update_address(&attr.payload, addr_msg.prefix_len)
Expand All @@ -88,7 +88,7 @@ impl Address {

#[cfg(test)]
mod tests {
use crate::route::message::{Payload, RouteAttr, RouteAttrHeader};
use crate::types::message::{Payload, RouteAttr, RouteAttrHeader};

use super::*;

Expand Down
Loading

0 comments on commit 92f3b37

Please sign in to comment.