Hello,

I reproduced this issue in a clean Noble container and investigated the root 
causes:
1. handle_bond_primary_member() looks up the primary member strictly by NetDef 
ID in npp->parsed_defs. But NetworkManager generates UUID-based IDs (NM-<UUID>) 
for ethernet interfaces while storing the actual name under match.name.
2. NetworkManager stores each connection in a separate YAML file. If the bond 
YAML file sorts alphabetically before the member interface file (e.g. 
90-NM-9...yaml before 90-NM-b...yaml), Netplan aborts with exit code 78 during 
the first file pass because process_missing_ids() lacked a handler for bonds 
with NM backend.

I prepared and attached a debdiff for Noble (1.1.2-8ubuntu1~24.04.4) that 
resolves both issues:
- Adds a fallback search by original_name / set_name in 
handle_bond_primary_member().
- Adds handling for NETPLAN_DEF_TYPE_BOND in process_missing_ids() to create a 
placeholder definition (matching existing VLAN/VETH logic), enabling clean 
cross-file resolution.
- Adds a unit test in tests/generator/test_bonds.py.

Verified on Noble: netplan apply succeeds with exit code 0,
NetworkManager keeps primary=cockpit in bond.options, and all 14 test
suites pass with 0 regressions.

Upstream pull request submitted for review:
https://github.com/canonical/netplan/pull/616

Thanks!


** Description changed:

+ [ Impact ]
+ 
+ Setting a primary interface on an active-backup bond fails when using Netplan 
with the NetworkManager renderer (e.g. via Cockpit or nmcli).
+ "netplan apply" exits with code 78:
+   Error in network definition: tbond: interface 'cockpit' is not defined
+           primary: "cockpit"
+                    ^
+ 
+ As a result, NetworkManager drops the 'primary' attribute from
+ bond.options, preventing deterministic failover behavior.
+ 
+ [ Fix ]
+ 
+ 1. In handle_bond_primary_member() (src/parse.c), if direct lookup by NetDef 
ID returns NULL, fall back to searching parsed_defs for any netdef where 
match.original_name or set_name matches the requested interface name.
+ 2. In process_missing_ids() (src/parse.c), handle NETPLAN_DEF_TYPE_BOND for 
NETPLAN_BACKEND_NM by creating a placeholder definition (identical to existing 
VLAN and VETH handling). This ensures cross-file resolution succeeds even when 
the bond YAML file sorts lexicographically before the member interface YAML 
file.
+ 3. Added test_bond_primary_nm_matched_by_name in 
tests/generator/test_bonds.py.
+ 
+ [ Test Plan ]
+ 
+ 1. In an Ubuntu 24.04 (Noble) container/system, install network-manager and 
netplan.io.
+ 2. Create a dummy interface:
+    $ ip link add cockpit type dummy
+    $ ip link set cockpit up
+ 3. Create connections using nmcli:
+    $ nmcli connection add type ethernet con-name cockpit ifname cockpit
+    $ nmcli connection add type bond con-name tbond ifname tbond bond.options 
"mode=active-backup,downdelay=0,miimon=100,updelay=0,primary=cockpit"
+    $ nmcli con modify cockpit master tbond
+ 4. Verify with netplan:
+    $ netplan apply
+    $ nmcli con show tbond | grep ^bond
+ 5. On unpatched netplan.io, 'netplan apply' fails with exit code 78 and 
'primary=cockpit' is missing from bond.options.
+ 6. With the updated package, 'netplan apply' exits with 0 and bond.options 
shows:
+    bond.options: 
mode=active-backup,downdelay=0,miimon=100,primary=cockpit,updelay=0
+ 
+ [ Where problems could occur ]
+ 
+ The fallback lookup checks match.original_name and set_name only when direct 
NetDef ID lookup fails, preserving existing behavior for standard Netplan 
configurations.
+ For NetworkManager bonds, creating a placeholder definition in 
process_missing_ids() allows multi-file parsing to complete without early 
abort; placeholders are ignored during keyfile generation and YAML emission, so 
no extraneous configuration files are generated.
+ If a bond YAML references a non-existent interface on a system not managed by 
NetworkManager, the parser will still report an error on the missing interface.
+ 
+ [ Other Info ]
+ 
+ Full test suite passed (14/14 suites OK, 0 regressions).
+ 
+ --- [ Original Report ]
  Ubuntu 2404
  
  network-manager 1.46.0-1ubuntu2.2
  
  netplan.io      1.1.1-1~ubuntu24.04.1
  
  When [improving support for primary interfaces of
  bonds](https://github.com/cockpit-project/cockpit/pull/21533) in
  Cockpit, we encountered this message in the journal:
  
  ```
  Feb 10 08:43:17 ubuntu NetworkManager[9361]: 
/etc/netplan/90-NM-861a710b-9858-48f4-b5e5-a770ab67bd1f.yaml:13:18: Error in 
network definition: tbond: interface 'cockpit' is not defined
  Feb 10 08:43:17 ubuntu NetworkManager[9361]:         primary: "cockpit"
  Feb 10 08:43:17 ubuntu NetworkManager[9361]:                  ^
  ```
  
  The message seems to come from "netplan apply":
  
  ```
  # netplan apply
  [...]
  /etc/netplan/90-NM-4883fb46-4315-41f1-b945-bb096768da61.yaml:13:18: Error in 
network definition: tbond: interface 'cockpit' is not defined
          primary: "cockpit"
                   ^
  # echo $?
  78
  ```
  
  NetworkManager seems to ignore the failure, and somehow the bond
  interface is created anyway, but the "bond.options" setting of its
  connection doesn't include the expected "primary" attribute:
  
  ```
  # nmcli con show tbond | grep ^bond
  bond.options:                           
mode=active-backup,downdelay=0,miimon=100,updelay=0
  ```
  
  I have no idea what the relationship between netplan and NetworkManager
  is. I am guessing that NetworkManager is writing the yaml files in
  /etc/netplan/.
  
  The problem seems to be that the definition of the "cockpit" interface
  uses a generated name:
  
  ```
  network:
    version: 2
    ethernets:
      NM-3287d9ea-ffda-49df-9f21-27594d7cc1b8:
        renderer: NetworkManager
        match:
          name: "cockpit"
        wakeonlan: true
        networkmanager:
          uuid: "3287d9ea-ffda-49df-9f21-27594d7cc1b8"
          name: "cockpit"
          passthrough:
            connection.controller: "tbond"
            connection.master: "tbond"
            connection.port-type: "bond"
            connection.slave-type: "bond"
            ethernet._: ""
  ```
  
  If I change this to
  
  ```
  network:
    version: 2
    ethernets:
      cockpit:
        renderer: NetworkManager
        match:
          name: "cockpit"
  [...]
  ```
  
  then the error disappears and `bond.options` shows the expected value:
  
  ```
  # nmcli con show tbond | grep ^bond
  bond.options:                           
mode=active-backup,downdelay=0,miimon=100,primary=cockpit,updelay=0
  ```

** Tags added: bonding netplan noble patch

** Patch added: "netplan.io_1.1.2-8ubuntu1~24.04.4 debdiff fixing bond primary 
resolution for NM"
   
https://bugs.launchpad.net/ubuntu/+source/netplan.io/+bug/2098093/+attachment/6002244/+files/netplan.io_1.1.2-8ubuntu1~24.04.4.debdiff

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2098093

Title:
  Setting primary interface for a bond fails with netplan

To manage notifications about this bug go to:
https://bugs.launchpad.net/netplan/+bug/2098093/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to