NetworkManager Integration Guide

NetworkManager Integration Guide

1. Overview

This document provides guidance for third-party application developers working on network-related development on RobustOS Pro devices. RobustOS Pro uses NetworkManager (NM) as its core network management service and provides two primary configuration interaction modes:

  1. Standard Mode (Recommended): Configuration through UCI (Unified Configuration Interface). This is the safest and most stable approach, ensuring seamless integration with other system services (such as Web UI and firewall).

  2. Advanced Mode: Direct interaction with NetworkManager (e.g., through nmcli, D-Bus, or editing .nmconnection files). This mode provides greater flexibility for advanced users but requires developers to have a deep understanding of the system's internal workings and associated risks.

This guide aims to help you understand both modes and make the right choice based on your requirements.

2. Understanding RobustOS Pro's Network Management Model

To ensure system stability and configuration consistency, RobustOS Pro implements a UCI-based upper management mechanism.

2.1 Core Mechanism: UCI and nm-helper

The core design principle is UCI as the "single source of truth" for network configuration. A system service named nm-helper continuously monitors changes to UCI configuration. When changes are detected, nm-helper automatically translates UCI configuration into NetworkManager connection configuration files (located at /etc/NetworkManager/system-connections/*.nmconnection).

Workflow Diagram:

User/Application → UCI Configuration → nm-helper Listens → Generate/Overwrite .nmconnection → NetworkManager Applies

This mechanism ensures that any modifications made through official channels (such as Web UI or UCI command line) are correctly applied and persisted.

2.2 Key Behavior of Configuration Overwriting

Understanding nm-helper's overwrite logic is crucial:

  • Overwrite Trigger ConditionOnly when system-related UCI network configuration changes occur will nm-helper regenerate the corresponding .nmconnection files, thereby overwriting any direct manual modifications.

    • For example: Modifying LAN port IP address through Web UI, or changing WAN port DNS server using the uci set command.
  • Restart Does Not Trigger OverwriteDevice restart will not automatically overwrite your direct modifications to .nmconnection files. If you manually edit a connection file, your changes will remain effective after restart as long as there are no related UCI changes.

  • Risk: Although direct modifications can be preserved after restart, they create a "desynchronized" state between UCI configuration and actual network state. Once any UCI network configuration change occurs in the future, your manual modifications will be cleared without warning, potentially causing network interruption or abnormal behavior that is difficult to troubleshoot.

3. Direct Interaction with NetworkManager (Advanced Mode)

After fully understanding the mechanisms and risks described in the previous section, advanced users can choose to interact directly with NetworkManager.

3.1 Applicable Scenarios

  • Managing Application-Specific Networks: Creating and managing independent network connections for your application, such as VPN (tun interface), containers (veth interface), or virtual networks. This is the safest and most recommended "advanced mode" use case.

  • Temporary Debugging: During development or troubleshooting, using nmcli to temporarily modify network parameters for quick verification.

  • Implementing Fine-Grained Configuration Not Exposed by UCI: When you need to use specific advanced features provided by NetworkManager but not included in the UCI model.

3.2 Risks and Responsibilities

When you choose to bypass UCI and operate NetworkManager directly, you assume the following risks:

  • Configuration Loss: As mentioned above, your modifications may be automatically overwritten by the system at any time after UCI changes.

  • State Inconsistency: Other parts of the system (firewall, DHCP service, Web UI) rely on UCI to obtain network status. Direct modifications to NM will cause these services to receive outdated or incorrect information, leading to functional anomalies.

  • Support Complexity: Configurations made through non-standard methods make troubleshooting extremely difficult. Official technical support may not be able to help you resolve issues arising from this.

3.3 Safe Interaction Boundaries

Behavior CategorySafe Operations (Do)Description
Status MonitoringUse nmcli read-only commands or monitor network status through D-Bus signals.For example, nmcli d status, nmcli c show. This is completely safe.
Independent ConnectionsCreate and manage application-specific connections on independent virtual interfaces (such as tun, veth).The system does not manage your self-created interfaces, so there are no configuration overwrite conflicts.
Hardware TakeoverSet application owned hardware (such as USB network card) to managed no and have the application take full control.Suitable for special applications requiring low-level control.
Configuration ModificationAlways prioritize using UCI (uci set, uci commit) to modify system-managed network configuration.This is the primary and safest way to integrate with the system.

Dangerous Operations (Don't)

  • Do not directly edit or delete .nmconnection files managed by nm-helper, unless you clearly know the consequences and are prepared to handle configuration overwrite issues.

  • Use nmcli c modify/delete operations with caution to modify system-managed connections. These modifications will be overwritten on the next UCI change, and delete operations may cause permanent network function failure (until the next UCI change).

4. Practical Guide and Examples

4.1 Monitoring Network Status (Safe)

Using nmcli (Command Line)

  • View device status: nmcli device status

  • View connection list: nmcli connection show

  • View specific network device details: nmcli device show

Using D-Bus (Programmatic Approach)

For applications that need to respond to network changes in real-time, it's recommended to use D-Bus to listen to NetworkManager events.

#!/usr/bin/env python3
import dbus
from dbus.mainloop.glib import DBusGMainLoop
from gi.repository import GLib

def on_state_changed(state):
    # Respond to overall network state changes
    print(f"NetworkManager state changed to: {state}")

DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
nm = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager')
nm.connect_to_signal('StateChanged', on_state_changed)

print("Listening for NetworkManager state changes...")
loop = GLib.MainLoop()
loop.run()

If your application requires a dedicated network (e.g., for VPN or containers), the best practice is to create independent virtual interfaces. Since these interfaces are not managed by UCI, you can safely perform direct operations.

Example: Creating an Independent tun Interface for VPN Application

# 1. Add a tun connection managed by your application using nmcli
# Note: This connection does not conflict with any physical interfaces managed by the system
sudo nmcli connection add \
    type tun \
    con-name "my-app-vpn" \
    ifname tun-myapp \
    mode tun \
    ipv4.method disabled \
    ipv6.method disabled \
    autoconnect no

# 2. Your application can now fully control this "my-app-vpn" connection
# For example, activate it when the application starts
sudo nmcli connection up my-app-vpn

# 3. When the application exits, it can safely disconnect and delete it
sudo nmcli connection down my-app-vpn
sudo nmcli connection delete my-app-vpn

4.3 Modifying Network Configuration Through UCI (Standard Mode)

This is the primary and safest way to integrate with the system. After modification, nm-helper will automatically apply changes to NetworkManager.

For a detailed list and description of all available UCI parameters, please refer to the "RobustOS Pro UCI Configuration Manual."

Scenario 1: Modifying LAN IP Address

# Modify LAN IP address to 192.168.10.1
sudo uci set lan_links.link[1].ip4_setting.ip4_addrs.ip4_addr[1]="192.168.10.1/24"
sudo uci commit

Scenario 2: Adding Firewall Port Forwarding

# Forward TCP traffic from external port 8080 to internal 192.168.1.100 port 80
sudo uci add firewall.port_forwards 99
sudo uci set firewall.port_forwards[99].desc="WebApp"
sudo uci set firewall.port_forwards[99].protocol="tcp"
sudo uci set firewall.port_forwards[99].source_zone="external"
sudo uci set firewall.port_forwards[99].internet_port="8080"
sudo uci set firewall.port_forwards[99].destination_zone="internal"
sudo uci set firewall.port_forwards[99].local_ip="192.168.1.100"
sudo uci set firewall.port_forwards[99].local_port="80"

# Commit configuration
sudo uci commit

4.4 Persistence Strategies for Advanced Configuration (Advanced)

For scenarios where you must directly modify system-managed connections, the biggest challenge is how to preserve your custom modifications after nm-helper automatically overwrites the configuration. Here are two strategies to avoid the risk of configuration loss.

Important Note: These methods require you to have certain scripting development and system administration capabilities and understand their potential risks.

Strategy 1: Monitor and Re-apply

This is a straightforward strategy: use a background script to monitor changes to .nmconnection files. Once a file modification is detected (usually meaning it was overwritten by nm-helper), the script immediately re-applies your custom configuration.

How it works:

  1. Back up your customized .nmconnection file to a safe location.

  2. Or record the nmcli commands you need to forcefully set.

  3. A monitoring script (e.g., using inotifywait) runs in the background, listening for modify events on the target connection file.

  4. When an event is triggered, the script executes preset recovery operations (e.g., copying back the backup file, or re-executing nmcli commands).

Example: Using inotifywait and nmcli to Forcefully Set never-default

Suppose you want the wan0 connection to never become the default route, even if this setting is cleared by UCI changes.

#!/bin/bash
# Purpose: Ensure ipv4.never-default=true persists for wan0 after .nmconnection is overwritten by system
# Dependencies: inotifywait(inotify-tools), nmcli(NetworkManager)
# Description: Only write when value is inconsistent to avoid inotify self-loop
CONNECTION_FILE="/etc/NetworkManager/system-connections/wan0.nmconnection"
CONNECTION_ID="wan0"
SETTING_KEY="ipv4.never-default"
SETTING_VALUE="true"

needs_update() {
  # Read current value and compare with expected value; return true if inconsistent
  current=$(nmcli -g "$SETTING_KEY" connection show "$CONNECTION_ID" 2>/dev/null | tr -d '[:space:]')
  [ "$current" != "$SETTING_VALUE" ]
}

apply_once() {
  # Idempotent: only modify when needed to avoid unnecessary writes
  if needs_update; then
    nmcli connection modify "$CONNECTION_ID" "$SETTING_KEY" "$SETTING_VALUE"
    echo "Applied: $SETTING_KEY=$SETTING_VALUE on $CONNECTION_ID"
  else
    echo "No change needed."
  fi
}

# Execute once initially to ensure current state is correct
apply_once
# Listen for close_write (complete write) events; wait 0.5s for disk stabilization
inotifywait -m -e close_write "$CONNECTION_FILE" | while read -r _ _ _; do
  sleep 0.5
  apply_once
done

Risks and Considerations:

  • Too Aggressive: This method blindly overwrites all changes and may undo legitimate configuration updates made by users through the Web UI.

  • Race Conditions: In complex scenarios, your recovery script may conflict with nm-helper or other system services.

  • Applicable Scenarios: Suitable for simple scenarios where you need to forcefully maintain a few independent configuration items and are certain that the configuration item should not be modified by any upper-layer logic.

Strategy 2: Layered Configuration with Intelligent Merging

This is a more robust and recommended strategy. Instead of fighting against the system, it cooperates with it. The core idea is: let nm-helper manage base configuration, then your script is only responsible for "adding" or "correcting" the advanced parameters you need on top of the generated file.

How it works:

  1. Let nm-helper work normally, don't prevent it.

  2. Your script also monitors file changes.

  3. After the file is overwritten, the script reads the new file content, then programmatically (such as using sed, awk, or more professional INI parsing tools) only modifies or adds the few lines of configuration you care about, rather than overwriting the entire file.

Example: Using sed to Add never-default=true

This script will check if never-default=true already exists in the [ipv4] section after wan0.nmconnection is modified, and if not, add it.

#!/bin/bash
# Purpose: When wan0's .nmconnection is overwritten, ensure never-default=true is set in [ipv4] section;
#          Only write back when content needs to change, and trigger NetworkManager to reload the connection.
CONNECTION_FILE="/etc/NetworkManager/system-connections/wan0.nmconnection"
# Target section and key-value
TARGET_SECTION="[ipv4]"
KEY="never-default"
VALUE="true"

apply_setting() {
  # Use temporary file to receive awk output, ensuring atomic write-back
  tmp="$(mktemp)"
  awk -v section="$TARGET_SECTION" -v key="$KEY" -v value="$VALUE" '
    # insec: whether in target section; updated: whether change occurred
    BEGIN { insec=0; updated=0 }
    # When encountering section header, determine if entering target section
    /^\[/ { insec=($0==section) }
    {
      # Match target key within target section
      if (insec && $0 ~ "^[ \t]*"key"[ \t]*=") {
        # Replace if value differs, mark as updated; output as-is if same
        if ($0 != key"="value) {
          print key"="value
          updated=1
        } else {
          print
        }
        next
      }
      # Non-target key or not in target section, output as-is
      print
    }
    END {
      # If no update throughout, use exit code 10 to signal outer layer no write-back needed
      if (!updated) exit 10
    }
  ' "$CONNECTION_FILE" > "$tmp"
  rc=$?
  # awk normal exit(0) indicates content was modified: overwrite original file and have NM reload
  if [ $rc -eq 0 ]; then
    mv "$tmp" "$CONNECTION_FILE"
    nmcli connection load "$CONNECTION_FILE"
    echo "Updated [$TARGET_SECTION] $KEY=$VALUE and reloaded."
  else
    # No modification or exception: delete temporary file and indicate no change
    rm -f "$tmp"
    echo "No change needed."
  fi
}

# Apply once at startup to ensure current state is correct
apply_setting
# Listen for file complete write events; wait 0.5s to avoid disk race, then apply again
inotifywait -m -e close_write "$CONNECTION_FILE" | while read -r _ _ _; do
  sleep 0.5
  apply_setting
done

Advantages:

  • High Robustness: This method preserves all configuration from UCI, only modifying the parts you care about, greatly reducing the risk of conflicts with other parts of the system.

  • Good Maintainability: Configuration logic is clearer and easier to debug.

  • Recommended Tools: For complex INI file operations, it's recommended to use dedicated tools like crudini, which are safer and more powerful than sed or awk.

Final Recommendation: Prioritize using the "Layered Configuration" strategy as it's safer and more aligned with the system design philosophy. Only consider using the "Monitor and Re-apply" strategy when requirements are very simple and fixed.

5. Summary and Final Recommendations

  • Prioritize Using UCI: Always use UCI as the preferred entry point for network configuration to ensure system stability, consistency, and maintainability.

  • Understand Mechanisms, Operate Cautiously: If you must interact directly with NetworkManager, ensure you fully understand nm-helper's unidirectional synchronization and configuration overwrite mechanisms.

  • Isolate Application Networks: For applications requiring custom networks, the best practice is to create independent virtual interfaces (tun, veth, etc.) and have your application fully manage them. This effectively avoids conflicts with system configuration.

  • Safe Process:

    1. Modify: Prioritize using sudo uci set and sudo uci commit.

    2. Verify: Wait a few seconds, use nmcli c show or nmcli d status to verify changes have taken effect.

    3. Monitor: Use read-only commands or D-Bus signals to safely monitor network status.

By following the above guidance, you can ensure application functionality while maximizing stable and reliable operation in the RobustOS Pro environment.

    • Related Articles

    • RobustOS Pro Third-Party Application Development Guide

      1. Quick Overview What is RobustOS Pro? RobustOS Pro is an embedded Linux distribution based on Debian 11 (bullseye), designed specifically to meet the demanding requirements of industrial IoT gateways, providing a high degree of customization and ...
    • Systemd Integration Guide for Robustel Gateway

      Overview This guide demonstrates how to integrate existing Linux applications into Robustel gateways using standard systemd service management. Applications managed by systemd run independently from the router service and follow standard Linux daemon ...
    • How to Set up Bidirectional SMS Integration with Telegram

      This guide describes how to set up bidirectional SMS integration with Telegram on a RobustOS Pro device. After setup, you'll be able to: Receive device SMS messages in your Telegram chat Send SMS from Telegram using simple commands Prerequisites ...
    • Web Service Integration Guide for RobustOS Pro

      1. Core Conventions Before starting, please follow these conventions to avoid affecting system stability. 1.1 Files and Directories Path Purpose Action /etc/nginx/sites-available/ Configuration files for standalone port services Create new files here ...
    • Edge Gateway Main Page

      Edge Gateway Configuration & Development Your central hub for mastering Robustel Edge Gateways, tailored for developers and system integrators. From basic device configuration to advanced application development and third-party integration, find the ...