Skip to content

Commit

Permalink
Merge pull request #650 from mtomaschewski/bonding-3.7.1
Browse files Browse the repository at this point in the history
bonding: support for new v3.7.1 netlink options in 4.4 kernel
  • Loading branch information
mtomaschewski committed May 26, 2016
2 parents bd48dae + e8aa09a commit d84174a
Show file tree
Hide file tree
Showing 13 changed files with 542 additions and 10 deletions.
12 changes: 12 additions & 0 deletions client/compat.c
Expand Up @@ -451,6 +451,18 @@ __ni_compat_generate_bonding(xml_node_t *ifnode, const ni_compat_netdev_t *compa
xml_node_new_element("ad-select", child,
ni_bonding_ad_select_name(bond->ad_select));
}
if (verbose || bond->ad_user_port_key) {
xml_node_new_element("ad-user-port-key", child,
ni_sprint_uint(bond->ad_user_port_key));
}
if (verbose || bond->ad_actor_sys_prio != 65535) {
xml_node_new_element("ad-actor-sys-prio", child,
ni_sprint_uint(bond->ad_actor_sys_prio));
}
if (bond->ad_actor_system.len) {
xml_node_new_element("ad-actor-system", child,
ni_link_address_print(&bond->ad_actor_system));
}
if (verbose || bond->min_links > 0) {
xml_node_new_element("min-links", child,
ni_sprint_uint(bond->min_links));
Expand Down
3 changes: 3 additions & 0 deletions include/wicked/bonding.h
Expand Up @@ -130,6 +130,9 @@ struct ni_bonding {
unsigned int packets_per_slave;
ni_bool_t tlb_dynamic_lb;
unsigned int lp_interval;
uint16_t ad_user_port_key;
uint16_t ad_actor_sys_prio;
ni_hwaddr_t ad_actor_system;
struct ni_bonding_ad_info {
unsigned int aggregator_id;
unsigned int ports;
Expand Down
3 changes: 3 additions & 0 deletions schema/bonding.xml
Expand Up @@ -64,6 +64,9 @@
<xmit-hash-policy type="builtin-bonding-xmit-hash-policy"/>
<lacp-rate type="builtin-bonding-lacp-rate"/>
<ad-select type="builtin-bonding-ad-select"/>
<ad-user-port-key type="uint16"/>
<ad-actor-sys-prio type="uint16"/>
<ad-actor-system type="ethernet-address"/>
<fail-over-mac type="builtin-bonding-fail-over-mac"/>
<primary-reselect type="builtin-bonding-primary-reselect"/>

Expand Down
1 change: 1 addition & 0 deletions src/Makefile.am
Expand Up @@ -175,6 +175,7 @@ noinst_HEADERS = \
system_headers = \
linux/dcbnl.h \
linux/ethtool.h \
linux/if_addr.h \
linux/if_link.h \
linux/if_tunnel.h

Expand Down
40 changes: 40 additions & 0 deletions src/bonding.c
Expand Up @@ -8,6 +8,7 @@
#endif

#include <arpa/inet.h>
#include <net/if_arp.h>
#include <limits.h>

#include <wicked/netinfo.h>
Expand Down Expand Up @@ -182,6 +183,8 @@ __ni_bonding_init(ni_bonding_t *bonding)
bonding->packets_per_slave = 1;
bonding->tlb_dynamic_lb = TRUE;
bonding->lp_interval = 1;
bonding->ad_actor_sys_prio = 65535;
ni_link_address_init(&bonding->ad_actor_system);
}

/*
Expand Down Expand Up @@ -250,6 +253,10 @@ ni_bonding_clone(const ni_bonding_t *orig)
C(tlb_dynamic_lb);
C(lp_interval);

C(ad_user_port_key);
C(ad_actor_sys_prio);
memcpy(&bond->ad_actor_system, &orig->ad_actor_system,
sizeof(bond->ad_actor_system));
C(ad_info.aggregator_id);
C(ad_info.ports);
C(ad_info.actor_key);
Expand Down Expand Up @@ -438,6 +445,16 @@ ni_bonding_validate(const ni_bonding_t *bonding)

if (bonding->min_links > INT_MAX)
return "ieee802-3ad min-links option not in range 0-INT_MAX";

if (bonding->ad_user_port_key > 1023)
return "ieee802-3ad user port key is not in range 0-1023";
if (bonding->ad_actor_sys_prio < 1)
return "ieee802-3ad actor system prio is not in range 1-65535";
if (bonding->ad_actor_system.len &&
bonding->ad_actor_system.type != ARPHRD_ETHER &&
ni_link_address_is_invalid(&bonding->ad_actor_system))
return "ieee802-3ad actor system is not a valid ethernet address";

} else {
if (bonding->lacp_rate != NI_BOND_LACP_RATE_SLOW)
return "lacp rate only valid in ieee802-3ad mode";
Expand Down Expand Up @@ -1428,6 +1445,29 @@ ni_bonding_set_option(ni_bonding_t *bond, const char *option, const char *value)
return TRUE;
} else

if (strcmp(option, "ad_user_port_key") == 0) {
if (ni_parse_uint(value, &tmp, 0) < 0 || tmp > 1023)
return FALSE;
bond->ad_user_port_key = tmp;
return TRUE;
} else

if (strcmp(option, "ad_actor_sys_prio") == 0) {
if (ni_parse_uint(value, &tmp, 0) < 0 || tmp < 1 || tmp > 65535)
return FALSE;
bond->ad_actor_sys_prio = tmp;
return TRUE;
} else

if (strcmp(option, "ad_actor_system") == 0) {
if (ni_link_address_parse(&bond->ad_actor_system, ARPHRD_ETHER, value) < 0 ||
ni_link_address_is_invalid(&bond->ad_actor_system)) {
ni_link_address_init(&bond->ad_actor_system);
return FALSE;
}
return TRUE;
} else

if (strcmp(option, "min_links") == 0) {
if (ni_parse_uint(value, &tmp, 10) < 0)
return FALSE;
Expand Down
39 changes: 39 additions & 0 deletions src/dbus-objects/bonding.c
Expand Up @@ -590,6 +590,39 @@ __ni_objectmodel_bonding_set_slaves(ni_dbus_object_t *object,
return TRUE;
}

static dbus_bool_t
__ni_objectmodel_bonding_get_ad_actor_system(const ni_dbus_object_t *object,
const ni_dbus_property_t *property,
ni_dbus_variant_t *result,
DBusError *error)
{
const ni_bonding_t *bond;

if (!(bond = __ni_objectmodel_bonding_read_handle(object, error)))
return FALSE;
return __ni_objectmodel_get_hwaddr(result, &bond->ad_actor_system);
}

static dbus_bool_t
__ni_objectmodel_bonding_set_ad_actor_system(ni_dbus_object_t *object,
const ni_dbus_property_t *property,
const ni_dbus_variant_t *argument,
DBusError *error)
{
ni_bonding_t *bond;

if (!(bond = __ni_objectmodel_bonding_write_handle(object, error)))
return FALSE;

ni_link_address_init(&bond->ad_actor_system);
if (__ni_objectmodel_set_hwaddr(argument, &bond->ad_actor_system)) {
if (bond->ad_actor_system.len == ni_link_address_length(ARPHRD_ETHER))
bond->ad_actor_system.type = ARPHRD_ETHER;
return TRUE;
}
return TRUE;
}

static dbus_bool_t
__ni_objectmodel_bonding_get_address(const ni_dbus_object_t *object,
const ni_dbus_property_t *property,
Expand Down Expand Up @@ -622,6 +655,8 @@ __ni_objectmodel_bonding_set_address(ni_dbus_object_t *object,
NI_DBUS_GENERIC_STRING_PROPERTY(bonding, dbus_name, member_name, rw)
#define BONDING_UINT_PROPERTY(dbus_name, member_name, rw) \
NI_DBUS_GENERIC_UINT_PROPERTY(bonding, dbus_name, member_name, rw)
#define BONDING_UINT16_PROPERTY(dbus_name, member_name, rw) \
NI_DBUS_GENERIC_UINT16_PROPERTY(bonding, dbus_name, member_name, rw)
#define BONDING_BOOL_PROPERTY(dbus_name, member_name, rw) \
NI_DBUS_GENERIC_BOOL_PROPERTY(bonding, dbus_name, member_name, rw)
#define BONDING_STRING_ARRAY_PROPERTY(dbus_name, member_name, rw) \
Expand All @@ -632,6 +667,10 @@ static ni_dbus_property_t ni_objectmodel_bond_properties[] = {
BONDING_UINT_PROPERTY(xmit-hash-policy, xmit_hash_policy, RO),
BONDING_UINT_PROPERTY(lacp-rate, lacp_rate, RO),
BONDING_UINT_PROPERTY(ad-select, ad_select, RO),
BONDING_UINT16_PROPERTY(ad-user-port-key, ad_user_port_key, RO),
BONDING_UINT16_PROPERTY(ad-actor-sys-prio, ad_actor_sys_prio, RO),
___NI_DBUS_PROPERTY(DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
ad-actor-system, ad_actor_system, __ni_objectmodel_bonding, RO),
BONDING_UINT_PROPERTY(min-links, min_links, RO),
BONDING_UINT_PROPERTY(resend-igmp, resend_igmp, RO),
BONDING_UINT_PROPERTY(num-grat-arp, num_grat_arp, RO),
Expand Down
52 changes: 52 additions & 0 deletions src/ifconfig.c
Expand Up @@ -1495,9 +1495,17 @@ ni_system_bond_create_netlink(ni_netconfig_t *nc, const ni_netdev_t *cfg, ni_net
int
ni_system_bond_create(ni_netconfig_t *nc, const ni_netdev_t *cfg, ni_netdev_t **dev_ret)
{
const char *complaint;

if (!nc || !dev_ret || !cfg || cfg->link.type != NI_IFTYPE_BOND || ni_string_empty(cfg->name))
return -NI_ERROR_INVALID_ARGS;

complaint = ni_bonding_validate(cfg->bonding);
if (complaint != NULL) {
ni_error("%s: cannot set up bonding device: %s", cfg->name, complaint);
return -NI_ERROR_INVALID_ARGS;
}

switch (ni_config_bonding_ctl()) {
case NI_CONFIG_BONDING_CTL_SYSFS:
return ni_system_bond_create_sysfs(nc, cfg, dev_ret);
Expand Down Expand Up @@ -2471,6 +2479,16 @@ __ni_rtnl_link_put_bond_opt(ni_netconfig_t *nc, struct nl_msg *msg, const char *
return __ni_rtnl_link_put_bond_opt_debug(ifname, name, ret,
conf->packets_per_slave, NULL);

case IFLA_BOND_TLB_DYNAMIC_LB:
if (conf->tlb_dynamic_lb != bond->tlb_dynamic_lb) {
NLA_PUT_U8 (msg, attr, conf->tlb_dynamic_lb ? 1 : 0);
bond->tlb_dynamic_lb = conf->tlb_dynamic_lb;
ret = 0;
}
return __ni_rtnl_link_put_bond_opt_debug(ifname, name, ret,
conf->tlb_dynamic_lb,
conf->tlb_dynamic_lb ? "on" : "off");

case IFLA_BOND_AD_LACP_RATE:
if (conf->lacp_rate != bond->lacp_rate) {
NLA_PUT_U8 (msg, attr, conf->lacp_rate);
Expand All @@ -2491,6 +2509,32 @@ __ni_rtnl_link_put_bond_opt(ni_netconfig_t *nc, struct nl_msg *msg, const char *
conf->ad_select,
ni_bonding_ad_select_name(conf->ad_select));

case IFLA_BOND_AD_USER_PORT_KEY:
if (conf->ad_user_port_key != bond->ad_user_port_key) {
NLA_PUT_U16(msg, attr, conf->ad_user_port_key);
ret = 0;
}
return __ni_rtnl_link_put_bond_opt_debug(ifname, name, ret,
0, "a key");

case IFLA_BOND_AD_ACTOR_SYS_PRIO:
if (conf->ad_actor_sys_prio != bond->ad_actor_sys_prio) {
NLA_PUT_U16(msg, attr, conf->ad_actor_sys_prio);
ret = 0;
}
return __ni_rtnl_link_put_bond_opt_debug(ifname, name, ret,
0, "a prio");

case IFLA_BOND_AD_ACTOR_SYSTEM:
if (conf->ad_actor_system.len &&
!ni_link_address_is_invalid(&conf->ad_actor_system) &&
!ni_link_address_equal(&conf->ad_actor_system, &bond->ad_actor_system)) {
NLA_PUT(msg, attr, conf->ad_actor_system.len, conf->ad_actor_system.data);
ret = 0;
}
return __ni_rtnl_link_put_bond_opt_debug(ifname, name, ret,
0, "a mac");

default:
ret = -1;
}
Expand Down Expand Up @@ -2529,6 +2573,12 @@ __ni_rtnl_link_put_bond(ni_netconfig_t *nc, struct nl_msg *msg, ni_netdev_t *dev
.bstate = -1),
map_opt(IFLA_BOND_AD_SELECT, .modes = NI_BIT(NI_BOND_MODE_802_3AD),
.bstate = -1),
map_opt(IFLA_BOND_AD_ACTOR_SYS_PRIO, .modes = NI_BIT(NI_BOND_MODE_802_3AD),
.bstate = -1),
map_opt(IFLA_BOND_AD_USER_PORT_KEY, .modes = NI_BIT(NI_BOND_MODE_802_3AD),
.bstate = -1),
map_opt(IFLA_BOND_AD_ACTOR_SYSTEM, .modes = NI_BIT(NI_BOND_MODE_802_3AD),
.bstate = -1),
map_opt(IFLA_BOND_XMIT_HASH_POLICY, .modes = NI_BIT(NI_BOND_MODE_802_3AD)
| NI_BIT(NI_BOND_MODE_BALANCE_XOR)
| NI_BIT(NI_BOND_MODE_BALANCE_TLB)),
Expand All @@ -2540,6 +2590,8 @@ __ni_rtnl_link_put_bond(ni_netconfig_t *nc, struct nl_msg *msg, ni_netdev_t *dev
| NI_BIT(NI_BOND_MODE_BALANCE_ALB)
| NI_BIT(NI_BOND_MODE_BALANCE_TLB),
.bstate = 1, .slaves = 1),
map_opt(IFLA_BOND_TLB_DYNAMIC_LB, .modes = NI_BIT(NI_BOND_MODE_BALANCE_TLB),
.bstate = -1),
map_opt(IFLA_BOND_MIN_LINKS),
map_opt(IFLA_BOND_FAIL_OVER_MAC, .slaves = -1),
map_opt(IFLA_BOND_ALL_SLAVES_ACTIVE),
Expand Down
34 changes: 30 additions & 4 deletions src/iflist.c
Expand Up @@ -3259,6 +3259,10 @@ __ni_discover_bond_netlink_master(ni_netdev_t *dev, struct nlattr *info_data, ni
[IFLA_BOND_AD_LACP_RATE] = { .type = NLA_U8 },
[IFLA_BOND_AD_SELECT] = { .type = NLA_U8 },
[IFLA_BOND_AD_INFO] = { .type = NLA_NESTED },
[IFLA_BOND_AD_USER_PORT_KEY] = { .type = NLA_U16 },
[IFLA_BOND_AD_ACTOR_SYS_PRIO] = { .type = NLA_U16 },
[IFLA_BOND_AD_ACTOR_SYSTEM] = { .type = NLA_UNSPEC },
[IFLA_BOND_TLB_DYNAMIC_LB] = { .type = NLA_U8 },
};
#define map_attr(attr) [attr] = #attr
static const char * __bond_master_attrs[IFLA_BOND_MAX+1] = {
Expand All @@ -3285,6 +3289,10 @@ __ni_discover_bond_netlink_master(ni_netdev_t *dev, struct nlattr *info_data, ni
map_attr(IFLA_BOND_AD_LACP_RATE),
map_attr(IFLA_BOND_AD_SELECT),
map_attr(IFLA_BOND_AD_INFO),
map_attr(IFLA_BOND_AD_USER_PORT_KEY),
map_attr(IFLA_BOND_AD_ACTOR_SYS_PRIO),
map_attr(IFLA_BOND_AD_ACTOR_SYSTEM),
map_attr(IFLA_BOND_TLB_DYNAMIC_LB),
};
#undef map_attr
struct nlattr *tb[IFLA_BOND_MAX+1];
Expand Down Expand Up @@ -3448,16 +3456,13 @@ __ni_discover_bond_netlink_master(ni_netdev_t *dev, struct nlattr *info_data, ni
"%s: get attr %s=%u", dev->name, name,
bond->lp_interval);
break;
#if 0
case IFLA_BOND_TLB_DYNAMIC_LP:
/* bonding 3.7.1 in linux-4.1.15 does not handle it via netlink */
case IFLA_BOND_TLB_DYNAMIC_LB:
bond->tlb_dynamic_lb = nla_get_u8(aptr);
ni_debug_verbose(NI_LOG_DEBUG2, NI_TRACE_EVENTS,
"%s: get attr %s=%u (%s)", dev->name, name,
bond->tlb_dynamic_lb,
bond->tlb_dynamic_lb ? "on" : "off");
break;
#endif
case IFLA_BOND_PACKETS_PER_SLAVE:
bond->packets_per_slave = nla_get_u32(aptr);
ni_debug_verbose(NI_LOG_DEBUG2, NI_TRACE_EVENTS,
Expand All @@ -3478,6 +3483,27 @@ __ni_discover_bond_netlink_master(ni_netdev_t *dev, struct nlattr *info_data, ni
bond->ad_select,
ni_bonding_ad_select_name(bond->ad_select));
break;
case IFLA_BOND_AD_USER_PORT_KEY:
/* do not log it */
bond->ad_user_port_key = nla_get_u16(aptr);
break;
case IFLA_BOND_AD_ACTOR_SYS_PRIO:
/* do not log it */
bond->ad_actor_sys_prio = nla_get_u16(aptr);
break;
case IFLA_BOND_AD_ACTOR_SYSTEM:
/* do not log it */
if ((unsigned int)nla_len(aptr) == ni_link_address_length(ARPHRD_ETHER)) {
ni_link_address_set(&bond->ad_actor_system,
ARPHRD_ETHER, nla_data(aptr), nla_len(aptr));
/* kernel accepts only valid macs, but reports as-is;
* we have to filter out e.g. a 00:00:00:00:00:00 mac.
*/
if (!ni_link_address_is_invalid(&bond->ad_actor_system))
break;
}
ni_link_address_init(&bond->ad_actor_system);
break;
case IFLA_BOND_AD_INFO:
(void)__ni_discover_bond_netlink_ad_info(dev, aptr, nc);
/* ignore errors, it is info only */
Expand Down

0 comments on commit d84174a

Please sign in to comment.