diff options
Diffstat (limited to 'src/network/netdev/bond.c')
-rw-r--r-- | src/network/netdev/bond.c | 141 |
1 files changed, 138 insertions, 3 deletions
diff --git a/src/network/netdev/bond.c b/src/network/netdev/bond.c index 5840a966ab..550a7f8914 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,10 +285,34 @@ 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"); + if (b->tlb_dynamic_lb >= 0) { + r = sd_netlink_message_append_u8(m, IFLA_BOND_TLB_DYNAMIC_LB, b->tlb_dynamic_lb); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_TLB_DYNAMIC_LB attribute: %m"); + } + if (b->arp_interval > 0) { if (b->n_arp_ip_targets > 0) { @@ -357,10 +382,8 @@ int config_parse_arp_ip_target_address(const char *unit, return 0; } - LIST_PREPEND(arp_ip_target, b->arp_ip_targets, buffer); + LIST_PREPEND(arp_ip_target, b->arp_ip_targets, TAKE_PTR(buffer)); b->n_arp_ip_targets++; - - buffer = NULL; } if (b->n_arp_ip_targets > NETDEV_BOND_ARP_TARGETS_MAX) @@ -371,6 +394,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, 0, "Failed to parse actor system priority '%s'. Range is [1,65535], ignoring.", 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, 0, "Failed to parse user port key '%s'. Range is [0,1023], ignoring.", 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, 0, "Not a valid MAC address %s, can not be null or multicast. Ignoring assignment.", 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 +513,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); @@ -406,6 +540,7 @@ static void bond_init(NetDev *netdev) { b->primary_reselect = _NETDEV_BOND_PRIMARY_RESELECT_INVALID; b->all_slaves_active = false; + b->tlb_dynamic_lb = -1; b->resend_igmp = RESEND_IGMP_DEFAULT; b->packets_per_slave = PACKETS_PER_SLAVE_DEFAULT; |