mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-26 04:10:14 +01:00
merge: branch 'ff/bond_netlink'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1227
This commit is contained in:
commit
fba856f204
15 changed files with 943 additions and 36 deletions
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <net/if.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_link.h>
|
||||
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-device-private.h"
|
||||
|
|
@ -16,6 +18,7 @@
|
|||
#include "nm-device-factory.h"
|
||||
#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
|
||||
#include "libnm-core-intern/nm-core-internal.h"
|
||||
#include "nm-manager.h"
|
||||
#include "nm-setting-bond-port.h"
|
||||
|
||||
#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));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
apply_bonding_config(NMDeviceBond *self)
|
||||
static guint8
|
||||
_bond_arp_ip_target_to_platform(const char *value, in_addr_t out[static NM_BOND_MAX_ARP_TARGETS])
|
||||
{
|
||||
NMDevice *device = NM_DEVICE(self);
|
||||
NMSettingBond *s_bond;
|
||||
NMBondMode mode;
|
||||
const char *mode_str;
|
||||
gs_free char *device_bond_mode = NULL;
|
||||
gs_free const char **ip = NULL;
|
||||
in_addr_t in_a;
|
||||
int i;
|
||||
int added = 0;
|
||||
|
||||
s_bond = nm_device_get_applied_setting(device, NM_TYPE_SETTING_BOND);
|
||||
g_return_val_if_fail(s_bond, FALSE);
|
||||
ip = nm_strsplit_set(value, " ");
|
||||
|
||||
mode_str = nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_MODE);
|
||||
mode = _nm_setting_bond_mode_from_string(mode_str);
|
||||
g_return_val_if_fail(mode != NM_BOND_MODE_UNKNOWN, FALSE);
|
||||
if (!ip)
|
||||
return added;
|
||||
|
||||
/* Set mode first, as some other options (e.g. arp_interval) are valid
|
||||
* only for certain modes.
|
||||
*/
|
||||
device_bond_mode = nm_platform_sysctl_master_get_option(nm_device_get_platform(device),
|
||||
nm_device_get_ifindex(device),
|
||||
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);
|
||||
for (i = 0; ip[i]; i++) {
|
||||
if (added > NM_BOND_MAX_ARP_TARGETS - 1)
|
||||
break;
|
||||
if (!nm_utils_parse_inaddr_bin(AF_INET, ip[i], NULL, &in_a))
|
||||
continue;
|
||||
|
||||
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));
|
||||
return TRUE;
|
||||
primary_str = nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_PRIMARY);
|
||||
|
||||
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
|
||||
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 */
|
||||
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;
|
||||
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))
|
||||
ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
|
@ -535,12 +631,19 @@ create_and_realize(NMDevice *device,
|
|||
const NMPlatformLink **out_plink,
|
||||
GError **error)
|
||||
{
|
||||
const char *iface = nm_device_get_iface(device);
|
||||
int r;
|
||||
const char *iface = nm_device_get_iface(device);
|
||||
NMSettingBond *s_bond;
|
||||
NMPlatformLnkBond props;
|
||||
int r;
|
||||
|
||||
g_assert(iface);
|
||||
|
||||
r = nm_platform_link_bond_add(nm_device_get_platform(device), iface, 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) {
|
||||
g_set_error(error,
|
||||
NM_DEVICE_ERROR,
|
||||
|
|
|
|||
|
|
@ -323,6 +323,15 @@ link_add(NMPlatform *platform,
|
|||
dev_lnk = nmp_object_new(NMP_OBJECT_TYPE_LNK_BRIDGE, props);
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_BOND:
|
||||
{
|
||||
const NMPlatformLnkBond *props = extra_data;
|
||||
|
||||
nm_assert(props);
|
||||
|
||||
dev_lnk = nmp_object_new(NMP_OBJECT_TYPE_LNK_BOND, props);
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_VETH:
|
||||
veth_peer = extra_data;
|
||||
g_assert(veth_peer);
|
||||
|
|
|
|||
|
|
@ -111,13 +111,16 @@ software_add(NMLinkType link_type, const char *name)
|
|||
{
|
||||
gboolean bond0_exists = !!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "bond0");
|
||||
int r;
|
||||
const NMPlatformLnkBond nm_platform_lnk_bond_default = {
|
||||
.mode = 3,
|
||||
};
|
||||
|
||||
r = nm_platform_link_bond_add(NM_PLATFORM_GET, name, NULL);
|
||||
r = nm_platform_link_bond_add(NM_PLATFORM_GET, name, &nm_platform_lnk_bond_default, NULL);
|
||||
|
||||
/* Check that bond0 is *not* automatically created. */
|
||||
if (!bond0_exists)
|
||||
g_assert(!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "bond0"));
|
||||
return r >= 0;
|
||||
return NMTST_NM_ERR_SUCCESS(r);
|
||||
}
|
||||
case NM_LINK_TYPE_TEAM:
|
||||
return NMTST_NM_ERR_SUCCESS(nm_platform_link_team_add(NM_PLATFORM_GET, name, NULL));
|
||||
|
|
|
|||
|
|
@ -40,6 +40,121 @@ _nm_setting_bond_remove_options_arp_interval(NMSettingBond *s_bond)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(
|
||||
_nm_setting_bond_ad_select_from_string,
|
||||
NMBondAdSelect,
|
||||
{
|
||||
G_STATIC_ASSERT_EXPR(_NM_BOND_AD_SELECT_NUM <= 3);
|
||||
|
||||
if (name && name[0] < '0' + _NM_BOND_AD_SELECT_NUM && name[0] >= '0' && name[1] == '\0') {
|
||||
return name[0] - '0';
|
||||
}
|
||||
},
|
||||
{ return NM_BOND_AD_SELECT_STABLE; },
|
||||
{"bandwith", NM_BOND_AD_SELECT_BANDWIDTH},
|
||||
{"count", NM_BOND_AD_SELECT_COUNT},
|
||||
{"stable", NM_BOND_AD_SELECT_STABLE}, );
|
||||
|
||||
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(
|
||||
_nm_setting_bond_arp_all_targets_from_string,
|
||||
NMBondArpAllTargets,
|
||||
{
|
||||
G_STATIC_ASSERT_EXPR(_NM_BOND_ARP_ALL_TARGETS_NUM <= 2);
|
||||
|
||||
if (name && name[0] < '0' + _NM_BOND_ARP_ALL_TARGETS_NUM && name[0] >= '0'
|
||||
&& name[1] == '\0') {
|
||||
return name[0] - '0';
|
||||
}
|
||||
},
|
||||
{ return NM_BOND_ARP_ALL_TARGETS_ANY; },
|
||||
{"all", NM_BOND_ARP_ALL_TARGETS_ALL},
|
||||
{"any", NM_BOND_ARP_ALL_TARGETS_ANY}, );
|
||||
|
||||
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(
|
||||
_nm_setting_bond_fail_over_mac_from_string,
|
||||
NMBondFailOverMac,
|
||||
{
|
||||
G_STATIC_ASSERT_EXPR(_NM_BOND_FAIL_OVER_MAC_NUM <= 3);
|
||||
|
||||
if (name && name[0] < '0' + _NM_BOND_FAIL_OVER_MAC_NUM && name[0] >= '0'
|
||||
&& name[1] == '\0') {
|
||||
return name[0] - '0';
|
||||
}
|
||||
},
|
||||
{ return NM_BOND_FAIL_OVER_MAC_NONE; },
|
||||
{"active", NM_BOND_FAIL_OVER_MAC_ACTIVE},
|
||||
{"follow", NM_BOND_FAIL_OVER_MAC_FOLLOW},
|
||||
{"none", NM_BOND_FAIL_OVER_MAC_NONE}, );
|
||||
|
||||
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(
|
||||
_nm_setting_bond_lacp_rate_from_string,
|
||||
NMBondLacpRate,
|
||||
{
|
||||
G_STATIC_ASSERT_EXPR(_NM_BOND_LACP_RATE_NUM <= 2);
|
||||
|
||||
if (name && name[0] < '0' + _NM_BOND_LACP_RATE_NUM && name[0] >= '0' && name[1] == '\0') {
|
||||
return name[0] - '0';
|
||||
}
|
||||
},
|
||||
{ return NM_BOND_LACP_RATE_SLOW; },
|
||||
{"fast", NM_BOND_LACP_RATE_FAST},
|
||||
{"slow", NM_BOND_LACP_RATE_SLOW}, );
|
||||
|
||||
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(
|
||||
_nm_setting_bond_arp_validate_from_string,
|
||||
NMBondArpValidate,
|
||||
{
|
||||
G_STATIC_ASSERT_EXPR(_NM_BOND_ARP_VALIDATE_NUM <= 7);
|
||||
|
||||
if (name && name[0] < '0' + _NM_BOND_ARP_VALIDATE_NUM && name[0] >= '0'
|
||||
&& name[1] == '\0') {
|
||||
return name[0] - '0';
|
||||
}
|
||||
},
|
||||
{ return NM_BOND_ARP_VALIDATE_NONE; },
|
||||
{"active", NM_BOND_ARP_VALIDATE_ACTIVE},
|
||||
{"all", NM_BOND_ARP_VALIDATE_ALL},
|
||||
{"backup", NM_BOND_ARP_VALIDATE_BACKUP},
|
||||
{"filter", NM_BOND_ARP_VALIDATE_FILTER},
|
||||
{"filter_active", NM_BOND_ARP_VALIDATE_FILTER_ACTIVE},
|
||||
{"filter_backup", NM_BOND_ARP_VALIDATE_FILTER_BACKUP},
|
||||
{"none", NM_BOND_ARP_VALIDATE_NONE}, );
|
||||
|
||||
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(
|
||||
_nm_setting_bond_primary_reselect_from_string,
|
||||
NMBondPrimaryReselect,
|
||||
{
|
||||
G_STATIC_ASSERT_EXPR(_NM_BOND_PRIMARY_RESELECT_NUM <= 3);
|
||||
|
||||
if (name && name[0] < '0' + _NM_BOND_PRIMARY_RESELECT_NUM && name[0] >= '0'
|
||||
&& name[1] == '\0') {
|
||||
return name[0] - '0';
|
||||
}
|
||||
},
|
||||
{ return NM_BOND_PRIMARY_RESELECT_ALWAYS; },
|
||||
{"always", NM_BOND_PRIMARY_RESELECT_ALWAYS},
|
||||
{"better", NM_BOND_PRIMARY_RESELECT_BETTER},
|
||||
{"failure", NM_BOND_PRIMARY_RESELECT_FAILURE}, );
|
||||
|
||||
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(
|
||||
_nm_setting_bond_xmit_hash_policy_from_string,
|
||||
NMBondXmitHashPolicy,
|
||||
{
|
||||
G_STATIC_ASSERT_EXPR(_NM_BOND_XMIT_HASH_POLICY_NUM <= 6);
|
||||
|
||||
if (name && name[0] < '0' + _NM_BOND_XMIT_HASH_POLICY_NUM && name[0] >= '0'
|
||||
&& name[1] == '\0') {
|
||||
return name[0] - '0';
|
||||
}
|
||||
},
|
||||
{ return NM_BOND_XMIT_HASH_POLICY_LAYER2; },
|
||||
{"encap2+3", NM_BOND_XMIT_HASH_POLICY_ENCAP2_3},
|
||||
{"encap3+4", NM_BOND_XMIT_HASH_POLICY_ENCAP3_4},
|
||||
{"layer2", NM_BOND_XMIT_HASH_POLICY_LAYER2},
|
||||
{"layer2+3", NM_BOND_XMIT_HASH_POLICY_LAYER2_3},
|
||||
{"layer3+4", NM_BOND_XMIT_HASH_POLICY_LAYER3_4},
|
||||
{"vlan+srcmac", NM_BOND_XMIT_HASH_POLICY_VLAN_SRCMAC}, );
|
||||
|
||||
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(
|
||||
_nm_setting_bond_mode_from_string,
|
||||
NMBondMode,
|
||||
|
|
|
|||
|
|
@ -57,6 +57,102 @@ const char **nm_utils_bond_option_arp_ip_targets_split(const char *arp_ip_target
|
|||
void _nm_setting_bond_remove_options_miimon(NMSettingBond *s_bond);
|
||||
void _nm_setting_bond_remove_options_arp_interval(NMSettingBond *s_bond);
|
||||
|
||||
typedef enum {
|
||||
NM_BOND_AD_SELECT_UNKNOWN = -1,
|
||||
|
||||
/* The numeric values correspond to kernel's numbering. */
|
||||
NM_BOND_AD_SELECT_STABLE = 0,
|
||||
NM_BOND_AD_SELECT_BANDWIDTH = 1,
|
||||
NM_BOND_AD_SELECT_COUNT = 2,
|
||||
|
||||
_NM_BOND_AD_SELECT_NUM,
|
||||
} NMBondAdSelect;
|
||||
|
||||
NMBondAdSelect _nm_setting_bond_ad_select_from_string(const char *str);
|
||||
|
||||
typedef enum {
|
||||
NM_BOND_ARP_ALL_TARGETS_UNKNOWN = -1,
|
||||
|
||||
/* The numeric values correspond to kernel's numbering. */
|
||||
NM_BOND_ARP_ALL_TARGETS_ANY = 0,
|
||||
NM_BOND_ARP_ALL_TARGETS_ALL = 1,
|
||||
|
||||
_NM_BOND_ARP_ALL_TARGETS_NUM,
|
||||
} NMBondArpAllTargets;
|
||||
|
||||
NMBondArpAllTargets _nm_setting_bond_arp_all_targets_from_string(const char *str);
|
||||
|
||||
typedef enum {
|
||||
NM_BOND_FAIL_OVER_MAC_UNKNOWN = -1,
|
||||
|
||||
/* The numeric values correspond to kernel's numbering. */
|
||||
NM_BOND_FAIL_OVER_MAC_NONE = 0,
|
||||
NM_BOND_FAIL_OVER_MAC_ACTIVE = 1,
|
||||
NM_BOND_FAIL_OVER_MAC_FOLLOW = 2,
|
||||
|
||||
_NM_BOND_FAIL_OVER_MAC_NUM,
|
||||
} NMBondFailOverMac;
|
||||
|
||||
NMBondFailOverMac _nm_setting_bond_fail_over_mac_from_string(const char *str);
|
||||
|
||||
typedef enum {
|
||||
NM_BOND_LACP_RATE_UNKNOWN = -1,
|
||||
|
||||
/* The numeric values correspond to kernel's numbering. */
|
||||
NM_BOND_LACP_RATE_SLOW = 0,
|
||||
NM_BOND_LACP_RATE_FAST = 1,
|
||||
|
||||
_NM_BOND_LACP_RATE_NUM,
|
||||
} NMBondLacpRate;
|
||||
|
||||
NMBondLacpRate _nm_setting_bond_lacp_rate_from_string(const char *str);
|
||||
|
||||
typedef enum {
|
||||
NM_BOND_ARP_VALIDATE_UNKNOWN = -1,
|
||||
|
||||
/* The numeric values correspond to kernel's numbering. */
|
||||
NM_BOND_ARP_VALIDATE_NONE = 0,
|
||||
NM_BOND_ARP_VALIDATE_ACTIVE = 1,
|
||||
NM_BOND_ARP_VALIDATE_BACKUP = 2,
|
||||
NM_BOND_ARP_VALIDATE_ALL = 3,
|
||||
NM_BOND_ARP_VALIDATE_FILTER = 4,
|
||||
NM_BOND_ARP_VALIDATE_FILTER_ACTIVE = 5,
|
||||
NM_BOND_ARP_VALIDATE_FILTER_BACKUP = 6,
|
||||
|
||||
_NM_BOND_ARP_VALIDATE_NUM,
|
||||
} NMBondArpValidate;
|
||||
|
||||
NMBondArpValidate _nm_setting_bond_arp_validate_from_string(const char *str);
|
||||
|
||||
typedef enum {
|
||||
NM_BOND_PRIMARY_RESELECT_UNKNOWN = -1,
|
||||
|
||||
/* The numeric values correspond to kernel's numbering. */
|
||||
NM_BOND_PRIMARY_RESELECT_ALWAYS = 0,
|
||||
NM_BOND_PRIMARY_RESELECT_BETTER = 1,
|
||||
NM_BOND_PRIMARY_RESELECT_FAILURE = 2,
|
||||
|
||||
_NM_BOND_PRIMARY_RESELECT_NUM,
|
||||
} NMBondPrimaryReselect;
|
||||
|
||||
NMBondPrimaryReselect _nm_setting_bond_primary_reselect_from_string(const char *str);
|
||||
|
||||
typedef enum {
|
||||
NM_BOND_XMIT_HASH_POLICY_UNKNOWN = -1,
|
||||
|
||||
/* The numeric values correspond to kernel's numbering. */
|
||||
NM_BOND_XMIT_HASH_POLICY_LAYER2 = 0,
|
||||
NM_BOND_XMIT_HASH_POLICY_LAYER3_4 = 1,
|
||||
NM_BOND_XMIT_HASH_POLICY_LAYER2_3 = 2,
|
||||
NM_BOND_XMIT_HASH_POLICY_ENCAP2_3 = 3,
|
||||
NM_BOND_XMIT_HASH_POLICY_ENCAP3_4 = 4,
|
||||
NM_BOND_XMIT_HASH_POLICY_VLAN_SRCMAC = 5,
|
||||
|
||||
_NM_BOND_XMIT_HASH_POLICY_NUM,
|
||||
} NMBondXmitHashPolicy;
|
||||
|
||||
NMBondXmitHashPolicy _nm_setting_bond_xmit_hash_policy_from_string(const char *str);
|
||||
|
||||
typedef enum {
|
||||
NM_BOND_MODE_UNKNOWN = -1,
|
||||
|
||||
|
|
|
|||
|
|
@ -764,6 +764,39 @@ _nm_setting_bond_get_option_type(NMSettingBond *setting, const char *name)
|
|||
return option_meta->opt_type;
|
||||
}
|
||||
|
||||
guint32
|
||||
_nm_setting_bond_opt_value_as_u32(NMSettingBond *s_bond, const char *opt)
|
||||
{
|
||||
nm_assert(_get_option_meta(opt)->opt_type == NM_BOND_OPTION_TYPE_INT);
|
||||
return _nm_utils_ascii_str_to_uint64(nm_setting_bond_get_option_normalized(s_bond, opt),
|
||||
10,
|
||||
0,
|
||||
G_MAXUINT32,
|
||||
0);
|
||||
}
|
||||
|
||||
guint16
|
||||
_nm_setting_bond_opt_value_as_u16(NMSettingBond *s_bond, const char *opt)
|
||||
{
|
||||
nm_assert(_get_option_meta(opt)->opt_type == NM_BOND_OPTION_TYPE_INT);
|
||||
return _nm_utils_ascii_str_to_uint64(nm_setting_bond_get_option_normalized(s_bond, opt),
|
||||
10,
|
||||
0,
|
||||
G_MAXUINT16,
|
||||
0);
|
||||
}
|
||||
|
||||
guint8
|
||||
_nm_setting_bond_opt_value_as_u8(NMSettingBond *s_bond, const char *opt)
|
||||
{
|
||||
nm_assert(_get_option_meta(opt)->opt_type == NM_BOND_OPTION_TYPE_INT);
|
||||
return _nm_utils_ascii_str_to_uint64(nm_setting_bond_get_option_normalized(s_bond, opt),
|
||||
10,
|
||||
0,
|
||||
G_MAXUINT8,
|
||||
0);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
|
|
|
|||
|
|
@ -517,6 +517,10 @@ NMConnectionMultiConnect _nm_connection_get_multi_connect(NMConnection *connecti
|
|||
|
||||
gboolean _nm_setting_bond_option_supported(const char *option, NMBondMode mode);
|
||||
|
||||
guint32 _nm_setting_bond_opt_value_as_u32(NMSettingBond *s_bond, const char *opt);
|
||||
guint16 _nm_setting_bond_opt_value_as_u16(NMSettingBond *s_bond, const char *opt);
|
||||
guint8 _nm_setting_bond_opt_value_as_u8(NMSettingBond *s_bond, const char *opt);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
GPtrArray *_nm_setting_bridge_get_vlans(NMSettingBridge *setting);
|
||||
|
|
|
|||
|
|
@ -146,6 +146,18 @@ G_STATIC_ASSERT(ETH_ALEN == sizeof(NMEtherAddr));
|
|||
|
||||
G_STATIC_ASSERT(_nm_alignof(struct ether_addr) <= _nm_alignof(NMEtherAddr));
|
||||
|
||||
NMEtherAddr *
|
||||
nm_ether_addr_from_string(NMEtherAddr *addr, const char *str)
|
||||
{
|
||||
nm_assert(addr);
|
||||
|
||||
if (!str || !_nm_utils_hwaddr_aton_exact(str, addr, ETH_ALEN)) {
|
||||
*addr = NM_ETHER_ADDR_INIT(0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2859,6 +2859,8 @@ nm_ether_addr_to_string(const NMEtherAddr *ether_addr, char sbuf[static(sizeof(N
|
|||
#define nm_ether_addr_to_string_a(ether_addr) \
|
||||
nm_ether_addr_to_string((ether_addr), g_alloca(sizeof(NMEtherAddr) * 3))
|
||||
|
||||
NMEtherAddr *nm_ether_addr_from_string(NMEtherAddr *addr, const char *str);
|
||||
|
||||
guint8 *nm_utils_hexstr2bin_full(const char *hexstr,
|
||||
gboolean allow_0x_prefix,
|
||||
gboolean delimiter_required,
|
||||
|
|
|
|||
|
|
@ -1535,6 +1535,152 @@ _parse_lnk_bridge(const char *kind, struct nlattr *info_data)
|
|||
|
||||
/***********************************************************************************/
|
||||
|
||||
static NMPObject *
|
||||
_parse_lnk_bond(const char *kind, struct nlattr *info_data)
|
||||
{
|
||||
static const struct nla_policy policy[] = {
|
||||
[IFLA_BOND_MODE] = {.type = NLA_U8},
|
||||
[IFLA_BOND_ACTIVE_SLAVE] = {.type = NLA_U32},
|
||||
[IFLA_BOND_MIIMON] = {.type = NLA_U32},
|
||||
[IFLA_BOND_UPDELAY] = {.type = NLA_U32},
|
||||
[IFLA_BOND_DOWNDELAY] = {.type = NLA_U32},
|
||||
[IFLA_BOND_USE_CARRIER] = {.type = NLA_U8},
|
||||
[IFLA_BOND_ARP_INTERVAL] = {.type = NLA_U32},
|
||||
[IFLA_BOND_ARP_IP_TARGET] = {.type = NLA_NESTED},
|
||||
[IFLA_BOND_ARP_VALIDATE] = {.type = NLA_U32},
|
||||
[IFLA_BOND_ARP_ALL_TARGETS] = {.type = NLA_U32},
|
||||
[IFLA_BOND_PRIMARY] = {.type = NLA_U32},
|
||||
[IFLA_BOND_PRIMARY_RESELECT] = {.type = NLA_U8},
|
||||
[IFLA_BOND_FAIL_OVER_MAC] = {.type = NLA_U8},
|
||||
[IFLA_BOND_XMIT_HASH_POLICY] = {.type = NLA_U8},
|
||||
[IFLA_BOND_RESEND_IGMP] = {.type = NLA_U32},
|
||||
[IFLA_BOND_NUM_PEER_NOTIF] = {.type = NLA_U8},
|
||||
[IFLA_BOND_ALL_SLAVES_ACTIVE] = {.type = NLA_U8},
|
||||
[IFLA_BOND_MIN_LINKS] = {.type = NLA_U32},
|
||||
[IFLA_BOND_LP_INTERVAL] = {.type = NLA_U32},
|
||||
[IFLA_BOND_PACKETS_PER_SLAVE] = {.type = NLA_U32},
|
||||
[IFLA_BOND_AD_LACP_RATE] = {.type = NLA_U8},
|
||||
[IFLA_BOND_AD_SELECT] = {.type = NLA_U8},
|
||||
[IFLA_BOND_AD_ACTOR_SYS_PRIO] = {.type = NLA_U16},
|
||||
[IFLA_BOND_AD_USER_PORT_KEY] = {.type = NLA_U16},
|
||||
[IFLA_BOND_AD_ACTOR_SYSTEM] = {.minlen = sizeof(NMEtherAddr)},
|
||||
[IFLA_BOND_TLB_DYNAMIC_LB] = {.type = NLA_U8},
|
||||
[IFLA_BOND_PEER_NOTIF_DELAY] = {.type = NLA_U32},
|
||||
};
|
||||
NMPlatformLnkBond *props;
|
||||
struct nlattr *tb[G_N_ELEMENTS(policy)];
|
||||
NMPObject *obj = NULL;
|
||||
|
||||
if (!info_data || !nm_streq0(kind, "bond"))
|
||||
return NULL;
|
||||
|
||||
if (nla_parse_nested_arr(tb, info_data, policy) < 0)
|
||||
return NULL;
|
||||
|
||||
obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_BOND, NULL);
|
||||
|
||||
props = &obj->lnk_bond;
|
||||
|
||||
if (tb[IFLA_BOND_MODE])
|
||||
props->mode = nla_get_u8(tb[IFLA_BOND_MODE]);
|
||||
if (tb[IFLA_BOND_PRIMARY]) {
|
||||
props->primary = nla_get_u32(tb[IFLA_BOND_PRIMARY]);
|
||||
} else if (tb[IFLA_BOND_ACTIVE_SLAVE]) {
|
||||
props->primary = nla_get_u32(tb[IFLA_BOND_ACTIVE_SLAVE]);
|
||||
}
|
||||
if (tb[IFLA_BOND_MIIMON]) {
|
||||
props->miimon = nla_get_u32(tb[IFLA_BOND_MIIMON]);
|
||||
props->miimon_has = TRUE;
|
||||
} else {
|
||||
props->miimon_has = FALSE;
|
||||
}
|
||||
if (tb[IFLA_BOND_UPDELAY]) {
|
||||
props->updelay = nla_get_u32(tb[IFLA_BOND_UPDELAY]);
|
||||
props->updelay_has = TRUE;
|
||||
} else {
|
||||
props->updelay_has = FALSE;
|
||||
}
|
||||
if (tb[IFLA_BOND_DOWNDELAY]) {
|
||||
props->downdelay = nla_get_u32(tb[IFLA_BOND_DOWNDELAY]);
|
||||
props->downdelay_has = TRUE;
|
||||
} else {
|
||||
props->downdelay_has = FALSE;
|
||||
}
|
||||
if (tb[IFLA_BOND_USE_CARRIER])
|
||||
props->use_carrier = nla_get_u8(tb[IFLA_BOND_USE_CARRIER]);
|
||||
if (tb[IFLA_BOND_ARP_INTERVAL])
|
||||
props->arp_interval = nla_get_u32(tb[IFLA_BOND_ARP_INTERVAL]);
|
||||
if (tb[IFLA_BOND_ARP_IP_TARGET]) {
|
||||
struct nlattr *attr;
|
||||
int rem;
|
||||
|
||||
nla_for_each_nested (attr, tb[IFLA_BOND_ARP_IP_TARGET], rem) {
|
||||
if (props->arp_ip_targets_num > NM_BOND_MAX_ARP_TARGETS - 1)
|
||||
break;
|
||||
if (nla_len(attr) < sizeof(in_addr_t))
|
||||
break;
|
||||
|
||||
props->arp_ip_target[props->arp_ip_targets_num++] = nla_get_u32(attr);
|
||||
}
|
||||
}
|
||||
if (tb[IFLA_BOND_ARP_VALIDATE])
|
||||
props->arp_validate = nla_get_u32(tb[IFLA_BOND_ARP_VALIDATE]);
|
||||
if (tb[IFLA_BOND_ARP_ALL_TARGETS]) {
|
||||
props->arp_all_targets = nla_get_u32(tb[IFLA_BOND_ARP_ALL_TARGETS]);
|
||||
props->arp_all_targets_has = TRUE;
|
||||
} else {
|
||||
props->arp_all_targets_has = FALSE;
|
||||
}
|
||||
if (tb[IFLA_BOND_PRIMARY_RESELECT])
|
||||
props->primary_reselect = nla_get_u8(tb[IFLA_BOND_PRIMARY_RESELECT]);
|
||||
if (tb[IFLA_BOND_FAIL_OVER_MAC])
|
||||
props->fail_over_mac = nla_get_u8(tb[IFLA_BOND_FAIL_OVER_MAC]);
|
||||
if (tb[IFLA_BOND_XMIT_HASH_POLICY])
|
||||
props->xmit_hash_policy = nla_get_u8(tb[IFLA_BOND_XMIT_HASH_POLICY]);
|
||||
if (tb[IFLA_BOND_RESEND_IGMP]) {
|
||||
props->resend_igmp = nla_get_u32(tb[IFLA_BOND_RESEND_IGMP]);
|
||||
props->resend_igmp_has = TRUE;
|
||||
} else {
|
||||
props->resend_igmp_has = FALSE;
|
||||
}
|
||||
if (tb[IFLA_BOND_NUM_PEER_NOTIF])
|
||||
props->num_grat_arp = nla_get_u8(tb[IFLA_BOND_NUM_PEER_NOTIF]);
|
||||
if (tb[IFLA_BOND_ALL_SLAVES_ACTIVE])
|
||||
props->all_ports_active = nla_get_u8(tb[IFLA_BOND_ALL_SLAVES_ACTIVE]);
|
||||
if (tb[IFLA_BOND_MIN_LINKS])
|
||||
props->min_links = nla_get_u32(tb[IFLA_BOND_MIN_LINKS]);
|
||||
if (tb[IFLA_BOND_LP_INTERVAL])
|
||||
props->lp_interval = nla_get_u32(tb[IFLA_BOND_LP_INTERVAL]);
|
||||
if (tb[IFLA_BOND_PACKETS_PER_SLAVE])
|
||||
props->packets_per_port = nla_get_u32(tb[IFLA_BOND_PACKETS_PER_SLAVE]);
|
||||
if (tb[IFLA_BOND_AD_LACP_RATE])
|
||||
props->lacp_rate = nla_get_u8(tb[IFLA_BOND_AD_LACP_RATE]);
|
||||
if (tb[IFLA_BOND_AD_SELECT])
|
||||
props->ad_select = nla_get_u8(tb[IFLA_BOND_AD_SELECT]);
|
||||
if (tb[IFLA_BOND_AD_ACTOR_SYS_PRIO])
|
||||
props->ad_actor_sys_prio = nla_get_u16(tb[IFLA_BOND_AD_ACTOR_SYS_PRIO]);
|
||||
if (tb[IFLA_BOND_AD_USER_PORT_KEY])
|
||||
props->ad_user_port_key = nla_get_u16(tb[IFLA_BOND_AD_USER_PORT_KEY]);
|
||||
if (tb[IFLA_BOND_AD_ACTOR_SYSTEM])
|
||||
props->ad_actor_system = *nla_data_as(NMEtherAddr, tb[IFLA_BOND_AD_ACTOR_SYSTEM]);
|
||||
if (tb[IFLA_BOND_TLB_DYNAMIC_LB]) {
|
||||
props->tlb_dynamic_lb = nla_get_u8(tb[IFLA_BOND_TLB_DYNAMIC_LB]);
|
||||
props->tlb_dynamic_lb_has = TRUE;
|
||||
} else {
|
||||
props->tlb_dynamic_lb_has = FALSE;
|
||||
}
|
||||
if (tb[IFLA_BOND_PEER_NOTIF_DELAY]) {
|
||||
props->peer_notif_delay = nla_get_u32(tb[IFLA_BOND_PEER_NOTIF_DELAY]);
|
||||
props->peer_notif_delay_has = TRUE;
|
||||
} else {
|
||||
props->peer_notif_delay_has = FALSE;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/***********************************************************************************/
|
||||
|
||||
static NMPObject *
|
||||
_parse_lnk_gre(const char *kind, struct nlattr *info_data)
|
||||
{
|
||||
|
|
@ -3202,6 +3348,9 @@ _new_from_nl_link(NMPlatform *platform,
|
|||
case NM_LINK_TYPE_BRIDGE:
|
||||
lnk_data = _parse_lnk_bridge(nl_info_kind, nl_info_data);
|
||||
break;
|
||||
case NM_LINK_TYPE_BOND:
|
||||
lnk_data = _parse_lnk_bond(nl_info_kind, nl_info_data);
|
||||
break;
|
||||
case NM_LINK_TYPE_GRE:
|
||||
case NM_LINK_TYPE_GRETAP:
|
||||
lnk_data = _parse_lnk_gre(nl_info_kind, nl_info_data);
|
||||
|
|
@ -4354,6 +4503,86 @@ _nl_msg_new_link_set_linkinfo(struct nl_msg *msg, NMLinkType link_type, gconstpo
|
|||
NLA_PUT_U64(msg, IFLA_BR_MCAST_STARTUP_QUERY_INTVL, props->mcast_startup_query_interval);
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_BOND:
|
||||
{
|
||||
const NMPlatformLnkBond *props = extra_data;
|
||||
struct nlattr *targets;
|
||||
int i = 0;
|
||||
|
||||
nm_assert(extra_data);
|
||||
|
||||
if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (props->arp_ip_targets_num > 0) {
|
||||
targets = nla_nest_start(msg, IFLA_BOND_ARP_IP_TARGET);
|
||||
if (!targets)
|
||||
goto nla_put_failure;
|
||||
|
||||
for (i = 0; i < props->arp_ip_targets_num; i++)
|
||||
NLA_PUT_U32(msg, i, props->arp_ip_target[i]);
|
||||
|
||||
nla_nest_end(msg, targets);
|
||||
}
|
||||
|
||||
if (props->arp_all_targets_has)
|
||||
NLA_PUT_U32(msg, IFLA_BOND_ARP_ALL_TARGETS, props->arp_all_targets);
|
||||
if (props->arp_interval)
|
||||
NLA_PUT_U32(msg, IFLA_BOND_ARP_INTERVAL, props->arp_interval);
|
||||
if (props->arp_validate)
|
||||
NLA_PUT_U32(msg, IFLA_BOND_ARP_VALIDATE, props->arp_validate);
|
||||
if (props->downdelay_has)
|
||||
NLA_PUT_U32(msg, IFLA_BOND_DOWNDELAY, props->downdelay);
|
||||
if (props->lp_interval_has)
|
||||
NLA_PUT_U32(msg, IFLA_BOND_LP_INTERVAL, props->lp_interval);
|
||||
if (props->miimon_has)
|
||||
NLA_PUT_U32(msg, IFLA_BOND_MIIMON, props->miimon);
|
||||
if (props->min_links)
|
||||
NLA_PUT_U32(msg, IFLA_BOND_MIN_LINKS, props->min_links);
|
||||
if (props->packets_per_port)
|
||||
NLA_PUT_U32(msg, IFLA_BOND_PACKETS_PER_SLAVE, props->packets_per_port);
|
||||
if (props->peer_notif_delay_has)
|
||||
NLA_PUT_U32(msg, IFLA_BOND_PEER_NOTIF_DELAY, props->peer_notif_delay);
|
||||
if (props->primary)
|
||||
NLA_PUT_U32(msg, IFLA_BOND_PRIMARY, props->primary);
|
||||
if (props->resend_igmp_has)
|
||||
NLA_PUT_U32(msg, IFLA_BOND_RESEND_IGMP, props->resend_igmp);
|
||||
if (props->updelay_has)
|
||||
NLA_PUT_U32(msg, IFLA_BOND_UPDELAY, props->updelay);
|
||||
if (props->ad_actor_sys_prio)
|
||||
NLA_PUT_U16(msg, IFLA_BOND_AD_ACTOR_SYS_PRIO, props->ad_actor_sys_prio);
|
||||
if (props->ad_user_port_key)
|
||||
NLA_PUT_U16(msg, IFLA_BOND_AD_USER_PORT_KEY, props->ad_user_port_key);
|
||||
if (!nm_ether_addr_equal(&props->ad_actor_system, &nm_ether_addr_zero))
|
||||
NLA_PUT(msg,
|
||||
IFLA_BOND_AD_ACTOR_SYSTEM,
|
||||
sizeof(props->ad_actor_system),
|
||||
&props->ad_actor_system);
|
||||
if (props->ad_select)
|
||||
NLA_PUT_U8(msg, IFLA_BOND_AD_SELECT, props->ad_select);
|
||||
|
||||
NLA_PUT_U8(msg, IFLA_BOND_ALL_SLAVES_ACTIVE, props->all_ports_active);
|
||||
|
||||
if (props->fail_over_mac)
|
||||
NLA_PUT_U8(msg, IFLA_BOND_FAIL_OVER_MAC, props->fail_over_mac);
|
||||
if (props->lacp_rate)
|
||||
NLA_PUT_U8(msg, IFLA_BOND_AD_LACP_RATE, props->lacp_rate);
|
||||
if (props->num_grat_arp)
|
||||
NLA_PUT_U8(msg, IFLA_BOND_NUM_PEER_NOTIF, props->num_grat_arp);
|
||||
|
||||
NLA_PUT_U8(msg, IFLA_BOND_MODE, props->mode);
|
||||
|
||||
if (props->primary_reselect)
|
||||
NLA_PUT_U8(msg, IFLA_BOND_PRIMARY_RESELECT, props->primary_reselect);
|
||||
if (props->xmit_hash_policy)
|
||||
NLA_PUT_U8(msg, IFLA_BOND_XMIT_HASH_POLICY, props->xmit_hash_policy);
|
||||
if (props->tlb_dynamic_lb_has)
|
||||
NLA_PUT_U8(msg, IFLA_BOND_TLB_DYNAMIC_LB, !!props->tlb_dynamic_lb);
|
||||
|
||||
NLA_PUT_U8(msg, IFLA_BOND_USE_CARRIER, !!props->use_carrier);
|
||||
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_VLAN:
|
||||
{
|
||||
const NMPlatformLnkVlan *props = extra_data;
|
||||
|
|
|
|||
|
|
@ -1362,6 +1362,12 @@ nm_platform_link_add(NMPlatform *self,
|
|||
buf_p,
|
||||
buf_len);
|
||||
break;
|
||||
case NM_LINK_TYPE_BOND:
|
||||
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
||||
nm_platform_lnk_bond_to_string((const NMPlatformLnkBond *) extra_data,
|
||||
buf_p,
|
||||
buf_len);
|
||||
break;
|
||||
default:
|
||||
nm_assert(!extra_data);
|
||||
break;
|
||||
|
|
@ -1402,6 +1408,12 @@ nm_platform_link_change(NMPlatform *self, NMLinkType type, int ifindex, gconstpo
|
|||
buf_p,
|
||||
buf_len);
|
||||
break;
|
||||
case NM_LINK_TYPE_BOND:
|
||||
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
||||
nm_platform_lnk_bond_to_string((const NMPlatformLnkBond *) extra_data,
|
||||
buf_p,
|
||||
buf_len);
|
||||
break;
|
||||
default:
|
||||
nm_assert(!extra_data);
|
||||
break;
|
||||
|
|
@ -2302,6 +2314,12 @@ _link_get_lnk(NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatf
|
|||
return lnk ? &lnk->object : NULL;
|
||||
}
|
||||
|
||||
const NMPlatformLnkBond *
|
||||
nm_platform_link_get_lnk_bond(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
||||
{
|
||||
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_BOND, out_link);
|
||||
}
|
||||
|
||||
const NMPlatformLnkBridge *
|
||||
nm_platform_link_get_lnk_bridge(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
||||
{
|
||||
|
|
@ -6047,6 +6065,123 @@ nm_platform_lnk_bridge_to_string(const NMPlatformLnkBridge *lnk, char *buf, gsiz
|
|||
return buf;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_platform_lnk_bond_to_string(const NMPlatformLnkBond *lnk, char *buf, gsize len)
|
||||
{
|
||||
char sbuf_miimon[30];
|
||||
char sbuf_updelay[30];
|
||||
char sbuf_downdelay[30];
|
||||
char sbuf_peer_notif_delay[60];
|
||||
char sbuf_arp_all_targets[30];
|
||||
char sbuf_resend_igmp[30];
|
||||
char sbuf_lp_interval[30];
|
||||
char sbuf_tlb_dynamic_lb[30];
|
||||
int i;
|
||||
|
||||
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
||||
return buf;
|
||||
|
||||
nm_strbuf_append(
|
||||
&buf,
|
||||
&len,
|
||||
"bond"
|
||||
" mode %u"
|
||||
" primary %u"
|
||||
"%s" /* miimon */
|
||||
"%s" /* updelay */
|
||||
"%s" /* downdelay */
|
||||
" arp_interval %u"
|
||||
"%s" /* resend_igmp */
|
||||
" min_links %u"
|
||||
"%s" /* lp_interval */
|
||||
" packets_per_port %u"
|
||||
"%s" /* peer_notif_delay */
|
||||
"%s" /* arp_all_targets */
|
||||
" arp_validate %u"
|
||||
" ad_actor_sys_prio %u"
|
||||
" ad_user_port_key %u"
|
||||
" ad_actor_system " NM_ETHER_ADDR_FORMAT_STR ""
|
||||
" primary_reselect %u"
|
||||
" fail_over_mac %u"
|
||||
" xmit_hash_policy %u"
|
||||
" num_gray_arp %u"
|
||||
" all_ports_active %u"
|
||||
" lacp_rate %u"
|
||||
" ad_select %u"
|
||||
" use_carrier %d"
|
||||
"%s" /* tlb_dynamic_lb */,
|
||||
lnk->mode,
|
||||
lnk->primary,
|
||||
lnk->miimon_has || lnk->miimon != 0
|
||||
? nm_sprintf_buf(sbuf_miimon, " miimon%s %u", !lnk->miimon_has ? "?" : "", lnk->miimon)
|
||||
: "",
|
||||
lnk->updelay_has || lnk->updelay != 0 ? nm_sprintf_buf(sbuf_updelay,
|
||||
" updelay%s %u",
|
||||
!lnk->updelay_has ? "?" : "",
|
||||
lnk->updelay)
|
||||
: "",
|
||||
lnk->downdelay_has || lnk->downdelay != 0 ? nm_sprintf_buf(sbuf_downdelay,
|
||||
" downdelay%s %u",
|
||||
!lnk->downdelay_has ? "?" : "",
|
||||
lnk->downdelay)
|
||||
: "",
|
||||
lnk->arp_interval,
|
||||
lnk->resend_igmp_has || lnk->resend_igmp != 0
|
||||
? nm_sprintf_buf(sbuf_resend_igmp,
|
||||
" resend_igmp%s %u",
|
||||
!lnk->resend_igmp_has ? "?" : "",
|
||||
lnk->resend_igmp)
|
||||
: "",
|
||||
lnk->min_links,
|
||||
lnk->lp_interval_has || lnk->lp_interval != 1
|
||||
? nm_sprintf_buf(sbuf_lp_interval,
|
||||
" lp_interval%s %u",
|
||||
!lnk->lp_interval_has ? "?" : "",
|
||||
lnk->lp_interval)
|
||||
: "",
|
||||
lnk->packets_per_port,
|
||||
lnk->peer_notif_delay_has || lnk->peer_notif_delay != 0
|
||||
? nm_sprintf_buf(sbuf_peer_notif_delay,
|
||||
" peer_notif_delay%s %u",
|
||||
!lnk->peer_notif_delay_has ? "?" : "",
|
||||
lnk->peer_notif_delay)
|
||||
: "",
|
||||
lnk->arp_all_targets_has || lnk->arp_all_targets != 0
|
||||
? nm_sprintf_buf(sbuf_arp_all_targets,
|
||||
" arp_all_targets%s %u",
|
||||
!lnk->arp_all_targets_has ? "?" : "",
|
||||
lnk->arp_all_targets)
|
||||
: "",
|
||||
lnk->arp_validate,
|
||||
lnk->ad_actor_sys_prio,
|
||||
lnk->ad_user_port_key,
|
||||
NM_ETHER_ADDR_FORMAT_VAL(&lnk->ad_actor_system),
|
||||
lnk->primary_reselect,
|
||||
lnk->fail_over_mac,
|
||||
lnk->xmit_hash_policy,
|
||||
lnk->num_grat_arp,
|
||||
lnk->all_ports_active,
|
||||
lnk->lacp_rate,
|
||||
lnk->ad_select,
|
||||
(int) lnk->use_carrier,
|
||||
lnk->tlb_dynamic_lb_has ? nm_sprintf_buf(sbuf_tlb_dynamic_lb,
|
||||
" tlb_dynamic_lb%s %u",
|
||||
!lnk->tlb_dynamic_lb_has ? "?" : "",
|
||||
(int) lnk->tlb_dynamic_lb)
|
||||
: "");
|
||||
|
||||
if (lnk->arp_ip_targets_num > 0) {
|
||||
nm_strbuf_append_str(&buf, &len, " arp_ip_target");
|
||||
for (i = 0; i < lnk->arp_ip_targets_num; i++) {
|
||||
char target[INET_ADDRSTRLEN];
|
||||
|
||||
nm_strbuf_append_c(&buf, &len, ' ');
|
||||
nm_strbuf_append_str(&buf, &len, _nm_utils_inet4_ntop(lnk->arp_ip_target[i], target));
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_platform_lnk_gre_to_string(const NMPlatformLnkGre *lnk, char *buf, gsize len)
|
||||
{
|
||||
|
|
@ -7855,6 +7990,95 @@ nm_platform_lnk_bridge_hash_update(const NMPlatformLnkBridge *obj, NMHashState *
|
|||
obj->vlan_stats_enabled));
|
||||
}
|
||||
|
||||
void
|
||||
nm_platform_lnk_bond_hash_update(const NMPlatformLnkBond *obj, NMHashState *h)
|
||||
{
|
||||
nm_hash_update_vals(h,
|
||||
obj->arp_all_targets,
|
||||
obj->arp_interval,
|
||||
obj->arp_validate,
|
||||
obj->downdelay,
|
||||
obj->lp_interval,
|
||||
obj->miimon,
|
||||
obj->min_links,
|
||||
obj->packets_per_port,
|
||||
obj->peer_notif_delay,
|
||||
obj->primary,
|
||||
obj->resend_igmp,
|
||||
obj->updelay,
|
||||
obj->ad_actor_sys_prio,
|
||||
obj->ad_user_port_key,
|
||||
obj->ad_actor_system,
|
||||
obj->ad_select,
|
||||
obj->all_ports_active,
|
||||
obj->arp_ip_targets_num,
|
||||
obj->fail_over_mac,
|
||||
obj->lacp_rate,
|
||||
obj->num_grat_arp,
|
||||
obj->mode,
|
||||
obj->primary_reselect,
|
||||
obj->xmit_hash_policy,
|
||||
NM_HASH_COMBINE_BOOLS(guint16,
|
||||
obj->arp_all_targets_has,
|
||||
obj->downdelay_has,
|
||||
obj->lp_interval_has,
|
||||
obj->miimon_has,
|
||||
obj->peer_notif_delay_has,
|
||||
obj->resend_igmp_has,
|
||||
obj->tlb_dynamic_lb,
|
||||
obj->tlb_dynamic_lb_has,
|
||||
obj->updelay_has,
|
||||
obj->use_carrier));
|
||||
|
||||
nm_hash_update(h, obj->arp_ip_target, obj->arp_ip_targets_num * sizeof(obj->arp_ip_target[0]));
|
||||
}
|
||||
|
||||
int
|
||||
nm_platform_lnk_bond_cmp(const NMPlatformLnkBond *a, const NMPlatformLnkBond *b)
|
||||
{
|
||||
NM_CMP_SELF(a, b);
|
||||
NM_CMP_FIELD_MEMCMP_LEN(a,
|
||||
b,
|
||||
arp_ip_target,
|
||||
a->arp_ip_targets_num * sizeof(a->arp_ip_target[0]));
|
||||
NM_CMP_FIELD(a, b, arp_all_targets);
|
||||
NM_CMP_FIELD(a, b, arp_interval);
|
||||
NM_CMP_FIELD(a, b, arp_validate);
|
||||
NM_CMP_FIELD(a, b, downdelay);
|
||||
NM_CMP_FIELD(a, b, lp_interval);
|
||||
NM_CMP_FIELD(a, b, miimon);
|
||||
NM_CMP_FIELD(a, b, min_links);
|
||||
NM_CMP_FIELD(a, b, packets_per_port);
|
||||
NM_CMP_FIELD(a, b, peer_notif_delay);
|
||||
NM_CMP_FIELD(a, b, primary);
|
||||
NM_CMP_FIELD(a, b, resend_igmp);
|
||||
NM_CMP_FIELD(a, b, updelay);
|
||||
NM_CMP_FIELD(a, b, ad_actor_sys_prio);
|
||||
NM_CMP_FIELD(a, b, ad_user_port_key);
|
||||
NM_CMP_FIELD_MEMCMP(a, b, ad_actor_system);
|
||||
NM_CMP_FIELD(a, b, ad_select);
|
||||
NM_CMP_FIELD(a, b, all_ports_active);
|
||||
NM_CMP_FIELD(a, b, arp_ip_targets_num);
|
||||
NM_CMP_FIELD(a, b, fail_over_mac);
|
||||
NM_CMP_FIELD(a, b, lacp_rate);
|
||||
NM_CMP_FIELD(a, b, num_grat_arp);
|
||||
NM_CMP_FIELD(a, b, mode);
|
||||
NM_CMP_FIELD(a, b, primary_reselect);
|
||||
NM_CMP_FIELD(a, b, xmit_hash_policy);
|
||||
NM_CMP_FIELD_BOOL(a, b, arp_all_targets_has);
|
||||
NM_CMP_FIELD_BOOL(a, b, downdelay_has);
|
||||
NM_CMP_FIELD_BOOL(a, b, lp_interval_has);
|
||||
NM_CMP_FIELD_BOOL(a, b, miimon_has);
|
||||
NM_CMP_FIELD_BOOL(a, b, peer_notif_delay_has);
|
||||
NM_CMP_FIELD_BOOL(a, b, resend_igmp_has);
|
||||
NM_CMP_FIELD_BOOL(a, b, tlb_dynamic_lb);
|
||||
NM_CMP_FIELD_BOOL(a, b, tlb_dynamic_lb_has);
|
||||
NM_CMP_FIELD_BOOL(a, b, updelay_has);
|
||||
NM_CMP_FIELD_BOOL(a, b, use_carrier);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nm_platform_lnk_bridge_cmp(const NMPlatformLnkBridge *a, const NMPlatformLnkBridge *b)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -891,6 +891,47 @@ typedef struct {
|
|||
|
||||
extern const NMPlatformLnkBridge nm_platform_lnk_bridge_default;
|
||||
|
||||
/* Defined in net/bonding.h. */
|
||||
#define NM_BOND_MAX_ARP_TARGETS 16
|
||||
|
||||
typedef struct {
|
||||
in_addr_t arp_ip_target[NM_BOND_MAX_ARP_TARGETS];
|
||||
guint32 arp_all_targets;
|
||||
guint32 arp_interval;
|
||||
guint32 arp_validate;
|
||||
guint32 downdelay;
|
||||
guint32 lp_interval;
|
||||
guint32 miimon;
|
||||
guint32 min_links;
|
||||
guint32 packets_per_port;
|
||||
guint32 peer_notif_delay;
|
||||
guint32 primary;
|
||||
guint32 resend_igmp;
|
||||
guint32 updelay;
|
||||
guint16 ad_actor_sys_prio;
|
||||
guint16 ad_user_port_key;
|
||||
NMEtherAddr ad_actor_system;
|
||||
guint8 ad_select;
|
||||
guint8 all_ports_active;
|
||||
guint8 arp_ip_targets_num;
|
||||
guint8 fail_over_mac;
|
||||
guint8 lacp_rate;
|
||||
guint8 num_grat_arp;
|
||||
guint8 mode;
|
||||
guint8 primary_reselect;
|
||||
guint8 xmit_hash_policy;
|
||||
bool arp_all_targets_has : 1;
|
||||
bool downdelay_has : 1;
|
||||
bool lp_interval_has : 1;
|
||||
bool miimon_has : 1;
|
||||
bool peer_notif_delay_has : 1;
|
||||
bool resend_igmp_has : 1;
|
||||
bool tlb_dynamic_lb : 1;
|
||||
bool tlb_dynamic_lb_has : 1;
|
||||
bool updelay_has : 1;
|
||||
bool use_carrier : 1;
|
||||
} NMPlatformLnkBond;
|
||||
|
||||
typedef struct {
|
||||
int parent_ifindex;
|
||||
in_addr_t local;
|
||||
|
|
@ -1262,6 +1303,7 @@ typedef struct {
|
|||
gboolean egress_reset_all,
|
||||
const NMVlanQosMapping *egress_map,
|
||||
gsize n_egress_map);
|
||||
|
||||
gboolean (*link_tun_add)(NMPlatform *self,
|
||||
const char *name,
|
||||
const NMPlatformLnkTun *props,
|
||||
|
|
@ -1748,9 +1790,18 @@ nm_platform_link_bridge_change(NMPlatform *self, int ifindex, const NMPlatformLn
|
|||
}
|
||||
|
||||
static inline int
|
||||
nm_platform_link_bond_add(NMPlatform *self, const char *name, const NMPlatformLink **out_link)
|
||||
nm_platform_link_bond_change(NMPlatform *self, int ifindex, const NMPlatformLnkBond *props)
|
||||
{
|
||||
return nm_platform_link_add(self, NM_LINK_TYPE_BOND, name, 0, NULL, 0, 0, NULL, out_link);
|
||||
return nm_platform_link_change(self, NM_LINK_TYPE_BOND, ifindex, props);
|
||||
}
|
||||
|
||||
static inline int
|
||||
nm_platform_link_bond_add(NMPlatform *self,
|
||||
const char *name,
|
||||
const NMPlatformLnkBond *props,
|
||||
const NMPlatformLink **out_link)
|
||||
{
|
||||
return nm_platform_link_add(self, NM_LINK_TYPE_BOND, name, 0, NULL, 0, 0, props, out_link);
|
||||
}
|
||||
|
||||
static inline int
|
||||
|
|
@ -2084,6 +2135,8 @@ const NMPObject *nm_platform_link_get_lnk(NMPlatform *self,
|
|||
int ifindex,
|
||||
NMLinkType link_type,
|
||||
const NMPlatformLink **out_link);
|
||||
const NMPlatformLnkBond *
|
||||
nm_platform_link_get_lnk_bond(NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||
const NMPlatformLnkBridge *
|
||||
nm_platform_link_get_lnk_bridge(NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||
const NMPlatformLnkGre *
|
||||
|
|
@ -2378,6 +2431,7 @@ gboolean nm_platform_tc_sync(NMPlatform *self,
|
|||
GPtrArray *known_tfilters);
|
||||
|
||||
const char *nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len);
|
||||
const char *nm_platform_lnk_bond_to_string(const NMPlatformLnkBond *lnk, char *buf, gsize len);
|
||||
const char *nm_platform_lnk_bridge_to_string(const NMPlatformLnkBridge *lnk, char *buf, gsize len);
|
||||
const char *nm_platform_lnk_gre_to_string(const NMPlatformLnkGre *lnk, char *buf, gsize len);
|
||||
const char *
|
||||
|
|
@ -2421,6 +2475,7 @@ const char *
|
|||
nm_platform_mptcp_addr_to_string(const NMPlatformMptcpAddr *mptcp_addr, char *buf, gsize len);
|
||||
|
||||
int nm_platform_link_cmp(const NMPlatformLink *a, const NMPlatformLink *b);
|
||||
int nm_platform_lnk_bond_cmp(const NMPlatformLnkBond *a, const NMPlatformLnkBond *b);
|
||||
int nm_platform_lnk_bridge_cmp(const NMPlatformLnkBridge *a, const NMPlatformLnkBridge *b);
|
||||
int nm_platform_lnk_gre_cmp(const NMPlatformLnkGre *a, const NMPlatformLnkGre *b);
|
||||
int nm_platform_lnk_infiniband_cmp(const NMPlatformLnkInfiniband *a,
|
||||
|
|
@ -2512,6 +2567,7 @@ void nm_platform_ip6_route_hash_update(const NMPlatformIP6Route *obj,
|
|||
void nm_platform_routing_rule_hash_update(const NMPlatformRoutingRule *obj,
|
||||
NMPlatformRoutingRuleCmpType cmp_type,
|
||||
NMHashState *h);
|
||||
void nm_platform_lnk_bond_hash_update(const NMPlatformLnkBond *obj, NMHashState *h);
|
||||
void nm_platform_lnk_bridge_hash_update(const NMPlatformLnkBridge *obj, NMHashState *h);
|
||||
void nm_platform_lnk_gre_hash_update(const NMPlatformLnkGre *obj, NMHashState *h);
|
||||
void nm_platform_lnk_infiniband_hash_update(const NMPlatformLnkInfiniband *obj, NMHashState *h);
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ typedef enum _nm_packed {
|
|||
NMP_OBJECT_TYPE_LNK_VRF,
|
||||
NMP_OBJECT_TYPE_LNK_VXLAN,
|
||||
NMP_OBJECT_TYPE_LNK_WIREGUARD,
|
||||
NMP_OBJECT_TYPE_LNK_BOND,
|
||||
|
||||
NMP_OBJECT_TYPE_MPTCP_ADDR,
|
||||
|
||||
|
|
|
|||
|
|
@ -3499,6 +3499,18 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
|
|||
.cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_wireguard_hash_update,
|
||||
.cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_wireguard_cmp,
|
||||
},
|
||||
[NMP_OBJECT_TYPE_LNK_BOND - 1] =
|
||||
{
|
||||
.parent = DEDUP_MULTI_OBJ_CLASS_INIT(),
|
||||
.obj_type = NMP_OBJECT_TYPE_LNK_BOND,
|
||||
.sizeof_data = sizeof(NMPObjectLnkBond),
|
||||
.sizeof_public = sizeof(NMPlatformLnkBond),
|
||||
.obj_type_name = "bond",
|
||||
.lnk_link_type = NM_LINK_TYPE_BOND,
|
||||
.cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_bond_to_string,
|
||||
.cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_bond_hash_update,
|
||||
.cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_bond_cmp,
|
||||
},
|
||||
[NMP_OBJECT_TYPE_MPTCP_ADDR - 1] =
|
||||
{
|
||||
.parent = DEDUP_MULTI_OBJ_CLASS_INIT(),
|
||||
|
|
|
|||
|
|
@ -244,6 +244,10 @@ typedef struct {
|
|||
NMPlatformLnkBridge _public;
|
||||
} NMPObjectLnkBridge;
|
||||
|
||||
typedef struct {
|
||||
NMPlatformLnkBond _public;
|
||||
} NMPObjectLnkBond;
|
||||
|
||||
typedef struct {
|
||||
NMPlatformLnkGre _public;
|
||||
} NMPObjectLnkGre;
|
||||
|
|
@ -351,6 +355,9 @@ struct _NMPObject {
|
|||
NMPlatformLnkBridge lnk_bridge;
|
||||
NMPObjectLnkBridge _lnk_bridge;
|
||||
|
||||
NMPlatformLnkBond lnk_bond;
|
||||
NMPObjectLnkBond _lnk_bond;
|
||||
|
||||
NMPlatformLnkGre lnk_gre;
|
||||
NMPObjectLnkGre _lnk_gre;
|
||||
|
||||
|
|
@ -495,6 +502,7 @@ _NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX(NMPObjectType obj_type)
|
|||
case NMP_OBJECT_TYPE_TFILTER:
|
||||
|
||||
case NMP_OBJECT_TYPE_LNK_BRIDGE:
|
||||
case NMP_OBJECT_TYPE_LNK_BOND:
|
||||
case NMP_OBJECT_TYPE_LNK_GRE:
|
||||
case NMP_OBJECT_TYPE_LNK_GRETAP:
|
||||
case NMP_OBJECT_TYPE_LNK_INFINIBAND:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue