07-17-2019, 10:58 AM
Bond WiFi and Ethernet for easier networking mobility
<div><p>Sometimes one network interface isn’t enough. Network bonding allows multiple network connections to act together with a single logical interface. You might do this because you want more bandwidth than a single connection can handle. Or maybe you want to switch back and forth between your wired and wireless networks without losing your network connection.</p>
<p> <span id="more-28716"></span> </p>
<p>The latter applies to me. One of the benefits to working from home is that when the weather is nice, it’s enjoyable to work from a sunny deck instead of inside. But every time I did that, I lost my network connections. IRC, SSH, VPN — everything goes away, at least for a moment while some clients reconnect. This article describes how I set up network bonding on my Fedora 30 laptop to seamlessly move from the wired connection my laptop dock to a WiFi connection.</p>
<p>In Linux, interface bonding is handled by the bonding kernel module. Fedora does not ship with this enabled by default, but it is included in the kernel-core package. This means that enabling interface bonding is only a command away:</p>
<pre class="wp-block-preformatted">sudo modprobe bonding</pre>
<p>Note that this will only have effect until you reboot. To permanently enable interface bonding, create a file called <em>bonding.conf</em> in the <em>/etc/modules-load.d</em> directory that contains only the word “bonding”.</p>
<p>Now that you have bonding enabled, it’s time to create the bonded interface. First, you must get the names of the interfaces you want to bond. To list the available interfaces, run:</p>
<pre class="wp-block-preformatted">sudo nmcli device status</pre>
<p> You will see output that looks like this:</p>
<pre class="wp-block-preformatted">DEVICE TYPE STATE CONNECTION <br />enp12s0u1 ethernet connected Wired connection 1<br />tun0 tun connected tun0 <br />virbr0 bridge connected virbr0 <br />wlp2s0 wifi disconnected -- <br />p2p-dev-wlp2s0 wifi-p2p disconnected -- <br />enp0s31f6 ethernet unavailable -- <br />lo loopback unmanaged -- <br />virbr0-nic tun unmanaged -- </pre>
<p>In this case, there are two (wired) Ethernet interfaces available. <em>enp12s0u1</em> is on a laptop docking station, and you can tell that it’s connected from the <em>STATE</em> column. The other, <em>enp0s31f6</em>, is the built-in port in the laptop. There is also a WiFi connection called <em>wlp2s0</em>. <em>enp12s0u1</em> and <em>wlp2s0</em> are the two interfaces we’re interested in here. (Note that it’s not necessary for this exercise to understand how network devices are named, but if you’re interested you can see the <a href="https://www.freedesktop.org/software/systemd/man/systemd.net-naming-scheme.html">systemd.net-naming-scheme man page</a>.)</p>
<p>The first step is to create the bonded interface:</p>
<pre class="wp-block-preformatted">sudo nmcli connection add type bond ifname bond0 con-name bond0</pre>
<p>In this example, the bonded interface is named <em>bond0</em>. The “<em>con-name bond0</em>” sets the connection name to <em>bond0</em>; leaving this off would result in a connection named <em>bond-bond0</em>. You can also set the connection name to something more human-friendly, like “Docking station bond” or “Ben”</p>
<p>The next step is to add the interfaces to the bonded interface:</p>
<pre class="wp-block-preformatted">sudo nmcli connection add type ethernet ifname enp12s0u1 master bond0 con-name bond-ethernet<br />sudo nmcli connection add type wifi ifname wlp2s0 master bond0 ssid Cotton con-name bond-wifi</pre>
<p>As above, the connection name is specified to be <a href="https://en.wikipedia.org/wiki/Master/slave_(technology)#Terminology_concerns">more descriptive</a>. Be sure to replace <em>enp12s0u1</em> and <em>wlp2s0</em> with the appropriate interface names on your system. For the WiFi interface, use your own network name (SSID) where I use “Cotton”. If your WiFi connection has a password (and of course it does!), you’ll need to add that to the configuration, too. The following assumes you’re using <a href="https://en.wikipedia.org/wiki/Wi-Fi_Protected_Access#Target_users_(authentication_key_distribution)">WPA2-PSK</a> authentication</p>
<pre class="wp-block-preformatted">sudo nmcli connection modify bond-wifi wifi-sec.key-mgmt wpa-psk<br />sudo nmcli connection edit bond-wif</pre>
<p>The second command will bring you into the interactive editor where you can enter your password without it being logged in your shell history. Enter the following, replacing <em>password</em> with your actual password</p>
<pre class="wp-block-preformatted">set wifi-sec.psk password<br />save<br />quit<br /></pre>
<p>Now you’re ready to start your bonded interface and the secondary interfaces you created</p>
<pre class="wp-block-preformatted">sudo nmcli connection up bond0<br />sudo nmcli connection up bond-ethernet<br />sudo nmcli connection up bond-wifi</pre>
<p>You should now be able to disconnect your wired or wireless connections without losing your network connections.</p>
<h2>A caveat: using other WiFi networks</h2>
<p>This configuration works well when moving around on the specified WiFi network, but when away from this network, the SSID used in the bond is not available. Theoretically, one could add an interface to the bond for every WiFi connection used, but that doesn’t seem reasonable. Instead, you can disable the bonded interface:</p>
<pre class="wp-block-preformatted">sudo nmcli connection down bond0</pre>
<p>When back on the defined WiFi network, simply start the bonded interface as above.</p>
<h2>Fine-tuning your bond</h2>
<p>By default, the bonded interface uses the “load balancing (round-robin)” mode. This spreads the load equally across the interfaces. But if you have a wired and a wireless connection, you may want to prefer the wired connection. The “active-backup” mode enables this. You can specify the mode and primary interface when you are creating the interface, or afterward using this command (the bonded interface should be down):</p>
<pre class="wp-block-preformatted">sudo nmcli connection modify bond0 +bond.options "mode=active-backup,primary=enp12s0u1"</pre>
<p>The <a href="https://www.kernel.org/doc/Documentation/networking/bonding.txt">kernel documentation</a> has much more information about bonding options.</p>
</div>
<div><p>Sometimes one network interface isn’t enough. Network bonding allows multiple network connections to act together with a single logical interface. You might do this because you want more bandwidth than a single connection can handle. Or maybe you want to switch back and forth between your wired and wireless networks without losing your network connection.</p>
<p> <span id="more-28716"></span> </p>
<p>The latter applies to me. One of the benefits to working from home is that when the weather is nice, it’s enjoyable to work from a sunny deck instead of inside. But every time I did that, I lost my network connections. IRC, SSH, VPN — everything goes away, at least for a moment while some clients reconnect. This article describes how I set up network bonding on my Fedora 30 laptop to seamlessly move from the wired connection my laptop dock to a WiFi connection.</p>
<p>In Linux, interface bonding is handled by the bonding kernel module. Fedora does not ship with this enabled by default, but it is included in the kernel-core package. This means that enabling interface bonding is only a command away:</p>
<pre class="wp-block-preformatted">sudo modprobe bonding</pre>
<p>Note that this will only have effect until you reboot. To permanently enable interface bonding, create a file called <em>bonding.conf</em> in the <em>/etc/modules-load.d</em> directory that contains only the word “bonding”.</p>
<p>Now that you have bonding enabled, it’s time to create the bonded interface. First, you must get the names of the interfaces you want to bond. To list the available interfaces, run:</p>
<pre class="wp-block-preformatted">sudo nmcli device status</pre>
<p> You will see output that looks like this:</p>
<pre class="wp-block-preformatted">DEVICE TYPE STATE CONNECTION <br />enp12s0u1 ethernet connected Wired connection 1<br />tun0 tun connected tun0 <br />virbr0 bridge connected virbr0 <br />wlp2s0 wifi disconnected -- <br />p2p-dev-wlp2s0 wifi-p2p disconnected -- <br />enp0s31f6 ethernet unavailable -- <br />lo loopback unmanaged -- <br />virbr0-nic tun unmanaged -- </pre>
<p>In this case, there are two (wired) Ethernet interfaces available. <em>enp12s0u1</em> is on a laptop docking station, and you can tell that it’s connected from the <em>STATE</em> column. The other, <em>enp0s31f6</em>, is the built-in port in the laptop. There is also a WiFi connection called <em>wlp2s0</em>. <em>enp12s0u1</em> and <em>wlp2s0</em> are the two interfaces we’re interested in here. (Note that it’s not necessary for this exercise to understand how network devices are named, but if you’re interested you can see the <a href="https://www.freedesktop.org/software/systemd/man/systemd.net-naming-scheme.html">systemd.net-naming-scheme man page</a>.)</p>
<p>The first step is to create the bonded interface:</p>
<pre class="wp-block-preformatted">sudo nmcli connection add type bond ifname bond0 con-name bond0</pre>
<p>In this example, the bonded interface is named <em>bond0</em>. The “<em>con-name bond0</em>” sets the connection name to <em>bond0</em>; leaving this off would result in a connection named <em>bond-bond0</em>. You can also set the connection name to something more human-friendly, like “Docking station bond” or “Ben”</p>
<p>The next step is to add the interfaces to the bonded interface:</p>
<pre class="wp-block-preformatted">sudo nmcli connection add type ethernet ifname enp12s0u1 master bond0 con-name bond-ethernet<br />sudo nmcli connection add type wifi ifname wlp2s0 master bond0 ssid Cotton con-name bond-wifi</pre>
<p>As above, the connection name is specified to be <a href="https://en.wikipedia.org/wiki/Master/slave_(technology)#Terminology_concerns">more descriptive</a>. Be sure to replace <em>enp12s0u1</em> and <em>wlp2s0</em> with the appropriate interface names on your system. For the WiFi interface, use your own network name (SSID) where I use “Cotton”. If your WiFi connection has a password (and of course it does!), you’ll need to add that to the configuration, too. The following assumes you’re using <a href="https://en.wikipedia.org/wiki/Wi-Fi_Protected_Access#Target_users_(authentication_key_distribution)">WPA2-PSK</a> authentication</p>
<pre class="wp-block-preformatted">sudo nmcli connection modify bond-wifi wifi-sec.key-mgmt wpa-psk<br />sudo nmcli connection edit bond-wif</pre>
<p>The second command will bring you into the interactive editor where you can enter your password without it being logged in your shell history. Enter the following, replacing <em>password</em> with your actual password</p>
<pre class="wp-block-preformatted">set wifi-sec.psk password<br />save<br />quit<br /></pre>
<p>Now you’re ready to start your bonded interface and the secondary interfaces you created</p>
<pre class="wp-block-preformatted">sudo nmcli connection up bond0<br />sudo nmcli connection up bond-ethernet<br />sudo nmcli connection up bond-wifi</pre>
<p>You should now be able to disconnect your wired or wireless connections without losing your network connections.</p>
<h2>A caveat: using other WiFi networks</h2>
<p>This configuration works well when moving around on the specified WiFi network, but when away from this network, the SSID used in the bond is not available. Theoretically, one could add an interface to the bond for every WiFi connection used, but that doesn’t seem reasonable. Instead, you can disable the bonded interface:</p>
<pre class="wp-block-preformatted">sudo nmcli connection down bond0</pre>
<p>When back on the defined WiFi network, simply start the bonded interface as above.</p>
<h2>Fine-tuning your bond</h2>
<p>By default, the bonded interface uses the “load balancing (round-robin)” mode. This spreads the load equally across the interfaces. But if you have a wired and a wireless connection, you may want to prefer the wired connection. The “active-backup” mode enables this. You can specify the mode and primary interface when you are creating the interface, or afterward using this command (the bonded interface should be down):</p>
<pre class="wp-block-preformatted">sudo nmcli connection modify bond0 +bond.options "mode=active-backup,primary=enp12s0u1"</pre>
<p>The <a href="https://www.kernel.org/doc/Documentation/networking/bonding.txt">kernel documentation</a> has much more information about bonding options.</p>
</div>