summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Jungel <Tobias.Jungel@gmail.com>2018-11-02 02:31:20 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2018-11-02 10:31:20 +0900
commit99f68ef02d1e136457c2b0fd1a375050ff965af3 (patch)
treee820715240042c1671f0ca30ef7ed271e3e806ad
parent9cbdf5db4836588c30310eba9470ced398207a1c (diff)
downloadsystemd-99f68ef02d1e136457c2b0fd1a375050ff965af3.tar.gz
systemd-99f68ef02d1e136457c2b0fd1a375050ff965af3.tar.bz2
systemd-99f68ef02d1e136457c2b0fd1a375050ff965af3.zip
networkd: add missing bonding options (#10542)
Add support for bonding options system prio, port key and actor system mac. These options exist in the linux kernel since 4.2 (torvalds/linux@171a42c38c6e1) Details: https://www.kernel.org/doc/Documentation/networking/bonding.txt
-rw-r--r--man/systemd.netdev.xml21
-rw-r--r--meson.build2
-rw-r--r--src/basic/missing.h7
-rw-r--r--src/libsystemd/sd-netlink/netlink-types.c3
-rw-r--r--src/network/netdev/bond.c130
-rw-r--r--src/network/netdev/bond.h7
-rw-r--r--src/network/netdev/netdev-gperf.gperf3
-rw-r--r--test/test-network/conf/25-bond.netdev5
-rwxr-xr-xtest/test-network/systemd-networkd-tests.py19
9 files changed, 186 insertions, 11 deletions
diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml
index 971d81aa42..7b702e8ed1 100644
--- a/man/systemd.netdev.xml
+++ b/man/systemd.netdev.xml
@@ -1269,6 +1269,27 @@
</varlistentry>
<varlistentry>
+ <term><varname>AdActorSysPrio=</varname></term>
+ <listitem>
+ <para>Specifies the 802.3ad system priority. Ranges [1-65535].</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>AdUserPortKey=</varname></term>
+ <listitem>
+ <para>Specifies the 802.3ad user defined portion of the port key. Ranges [0-1023].</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>AdActorSystem=</varname></term>
+ <listitem>
+ <para>Specifies the 802.3ad system mac address. This can not be either NULL or Multicast.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>FailOverMACPolicy=</varname></term>
<listitem>
<para>Specifies whether the active-backup mode should set all slaves to
diff --git a/meson.build b/meson.build
index fcbb22b540..76add43146 100644
--- a/meson.build
+++ b/meson.build
@@ -455,7 +455,7 @@ foreach decl : [['IFLA_INET6_ADDR_GEN_MODE', 'linux/if_link.h'],
['IFLA_MACVLAN_FLAGS', 'linux/if_link.h'],
['IFLA_IPVLAN_FLAGS', 'linux/if_link.h'],
['IFLA_PHYS_PORT_ID', 'linux/if_link.h'],
- ['IFLA_BOND_AD_INFO', 'linux/if_link.h'],
+ ['IFLA_BOND_AD_ACTOR_SYSTEM', 'linux/if_link.h'],
['IFLA_VLAN_PROTOCOL', 'linux/if_link.h'],
['IFLA_VXLAN_REMCSUM_NOPARTIAL', 'linux/if_link.h'],
['IFLA_VXLAN_GPE', 'linux/if_link.h'],
diff --git a/src/basic/missing.h b/src/basic/missing.h
index 648a2b92d9..d671202551 100644
--- a/src/basic/missing.h
+++ b/src/basic/missing.h
@@ -752,7 +752,7 @@ struct input_mask {
#define IFLA_MAX (__IFLA_MAX - 1)
#endif
-#if !HAVE_IFLA_BOND_AD_INFO
+#if !HAVE_IFLA_BOND_AD_ACTOR_SYSTEM
#define IFLA_BOND_UNSPEC 0
#define IFLA_BOND_MODE 1
#define IFLA_BOND_ACTIVE_SLAVE 2
@@ -777,7 +777,10 @@ struct input_mask {
#define IFLA_BOND_AD_LACP_RATE 21
#define IFLA_BOND_AD_SELECT 22
#define IFLA_BOND_AD_INFO 23
-#define __IFLA_BOND_MAX 24
+#define IFLA_BOND_AD_ACTOR_SYS_PRIO 24
+#define IFLA_BOND_AD_USER_PORT_KEY 25
+#define IFLA_BOND_AD_ACTOR_SYSTEM 26
+#define __IFLA_BOND_MAX 27
#define IFLA_BOND_MAX (__IFLA_BOND_MAX - 1)
#endif
diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c
index 3365906813..4e42ab175f 100644
--- a/src/libsystemd/sd-netlink/netlink-types.c
+++ b/src/libsystemd/sd-netlink/netlink-types.c
@@ -224,6 +224,9 @@ static const NLType rtnl_link_info_data_bond_types[] = {
[IFLA_BOND_AD_LACP_RATE] = { .type = NETLINK_TYPE_U8 },
[IFLA_BOND_AD_SELECT] = { .type = NETLINK_TYPE_U8 },
[IFLA_BOND_AD_INFO] = { .type = NETLINK_TYPE_NESTED },
+ [IFLA_BOND_AD_ACTOR_SYS_PRIO] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BOND_AD_USER_PORT_KEY] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BOND_AD_ACTOR_SYSTEM] = { .type = NETLINK_TYPE_ETHER_ADDR },
};
static const NLType rtnl_link_info_data_iptun_types[] = {
diff --git a/src/network/netdev/bond.c b/src/network/netdev/bond.c
index 5840a966ab..43019c3700 100644
--- a/src/network/netdev/bond.c
+++ b/src/network/netdev/bond.c
@@ -7,6 +7,7 @@
#include "alloc-util.h"
#include "conf-parser.h"
+#include "ether-addr-util.h"
#include "extract-word.h"
#include "missing.h"
#include "netdev/bond.h"
@@ -284,6 +285,24 @@ static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_netlin
return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_MIN_LINKS attribute: %m");
}
+ if (b->ad_actor_sys_prio != 0) {
+ r = sd_netlink_message_append_u16(m, IFLA_BOND_AD_ACTOR_SYS_PRIO, b->ad_actor_sys_prio);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_ACTOR_SYS_PRIO attribute: %m");
+ }
+
+ if (b->ad_user_port_key != 0) {
+ r = sd_netlink_message_append_u16(m, IFLA_BOND_AD_USER_PORT_KEY, b->ad_user_port_key);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_USER_PORT_KEY attribute: %m");
+ }
+
+ if (b->ad_actor_system) {
+ r = sd_netlink_message_append_ether_addr(m, IFLA_BOND_AD_ACTOR_SYSTEM, b->ad_actor_system);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_ACTOR_SYSTEM attribute: %m");
+ }
+
r = sd_netlink_message_append_u8(m, IFLA_BOND_ALL_SLAVES_ACTIVE, b->all_slaves_active);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ALL_SLAVES_ACTIVE attribute: %m");
@@ -371,6 +390,115 @@ int config_parse_arp_ip_target_address(const char *unit,
return 0;
}
+int config_parse_ad_actor_sys_prio(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ Bond *b = userdata;
+ uint16_t v;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = safe_atou16(rvalue, &v);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse actor system priority '%s', ignoring: %m", rvalue);
+ return 0;
+ }
+
+ if (v == 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse actor system priority '%s'. Range is [1,65535], ignoring: %m", rvalue);
+ return 0;
+ }
+
+ b->ad_actor_sys_prio = v;
+
+ return 0;
+}
+
+int config_parse_ad_user_port_key(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ Bond *b = userdata;
+ uint16_t v;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = safe_atou16(rvalue, &v);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse user port key '%s', ignoring: %m", rvalue);
+ return 0;
+ }
+
+ if (v > 1023) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse user port key '%s'. Range is [0,1023], ignoring: %m", rvalue);
+ return 0;
+ }
+
+ b->ad_user_port_key = v;
+
+ return 0;
+}
+
+int config_parse_ad_actor_system(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ Bond *b = userdata;
+ _cleanup_free_ struct ether_addr *n = NULL;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ n = new0(struct ether_addr, 1);
+ if (!n)
+ return log_oom();
+
+ r = ether_addr_from_string(rvalue, n);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Not a valid MAC address %s. Ignoring assignment: %m", rvalue);
+ return 0;
+ }
+
+ if (ether_addr_is_null(n) || (n->ether_addr_octet[0] & 0x01)) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Not a valid MAC address %s, can not be null or multicast. Ignoring assignment: %m", rvalue);
+ return 0;
+ }
+
+ free_and_replace(b->ad_actor_system, n);
+
+ return 0;
+}
+
static void bond_done(NetDev *netdev) {
ArpIpTarget *t = NULL, *n = NULL;
Bond *b;
@@ -381,6 +509,8 @@ static void bond_done(NetDev *netdev) {
assert(b);
+ free(b->ad_actor_system);
+
LIST_FOREACH_SAFE(arp_ip_target, t, n, b->arp_ip_targets)
free(t);
diff --git a/src/network/netdev/bond.h b/src/network/netdev/bond.h
index be03d72087..ce6e8cadef 100644
--- a/src/network/netdev/bond.h
+++ b/src/network/netdev/bond.h
@@ -106,6 +106,10 @@ typedef struct Bond {
unsigned num_grat_arp;
unsigned min_links;
+ uint16_t ad_actor_sys_prio;
+ uint16_t ad_user_port_key;
+ struct ether_addr *ad_actor_system;
+
usec_t miimon;
usec_t updelay;
usec_t downdelay;
@@ -152,3 +156,6 @@ int config_parse_bond_arp_validate(const char *unit, const char *filename, unsig
int config_parse_bond_arp_all_targets(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_bond_primary_reselect(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_arp_ip_target_address(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_ad_actor_sys_prio(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_ad_user_port_key(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_ad_actor_system(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf
index 96c8fb1832..f754f230d7 100644
--- a/src/network/netdev/netdev-gperf.gperf
+++ b/src/network/netdev/netdev-gperf.gperf
@@ -141,6 +141,9 @@ Bond.UpDelaySec, config_parse_sec, 0,
Bond.DownDelaySec, config_parse_sec, 0, offsetof(Bond, downdelay)
Bond.ARPIntervalSec, config_parse_sec, 0, offsetof(Bond, arp_interval)
Bond.LearnPacketIntervalSec, config_parse_sec, 0, offsetof(Bond, lp_interval)
+Bond.AdActorSysPrio, config_parse_ad_actor_sys_prio, 0, offsetof(Bond, ad_actor_sys_prio)
+Bond.AdUserPortKey, config_parse_ad_user_port_key, 0, offsetof(Bond, ad_user_port_key)
+Bond.AdActorSystem, config_parse_ad_actor_system, 0, offsetof(Bond, ad_actor_system)
Bridge.HelloTimeSec, config_parse_sec, 0, offsetof(Bridge, hello_time)
Bridge.MaxAgeSec, config_parse_sec, 0, offsetof(Bridge, max_age)
Bridge.AgeingTimeSec, config_parse_sec, 0, offsetof(Bridge, ageing_time)
diff --git a/test/test-network/conf/25-bond.netdev b/test/test-network/conf/25-bond.netdev
index 10599108af..61c54c4de0 100644
--- a/test/test-network/conf/25-bond.netdev
+++ b/test/test-network/conf/25-bond.netdev
@@ -11,3 +11,8 @@ UpDelaySec=2s
DownDelaySec=2s
ResendIGMP=4
MinLinks=1
+AdActorSysPrio=1218
+AdUserPortKey=811
+AdActorSystem=00:11:22:33:44:55
+# feed the sanitizer
+AdActorSystem=00:11:22:33:44:55
diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py
index fc347c6008..a0db6eeb93 100755
--- a/test/test-network/systemd-networkd-tests.py
+++ b/test/test-network/systemd-networkd-tests.py
@@ -173,14 +173,17 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
self.assertTrue(self.link_exits('bond99'))
- self.assertEqual('802.3ad 4', self.read_link_attr('bond99', 'bonding', 'mode'))
- self.assertEqual('layer3+4 1', self.read_link_attr('bond99', 'bonding', 'xmit_hash_policy'))
- self.assertEqual('1000', self.read_link_attr('bond99', 'bonding', 'miimon'))
- self.assertEqual('fast 1', self.read_link_attr('bond99', 'bonding', 'lacp_rate'))
- self.assertEqual('2000', self.read_link_attr('bond99', 'bonding', 'updelay'))
- self.assertEqual('2000', self.read_link_attr('bond99', 'bonding', 'downdelay'))
- self.assertEqual('4', self.read_link_attr('bond99', 'bonding', 'resend_igmp'))
- self.assertEqual('1', self.read_link_attr('bond99', 'bonding', 'min_links'))
+ self.assertEqual('802.3ad 4', self.read_link_attr('bond99', 'bonding', 'mode'))
+ self.assertEqual('layer3+4 1', self.read_link_attr('bond99', 'bonding', 'xmit_hash_policy'))
+ self.assertEqual('1000', self.read_link_attr('bond99', 'bonding', 'miimon'))
+ self.assertEqual('fast 1', self.read_link_attr('bond99', 'bonding', 'lacp_rate'))
+ self.assertEqual('2000', self.read_link_attr('bond99', 'bonding', 'updelay'))
+ self.assertEqual('2000', self.read_link_attr('bond99', 'bonding', 'downdelay'))
+ self.assertEqual('4', self.read_link_attr('bond99', 'bonding', 'resend_igmp'))
+ self.assertEqual('1', self.read_link_attr('bond99', 'bonding', 'min_links'))
+ self.assertEqual('1218', self.read_link_attr('bond99', 'bonding', 'ad_actor_sys_prio'))
+ self.assertEqual('811', self.read_link_attr('bond99', 'bonding', 'ad_user_port_key'))
+ self.assertEqual('00:11:22:33:44:55', self.read_link_attr('bond99', 'bonding', 'ad_actor_system'))
def test_vlan(self):
self.copy_unit_to_networkd_unit_path('21-vlan.netdev', '11-dummy.netdev', '21-vlan.network')