Ensuring predictable MAC address for bond interface



I'm using NetworkManager on a server with two wired Ethernet interfaces (eth0 and eth1) configured as slaves of a bond in active-backup mode. I'd like the bond interface to always be assigned eth0's MAC address.

This is easy with old-school static network configuration like ifupdown: just make eth0 the first slave of the bond interface, and Linux will copy eth0's MAC address to the bond.

When NetworkManager starts up and reads system-interface config files, it creates the bond interface right away, but doesn't add a slave until it notices that the slave's link is up (i.e. carrier is 1). And of course the link state depends on lots of things, like whether a cable is plugged in and the state of the switch or host at the other end. Thus whether eth0 or eth1 gets enslaved to the bond first is unpredictable, meaning the bond interface's MAC address is unpredictable. This is troublesome in some environments, such as ones where a DHCP server assigns IP addresses based on the MAC address of the client.

NetworkManager already treats a bond slave interface differently when its link goes down, leaving it in DISCONNECTED state rather than switching it to UNAVAILABLE. So there's precedent for having a bond interface with one or more link-down slave interfaces. I think the easiest way to achieve a stable MAC address is to extend that behavior to the startup case: as soon as NetworkManager sees an interface that's configured as a bond slave, it should move it from UNAVAILABLE to DISCONNECTED. That way the first configured slave interface, rather than the first one with link up, is enslaved to the bond.

I couldn't figure out a way to configure this in NetworkManager 0.9.8.10, nor in mainline code. As a proof of concept, I hacked nm_device_state_changed() in src/nm-device.c: in the second switch(state), UNAVAILABLE case, I force the transition to DISCONNECTED for eth0 and eth1. This works as I'd hoped: both interfaces are enslaved right away, with eth0 always first.

I didn't see any easy way to implement this behavior cleanly, though. This new behavior should apply only to bond slave interfaces. At the point where nm_device_state_changed() is called, there's not yet a corresponding connection for eth0 or eth1, so I can't check whether the interface is configured as a bond slave. I thought I'd ask for advice before spending more time on this.

Any help would be appreciated!

--Ed



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]