Configuring a network bond on RHEL with source load balancing

Solution Verified - Updated

Environment

  • Red Hat Enterprise Linux 9.3 and later
  • Red Hat Enterprise Linux 10

Issue

  • I want to configure source load balancing (SLB) on a bond.

Resolution

The source load balancing (SLB) bonding mode distributes outcoming data streams across multiple network interfaces based on the source address of the traffic and a VLAN hash. Use this mode if the bond should handle traffic from multiple Ethernet sources, such as traffic from several VMs combined over the bond.

The Linux bonding driver does not support SLB. In environments that use Open vSwitch (OVS), such as OpenStack, administrators typically use Open vSwitch to configure SLB. On RHEL, you can configure SLB by creating a bond with a variant of the balance-xor mode. With this variant, NetworkManager automatically creates nftables rules in the background and the bond provides SLB.

Using nmcli to configuring a network bond on RHEL with source load balancing

You can use the nmcli utility to configure a bond with source load balancing (SLB) on the command line.

Prerequisites

  • Two or more physical or virtual network devices are installed on the server.
  • To use Ethernet devices as ports of the bond, the physical or virtual Ethernet devices must be installed on the server.

Procedure

  1. Create a bond interface:

    # nmcli connection add type bond con-name bond0 ifname bond0 bond.options "mode=balance-xor,xmit_hash_policy=vlan+srcmac,balance-slb=1"
    

    Note that all mentioned settings in the bond.options parameter are required to create a bond with SLB mode.

  2. Display the network interfaces, and note names of interfaces you plan to add to the bond:

    # nmcli device status
    DEVICE   TYPE      STATE         CONNECTION
    enp7s0  ethernet    disconnected  --
    enp8s0  ethernet    disconnected  --
    enp1s0  ethernet    connected     enp1s0
    enp2s0  ethernet    connected     enp2s0
    ...
    

    In this example:

    • enp7s0 and enp8s0 are not configured. To use these devices as ports, add connection profiles in the next step.
    • enp1s0 and enp2s0 have existing connection profiles. To use these devices as ports, modify their profiles in the next step.
  3. Assign interfaces to the bond:

    • If the interfaces you want to assign to the bond are not configured, create new connection profiles for them:

      # nmcli connection add type ethernet port-type bond con-name bond0-port1 ifname enp7s0 controller bond0
      # nmcli connection add type ethernet port-type bond con-name bond0-port2 ifname enp8s0 controller bond0
      

      These commands create profiles for enp7s0 and enp8s0, and add them to the bond0 connection.

    • To assign an existing connection profile to the bond:

      1. Set the controller parameter of these connections to bond0:

        # nmcli connection modify enp1s0 controller bond0
        # nmcli connection modify enp2s0 controller bond0
        

        These commands assign the existing connection profiles named enp1s0 and enp2s0 to the bond0 connection.

      2. Reactivate the connections:

        # nmcli connection up enp1s0
        # nmcli connection up enp2s0
        
  4. Configure the IPv4 settings:

    • To use DHCP, no action is required.

    • To set a static IPv4 address, network mask, default gateway, and DNS server to the bond0 connection, enter:

      # nmcli connection modify bond0 ipv4.addresses '192.0.2.1/24' ipv4.gateway '192.0.2.254' ipv4.dns '192.0.2.253' ipv4.dns-search 'example.com' ipv4.method manual
      
    • To use this bond device as a port of other devices, enter:

      # nmcli connection modify bond0 ipv4.method disabled
      
  5. Configure the IPv6 settings:

    • To use stateless address autoconfiguration (SLAAC), no action is required.

    • To set a static IPv6 address, network mask, default gateway, and DNS server to the bond0 connection, enter:

      # nmcli connection modify bond0 ipv6.addresses '2001:db8:1::1/64' ipv6.gateway '2001:db8:1::fffe' ipv6.dns '2001:db8:1::fffd' ipv6.dns-search 'example.com' ipv6.method manual
      
    • To use this bond device as a port of other devices, enter:

      # nmcli connection modify bond0 ipv6.method disabled
      
  6. Optional: If you want to set any parameters on the bond ports, use the following command:

    # nmcli connection modify bond0-port1 bond-port.<parameter> <value>
    
  7. Activate the connection:

    # nmcli connection up bond0
    
  8. Verify that the ports are connected, and the CONNECTION column displays the port’s connection name:

    # nmcli device
    DEVICE   TYPE      STATE      CONNECTION
    ...
    enp7s0   ethernet  connected  bond0-port1
    enp8s0   ethernet  connected  bond0-port2
    

    When you activate any port of the connection, NetworkManager also activates the bond, but not the other ports of it. You can configure that Red Hat Enterprise Linux enables all ports automatically when the bond is enabled:

    1. Enable the connection.autoconnect-ports parameter of the bond’s connection:

      # nmcli connection modify bond0 connection.autoconnect-ports 1
      
    2. Reactivate the bridge:

      # nmcli connection up bond0
      

Using nmstatectl to configuring a network bond on RHEL with source load balancing

You can use the nmstatectl utility to configure a bond with source load balancing (SLB) through the Nmstate API. This API ensures that, after setting the configuration, the result matches the configuration file. If anything fails, nmstatectl automatically rolls back the changes to avoid leaving the system in an incorrect state.

Prerequisites

  • Two or more physical or virtual network devices are installed on the server.
  • To use Ethernet devices as ports of the bond, the physical or virtual Ethernet devices must be installed on the server.
  • The nmstate package is installed.

Procedure

  1. Create a YAML file, for example ~/create-bond.yml, with the following content:

       interfaces:
       - name: bond0
         type: bond
         state: up
         ipv4:
           enabled: true
           address:
           - ip: 192.0.2.1
             prefix-length: 24
           dhcp: false
         ipv6:
           enabled: true
           address:
           - ip: 2001:db8:1::1
             prefix-length: 64
           dhcp: false
           autoconf: false
         link-aggregation:
           mode: balance-xor
           options:
             xmit_hash_policy: vlan+srcmac
             balance_slb: true
           port:
           - enp7s0
           - enp8s0
       - name: enp7s0
         type: ethernet
         state: up
       - name: enp8s0
         type: ethernet
         state: up
    
       routes:
         config:
         - destination: 0.0.0.0/0
           next-hop-interface: bond0
           next-hop-address: 192.0.2.254
         - destination: ::/0
           next-hop-interface: bond0
           next-hop-address: 2001:db8:1::fffe
    
       dns-resolver:
         config:
           search:
           - example.com
           server:
           - 192.0.2.200
           - 2001:db8:1::ffbb
    
  2. Apply the settings to the system:

    # nmstatectl apply ~/create-bond.yml
    

Verification

  • Display the nftables rule set and check that the nm-mlag-<bond_name> table with the corresponding rules was created:

       # nft list ruleset
       table netdev nm-mlag-bond0 {
           set macset-tagged {
               typeof ether saddr . vlan id
               size 65535
               flags dynamic,timeout
           }
    
           set macset-untagged {
               typeof ether saddr
               size 65535
               flags dynamic,timeout
               elements = { 16:40:7d:e5:9e:25 timeout 5s expires 3s817ms,
                        52:54:00:31:39:ee timeout 5s expires 3s837ms }
           }
    
           chain tx-snoop-source-mac {
               type filter hook egress device "bond0" priority filter; policy accept;
               update @macset-tagged { ether saddr . vlan id timeout 5s } return
               update @macset-untagged { ether saddr timeout 5s }
           }
    
           chain rx-drop-looped-packets {
               type filter hook ingress device "bond0" priority filter; policy accept;
               ether saddr . vlan id @macset-tagged drop
               ether type 8021q return
               ether saddr @macset-untagged drop
           }
    
           chain rx-drop-bc-mc-enp8s0 {
               type filter hook ingress device "enp8s0" priority filter; policy accept;
               meta pkttype { broadcast, multicast } drop
           }
       }
    
Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.