Builders Module

The builders module provides low-level APIs for constructing NetworkManager connection settings. Most users should use the high-level NetworkManager API instead — these builders are for advanced use cases where you need fine-grained control over the settings dictionary.

To submit builder output, use NetworkManager::add_connection or NetworkManager::add_and_activate_connection. See Submitting Builder Output below.

ConnectionBuilder

The base builder for all connection types. Handles common sections: connection, ipv4, ipv6.

#![allow(unused)]
fn main() {
use nmrs::builders::ConnectionBuilder;

let settings = ConnectionBuilder::new("802-3-ethernet", "MyConnection")
    .autoconnect(true)
    .autoconnect_priority(10)
    .ipv4_auto()
    .ipv6_auto()
    .build();
}

Methods

MethodDescription
new(type, id)Create with connection type and name
uuid(uuid)Set specific UUID
interface_name(name)Restrict to a specific interface
autoconnect(bool)Enable/disable auto-connect
autoconnect_priority(i32)Set priority (higher = preferred)
autoconnect_retries(i32)Set retry limit
options(&ConnectionOptions)Apply options struct
ipv4_auto()DHCP for IPv4
ipv4_manual(Vec<IpConfig>)Static IPv4 addresses
ipv4_disabled()Disable IPv4
ipv4_link_local()Link-local IPv4 (169.254.x.x)
ipv4_shared()Internet connection sharing
ipv4_dns(Vec<Ipv4Addr>)Set DNS servers
ipv4_gateway(Ipv4Addr)Set gateway
ipv4_routes(Vec<Route>)Add static routes
ipv6_auto()SLAAC/DHCPv6
ipv6_manual(Vec<IpConfig>)Static IPv6 addresses
ipv6_ignore()Disable IPv6
ipv6_link_local()Link-local IPv6 only
ipv6_dns(Vec<Ipv6Addr>)Set IPv6 DNS
ipv6_gateway(Ipv6Addr)Set IPv6 gateway
ipv6_routes(Vec<Route>)Add IPv6 static routes
with_section(name, HashMap)Add custom settings section
update_section(name, closure)Modify existing section
build()Produce the settings dictionary

IpConfig

#![allow(unused)]
fn main() {
use nmrs::builders::IpConfig;

let ip = IpConfig::new("192.168.1.100", 24);
}

Route

#![allow(unused)]
fn main() {
use nmrs::builders::Route;

let route = Route::new("10.0.0.0", 8)
    .next_hop("192.168.1.1")
    .metric(100);
}

WifiConnectionBuilder

Builds Wi-Fi connection settings with security configuration.

#![allow(unused)]
fn main() {
use nmrs::builders::WifiConnectionBuilder;

let settings = WifiConnectionBuilder::new("MyNetwork")
    .wpa_psk("my_password")
    .band(nmrs::builders::WifiBand::A) // 5 GHz
    .ipv4_auto()
    .build();
}

WifiBand / WifiMode

#![allow(unused)]
fn main() {
pub enum WifiBand { Bg, A } // 2.4 GHz, 5 GHz
pub enum WifiMode { Infrastructure, Adhoc, Ap }
}

WireGuardBuilder

Builds WireGuard VPN connection settings with validation.

#![allow(unused)]
fn main() {
use nmrs::builders::WireGuardBuilder;
use nmrs::WireGuardPeer;

let peer = WireGuardPeer::new(
    "HIgo9xNzJMWLKAShlKl6/bUT1VI9Q0SDBXGtLXkPFXc=",
    "vpn.example.com:51820",
    vec!["0.0.0.0/0".into()],
);

let settings = WireGuardBuilder::new("MyVPN")
    .private_key("YBk6X3pP8KjKz7+HFWzVHNqL3qTZq8hX9VxFQJ4zVmM=")
    .address("10.0.0.2/24")
    .add_peer(peer)
    .dns(vec!["1.1.1.1".into()])
    .mtu(1420)
    .autoconnect(false)
    .build()?;
}

The build() method validates all fields and returns Result<Settings, ConnectionError>.

Validation

CheckError
Private key formatInvalidPrivateKey
Address CIDR formatInvalidAddress
At least one peerInvalidPeers
Peer public key formatInvalidPublicKey
Gateway host:port formatInvalidGateway
Peer allowed IPs non-emptyInvalidPeers

Builder Functions

Convenience functions that wrap the builders:

#![allow(unused)]
fn main() {
use nmrs::builders::{build_wifi_connection, build_ethernet_connection};
use nmrs::{WifiSecurity, ConnectionOptions};

// Wi-Fi
let wifi = build_wifi_connection(
    "MyNetwork",
    &WifiSecurity::Open,
    &ConnectionOptions::default(),
)?;

// Ethernet
let eth = build_ethernet_connection("eth0", &ConnectionOptions::default());
}

When to Use Builders

Use the builders when you need:

  • Custom IP configuration (static IP, DNS, routes)
  • Specific Wi-Fi band or mode settings
  • Custom connection sections (bridge, bond, VLAN)
  • Fine-grained control over the settings dictionary

For standard connections, the NetworkManager API handles everything automatically.

Submitting Builder Output

Builders produce a NetworkManager settings dictionary (HashMap<&str, HashMap<&str, zvariant::Value>>). Pass that map to NetworkManager::add_connection to save a profile, or NetworkManager::add_and_activate_connection to create and bring it up immediately.

Wi-Fi hotspot (AP mode)

This closes the workflow requested in #260 — use WifiMode::Ap with the high-level API:

#![allow(unused)]
fn main() {
use nmrs::builders::{WifiConnectionBuilder, WifiMode};
use nmrs::NetworkManager;

async fn start_hotspot(nm: &NetworkManager, interface: &str) -> nmrs::Result<()> {
    let settings = WifiConnectionBuilder::new("Hotspot")
        .wpa_psk("password")
        .mode(WifiMode::Ap)
        .ipv4_shared()
        .ipv6_ignore()
        .build();

    nm.add_and_activate_connection(settings, Some(interface), None).await?;
    Ok(())
}
}

specific_object defaults to "/", which is correct for AP mode.

Saving without activating

To persist a profile without bringing it up immediately — the workflow from #463:

#![allow(unused)]
fn main() {
use nmrs::builders::build_wifi_connection;
use nmrs::{ConnectionOptions, NetworkManager, WifiSecurity};

let nm = NetworkManager::new().await?;
let settings = build_wifi_connection(
    "GuestWiFi",
    &WifiSecurity::WpaPsk { psk: "password".into() },
    &ConnectionOptions::new(true),
)?;
let profile = nm.add_connection(settings).await?;
}

Activate the saved profile later with activate_connection via D-Bus, or use the existing high-level connect() APIs when the profile matches a visible network.

Advanced: direct D-Bus access

If you need an NetworkManager D-Bus method that nmrs does not wrap yet, combine dbus_connection() with nmrs::raw and define your own #[zbus::proxy] trait on top of the builder output.

OpenVpnBuilder

Builds OpenVPN connection settings from an OpenVpnConfig or by importing a .ovpn file.

From Configuration

#![allow(unused)]
fn main() {
use nmrs::{OpenVpnConfig, OpenVpnAuthType};

let config = OpenVpnConfig::new("CorpVPN", "vpn.example.com", 1194, false)
    .with_auth_type(OpenVpnAuthType::PasswordTls)
    .with_username("user")
    .with_password("secret")
    .with_ca_cert("/etc/openvpn/ca.crt")
    .with_client_cert("/etc/openvpn/client.crt")
    .with_client_key("/etc/openvpn/client.key");
}

From .ovpn File

#![allow(unused)]
fn main() {
use nmrs::builders::OpenVpnBuilder;

let config = OpenVpnBuilder::from_ovpn_file("client.ovpn")?
    .username("user")
    .password("secret")
    .build()?;
}

Or use the high-level API directly:

#![allow(unused)]
fn main() {
let nm = NetworkManager::new().await?;
nm.import_ovpn("client.ovpn", Some("user"), Some("secret")).await?;
}

Full API Reference

See docs.rs/nmrs for complete builder documentation.

See Also