core: add checks on connection default properties

Add a new CON_DEFAULT() macro that places a property name into a
special section used at runtime to check whether it is a supported
connection default.

Unfortunately, this mechanism doesn't work for plugins so we have to
enumerate the connection defaults from plugins in the daemon using
another CON_DEFAULT_NOP() macro.
This commit is contained in:
Beniamino Galvani 2018-11-14 14:52:21 +01:00
parent 2e45d4ada6
commit 446e5b27d6
13 changed files with 185 additions and 55 deletions

View file

@ -672,6 +672,8 @@ ipv6.ip6-privacy=0
(see <link linkend='nm-settings'><citerefentry><refentrytitle>nm-settings</refentrytitle><manvolnum>5</manvolnum></citerefentry></link> for details).
A default value is only consulted if the corresponding per-connection value
explicitly allows for that.
<!-- The following comment is used by check-config-options.sh, don't remove it. -->
<!-- start connection defaults -->
<variablelist>
<varlistentry>
<term><varname>802-1x.auth-timeout</varname></term>
@ -824,6 +826,8 @@ ipv6.ip6-privacy=0
<term><varname>wifi.wake-on-wlan</varname></term>
</varlistentry>
</variablelist>
<!-- The following comment is used by check-config-options.sh, don't remove it. -->
<!-- end connection defaults -->
</para>
</refsect2>

View file

@ -34,10 +34,12 @@
#define _nm_packed __attribute__ ((packed))
#define _nm_unused __attribute__ ((unused))
#define _nm_used __attribute__ ((used))
#define _nm_pure __attribute__ ((pure))
#define _nm_const __attribute__ ((const))
#define _nm_printf(a,b) __attribute__ ((__format__ (__printf__, a, b)))
#define _nm_align(s) __attribute__ ((aligned (s)))
#define _nm_section(s) __attribute__ ((section (s)))
#define _nm_alignof(type) __alignof (type)
#define _nm_alignas(type) _nm_align (_nm_alignof (type))
#define nm_auto(fcn) __attribute__ ((cleanup(fcn)))

View file

@ -1216,7 +1216,7 @@ wake_on_lan_enable (NMDevice *device)
}
wol = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
"ethernet.wake-on-lan",
NM_CON_DEFAULT ("ethernet.wake-on-lan"),
device,
NM_SETTING_WIRED_WAKE_ON_LAN_NONE,
G_MAXINT32,

View file

@ -1120,8 +1120,8 @@ init_ip_config_dns_priority (NMDevice *self, NMIPConfig *config)
int priority;
property = (nm_ip_config_get_addr_family (config) == AF_INET)
? "ipv4.dns-priority"
: "ipv6.dns-priority";
? NM_CON_DEFAULT ("ipv4.dns-priority")
: NM_CON_DEFAULT ("ipv6.dns-priority");
priority = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
property,
@ -1279,7 +1279,7 @@ _get_stable_id (NMDevice *self,
if (!stable_id) {
default_id = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
"connection.stable-id",
NM_CON_DEFAULT ("connection.stable-id"),
self);
stable_id = default_id;
}
@ -2165,7 +2165,9 @@ nm_device_get_route_metric (NMDevice *self,
/* use the current NMConfigData, which makes this configuration reloadable.
* Note that that means that the route-metric might change between SIGHUP.
* You must cache the returned value if that is a problem. */
property = addr_family == AF_INET ? "ipv4.route-metric" : "ipv6.route-metric";
property = addr_family == AF_INET
? NM_CON_DEFAULT ("ipv4.route-metric")
: NM_CON_DEFAULT ("ipv6.route-metric");
route_metric = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
property,
self,
@ -2195,7 +2197,7 @@ _get_mdns (NMDevice *self)
return mdns;
return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
"connection.mdns",
NM_CON_DEFAULT ("connection.mdns"),
self,
NM_SETTING_CONNECTION_MDNS_NO,
NM_SETTING_CONNECTION_MDNS_YES,
@ -2217,7 +2219,7 @@ _get_llmnr (NMDevice *self)
return llmnr;
return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
"connection.llmnr",
NM_CON_DEFAULT ("connection.llmnr"),
self,
NM_SETTING_CONNECTION_LLMNR_NO,
NM_SETTING_CONNECTION_LLMNR_YES,
@ -2266,7 +2268,9 @@ nm_device_get_route_table (NMDevice *self,
if (route_table == 0) {
const char *property;
property = addr_family == AF_INET ? "ipv4.route-table" : "ipv6.route-table";
property = addr_family == AF_INET
? NM_CON_DEFAULT ("ipv4.route-table")
: NM_CON_DEFAULT ("ipv6.route-table");
route_table = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
property,
self,
@ -6150,7 +6154,7 @@ lldp_rx_enabled (NMDevice *self)
lldp = nm_setting_connection_get_lldp (s_con);
if (lldp == NM_SETTING_CONNECTION_LLDP_DEFAULT) {
lldp = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
"connection.lldp",
NM_CON_DEFAULT ("connection.lldp"),
self,
NM_SETTING_CONNECTION_LLDP_DEFAULT,
NM_SETTING_CONNECTION_LLDP_ENABLE_RX,
@ -6254,7 +6258,7 @@ act_stage1_prepare (NMDevice *self, NMDeviceStateReason *out_failure_reason)
autoprobe = nm_setting_sriov_get_autoprobe_drivers (s_sriov);
if (autoprobe == NM_TERNARY_DEFAULT) {
autoprobe = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
"sriov.autoprobe-drivers",
NM_CON_DEFAULT ("sriov.autoprobe-drivers"),
self,
NM_TERNARY_FALSE,
NM_TERNARY_TRUE,
@ -6624,7 +6628,7 @@ get_ipv4_dad_timeout (NMDevice *self)
return timeout;
return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
"ipv4.dad-timeout",
NM_CON_DEFAULT ("ipv4.dad-timeout"),
self,
0,
NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX,
@ -7489,8 +7493,8 @@ get_dhcp_timeout (NMDevice *self, int addr_family)
timeout = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
addr_family == AF_INET
? "ipv4.dhcp-timeout"
: "ipv6.dhcp-timeout",
? NM_CON_DEFAULT ("ipv4.dhcp-timeout")
: NM_CON_DEFAULT ("ipv6.dhcp-timeout"),
self,
0, G_MAXINT32, 0);
if (timeout)
@ -7536,7 +7540,8 @@ dhcp4_get_client_id (NMDevice *self,
if (!client_id) {
client_id_default = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
"ipv4.dhcp-client-id", self);
NM_CON_DEFAULT ("ipv4.dhcp-client-id"),
self);
if (client_id_default && client_id_default[0]) {
/* a non-empty client-id is always valid, see nm_dhcp_utils_client_id_string_to_bytes(). */
client_id = client_id_default;
@ -8352,7 +8357,8 @@ dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, gboole
if (!duid) {
duid_default = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
"ipv6.dhcp-duid", self);
NM_CON_DEFAULT ("ipv6.dhcp-duid"),
self);
duid = duid_default;
if (!duid)
duid = "lease";
@ -8913,19 +8919,19 @@ nm_device_get_configured_mtu_from_connection (NMDevice *self,
if (setting_type == NM_TYPE_SETTING_WIRED) {
if (setting)
mtu = nm_setting_wired_get_mtu (NM_SETTING_WIRED (setting));
global_property_name = "ethernet.mtu";
global_property_name = NM_CON_DEFAULT ("ethernet.mtu");
} else if (setting_type == NM_TYPE_SETTING_WIRELESS) {
if (setting)
mtu = nm_setting_wireless_get_mtu (NM_SETTING_WIRELESS (setting));
global_property_name = "wifi.mtu";
global_property_name = NM_CON_DEFAULT ("wifi.mtu");
} else if (setting_type == NM_TYPE_SETTING_INFINIBAND) {
if (setting)
mtu = nm_setting_infiniband_get_mtu (NM_SETTING_INFINIBAND (setting));
global_property_name = "infiniband.mtu";
global_property_name = NM_CON_DEFAULT ("infiniband.mtu");
} else if (setting_type == NM_TYPE_SETTING_IP_TUNNEL) {
if (setting)
mtu = nm_setting_ip_tunnel_get_mtu (NM_SETTING_IP_TUNNEL (setting));
global_property_name = "ip-tunnel.mtu";
global_property_name = NM_CON_DEFAULT ("ip-tunnel.mtu");
} else
g_return_val_if_reached (0);
@ -9606,7 +9612,7 @@ _ip6_privacy_get (NMDevice *self)
/* 2.) use the default value from the configuration. */
ip6_privacy = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
"ipv6.ip6-privacy",
NM_CON_DEFAULT ("ipv6.ip6-privacy"),
self,
NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR,
@ -15296,7 +15302,9 @@ _get_cloned_mac_address_setting (NMDevice *self, NMConnection *connection, gbool
gs_free char *a = NULL;
a = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
is_wifi ? "wifi.cloned-mac-address" : "ethernet.cloned-mac-address",
is_wifi
? NM_CON_DEFAULT ("wifi.cloned-mac-address")
: NM_CON_DEFAULT ("ethernet.cloned-mac-address"),
self);
addr = NM_CLONED_MAC_PRESERVE;
@ -15307,7 +15315,7 @@ _get_cloned_mac_address_setting (NMDevice *self, NMConnection *connection, gbool
/* for backward compatibility, read the deprecated wifi.mac-address-randomization setting. */
a = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
"wifi." NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION,
NM_CON_DEFAULT ("wifi.mac-address-randomization"),
self);
v = _nm_utils_ascii_str_to_int64 (a, 10,
NM_SETTING_MAC_RANDOMIZATION_DEFAULT,
@ -15344,7 +15352,9 @@ _get_generate_mac_address_mask_setting (NMDevice *self, NMConnection *connection
}
a = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
is_wifi ? "wifi.generate-mac-address-mask" : "ethernet.generate-mac-address-mask",
is_wifi
? NM_CON_DEFAULT ("wifi.generate-mac-address-mask")
: NM_CON_DEFAULT ("ethernet.generate-mac-address-mask"),
self);
if (!a)
return NULL;
@ -15862,7 +15872,7 @@ nm_device_get_supplicant_timeout (NMDevice *self)
}
return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
"802-1x.auth-timeout",
NM_CON_DEFAULT ("802-1x.auth-timeout"),
self,
1,
G_MAXINT32,
@ -15890,7 +15900,7 @@ nm_device_auth_retries_try_next (NMDevice *self)
if (auth_retries == -1) {
auth_retries = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
"connection.auth-retries",
NM_CON_DEFAULT ("connection.auth-retries"),
self,
-1, G_MAXINT32, -1);
}
@ -16947,3 +16957,11 @@ nm_device_class_init (NMDeviceClass *klass)
0, NULL, NULL, NULL,
G_TYPE_NONE, 0);
}
/* Connection defaults from plugins */
NM_CON_DEFAULT_NOP ("cdma.mtu");
NM_CON_DEFAULT_NOP ("gsm.mtu");
NM_CON_DEFAULT_NOP ("wifi.powersave");
NM_CON_DEFAULT_NOP ("wifi.wake-on-wlan");
NM_CON_DEFAULT_NOP ("wifi-sec.pmf");
NM_CON_DEFAULT_NOP ("wifi-sec.fils");

View file

@ -1386,6 +1386,19 @@ nm_config_data_get_connection_default (const NMConfigData *self,
priv = NM_CONFIG_DATA_GET_PRIVATE (self);
#if NM_MORE_ASSERTS > 10
{
const char **ptr;
for (ptr = __start_connection_defaults; ptr < __stop_connection_defaults; ptr++) {
if (nm_streq (property, *ptr))
break;
}
nm_assert (ptr < __stop_connection_defaults);
}
#endif
_match_section_infos_lookup (&priv->connection_infos[0],
priv->keyfile,
property,

View file

@ -178,6 +178,21 @@ int nm_config_data_get_sriov_num_vfs (const NMConfigData *self, NMDevice *d
NMGlobalDnsConfig *nm_config_data_get_global_dns_config (const NMConfigData *self);
extern const char *__start_connection_defaults[];
extern const char *__stop_connection_defaults[];
#define NM_CON_DEFAULT_NOP(name) \
static const char *NM_UNIQ_T (connection_default, NM_UNIQ) \
_nm_used _nm_section ("connection_defaults") = "" name
#define NM_CON_DEFAULT(name) \
({ \
static const char *__con_default_prop \
_nm_used _nm_section ("connection_defaults") = "" name; \
\
name; \
})
char *nm_config_data_get_connection_default (const NMConfigData *self,
const char *property,
NMDevice *device);

View file

@ -848,6 +848,24 @@ check_config_key (const char *group, const char *key)
{
const ConfigGroup *g;
const char *const *k;
const char **ptr;
#if NM_MORE_ASSERTS > 10
{
static gboolean checked = FALSE;
const char **ptr1, **ptr2;
/* check for duplicate elements in the static list */
if (!checked) {
for (ptr1 = __start_connection_defaults; ptr1 < __stop_connection_defaults; ptr1++) {
for (ptr2 = ptr1 + 1; ptr2 < __stop_connection_defaults; ptr2++)
nm_assert (!nm_streq (*ptr1, *ptr2));
}
checked = TRUE;
}
}
#endif
for (g = config_groups; g->group; g++) {
if ( (!g->is_prefix && nm_streq (group, g->group))
@ -864,8 +882,11 @@ check_config_key (const char *group, const char *key)
}
if (g->is_connection) {
/* For now just accept everything */
return TRUE;
for (ptr = __start_connection_defaults; ptr < __stop_connection_defaults; ptr++) {
if (nm_streq (key, *ptr))
return TRUE;
}
return FALSE;
}
return FALSE;

View file

@ -4110,7 +4110,7 @@ should_connect_slaves (NMConnection *connection, NMDevice *device)
goto out;
val = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
"connection.autoconnect-slaves",
NM_CON_DEFAULT ("connection.autoconnect-slaves"),
device,
0, 1, -1);

View file

@ -13,3 +13,14 @@ uri=http://example.com
interval=100
response=Hello
audit=true
[connection]
ipv4.route-metric=50
ipv4.addresses=1.2.3.4
ipv4.dad-timeout=100
[connection-wifi]
match-device=type:wifi
wifi.powersave=2
ipv6.ip6-privacy=1
wifi.tx-power=99

View file

@ -19,8 +19,8 @@ extra-key=some value
[connection]
ipv4.route-metric=50
ipv6.ip6_privacy=0
dummy.test1=no
dummy.test2=no
ethernet.mtu=1400
ipv4.dns-priority=60
ord.key00=A-0.0.00
ord.key01=A-0.0.01
@ -37,7 +37,7 @@ ord.key09=A-0.0.09
match-device=mac:00:00:00:00:00:51
stop-match=yes
ipv4.route-metric=51
dummy.test1=yes
ethernet.mtu=9000
[connection.dev52]
match-device=mac:00:00:00:00:00:52

View file

@ -206,20 +206,20 @@ test_config_simple (void)
g_assert_cmpstr (value, ==, "52");
g_free (value);
value = nm_config_data_get_connection_default (nm_config_get_data_orig (config), "dummy.test1", dev51);
g_assert_cmpstr (value, ==, "yes");
value = nm_config_data_get_connection_default (nm_config_get_data_orig (config), "ethernet.mtu", dev51);
g_assert_cmpstr (value, ==, "9000");
g_free (value);
value = nm_config_data_get_connection_default (nm_config_get_data_orig (config), "dummy.test1", dev50);
g_assert_cmpstr (value, ==, "no");
value = nm_config_data_get_connection_default (nm_config_get_data_orig (config), "ethernet.mtu", dev50);
g_assert_cmpstr (value, ==, "1400");
g_free (value);
value = nm_config_data_get_connection_default (nm_config_get_data_orig (config), "dummy.test2", dev51);
value = nm_config_data_get_connection_default (nm_config_get_data_orig (config), "ipv4.dns-priority", dev51);
g_assert_cmpstr (value, ==, NULL);
g_free (value);
value = nm_config_data_get_connection_default (nm_config_get_data_orig (config), "dummy.test2", dev50);
g_assert_cmpstr (value, ==, "no");
value = nm_config_data_get_connection_default (nm_config_get_data_orig (config), "ipv4.dns-priority", dev50);
g_assert_cmpstr (value, ==, "60");
g_free (value);
}
@ -506,17 +506,17 @@ test_config_confdir (void)
gs_free char *_value = nm_config_data_get_connection_default (nm_config_get_data_orig (xconfig), (xname), NULL); \
g_assert_cmpstr (_value, ==, (xvalue)); \
} G_STMT_END
ASSERT_GET_CONN_DEFAULT (config, "ord.key00", "A-0.0.00");
ASSERT_GET_CONN_DEFAULT (config, "ord.key01", "A-0.3.01");
ASSERT_GET_CONN_DEFAULT (config, "ord.key02", "A-0.2.02");
ASSERT_GET_CONN_DEFAULT (config, "ord.key03", "A-0.1.03");
ASSERT_GET_CONN_DEFAULT (config, "ord.key04", "B-1.3.04");
ASSERT_GET_CONN_DEFAULT (config, "ord.key05", "B-1.2.05");
ASSERT_GET_CONN_DEFAULT (config, "ord.key06", "B-1.1.06");
ASSERT_GET_CONN_DEFAULT (config, "ord.key07", "C-2.3.07");
ASSERT_GET_CONN_DEFAULT (config, "ord.key08", "C-2.2.08");
ASSERT_GET_CONN_DEFAULT (config, "ord.key09", "C-2.1.09");
ASSERT_GET_CONN_DEFAULT (config, "ord.ovw01", "C-0.1.ovw01");
ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key00"), "A-0.0.00");
ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key01"), "A-0.3.01");
ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key02"), "A-0.2.02");
ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key03"), "A-0.1.03");
ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key04"), "B-1.3.04");
ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key05"), "B-1.2.05");
ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key06"), "B-1.1.06");
ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key07"), "C-2.3.07");
ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key08"), "C-2.2.08");
ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key09"), "C-2.1.09");
ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.ovw01"), "C-0.1.ovw01");
value = nm_config_data_get_value (nm_config_get_data_orig (config), NM_CONFIG_KEYFILE_GROUPPREFIX_TEST_APPEND_STRINGLIST".1", "val1", NM_CONFIG_GET_VALUE_NONE);
g_assert_cmpstr (value, ==, "a,c");
@ -572,10 +572,12 @@ test_config_warnings (void)
}
g_assert (warnings);
g_assert_cmpint (g_strv_length ((char **) warnings), ==, 3);
g_assert_cmpint (g_strv_length ((char **) warnings), ==, 5);
check_warning (warnings[0], "main", "plugin");
check_warning (warnings[1], "main", "rc-managed");
check_warning (warnings[2], "connectivity", "audit");
check_warning (warnings[3], "connection-wifi", "wifi.tx-power");
check_warning (warnings[4], "connection", "ipv4.addresses");
#undef check_warning
}

View file

@ -1878,7 +1878,7 @@ connect_success (NMVpnConnection *self)
timeout = nm_setting_vpn_get_timeout (s_vpn);
if (timeout == 0) {
timeout = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
"vpn.timeout",
NM_CON_DEFAULT ("vpn.timeout"),
NULL,
1, G_MAXUINT32, 60);
}

View file

@ -1,6 +1,7 @@
#!/bin/bash
srcdir=${1:-.}
ret=0
get_supported_options()
{
@ -8,21 +9,64 @@ get_supported_options()
grep -o 'NM_CONFIG_KEYFILE_KEY_\w*'
}
get_missing()
get_missing_options()
{
grep -v '/\* check-config-options skip \*/' "$srcdir/src/nm-config.h" |
grep -o 'NM_CONFIG_KEYFILE_KEY_\w*' |
grep -v -Fx -f <(get_supported_options)
}
missing=$(get_missing)
get_src_con_defaults()
{
sed -ne 's/.*\<NM_CON_DEFAULT\s*("\([^"]*\)").*/\1/p' $(find "$srcdir/src/" -name \*.c ! -name test\*.c)
sed -ne 's/.*\<NM_CON_DEFAULT_NOP\s*("\([^"]*\)").*/\1/p' $(find "$srcdir/src/" -name \*.c ! -name test\*.c)
}
get_man_con_defaults()
{
awk '/start connection defaults/{flag=1;next}/end connection defaults/{flag=0}flag' "$srcdir/man/NetworkManager.conf.xml" |
sed -ne 's#.*<varname>\([^<]*\)</varname>.*#\1#p'
}
get_missing_con_defaults()
{
get_src_con_defaults | grep -v -Fx -f <(get_man_con_defaults)
}
get_missing_con_defaults2()
{
get_man_con_defaults | grep -v -Fx -f <(get_src_con_defaults)
}
missing=$(get_missing_options)
if [ -n "$missing" ]; then
echo "***"
echo "*** Error: the following configuration options are defined but not present in the list of supported options"
echo "***"
echo "$missing"
exit 1
echo
ret=1
fi
exit 0
missing_con_defaults=$(get_missing_con_defaults)
if [ -n "$missing_con_defaults" ]; then
echo "***"
echo "*** Error: the following connection defaults are present in source files but not in the NetworkManager.conf man page:"
echo "***"
echo "$missing_con_defaults"
echo
ret=1
fi
missing_con_defaults2=$(get_missing_con_defaults2)
if [ -n "$missing_con_defaults2" ]; then
echo "***"
echo "*** Error: the following connection defaults are present in the NetworkManager.conf man page but not in source files:"
echo "***"
echo "$missing_con_defaults2"
echo
ret=1
fi
exit $ret