diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c index 721acf027b..3e083de461 100644 --- a/src/core/devices/nm-device-bond.c +++ b/src/core/devices/nm-device-bond.c @@ -395,61 +395,57 @@ _platform_lnk_bond_init_from_setting(NMSettingBond *s_bond, NMPlatformLnkBond *p { const char *opt_value; +#define _v_fcn(fcn, s_bond, opt) (fcn(nm_setting_bond_get_option_normalized((s_bond), (opt)))) +#define _v_u8(s_bond, opt) _nm_setting_bond_opt_value_as_u8((s_bond), (opt)) +#define _v_u16(s_bond, opt) _nm_setting_bond_opt_value_as_u16((s_bond), (opt)) +#define _v_u32(s_bond, opt) _nm_setting_bond_opt_value_as_u32((s_bond), (opt)) +#define _v_intbool(s_bond, opt) _nm_setting_bond_opt_value_as_intbool((s_bond), (opt)) + *props = (NMPlatformLnkBond){ - .mode = _nm_setting_bond_mode_from_string( - nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_MODE)), + .mode = _v_fcn(_nm_setting_bond_mode_from_string, 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)), + .miimon = _v_u32(s_bond, NM_SETTING_BOND_OPTION_MIIMON), + .updelay = _v_u32(s_bond, NM_SETTING_BOND_OPTION_UPDELAY), + .downdelay = _v_u32(s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY), + .arp_interval = _v_u32(s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL), + .resend_igmp = _v_u32(s_bond, NM_SETTING_BOND_OPTION_RESEND_IGMP), + .min_links = _v_u32(s_bond, NM_SETTING_BOND_OPTION_MIN_LINKS), + .lp_interval = _v_u32(s_bond, NM_SETTING_BOND_OPTION_LP_INTERVAL), + .packets_per_port = _v_u32(s_bond, NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE), + .peer_notif_delay = _v_u32(s_bond, NM_SETTING_BOND_OPTION_PEER_NOTIF_DELAY), + .arp_all_targets = _v_fcn(_nm_setting_bond_arp_all_targets_from_string, + s_bond, + NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS), + .arp_validate = _v_fcn(_nm_setting_bond_arp_validate_from_string, + s_bond, + NM_SETTING_BOND_OPTION_ARP_VALIDATE), + .ad_actor_sys_prio = _v_u16(s_bond, NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO), + .ad_user_port_key = _v_u16(s_bond, NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY), + .primary_reselect = _v_fcn(_nm_setting_bond_primary_reselect_from_string, + s_bond, + NM_SETTING_BOND_OPTION_PRIMARY_RESELECT), + .fail_over_mac = _v_fcn(_nm_setting_bond_fail_over_mac_from_string, + s_bond, + NM_SETTING_BOND_OPTION_FAIL_OVER_MAC), + .xmit_hash_policy = _v_fcn(_nm_setting_bond_xmit_hash_policy_from_string, + s_bond, + NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY), + .num_grat_arp = _v_u8(s_bond, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP), + .all_ports_active = _v_u8(s_bond, NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE), + .lacp_rate = _v_fcn(_nm_setting_bond_lacp_rate_from_string, + s_bond, + NM_SETTING_BOND_OPTION_LACP_RATE), + .ad_select = _v_fcn(_nm_setting_bond_ad_select_from_string, + s_bond, + NM_SETTING_BOND_OPTION_AD_SELECT), + .use_carrier = _v_intbool(s_bond, NM_SETTING_BOND_OPTION_USE_CARRIER), + .tlb_dynamic_lb = _v_intbool(s_bond, NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB), }; 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 = diff --git a/src/libnm-core-impl/nm-setting-bond.c b/src/libnm-core-impl/nm-setting-bond.c index cdfc764187..18b6fefbc0 100644 --- a/src/libnm-core-impl/nm-setting-bond.c +++ b/src/libnm-core-impl/nm-setting-bond.c @@ -764,37 +764,64 @@ _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) +#define _opt_value_as_u64(s_bond, opt, v_max) \ + ({ \ + const OptionMeta *_meta; \ + NMSettingBond *_s_bond = (s_bond); \ + const char *_opt = (opt); \ + const guint64 _v_max = (v_max); \ + const char *_s; \ + guint64 _val; \ + \ + nm_assert(NM_IS_SETTING_BOND(_s_bond)); \ + nm_assert(_opt); \ + \ + _meta = _get_option_meta(_opt); \ + \ + nm_assert(_meta); \ + nm_assert(_meta->opt_type == NM_BOND_OPTION_TYPE_INT); \ + nm_assert(_meta->min < _meta->max); \ + nm_assert(_meta->max <= _v_max); \ + nm_assert(_meta->val); \ + \ + _s = nm_setting_bond_get_option_normalized(_s_bond, _opt); \ + if (_s) { \ + _val = _nm_utils_ascii_str_to_uint64(_s, 10, _meta->min, _meta->max, 0); \ + /* Note that _s is only a valid integer, if the profile verifies. We require + * that the caller only calls these functions on valid profile. */ \ + nm_assert(errno == 0); \ + } else { \ + _val = 0; \ + errno = EINVAL; \ + } \ + \ + _val; \ + }) + +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_MAXUINT32, - 0); + return _opt_value_as_u64(s_bond, opt, G_MAXUINT8); } 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); + return _opt_value_as_u64(s_bond, opt, G_MAXUINT16); } -guint8 -_nm_setting_bond_opt_value_as_u8(NMSettingBond *s_bond, const char *opt) +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_MAXUINT8, - 0); + return _opt_value_as_u64(s_bond, opt, G_MAXUINT32); +} + +bool +_nm_setting_bond_opt_value_as_intbool(NMSettingBond *s_bond, const char *opt) +{ + /* This does not parse the value as a boolean string, instead, it requires + * that it's a number, either "0" or "1". */ + return _opt_value_as_u64(s_bond, opt, 1); } /*****************************************************************************/ diff --git a/src/libnm-core-impl/tests/test-setting.c b/src/libnm-core-impl/tests/test-setting.c index 5bdae71660..a4e3932adf 100644 --- a/src/libnm-core-impl/tests/test-setting.c +++ b/src/libnm-core-impl/tests/test-setting.c @@ -5068,6 +5068,65 @@ test_6lowpan_1(void) /*****************************************************************************/ +static void +test_bond_meta(void) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingBond *set; + char sbuf[200]; + + create_bond_connection(&con, &set); + + g_assert_cmpstr(nm_setting_bond_get_option_normalized(set, NM_SETTING_BOND_OPTION_MODE), + ==, + "balance-rr"); + +#define _A(_nm_setting_bond_opt_value_as_xxx, set, opt, value, errsv) \ + G_STMT_START \ + { \ + g_assert_cmpint(_nm_setting_bond_opt_value_as_xxx((set), (opt)), ==, (value)); \ + g_assert_cmpint(errno, ==, (errsv)); \ + } \ + G_STMT_END + + _A(_nm_setting_bond_opt_value_as_u32, set, NM_SETTING_BOND_OPTION_MIIMON, 100, 0); + _A(_nm_setting_bond_opt_value_as_u32, set, NM_SETTING_BOND_OPTION_UPDELAY, 0, 0); + _A(_nm_setting_bond_opt_value_as_u32, set, NM_SETTING_BOND_OPTION_DOWNDELAY, 0, 0); + _A(_nm_setting_bond_opt_value_as_u32, set, NM_SETTING_BOND_OPTION_ARP_INTERVAL, 0, 0); + _A(_nm_setting_bond_opt_value_as_u32, set, NM_SETTING_BOND_OPTION_RESEND_IGMP, 1, 0); + _A(_nm_setting_bond_opt_value_as_u32, set, NM_SETTING_BOND_OPTION_MIN_LINKS, 0, 0); + _A(_nm_setting_bond_opt_value_as_u32, set, NM_SETTING_BOND_OPTION_LP_INTERVAL, 1, 0); + _A(_nm_setting_bond_opt_value_as_u32, set, NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE, 1, 0); + _A(_nm_setting_bond_opt_value_as_u32, set, NM_SETTING_BOND_OPTION_PEER_NOTIF_DELAY, 0, 0); + _A(_nm_setting_bond_opt_value_as_u16, set, NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO, 0, EINVAL); + _A(_nm_setting_bond_opt_value_as_u16, set, NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY, 0, EINVAL); + _A(_nm_setting_bond_opt_value_as_u8, set, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP, 1, 0); + _A(_nm_setting_bond_opt_value_as_u8, set, NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE, 0, 0); + _A(_nm_setting_bond_opt_value_as_intbool, set, NM_SETTING_BOND_OPTION_USE_CARRIER, 1, 0); + _A(_nm_setting_bond_opt_value_as_intbool, + set, + NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB, + 0, + EINVAL); + + nm_setting_bond_add_option(set, NM_SETTING_BOND_OPTION_ARP_INTERVAL, "5"); + _A(_nm_setting_bond_opt_value_as_u32, set, NM_SETTING_BOND_OPTION_ARP_INTERVAL, 5, 0); + + nm_setting_bond_add_option(set, + NM_SETTING_BOND_OPTION_ARP_INTERVAL, + nm_sprintf_buf(sbuf, "%d", G_MAXINT)); + _A(_nm_setting_bond_opt_value_as_u32, set, NM_SETTING_BOND_OPTION_ARP_INTERVAL, G_MAXINT, 0); + + nm_setting_bond_add_option(set, NM_SETTING_BOND_OPTION_MODE, "802.3ad"); + _A(_nm_setting_bond_opt_value_as_u16, set, NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO, 65535, 0); + _A(_nm_setting_bond_opt_value_as_u16, set, NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY, 0, 0); + + nm_setting_bond_add_option(set, NM_SETTING_BOND_OPTION_MODE, "balance-tlb"); + _A(_nm_setting_bond_opt_value_as_intbool, set, NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB, 1, 0); +} + +/*****************************************************************************/ + NMTST_DEFINE(); int @@ -5185,5 +5244,7 @@ main(int argc, char **argv) g_test_add_func("/libnm/test_setting_metadata", test_setting_metadata); + g_test_add_func("/libnm/test_bond_meta", test_bond_meta); + return g_test_run(); } diff --git a/src/libnm-core-intern/nm-core-internal.h b/src/libnm-core-intern/nm-core-internal.h index ee4cc25b42..4e1bab4723 100644 --- a/src/libnm-core-intern/nm-core-internal.h +++ b/src/libnm-core-intern/nm-core-internal.h @@ -517,9 +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); +guint16 _nm_setting_bond_opt_value_as_u16(NMSettingBond *s_bond, const char *opt); +guint32 _nm_setting_bond_opt_value_as_u32(NMSettingBond *s_bond, const char *opt); +bool _nm_setting_bond_opt_value_as_intbool(NMSettingBond *s_bond, const char *opt); /*****************************************************************************/