bond: use netlink to set bond options
Use the netlink platform implementation for setting the bond link options.
This commit is contained in:
@@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
#include <linux/if_ether.h>
|
||||||
|
#include <linux/if_link.h>
|
||||||
|
|
||||||
#include "NetworkManagerUtils.h"
|
#include "NetworkManagerUtils.h"
|
||||||
#include "nm-device-private.h"
|
#include "nm-device-private.h"
|
||||||
@@ -16,6 +18,7 @@
|
|||||||
#include "nm-device-factory.h"
|
#include "nm-device-factory.h"
|
||||||
#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
|
#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
|
||||||
#include "libnm-core-intern/nm-core-internal.h"
|
#include "libnm-core-intern/nm-core-internal.h"
|
||||||
|
#include "nm-manager.h"
|
||||||
#include "nm-setting-bond-port.h"
|
#include "nm-setting-bond-port.h"
|
||||||
|
|
||||||
#define _NMLOG_DEVICE_TYPE NMDeviceBond
|
#define _NMLOG_DEVICE_TYPE NMDeviceBond
|
||||||
@@ -349,51 +352,144 @@ set_bond_arp_ip_targets(NMDevice *device, NMSettingBond *s_bond)
|
|||||||
nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET));
|
nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET));
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static guint8
|
||||||
apply_bonding_config(NMDeviceBond *self)
|
_bond_arp_ip_target_to_platform(const char *value, in_addr_t out[static NM_BOND_MAX_ARP_TARGETS])
|
||||||
{
|
{
|
||||||
NMDevice *device = NM_DEVICE(self);
|
gs_free const char **ip = NULL;
|
||||||
NMSettingBond *s_bond;
|
in_addr_t in_a;
|
||||||
NMBondMode mode;
|
int i;
|
||||||
const char *mode_str;
|
int added = 0;
|
||||||
gs_free char *device_bond_mode = NULL;
|
|
||||||
|
|
||||||
s_bond = nm_device_get_applied_setting(device, NM_TYPE_SETTING_BOND);
|
ip = nm_strsplit_set(value, " ");
|
||||||
g_return_val_if_fail(s_bond, FALSE);
|
|
||||||
|
|
||||||
mode_str = nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_MODE);
|
if (!ip)
|
||||||
mode = _nm_setting_bond_mode_from_string(mode_str);
|
return added;
|
||||||
g_return_val_if_fail(mode != NM_BOND_MODE_UNKNOWN, FALSE);
|
|
||||||
|
|
||||||
/* Set mode first, as some other options (e.g. arp_interval) are valid
|
for (i = 0; ip[i]; i++) {
|
||||||
* only for certain modes.
|
if (added > NM_BOND_MAX_ARP_TARGETS - 1)
|
||||||
*/
|
break;
|
||||||
device_bond_mode = nm_platform_sysctl_master_get_option(nm_device_get_platform(device),
|
if (!nm_utils_parse_inaddr_bin(AF_INET, ip[i], NULL, &in_a))
|
||||||
nm_device_get_ifindex(device),
|
continue;
|
||||||
NM_SETTING_BOND_OPTION_MODE);
|
|
||||||
/* Need to release all slaves before we can change bond mode */
|
|
||||||
if (!nm_streq0(device_bond_mode, mode_str))
|
|
||||||
nm_device_master_release_slaves_all(device);
|
|
||||||
|
|
||||||
set_bond_attr_or_default(device, s_bond, NM_SETTING_BOND_OPTION_MODE);
|
out[added++] = in_a;
|
||||||
|
}
|
||||||
|
return added;
|
||||||
|
}
|
||||||
|
|
||||||
set_bond_arp_ip_targets(device, s_bond);
|
static int
|
||||||
|
_setting_bond_primary_opt_as_ifindex(NMSettingBond *s_bond)
|
||||||
|
{
|
||||||
|
const char *primary_str;
|
||||||
|
int ifindex = 0;
|
||||||
|
|
||||||
set_bond_attrs_or_default(device, s_bond, NM_MAKE_STRV(OPTIONS_APPLY_SUBSET));
|
primary_str = nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_PRIMARY);
|
||||||
return TRUE;
|
|
||||||
|
if (primary_str != NULL)
|
||||||
|
ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, primary_str);
|
||||||
|
|
||||||
|
return ifindex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_platform_lnk_bond_init_from_setting(NMSettingBond *s_bond, NMPlatformLnkBond *props)
|
||||||
|
{
|
||||||
|
const char *opt_value;
|
||||||
|
|
||||||
|
*props = (NMPlatformLnkBond){
|
||||||
|
.mode = _nm_setting_bond_mode_from_string(
|
||||||
|
nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_MODE)),
|
||||||
|
.primary = _setting_bond_primary_opt_as_ifindex(s_bond),
|
||||||
|
.miimon = _nm_setting_bond_opt_value_as_u32(s_bond, NM_SETTING_BOND_OPTION_MIIMON),
|
||||||
|
.updelay = _nm_setting_bond_opt_value_as_u32(s_bond, NM_SETTING_BOND_OPTION_UPDELAY),
|
||||||
|
.downdelay = _nm_setting_bond_opt_value_as_u32(s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY),
|
||||||
|
.arp_interval =
|
||||||
|
_nm_setting_bond_opt_value_as_u32(s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL),
|
||||||
|
.resend_igmp =
|
||||||
|
_nm_setting_bond_opt_value_as_u32(s_bond, NM_SETTING_BOND_OPTION_RESEND_IGMP),
|
||||||
|
.min_links = _nm_setting_bond_opt_value_as_u32(s_bond, NM_SETTING_BOND_OPTION_MIN_LINKS),
|
||||||
|
.lp_interval =
|
||||||
|
_nm_setting_bond_opt_value_as_u32(s_bond, NM_SETTING_BOND_OPTION_LP_INTERVAL),
|
||||||
|
.packets_per_port =
|
||||||
|
_nm_setting_bond_opt_value_as_u32(s_bond, NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE),
|
||||||
|
.peer_notif_delay =
|
||||||
|
_nm_setting_bond_opt_value_as_u32(s_bond, NM_SETTING_BOND_OPTION_PEER_NOTIF_DELAY),
|
||||||
|
.arp_all_targets = _nm_setting_bond_arp_all_targets_from_string(
|
||||||
|
nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS)),
|
||||||
|
.arp_validate = _nm_setting_bond_arp_validate_from_string(
|
||||||
|
nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_ARP_VALIDATE)),
|
||||||
|
.ad_actor_sys_prio =
|
||||||
|
_nm_setting_bond_opt_value_as_u16(s_bond, NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO),
|
||||||
|
.ad_user_port_key =
|
||||||
|
_nm_setting_bond_opt_value_as_u16(s_bond, NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY),
|
||||||
|
.primary_reselect = _nm_setting_bond_primary_reselect_from_string(
|
||||||
|
nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_PRIMARY_RESELECT)),
|
||||||
|
.fail_over_mac = _nm_setting_bond_fail_over_mac_from_string(
|
||||||
|
nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_FAIL_OVER_MAC)),
|
||||||
|
.xmit_hash_policy = _nm_setting_bond_xmit_hash_policy_from_string(
|
||||||
|
nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY)),
|
||||||
|
.num_grat_arp =
|
||||||
|
_nm_setting_bond_opt_value_as_u8(s_bond, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP),
|
||||||
|
.all_ports_active =
|
||||||
|
_nm_setting_bond_opt_value_as_u8(s_bond, NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE),
|
||||||
|
.lacp_rate = _nm_setting_bond_lacp_rate_from_string(
|
||||||
|
nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_LACP_RATE)),
|
||||||
|
.ad_select = _nm_setting_bond_ad_select_from_string(
|
||||||
|
nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_AD_SELECT)),
|
||||||
|
};
|
||||||
|
|
||||||
|
nm_ether_addr_from_string(
|
||||||
|
&props->ad_actor_system,
|
||||||
|
nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM));
|
||||||
|
|
||||||
|
opt_value = nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_USE_CARRIER);
|
||||||
|
if (opt_value != NULL)
|
||||||
|
props->use_carrier = _nm_utils_ascii_str_to_bool(opt_value, FALSE);
|
||||||
|
|
||||||
|
opt_value =
|
||||||
|
nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB);
|
||||||
|
if (opt_value != NULL)
|
||||||
|
props->tlb_dynamic_lb = _nm_utils_ascii_str_to_bool(opt_value, FALSE);
|
||||||
|
|
||||||
|
opt_value = nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
|
||||||
|
if (opt_value != NULL)
|
||||||
|
props->arp_ip_targets_num =
|
||||||
|
_bond_arp_ip_target_to_platform(opt_value, props->arp_ip_target);
|
||||||
|
|
||||||
|
props->miimon_has = !props->arp_interval && !props->arp_validate;
|
||||||
|
props->updelay_has = props->miimon_has && props->miimon;
|
||||||
|
props->downdelay_has = props->miimon_has && props->miimon;
|
||||||
|
props->peer_notif_delay_has = (props->miimon || props->arp_interval) && props->peer_notif_delay;
|
||||||
|
props->arp_all_targets_has = props->arp_interval && props->arp_all_targets;
|
||||||
|
props->resend_igmp_has = props->resend_igmp != 1;
|
||||||
|
props->lp_interval = props->lp_interval != 1;
|
||||||
|
props->tlb_dynamic_lb_has = NM_IN_SET(props->mode, NM_BOND_MODE_TLB, NM_BOND_MODE_ALB);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NMActStageReturn
|
static NMActStageReturn
|
||||||
act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
||||||
{
|
{
|
||||||
NMDeviceBond *self = NM_DEVICE_BOND(device);
|
|
||||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
||||||
|
NMConnection *connection;
|
||||||
|
NMSettingBond *s_bond;
|
||||||
|
NMPlatformLnkBond props;
|
||||||
|
int r;
|
||||||
|
int ifindex = nm_device_get_ifindex(device);
|
||||||
|
|
||||||
|
connection = nm_device_get_applied_connection(device);
|
||||||
|
g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE);
|
||||||
|
|
||||||
|
s_bond = nm_connection_get_setting_bond(connection);
|
||||||
|
g_return_val_if_fail(s_bond, NM_ACT_STAGE_RETURN_FAILURE);
|
||||||
|
|
||||||
|
_platform_lnk_bond_init_from_setting(s_bond, &props);
|
||||||
|
|
||||||
/* Interface must be down to set bond options */
|
/* Interface must be down to set bond options */
|
||||||
nm_device_take_down(device, TRUE);
|
nm_device_take_down(device, TRUE);
|
||||||
if (!apply_bonding_config(self))
|
r = nm_platform_link_bond_change(nm_device_get_platform(device), ifindex, &props);
|
||||||
|
if (r < 0) {
|
||||||
ret = NM_ACT_STAGE_RETURN_FAILURE;
|
ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||||
else {
|
NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
|
||||||
|
} else {
|
||||||
if (!nm_device_hw_addr_set_cloned(device, nm_device_get_applied_connection(device), FALSE))
|
if (!nm_device_hw_addr_set_cloned(device, nm_device_get_applied_connection(device), FALSE))
|
||||||
ret = NM_ACT_STAGE_RETURN_FAILURE;
|
ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||||
}
|
}
|
||||||
@@ -536,11 +632,18 @@ create_and_realize(NMDevice *device,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
const char *iface = nm_device_get_iface(device);
|
const char *iface = nm_device_get_iface(device);
|
||||||
|
NMSettingBond *s_bond;
|
||||||
|
NMPlatformLnkBond props;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
g_assert(iface);
|
g_assert(iface);
|
||||||
|
|
||||||
r = nm_platform_link_bond_add(nm_device_get_platform(device), iface, NULL, out_plink);
|
s_bond = nm_connection_get_setting_bond(connection);
|
||||||
|
nm_assert(s_bond);
|
||||||
|
|
||||||
|
_platform_lnk_bond_init_from_setting(s_bond, &props);
|
||||||
|
|
||||||
|
r = nm_platform_link_bond_add(nm_device_get_platform(device), iface, &props, out_plink);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_set_error(error,
|
g_set_error(error,
|
||||||
NM_DEVICE_ERROR,
|
NM_DEVICE_ERROR,
|
||||||
|
Reference in New Issue
Block a user