Skip to content

Commit

Permalink
networkd: add missing bonding options (systemd#10542)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
toanju authored and yuwata committed Nov 2, 2018
1 parent 9cbdf5d commit 99f68ef
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 11 deletions.
21 changes: 21 additions & 0 deletions man/systemd.netdev.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,27 @@
</listitem>
</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>
Expand Down
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -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'],
Expand Down
7 changes: 5 additions & 2 deletions src/basic/missing.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/libsystemd/sd-netlink/netlink-types.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = {
Expand Down
130 changes: 130 additions & 0 deletions src/network/netdev/bond.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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;
Expand All @@ -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);

Expand Down
7 changes: 7 additions & 0 deletions src/network/netdev/bond.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
3 changes: 3 additions & 0 deletions src/network/netdev/netdev-gperf.gperf
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions test/test-network/conf/25-bond.netdev
Original file line number Diff line number Diff line change
Expand Up @@ -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
19 changes: 11 additions & 8 deletions test/test-network/systemd-networkd-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,17 @@ def test_bond(self):

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')
Expand Down

0 comments on commit 99f68ef

Please sign in to comment.