A Bondmode Band-Aid

In which an ever-ready watch keep standing up the bond when it spontaneously falls down.

I've recently built a personal file server (running Ubuntu 16.04), and elected to try connecting it to my main workstation (a macpro6,1 running macOS Sierra) with a pair of bonded 1Gb/s Ethernet links.

Using the default settings does work, however I don't seem to have any control over how the link is negotiated with LACP. It results in using one of the packet hashing modes that puts entire TCP connections on one link or the other. This seems great for stability, and aggregate throughput, however my use case has be mounting the server via NFS or SMB (which runs via a single connection).

In that case, I'm not getting much benefit out of the bond for my primary use case of setting up the bond at all!

Early on, I discovered that if I set both sides of the bond to be "static", then they would both default into a round-robin style packet distribution. In this mode, I can hit 220-230MB/s while doing file operations!

The problem: macOS spontaneously reverts the bond mode back to LACP.

I could set the "bondmode" back:

$ sudo ifconfig bond0 bondmode static

However, I couldn't keep it that way. After apple.stackexchange.com didn't bite, I needed to figure out a band-aid.

I spent a few hours digging through Apple's various SDKs. I feel like there is something I could do in the SystemConfiguration framework (specifically in SCNetworkConfiguration), but I'm not much of an Apple programmer, and kept getting stopped by Swift.

A few (increasingly desperate) searches later, and I had determined that the Python psutil package can at least see an effect on my bond with the different modes! After reading the source, I put together my own tiny tool:

$ sudo ./bondwatch -i bond0
[bondwatch] 2017-02-03T17:10:55 DEBUG: Opening socket...
< time passes here >
[bondwatch] 2017-02-03T18:11:06 INFO: Bond appears inactive; setting bondmode to static.

This tiny command simply checks for an indication that the bond has become inactive, and runs the above ifconfig command to reset the bondmode. It does this in a loop, checking every 0.25s. That seems a little overkill to me, but it doesn't have any visible impact on my system, and keeps my connections open!

I've released the tool on Github as bondwatch!

Posted . Categories: .