Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bonding support #885

Merged
merged 61 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
256c076
Add Bonding model
cfconrad Sep 26, 2023
2f4e8b9
nm-dbus: use WIRELESS_KEY instead of slice
cfconrad Sep 26, 2023
5053b87
nm-dbus: initial bonding to dbus impl
cfconrad Sep 26, 2023
a241308
Added bonding configuration support
teclator Nov 14, 2023
48480fa
Mutable connection
teclator Nov 15, 2023
9d0369c
Bond schema and settings
teclator Nov 17, 2023
9a4f521
Bonding DBUS API fixes
teclator Nov 21, 2023
00c4177
Fix device type DBUS method
teclator Nov 22, 2023
802dbb6
Add controller and interface name
teclator Nov 22, 2023
25df7cf
Cleanup empty fields
teclator Nov 22, 2023
8284e57
Wait for ports to be added
teclator Nov 23, 2023
4c0e1e8
Cleanup BondConfig code
teclator Nov 24, 2023
0ccfff5
Some fixes and adding a bond connection unit test
teclator Nov 24, 2023
729f5bd
Handle potential problems parsing bonding options
imobachgs Nov 24, 2023
7aea974
controller_from_dbus does not consume the argument
imobachgs Nov 24, 2023
864376f
Some small fixed based on CR
teclator Nov 24, 2023
d278bb6
Prefix unused error variable
teclator Nov 24, 2023
8b221e8
Use the WIRELESS constants
teclator Nov 27, 2023
f1699fa
Moved ControllerSettings from dbus to the model
teclator Nov 27, 2023
cdfe151
Renamed as suggested during CR
teclator Nov 27, 2023
e958fd2
Fix lint formatting reported errors
teclator Nov 28, 2023
b917e3e
Added the Bond mode explicitly to the settings
teclator Nov 30, 2023
c85c68b
Add the bonding mode to the options
teclator Nov 30, 2023
ae62b01
Handle better update controller errors
teclator Nov 30, 2023
89046e1
Remove options and mode from the ControllerConfig
teclator Dec 1, 2023
1f77951
Ports will be in the State connections referencing its controller by …
teclator Dec 5, 2023
2526340
Adapted NM adapter and client for writing the controlled connections
teclator Dec 5, 2023
7d5124b
Extend the BuilderConnection to handle ports
imobachgs Dec 5, 2023
f4a6341
Improve handling of bond ports
imobachgs Dec 5, 2023
894a647
Drop some unused code
imobachgs Dec 5, 2023
cce1dca
Update bonding ports
imobachgs Dec 6, 2023
4b025e4
Merge branch 'master' into add_bonding_support
imobachgs Dec 11, 2023
aa5ab03
Make rustfmt happy
imobachgs Dec 11, 2023
69eec57
Better matching on update_controller_ports
imobachgs Dec 11, 2023
de0edd7
Fix the assignment of bond ports
imobachgs Dec 12, 2023
f08b285
Use a channel to get the connection in the Bond interface
imobachgs Dec 12, 2023
79fc753
Clean unused code
imobachgs Dec 12, 2023
b72cf23
Do not keep the ports in the bond connection
imobachgs Dec 12, 2023
48822a1
Consider the connection interface name optional
imobachgs Dec 12, 2023
aad9c0d
Imports the network connections in the right order
imobachgs Dec 13, 2023
a4180a2
Writes the connections to NetworkManager in the right order
imobachgs Dec 13, 2023
9f05659
Handle errors setting bonding ports
imobachgs Dec 13, 2023
779e39a
Assign an UUID to each network connection
imobachgs Dec 13, 2023
7115509
Fix test_set_bonding_ports test
imobachgs Dec 13, 2023
d8e0ad3
Fix writing of network connections
imobachgs Dec 13, 2023
483f771
Always write the interface-name in bonds
imobachgs Dec 13, 2023
fa01ee0
Improve error reporting when adding a bond
imobachgs Dec 13, 2023
e7e2d63
Fix network example
imobachgs Dec 13, 2023
c5f4b07
Minor refactoring
imobachgs Dec 13, 2023
f17fb52
Fallback to connection IDs when exposing the ports
imobachgs Dec 13, 2023
447f77f
Code and documentation clean-up
imobachgs Dec 13, 2023
ef2b7dd
Merge branch 'master' into add_bonding_support
imobachgs Dec 13, 2023
f118c42
Update the agama-cli.changes file
imobachgs Dec 13, 2023
1a9ffd5
Documentation and grammar fixes
imobachgs Dec 14, 2023
c12d79d
Merge branch 'master' into add_bonding_support
imobachgs Dec 14, 2023
cd47d9d
Include the ethernet section in dummy and bond connections too
imobachgs Dec 14, 2023
f335cf0
Fix client set interface when not present
teclator Dec 14, 2023
5f1fa3d
Add support to read the bond ports from NetworkManager
imobachgs Dec 14, 2023
c73a8ef
Remove the Bond D-Bus interface when cleaning the type
imobachgs Dec 15, 2023
d7fdfd3
Fixes for bonding support
teclator Dec 15, 2023
9edb940
Publish the connection uuid and controller
teclator Dec 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions rust/agama-dbus-server/src/network/action.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
use crate::network::model::Connection;
use agama_lib::network::types::DeviceType;
use tokio::sync::oneshot;
use uuid::Uuid;

use super::error::NetworkStateError;

pub type Responder<T> = oneshot::Sender<T>;
pub type ControllerConnection = (Connection, Vec<String>);

/// Networking actions, like adding, updating or removing connections.
///
Expand All @@ -9,6 +16,16 @@ use agama_lib::network::types::DeviceType;
pub enum Action {
/// Add a new connection with the given name and type.
AddConnection(String, DeviceType),
/// Gets a connection
GetConnection(Uuid, Responder<Option<Connection>>),
/// Gets a controller connection
GetController(
Uuid,
Responder<Result<ControllerConnection, NetworkStateError>>,
),
/// Sets a controller's ports. It uses the Uuid of the controller and the IDs or interface names
/// of the ports.
SetPorts(Uuid, Vec<String>, Responder<Result<(), NetworkStateError>>),
/// Update a connection (replacing the old one).
UpdateConnection(Connection),
/// Remove the connection with the given Uuid.
Expand Down
134 changes: 129 additions & 5 deletions rust/agama-dbus-server/src/network/dbus/interfaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@
//!
//! This module contains the set of D-Bus interfaces that are exposed by [D-Bus network
//! service](crate::NetworkService).

use super::ObjectsRegistry;
use crate::network::{
action::Action,
error::NetworkStateError,
model::{
Connection as NetworkConnection, Device as NetworkDevice, MacAddress, WirelessConnection,
BondConnection, Connection as NetworkConnection, Device as NetworkDevice, MacAddress,
WirelessConnection,
},
};

use agama_lib::network::types::SSID;
use std::{str::FromStr, sync::Arc};
use tokio::sync::mpsc::UnboundedSender;
use tokio::sync::{mpsc::UnboundedSender, oneshot};
use tokio::sync::{MappedMutexGuard, Mutex, MutexGuard};
use uuid::Uuid;
use zbus::{
dbus_interface,
zvariant::{ObjectPath, OwnedObjectPath},
Expand Down Expand Up @@ -229,9 +232,31 @@ impl Connection {
self.get_connection().await.id().to_string()
}

/// Connection UUID.
///
/// Unique identifier of the network connection. It may or not be the same that the used by the
/// backend.
#[dbus_interface(property)]
pub async fn uuid(&self) -> String {
self.get_connection().await.uuid().to_string()
}

#[dbus_interface(property)]
pub async fn controller(&self) -> String {
let connection = self.get_connection().await;
match connection.controller() {
Some(uuid) => uuid.to_string(),
None => "".to_string(),
}
}

#[dbus_interface(property)]
pub async fn interface(&self) -> String {
self.get_connection().await.interface().to_string()
self.get_connection()
.await
.interface()
.unwrap_or("")
.to_string()
}

#[dbus_interface(property)]
Expand Down Expand Up @@ -296,6 +321,106 @@ impl Match {
}
}

/// D-Bus interface for Bond settings.
pub struct Bond {
actions: Arc<Mutex<UnboundedSender<Action>>>,
uuid: Uuid,
}

impl Bond {
/// Creates a Bond interface object.
///
/// * `actions`: sending-half of a channel to send actions.
/// * `uuid`: connection UUID.
pub fn new(actions: UnboundedSender<Action>, uuid: Uuid) -> Self {
Self {
actions: Arc::new(Mutex::new(actions)),
uuid,
}
}

/// Gets the bond connection.
///
/// Beware that it crashes when it is not a bond connection.
async fn get_bond(&self) -> BondConnection {
let actions = self.actions.lock().await;
let (tx, rx) = oneshot::channel();
actions.send(Action::GetConnection(self.uuid, tx)).unwrap();
let connection = rx.await.unwrap();

match connection {
Some(NetworkConnection::Bond(config)) => config,
_ => panic!("Not a bond connection. This is most probably a bug."),
}
}

/// Updates the connection data in the NetworkSystem.
///
/// * `connection`: Updated connection.
async fn update_connection<'a>(&self, connection: BondConnection) -> zbus::fdo::Result<()> {
let actions = self.actions.lock().await;
let connection = NetworkConnection::Bond(connection.clone());
actions.send(Action::UpdateConnection(connection)).unwrap();
Ok(())
}
}

#[dbus_interface(name = "org.opensuse.Agama1.Network.Connection.Bond")]
impl Bond {
/// Bonding mode.
#[dbus_interface(property)]
pub async fn mode(&self) -> String {
let connection = self.get_bond().await;
connection.bond.mode.to_string()
}

#[dbus_interface(property)]
pub async fn set_mode(&mut self, mode: &str) -> zbus::fdo::Result<()> {
let mut connection = self.get_bond().await;
connection.set_mode(mode.try_into()?);
self.update_connection(connection).await
}

/// List of bonding options.
#[dbus_interface(property)]
pub async fn options(&self) -> String {
let connection = self.get_bond().await;
connection.bond.options.to_string()
}

#[dbus_interface(property)]
pub async fn set_options(&mut self, opts: &str) -> zbus::fdo::Result<()> {
let mut connection = self.get_bond().await;
connection.set_options(opts.try_into()?);
self.update_connection(connection).await
}

/// List of bond ports.
///
/// For the port names, it uses the interface name (preferred) or, as a fallback,
/// the connection ID of the port.
#[dbus_interface(property)]
pub async fn ports(&self) -> zbus::fdo::Result<Vec<String>> {
let actions = self.actions.lock().await;
let (tx, rx) = oneshot::channel();
actions.send(Action::GetController(self.uuid, tx)).unwrap();

let (_, ports) = rx.await.unwrap()?;
Ok(ports)
}

#[dbus_interface(property)]
pub async fn set_ports(&mut self, ports: Vec<String>) -> zbus::fdo::Result<()> {
let actions = self.actions.lock().await;
let (tx, rx) = oneshot::channel();
actions
.send(Action::SetPorts(self.uuid, ports, tx))
.unwrap();
let result = rx.await.unwrap();
Ok(result?)
}
}

#[dbus_interface(name = "org.opensuse.Agama1.Network.Connection.Match")]
impl Match {
/// List of driver names to match.
Expand Down Expand Up @@ -477,7 +602,6 @@ impl Wireless {
connection.wireless.security = security
.try_into()
.map_err(|_| NetworkStateError::InvalidSecurityProtocol(security.to_string()))?;
self.update_connection(connection).await?;
Ok(())
self.update_connection(connection).await
}
}
8 changes: 8 additions & 0 deletions rust/agama-dbus-server/src/network/dbus/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ impl Tree {
let mut objects = self.objects.lock().await;

let orig_id = conn.id().to_owned();
let uuid = conn.uuid();
let (id, path) = objects.register_connection(conn);
if id != conn.id() {
conn.set_id(&id)
Expand All @@ -112,6 +113,12 @@ impl Tree {
interfaces::Match::new(self.actions.clone(), Arc::clone(&cloned)),
)
.await?;

if let Connection::Bond(_) = conn {
self.add_interface(&path, interfaces::Bond::new(self.actions.clone(), uuid))
.await?;
}

if let Connection::Wireless(_) = conn {
self.add_interface(
&path,
Expand Down Expand Up @@ -185,6 +192,7 @@ impl Tree {
/// * `path`: connection D-Bus path.
async fn remove_connection_on(&self, path: &str) -> Result<(), ServiceError> {
let object_server = self.connection.object_server();
_ = object_server.remove::<interfaces::Bond, _>(path).await;
_ = object_server.remove::<interfaces::Wireless, _>(path).await;
object_server.remove::<interfaces::Ip, _>(path).await?;
object_server
Expand Down
8 changes: 7 additions & 1 deletion rust/agama-dbus-server/src/network/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use uuid::Uuid;
/// Errors that are related to the network configuration.
#[derive(Error, Debug)]
pub enum NetworkStateError {
#[error("Unknown connection with ID: '{0}'")]
#[error("Unknown connection '{0}'")]
UnknownConnection(String),
#[error("Invalid connection UUID: '{0}'")]
InvalidUuid(String),
Expand All @@ -21,6 +21,12 @@ pub enum NetworkStateError {
InvalidSecurityProtocol(String),
#[error("Adapter error: '{0}'")]
AdapterError(String),
#[error("Invalid bond mode '{0}'")]
InvalidBondMode(String),
#[error("Invalid bond options")]
InvalidBondOptions,
#[error("Not a controller connection: '{0}'")]
NotControllerConnection(String),
}

impl From<NetworkStateError> for zbus::fdo::Error {
Expand Down
Loading