mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 22:48:01 +02:00
libnm,core: support "bond.balance-slb" option
(cherry picked from commit 2366d45e11ebef55cf20c3012098022507255749) (cherry picked from commit8891f76f03) (cherry picked from commit83dbfe6d0d)
This commit is contained in:
parent
9b247f7969
commit
9be35e2f55
3 changed files with 164 additions and 5 deletions
|
|
@ -17,6 +17,7 @@
|
||||||
#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-setting-bond-port.h"
|
#include "nm-setting-bond-port.h"
|
||||||
|
#include "nm-bond-manager.h"
|
||||||
|
|
||||||
#define _NMLOG_DEVICE_TYPE NMDeviceBond
|
#define _NMLOG_DEVICE_TYPE NMDeviceBond
|
||||||
#include "nm-device-logging.h"
|
#include "nm-device-logging.h"
|
||||||
|
|
@ -56,7 +57,8 @@
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
struct _NMDeviceBond {
|
struct _NMDeviceBond {
|
||||||
NMDevice parent;
|
NMDevice parent;
|
||||||
|
NMBondManager *bond_manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _NMDeviceBondClass {
|
struct _NMDeviceBondClass {
|
||||||
|
|
@ -175,7 +177,9 @@ update_connection(NMDevice *device, NMConnection *connection)
|
||||||
gs_free char *value = NULL;
|
gs_free char *value = NULL;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
if (NM_IN_STRSET(option, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE))
|
if (NM_IN_STRSET(option,
|
||||||
|
NM_SETTING_BOND_OPTION_ACTIVE_SLAVE,
|
||||||
|
NM_SETTING_BOND_OPTION_BALANCE_SLB))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
value =
|
value =
|
||||||
|
|
@ -383,11 +387,115 @@ apply_bonding_config(NMDeviceBond *self)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_balance_slb_cb(NMBondManager *bond_manager, NMBondManagerEventType event_type, gpointer user_data)
|
||||||
|
{
|
||||||
|
NMDevice *device = user_data;
|
||||||
|
NMDeviceBond *self = NM_DEVICE_BOND(device);
|
||||||
|
|
||||||
|
nm_assert(NM_IS_DEVICE_BOND(self));
|
||||||
|
nm_assert(self->bond_manager == bond_manager);
|
||||||
|
|
||||||
|
switch (event_type) {
|
||||||
|
case NM_BOND_MANAGER_EVENT_TYPE_STATE:
|
||||||
|
switch (nm_bond_manager_get_state(bond_manager)) {
|
||||||
|
case NM_OPTION_BOOL_FALSE:
|
||||||
|
if (nm_device_get_state(device) <= NM_DEVICE_STATE_ACTIVATED) {
|
||||||
|
_LOGD(LOGD_BOND, "balance-slb: failed");
|
||||||
|
nm_device_state_changed(device,
|
||||||
|
NM_DEVICE_STATE_FAILED,
|
||||||
|
NM_DEVICE_STATE_REASON_CONFIG_FAILED);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case NM_OPTION_BOOL_TRUE:
|
||||||
|
if (nm_device_get_state(device) <= NM_DEVICE_STATE_ACTIVATED
|
||||||
|
&& nm_device_devip_get_state(device, AF_UNSPEC) <= NM_DEVICE_IP_STATE_PENDING) {
|
||||||
|
nm_device_devip_set_state(device, AF_UNSPEC, NM_DEVICE_IP_STATE_READY, NULL);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case NM_OPTION_BOOL_DEFAULT:
|
||||||
|
if (nm_device_get_state(device) <= NM_DEVICE_STATE_ACTIVATED
|
||||||
|
&& nm_device_devip_get_state(device, AF_UNSPEC) == NM_DEVICE_IP_STATE_READY) {
|
||||||
|
/* We are again busy. We can also go back to "pending" from "ready".
|
||||||
|
* If ip-config state is not yet complete, this will further delay it.
|
||||||
|
* Otherwise, it should have no effect. */
|
||||||
|
nm_device_devip_set_state(device, AF_UNSPEC, NM_DEVICE_IP_STATE_PENDING, NULL);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nm_assert_not_reached();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nm_assert_not_reached();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_balance_slb_setup(NMDeviceBond *self, NMConnection *connection)
|
||||||
|
{
|
||||||
|
int ifindex = nm_device_get_ifindex(NM_DEVICE(self));
|
||||||
|
gboolean balance_slb = FALSE;
|
||||||
|
const char *uuid;
|
||||||
|
NMSettingBond *s_bond;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
if (ifindex > 0 && connection && (s_bond = nm_connection_get_setting_bond(connection))
|
||||||
|
&& (s = nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_BALANCE_SLB)))
|
||||||
|
balance_slb = (!!_nm_utils_ascii_str_to_int64(s, 10, 0, 1, 0));
|
||||||
|
|
||||||
|
if (!balance_slb) {
|
||||||
|
if (nm_clear_pointer(&self->bond_manager, nm_bond_manager_destroy)) {
|
||||||
|
_LOGD(LOGD_BOND, "balance-slb: stopped");
|
||||||
|
nm_device_devip_set_state(NM_DEVICE(self), AF_UNSPEC, NM_DEVICE_IP_STATE_NONE, NULL);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uuid = nm_connection_get_uuid(connection);
|
||||||
|
|
||||||
|
if (self->bond_manager) {
|
||||||
|
if (nm_bond_manager_get_ifindex(self->bond_manager) == ifindex
|
||||||
|
&& nm_streq0(nm_bond_manager_get_connection_uuid(self->bond_manager), uuid)) {
|
||||||
|
_LOGD(LOGD_BOND, "balance-slb: reapply");
|
||||||
|
nm_bond_manager_reapply(self->bond_manager);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nm_clear_pointer(&self->bond_manager, nm_bond_manager_destroy);
|
||||||
|
_LOGD(LOGD_BOND, "balance-slb: restart");
|
||||||
|
}
|
||||||
|
|
||||||
|
_LOGD(LOGD_BOND, "balance-slb: start");
|
||||||
|
if (nm_device_devip_get_state(NM_DEVICE(self), AF_UNSPEC) < NM_DEVICE_IP_STATE_PENDING)
|
||||||
|
nm_device_devip_set_state(NM_DEVICE(self), AF_UNSPEC, NM_DEVICE_IP_STATE_PENDING, NULL);
|
||||||
|
self->bond_manager = nm_bond_manager_new(nm_device_get_platform(NM_DEVICE(self)),
|
||||||
|
ifindex,
|
||||||
|
uuid,
|
||||||
|
_balance_slb_cb,
|
||||||
|
self);
|
||||||
|
nm_assert(nm_bond_manager_get_state(self->bond_manager) == NM_OPTION_BOOL_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (nm_device_sys_iface_state_is_external(device))
|
||||||
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||||
|
|
||||||
|
_balance_slb_setup(self, connection);
|
||||||
|
|
||||||
|
if (nm_device_sys_iface_state_is_external_or_assume(device))
|
||||||
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||||
|
|
||||||
/* 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);
|
||||||
|
|
@ -576,7 +684,7 @@ can_reapply_change(NMDevice *device,
|
||||||
const char *name = *option_list;
|
const char *name = *option_list;
|
||||||
|
|
||||||
/* We support changes to these */
|
/* We support changes to these */
|
||||||
if (NM_IN_STRSET(name, OPTIONS_REAPPLY_FULL))
|
if (NM_IN_STRSET(name, OPTIONS_REAPPLY_FULL, NM_SETTING_BOND_OPTION_BALANCE_SLB))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Reject any other changes */
|
/* Reject any other changes */
|
||||||
|
|
@ -622,6 +730,16 @@ reapply_connection(NMDevice *device, NMConnection *con_old, NMConnection *con_ne
|
||||||
set_bond_arp_ip_targets(device, s_bond);
|
set_bond_arp_ip_targets(device, s_bond);
|
||||||
|
|
||||||
set_bond_attrs_or_default(device, s_bond, NM_MAKE_STRV(OPTIONS_REAPPLY_SUBSET));
|
set_bond_attrs_or_default(device, s_bond, NM_MAKE_STRV(OPTIONS_REAPPLY_SUBSET));
|
||||||
|
|
||||||
|
_balance_slb_setup(self, con_new);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
deactivate(NMDevice *device)
|
||||||
|
{
|
||||||
|
NMDeviceBond *self = NM_DEVICE_BOND(device);
|
||||||
|
|
||||||
|
_balance_slb_setup(self, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
@ -660,13 +778,15 @@ nm_device_bond_class_init(NMDeviceBondClass *klass)
|
||||||
device_class->update_connection = update_connection;
|
device_class->update_connection = update_connection;
|
||||||
device_class->master_update_slave_connection = controller_update_port_connection;
|
device_class->master_update_slave_connection = controller_update_port_connection;
|
||||||
|
|
||||||
device_class->create_and_realize = create_and_realize;
|
device_class->create_and_realize = create_and_realize;
|
||||||
device_class->act_stage1_prepare = act_stage1_prepare;
|
device_class->act_stage1_prepare = act_stage1_prepare;
|
||||||
|
device_class->act_stage1_prepare_also_for_external_or_assume = TRUE;
|
||||||
device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired;
|
device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired;
|
||||||
device_class->enslave_slave = enslave_slave;
|
device_class->enslave_slave = enslave_slave;
|
||||||
device_class->release_slave = release_slave;
|
device_class->release_slave = release_slave;
|
||||||
device_class->can_reapply_change = can_reapply_change;
|
device_class->can_reapply_change = can_reapply_change;
|
||||||
device_class->reapply_connection = reapply_connection;
|
device_class->reapply_connection = reapply_connection;
|
||||||
|
device_class->deactivate = deactivate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ static const char *const valid_options_lst[] = {
|
||||||
NM_SETTING_BOND_OPTION_ARP_INTERVAL,
|
NM_SETTING_BOND_OPTION_ARP_INTERVAL,
|
||||||
NM_SETTING_BOND_OPTION_ARP_IP_TARGET,
|
NM_SETTING_BOND_OPTION_ARP_IP_TARGET,
|
||||||
NM_SETTING_BOND_OPTION_ARP_VALIDATE,
|
NM_SETTING_BOND_OPTION_ARP_VALIDATE,
|
||||||
|
NM_SETTING_BOND_OPTION_BALANCE_SLB,
|
||||||
NM_SETTING_BOND_OPTION_PRIMARY,
|
NM_SETTING_BOND_OPTION_PRIMARY,
|
||||||
NM_SETTING_BOND_OPTION_PRIMARY_RESELECT,
|
NM_SETTING_BOND_OPTION_PRIMARY_RESELECT,
|
||||||
NM_SETTING_BOND_OPTION_FAIL_OVER_MAC,
|
NM_SETTING_BOND_OPTION_FAIL_OVER_MAC,
|
||||||
|
|
@ -195,6 +196,7 @@ static NM_UTILS_STRING_TABLE_LOOKUP_STRUCT_DEFINE(
|
||||||
{NM_SETTING_BOND_OPTION_ARP_IP_TARGET, {"", NM_BOND_OPTION_TYPE_IP}},
|
{NM_SETTING_BOND_OPTION_ARP_IP_TARGET, {"", NM_BOND_OPTION_TYPE_IP}},
|
||||||
{NM_SETTING_BOND_OPTION_ARP_VALIDATE,
|
{NM_SETTING_BOND_OPTION_ARP_VALIDATE,
|
||||||
{"none", NM_BOND_OPTION_TYPE_BOTH, 0, 6, _option_default_strv_arp_validate}},
|
{"none", NM_BOND_OPTION_TYPE_BOTH, 0, 6, _option_default_strv_arp_validate}},
|
||||||
|
{NM_SETTING_BOND_OPTION_BALANCE_SLB, {"0", NM_BOND_OPTION_TYPE_INT, 0, 1}},
|
||||||
{NM_SETTING_BOND_OPTION_DOWNDELAY, {"0", NM_BOND_OPTION_TYPE_INT, 0, G_MAXINT}},
|
{NM_SETTING_BOND_OPTION_DOWNDELAY, {"0", NM_BOND_OPTION_TYPE_INT, 0, G_MAXINT}},
|
||||||
{NM_SETTING_BOND_OPTION_FAIL_OVER_MAC,
|
{NM_SETTING_BOND_OPTION_FAIL_OVER_MAC,
|
||||||
{"none", NM_BOND_OPTION_TYPE_BOTH, 0, 2, _option_default_strv_fail_over_mac}},
|
{"none", NM_BOND_OPTION_TYPE_BOTH, 0, 2, _option_default_strv_fail_over_mac}},
|
||||||
|
|
@ -344,6 +346,17 @@ _bond_get_option_normalized(NMSettingBond *self, const char *option, gboolean ge
|
||||||
value = _bond_get_option(self, NM_SETTING_BOND_OPTION_PRIMARY);
|
value = _bond_get_option(self, NM_SETTING_BOND_OPTION_PRIMARY);
|
||||||
if (!value)
|
if (!value)
|
||||||
value = _bond_get_option(self, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE);
|
value = _bond_get_option(self, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE);
|
||||||
|
} else if (nm_streq(option, NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY)) {
|
||||||
|
if (_nm_utils_ascii_str_to_int64(
|
||||||
|
_bond_get_option(self, NM_SETTING_BOND_OPTION_BALANCE_SLB),
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
-1)
|
||||||
|
== 1) {
|
||||||
|
/* balance-slb implies vlan+srcmac */
|
||||||
|
return "5";
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
value = _bond_get_option(self, option);
|
value = _bond_get_option(self, option);
|
||||||
|
|
||||||
|
|
@ -789,6 +802,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
|
||||||
const char *arp_ip_target = NULL;
|
const char *arp_ip_target = NULL;
|
||||||
const char *lacp_rate;
|
const char *lacp_rate;
|
||||||
const char *primary;
|
const char *primary;
|
||||||
|
const char *s;
|
||||||
NMBondMode bond_mode;
|
NMBondMode bond_mode;
|
||||||
guint i;
|
guint i;
|
||||||
const NMUtilsNamedValue *n;
|
const NMUtilsNamedValue *n;
|
||||||
|
|
@ -1016,6 +1030,30 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s = _bond_get_option(self, NM_SETTING_BOND_OPTION_BALANCE_SLB);
|
||||||
|
if (s && _atoi(s) > 0) {
|
||||||
|
if (bond_mode != NM_BOND_MODE_XOR) {
|
||||||
|
g_set_error(error,
|
||||||
|
NM_CONNECTION_ERROR,
|
||||||
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
|
_("%s requires bond mode \"%s\""),
|
||||||
|
NM_SETTING_BOND_OPTION_BALANCE_SLB,
|
||||||
|
"balance-xor");
|
||||||
|
g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
s = _bond_get_option(self, NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY);
|
||||||
|
if (!NM_IN_STRSET(s, NULL, "5", "vlan+srcmac")) {
|
||||||
|
g_set_error(error,
|
||||||
|
NM_CONNECTION_ERROR,
|
||||||
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
|
_("%s requires xmit_hash_policy \"vlan+srcmac\""),
|
||||||
|
NM_SETTING_BOND_OPTION_BALANCE_SLB);
|
||||||
|
g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!_nm_connection_verify_required_interface_name(connection, error))
|
if (!_nm_connection_verify_required_interface_name(connection, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ G_BEGIN_DECLS
|
||||||
#define NM_SETTING_BOND_OPTION_ARP_IP_TARGET "arp_ip_target"
|
#define NM_SETTING_BOND_OPTION_ARP_IP_TARGET "arp_ip_target"
|
||||||
#define NM_SETTING_BOND_OPTION_ARP_VALIDATE "arp_validate"
|
#define NM_SETTING_BOND_OPTION_ARP_VALIDATE "arp_validate"
|
||||||
#define NM_SETTING_BOND_OPTION_PRIMARY "primary"
|
#define NM_SETTING_BOND_OPTION_PRIMARY "primary"
|
||||||
|
#define NM_SETTING_BOND_OPTION_BALANCE_SLB "balance-slb"
|
||||||
#define NM_SETTING_BOND_OPTION_PRIMARY_RESELECT "primary_reselect"
|
#define NM_SETTING_BOND_OPTION_PRIMARY_RESELECT "primary_reselect"
|
||||||
#define NM_SETTING_BOND_OPTION_FAIL_OVER_MAC "fail_over_mac"
|
#define NM_SETTING_BOND_OPTION_FAIL_OVER_MAC "fail_over_mac"
|
||||||
#define NM_SETTING_BOND_OPTION_USE_CARRIER "use_carrier"
|
#define NM_SETTING_BOND_OPTION_USE_CARRIER "use_carrier"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue