]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: bond support primary slave and active slave (#4873)
authorSusant Sahani <ssahani@users.noreply.github.com>
Wed, 21 Dec 2016 18:10:36 +0000 (23:40 +0530)
committerLennart Poettering <lennart@poettering.net>
Wed, 21 Dec 2016 18:10:36 +0000 (19:10 +0100)
active_slave:

Specifies the new active slave for modes that support it
(active-backup, balance-alb and balance-tlb).

primary slave:
systemd-networks currently lacks the capability to set the primary slave
in an
active-backup bonding. This is necessary if you prefer one interface
over the
other. A common example is a eth0-wlan0 bonding on a laptop where you'd
want to
switch to the wired connection whenever it's available.

Fixes: #2837
man/systemd.netdev.xml
src/network/networkd-link.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.h

index 4df98b281e3df6ae342ae9110fa80bd3bd8a223b..5145b019ae16655ced7b68e15b4b4111b6b7e19e 100644 (file)
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>ActiveSlave=</varname></term>
+        <listitem>
+          <para>A boolean. Specifies the new active slave. The <literal>ActiveSlave=</literal>
+          option is only valid for following modes:
+          <literal>active-backup</literal>,
+          <literal>balance-alb</literal> and
+          <literal>balance-tlb</literal>. Defaults to false.
+          </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>PrimarySlave=</varname></term>
+        <listitem>
+          <para>A boolean. Specifies which slave is the primary device. The specified
+          device will always be the active slave while it is available. Only when the
+          primary is off-line will alternate devices be used.  This is useful when
+          one slave is preferred over another, e.g. when one slave has higher throughput
+          than another. The <literal>PrimarySlave=</literal> option is only valid for
+          following modes:
+          <literal>active-backup</literal>,
+          <literal>balance-alb</literal> and
+          <literal>balance-tlb</literal>. Defaults to false.
+          </para>
+        </listitem>
+      </varlistentry>
     </variablelist>
 
     <para>For more detail information see
index 8d6992cee85f0bb2975acc184d1831e8869d3373..b993d27c2f54de09add6a8dbd2711a2480ff4c10 100644 (file)
@@ -1338,6 +1338,58 @@ static int link_set_bridge(Link *link) {
         return r;
 }
 
+static int link_bond_set(Link *link) {
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+        int r;
+
+        assert(link);
+        assert(link->network);
+
+        r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->network->bond->ifindex);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
+
+        r = sd_netlink_message_set_flags(req, NLM_F_REQUEST | NLM_F_ACK);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Could not set netlink flags: %m");
+
+        r = sd_netlink_message_open_container(req, IFLA_LINKINFO);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m");
+
+        r = sd_netlink_message_open_container_union(req, IFLA_INFO_DATA, "bond");
+        if (r < 0)
+                return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
+
+        if (link->network->active_slave) {
+                r = sd_netlink_message_append_u32(req, IFLA_BOND_ACTIVE_SLAVE, link->ifindex);
+                if (r < 0)
+                        return log_link_error_errno(link, r, "Could not append IFLA_BOND_ACTIVE_SLAVE attribute: %m");
+        }
+
+        if (link->network->primary_slave) {
+                r = sd_netlink_message_append_u32(req, IFLA_BOND_PRIMARY, link->ifindex);
+                if (r < 0)
+                        return log_link_error_errno(link, r, "Could not append IFLA_BOND_PRIMARY attribute: %m");
+        }
+
+        r = sd_netlink_message_close_container(req);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
+
+        r = sd_netlink_message_close_container(req);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
+
+        r = sd_netlink_call_async(link->manager->rtnl, req, set_flags_handler, link, 0, NULL);
+        if (r < 0)
+                return log_link_error_errno(link, r,  "Could not send rtnetlink message: %m");
+
+        link_ref(link);
+
+        return r;
+}
+
 static int link_lldp_save(Link *link) {
         _cleanup_free_ char *temp_path = NULL;
         _cleanup_fclose_ FILE *f = NULL;
@@ -1992,6 +2044,12 @@ static int link_joined(Link *link) {
                         log_link_error_errno(link, r, "Could not set bridge message: %m");
         }
 
+        if (link->network->bond) {
+                r = link_bond_set(link);
+                if (r < 0)
+                        log_link_error_errno(link, r, "Could not set bond message: %m");
+        }
+
         if (link->network->use_br_vlan &&
             (link->network->bridge || streq_ptr("bridge", link->kind))) {
                 r = link_set_bridge_vlan(link);
index c9b9044a14f4240f3253e0079f118dd37cfa1379..4fa17e84527e319150c6a7dc49a8022e795343d6 100644 (file)
@@ -60,6 +60,8 @@ Network.IPForward,                      config_parse_address_family_boolean_with
 Network.IPMasquerade,                   config_parse_bool,                              0,                             offsetof(Network, ip_masquerade)
 Network.IPv6PrivacyExtensions,          config_parse_ipv6_privacy_extensions,           0,                             offsetof(Network, ipv6_privacy_extensions)
 Network.IPv6AcceptRA,                   config_parse_tristate,                          0,                             offsetof(Network, ipv6_accept_ra)
+Network.ActiveSlave,                    config_parse_bool,                              0,                             offsetof(Network, active_slave)
+Network.PrimarySlave,                   config_parse_bool,                              0,                             offsetof(Network, primary_slave)
 /* legacy alias for the above */
 Network.IPv6AcceptRouterAdvertisements, config_parse_tristate,                          0,                             offsetof(Network, ipv6_accept_ra)
 Network.IPv6DuplicateAddressDetection,  config_parse_int,                               0,                             offsetof(Network, ipv6_dad_transmits)
index d13e306addb5c5d7a9fe97f61593cc059e1e67a8..4cf784f67c4c3bf42884ab2399e7b1b568e55b40 100644 (file)
@@ -167,6 +167,8 @@ struct Network {
         int proxy_arp;
 
         bool ipv6_accept_ra_use_dns;
+        bool active_slave;
+        bool primary_slave;
         DHCPUseDomains ipv6_accept_ra_use_domains;
         uint32_t ipv6_accept_ra_route_table;