summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rw-r--r--clients/cli/devices.c102
-rw-r--r--clients/cli/settings.c139
-rw-r--r--clients/common/nm-vpn-helpers.c5
-rw-r--r--clients/tui/nmtui-connect.c8
-rw-r--r--clients/tui/nmtui-connect.h2
-rw-r--r--clients/tui/nmtui-edit.c8
-rw-r--r--clients/tui/nmtui-edit.h2
-rw-r--r--clients/tui/nmtui-hostname.c2
-rw-r--r--clients/tui/nmtui-hostname.h2
-rw-r--r--clients/tui/nmtui.c47
-rw-r--r--configure.ac43
-rw-r--r--contrib/fedora/REQUIRED_PACKAGES6
-rw-r--r--contrib/fedora/rpm/NetworkManager.spec32
-rwxr-xr-xcontrib/fedora/rpm/build.sh3
-rw-r--r--introspection/nm-device-team.xml7
-rw-r--r--introspection/nm-ip4-config.xml7
-rw-r--r--introspection/nm-ip6-config.xml7
-rw-r--r--libnm-core/Makefile.am7
-rw-r--r--libnm-core/nm-connection.c34
-rw-r--r--libnm-core/nm-core-internal.h4
-rw-r--r--libnm-core/nm-keyfile-writer.c28
-rw-r--r--libnm-core/nm-setting-ip-config.c62
-rw-r--r--libnm-core/nm-setting-ip-config.h4
-rw-r--r--libnm-core/nm-setting-ip4-config.c11
-rw-r--r--libnm-core/nm-setting-ip6-config.c115
-rw-r--r--libnm-core/nm-setting-ip6-config.h4
-rw-r--r--libnm-core/nm-setting-team-port.c46
-rw-r--r--libnm-core/nm-setting-team.c52
-rw-r--r--libnm-core/nm-utils-private.h3
-rw-r--r--libnm-core/nm-utils.c175
-rw-r--r--libnm-core/nm-version.h14
-rw-r--r--libnm-core/nm-vpn-editor-plugin.c40
-rw-r--r--libnm-core/nm-vpn-editor-plugin.h5
-rw-r--r--libnm-core/nm-vpn-plugin-info.c175
-rw-r--r--libnm-core/nm-vpn-plugin-info.h10
-rw-r--r--libnm-core/tests/test-general.c160
-rw-r--r--libnm-glib/nm-vpn-plugin.c2
-rw-r--r--libnm-util/nm-setting.c2
-rw-r--r--libnm-util/nm-version.h14
-rw-r--r--libnm/libnm.ver12
-rw-r--r--libnm/nm-device-team.c40
-rw-r--r--libnm/nm-device-team.h3
-rw-r--r--libnm/nm-vpn-editor.h2
-rw-r--r--m4/compiler_options.m4 (renamed from m4/compiler_warnings.m4)45
-rw-r--r--man/NetworkManager.conf.xml30
-rw-r--r--man/NetworkManager.xml2
-rw-r--r--man/common.ent.in1
-rw-r--r--po/pt_BR.po264
-rw-r--r--po/sv.po1645
-rw-r--r--shared/nm-macros-internal.h19
-rw-r--r--shared/nm-test-utils.h286
-rw-r--r--shared/nm-version-macros.h.in1
-rw-r--r--src/Makefile.am9
-rw-r--r--src/NetworkManager.ver3
-rw-r--r--src/devices/bluetooth/nm-bluez-device.c49
-rw-r--r--src/devices/bluetooth/nm-bluez-device.h3
-rw-r--r--src/devices/bluetooth/nm-bluez-manager.c17
-rw-r--r--src/devices/bluetooth/nm-bluez-manager.h4
-rw-r--r--src/devices/bluetooth/nm-bluez4-adapter.c16
-rw-r--r--src/devices/bluetooth/nm-bluez4-adapter.h5
-rw-r--r--src/devices/bluetooth/nm-bluez4-manager.c18
-rw-r--r--src/devices/bluetooth/nm-bluez4-manager.h4
-rw-r--r--src/devices/bluetooth/nm-bluez5-manager.c20
-rw-r--r--src/devices/bluetooth/nm-bluez5-manager.h7
-rw-r--r--src/devices/bluetooth/nm-device-bt.c19
-rw-r--r--src/devices/nm-device-ethernet-utils.c28
-rw-r--r--src/devices/nm-device-ethernet-utils.h4
-rw-r--r--src/devices/nm-device-ethernet.c14
-rw-r--r--src/devices/nm-device-ip-tunnel.c9
-rw-r--r--src/devices/nm-device-macvlan.c7
-rw-r--r--src/devices/nm-device-private.h6
-rw-r--r--src/devices/nm-device-vlan.c7
-rw-r--r--src/devices/nm-device-vxlan.c9
-rw-r--r--src/devices/nm-device.c967
-rw-r--r--src/devices/nm-device.h3
-rw-r--r--src/devices/team/nm-device-team.c84
-rw-r--r--src/devices/team/nm-device-team.h3
-rw-r--r--src/devices/tests/test-lldp.c2
-rw-r--r--src/devices/wifi/nm-device-wifi.c33
-rw-r--r--src/devices/wifi/nm-wifi-ap.c196
-rw-r--r--src/devices/wifi/nm-wifi-ap.h10
-rw-r--r--src/devices/wifi/tests/test-wifi-ap-utils.c2
-rw-r--r--src/devices/wwan/nm-device-modem.c33
-rw-r--r--src/devices/wwan/nm-modem-broadband.c154
-rw-r--r--src/dhcp-manager/nm-dhcp-client.c68
-rw-r--r--src/dhcp-manager/nm-dhcp-dhclient-utils.c2
-rw-r--r--src/dhcp-manager/nm-dhcp-dhclient.c6
-rw-r--r--src/dhcp-manager/nm-dhcp-systemd.c20
-rw-r--r--src/dhcp-manager/nm-dhcp-utils.c12
-rw-r--r--src/dhcp-manager/tests/test-dhcp-dhclient.c2
-rw-r--r--src/dhcp-manager/tests/test-dhcp-utils.c2
-rw-r--r--src/dns-manager/nm-dns-dnsmasq.c125
-rw-r--r--src/dns-manager/nm-dns-manager.c832
-rw-r--r--src/dns-manager/nm-dns-manager.h58
-rw-r--r--src/dns-manager/nm-dns-plugin.c8
-rw-r--r--src/dns-manager/nm-dns-plugin.h22
-rw-r--r--src/dns-manager/nm-dns-unbound.c4
-rw-r--r--src/dnsmasq-manager/nm-dnsmasq-manager.c143
-rw-r--r--src/dnsmasq-manager/nm-dnsmasq-manager.h3
-rw-r--r--src/dnsmasq-manager/tests/test-dnsmasq-utils.c2
-rw-r--r--src/main-utils.c1
-rw-r--r--src/main.c95
-rw-r--r--src/nm-audit-manager.c9
-rw-r--r--src/nm-audit-manager.h7
-rw-r--r--src/nm-auth-subject.c48
-rw-r--r--src/nm-auth-subject.h8
-rw-r--r--src/nm-config.c222
-rw-r--r--src/nm-config.h27
-rw-r--r--src/nm-connection-provider.c126
-rw-r--r--src/nm-connection-provider.h127
-rw-r--r--src/nm-core-utils.c197
-rw-r--r--src/nm-core-utils.h22
-rw-r--r--src/nm-default-route-manager.c30
-rw-r--r--src/nm-iface-helper.c4
-rw-r--r--src/nm-ip4-config.c192
-rw-r--r--src/nm-ip4-config.h18
-rw-r--r--src/nm-ip6-config.c212
-rw-r--r--src/nm-ip6-config.h20
-rw-r--r--src/nm-logging.c108
-rw-r--r--src/nm-logging.h19
-rw-r--r--src/nm-manager.c225
-rw-r--r--src/nm-manager.h19
-rw-r--r--src/nm-policy.c12
-rw-r--r--src/nm-route-manager.c4
-rw-r--r--src/nm-session-monitor.c39
-rw-r--r--src/nm-session-monitor.h6
-rw-r--r--src/nm-test-utils-core.h296
-rw-r--r--src/nm-types.h23
-rw-r--r--src/platform/nm-fake-platform.c21
-rw-r--r--src/platform/nm-linux-platform.c269
-rw-r--r--src/platform/nm-linux-platform.h6
-rw-r--r--src/platform/nm-platform-utils.c134
-rw-r--r--src/platform/nm-platform-utils.h7
-rw-r--r--src/platform/nm-platform.c162
-rw-r--r--src/platform/nm-platform.h34
-rw-r--r--src/platform/nmp-object.c4
-rw-r--r--src/platform/nmp-object.h6
-rw-r--r--src/platform/tests/monitor.c2
-rw-r--r--src/platform/tests/test-common.h2
-rw-r--r--src/platform/tests/test-general.c2
-rw-r--r--src/platform/tests/test-link.c4
-rw-r--r--src/platform/tests/test-nmp-object.c2
-rw-r--r--src/platform/tests/test-route.c16
-rw-r--r--src/platform/wifi/wifi-utils.c21
-rw-r--r--src/platform/wifi/wifi-utils.h2
-rw-r--r--src/ppp-manager/nm-ppp-manager.c22
-rw-r--r--src/ppp-manager/nm-pppd-plugin.c2
-rw-r--r--src/rdisc/nm-rdisc.c2
-rw-r--r--src/rdisc/tests/test-rdisc-fake.c2
-rw-r--r--src/rdisc/tests/test-rdisc-linux.c2
-rw-r--r--src/settings/nm-settings-connection.c78
-rw-r--r--src/settings/nm-settings.c183
-rw-r--r--src/settings/nm-settings.h29
-rw-r--r--src/settings/plugins/ibft/tests/test-ibft.c2
-rw-r--r--src/settings/plugins/ifcfg-rh/common.h4
-rw-r--r--src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c3
-rw-r--r--src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h8
-rw-r--r--src/settings/plugins/ifcfg-rh/plugin.c9
-rw-r--r--src/settings/plugins/ifcfg-rh/plugin.h4
-rw-r--r--src/settings/plugins/ifcfg-rh/reader.c200
-rw-r--r--src/settings/plugins/ifcfg-rh/reader.h5
-rw-r--r--src/settings/plugins/ifcfg-rh/shvar.c20
-rw-r--r--src/settings/plugins/ifcfg-rh/shvar.h8
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c2
-rw-r--r--src/settings/plugins/ifcfg-rh/utils.c3
-rw-r--r--src/settings/plugins/ifcfg-rh/utils.h5
-rw-r--r--src/settings/plugins/ifcfg-rh/writer.c45
-rw-r--r--src/settings/plugins/ifcfg-rh/writer.h6
-rw-r--r--src/settings/plugins/ifnet/tests/test-ifnet.c2
-rw-r--r--src/settings/plugins/ifupdown/tests/test-ifupdown.c2
-rw-r--r--src/settings/plugins/keyfile/plugin.c1
-rw-r--r--src/settings/plugins/keyfile/tests/test-keyfile.c2
-rw-r--r--src/supplicant-manager/tests/test-supplicant-config.c2
-rw-r--r--src/systemd/src/basic/ether-addr-util.c69
-rw-r--r--src/systemd/src/basic/ether-addr-util.h2
-rw-r--r--src/systemd/src/basic/extract-word.c302
-rw-r--r--src/systemd/src/basic/extract-word.h35
-rw-r--r--src/systemd/src/basic/fd-util.c18
-rw-r--r--src/systemd/src/basic/fd-util.h2
-rw-r--r--src/systemd/src/basic/fileio.c128
-rw-r--r--src/systemd/src/basic/fileio.h6
-rw-r--r--src/systemd/src/basic/fs-util.c17
-rw-r--r--src/systemd/src/basic/fs-util.h2
-rw-r--r--src/systemd/src/basic/hashmap.c10
-rw-r--r--src/systemd/src/basic/hostname-util.c10
-rw-r--r--src/systemd/src/basic/io-util.c5
-rw-r--r--src/systemd/src/basic/parse-util.c2
-rw-r--r--src/systemd/src/basic/parse-util.h12
-rw-r--r--src/systemd/src/basic/path-util.c75
-rw-r--r--src/systemd/src/basic/path-util.h20
-rw-r--r--src/systemd/src/basic/signal-util.h56
-rw-r--r--src/systemd/src/basic/socket-util.c78
-rw-r--r--src/systemd/src/basic/socket-util.h15
-rw-r--r--src/systemd/src/basic/string-table.h54
-rw-r--r--src/systemd/src/basic/string-util.h1
-rw-r--r--src/systemd/src/basic/strv.c38
-rw-r--r--src/systemd/src/basic/strv.h5
-rw-r--r--src/systemd/src/basic/time-util.c44
-rw-r--r--src/systemd/src/basic/time-util.h1
-rw-r--r--src/systemd/src/basic/util.c43
-rw-r--r--src/systemd/src/basic/util.h2
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-identifier.c31
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-identifier.h40
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-internal.h3
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-protocol.h2
-rw-r--r--src/systemd/src/libsystemd-network/dhcp6-internal.h3
-rw-r--r--src/systemd/src/libsystemd-network/network-internal.c161
-rw-r--r--src/systemd/src/libsystemd-network/network-internal.h4
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp-client.c270
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp6-client.c171
-rw-r--r--src/systemd/src/libsystemd-network/sd-ipv4acd.c505
-rw-r--r--src/systemd/src/libsystemd-network/sd-ipv4ll.c180
-rw-r--r--src/systemd/src/libsystemd/sd-event/sd-event.c17
-rw-r--r--src/systemd/src/systemd/sd-dhcp-client.h78
-rw-r--r--src/systemd/src/systemd/sd-dhcp6-client.h61
-rw-r--r--src/systemd/src/systemd/sd-ipv4acd.h28
-rw-r--r--src/systemd/src/systemd/sd-ipv4ll.h6
-rw-r--r--src/systemd/src/systemd/sd-lldp.h75
-rw-r--r--src/systemd/src/systemd/sd-ndisc.h2
-rw-r--r--src/tests/Makefile.am9
-rw-r--r--src/tests/config/Makefile.am5
-rw-r--r--src/tests/config/NetworkManager.state4
-rw-r--r--src/tests/config/test-config.c63
-rw-r--r--src/tests/test-dcb.c2
-rw-r--r--src/tests/test-general-with-expect.c2
-rw-r--r--src/tests/test-general.c2
-rw-r--r--src/tests/test-ip4-config.c42
-rw-r--r--src/tests/test-ip6-config.c42
-rw-r--r--src/tests/test-resolvconf-capture.c2
-rw-r--r--src/tests/test-route-manager.c101
-rw-r--r--src/tests/test-systemd.c2
-rw-r--r--src/tests/test-utils.c2
-rw-r--r--src/tests/test-wired-defname.c26
-rw-r--r--src/vpn-manager/nm-vpn-connection.c180
-rw-r--r--src/vpn-manager/nm-vpn-connection.h4
237 files changed, 8335 insertions, 5102 deletions
diff --git a/.travis.yml b/.travis.yml
index b907bf13ed..44e5e0a247 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,7 @@ before_install:
libnl-3-dev libnl-route-3-dev libnl-genl-3-dev ppp-dev libpolkit-gobject-1-dev libgnutls28-dev libgcrypt11-dev
uuid-dev libudev-dev libgudev-1.0-dev libgirepository1.0-dev gobject-introspection libsoup2.4-dev gtk-doc-tools
libglib2.0-doc libreadline-dev libnewt-dev libnss3-dev iptables make python-software-properties python-gi
- python-dbus dbus dbus-x11
+ python-dbus dbus dbus-x11 libjansson4 libjansson-dev
- sudo dbus-uuidgen --ensure
- sudo apt-add-repository 'deb http://archive.ubuntu.com/ubuntu trusty main'
- sudo apt-add-repository 'deb http://archive.ubuntu.com/ubuntu trusty-backports main restricted universe multiverse'
diff --git a/clients/cli/devices.c b/clients/cli/devices.c
index 65c4be7286..e1688278a4 100644
--- a/clients/cli/devices.c
+++ b/clients/cli/devices.c
@@ -186,7 +186,7 @@ static NmcOutputField nmc_fields_dev_wimax_list[] = {
#define NMC_FIELDS_DEV_WIMAX_LIST_COMMON "NSP,SIGNAL,TYPE,DEVICE,ACTIVE"
#define NMC_FIELDS_DEV_WIMAX_LIST_FOR_DEV_LIST "NAME,"NMC_FIELDS_DEV_WIMAX_LIST_COMMON
-/* Available fields for 'device show' - BOND, TEAM, BRIDGE part */
+/* Available fields for 'device show' - BOND, BRIDGE part */
static NmcOutputField nmc_fields_dev_show_master_prop[] = {
{"NAME", N_("NAME")}, /* 0 */
{"SLAVES", N_("SLAVES")}, /* 1 */
@@ -195,6 +195,16 @@ static NmcOutputField nmc_fields_dev_show_master_prop[] = {
#define NMC_FIELDS_DEV_SHOW_MASTER_PROP_ALL "NAME,SLAVES"
#define NMC_FIELDS_DEV_SHOW_MASTER_PROP_COMMON "NAME,SLAVES"
+/* Available fields for 'device show' - TEAM part */
+static NmcOutputField nmc_fields_dev_show_team_prop[] = {
+ {"NAME", N_("NAME")}, /* 0 */
+ {"SLAVES", N_("SLAVES")}, /* 1 */
+ {"CONFIG", N_("CONFIG")}, /* 2 */
+ {NULL, NULL}
+};
+#define NMC_FIELDS_DEV_SHOW_TEAM_PROP_ALL "NAME,SLAVES,CONFIG"
+#define NMC_FIELDS_DEV_SHOW_TEAM_PROP_COMMON "NAME,SLAVES,CONFIG"
+
/* Available fields for 'device show' - VLAN part */
static NmcOutputField nmc_fields_dev_show_vlan_prop[] = {
{"NAME", N_("NAME")}, /* 0 */
@@ -234,7 +244,7 @@ static NmcOutputField nmc_fields_dev_show_sections[] = {
{"IP6", N_("IP6"), 0, nmc_fields_ip6_config + 1 }, /* 9 */
{"DHCP6", N_("DHCP6"), 0, nmc_fields_dhcp6_config + 1 }, /* 10 */
{"BOND", N_("BOND"), 0, nmc_fields_dev_show_master_prop + 1 }, /* 11 */
- {"TEAM", N_("TEAM"), 0, nmc_fields_dev_show_master_prop + 1 }, /* 12 */
+ {"TEAM", N_("TEAM"), 0, nmc_fields_dev_show_team_prop + 1 }, /* 12 */
{"BRIDGE", N_("BRIDGE"), 0, nmc_fields_dev_show_master_prop + 1 }, /* 13 */
{"VLAN", N_("VLAN"), 0, nmc_fields_dev_show_vlan_prop + 1 }, /* 14 */
{"BLUETOOTH", N_("BLUETOOTH"), 0, nmc_fields_dev_show_bluetooth + 1 }, /* 15 */
@@ -840,10 +850,10 @@ get_active_connection_id (NMDevice *device)
}
static gboolean
-print_bond_team_bridge_info (NMDevice *device,
- NmCli *nmc,
- const char *group_prefix,
- const char *one_field)
+print_bond_bridge_info (NMDevice *device,
+ NmCli *nmc,
+ const char *group_prefix,
+ const char *one_field)
{
const GPtrArray *slaves = NULL;
GString *slaves_str;
@@ -853,10 +863,10 @@ print_bond_team_bridge_info (NMDevice *device,
if (NM_IS_DEVICE_BOND (device))
slaves = nm_device_bond_get_slaves (NM_DEVICE_BOND (device));
- else if (NM_IS_DEVICE_TEAM (device))
- slaves = nm_device_team_get_slaves (NM_DEVICE_TEAM (device));
else if (NM_IS_DEVICE_BRIDGE (device))
slaves = nm_device_bridge_get_slaves (NM_DEVICE_BRIDGE (device));
+ else
+ g_return_val_if_reached (FALSE);
slaves_str = g_string_new (NULL);
for (idx = 0; slaves && idx < slaves->len; idx++) {
@@ -891,6 +901,76 @@ print_bond_team_bridge_info (NMDevice *device,
return TRUE;
}
+static char *
+sanitize_team_config (const char *config)
+{
+ char *ret;
+ int i;
+
+ if (!config)
+ return NULL;
+
+ ret = g_strdup (config);
+
+ for (i = 0; i < strlen (ret); i++) {
+ if (ret[i] == '\n')
+ ret[i] = ' ';
+ }
+
+ return ret;
+}
+
+static gboolean
+print_team_info (NMDevice *device,
+ NmCli *nmc,
+ const char *group_prefix,
+ const char *one_field)
+{
+ const GPtrArray *slaves = NULL;
+ GString *slaves_str;
+ int idx;
+ NmcOutputField *tmpl, *arr;
+ size_t tmpl_len;
+
+ if (NM_IS_DEVICE_TEAM (device))
+ slaves = nm_device_team_get_slaves (NM_DEVICE_TEAM (device));
+ else
+ g_return_val_if_reached (FALSE);
+
+ slaves_str = g_string_new (NULL);
+ for (idx = 0; slaves && idx < slaves->len; idx++) {
+ NMDevice *slave = g_ptr_array_index (slaves, idx);
+ const char *iface = nm_device_get_iface (slave);
+
+ if (iface) {
+ g_string_append (slaves_str, iface);
+ g_string_append_c (slaves_str, ' ');
+ }
+ }
+ if (slaves_str->len > 0)
+ g_string_truncate (slaves_str, slaves_str->len-1); /* Chop off last space */
+
+ tmpl = nmc_fields_dev_show_team_prop;
+ tmpl_len = sizeof (nmc_fields_dev_show_team_prop);
+ nmc->print_fields.indices = parse_output_fields (one_field ? one_field : NMC_FIELDS_DEV_SHOW_TEAM_PROP_ALL,
+ tmpl, FALSE, NULL, NULL);
+ arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES);
+ g_ptr_array_add (nmc->output_data, arr);
+
+ arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX);
+ set_val_strc (arr, 0, group_prefix); /* TEAM */
+ set_val_str (arr, 1, slaves_str->str);
+ set_val_str (arr, 2, sanitize_team_config (nm_device_team_get_config (NM_DEVICE_TEAM (device))));
+ g_ptr_array_add (nmc->output_data, arr);
+
+ print_data (nmc); /* Print all data */
+
+ g_string_free (slaves_str, FALSE);
+ nmc_empty_output_fields (nmc);
+
+ return TRUE;
+}
+
static gboolean
show_device_info (NMDevice *device, NmCli *nmc)
{
@@ -1146,19 +1226,19 @@ show_device_info (NMDevice *device, NmCli *nmc)
/* Bond specific information */
if (NM_IS_DEVICE_BOND (device)) {
if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[11].name))
- was_output = print_bond_team_bridge_info (device, nmc, nmc_fields_dev_show_sections[11].name, section_fld);
+ was_output = print_bond_bridge_info (device, nmc, nmc_fields_dev_show_sections[11].name, section_fld);
}
/* Team specific information */
if (NM_IS_DEVICE_TEAM (device)) {
if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[12].name))
- was_output = print_bond_team_bridge_info (device, nmc, nmc_fields_dev_show_sections[12].name, section_fld);
+ was_output = print_team_info (device, nmc, nmc_fields_dev_show_sections[12].name, section_fld);
}
/* Bridge specific information */
if (NM_IS_DEVICE_BRIDGE (device)) {
if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[13].name))
- was_output = print_bond_team_bridge_info (device, nmc, nmc_fields_dev_show_sections[13].name, section_fld);
+ was_output = print_bond_bridge_info (device, nmc, nmc_fields_dev_show_sections[13].name, section_fld);
}
/* VLAN-specific information */
diff --git a/clients/cli/settings.c b/clients/cli/settings.c
index d254df3c68..0f75d2a791 100644
--- a/clients/cli/settings.c
+++ b/clients/cli/settings.c
@@ -272,20 +272,21 @@ NmcOutputField nmc_fields_setting_ip4_config[] = {
SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS), /* 2 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS_SEARCH), /* 3 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS_OPTIONS), /* 4 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_ADDRESSES), /* 5 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_GATEWAY), /* 6 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTES), /* 7 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTE_METRIC), /* 8 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES), /* 9 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS), /* 10 */
- SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID), /* 11 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_TIMEOUT), /* 12 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME), /* 13 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME), /* 14 */
- SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_FQDN), /* 15 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_NEVER_DEFAULT), /* 16 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_MAY_FAIL), /* 17 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_DAD_TIMEOUT), /* 18 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS_PRIORITY), /* 5 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_ADDRESSES), /* 6 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_GATEWAY), /* 7 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTES), /* 8 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTE_METRIC), /* 9 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES), /* 10 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS), /* 11 */
+ SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID), /* 12 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_TIMEOUT), /* 13 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME), /* 14 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME), /* 15 */
+ SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_FQDN), /* 16 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_NEVER_DEFAULT), /* 17 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_MAY_FAIL), /* 18 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_DAD_TIMEOUT), /* 19 */
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
};
#define NMC_FIELDS_SETTING_IP4_CONFIG_ALL "name"","\
@@ -293,6 +294,7 @@ NmcOutputField nmc_fields_setting_ip4_config[] = {
NM_SETTING_IP_CONFIG_DNS","\
NM_SETTING_IP_CONFIG_DNS_SEARCH","\
NM_SETTING_IP_CONFIG_DNS_OPTIONS","\
+ NM_SETTING_IP_CONFIG_DNS_PRIORITY","\
NM_SETTING_IP_CONFIG_ADDRESSES","\
NM_SETTING_IP_CONFIG_GATEWAY","\
NM_SETTING_IP_CONFIG_ROUTES","\
@@ -315,18 +317,20 @@ NmcOutputField nmc_fields_setting_ip6_config[] = {
SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS), /* 2 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS_SEARCH), /* 3 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS_OPTIONS), /* 4 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_ADDRESSES), /* 5 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_GATEWAY), /* 6 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTES), /* 7 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTE_METRIC), /* 8 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES), /* 9 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS), /* 10 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_NEVER_DEFAULT), /* 11 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_MAY_FAIL), /* 12 */
- SETTING_FIELD (NM_SETTING_IP6_CONFIG_IP6_PRIVACY), /* 13 */
- SETTING_FIELD (NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE), /* 14 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME), /* 15 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME), /* 16 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS_PRIORITY), /* 5 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_ADDRESSES), /* 6 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_GATEWAY), /* 7 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTES), /* 8 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTE_METRIC), /* 9 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES), /* 10 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS), /* 11 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_NEVER_DEFAULT), /* 12 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_MAY_FAIL), /* 13 */
+ SETTING_FIELD (NM_SETTING_IP6_CONFIG_IP6_PRIVACY), /* 14 */
+ SETTING_FIELD (NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE), /* 15 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME), /* 16 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME), /* 17 */
+ SETTING_FIELD (NM_SETTING_IP6_CONFIG_TOKEN), /* 18 */
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
};
#define NMC_FIELDS_SETTING_IP6_CONFIG_ALL "name"","\
@@ -334,6 +338,7 @@ NmcOutputField nmc_fields_setting_ip6_config[] = {
NM_SETTING_IP_CONFIG_DNS","\
NM_SETTING_IP_CONFIG_DNS_SEARCH","\
NM_SETTING_IP_CONFIG_DNS_OPTIONS","\
+ NM_SETTING_IP_CONFIG_DNS_PRIORITY","\
NM_SETTING_IP_CONFIG_ADDRESSES","\
NM_SETTING_IP_CONFIG_GATEWAY","\
NM_SETTING_IP_CONFIG_ROUTES","\
@@ -345,7 +350,8 @@ NmcOutputField nmc_fields_setting_ip6_config[] = {
NM_SETTING_IP6_CONFIG_IP6_PRIVACY","\
NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE","\
NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME","\
- NM_SETTING_IP_CONFIG_DHCP_HOSTNAME
+ NM_SETTING_IP_CONFIG_DHCP_HOSTNAME","\
+ NM_SETTING_IP6_CONFIG_TOKEN
/* Available fields for NM_SETTING_SERIAL_SETTING_NAME */
NmcOutputField nmc_fields_setting_serial[] = {
@@ -1488,6 +1494,7 @@ DEFINE_GETTER (nmc_property_ipv4_get_method, NM_SETTING_IP_CONFIG_METHOD)
DEFINE_GETTER (nmc_property_ipv4_get_dns, NM_SETTING_IP_CONFIG_DNS)
DEFINE_GETTER (nmc_property_ipv4_get_dns_search, NM_SETTING_IP_CONFIG_DNS_SEARCH)
DEFINE_GETTER_WITH_DEFAULT (nmc_property_ipv4_get_dns_options, NM_SETTING_IP_CONFIG_DNS_OPTIONS, !nm_setting_ip_config_has_dns_options ((NMSettingIPConfig *) setting))
+DEFINE_GETTER (nmc_property_ipv4_get_dns_priority, NM_SETTING_IP_CONFIG_DNS_PRIORITY)
static char *
nmc_property_ip_get_addresses (NMSetting *setting, NmcPropertyGetType get_type)
@@ -1608,6 +1615,7 @@ DEFINE_GETTER (nmc_property_ipv6_get_method, NM_SETTING_IP_CONFIG_METHOD)
DEFINE_GETTER (nmc_property_ipv6_get_dns, NM_SETTING_IP_CONFIG_DNS)
DEFINE_GETTER (nmc_property_ipv6_get_dns_search, NM_SETTING_IP_CONFIG_DNS_SEARCH)
DEFINE_GETTER_WITH_DEFAULT (nmc_property_ipv6_get_dns_options, NM_SETTING_IP_CONFIG_DNS_OPTIONS, !nm_setting_ip_config_has_dns_options ((NMSettingIPConfig *) setting))
+DEFINE_GETTER (nmc_property_ipv6_get_dns_priority, NM_SETTING_IP_CONFIG_DNS_PRIORITY)
static char *
nmc_property_ipv6_get_routes (NMSetting *setting, NmcPropertyGetType get_type)
@@ -1623,6 +1631,7 @@ DEFINE_GETTER (nmc_property_ipv6_get_never_default, NM_SETTING_IP_CONFIG_NEVER_D
DEFINE_GETTER (nmc_property_ipv6_get_may_fail, NM_SETTING_IP_CONFIG_MAY_FAIL)
DEFINE_GETTER (nmc_property_ipv6_get_dhcp_send_hostname, NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME)
DEFINE_GETTER (nmc_property_ipv6_get_dhcp_hostname, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME)
+DEFINE_GETTER (nmc_property_ipv6_get_token, NM_SETTING_IP6_CONFIG_TOKEN)
static char *
nmc_property_ipv6_get_ip6_privacy (NMSetting *setting, NmcPropertyGetType get_type)
@@ -6496,6 +6505,13 @@ nmc_properties_init (void)
NULL,
NULL,
NULL);
+ nmc_add_prop_funcs (GLUE_IP (4, DNS_PRIORITY),
+ nmc_property_ipv4_get_dns_priority,
+ nmc_property_set_int,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
nmc_add_prop_funcs (GLUE_IP (4, ADDRESSES),
nmc_property_ip_get_addresses,
nmc_property_ipv4_set_addresses,
@@ -6624,6 +6640,13 @@ nmc_properties_init (void)
NULL,
NULL,
NULL);
+ nmc_add_prop_funcs (GLUE_IP (6, DNS_PRIORITY),
+ nmc_property_ipv6_get_dns_priority,
+ nmc_property_set_int,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
nmc_add_prop_funcs (GLUE_IP (6, ADDRESSES),
nmc_property_ip_get_addresses,
nmc_property_ipv6_set_addresses,
@@ -6708,6 +6731,13 @@ nmc_properties_init (void)
NULL,
NULL,
NULL);
+ nmc_add_prop_funcs (GLUE (IP6_CONFIG, TOKEN),
+ nmc_property_ipv6_get_token,
+ nmc_property_set_string,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
/* Add editable properties for NM_SETTING_OLPC_MESH_SETTING_NAME */
nmc_add_prop_funcs (GLUE (OLPC_MESH, SSID),
@@ -8179,20 +8209,21 @@ setting_ip4_config_details (NMSetting *setting, NmCli *nmc, const char *one_pro
set_val_str (arr, 2, nmc_property_ipv4_get_dns (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 3, nmc_property_ipv4_get_dns_search (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 4, nmc_property_ipv4_get_dns_options (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 5, nmc_property_ip_get_addresses (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 6, nmc_property_ipv4_get_gateway (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 7, nmc_property_ipv4_get_routes (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 8, nmc_property_ipv4_get_route_metric (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 9, nmc_property_ipv4_get_ignore_auto_routes (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 10, nmc_property_ipv4_get_ignore_auto_dns (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 11, nmc_property_ipv4_get_dhcp_client_id (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 12, nmc_property_ipv4_get_dhcp_timeout (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 13, nmc_property_ipv4_get_dhcp_send_hostname (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 14, nmc_property_ipv4_get_dhcp_hostname (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 15, nmc_property_ipv4_get_dhcp_fqdn (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 16, nmc_property_ipv4_get_never_default (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 17, nmc_property_ipv4_get_may_fail (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 18, nmc_property_ipv4_get_dad_timeout (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 5, nmc_property_ipv4_get_dns_priority (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 6, nmc_property_ip_get_addresses (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 7, nmc_property_ipv4_get_gateway (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 8, nmc_property_ipv4_get_routes (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 9, nmc_property_ipv4_get_route_metric (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 10, nmc_property_ipv4_get_ignore_auto_routes (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 11, nmc_property_ipv4_get_ignore_auto_dns (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 12, nmc_property_ipv4_get_dhcp_client_id (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 13, nmc_property_ipv4_get_dhcp_timeout (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 14, nmc_property_ipv4_get_dhcp_send_hostname (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 15, nmc_property_ipv4_get_dhcp_hostname (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 16, nmc_property_ipv4_get_dhcp_fqdn (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 17, nmc_property_ipv4_get_never_default (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 18, nmc_property_ipv4_get_may_fail (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 19, nmc_property_ipv4_get_dad_timeout (setting, NMC_PROPERTY_GET_PRETTY));
g_ptr_array_add (nmc->output_data, arr);
print_data (nmc); /* Print all data */
@@ -8222,18 +8253,20 @@ setting_ip6_config_details (NMSetting *setting, NmCli *nmc, const char *one_pro
set_val_str (arr, 2, nmc_property_ipv6_get_dns (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 3, nmc_property_ipv6_get_dns_search (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 4, nmc_property_ipv6_get_dns_options (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 5, nmc_property_ip_get_addresses (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 6, nmc_property_ipv6_get_gateway (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 7, nmc_property_ipv6_get_routes (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 8, nmc_property_ipv6_get_route_metric (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 9, nmc_property_ipv6_get_ignore_auto_routes (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 10, nmc_property_ipv6_get_ignore_auto_dns (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 11, nmc_property_ipv6_get_never_default (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 12, nmc_property_ipv6_get_may_fail (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 13, nmc_property_ipv6_get_ip6_privacy (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 14, nmc_property_ipv6_get_addr_gen_mode (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 15, nmc_property_ipv6_get_dhcp_send_hostname (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 16, nmc_property_ipv6_get_dhcp_hostname (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 5, nmc_property_ipv6_get_dns_priority (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 6, nmc_property_ip_get_addresses (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 7, nmc_property_ipv6_get_gateway (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 8, nmc_property_ipv6_get_routes (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 9, nmc_property_ipv6_get_route_metric (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 10, nmc_property_ipv6_get_ignore_auto_routes (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 11, nmc_property_ipv6_get_ignore_auto_dns (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 12, nmc_property_ipv6_get_never_default (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 13, nmc_property_ipv6_get_may_fail (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 14, nmc_property_ipv6_get_ip6_privacy (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 15, nmc_property_ipv6_get_addr_gen_mode (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 16, nmc_property_ipv6_get_dhcp_send_hostname (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 17, nmc_property_ipv6_get_dhcp_hostname (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 18, nmc_property_ipv6_get_token (setting, NMC_PROPERTY_GET_PRETTY));
g_ptr_array_add (nmc->output_data, arr);
print_data (nmc); /* Print all data */
diff --git a/clients/common/nm-vpn-helpers.c b/clients/common/nm-vpn-helpers.c
index fe777ef55f..43ac4b2e61 100644
--- a/clients/common/nm-vpn-helpers.c
+++ b/clients/common/nm-vpn-helpers.c
@@ -28,7 +28,6 @@
#include "nm-vpn-helpers.h"
#include <string.h>
-#include <gmodule.h>
#include "nm-utils.h"
@@ -157,9 +156,7 @@ nm_vpn_get_service_for_name (const char *name)
if (plugin_info) {
/* this only means we have a .name file (NMVpnPluginInfo). Possibly the
* NMVpnEditorPlugin is not loadable. */
- return nm_vpn_plugin_info_lookup_property (plugin_info,
- NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION,
- "service");
+ return nm_vpn_plugin_info_get_service (plugin_info);
}
return NULL;
}
diff --git a/clients/tui/nmtui-connect.c b/clients/tui/nmtui-connect.c
index 46e3361740..ae9dd43ed9 100644
--- a/clients/tui/nmtui-connect.c
+++ b/clients/tui/nmtui-connect.c
@@ -378,7 +378,7 @@ listbox_active_changed (GObject *object,
}
static NmtNewtForm *
-nmt_connect_connection_list (void)
+nmt_connect_connection_list (gboolean is_top)
{
int screen_width, screen_height;
NmtNewtForm *form;
@@ -410,7 +410,7 @@ nmt_connect_connection_list (void)
listbox_active_changed (G_OBJECT (list), NULL, activate);
g_signal_connect (activate, "clicked", G_CALLBACK (activate_clicked), list);
- quit = nmt_newt_button_box_add_end (NMT_NEWT_BUTTON_BOX (bbox), _("Quit"));
+ quit = nmt_newt_button_box_add_end (NMT_NEWT_BUTTON_BOX (bbox), is_top ? _("Quit") : _("Back"));
nmt_newt_widget_set_exit_on_activate (quit, TRUE);
nmt_newt_form_set_content (form, grid);
@@ -444,10 +444,10 @@ nmt_connect_connection (const char *identifier)
}
NmtNewtForm *
-nmtui_connect (int argc, char **argv)
+nmtui_connect (gboolean is_top, int argc, char **argv)
{
if (argc == 2)
return nmt_connect_connection (argv[1]);
else
- return nmt_connect_connection_list ();
+ return nmt_connect_connection_list (is_top);
}
diff --git a/clients/tui/nmtui-connect.h b/clients/tui/nmtui-connect.h
index 8310ac389a..89cb3916da 100644
--- a/clients/tui/nmtui-connect.h
+++ b/clients/tui/nmtui-connect.h
@@ -21,7 +21,7 @@
G_BEGIN_DECLS
-NmtNewtForm *nmtui_connect (int argc, char **argv);
+NmtNewtForm *nmtui_connect (gboolean is_top, int argc, char **argv);
G_END_DECLS
diff --git a/clients/tui/nmtui-edit.c b/clients/tui/nmtui-edit.c
index c7efd856db..1e887f516f 100644
--- a/clients/tui/nmtui-edit.c
+++ b/clients/tui/nmtui-edit.c
@@ -103,7 +103,7 @@ edit_connection_list_filter (NmtEditConnectionList *list,
}
static NmtNewtForm *
-nmt_edit_main_connection_list (void)
+nmt_edit_main_connection_list (gboolean is_top)
{
int screen_width, screen_height;
NmtNewtForm *form;
@@ -117,7 +117,7 @@ nmt_edit_main_connection_list (void)
"escape-exits", TRUE,
NULL);
- quit = nmt_newt_button_new (_("Quit"));
+ quit = nmt_newt_button_new (is_top ? _("Quit") : _("Back"));
nmt_newt_widget_set_exit_on_activate (quit, TRUE);
list = g_object_new (NMT_TYPE_EDIT_CONNECTION_LIST,
@@ -555,7 +555,7 @@ nmt_remove_connection (NMRemoteConnection *connection)
}
NmtNewtForm *
-nmtui_edit (int argc, char **argv)
+nmtui_edit (gboolean is_top, int argc, char **argv)
{
NMConnection *conn = NULL;
@@ -572,5 +572,5 @@ nmtui_edit (int argc, char **argv)
return nmt_editor_new (conn);
} else
- return nmt_edit_main_connection_list ();
+ return nmt_edit_main_connection_list (is_top);
}
diff --git a/clients/tui/nmtui-edit.h b/clients/tui/nmtui-edit.h
index dae91cfac7..459011e10b 100644
--- a/clients/tui/nmtui-edit.h
+++ b/clients/tui/nmtui-edit.h
@@ -26,7 +26,7 @@ G_BEGIN_DECLS
typedef gboolean (*NmtAddConnectionTypeFilter) (GType connection_type,
gpointer user_data);
-NmtNewtForm *nmtui_edit (int argc, char **argv);
+NmtNewtForm *nmtui_edit (gboolean is_top, int argc, char **argv);
void nmt_add_connection (void);
void nmt_add_connection_full (const char *primary_text,
diff --git a/clients/tui/nmtui-hostname.c b/clients/tui/nmtui-hostname.c
index ada2393fd1..f800550292 100644
--- a/clients/tui/nmtui-hostname.c
+++ b/clients/tui/nmtui-hostname.c
@@ -96,7 +96,7 @@ hostname_set (GObject *object,
}
NmtNewtForm *
-nmtui_hostname (int argc, char **argv)
+nmtui_hostname (gboolean is_top, int argc, char **argv)
{
const char *hostname;
char *tmp = NULL;
diff --git a/clients/tui/nmtui-hostname.h b/clients/tui/nmtui-hostname.h
index a14bc69937..1af711f9bb 100644
--- a/clients/tui/nmtui-hostname.h
+++ b/clients/tui/nmtui-hostname.h
@@ -21,7 +21,7 @@
G_BEGIN_DECLS
-NmtNewtForm *nmtui_hostname (int argc, char **argv);
+NmtNewtForm *nmtui_hostname (gboolean is_top, int argc, char **argv);
G_END_DECLS
diff --git a/clients/tui/nmtui.c b/clients/tui/nmtui.c
index 47ba5bf56e..70cad5d6ad 100644
--- a/clients/tui/nmtui.c
+++ b/clients/tui/nmtui.c
@@ -43,7 +43,7 @@
NMClient *nm_client;
static GMainLoop *loop;
-typedef NmtNewtForm * (*NmtuiSubprogram) (int argc, char **argv);
+typedef NmtNewtForm * (*NmtuiSubprogram) (gboolean is_top, int argc, char **argv);
static const struct {
const char *name, *shortcut, *arg;
@@ -61,22 +61,43 @@ static const struct {
nmtui_hostname }
};
static const int num_subprograms = G_N_ELEMENTS (subprograms);
+static NmtNewtForm *toplevel_form;
-static void
+static NmtNewtForm *
quit_func (int argc, char **argv)
{
+ if (toplevel_form)
+ nmt_newt_form_quit (toplevel_form);
+
nmtui_quit ();
+
+ return NULL;
+}
+
+static void
+main_list_activated (NmtNewtWidget *widget, NmtNewtListbox *listbox)
+{
+ NmtNewtForm *form;
+ NmtuiSubprogram sub;
+
+ sub = nmt_newt_listbox_get_active_key (listbox);
+ if (sub) {
+ form = sub (FALSE, 0, NULL);
+ if (form) {
+ nmt_newt_form_show (form);
+ g_object_unref (form);
+ }
+ }
}
static NmtNewtForm *
-nmtui_main (int argc, char **argv)
+nmtui_main (gboolean is_top, int argc, char **argv)
{
NmtNewtForm *form;
NmtNewtWidget *widget, *ok;
NmtNewtGrid *grid;
NmtNewtListbox *listbox;
NmtNewtButtonBox *bbox;
- NmtuiSubprogram subprogram = NULL;
int i;
form = g_object_new (NMT_TYPE_NEWT_FORM,
@@ -97,8 +118,9 @@ nmtui_main (int argc, char **argv)
NULL);
nmt_newt_grid_add (grid, widget, 0, 1);
nmt_newt_widget_set_padding (widget, 0, 1, 0, 1);
- nmt_newt_widget_set_exit_on_activate (widget, TRUE);
listbox = NMT_NEWT_LISTBOX (widget);
+ g_signal_connect (widget, "activated",
+ G_CALLBACK (main_list_activated), listbox);
for (i = 0; i < num_subprograms; i++) {
nmt_newt_listbox_append (listbox, _(subprograms[i].display_name),
@@ -112,17 +134,12 @@ nmtui_main (int argc, char **argv)
bbox = NMT_NEWT_BUTTON_BOX (widget);
ok = nmt_newt_button_box_add_end (bbox, _("OK"));
- nmt_newt_widget_set_exit_on_activate (ok, TRUE);
+ g_signal_connect (ok, "activated",
+ G_CALLBACK (main_list_activated), listbox);
- widget = nmt_newt_form_run_sync (form);
- if (widget)
- subprogram = nmt_newt_listbox_get_active_key (listbox);
- g_object_unref (form);
+ toplevel_form = form;
- if (subprogram)
- return subprogram (argc, argv);
- else
- return NULL;
+ return form;
}
/**
@@ -179,7 +196,7 @@ idle_run_subprogram (gpointer user_data)
NmtuiStartupData *data = user_data;
NmtNewtForm *form;
- form = data->subprogram (data->argc, data->argv);
+ form = data->subprogram (TRUE, data->argc, data->argv);
if (form) {
g_signal_connect (form, "quit", G_CALLBACK (toplevel_form_quit), NULL);
nmt_newt_form_show (form);
diff --git a/configure.ac b/configure.ac
index 6067a88fbe..e963b4f3a9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -35,6 +35,10 @@ AC_PROG_CXX
AC_PROG_LN_S
+# Prefer gcc-* variants; the ones libtool would choose don't work with LTO
+AC_CHECK_TOOLS(AR, [gcc-ar ar], false)
+AC_CHECK_TOOLS(RANLIB, [gcc-ranlib ranlib], :)
+
dnl Initialize libtool
LT_PREREQ([2.2])
LT_INIT([disable-static])
@@ -553,6 +557,18 @@ else
fi
AM_CONDITIONAL(WITH_TEAMDCTL, test "${enable_teamdctl}" = "yes")
+PKG_CHECK_MODULES(JANSSON, jansson, [have_jansson=yes], [have_jansson=no])
+AC_ARG_ENABLE(json-validation, AS_HELP_STRING([--enable-json-validation], [Enable JSON validation in libnm]),
+ [enable_json_validation=${enableval}], [enable_json_validation=${have_jansson}])
+if (test "${enable_json_validation}" = "yes"); then
+ if test x"$have_jansson" = x"no"; then
+ AC_MSG_ERROR(Jansson is required for JSON validation)
+ fi
+ AC_DEFINE(WITH_JANSSON, 1, [Define if JANSSON is enabled])
+else
+ AC_DEFINE(WITH_JANSSON, 0, [Define if JANSSON is enabled])
+fi
+
# we usually compile with polkit support. --enable-polkit=yes|no only sets the
# default configuration for main.auth-polkit. User can always enable/disable polkit
# autorization via config. Only when specifying --enable-polkit=disabled, we do
@@ -763,6 +779,11 @@ fi
# resolvconf and netconfig support
AC_ARG_WITH(resolvconf, AS_HELP_STRING([--with-resolvconf=yes|no|path], [Enable resolvconf support]))
AC_ARG_WITH(netconfig, AS_HELP_STRING([--with-netconfig=yes|no], [Enable SUSE netconfig support]))
+AC_ARG_WITH(config-dns-rc-manager-default, AS_HELP_STRING([--with-config-dns-rc-manager-default=symlink|file|netconfig|resolvconf], [Configure default value for main.rc-manager setting]), [config_dns_rc_manager_default=$withval])
+if test "$config_dns_rc_manager_default" != symlink -a "$config_dns_rc_manager_default" != file -a "$config_dns_rc_manager_default" != netconfig -a "$config_dns_rc_manager_default" != resolvconf; then
+ AC_MSG_WARN([Unknown --with-config-dns-rc-manager-default=$config_dns_rc_manager_default setting.])
+ config_dns_rc_manager_default=
+fi
# Use netconfig by default on SUSE
AS_IF([test -z "$with_netconfig"], AC_CHECK_FILE(/etc/SuSE-release, with_netconfig=yes))
# Otherwise default to "no"
@@ -772,9 +793,16 @@ AS_IF([test -z "$with_netconfig"], with_netconfig=no)
if test "$with_resolvconf" = "yes"; then
AC_PATH_PROGS(with_resolvconf, resolvconf, no, /sbin:/usr/sbin:/usr/local/sbin)
fi
+if test "$with_resolvconf" != "no"; then
+ AS_IF([test -z "$config_dns_rc_manager_default"], config_dns_rc_manager_default=resolvconf)
+fi
if test "$with_netconfig" = "yes"; then
AC_PATH_PROGS(with_netconfig, netconfig, no, /sbin:/usr/sbin:/usr/local/sbin)
fi
+if test "$with_netconfig" != "no"; then
+ AS_IF([test -z "$config_dns_rc_manager_default"], config_dns_rc_manager_default=netconfig)
+fi
+AS_IF([test -z "$config_dns_rc_manager_default"], config_dns_rc_manager_default=symlink)
# Define resolvconf and netconfig paths
if test "$with_resolvconf" != "no"; then
AC_DEFINE_UNQUOTED(RESOLVCONF_PATH, "$with_resolvconf", [Path to resolvconf])
@@ -782,6 +810,8 @@ fi
if test "$with_netconfig" != "no"; then
AC_DEFINE_UNQUOTED(NETCONFIG_PATH, "$with_netconfig", [Path to netconfig])
fi
+AC_DEFINE_UNQUOTED(NM_CONFIG_DEFAULT_DNS_RC_MANAGER, "$config_dns_rc_manager_default", [Default value for main.rc-manager setting (--with-config-dns-rc-manager-default)])
+AC_SUBST(NM_CONFIG_DEFAULT_DNS_RC_MANAGER, $config_dns_rc_manager_default)
# iptables path
AC_ARG_WITH(iptables, AS_HELP_STRING([--with-iptables=/path/to/iptables], [path to iptables]))
@@ -919,6 +949,16 @@ else
enable_lto='no'
fi
+AC_ARG_ENABLE(ld-gc, AS_HELP_STRING([--enable-ld-gc], [Enable garbage collection of unused symbols on linking (default: auto)]))
+if (test "${enable_ld_gc}" != "no"); then
+ NM_COMPILER_FLAG([-fdata-sections -ffunction-sections -Wl,--gc-sections], [enable_ld_gc='yes'], [
+ if (test "${enable_ld_gc}" = "yes"); then
+ AC_MSG_ERROR([Unused symbol eviction requested but not supported.])
+ else
+ enable_ld_gc='no'
+ fi
+ ])
+fi
dnl -------------------------
dnl Vala bindings
@@ -1164,6 +1204,7 @@ echo
echo "Handlers for /etc/resolv.conf:"
echo " resolvconf: ${with_resolvconf}"
echo " netconfig: ${with_netconfig}"
+echo " config-dns-rc-manager-default: ${config_dns_rc_manager_default}"
echo
echo "DHCP clients:"
@@ -1178,4 +1219,6 @@ echo " more-asserts: $more_asserts"
echo " valgrind: $with_valgrind $with_valgrind_suppressions"
echo " code coverage: $enable_code_coverage"
echo " LTO: $enable_lto"
+echo " linker garbage collection: $enable_ld_gc"
+echo " JSON validation: $enable_json_validation"
echo
diff --git a/contrib/fedora/REQUIRED_PACKAGES b/contrib/fedora/REQUIRED_PACKAGES
index 559ac848f6..5a4b42863c 100644
--- a/contrib/fedora/REQUIRED_PACKAGES
+++ b/contrib/fedora/REQUIRED_PACKAGES
@@ -42,4 +42,10 @@ yum install \
rpm-build \
perl-YAML-LibYAM \
perl-YAML \
+ audit-libs-devel \
+ bluez-libs-devel \
+ dbus-python \
+ libselinux-devel \
+ pygobject3-base \
+ jansson-devel \
diff --git a/contrib/fedora/rpm/NetworkManager.spec b/contrib/fedora/rpm/NetworkManager.spec
index 1f40e01a5f..8a25690efe 100644
--- a/contrib/fedora/rpm/NetworkManager.spec
+++ b/contrib/fedora/rpm/NetworkManager.spec
@@ -30,7 +30,14 @@
%global _hardened_build 1
-%global git_sha_version %{?git_sha:.%{git_sha}}
+%if x%{?snapshot} != x
+%global snapshot_dot .%{snapshot}
+%endif
+%if x%{?git_sha} != x
+%global git_sha_dot .%{git_sha}
+%endif
+
+%global snap %{?git_sha_dot}%{?snapshot_dot}
###############################################################################
@@ -89,7 +96,7 @@ Name: NetworkManager
Summary: Network connection manager and user applications
Epoch: %{epoch_version}
Version: %{rpm_version}
-Release: %{release_version}%{snapshot}%{git_sha_version}%{?dist}
+Release: %{release_version}%{?snap}%{?dist}
Group: System Environment/Base
License: GPLv2+
URL: http://www.gnome.org/projects/NetworkManager/
@@ -169,6 +176,7 @@ BuildRequires: pygobject3-base
BuildRequires: dbus-python
BuildRequires: libselinux-devel
BuildRequires: polkit-devel
+BuildRequires: jansson-devel
%description
@@ -324,6 +332,18 @@ ethernet devices with no carrier.
This package is intended to be installed by default for server
deployments.
+%package dispatcher-routing-rules
+Summary: NetworkManager dispatcher file for advanced routing rules
+Group: System Environment/Base
+BuildArch: noarch
+Provides: %{name}-config-routing-rules = %{epoch}:%{version}-%{release}
+Obsoletes: %{name}-config-routing-rules < %{epoch}:%{version}-%{release}
+
+%description dispatcher-routing-rules
+This adds a NetworkManager dispatcher file to support networking
+configurations using "/etc/sysconfig/network-scripts/rule-NAME" files
+(eg, to do policy-based routing).
+
%if 0%{with_nmtui}
%package tui
Summary: NetworkManager curses-based UI
@@ -498,12 +518,9 @@ fi
%{_datadir}/bash-completion/completions/nmcli
%dir %{_sysconfdir}/%{name}/
%dir %{_sysconfdir}/%{name}/dispatcher.d
-%{_sysconfdir}/%{name}/dispatcher.d/10-ifcfg-rh-routes.sh
%dir %{_sysconfdir}/%{name}/dispatcher.d/pre-down.d
%dir %{_sysconfdir}/%{name}/dispatcher.d/pre-up.d
%dir %{_sysconfdir}/%{name}/dispatcher.d/no-wait.d
-%{_sysconfdir}/%{name}/dispatcher.d/no-wait.d/10-ifcfg-rh-routes.sh
-%{_sysconfdir}/%{name}/dispatcher.d/pre-up.d/10-ifcfg-rh-routes.sh
%dir %{_sysconfdir}/%{name}/dnsmasq.d
%dir %{_sysconfdir}/%{name}/dnsmasq-shared.d
%dir %{_sysconfdir}/%{name}/VPN
@@ -633,6 +650,11 @@ fi
%dir %{nmlibdir}/conf.d
%{nmlibdir}/conf.d/00-server.conf
+%files dispatcher-routing-rules
+%{_sysconfdir}/%{name}/dispatcher.d/10-ifcfg-rh-routes.sh
+%{_sysconfdir}/%{name}/dispatcher.d/no-wait.d/10-ifcfg-rh-routes.sh
+%{_sysconfdir}/%{name}/dispatcher.d/pre-up.d/10-ifcfg-rh-routes.sh
+
%if %{with nmtui}
%files tui
%{_bindir}/nmtui
diff --git a/contrib/fedora/rpm/build.sh b/contrib/fedora/rpm/build.sh
index 6da1ade3c1..35336bad15 100755
--- a/contrib/fedora/rpm/build.sh
+++ b/contrib/fedora/rpm/build.sh
@@ -70,7 +70,7 @@ get_version() {
write_changelog() {
if [[ "x$CHANGELOG" == x ]]; then
cat <<- EOF
- * $(LC_TIME=C date '+%a %b %d %Y') $USERNAME - %{epoch_version}:%{version}-%{release_version}%{snapshot}%{git_sha_version}
+ * $(LC_TIME=C date '+%a %b %d %Y') $USERNAME - %{epoch_version}:%{version}-%{release_version}%{?snap}
- build of NetworkManager ($DATE, uuid: $UUID, git: $COMMIT_FULL)
$(git log -n20 --date=local --format='- %h %s [%an] (%ci)')
- ...
@@ -163,6 +163,7 @@ sed -e "s/__VERSION__/$VERSION/g" \
-e "s/__RELEASE_VERSION__/$RELEASE_VERSION/g" \
-e "s/__COMMIT__/$COMMIT/g" \
-e "s/__COMMIT_FULL__/$COMMIT_FULL/g" \
+ -e "s/__SNAPSHOT__/$SNAPSHOT/g" \
-e "s/__SOURCE1__/$(basename "$SOURCE")/g" \
"$SPECFILE" |
sed -e "/^__CHANGELOG__$/ \
diff --git a/introspection/nm-device-team.xml b/introspection/nm-device-team.xml
index 05bbbafe46..64faaec4b0 100644
--- a/introspection/nm-device-team.xml
+++ b/introspection/nm-device-team.xml
@@ -26,6 +26,13 @@
<property name="Slaves" type="ao" access="read"/>
<!--
+ Config:
+
+ The JSON configuration currently applied on the device.
+ -->
+ <property name="Config" type="s" access="read" />
+
+ <!--
PropertiesChanged:
@properties: A dictionary mapping property names to variant boxed values
-->
diff --git a/introspection/nm-ip4-config.xml b/introspection/nm-ip4-config.xml
index c2a0f06828..bbe7bebeae 100644
--- a/introspection/nm-ip4-config.xml
+++ b/introspection/nm-ip4-config.xml
@@ -77,6 +77,13 @@
<property name="DnsOptions" type="as" access="read"/>
<!--
+ DnsPriority:
+
+ The relative priority of DNS servers.
+ -->
+ <property name="DnsPriority" type="i" access="read"/>
+
+ <!--
WinsServers:
The Windows Internet Name Service servers associated with the connection.
diff --git a/introspection/nm-ip6-config.xml b/introspection/nm-ip6-config.xml
index 606761dd2b..a58bfffa55 100644
--- a/introspection/nm-ip6-config.xml
+++ b/introspection/nm-ip6-config.xml
@@ -77,6 +77,13 @@
<property name="DnsOptions" type="as" access="read"/>
<!--
+ DnsPriority:
+
+ The relative priority of DNS servers.
+ -->
+ <property name="DnsPriority" type="i" access="read"/>
+
+ <!--
PropertiesChanged:
@properties: A dictionary mapping property names to variant boxed values
-->
diff --git a/libnm-core/Makefile.am b/libnm-core/Makefile.am
index 3335720a4a..695b6a3a58 100644
--- a/libnm-core/Makefile.am
+++ b/libnm-core/Makefile.am
@@ -12,9 +12,11 @@ AM_CPPFLAGS = \
-DNMCONFDIR=\"$(nmconfdir)\" \
-DNMLIBDIR=\"$(nmlibdir)\" \
-DNMPLUGINDIR=\"$(pkglibdir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIB \
$(GLIB_CFLAGS) \
- $(CODE_COVERAGE_CFLAGS)
+ $(CODE_COVERAGE_CFLAGS) \
+ $(JANSSON_CFLAGS)
noinst_LTLIBRARIES = libnm-core.la
@@ -36,7 +38,8 @@ GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM
libnm_core_la_LIBADD = \
$(GLIB_LIBS) \
- $(UUID_LIBS)
+ $(UUID_LIBS) \
+ $(JANSSON_LIBS)
libnm_core_la_LDFLAGS = \
$(CODE_COVERAGE_LDFLAGS)
diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c
index 7a0e1f6bda..a823af9bea 100644
--- a/libnm-core/nm-connection.c
+++ b/libnm-core/nm-connection.c
@@ -23,6 +23,7 @@
#include "nm-default.h"
#include <string.h>
+#include <arpa/inet.h>
#include "nm-connection.h"
#include "nm-connection-private.h"
@@ -724,6 +725,7 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters)
const char *default_ip6_method = NULL;
NMSettingIPConfig *s_ip4, *s_ip6;
NMSetting *setting;
+ gboolean changed = FALSE;
if (parameters)
default_ip6_method = g_hash_table_lookup (parameters, NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD);
@@ -756,6 +758,12 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters)
NM_SETTING_IP_CONFIG_METHOD, default_ip4_method,
NULL);
nm_connection_add_setting (self, setting);
+ } else {
+ if ( nm_setting_ip_config_get_gateway (s_ip4)
+ && nm_setting_ip_config_get_never_default (s_ip4)) {
+ g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, NULL, NULL);
+ changed = TRUE;
+ }
}
if (!s_ip6) {
setting = nm_setting_ip6_config_new ();
@@ -765,8 +773,32 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters)
NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
NULL);
nm_connection_add_setting (self, setting);
+ } else {
+ const char *token;
+
+ token = nm_setting_ip6_config_get_token ((NMSettingIP6Config *) s_ip6);
+ if ( token
+ && nm_setting_ip6_config_get_addr_gen_mode ((NMSettingIP6Config *) s_ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) {
+ struct in6_addr i6_token;
+ char normalized[NM_UTILS_INET_ADDRSTRLEN];
+
+ if ( inet_pton (AF_INET6, token, &i6_token) == 1
+ && _nm_utils_inet6_is_token (&i6_token)) {
+ nm_utils_inet6_ntop (&i6_token, normalized);
+ if (g_strcmp0 (token, normalized)) {
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_TOKEN, normalized, NULL);
+ changed = TRUE;
+ }
+ }
+ }
+
+ if ( nm_setting_ip_config_get_gateway (s_ip6)
+ && nm_setting_ip_config_get_never_default (s_ip6)) {
+ g_object_set (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, NULL, NULL);
+ changed = TRUE;
+ }
}
- return !s_ip4 || !s_ip6;
+ return !s_ip4 || !s_ip6 || changed;
}
}
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index 2041a1d3a1..a09ee26c48 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -296,4 +296,8 @@ typedef enum {
NMBondOptionType
_nm_setting_bond_get_option_type (NMSettingBond *setting, const char *name);
+/***********************************************************/
+
+gboolean _nm_utils_inet6_is_token (const struct in6_addr *in6addr);
+
#endif
diff --git a/libnm-core/nm-keyfile-writer.c b/libnm-core/nm-keyfile-writer.c
index 0ce7641c1d..f62e97c3e6 100644
--- a/libnm-core/nm-keyfile-writer.c
+++ b/libnm-core/nm-keyfile-writer.c
@@ -233,16 +233,23 @@ route_writer (KeyfileWriterInfo *info,
write_ip_values (info->keyfile, setting_name, array, NULL, TRUE);
}
+static int
+sort_hash_keys (gconstpointer a, gconstpointer b, gpointer user_data)
+{
+ return g_strcmp0 (*((const char **) a), *((const char **) b));
+}
+
static void
write_hash_of_string (GKeyFile *file,
NMSetting *setting,
const char *key,
const GValue *value)
{
- GHashTableIter iter;
- const char *property = NULL, *data = NULL;
+ GHashTable *hash;
const char *group_name = nm_setting_get_name (setting);
gboolean vpn_secrets = FALSE;
+ gs_free const char **keys = NULL;
+ guint i, l;
/* Write VPN secrets out to a different group to keep them separate */
if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) {
@@ -250,10 +257,19 @@ write_hash_of_string (GKeyFile *file,
vpn_secrets = TRUE;
}
- g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value));
- while (g_hash_table_iter_next (&iter, (gpointer *) &property, (gpointer *) &data)) {
+ hash = g_value_get_boxed (value);
+ keys = (const char **) g_hash_table_get_keys_as_array (hash, &l);
+ if (!keys)
+ return;
+
+ g_qsort_with_data (keys, l, sizeof (const char *), sort_hash_keys, NULL);
+
+ for (i = 0; keys[i]; i++) {
+ const char *property, *data;
gboolean write_item = TRUE;
+ property = keys[i];
+
/* Handle VPN secrets specially; they are nested in the property's hash;
* we don't want to write them if the secret is not saved, not required,
* or owned by a user's secret agent.
@@ -266,8 +282,10 @@ write_hash_of_string (GKeyFile *file,
write_item = FALSE;
}
- if (write_item)
+ if (write_item) {
+ data = g_hash_table_lookup (hash, property);
nm_keyfile_plugin_kf_set_string (file, group_name, property, data);
+ }
}
}
diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c
index 3e7f93b065..bdcbc23b08 100644
--- a/libnm-core/nm-setting-ip-config.c
+++ b/libnm-core/nm-setting-ip-config.c
@@ -1120,6 +1120,7 @@ typedef struct {
GPtrArray *dns; /* array of IP address strings */
GPtrArray *dns_search; /* array of domain name strings */
GPtrArray *dns_options;/* array of DNS options */
+ gint dns_priority;
GPtrArray *addresses; /* array of NMIPAddress */
GPtrArray *routes; /* array of NMIPRoute */
gint64 route_metric;
@@ -1140,6 +1141,7 @@ enum {
PROP_DNS,
PROP_DNS_SEARCH,
PROP_DNS_OPTIONS,
+ PROP_DNS_PRIORITY,
PROP_ADDRESSES,
PROP_GATEWAY,
PROP_ROUTES,
@@ -1684,6 +1686,22 @@ nm_setting_ip_config_clear_dns_options (NMSettingIPConfig *setting, gboolean is_
}
/**
+ * nm_setting_ip_config_get_dns_priority:
+ * @setting: the #NMSettingIPConfig
+ *
+ * Returns: the priority of DNS servers
+ *
+ * Since: 1.2.4
+ **/
+gint
+nm_setting_ip_config_get_dns_priority (NMSettingIPConfig *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0);
+
+ return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dns_priority;
+}
+
+/**
* nm_setting_ip_config_get_num_addresses:
* @setting: the #NMSettingIPConfig
*
@@ -2274,6 +2292,16 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
}
+ if (priv->gateway && priv->never_default) {
+ g_set_error (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ _("a gateway is incompatible with '%s'"),
+ NM_SETTING_IP_CONFIG_NEVER_DEFAULT);
+ g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_GATEWAY);
+ return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
+ }
+
return TRUE;
}
@@ -2352,6 +2380,9 @@ set_property (GObject *object, guint prop_id,
}
}
break;
+ case PROP_DNS_PRIORITY:
+ priv->dns_priority = g_value_get_int (value);
+ break;
case PROP_ADDRESSES:
g_ptr_array_unref (priv->addresses);
priv->addresses = _nm_utils_copy_array (g_value_get_boxed (value),
@@ -2424,6 +2455,9 @@ get_property (GObject *object, guint prop_id,
case PROP_DNS_OPTIONS:
g_value_take_boxed (value, priv->dns_options ? _nm_utils_ptrarray_to_strv (priv->dns_options) : NULL);
break;
+ case PROP_DNS_PRIORITY:
+ g_value_set_int (value, priv->dns_priority);
+ break;
case PROP_ADDRESSES:
g_value_take_boxed (value, _nm_utils_copy_array (priv->addresses,
(NMUtilsCopyFunc) nm_ip_address_dup,
@@ -2576,6 +2610,34 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class)
G_PARAM_STATIC_STRINGS));
/**
+ * NMSettingIPConfig:dns-priority:
+ *
+ * DNS priority.
+ *
+ * The relative priority to be used when determining the order of DNS
+ * servers in resolv.conf. A lower value means that servers will be on top
+ * of the file. Zero selects the default value, which is 50 for VPNs and
+ * 100 for other connections. When multiple devices have configurations
+ * with the same priority, the one with an active default route will be
+ * preferred. Note that when using dns=dnsmasq the order is meaningless
+ * since dnsmasq forwards queries to all known servers at the same time.
+ *
+ * Negative values have the special effect of excluding other configurations
+ * with a greater priority value; so in presence of at least a negative
+ * priority, only DNS servers from configurations with the lowest priority
+ * value will be used.
+ *
+ * Since: 1.2.4
+ **/
+ g_object_class_install_property
+ (object_class, PROP_DNS_PRIORITY,
+ g_param_spec_int (NM_SETTING_IP_CONFIG_DNS_PRIORITY, "", "",
+ G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
* NMSettingIPConfig:addresses:
*
* Array of IP addresses.
diff --git a/libnm-core/nm-setting-ip-config.h b/libnm-core/nm-setting-ip-config.h
index 79c7e63921..a41c5466c8 100644
--- a/libnm-core/nm-setting-ip-config.h
+++ b/libnm-core/nm-setting-ip-config.h
@@ -136,6 +136,7 @@ void nm_ip_route_set_attribute (NMIPRoute *route,
#define NM_SETTING_IP_CONFIG_DNS "dns"
#define NM_SETTING_IP_CONFIG_DNS_SEARCH "dns-search"
#define NM_SETTING_IP_CONFIG_DNS_OPTIONS "dns-options"
+#define NM_SETTING_IP_CONFIG_DNS_PRIORITY "dns-priority"
#define NM_SETTING_IP_CONFIG_ADDRESSES "addresses"
#define NM_SETTING_IP_CONFIG_GATEWAY "gateway"
#define NM_SETTING_IP_CONFIG_ROUTES "routes"
@@ -219,6 +220,9 @@ gboolean nm_setting_ip_config_remove_dns_option_by_value (NMSettingIPConfig
const char *dns_option);
void nm_setting_ip_config_clear_dns_options (NMSettingIPConfig *setting, gboolean is_set);
+NM_AVAILABLE_IN_1_2_4
+gint nm_setting_ip_config_get_dns_priority (NMSettingIPConfig *setting);
+
guint nm_setting_ip_config_get_num_addresses (NMSettingIPConfig *setting);
NMIPAddress *nm_setting_ip_config_get_address (NMSettingIPConfig *setting,
int idx);
diff --git a/libnm-core/nm-setting-ip4-config.c b/libnm-core/nm-setting-ip4-config.c
index 9b479a083d..8f43def019 100644
--- a/libnm-core/nm-setting-ip4-config.c
+++ b/libnm-core/nm-setting-ip4-config.c
@@ -654,6 +654,17 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *ip4_class)
* ---end---
*/
+ /* ---ifcfg-rh---
+ * property: dns-priority
+ * variable: IPV4_DNS_PRIORITY(+)
+ * description: The priority for DNS servers of this connection. Lower values have higher priority.
+ * If zero, the default value will be used (50 for VPNs, 100 for other connections).
+ * A negative value prevents DNS from other connections with greater values to be used.
+ * default: 0
+ * example: IPV4_DNS_PRIORITY=20
+ * ---end---
+ */
+
/**
* NMSettingIP4Config:dhcp-client-id:
*
diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c
index 1f0b11fc98..17afcae79e 100644
--- a/libnm-core/nm-setting-ip6-config.c
+++ b/libnm-core/nm-setting-ip6-config.c
@@ -24,6 +24,7 @@
#include "nm-setting-ip6-config.h"
#include <string.h>
+#include <arpa/inet.h>
#include "nm-setting-private.h"
#include "nm-core-enum-types.h"
@@ -59,6 +60,7 @@ NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_IP6_CONFIG)
typedef struct {
NMSettingIP6ConfigPrivacy ip6_privacy;
NMSettingIP6ConfigAddrGenMode addr_gen_mode;
+ char *token;
} NMSettingIP6ConfigPrivate;
@@ -66,6 +68,7 @@ enum {
PROP_0,
PROP_IP6_PRIVACY,
PROP_ADDR_GEN_MODE,
+ PROP_TOKEN,
LAST_PROP
};
@@ -120,6 +123,25 @@ nm_setting_ip6_config_get_addr_gen_mode (NMSettingIP6Config *setting)
return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->addr_gen_mode;
}
+/**
+ * nm_setting_ip6_config_get_token:
+ * @setting: the #NMSettingIP6Config
+ *
+ * Returns the value contained in the #NMSettingIP6Config:token
+ * property.
+ *
+ * Returns: A string.
+ *
+ * Since: 1.2.4
+ **/
+const char *
+nm_setting_ip6_config_get_token (NMSettingIP6Config *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), NULL);
+
+ return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->token;
+}
+
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
@@ -127,6 +149,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting);
NMSettingVerifyResult ret;
const char *method;
+ gboolean token_needs_normalization = FALSE;
ret = NM_SETTING_CLASS (nm_setting_ip6_config_parent_class)->verify (setting, connection, error);
if (ret != NM_SETTING_VERIFY_SUCCESS)
@@ -201,6 +224,44 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return FALSE;
}
+ if (priv->token) {
+ if (priv->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) {
+ struct in6_addr i6_token;
+ char s_token[NM_UTILS_INET_ADDRSTRLEN];
+
+ if ( inet_pton (AF_INET6, priv->token, &i6_token) != 1
+ || !_nm_utils_inet6_is_token (&i6_token)) {
+ g_set_error_literal (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ _("value is not a valid token"));
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_TOKEN);
+ return FALSE;
+ }
+
+ if (g_strcmp0 (priv->token, nm_utils_inet6_ntop (&i6_token, s_token)))
+ token_needs_normalization = TRUE;
+ } else {
+ g_set_error_literal (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ _("only makes sense with EUI64 address generation mode"));
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_TOKEN);
+ return FALSE;
+ }
+ }
+
+ /* Failures from here on, are NORMALIZABLE_ERROR... */
+
+ if (token_needs_normalization) {
+ g_set_error_literal (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ _("token is not in canonical form"));
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_TOKEN);
+ return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
+ }
+
return TRUE;
}
@@ -388,6 +449,10 @@ set_property (GObject *object, guint prop_id,
case PROP_ADDR_GEN_MODE:
priv->addr_gen_mode = g_value_get_int (value);
break;
+ case PROP_TOKEN:
+ g_free (priv->token);
+ priv->token = g_value_dup_string (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -407,6 +472,9 @@ get_property (GObject *object, guint prop_id,
case PROP_ADDR_GEN_MODE:
g_value_set_int (value, priv->addr_gen_mode);
break;
+ case PROP_TOKEN:
+ g_value_set_string (value, priv->token);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -414,6 +482,17 @@ get_property (GObject *object, guint prop_id,
}
static void
+finalize (GObject *object)
+{
+ NMSettingIP6Config *self = NM_SETTING_IP6_CONFIG (object);
+ NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (self);
+
+ g_free (priv->token);
+
+ G_OBJECT_CLASS (nm_setting_ip6_config_parent_class)->finalize (object);
+}
+
+static void
nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (ip6_class);
@@ -424,6 +503,7 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class)
/* virtual methods */
object_class->set_property = set_property;
object_class->get_property = get_property;
+ object_class->finalize = finalize;
setting_class->verify = verify;
/* Properties */
@@ -556,6 +636,17 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class)
* ---end---
*/
+ /* ---ifcfg-rh---
+ * property: dns-priority
+ * variable: IPV6_DNS_PRIORITY(+)
+ * description: The priority for DNS servers of this connection. Lower values have higher priority.
+ * If zero, the default value will be used (50 for VPNs, 100 for other connections).
+ * A negative value prevents DNS from other connections with greater values to be used.
+ * default: 0
+ * example: IPV6_DNS_PRIORITY=20
+ * ---end---
+ */
+
/**
* NMSettingIP6Config:ip6-privacy:
*
@@ -645,6 +736,30 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class)
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
+ /**
+ * NMSettingIP6Config:token:
+ *
+ * Configure the token for draft-chown-6man-tokenised-ipv6-identifiers-02
+ * IPv6 tokenized interface identifiers. Useful with eui64 addr-gen-mode.
+ *
+ * Since: 1.2.4
+ **/
+ /* ---ifcfg-rh---
+ * property: token
+ * variable: IPV6_TOKEN
+ * description: The IPv6 tokenized interface identifier token
+ * example: IPV6_TOKEN=::53
+ * ---end---
+ */
+ g_object_class_install_property
+ (object_class, PROP_TOKEN,
+ g_param_spec_string (NM_SETTING_IP6_CONFIG_TOKEN, "", "",
+ NULL,
+ G_PARAM_READWRITE |
+ NM_SETTING_PARAM_INFERRABLE |
+ G_PARAM_STATIC_STRINGS));
+
+
/* IP6-specific property overrides */
/* ---dbus---
diff --git a/libnm-core/nm-setting-ip6-config.h b/libnm-core/nm-setting-ip6-config.h
index 2966e558cb..f5623b4ae0 100644
--- a/libnm-core/nm-setting-ip6-config.h
+++ b/libnm-core/nm-setting-ip6-config.h
@@ -43,6 +43,8 @@ G_BEGIN_DECLS
#define NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE "addr-gen-mode"
+#define NM_SETTING_IP6_CONFIG_TOKEN "token"
+
/**
* NM_SETTING_IP6_CONFIG_METHOD_IGNORE:
*
@@ -156,6 +158,8 @@ NMSetting *nm_setting_ip6_config_new (void);
NMSettingIP6ConfigPrivacy nm_setting_ip6_config_get_ip6_privacy (NMSettingIP6Config *setting);
NM_AVAILABLE_IN_1_2
NMSettingIP6ConfigAddrGenMode nm_setting_ip6_config_get_addr_gen_mode (NMSettingIP6Config *setting);
+NM_AVAILABLE_IN_1_2_4
+const char *nm_setting_ip6_config_get_token (NMSettingIP6Config *setting);
G_END_DECLS
diff --git a/libnm-core/nm-setting-team-port.c b/libnm-core/nm-setting-team-port.c
index 9671f1d915..8d570c9e1c 100644
--- a/libnm-core/nm-setting-team-port.c
+++ b/libnm-core/nm-setting-team-port.c
@@ -85,6 +85,18 @@ nm_setting_team_port_get_config (NMSettingTeamPort *setting)
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
+ NMSettingTeamPortPrivate *priv = NM_SETTING_TEAM_PORT_GET_PRIVATE (setting);
+
+ if (priv->config) {
+ if (!_nm_utils_check_valid_json (priv->config, error)) {
+ g_prefix_error (error,
+ "%s.%s: ",
+ NM_SETTING_TEAM_PORT_SETTING_NAME,
+ NM_SETTING_TEAM_PORT_CONFIG);
+ return FALSE;
+ }
+ }
+
if (connection) {
NMSettingConnection *s_con;
const char *slave_type;
@@ -116,6 +128,31 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return TRUE;
}
+static gboolean
+compare_property (NMSetting *setting,
+ NMSetting *other,
+ const GParamSpec *prop_spec,
+ NMSettingCompareFlags flags)
+{
+ NMSettingClass *parent_class;
+
+ /* If we are trying to match a connection in order to assume it (and thus
+ * @flags contains INFERRABLE), use the "relaxed" matching for team
+ * configuration. Otherwise, for all other purposes (including connection
+ * comparison before an update), resort to the default string comparison.
+ */
+ if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)
+ && nm_streq0 (prop_spec->name, NM_SETTING_TEAM_PORT_CONFIG)) {
+ return _nm_utils_team_config_equal (NM_SETTING_TEAM_PORT_GET_PRIVATE (setting)->config,
+ NM_SETTING_TEAM_PORT_GET_PRIVATE (other)->config,
+ TRUE);
+ }
+
+ /* Otherwise chain up to parent to handle generic compare */
+ parent_class = NM_SETTING_CLASS (nm_setting_team_port_parent_class);
+ return parent_class->compare_property (setting, other, prop_spec, flags);
+}
+
static void
nm_setting_team_port_init (NMSettingTeamPort *setting)
{
@@ -173,10 +210,11 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *setting_class)
g_type_class_add_private (setting_class, sizeof (NMSettingTeamPortPrivate));
/* virtual methods */
- object_class->set_property = set_property;
- object_class->get_property = get_property;
- object_class->finalize = finalize;
- parent_class->verify = verify;
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->finalize = finalize;
+ parent_class->compare_property = compare_property;
+ parent_class->verify = verify;
/* Properties */
/**
diff --git a/libnm-core/nm-setting-team.c b/libnm-core/nm-setting-team.c
index d47b1e72ca..36cd312b6e 100644
--- a/libnm-core/nm-setting-team.c
+++ b/libnm-core/nm-setting-team.c
@@ -27,6 +27,7 @@
#include "nm-utils.h"
#include "nm-utils-private.h"
#include "nm-connection-private.h"
+#include "nm-utils-private.h"
/**
* SECTION:nm-setting-team
@@ -82,7 +83,47 @@ nm_setting_team_get_config (NMSettingTeam *setting)
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
- return _nm_connection_verify_required_interface_name (connection, error);
+ NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting);
+
+ if (!_nm_connection_verify_required_interface_name (connection, error))
+ return FALSE;
+
+ if (priv->config) {
+ if (!_nm_utils_check_valid_json (priv->config, error)) {
+ g_prefix_error (error,
+ "%s.%s: ",
+ NM_SETTING_TEAM_SETTING_NAME,
+ NM_SETTING_TEAM_CONFIG);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean
+compare_property (NMSetting *setting,
+ NMSetting *other,
+ const GParamSpec *prop_spec,
+ NMSettingCompareFlags flags)
+{
+ NMSettingClass *parent_class;
+
+ /* If we are trying to match a connection in order to assume it (and thus
+ * @flags contains INFERRABLE), use the "relaxed" matching for team
+ * configuration. Otherwise, for all other purposes (including connection
+ * comparison before an update), resort to the default string comparison.
+ */
+ if ( NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)
+ && nm_streq0 (prop_spec->name, NM_SETTING_TEAM_CONFIG)) {
+ return _nm_utils_team_config_equal (NM_SETTING_TEAM_GET_PRIVATE (setting)->config,
+ NM_SETTING_TEAM_GET_PRIVATE (other)->config,
+ FALSE);
+ }
+
+ /* Otherwise chain up to parent to handle generic compare */
+ parent_class = NM_SETTING_CLASS (nm_setting_team_parent_class);
+ return parent_class->compare_property (setting, other, prop_spec, flags);
}
static void
@@ -142,10 +183,11 @@ nm_setting_team_class_init (NMSettingTeamClass *setting_class)
g_type_class_add_private (setting_class, sizeof (NMSettingTeamPrivate));
/* virtual methods */
- object_class->set_property = set_property;
- object_class->get_property = get_property;
- object_class->finalize = finalize;
- parent_class->verify = verify;
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->finalize = finalize;
+ parent_class->compare_property = compare_property;
+ parent_class->verify = verify;
/* Properties */
/**
diff --git a/libnm-core/nm-utils-private.h b/libnm-core/nm-utils-private.h
index 68aaaa1c80..611c467d06 100644
--- a/libnm-core/nm-utils-private.h
+++ b/libnm-core/nm-utils-private.h
@@ -31,6 +31,9 @@
gboolean _nm_utils_string_slist_validate (GSList *list,
const char **valid_values);
+gboolean _nm_utils_check_valid_json (const char *json, GError **error);
+gboolean _nm_utils_team_config_equal (const char *conf1, const char *conf2, gboolean port);
+
/* D-Bus transform funcs */
GVariant * _nm_utils_hwaddr_to_dbus (const GValue *prop_value);
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index 1080d9ea20..7a87dc18c4 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -33,6 +33,10 @@
#include <gmodule.h>
#include <sys/stat.h>
+#if WITH_JANSSON
+#include <jansson.h>
+#endif
+
#include "nm-utils-private.h"
#include "nm-setting-private.h"
#include "crypto.h"
@@ -3562,6 +3566,40 @@ nm_utils_ipaddr_valid (int family, const char *ip)
}
/**
+ * nm_utils_iinet6_is_token:
+ * @in6addr: the AF_INET6 address structure
+ *
+ * Checks if only the bottom 64bits of the address are set.
+ *
+ * Return value: %TRUE or %FALSE
+ */
+gboolean
+_nm_utils_inet6_is_token (const struct in6_addr *in6addr)
+{
+ if ( in6addr->s6_addr[0]
+ || in6addr->s6_addr[1]
+ || in6addr->s6_addr[2]
+ || in6addr->s6_addr[3]
+ || in6addr->s6_addr[4]
+ || in6addr->s6_addr[5]
+ || in6addr->s6_addr[6]
+ || in6addr->s6_addr[7])
+ return FALSE;
+
+ if ( in6addr->s6_addr[8]
+ || in6addr->s6_addr[9]
+ || in6addr->s6_addr[10]
+ || in6addr->s6_addr[11]
+ || in6addr->s6_addr[12]
+ || in6addr->s6_addr[13]
+ || in6addr->s6_addr[14]
+ || in6addr->s6_addr[15])
+ return TRUE;
+
+ return FALSE;
+}
+
+/**
* nm_utils_check_virtual_device_compatibility:
* @virtual_type: a virtual connection type
* @other_type: a connection type to test against @virtual_type
@@ -4090,3 +4128,140 @@ const char **nm_utils_enum_get_values (GType type, gint from, gint to)
return (const char **) g_ptr_array_free (array, FALSE);
}
+#if WITH_JANSSON
+gboolean
+_nm_utils_check_valid_json (const char *str, GError **error)
+{
+ json_t *json;
+ json_error_t jerror;
+
+ g_return_val_if_fail (!error || !*error, FALSE);
+
+ if (!str || !str[0]) {
+ g_set_error_literal (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ "value is NULL or empty");
+ return FALSE;
+ }
+
+ json = json_loads (str, 0, &jerror);
+ if (!json) {
+ g_set_error (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ "%s at position %d",
+ jerror.text,
+ jerror.position);
+ return FALSE;
+ }
+
+ json_decref (json);
+ return TRUE;
+}
+
+/* json_object_foreach_safe() is only available since Jansson 2.8,
+ * reimplement it */
+#define _json_object_foreach_safe(object, n, key, value) \
+ for (key = json_object_iter_key (json_object_iter (object)), \
+ n = json_object_iter_next (object, json_object_iter_at (object, key)); \
+ key && (value = json_object_iter_value (json_object_iter_at (object, key))); \
+ key = json_object_iter_key (n), \
+ n = json_object_iter_next (object, json_object_iter_at (object, key)))
+
+gboolean
+_nm_utils_team_config_equal (const char *conf1,
+ const char *conf2,
+ gboolean port_config)
+{
+ json_t *json1 = NULL, *json2 = NULL, *json;
+ gs_free char *dump1 = NULL, *dump2 = NULL;
+ json_t *value, *property;
+ json_error_t jerror;
+ const char *key;
+ gboolean ret;
+ void *tmp;
+ int i;
+
+ if (nm_streq0 (conf1, conf2))
+ return TRUE;
+
+ /* A NULL configuration is equivalent to default value '{}' */
+ json1 = json_loads (conf1 ?: "{}", 0, &jerror);
+ if (json1)
+ json2 = json_loads (conf2 ?: "{}", 0, &jerror);
+
+ if (!json1 || !json2) {
+ ret = FALSE;
+ goto out;
+ }
+
+ /* Some properties are added by teamd when missing from the initial
+ * configuration. Add them with the default value if necessary, depending
+ * on the configuration type.
+ */
+ for (i = 0, json = json1; i < 2; i++, json = json2) {
+ if (port_config) {
+ property = json_object_get (json, "link_watch");
+ if (!property) {
+ property = json_object ();
+ json_object_set_new (property, "name", json_string ("ethtool"));
+ json_object_set_new (json, "link_watch", property);
+ }
+ } else {
+ property = json_object_get (json, "runner");
+ if (!property) {
+ property = json_object ();
+ json_object_set_new (property, "name", json_string ("roundrobin"));
+ json_object_set_new (json, "runner", property);
+ }
+ }
+ }
+
+ /* Only consider a given subset of nodes, others can change depending on
+ * current state */
+ for (i = 0, json = json1; i < 2; i++, json = json2) {
+ _json_object_foreach_safe (json, tmp, key, value) {
+ if (!NM_IN_STRSET (key, "runner", "link_watch"))
+ json_object_del (json, key);
+ }
+ }
+
+ dump1 = json_dumps (json1, JSON_INDENT(0) | JSON_ENSURE_ASCII | JSON_SORT_KEYS);
+ dump2 = json_dumps (json2, JSON_INDENT(0) | JSON_ENSURE_ASCII | JSON_SORT_KEYS);
+
+ ret = nm_streq0 (dump1, dump2);
+out:
+
+ if (json1)
+ json_decref (json1);
+ if (json2)
+ json_decref (json2);
+
+ return ret;
+}
+
+#else /* WITH_JANSSON */
+
+gboolean
+_nm_utils_check_valid_json (const char *str, GError **error)
+{
+ if (!str || !str[0]) {
+ g_set_error_literal (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ "value is NULL or empty");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+_nm_utils_team_config_equal (const char *conf1,
+ const char *conf2,
+ gboolean port_config)
+{
+ return nm_streq0 (conf1, conf2);
+}
+#endif
diff --git a/libnm-core/nm-version.h b/libnm-core/nm-version.h
index d7f112bf93..95131f9e87 100644
--- a/libnm-core/nm-version.h
+++ b/libnm-core/nm-version.h
@@ -90,18 +90,10 @@
# define NM_AVAILABLE_IN_1_2
#endif
-#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_4
-# define NM_DEPRECATED_IN_1_4 G_DEPRECATED
-# define NM_DEPRECATED_IN_1_4_FOR(f) G_DEPRECATED_FOR(f)
+#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_2_4
+# define NM_AVAILABLE_IN_1_2_4 G_UNAVAILABLE(1,4)
#else
-# define NM_DEPRECATED_IN_1_4
-# define NM_DEPRECATED_IN_1_4_FOR(f)
-#endif
-
-#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_4
-# define NM_AVAILABLE_IN_1_4 G_UNAVAILABLE(1,4)
-#else
-# define NM_AVAILABLE_IN_1_4
+# define NM_AVAILABLE_IN_1_2_4
#endif
#endif /* NM_VERSION_H */
diff --git a/libnm-core/nm-vpn-editor-plugin.c b/libnm-core/nm-vpn-editor-plugin.c
index 6c78c20983..d0539b045b 100644
--- a/libnm-core/nm-vpn-editor-plugin.c
+++ b/libnm-core/nm-vpn-editor-plugin.c
@@ -25,6 +25,7 @@
#include "nm-vpn-editor-plugin.h"
#include <dlfcn.h>
+#include <gmodule.h>
#include "nm-core-internal.h"
@@ -232,7 +233,8 @@ _nm_vpn_editor_plugin_load (const char *plugin_name,
* If @plugin_name is not an absolute path name, it assumes the file
* is in the plugin directory of NetworkManager. In any case, the call
* will do certain checks on the file before passing it to dlopen.
- * A consequence for that is, that you cannot omit the ".so" suffix.
+ * A consequence for that is, that you cannot omit the ".so" suffix
+ * as you could for nm_vpn_editor_plugin_load().
*
* Returns: (transfer full): a new plugin instance or %NULL on error.
*
@@ -255,6 +257,42 @@ nm_vpn_editor_plugin_load_from_file (const char *plugin_name,
error);
}
+/**
+ * nm_vpn_editor_plugin_load:
+ * @plugin_name: The name of the shared library to load.
+ * This path will be directly passed to dlopen() without
+ * further checks.
+ * @check_service: if not-null, check that the loaded plugin advertises
+ * the given service.
+ * @error: on failure the error reason.
+ *
+ * Load the shared libary @plugin_name and create a new
+ * #NMVpnEditorPlugin instace via the #NMVpnEditorPluginFactory
+ * function.
+ *
+ * This is similar to nm_vpn_editor_plugin_load_from_file(), but
+ * it does no validation of the plugin name, instead passes it directly
+ * to dlopen(). If you have the full path to a plugin file,
+ * nm_vpn_editor_plugin_load_from_file() is preferred.
+ *
+ * Returns: (transfer full): a new plugin instance or %NULL on error.
+ *
+ * Since: 1.2.4
+ */
+NMVpnEditorPlugin *
+nm_vpn_editor_plugin_load (const char *plugin_name,
+ const char *check_service,
+ GError **error)
+{
+ return _nm_vpn_editor_plugin_load (plugin_name,
+ FALSE,
+ check_service,
+ -1,
+ NULL,
+ NULL,
+ error);
+}
+
/*********************************************************************/
/**
diff --git a/libnm-core/nm-vpn-editor-plugin.h b/libnm-core/nm-vpn-editor-plugin.h
index 9ff23a8134..62d09cc758 100644
--- a/libnm-core/nm-vpn-editor-plugin.h
+++ b/libnm-core/nm-vpn-editor-plugin.h
@@ -147,6 +147,11 @@ NMVpnEditorPlugin *nm_vpn_editor_plugin_load_from_file (const char *plugin_name
gpointer user_data,
GError **error);
+NM_AVAILABLE_IN_1_2_4
+NMVpnEditorPlugin *nm_vpn_editor_plugin_load (const char *plugin_name,
+ const char *check_service,
+ GError **error);
+
G_END_DECLS
#endif /* __NM_VPN_EDITOR_PLUGIN_H__ */
diff --git a/libnm-core/nm-vpn-plugin-info.c b/libnm-core/nm-vpn-plugin-info.c
index 2e6275e341..3e63f1bd29 100644
--- a/libnm-core/nm-vpn-plugin-info.c
+++ b/libnm-core/nm-vpn-plugin-info.c
@@ -45,6 +45,7 @@ typedef struct {
char *filename;
char *name;
char *service;
+ char *auth_dialog;
char **aliases;
GKeyFile *keyfile;
@@ -188,6 +189,23 @@ _sort_files (LoadDirInfo *a, LoadDirInfo *b)
nm_vpn_plugin_info_get_filename (b->plugin_info));
}
+#define DEFINE_DEFAULT_DIR_LIST(dir) \
+ const char *dir[] = { \
+ /* We load plugins from NM_VPN_PLUGIN_DIR *and* DEFAULT_DIR*, with
+ * preference to the former.
+ *
+ * load user directory with highest priority. */ \
+ _nm_vpn_plugin_info_get_default_dir_user (), \
+ \
+ /* lib directory has higher priority then etc. The reason is that
+ * etc is deprecated and used by old plugins. We expect newer plugins
+ * to install their file in lib, where they have higher priority.
+ *
+ * Optimally, there are no duplicates anyway, so it doesn't really matter. */ \
+ _nm_vpn_plugin_info_get_default_dir_lib (), \
+ _nm_vpn_plugin_info_get_default_dir_etc (), \
+ }
+
/**
* _nm_vpn_plugin_info_get_default_dir_etc:
*
@@ -253,7 +271,10 @@ _nm_vpn_plugin_info_list_load_dir (const char *dirname,
GSList *res = NULL;
guint i;
- g_return_val_if_fail (dirname && dirname[0], NULL);
+ g_return_val_if_fail (dirname, NULL);
+
+ if (!dirname[0])
+ return NULL;
dir = g_dir_open (dirname, 0, NULL);
if (!dir)
@@ -312,21 +333,7 @@ nm_vpn_plugin_info_list_load ()
gint64 uid;
GSList *list = NULL;
GSList *infos, *info;
- const char *dir[] = {
- /* We load plugins from NM_VPN_PLUGIN_DIR *and* DEFAULT_DIR*, with
- * preference to the former.
- *
- * load user directory with highest priority. */
- _nm_vpn_plugin_info_get_default_dir_user (),
-
- /* lib directory has higher priority then etc. The reason is that
- * etc is deprecated and used by old plugins. We expect newer plugins
- * to install their file in lib, where they have higher priority.
- *
- * Optimally, there are no duplicates anyway, so it doesn't really matter. */
- _nm_vpn_plugin_info_get_default_dir_lib (),
- _nm_vpn_plugin_info_get_default_dir_etc (),
- };
+ DEFINE_DEFAULT_DIR_LIST (dir);
uid = getuid ();
@@ -345,6 +352,66 @@ nm_vpn_plugin_info_list_load ()
return list;
}
+/**
+ * nm_vpn_plugin_info_new_search_file:
+ * @name: (allow-none): the name to search for. Either @name or @service
+ * must be present.
+ * @service: (allow-none): the service to search for. Either @name or
+ * @service must be present.
+ *
+ * This has the same effect as doing a full nm_vpn_plugin_info_list_load()
+ * followed by a search for the first matching VPN plugin info that has the
+ * given @name and/or @service.
+ *
+ * Returns: (transfer full): a newly created instance of plugin info
+ * or %NULL if no matching value was found.
+ *
+ * Since: 1.2.4
+ */
+NMVpnPluginInfo *
+nm_vpn_plugin_info_new_search_file (const char *name, const char *service)
+{
+ int i;
+ gint64 uid;
+ NMVpnPluginInfo *plugin_info = NULL;
+ GSList *infos, *info;
+ DEFINE_DEFAULT_DIR_LIST (dir);
+
+ if (!name && !service)
+ g_return_val_if_reached (NULL);
+
+ uid = getuid ();
+
+ for (i = 0; !plugin_info && i < G_N_ELEMENTS (dir); i++) {
+ if ( !dir[i]
+ || _nm_utils_strv_find_first ((char **) dir, i, dir[i]) >= 0)
+ continue;
+
+ /* We still must load the entire directory while searching for the matching
+ * plugin-info. The reason is that reading the directory has no stable
+ * order and we can only sort them after reading the entire directory --
+ * which _nm_vpn_plugin_info_list_load_dir() does. */
+ infos = _nm_vpn_plugin_info_list_load_dir (dir[i], TRUE, uid, NULL, NULL);
+
+ for (info = infos; info; info = info->next) {
+ NMVpnPluginInfo *p = info->data;
+
+ if (name && !nm_streq (nm_vpn_plugin_info_get_name (p), name))
+ continue;
+ if ( service
+ && !nm_streq (nm_vpn_plugin_info_get_service (p), service)
+ && (_nm_utils_strv_find_first (NM_VPN_PLUGIN_INFO_GET_PRIVATE (p)->aliases,
+ -1, service) < 0))
+ continue;
+ plugin_info = g_object_ref (p);
+ break;
+ }
+
+ g_slist_free_full (infos, g_object_unref);
+ }
+ return plugin_info;
+}
+
/*********************************************************************/
static gboolean
@@ -525,7 +592,7 @@ nm_vpn_plugin_info_list_find_by_service (GSList *list, const char *service)
/* First, consider the primary service name. */
for (iter = list; iter; iter = iter->next) {
- if (strcmp (NM_VPN_PLUGIN_INFO_GET_PRIVATE (iter->data)->service, service) == 0)
+ if (strcmp (nm_vpn_plugin_info_get_service (iter->data), service) == 0)
return iter->data;
}
@@ -576,6 +643,77 @@ nm_vpn_plugin_info_get_name (NMVpnPluginInfo *self)
}
/**
+ * nm_vpn_plugin_info_get_service:
+ * @self: plugin info instance
+ *
+ * Returns: (transfer none): the service. Cannot be %NULL.
+ *
+ * Since: 1.2.4
+ */
+const char *
+nm_vpn_plugin_info_get_service (NMVpnPluginInfo *self)
+{
+ g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL);
+
+ return NM_VPN_PLUGIN_INFO_GET_PRIVATE (self)->service;
+}
+
+/**
+ * nm_vpn_plugin_info_get_auth_dialog:
+ * @self: plugin info instance
+ *
+ * Returns: the absolute path to the auth-dialog helper or %NULL.
+ *
+ * Since: 1.2.4
+ **/
+const char *
+nm_vpn_plugin_info_get_auth_dialog (NMVpnPluginInfo *self)
+{
+ NMVpnPluginInfoPrivate *priv;
+
+ g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL);
+
+ priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (self);
+
+ if (G_UNLIKELY (priv->auth_dialog == NULL)) {
+ const char *s;
+
+ s = g_hash_table_lookup (priv->keys, _nm_utils_strstrdictkey_static (NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME, "auth-dialog"));
+ if (!s || !s[0])
+ priv->auth_dialog = g_strdup ("");
+ else if (g_path_is_absolute (s))
+ priv->auth_dialog = g_strdup (s);
+ else {
+ /* for relative paths, we take the basename and assume it's in LIBEXECDIR. */
+ gs_free char *prog_basename = g_path_get_basename (s);
+
+ priv->auth_dialog = g_build_filename (LIBEXECDIR, prog_basename, NULL);
+ }
+ }
+
+ return priv->auth_dialog[0] ? priv->auth_dialog : NULL;
+}
+
+/**
+ * nm_vpn_plugin_info_supports_hints:
+ * @self: plugin info instance
+ *
+ * Returns: %TRUE if the supports hints for secret requests, otherwise %FALSE
+ *
+ * Since: 1.2.4
+ */
+gboolean
+nm_vpn_plugin_info_supports_hints (NMVpnPluginInfo *self)
+{
+ const char *s;
+
+ g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), FALSE);
+
+ s = nm_vpn_plugin_info_lookup_property (self, NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME, "supports-hints");
+ return _nm_utils_ascii_str_to_bool (s, FALSE);
+}
+
+/**
* nm_vpn_plugin_info_get_plugin:
* @self: plugin info instance
*
@@ -753,7 +891,7 @@ nm_vpn_plugin_info_load_editor_plugin (NMVpnPluginInfo *self, GError **error)
priv->editor_plugin_loaded = TRUE;
priv->editor_plugin = nm_vpn_editor_plugin_load_from_file (plugin_filename,
- priv->service,
+ nm_vpn_plugin_info_get_service (self),
getuid (),
NULL,
NULL,
@@ -947,6 +1085,7 @@ finalize (GObject *object)
g_free (priv->name);
g_free (priv->service);
+ g_free (priv->auth_dialog);
g_strfreev (priv->aliases);
g_free (priv->filename);
g_hash_table_unref (priv->keys);
diff --git a/libnm-core/nm-vpn-plugin-info.h b/libnm-core/nm-vpn-plugin-info.h
index c7fef8574a..fce07e6d1b 100644
--- a/libnm-core/nm-vpn-plugin-info.h
+++ b/libnm-core/nm-vpn-plugin-info.h
@@ -73,14 +73,24 @@ NMVpnPluginInfo *nm_vpn_plugin_info_new_with_data (const char *filename,
GKeyFile *keyfile,
GError **error);
+NM_AVAILABLE_IN_1_2_4
+NMVpnPluginInfo *nm_vpn_plugin_info_new_search_file (const char *name,
+ const char *service);
+
NM_AVAILABLE_IN_1_2
const char *nm_vpn_plugin_info_get_name (NMVpnPluginInfo *self);
NM_AVAILABLE_IN_1_2
const char *nm_vpn_plugin_info_get_filename (NMVpnPluginInfo *self);
+NM_AVAILABLE_IN_1_2_4
+const char *nm_vpn_plugin_info_get_service (NMVpnPluginInfo *self);
NM_AVAILABLE_IN_1_2
const char *nm_vpn_plugin_info_get_plugin (NMVpnPluginInfo *self);
NM_AVAILABLE_IN_1_2
const char *nm_vpn_plugin_info_get_program (NMVpnPluginInfo *self);
+NM_AVAILABLE_IN_1_2_4
+const char *nm_vpn_plugin_info_get_auth_dialog (NMVpnPluginInfo *self);
+NM_AVAILABLE_IN_1_2_4
+gboolean nm_vpn_plugin_info_supports_hints (NMVpnPluginInfo *self);
NM_AVAILABLE_IN_1_2
gboolean nm_vpn_plugin_info_supports_multiple (NMVpnPluginInfo *self);
NM_AVAILABLE_IN_1_2
diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c
index dcbcb88021..c80f55893f 100644
--- a/libnm-core/tests/test-general.c
+++ b/libnm-core/tests/test-general.c
@@ -1968,6 +1968,7 @@ test_connection_diff_a_only (void)
{ NM_SETTING_IP_CONFIG_NEVER_DEFAULT, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_MAY_FAIL, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_DAD_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A },
+ { NM_SETTING_IP_CONFIG_DNS_PRIORITY, NM_SETTING_DIFF_RESULT_IN_A },
{ NULL, NM_SETTING_DIFF_RESULT_UNKNOWN },
} },
};
@@ -3717,6 +3718,57 @@ test_connection_normalize_infiniband_mtu (void)
}
static void
+test_connection_normalize_gateway_never_default (void)
+{
+ gs_unref_object NMConnection *con = NULL;
+ NMSettingIPConfig *s_ip4, *s_ip6;
+ NMIPAddress *addr;
+ gs_free_error GError *error = NULL;
+
+ con = nmtst_create_minimal_connection ("test1", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL);
+ nmtst_assert_connection_verifies_and_normalizable (con);
+
+ s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new ();
+ g_object_set (G_OBJECT (s_ip4),
+ NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
+ NULL);
+
+ addr = nm_ip_address_new (AF_INET, "1.1.1.1", 24, &error);
+ g_assert_no_error (error);
+ nm_setting_ip_config_add_address (s_ip4, addr);
+ nm_ip_address_unref (addr);
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.254",
+ NM_SETTING_IP_CONFIG_NEVER_DEFAULT, FALSE,
+ NULL);
+
+ s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new ();
+ g_object_set (s_ip6,
+ NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
+ NULL);
+
+ nm_connection_add_setting (con, (NMSetting *) s_ip4);
+ nm_connection_add_setting (con, (NMSetting *) s_ip6);
+
+ nmtst_assert_connection_verifies_without_normalization (con);
+ g_assert_cmpstr ("1.1.1.254", ==, nm_setting_ip_config_get_gateway (s_ip4));
+
+ /* Now set never-default to TRUE and check that the gateway is
+ * removed during normalization
+ * */
+ g_object_set (s_ip4,
+ NM_SETTING_IP_CONFIG_NEVER_DEFAULT, TRUE,
+ NULL);
+
+ nmtst_assert_connection_verifies_after_normalization (con,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY);
+ nmtst_connection_normalize (con);
+ g_assert_cmpstr (NULL, ==, nm_setting_ip_config_get_gateway (s_ip4));
+}
+
+static void
test_setting_ip4_gateway (void)
{
NMConnection *conn;
@@ -4382,6 +4434,110 @@ test_nm_utils_dns_option_find_idx (void)
/******************************************************************************/
+static void
+_json_config_check_valid (const char *conf, gboolean expected)
+{
+ GError *error = NULL;
+ gboolean res;
+
+ res = _nm_utils_check_valid_json (conf, &error);
+ g_assert_cmpint (res, ==, expected);
+ g_assert (res || error);
+}
+
+static void
+test_nm_utils_check_valid_json (void)
+{
+ _json_config_check_valid (NULL, FALSE);
+ _json_config_check_valid ("", FALSE);
+#if WITH_JANSSON
+ _json_config_check_valid ("{ }", TRUE);
+ _json_config_check_valid ("{ \"a\" : 1 }", TRUE);
+ _json_config_check_valid ("{ \"a\" : }", FALSE);
+#else
+ /* Without JSON library everything except empty string is considered valid */
+ _json_config_check_valid ("{ }", TRUE);
+ _json_config_check_valid ("{'%!-a1", TRUE);
+#endif
+}
+
+static void
+_team_config_equal_check (const char *conf1,
+ const char *conf2,
+ gboolean port_config,
+ gboolean expected)
+{
+ g_assert_cmpint (_nm_utils_team_config_equal (conf1, conf2, port_config), ==, expected);
+}
+
+static void
+test_nm_utils_team_config_equal (void)
+{
+#if WITH_JANSSON
+ _team_config_equal_check ("", "", TRUE, TRUE);
+ _team_config_equal_check ("{}",
+ "{ }",
+ TRUE,
+ TRUE);
+ _team_config_equal_check ("{}",
+ "{",
+ TRUE,
+ FALSE);
+
+ /* team config */
+ _team_config_equal_check ("{ }",
+ "{ \"runner\" : { \"name\" : \"roundrobin\"} }",
+ FALSE,
+ TRUE);
+ _team_config_equal_check ("{ }",
+ "{ \"runner\" : { \"name\" : \"random\"} }",
+ FALSE,
+ FALSE);
+ _team_config_equal_check ("{ \"runner\" : { \"name\" : \"roundrobin\"} }",
+ "{ \"runner\" : { \"name\" : \"random\"} }",
+ FALSE,
+ FALSE);
+ _team_config_equal_check ("{ \"runner\" : { \"name\" : \"random\"} }",
+ "{ \"runner\" : { \"name\" : \"random\"} }",
+ FALSE,
+ TRUE);
+ _team_config_equal_check ("{ \"runner\" : { \"name\" : \"random\"}, \"ports\" : { \"eth0\" : {} } }",
+ "{ \"runner\" : { \"name\" : \"random\"}, \"ports\" : { \"eth1\" : {} } }",
+ FALSE,
+ TRUE);
+
+ /* team port config */
+ _team_config_equal_check ("{ }",
+ "{ \"link_watch\" : { \"name\" : \"ethtool\"} }",
+ TRUE,
+ TRUE);
+ _team_config_equal_check ("{ }",
+ "{ \"link_watch\" : { \"name\" : \"arp_ping\"} }",
+ TRUE,
+ FALSE);
+ _team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"ethtool\"} }",
+ "{ \"link_watch\" : { \"name\" : \"arp_ping\"} }",
+ TRUE,
+ FALSE);
+ _team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"arp_ping\"} }",
+ "{ \"link_watch\" : { \"name\" : \"arp_ping\"} }",
+ TRUE,
+ TRUE);
+ _team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"arp_ping\"}, \"ports\" : { \"eth0\" : {} } }",
+ "{ \"link_watch\" : { \"name\" : \"arp_ping\"}, \"ports\" : { \"eth1\" : {} } }",
+ TRUE,
+ TRUE);
+#else
+ /* Without JSON library, strings are compared for equality */
+ _team_config_equal_check ("", "", TRUE, TRUE);
+ _team_config_equal_check ("", " ", TRUE, FALSE);
+ _team_config_equal_check ("{ \"a\": 1 }", "{ \"a\": 1 }", TRUE, TRUE);
+ _team_config_equal_check ("{ \"a\": 1 }", "{ \"a\": 1 }", TRUE, FALSE);
+#endif
+}
+
+/******************************************************************************/
+
enum TEST_IS_POWER_OF_TWP_ENUM_SIGNED {
_DUMMY_1 = -1,
};
@@ -5010,6 +5166,7 @@ int main (int argc, char **argv)
g_test_add_func ("/core/general/test_connection_normalize_slave_type_1", test_connection_normalize_slave_type_1);
g_test_add_func ("/core/general/test_connection_normalize_slave_type_2", test_connection_normalize_slave_type_2);
g_test_add_func ("/core/general/test_connection_normalize_infiniband_mtu", test_connection_normalize_infiniband_mtu);
+ g_test_add_func ("/core/general/test_connection_normalize_gateway_never_default", test_connection_normalize_gateway_never_default);
g_test_add_func ("/core/general/test_setting_connection_permissions_helpers", test_setting_connection_permissions_helpers);
g_test_add_func ("/core/general/test_setting_connection_permissions_property", test_setting_connection_permissions_property);
@@ -5066,7 +5223,8 @@ int main (int argc, char **argv)
g_test_add_func ("/core/general/_nm_utils_dns_option_validate", test_nm_utils_dns_option_validate);
g_test_add_func ("/core/general/_nm_utils_dns_option_find_idx", test_nm_utils_dns_option_find_idx);
-
+ g_test_add_func ("/core/general/_nm_utils_validate_json", test_nm_utils_check_valid_json);
+ g_test_add_func ("/core/general/_nm_utils_team_config_equal", test_nm_utils_team_config_equal);
g_test_add_func ("/core/general/test_nm_utils_enum", test_nm_utils_enum);
return g_test_run ();
diff --git a/libnm-glib/nm-vpn-plugin.c b/libnm-glib/nm-vpn-plugin.c
index 2af9deb4bd..0534b766e8 100644
--- a/libnm-glib/nm-vpn-plugin.c
+++ b/libnm-glib/nm-vpn-plugin.c
@@ -800,7 +800,7 @@ set_property (GObject *object, guint prop_id,
switch (prop_id) {
case PROP_DBUS_SERVICE_NAME:
/* Construct-only */
- priv->dbus_service_name = g_strdup (g_value_get_string (value));
+ priv->dbus_service_name = g_value_dup_string (value);
break;
case PROP_STATE:
nm_vpn_plugin_set_state (NM_VPN_PLUGIN (object),
diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c
index 990d6fe73b..c0d82b4263 100644
--- a/libnm-util/nm-setting.c
+++ b/libnm-util/nm-setting.c
@@ -1403,7 +1403,7 @@ _nm_setting_verify_deprecated_virtual_iface_name (const char *interface_name,
e_invalid_property,
_("property is invalid"));
g_prefix_error (error, "%s.%s: ", setting_name, setting_property);
- /* we would like to make this a NORMALIZEABLE_ERROR, but that might
+ /* we would like to make this a NORMALIZABLE_ERROR, but that might
* break older connections. */
return NM_SETTING_VERIFY_NORMALIZABLE;
}
diff --git a/libnm-util/nm-version.h b/libnm-util/nm-version.h
index 760151a68f..29f848930d 100644
--- a/libnm-util/nm-version.h
+++ b/libnm-util/nm-version.h
@@ -90,18 +90,10 @@
# define NM_AVAILABLE_IN_1_2
#endif
-#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_4
-# define NM_DEPRECATED_IN_1_4 G_DEPRECATED
-# define NM_DEPRECATED_IN_1_4_FOR(f) G_DEPRECATED_FOR(f)
+#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_2_4
+# define NM_AVAILABLE_IN_1_2_4 G_UNAVAILABLE(1,2,4)
#else
-# define NM_DEPRECATED_IN_1_4
-# define NM_DEPRECATED_IN_1_4_FOR(f)
-#endif
-
-#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_4
-# define NM_AVAILABLE_IN_1_4 G_UNAVAILABLE(1,4)
-#else
-# define NM_AVAILABLE_IN_1_4
+# define NM_AVAILABLE_IN_1_2_4
#endif
#endif /* NM_VERSION_H */
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index 7ece1b2fef..4362cd25c0 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -1058,3 +1058,15 @@ global:
nm_vpn_service_plugin_set_ip6_config;
nm_vpn_service_plugin_set_login_banner;
} libnm_1_0_0;
+
+libnm_1_2_4 {
+global:
+ nm_device_team_get_config;
+ nm_setting_ip6_config_get_token;
+ nm_setting_ip_config_get_dns_priority;
+ nm_vpn_editor_plugin_load;
+ nm_vpn_plugin_info_get_auth_dialog;
+ nm_vpn_plugin_info_get_service;
+ nm_vpn_plugin_info_new_search_file;
+ nm_vpn_plugin_info_supports_hints;
+} libnm_1_2_0;
diff --git a/libnm/nm-device-team.c b/libnm/nm-device-team.c
index b855d5ec38..7fa24f23f9 100644
--- a/libnm/nm-device-team.c
+++ b/libnm/nm-device-team.c
@@ -39,6 +39,7 @@ typedef struct {
char *hw_address;
gboolean carrier;
GPtrArray *slaves;
+ char *config;
} NMDeviceTeamPrivate;
enum {
@@ -46,6 +47,7 @@ enum {
PROP_HW_ADDRESS,
PROP_CARRIER,
PROP_SLAVES,
+ PROP_CONFIG,
LAST_PROP
};
@@ -101,6 +103,25 @@ nm_device_team_get_slaves (NMDeviceTeam *device)
return NM_DEVICE_TEAM_GET_PRIVATE (device)->slaves;
}
+/**
+ * nm_device_team_get_config:
+ * @device: a #NMDeviceTeam
+ *
+ * Gets the current JSON configuration of the #NMDeviceTeam
+ *
+ * Returns: the current configuration. This is the internal string used by the
+ * device, and must not be modified.
+ *
+ * Since: 1.2.4
+ **/
+const char *
+nm_device_team_get_config (NMDeviceTeam *device)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_TEAM (device), NULL);
+
+ return NM_DEVICE_TEAM_GET_PRIVATE (device)->config;
+}
+
static const char *
get_hw_address (NMDevice *device)
{
@@ -150,6 +171,7 @@ init_dbus (NMObject *object)
{ NM_DEVICE_TEAM_HW_ADDRESS, &priv->hw_address },
{ NM_DEVICE_TEAM_CARRIER, &priv->carrier },
{ NM_DEVICE_TEAM_SLAVES, &priv->slaves, NULL, NM_TYPE_DEVICE },
+ { NM_DEVICE_TEAM_CONFIG, &priv->config },
{ NULL },
};
@@ -176,6 +198,7 @@ finalize (GObject *object)
NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (object);
g_free (priv->hw_address);
+ g_free (priv->config);
G_OBJECT_CLASS (nm_device_team_parent_class)->finalize (object);
}
@@ -198,6 +221,9 @@ get_property (GObject *object,
case PROP_SLAVES:
g_value_take_boxed (value, _nm_utils_copy_object_array (nm_device_team_get_slaves (device)));
break;
+ case PROP_CONFIG:
+ g_value_set_string (value, nm_device_team_get_config (device));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -265,4 +291,18 @@ nm_device_team_class_init (NMDeviceTeamClass *team_class)
G_TYPE_PTR_ARRAY,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
+
+ /**
+ * NMDeviceTeam:config:
+ *
+ * The current JSON configuration of the device.
+ *
+ * Since: 1.2.4
+ **/
+ g_object_class_install_property
+ (object_class, PROP_CONFIG,
+ g_param_spec_string (NM_DEVICE_TEAM_CONFIG, "", "",
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
}
diff --git a/libnm/nm-device-team.h b/libnm/nm-device-team.h
index a9b71c6ab0..93cc14e51d 100644
--- a/libnm/nm-device-team.h
+++ b/libnm/nm-device-team.h
@@ -39,6 +39,7 @@ G_BEGIN_DECLS
#define NM_DEVICE_TEAM_HW_ADDRESS "hw-address"
#define NM_DEVICE_TEAM_CARRIER "carrier"
#define NM_DEVICE_TEAM_SLAVES "slaves"
+#define NM_DEVICE_TEAM_CONFIG "config"
/**
* NMDeviceTeam:
@@ -59,6 +60,8 @@ GType nm_device_team_get_type (void);
const char *nm_device_team_get_hw_address (NMDeviceTeam *device);
gboolean nm_device_team_get_carrier (NMDeviceTeam *device);
const GPtrArray *nm_device_team_get_slaves (NMDeviceTeam *device);
+NM_AVAILABLE_IN_1_2_4
+const char *nm_device_team_get_config (NMDeviceTeam *device);
G_END_DECLS
diff --git a/libnm/nm-vpn-editor.h b/libnm/nm-vpn-editor.h
index a11e9fd16d..2ee34525d8 100644
--- a/libnm/nm-vpn-editor.h
+++ b/libnm/nm-vpn-editor.h
@@ -30,7 +30,7 @@
#include <glib-object.h>
#include <nm-types.h>
-#include "nm-vpn-editor-plugin.h"
+#include <nm-vpn-editor-plugin.h>
G_BEGIN_DECLS
diff --git a/m4/compiler_warnings.m4 b/m4/compiler_options.m4
index 77dcc7a50d..3d2e4dbefc 100644
--- a/m4/compiler_warnings.m4
+++ b/m4/compiler_options.m4
@@ -1,17 +1,17 @@
-dnl Check whether a particular compiler flag works with code provided,
-dnl disable it in CFLAGS if the check fails.
-AC_DEFUN([NM_COMPILER_WARNING], [
+AC_DEFUN([_NM_COMPILER_FLAG], [
CFLAGS_SAVED="$CFLAGS"
- CFLAGS="$CFLAGS -Werror -W$1"
- AC_MSG_CHECKING(whether -W$1 works)
+ CFLAGS="$CFLAGS $GLIB_CFLAGS -Werror $1"
+ AC_MSG_CHECKING([whether $1 works as expected])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[]])], [
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[$2]])], [
AC_MSG_RESULT(yes)
- CFLAGS="$CFLAGS_SAVED -W$1"
+ CFLAGS="$CFLAGS_SAVED"
+ $3
],[
AC_MSG_RESULT(no)
- CFLAGS="$CFLAGS_SAVED -Wno-$1"
+ CFLAGS="$CFLAGS_SAVED"
+ $4
])
],[
AC_MSG_RESULT(not supported)
@@ -19,6 +19,21 @@ AC_DEFUN([NM_COMPILER_WARNING], [
])
])
+dnl Check whether a particular compiler flag is supported,
+dnl add it to CFLAGS if it is
+AC_DEFUN([NM_COMPILER_FLAG], [
+ _NM_COMPILER_FLAG([$1], [], [
+ CFLAGS="$CFLAGS $1"
+ $2
+ ], [$3])
+])
+
+dnl Check whether a particular warning is not emitted with code provided,
+dnl disable it in CFLAGS if the check fails.
+AC_DEFUN([NM_COMPILER_WARNING], [
+ _NM_COMPILER_FLAG([-W$1], [$2], [CFLAGS="$CFLAGS -W$1"], [CFLAGS="$CFLAGS -Wno-$1"])
+])
+
AC_DEFUN([NM_COMPILER_WARNINGS],
[AC_ARG_ENABLE(more-warnings,
AS_HELP_STRING([--enable-more-warnings], [Possible values: no/yes/error]),
@@ -40,7 +55,6 @@ if test "$GCC" = "yes" -a "$set_more_warnings" != "no"; then
dnl attach it to the CFLAGS.
NM_COMPILER_WARNING([unknown-warning-option], [])
- CFLAGS_SAVED="$CFLAGS"
CFLAGS_MORE_WARNINGS="-Wall -std=gnu89"
if test "x$set_more_warnings" = xerror; then
@@ -57,22 +71,11 @@ if test "$GCC" = "yes" -a "$set_more_warnings" != "no"; then
-Wpointer-arith -Winit-self \
-Wmissing-include-dirs -Wno-pragmas; do
dnl GCC 4.4 does not warn when checking for -Wno-* flags (https://gcc.gnu.org/wiki/FAQ#wnowarning)
- CFLAGS="-Werror $CFLAGS_MORE_WARNINGS $(printf '%s' "$option" | sed 's/^-Wno-/-W/') $CFLAGS_SAVED"
- AC_MSG_CHECKING([whether compiler understands $option])
- AC_TRY_COMPILE([], [],
- has_option=yes,
- has_option=no,)
- if test $has_option != no; then
- CFLAGS_MORE_WARNINGS="$CFLAGS_MORE_WARNINGS $option"
- fi
- AC_MSG_RESULT($has_option)
- unset has_option
+ _NM_COMPILER_FLAG([$(printf '%s' "$option" | sed 's/^-Wno-/-W/')], [],
+ [CFLAGS_MORE_WARNINGS="$CFLAGS_MORE_WARNINGS $option"], [])
done
unset option
- CFLAGS="$CFLAGS_SAVED"
- unset CFLAGS_SAVED
-
dnl Disable warnings triggered by known compiler problems
dnl https://bugzilla.gnome.org/show_bug.cgi?id=745821
diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml
index 9b53ce993e..fd6d7cef59 100644
--- a/man/NetworkManager.conf.xml
+++ b/man/NetworkManager.conf.xml
@@ -303,7 +303,8 @@ no-auto-default=*
configuration with DNSSEC support. The /etc/resolv.conf
will be managed by dnssec-trigger daemon.</para>
<para><literal>none</literal>: NetworkManager will not
- modify resolv.conf.</para>
+ modify resolv.conf. This implies
+ <literal>rc-manager</literal>&nbsp;<literal>unmanaged</literal></para>
</listitem>
</varlistentry>
@@ -311,17 +312,28 @@ no-auto-default=*
<term><varname>rc-manager</varname></term>
<listitem><para>Set the <filename>resolv.conf</filename>
management mode. The default value depends on how NetworkManager
- was built. Regardless of this setting, NetworkManager will
+ was built, whereas this version of NetworkManager was build with
+ a default of "<literal>&NM_CONFIG_DEFAULT_DNS_RC_MANAGER;</literal>".
+ Regardless of this setting, NetworkManager will
always write resolv.conf to its runtime state directory.</para>
- <para><literal>none</literal>: NetworkManager will symlink
+ <para><literal>symlink</literal>: NetworkManager will symlink
<filename>/etc/resolv.conf</filename> to its private
- resolv.conf file in the runtime state directory.</para>
+ resolv.conf file in the runtime state directory. If
+ <filename>/etc/resolv.conf</filename>
+ already is a symlink pointing to a different location, the file
+ will not be modified. This allows the user to disable managing
+ by pointing the link <filename>/etc/resolv.conf</filename> to
+ somewhere else.</para>
<para><literal>file</literal>: NetworkManager will write
<filename>/etc/resolv.conf</filename> as file.</para>
<para><literal>resolvconf</literal>: NetworkManager will run
resolvconf to update the DNS configuration.</para>
<para><literal>netconfig</literal>: NetworkManager will run
netconfig to update the DNS configuration.</para>
+ <para><literal>unmanaged</literal>: don't touch
+ <filename>/etc/resolv.conf</filename>.</para>
+ <para><literal>none</literal>: deprecated alias for
+ <literal>symlink</literal>.</para>
</listitem>
</varlistentry>
@@ -448,7 +460,7 @@ unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1E:65:30:D1:C4;interface-name:eth
WIFI_SCAN, IP4, IP6, AUTOIP4, DNS, VPN, SHARING, SUPPLICANT,
AGENTS, SETTINGS, SUSPEND, CORE, DEVICE, OLPC, WIMAX,
INFINIBAND, FIREWALL, ADSL, BOND, VLAN, BRIDGE, DBUS_PROPS,
- TEAM, CONCHECK, DCB, DISPATCH, AUDIT.</para>
+ TEAM, CONCHECK, DCB, DISPATCH, AUDIT, SYSTEMD, VPN_PLUGIN.</para>
<para>In addition, these special domains can be used: NONE,
ALL, DEFAULT, DHCP, IP.</para>
<para>You can specify per-domain log level overrides by
@@ -494,6 +506,8 @@ unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1E:65:30:D1:C4;interface-name:eth
<member>DCB : Data Center Bridging (DCB) operations</member>
<member>DISPATCH : Dispatcher scripts</member>
<member>AUDIT : Audit records</member>
+ <member>SYSTEMD : Messages from internal libsystemd</member>
+ <member>VPN_PLUGIN : logging messages from VPN plugins</member>
<member> </member>
<member>NONE : when given by itself logging is disabled</member>
<member>ALL : all log domains</member>
@@ -504,6 +518,12 @@ unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1E:65:30:D1:C4;interface-name:eth
<member>HW : deprecated alias for "PLATFORM"</member>
</simplelist>
</para>
+ <para>
+ In general, the logfile should not contain passwords or private data. However,
+ you are always advised to check the file before posting it online or attaching
+ to a bug report. <literal>VPN_PLUGIN</literal> is special in that it might
+ reveal private information from the VPN plugins and thus this level is excluded
+ from <literal>ALL</literal></para>
</varlistentry>
<varlistentry>
<term><varname>backend</varname></term>
diff --git a/man/NetworkManager.xml b/man/NetworkManager.xml
index 1088cc9c36..4624f0adaa 100644
--- a/man/NetworkManager.xml
+++ b/man/NetworkManager.xml
@@ -475,7 +475,7 @@
<citerefentry><refentrytitle>nm-online</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>nm-settings</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>nm-applet</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>nm-connection-editor</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>nm-connection-editor</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry>
</para>
</refsect1>
diff --git a/man/common.ent.in b/man/common.ent.in
index ae8897eb8a..ec91e8a6a2 100644
--- a/man/common.ent.in
+++ b/man/common.ent.in
@@ -4,3 +4,4 @@
<!ENTITY NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT "@NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@">
<!ENTITY NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT "@NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT@">
<!ENTITY NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT "@NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT@">
+<!ENTITY NM_CONFIG_DEFAULT_DNS_RC_MANAGER "@NM_CONFIG_DEFAULT_DNS_RC_MANAGER@">
diff --git a/po/pt_BR.po b/po/pt_BR.po
index ddb94f223c..3aa989dcb7 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -14,8 +14,8 @@ msgstr ""
"Project-Id-Version: NetworkManager\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
"product=NetworkManager&keywords=I18N+L10N&component=Translations\n"
-"POT-Creation-Date: 2016-05-04 02:03+0000\n"
-"PO-Revision-Date: 2016-05-04 08:14-0300\n"
+"POT-Creation-Date: 2016-05-04 02:01+0000\n"
+"PO-Revision-Date: 2016-05-04 08:11-0300\n"
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
"Language: pt_BR\n"
@@ -1856,7 +1856,7 @@ msgstr "Erro: \"%s\": \"%s\" não é um endereço MAC %s válido."
#. Ask for optional arguments
#: ../clients/cli/connections.c:3037 ../clients/cli/connections.c:3569
-#: ../clients/tui/nm-editor-utils.c:163 ../libnm-core/nm-connection.c:1716
+#: ../clients/tui/nm-editor-utils.c:163 ../libnm-core/nm-connection.c:1729
#: ../libnm-glib/nm-device.c:1861 ../libnm/nm-device.c:1812
msgid "InfiniBand"
msgstr "InfiniBand"
@@ -2043,7 +2043,7 @@ msgstr "Erro: o \"bt-type\": \"%s\" não é um tipo bluetooth válido.\n"
#. 13
#: ../clients/cli/connections.c:3782 ../clients/cli/devices.c:239
#: ../clients/tui/nm-editor-utils.c:217 ../clients/tui/nmt-page-vlan.c:94
-#: ../libnm-core/nm-connection.c:1714 ../libnm-glib/nm-device.c:1869
+#: ../libnm-core/nm-connection.c:1727 ../libnm-glib/nm-device.c:1869
#: ../libnm-util/nm-connection.c:1632 ../libnm/nm-device.c:1820
msgid "VLAN"
msgstr "VLAN"
@@ -4186,6 +4186,42 @@ msgstr "TIPO-ID-PORTA"
#: ../clients/cli/devices.c:283
#, c-format
+#| msgid ""
+#| "Usage: nmcli device { COMMAND | help }\n"
+#| "\n"
+#| "COMMAND := { status | show | connect | reapply | disconnect | delete | "
+#| "monitor | wifi | lldp }\n"
+#| "\n"
+#| " status\n"
+#| "\n"
+#| " show [<ifname>]\n"
+#| "\n"
+#| " set [ifname] <ifname> [autoconnect yes|no] [managed yes|no]\n"
+#| "\n"
+#| " connect <ifname>\n"
+#| "\n"
+#| " reapply <ifname> ...\n"
+#| "\n"
+#| " disconnect <ifname> ...\n"
+#| "\n"
+#| " delete <ifname> ...\n"
+#| "\n"
+#| " monitor <ifname> ...\n"
+#| "\n"
+#| " wifi [list [ifname <ifname>] [bssid <BSSID>]]\n"
+#| "\n"
+#| " wifi connect <(B)SSID> [password <password>] [wep-key-type key|phrase] "
+#| "[ifname <ifname>]\n"
+#| " [bssid <BSSID>] [name <name>] [private yes|no] "
+#| "[hidden yes|no]\n"
+#| "\n"
+#| " wifi hotspot [ifname <ifname>] [con-name <name>] [ssid <SSID>] [band a|"
+#| "bg] [channel <channel>] [password <password>]\n"
+#| "\n"
+#| " wifi rescan [ifname <ifname>] [[ssid <SSID to scan>] ...]\n"
+#| "\n"
+#| " lldp [list [ifname <ifname>]]\n"
+#| "\n"
msgid ""
"Usage: nmcli device { COMMAND | help }\n"
"\n"
@@ -4335,6 +4371,15 @@ msgstr ""
#: ../clients/cli/devices.c:343
#, c-format
+#| msgid ""
+#| "Usage: nmcli device reapply { ARGUMENTS | help }\n"
+#| "\n"
+#| "ARGUMENTS := <ifname> ...\n"
+#| "\n"
+#| "Attempts to update device with changes to the currently active "
+#| "connection\n"
+#| "made since it was last applied.\n"
+#| "\n"
msgid ""
"Usage: nmcli device reapply { ARGUMENTS | help }\n"
"\n"
@@ -4746,6 +4791,7 @@ msgstr "Dispositivo \"%s\" removido com sucesso.\n"
#: ../clients/cli/devices.c:1838
#, c-format
+#| msgid "Error: Reapplying connection to device '%s' (%s) failed: %s\n"
msgid "Error: Reapplying connection to device '%s' (%s) failed: %s"
msgstr "Erro: a reaplicação da conexão no dispositivo \"%s\" (%s) falhou: %s"
@@ -4756,11 +4802,13 @@ msgstr "Conexão reaplicada com sucesso no dispositivo \"%s\".\n"
#: ../clients/cli/devices.c:1885
#, c-format
+#| msgid "Error: Unexpected argument '%s'"
msgid "Error: unsupported argument '%s'."
msgstr "Erro: argumento \"%s\" sem suporte."
#: ../clients/cli/devices.c:1899
#, c-format
+#| msgid "Error: Device '%s' not found."
msgid "Error: device '%s' not found."
msgstr "Erro: dispositivo \"%s\" não localizado."
@@ -6708,9 +6756,9 @@ msgstr "Nome de usuário"
#: ../clients/common/nm-secret-agent-simple.c:492
#: ../clients/common/nm-secret-agent-simple.c:507
#: ../clients/common/nm-secret-agent-simple.c:525
+#: ../clients/common/nm-vpn-helpers.c:100
#: ../clients/common/nm-vpn-helpers.c:101
-#: ../clients/common/nm-vpn-helpers.c:102
-#: ../clients/common/nm-vpn-helpers.c:105 ../clients/tui/nmt-page-dsl.c:75
+#: ../clients/common/nm-vpn-helpers.c:104 ../clients/tui/nmt-page-dsl.c:75
#: ../clients/tui/nmt-page-wifi.c:277 ../clients/tui/nmt-page-wifi.c:308
#: ../clients/tui/nmt-page-wifi.c:341
msgid "Password"
@@ -6789,25 +6837,25 @@ msgstr "Requer uma senha para conectar ao \"%s\"."
msgid "VPN password required"
msgstr "Senha de VPN necessária"
-#: ../clients/common/nm-vpn-helpers.c:61
+#: ../clients/common/nm-vpn-helpers.c:60
msgid "could not get VPN plugin info"
msgstr "não foi possível obter informação de plug-in VPN"
-#: ../clients/common/nm-vpn-helpers.c:103
-#: ../clients/common/nm-vpn-helpers.c:106
+#: ../clients/common/nm-vpn-helpers.c:102
+#: ../clients/common/nm-vpn-helpers.c:105
msgid "Group password"
msgstr "Senha do grupo"
-#: ../clients/common/nm-vpn-helpers.c:108 ../clients/tui/nmt-page-ip4.c:143
+#: ../clients/common/nm-vpn-helpers.c:107 ../clients/tui/nmt-page-ip4.c:143
#: ../clients/tui/nmt-page-ip6.c:143
msgid "Gateway"
msgstr "Gateway"
-#: ../clients/common/nm-vpn-helpers.c:109
+#: ../clients/common/nm-vpn-helpers.c:108
msgid "Cookie"
msgstr "Cookie"
-#: ../clients/common/nm-vpn-helpers.c:110
+#: ../clients/common/nm-vpn-helpers.c:109
msgid "Gateway certificate hash"
msgstr "Hash de certificado do gateway"
@@ -6851,7 +6899,7 @@ msgstr ""
#: ../clients/tui/newt/nmt-newt-utils.c:177 ../clients/tui/nmt-editor.c:415
#: ../clients/tui/nmt-password-dialog.c:174
#: ../clients/tui/nmt-route-editor.c:122 ../clients/tui/nmtui-hostname.c:69
-#: ../clients/tui/nmtui.c:114
+#: ../clients/tui/nmtui.c:136
msgid "OK"
msgstr "OK"
@@ -6915,9 +6963,9 @@ msgstr "DSL"
msgid "DSL connection %d"
msgstr "Conexão DSL %d"
-#: ../clients/tui/nm-editor-utils.c:190 ../libnm-core/nm-connection.c:1708
+#: ../clients/tui/nm-editor-utils.c:190 ../libnm-core/nm-connection.c:1721
#: ../libnm-glib/nm-device.c:1863 ../libnm-util/nm-connection.c:1626
-#: ../libnm/nm-device.c:1814 ../src/settings/plugins/ifcfg-rh/reader.c:4182
+#: ../libnm/nm-device.c:1814 ../src/settings/plugins/ifcfg-rh/reader.c:4187
msgid "Bond"
msgstr "Vínculo"
@@ -6926,9 +6974,9 @@ msgstr "Vínculo"
msgid "Bond connection %d"
msgstr "Conexão vinculada %d"
-#: ../clients/tui/nm-editor-utils.c:199 ../libnm-core/nm-connection.c:1712
+#: ../clients/tui/nm-editor-utils.c:199 ../libnm-core/nm-connection.c:1725
#: ../libnm-glib/nm-device.c:1867 ../libnm-util/nm-connection.c:1630
-#: ../libnm/nm-device.c:1818 ../src/settings/plugins/ifcfg-rh/reader.c:4479
+#: ../libnm/nm-device.c:1818 ../src/settings/plugins/ifcfg-rh/reader.c:4484
msgid "Bridge"
msgstr "Ponte"
@@ -6937,9 +6985,9 @@ msgstr "Ponte"
msgid "Bridge connection %d"
msgstr "Conexão de Ponte %d"
-#: ../clients/tui/nm-editor-utils.c:208 ../libnm-core/nm-connection.c:1710
+#: ../clients/tui/nm-editor-utils.c:208 ../libnm-core/nm-connection.c:1723
#: ../libnm-glib/nm-device.c:1865 ../libnm-util/nm-connection.c:1628
-#: ../libnm/nm-device.c:1816 ../src/settings/plugins/ifcfg-rh/reader.c:4288
+#: ../libnm/nm-device.c:1816 ../src/settings/plugins/ifcfg-rh/reader.c:4293
msgid "Team"
msgstr "União"
@@ -7539,10 +7587,14 @@ msgid "Deactivate"
msgstr "Desativar"
#: ../clients/tui/nmtui-connect.c:413 ../clients/tui/nmtui-edit.c:120
-#: ../clients/tui/nmtui.c:108
+#: ../clients/tui/nmtui.c:130
msgid "Quit"
msgstr "Cancelar"
+#: ../clients/tui/nmtui-connect.c:413 ../clients/tui/nmtui-edit.c:120
+msgid "Back"
+msgstr "Voltar"
+
#: ../clients/tui/nmtui-connect.c:436
#, c-format
msgid "No such connection '%s'"
@@ -7626,28 +7678,28 @@ msgstr "novo nome de máquina"
msgid "Set system hostname"
msgstr "Definir nome de máquina do sistema"
-#: ../clients/tui/nmtui.c:83
+#: ../clients/tui/nmtui.c:104
msgid "NetworkManager TUI"
msgstr "NetworkManager TUI"
-#: ../clients/tui/nmtui.c:91
+#: ../clients/tui/nmtui.c:112
msgid "Please select an option"
msgstr "Por favor selecione uma opção"
-#: ../clients/tui/nmtui.c:143
+#: ../clients/tui/nmtui.c:160
msgid "Usage"
msgstr "Uso"
-#: ../clients/tui/nmtui.c:224
+#: ../clients/tui/nmtui.c:241
msgid "Could not parse arguments"
msgstr "Não foi possível analisar argumentos"
-#: ../clients/tui/nmtui.c:234
+#: ../clients/tui/nmtui.c:251
#, c-format
msgid "Could not contact NetworkManager: %s.\n"
msgstr "Não foi possível contatar o NetworkManager: %s.\n"
-#: ../clients/tui/nmtui.c:239
+#: ../clients/tui/nmtui.c:256
msgid "NetworkManager is not running."
msgstr "NetworkManager não está em execução."
@@ -7949,27 +8001,27 @@ msgstr "nome de definição desconhecido"
msgid "duplicate setting name"
msgstr "nome de definição duplicado"
-#: ../libnm-core/nm-connection.c:873
+#: ../libnm-core/nm-connection.c:886
msgid "setting not found"
msgstr "definição não localizada"
-#: ../libnm-core/nm-connection.c:937
+#: ../libnm-core/nm-connection.c:950
msgid "setting not allowed in slave connection"
msgstr "definição não permitida para conexão escrava"
-#: ../libnm-core/nm-connection.c:948
+#: ../libnm-core/nm-connection.c:961
msgid "setting is required for non-slave connections"
msgstr "definição é exigida para conexões não escravas"
-#: ../libnm-core/nm-connection.c:1042
+#: ../libnm-core/nm-connection.c:1055
msgid "Unexpected failure to verify the connection"
msgstr "Falha inesperada ao verificar a conexão"
-#: ../libnm-core/nm-connection.c:1075
+#: ../libnm-core/nm-connection.c:1088
msgid "Unexpected failure to normalize the connection"
msgstr "Falha inesperada ao normalizar a conexão"
-#: ../libnm-core/nm-connection.c:1576 ../libnm-core/nm-setting-8021x.c:2411
+#: ../libnm-core/nm-connection.c:1589 ../libnm-core/nm-setting-8021x.c:2411
#: ../libnm-core/nm-setting-8021x.c:2428 ../libnm-core/nm-setting-8021x.c:2459
#: ../libnm-core/nm-setting-8021x.c:2476 ../libnm-core/nm-setting-8021x.c:2518
#: ../libnm-core/nm-setting-8021x.c:2530 ../libnm-core/nm-setting-8021x.c:2548
@@ -8401,13 +8453,13 @@ msgid "'%d' is not a valid value for the property (should be <= %d)"
msgstr "\"%d\" não é um valor válido para a propriedade (deveria ser <= %d)"
#: ../libnm-core/nm-setting-bridge-port.c:154
-#: ../libnm-core/nm-setting-team-port.c:97
+#: ../libnm-core/nm-setting-team-port.c:109
#, c-format
msgid "missing setting"
msgstr "faltando definição"
#: ../libnm-core/nm-setting-bridge-port.c:165
-#: ../libnm-core/nm-setting-team-port.c:108
+#: ../libnm-core/nm-setting-team-port.c:120
#, c-format
msgid ""
"A connection with a '%s' setting must have the slave-type set to '%s'. "
@@ -8637,6 +8689,12 @@ msgstr "%d: rota é inválida"
msgid "%d. route cannot be a default route"
msgstr "%d. rota não pode ser uma rota padrão"
+#: ../libnm-core/nm-setting-ip-config.c:2281
+#, c-format
+#| msgid "'%s=%s' is incompatible with '%s > 0'"
+msgid "a gateway is incompatible with '%s'"
+msgstr "um gateway é incompatível com \"%s\""
+
#: ../libnm-core/nm-setting-ip4-config.c:143
#: ../libnm-core/nm-setting-ip6-config.c:144
#: ../libnm-util/nm-setting-ip4-config.c:879
@@ -8920,137 +8978,138 @@ msgstr "segredo não localizado"
msgid "secret is not set"
msgstr "segredo não está definido"
-#: ../libnm-core/nm-utils.c:2447
+#: ../libnm-core/nm-utils.c:2451
#, c-format
msgid "failed stat file %s: %s"
msgstr "falha ao obter estado do arquivo %s: %s"
-#: ../libnm-core/nm-utils.c:2456
+#: ../libnm-core/nm-utils.c:2460
#, c-format
msgid "not a file (%s)"
msgstr "não é um arquivo (%s)"
-#: ../libnm-core/nm-utils.c:2467
+#: ../libnm-core/nm-utils.c:2471
#, c-format
msgid "invalid file owner %d for %s"
msgstr "proprietário %d de arquivo inválido para %s"
-#: ../libnm-core/nm-utils.c:2478
+#: ../libnm-core/nm-utils.c:2482
#, c-format
msgid "file permissions for %s"
msgstr "permissões de arquivo para %s"
-#: ../libnm-core/nm-utils.c:2488
+#: ../libnm-core/nm-utils.c:2492
#, c-format
msgid "reject %s"
msgstr "rejeitar %s"
-#: ../libnm-core/nm-utils.c:2508
+#: ../libnm-core/nm-utils.c:2512
#, c-format
msgid "path is not absolute (%s)"
msgstr "o caminho não é absoluto (%s)"
-#: ../libnm-core/nm-utils.c:2522
+#: ../libnm-core/nm-utils.c:2526
#, c-format
msgid "Plugin file does not exist (%s)"
msgstr "O arquivo do plug-in não existe (%s)"
-#: ../libnm-core/nm-utils.c:2530
+#: ../libnm-core/nm-utils.c:2534
#, c-format
msgid "Plugin is not a valid file (%s)"
msgstr "O plug-in não é um arquivo válido (%s)"
-#: ../libnm-core/nm-utils.c:2540
+#: ../libnm-core/nm-utils.c:2544
#, c-format
msgid "libtool archives are not supported (%s)"
msgstr "Não há suporte a arquivos de libtool (%s)"
-#: ../libnm-core/nm-utils.c:2622 ../libnm-util/nm-utils.c:1815
+#: ../libnm-core/nm-utils.c:2626 ../libnm-util/nm-utils.c:1815
#, c-format
msgid "Could not find \"%s\" binary"
msgstr "Não foi possível localizar o executável \"%s\""
-#: ../libnm-core/nm-vpn-editor-plugin.c:142
+#: ../libnm-core/nm-vpn-editor-plugin.c:143
#, c-format
+#| msgid "cannot load plugin %s"
msgid "cannot load plugin \"%s\": %s"
msgstr "não foi possível carregar plug-in \"%s\": %s"
-#: ../libnm-core/nm-vpn-editor-plugin.c:153
+#: ../libnm-core/nm-vpn-editor-plugin.c:154
#, c-format
msgid "failed to load nm_vpn_editor_plugin_factory() from %s (%s)"
msgstr "falha ao carregar nm_vpn_editor_plugin_factory() de %s (%s)"
-#: ../libnm-core/nm-vpn-editor-plugin.c:178
+#: ../libnm-core/nm-vpn-editor-plugin.c:179
#, c-format
msgid "unknown error initializing plugin %s"
msgstr "erro desconhecido de inicialização do plug-in %s"
-#: ../libnm-core/nm-vpn-editor-plugin.c:195
+#: ../libnm-core/nm-vpn-editor-plugin.c:196
#, c-format
msgid "cannot load VPN plugin in '%s': missing plugin name"
msgstr ""
"não foi possível carregar plug-in de VPN em \"%s\": faltando nome do plug-in"
-#: ../libnm-core/nm-vpn-editor-plugin.c:204
+#: ../libnm-core/nm-vpn-editor-plugin.c:205
#, c-format
msgid "cannot load VPN plugin in '%s': invalid service name"
msgstr ""
"não foi possível carregar plug-in de VPN em \"%s\": nome de serviço inválido"
-#: ../libnm-core/nm-vpn-editor-plugin.c:310
+#: ../libnm-core/nm-vpn-editor-plugin.c:348
#, c-format
msgid "the plugin does not support import capability"
msgstr "o plug-in não oferece suporte à capacidade de importação"
-#: ../libnm-core/nm-vpn-editor-plugin.c:330
+#: ../libnm-core/nm-vpn-editor-plugin.c:368
#, c-format
msgid "the plugin does not support export capability"
msgstr "o plug-in não oferece suporte à capacidade de exportação"
-#: ../libnm-core/nm-vpn-plugin-info.c:109
+#: ../libnm-core/nm-vpn-plugin-info.c:110
#, c-format
msgid "missing filename"
msgstr "faltando nome de arquivo"
-#: ../libnm-core/nm-vpn-plugin-info.c:117
+#: ../libnm-core/nm-vpn-plugin-info.c:118
#, c-format
msgid "filename must be an absolute path (%s)"
msgstr "nome de arquivo deve ser um caminho absoluto (%s)"
-#: ../libnm-core/nm-vpn-plugin-info.c:126
+#: ../libnm-core/nm-vpn-plugin-info.c:127
#, c-format
msgid "filename has invalid format (%s)"
msgstr "nome de arquivo possui formato inválido (%s)"
-#: ../libnm-core/nm-vpn-plugin-info.c:383
+#: ../libnm-core/nm-vpn-plugin-info.c:450
#, c-format
msgid "there exists a conflicting plugin (%s) that has the same %s.%s value"
msgstr "há um plug-in conflitante (%s) que possui o mesmo valor %s.%s"
-#: ../libnm-core/nm-vpn-plugin-info.c:421
+#: ../libnm-core/nm-vpn-plugin-info.c:488
#, c-format
msgid "there exists a conflicting plugin with the same name (%s)"
msgstr "há um plug-in conflitante com o mesmo nome (%s)"
-#: ../libnm-core/nm-vpn-plugin-info.c:740
+#: ../libnm-core/nm-vpn-plugin-info.c:878
#, c-format
msgid "missing \"plugin\" setting"
msgstr "faltando definição \"plugin\""
-#: ../libnm-core/nm-vpn-plugin-info.c:750
+#: ../libnm-core/nm-vpn-plugin-info.c:888
#, c-format
msgid "%s: don't retry loading plugin which already failed previously"
msgstr "%s: não tentar novamente carregar plug-in que já falhou anteriormente"
-#: ../libnm-core/nm-vpn-plugin-info.c:842
+#: ../libnm-core/nm-vpn-plugin-info.c:980
msgid "missing filename to load VPN plugin info"
msgstr "faltando nome de arquivo para carregar informação de plug-in de VPN"
-#: ../libnm-core/nm-vpn-plugin-info.c:854
+#: ../libnm-core/nm-vpn-plugin-info.c:992
msgid "missing name for VPN plugin info"
msgstr "faltando nome de arquivo para carregar informação de plug-in de VPN"
-#: ../libnm-core/nm-vpn-plugin-info.c:863
+#: ../libnm-core/nm-vpn-plugin-info.c:1001
msgid "missing service for VPN plugin info"
msgstr "faltando serviço para informação de plug-in de VPN"
@@ -9522,47 +9581,43 @@ msgctxt "connection id fallback"
msgid "%s %d"
msgstr "%s %d"
-#: ../src/main.c:220 ../src/main.c:358
+#: ../src/main.c:148 ../src/main.c:283
#, c-format
msgid "Failed to read configuration: %s\n"
msgstr "Falha ao ler configuração: %s\n"
#. Logging/debugging
-#: ../src/main.c:234 ../src/nm-iface-helper.c:298
+#: ../src/main.c:162 ../src/nm-iface-helper.c:298
msgid "Print NetworkManager version and exit"
msgstr "Imprime a versão do NetworkManager e sai"
-#: ../src/main.c:235 ../src/nm-iface-helper.c:299
+#: ../src/main.c:163 ../src/nm-iface-helper.c:299
msgid "Don't become a daemon"
msgstr "Não se torna um daemon"
-#: ../src/main.c:236 ../src/nm-iface-helper.c:301
+#: ../src/main.c:164 ../src/nm-iface-helper.c:301
#, c-format
msgid "Log level: one of [%s]"
msgstr "Nível de registro: um dos [%s]"
-#: ../src/main.c:238 ../src/nm-iface-helper.c:303
+#: ../src/main.c:166 ../src/nm-iface-helper.c:303
#, c-format
msgid "Log domains separated by ',': any combination of [%s]"
msgstr "Domínios de registro separados por \",\": qualquer combinação de [%s]"
-#: ../src/main.c:240 ../src/nm-iface-helper.c:305
+#: ../src/main.c:168 ../src/nm-iface-helper.c:305
msgid "Make all warnings fatal"
msgstr "Torna todos os avisos fatais"
-#: ../src/main.c:241
+#: ../src/main.c:169
msgid "Specify the location of a PID file"
msgstr "Especifica a localização de um arquivo PID"
-#: ../src/main.c:242
-msgid "State file location"
-msgstr "Localização do arquivo de estado"
-
-#: ../src/main.c:244
+#: ../src/main.c:171
msgid "Print NetworkManager configuration and exit"
msgstr "Imprime a configuração do NetworkManager e sai"
-#: ../src/main.c:254
+#: ../src/main.c:181
msgid ""
"NetworkManager monitors all network connections and automatically\n"
"chooses the best connection to use. It also allows the user to\n"
@@ -9574,60 +9629,60 @@ msgstr ""
"especifique pontos de acesso sem fio os quais cartões sem fio no\n"
"computador podem ser associados."
-#: ../src/main.c:343 ../src/main-utils.c:269 ../src/nm-iface-helper.c:393
+#: ../src/main.c:268 ../src/main-utils.c:268 ../src/nm-iface-helper.c:393
#, c-format
msgid "%s. Please use --help to see a list of valid options.\n"
msgstr "%s. Por favor, use --help para ver uma lista de opções válidas.\n"
-#: ../src/main.c:348 ../src/nm-iface-helper.c:398
+#: ../src/main.c:273 ../src/nm-iface-helper.c:398
#, c-format
msgid "Ignoring unrecognized log domain(s) '%s' passed on command line.\n"
msgstr ""
"Ignorando domínio(s) de log irreconhecíveis '%s' passaram na linha de "
"comando.\n"
-#: ../src/main.c:373
+#: ../src/main.c:298
#, c-format
msgid "Error in configuration file: %s.\n"
msgstr "Erro no arquivo de configuração: %s.\n"
-#: ../src/main.c:378
+#: ../src/main.c:303
#, c-format
msgid "Ignoring unrecognized log domain(s) '%s' from config files.\n"
msgstr ""
"Ignorando domínio(s) de log irreconhecíveis '%s' dos arquivos de config.\n"
-#: ../src/main.c:389 ../src/nm-iface-helper.c:408
+#: ../src/main.c:314 ../src/nm-iface-helper.c:408
#, c-format
msgid "Could not daemonize: %s [error %u]\n"
msgstr "Não foi possível tornar um daemon: %s [erro %u]\n"
-#: ../src/main-utils.c:99
+#: ../src/main-utils.c:98
#, c-format
msgid "Opening %s failed: %s\n"
msgstr "Abertura de %s falhou: %s\n"
-#: ../src/main-utils.c:105
+#: ../src/main-utils.c:104
#, c-format
msgid "Writing to %s failed: %s\n"
msgstr "Escrita para %s falhou: %s\n"
-#: ../src/main-utils.c:110
+#: ../src/main-utils.c:109
#, c-format
msgid "Closing %s failed: %s\n"
msgstr "Fechamento de %s falhou: %s\n"
-#: ../src/main-utils.c:145
+#: ../src/main-utils.c:144
#, c-format
msgid "Cannot create '%s': %s"
msgstr "Não foi possível criar \"%s\": %s"
-#: ../src/main-utils.c:197
+#: ../src/main-utils.c:196
#, c-format
msgid "%s is already running (pid %ld)\n"
msgstr "%s já está em execução (pid %ld)\n"
-#: ../src/main-utils.c:207
+#: ../src/main-utils.c:206
#, c-format
msgid "You must be root to run %s!\n"
msgstr "Você precisa ser superusuário para executar %s!\n"
@@ -9649,7 +9704,7 @@ msgstr ""
msgid "ADSL connection"
msgstr "Conexão ADSL"
-#: ../src/devices/bluetooth/nm-bluez-device.c:197
+#: ../src/devices/bluetooth/nm-bluez-device.c:199
#, c-format
msgid "%s Network"
msgstr "Rede %s"
@@ -9740,7 +9795,7 @@ msgstr "Conexão VLAN"
msgid "VXLAN connection"
msgstr "Conexão VXLAN"
-#: ../src/devices/team/nm-device-team.c:115
+#: ../src/devices/team/nm-device-team.c:116
msgid "Team connection"
msgstr "Conexão de união"
@@ -9917,48 +9972,52 @@ msgstr "Falha ao determinar informação de segurança do AP"
msgid "GSM mobile broadband connection requires a 'gsm' setting"
msgstr "Conexão de banda larga móvel (GSM) requer uma configuração \"gsm\""
-#: ../src/nm-config.c:465
+#: ../src/nm-config.c:499
msgid "Config file location"
msgstr "Localização do arquivo de configuração"
-#: ../src/nm-config.c:466
+#: ../src/nm-config.c:500
msgid "Config directory location"
msgstr "Localização do diretório de configuração"
-#: ../src/nm-config.c:467
+#: ../src/nm-config.c:501
msgid "System config directory location"
msgstr "Localização do diretório de configuração do sistema"
-#: ../src/nm-config.c:468
+#: ../src/nm-config.c:502
msgid "Internal config file location"
msgstr "Localização do arquivo de configuração interna"
-#: ../src/nm-config.c:469
+#: ../src/nm-config.c:503
+msgid "State file location"
+msgstr "Localização do arquivo de estado"
+
+#: ../src/nm-config.c:504
msgid "State file for no-auto-default devices"
msgstr "Arquivo de estado para dispositivos no-auto-default"
-#: ../src/nm-config.c:470
+#: ../src/nm-config.c:505
msgid "List of plugins separated by ','"
msgstr "Lista de plug-ins separada por \",\""
-#: ../src/nm-config.c:471
+#: ../src/nm-config.c:506
msgid "Quit after initial configuration"
msgstr "Sair após configuração inicial"
-#: ../src/nm-config.c:472 ../src/nm-iface-helper.c:300
+#: ../src/nm-config.c:507 ../src/nm-iface-helper.c:300
msgid "Don't become a daemon, and log to stderr"
msgstr "Não se tornar um daemon e registrar à saída padrão de erro (stderr)"
#. These three are hidden for now, and should eventually just go away.
-#: ../src/nm-config.c:475
+#: ../src/nm-config.c:510
msgid "An http(s) address for checking internet connectivity"
msgstr "Um endereço http(s) para verificar a conectividade com a internet"
-#: ../src/nm-config.c:476
+#: ../src/nm-config.c:511
msgid "The interval between connectivity checks (in seconds)"
msgstr "O intervalo de tempo entre verificações de conectividade (em segundos)"
-#: ../src/nm-config.c:477
+#: ../src/nm-config.c:512
msgid "The expected start of the response"
msgstr "O início esperado da resposta"
@@ -10084,14 +10143,10 @@ msgstr "Nível de registro \"%s\" desconhecido"
msgid "Unknown log domain '%s'"
msgstr "Domínio de registro \"%s\" desconhecido"
-#: ../src/nm-manager.c:3635
+#: ../src/nm-manager.c:3603
msgid "VPN connection"
msgstr "Conexão VPN"
-#: ../src/nm-sleep-monitor-systemd.c:131
-msgid "NetworkManager needs to turn off networks"
-msgstr "O NetworkManager precisa desligar as redes"
-
#: ../src/settings/plugins/ifcfg-rh/reader.c:108
msgid "System"
msgstr "Sistema"
@@ -10108,6 +10163,9 @@ msgstr "Sistema"
#~ msgid "Error converting IP6 address '%s' to text form"
#~ msgstr "Erro ao converter endereço IP6 \"%s\" para o formato texto"
+#~ msgid "NetworkManager needs to turn off networks"
+#~ msgstr "O NetworkManager precisa desligar as redes"
+
#~ msgid "Failed to read configuration: (%d) %s\n"
#~ msgstr "Falha ao ler configuração: (%d) %s\n"
diff --git a/po/sv.po b/po/sv.po
index 8c1b5fd609..b937abaef2 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -10,8 +10,8 @@ msgstr ""
"Project-Id-Version: NetworkManager\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
"product=NetworkManager&keywords=I18N+L10N&component=Translations\n"
-"POT-Creation-Date: 2016-05-05 14:02+0000\n"
-"PO-Revision-Date: 2016-05-07 00:25+0200\n"
+"POT-Creation-Date: 2016-04-07 13:40+0000\n"
+"PO-Revision-Date: 2016-04-05 22:40+0200\n"
"Last-Translator: Anders Jonsson <anders.jonsson@norsjovallen.se>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
"Language: sv\n"
@@ -106,14 +106,14 @@ msgstr "Fel: Initiering av polkit-agent misslyckades: %s"
msgid "nmcli successfully registered as a polkit agent.\n"
msgstr "nmcli registrerade en polkit-agent.\n"
-#: ../clients/cli/agent.c:206 ../clients/cli/connections.c:11054
-#: ../clients/cli/devices.c:3644 ../clients/cli/general.c:343
-#: ../clients/cli/general.c:481
+#: ../clients/cli/agent.c:206 ../clients/cli/connections.c:11050
+#: ../clients/cli/devices.c:3669 ../clients/cli/general.c:343
+#: ../clients/cli/general.c:484
#, c-format
msgid "Error: NetworkManager is not running."
msgstr "Fel: Nätverkshanteraren är inte igång."
-#: ../clients/cli/agent.c:239
+#: ../clients/cli/agent.c:242
#, c-format
msgid "Error: 'agent' command '%s' is not valid."
msgstr "Fel: ”agent”-kommandot ”%s” är inte giltigt."
@@ -235,7 +235,7 @@ msgstr "ansluter (startar sekundära anslutningar)"
msgid "connected"
msgstr "ansluten"
-#: ../clients/cli/common.c:514 ../clients/cli/connections.c:645
+#: ../clients/cli/common.c:514 ../clients/cli/connections.c:648
msgid "deactivating"
msgstr "inaktiverar"
@@ -244,25 +244,25 @@ msgid "connection failed"
msgstr "anslutningen misslyckades"
#: ../clients/cli/common.c:518 ../clients/cli/common.c:535
-#: ../clients/cli/connections.c:650 ../clients/cli/connections.c:673
-#: ../clients/cli/connections.c:1946 ../clients/cli/devices.c:1024
+#: ../clients/cli/connections.c:653 ../clients/cli/connections.c:676
+#: ../clients/cli/connections.c:1949 ../clients/cli/devices.c:1024
#: ../clients/cli/devices.c:1065 ../clients/cli/devices.c:1067
#: ../clients/cli/general.c:248 ../clients/cli/general.c:286
-#: ../clients/cli/general.c:429 ../clients/cli/general.c:445
+#: ../clients/cli/general.c:432 ../clients/cli/general.c:448
#: ../clients/cli/settings.c:839 ../clients/cli/settings.c:925
#: ../clients/cli/settings.c:1265 ../clients/cli/settings.c:1901
-#: ../clients/cli/settings.c:3198
+#: ../clients/cli/settings.c:3205 ../clients/cli/utils.c:1400
#, c-format
msgid "unknown"
msgstr "okänd"
#. "CAPABILITIES"
-#: ../clients/cli/common.c:527 ../clients/cli/connections.c:930
-#: ../clients/cli/connections.c:932 ../clients/cli/connections.c:934
-#: ../clients/cli/connections.c:968 ../clients/cli/connections.c:1037
-#: ../clients/cli/connections.c:1038 ../clients/cli/connections.c:1040
-#: ../clients/cli/connections.c:3454 ../clients/cli/connections.c:8567
-#: ../clients/cli/connections.c:8568 ../clients/cli/devices.c:772
+#: ../clients/cli/common.c:527 ../clients/cli/connections.c:933
+#: ../clients/cli/connections.c:935 ../clients/cli/connections.c:937
+#: ../clients/cli/connections.c:971 ../clients/cli/connections.c:1040
+#: ../clients/cli/connections.c:1041 ../clients/cli/connections.c:1043
+#: ../clients/cli/connections.c:3450 ../clients/cli/connections.c:8563
+#: ../clients/cli/connections.c:8564 ../clients/cli/devices.c:772
#: ../clients/cli/devices.c:989 ../clients/cli/devices.c:990
#: ../clients/cli/devices.c:991 ../clients/cli/devices.c:992
#: ../clients/cli/devices.c:993 ../clients/cli/devices.c:1028
@@ -271,15 +271,15 @@ msgstr "okänd"
#: ../clients/cli/devices.c:1061 ../clients/cli/devices.c:1062
#: ../clients/cli/devices.c:1063 ../clients/cli/devices.c:1064
#: ../clients/cli/devices.c:1066 ../clients/cli/devices.c:1068
-#: ../clients/cli/general.c:439 ../clients/cli/settings.c:3193
+#: ../clients/cli/general.c:442 ../clients/cli/settings.c:3200
msgid "yes"
msgstr "ja"
-#: ../clients/cli/common.c:529 ../clients/cli/connections.c:930
-#: ../clients/cli/connections.c:932 ../clients/cli/connections.c:934
-#: ../clients/cli/connections.c:1037 ../clients/cli/connections.c:1038
-#: ../clients/cli/connections.c:1040 ../clients/cli/connections.c:3455
-#: ../clients/cli/connections.c:8567 ../clients/cli/connections.c:8568
+#: ../clients/cli/common.c:529 ../clients/cli/connections.c:933
+#: ../clients/cli/connections.c:935 ../clients/cli/connections.c:937
+#: ../clients/cli/connections.c:1040 ../clients/cli/connections.c:1041
+#: ../clients/cli/connections.c:1043 ../clients/cli/connections.c:3451
+#: ../clients/cli/connections.c:8563 ../clients/cli/connections.c:8564
#: ../clients/cli/devices.c:772 ../clients/cli/devices.c:989
#: ../clients/cli/devices.c:990 ../clients/cli/devices.c:991
#: ../clients/cli/devices.c:992 ../clients/cli/devices.c:993
@@ -288,8 +288,8 @@ msgstr "ja"
#: ../clients/cli/devices.c:1060 ../clients/cli/devices.c:1061
#: ../clients/cli/devices.c:1062 ../clients/cli/devices.c:1063
#: ../clients/cli/devices.c:1064 ../clients/cli/devices.c:1066
-#: ../clients/cli/devices.c:1068 ../clients/cli/general.c:441
-#: ../clients/cli/settings.c:3195
+#: ../clients/cli/devices.c:1068 ../clients/cli/general.c:444
+#: ../clients/cli/settings.c:3202
msgid "no"
msgstr "nej"
@@ -306,7 +306,7 @@ msgid "No reason given"
msgstr "Ingen anledning angiven"
#. We should not really come here
-#: ../clients/cli/common.c:547 ../clients/cli/connections.c:2980
+#: ../clients/cli/common.c:547 ../clients/cli/connections.c:2976
#, c-format
msgid "Unknown error"
msgstr "Okänt fel"
@@ -776,7 +776,7 @@ msgstr "SPEC-OBJEKT"
#. 4
#. Ask for optional 'vpn' arguments.
#: ../clients/cli/connections.c:200 ../clients/cli/connections.c:238
-#: ../clients/cli/connections.c:4173 ../clients/tui/nm-editor-utils.c:233
+#: ../clients/cli/connections.c:4169 ../clients/tui/nm-editor-utils.c:233
#: ../clients/tui/nmt-connect-connection-list.c:405
msgid "VPN"
msgstr "VPN"
@@ -847,7 +847,7 @@ msgstr "IP6"
msgid "DHCP6"
msgstr "DHCP6"
-#: ../clients/cli/connections.c:269
+#: ../clients/cli/connections.c:272
#, c-format
msgid ""
"Usage: nmcli connection { COMMAND | help }\n"
@@ -924,7 +924,7 @@ msgstr ""
" export [id | uuid | path] <ID> [<utdatafil>]\n"
"\n"
-#: ../clients/cli/connections.c:291
+#: ../clients/cli/connections.c:294
#, c-format
msgid ""
"Usage: nmcli connection show { ARGUMENTS | help }\n"
@@ -971,7 +971,7 @@ msgstr ""
"räknas. Flaggan --show-secrets kommer dessutom att visa associerade "
"hemligheter.\n"
-#: ../clients/cli/connections.c:312
+#: ../clients/cli/connections.c:315
#, c-format
msgid ""
"Usage: nmcli connection up { ARGUMENTS | help }\n"
@@ -1016,7 +1016,7 @@ msgstr ""
"passwd-file - fil med lösenord som krävs för att aktivera anslutningen\n"
"\n"
-#: ../clients/cli/connections.c:333
+#: ../clients/cli/connections.c:336
#, c-format
msgid ""
"Usage: nmcli connection down { ARGUMENTS | help }\n"
@@ -1039,7 +1039,7 @@ msgstr ""
"UUID eller D-Bus-sökväg.\n"
"\n"
-#: ../clients/cli/connections.c:345
+#: ../clients/cli/connections.c:348
#, c-format
msgid ""
"Usage: nmcli connection add { ARGUMENTS | help }\n"
@@ -1324,7 +1324,7 @@ msgstr ""
" [ip6 <IPv6-adress>] [gw6 <IPv6-gateway>]\n"
"\n"
-#: ../clients/cli/connections.c:457
+#: ../clients/cli/connections.c:460
#, c-format
msgid ""
"Usage: nmcli connection modify { ARGUMENTS | help }\n"
@@ -1374,7 +1374,7 @@ msgstr ""
"nmcli con mod bond0 -bond.options downdelay\n"
"\n"
-#: ../clients/cli/connections.c:480
+#: ../clients/cli/connections.c:483
#, c-format
msgid ""
"Usage: nmcli connection clone { ARGUMENTS | help }\n"
@@ -1397,7 +1397,7 @@ msgstr ""
"id (tillhandahålls av argumentet <nytt namn>).\n"
"\n"
-#: ../clients/cli/connections.c:492
+#: ../clients/cli/connections.c:495
#, c-format
msgid ""
"Usage: nmcli connection edit { ARGUMENTS | help }\n"
@@ -1424,7 +1424,7 @@ msgstr ""
"Lägg till en ny anslutningsprofil i en interaktiv redigerare.\n"
"\n"
-#: ../clients/cli/connections.c:507
+#: ../clients/cli/connections.c:510
#, c-format
msgid ""
"Usage: nmcli connection delete { ARGUMENTS | help }\n"
@@ -1443,7 +1443,7 @@ msgstr ""
"Profilen identifieras genom dess namn, UUID, och D-Bus-sökväg.\n"
"\n"
-#: ../clients/cli/connections.c:518
+#: ../clients/cli/connections.c:521
#, c-format
msgid ""
"Usage: nmcli connection monitor { ARGUMENTS | help }\n"
@@ -1465,7 +1465,7 @@ msgstr ""
"Övervakar alla anslutningsprofiler om ingen har angivits.\n"
"\n"
-#: ../clients/cli/connections.c:530
+#: ../clients/cli/connections.c:533
#, c-format
msgid ""
"Usage: nmcli connection reload { help }\n"
@@ -1478,7 +1478,7 @@ msgstr ""
"Läs om alla anslutningsfiler från disk.\n"
"\n"
-#: ../clients/cli/connections.c:538
+#: ../clients/cli/connections.c:541
#, c-format
msgid ""
"Usage: nmcli connection load { ARGUMENTS | help }\n"
@@ -1502,7 +1502,7 @@ msgstr ""
"tillstånd.\n"
"\n"
-#: ../clients/cli/connections.c:550
+#: ../clients/cli/connections.c:553
#, c-format
msgid ""
"Usage: nmcli connection import { ARGUMENTS | help }\n"
@@ -1527,7 +1527,7 @@ msgstr ""
"importeras av Nätverkshanterarens VPN-insticksmoduler.\n"
"\n"
-#: ../clients/cli/connections.c:563
+#: ../clients/cli/connections.c:566
#, c-format
msgid ""
"Usage: nmcli connection export { ARGUMENTS | help }\n"
@@ -1546,197 +1546,197 @@ msgstr ""
"Data dirigeras till standard ut eller till en fil om ett namn anges.\n"
"\n"
-#: ../clients/cli/connections.c:641
+#: ../clients/cli/connections.c:644
msgid "activating"
msgstr "aktiverar"
-#: ../clients/cli/connections.c:643
+#: ../clients/cli/connections.c:646
msgid "activated"
msgstr "aktiverad"
-#: ../clients/cli/connections.c:647
+#: ../clients/cli/connections.c:650
msgid "deactivated"
msgstr "inaktiverad"
-#: ../clients/cli/connections.c:659
+#: ../clients/cli/connections.c:662
msgid "VPN connecting (prepare)"
msgstr "VPN ansluter (förbereder)"
-#: ../clients/cli/connections.c:661
+#: ../clients/cli/connections.c:664
msgid "VPN connecting (need authentication)"
msgstr "VPN ansluter (behöver autentisering)"
-#: ../clients/cli/connections.c:663
+#: ../clients/cli/connections.c:666
msgid "VPN connecting"
msgstr "VPN ansluter"
-#: ../clients/cli/connections.c:665
+#: ../clients/cli/connections.c:668
msgid "VPN connecting (getting IP configuration)"
msgstr "VPN ansluter (hämtar IP-konfiguration)"
-#: ../clients/cli/connections.c:667
+#: ../clients/cli/connections.c:670
msgid "VPN connected"
msgstr "VPN ansluten"
-#: ../clients/cli/connections.c:669
+#: ../clients/cli/connections.c:672
msgid "VPN connection failed"
msgstr "VPN-anslutning misslyckades"
-#: ../clients/cli/connections.c:671
+#: ../clients/cli/connections.c:674
msgid "VPN disconnected"
msgstr "VPN frånkopplad"
-#: ../clients/cli/connections.c:741
+#: ../clients/cli/connections.c:744
#, c-format
msgid "Error updating secrets for %s: %s\n"
msgstr "Fel vid uppdatering av hemligheterna för %s: %s\n"
-#: ../clients/cli/connections.c:761
+#: ../clients/cli/connections.c:764
msgid "Connection profile details"
msgstr "Detaljer för anslutningsprofil"
-#: ../clients/cli/connections.c:773 ../clients/cli/connections.c:1166
+#: ../clients/cli/connections.c:776 ../clients/cli/connections.c:1169
#, c-format
msgid "Error: 'connection show': %s"
msgstr "Fel: ”connection show”: %s"
-#: ../clients/cli/connections.c:929 ../clients/cli/settings.c:1897
+#: ../clients/cli/connections.c:932 ../clients/cli/settings.c:1897
msgid "never"
msgstr "aldrig"
-#: ../clients/cli/connections.c:1154
+#: ../clients/cli/connections.c:1157
msgid "Activate connection details"
msgstr "Aktivera anslutningsdetaljer"
-#: ../clients/cli/connections.c:1390
+#: ../clients/cli/connections.c:1393
#, c-format
msgid "invalid field '%s'; allowed fields: %s and %s, or %s,%s"
msgstr "ogiltigt fält ”%s”; tillåtna fält: %s och %s, eller %s, %s"
-#: ../clients/cli/connections.c:1405 ../clients/cli/connections.c:1413
+#: ../clients/cli/connections.c:1408 ../clients/cli/connections.c:1416
#, c-format
msgid "'%s' has to be alone"
msgstr "”%s” måste vara ensamt"
#. Add headers
-#: ../clients/cli/connections.c:1631
+#: ../clients/cli/connections.c:1634
msgid "NetworkManager active profiles"
msgstr "Aktiva profiler för Nätverkshanteraren"
-#: ../clients/cli/connections.c:1632
+#: ../clients/cli/connections.c:1635
msgid "NetworkManager connection profiles"
msgstr "Anslutningsprofiler för Nätverkshanteraren"
-#: ../clients/cli/connections.c:1678 ../clients/cli/connections.c:2393
-#: ../clients/cli/connections.c:2415 ../clients/cli/connections.c:2424
-#: ../clients/cli/connections.c:2433 ../clients/cli/connections.c:2592
-#: ../clients/cli/connections.c:10160 ../clients/cli/connections.c:10277
-#: ../clients/cli/connections.c:10409 ../clients/cli/connections.c:10542
-#: ../clients/cli/connections.c:10652 ../clients/cli/connections.c:10663
-#: ../clients/cli/connections.c:10762 ../clients/cli/devices.c:2322
-#: ../clients/cli/devices.c:2330 ../clients/cli/devices.c:2653
-#: ../clients/cli/devices.c:2660 ../clients/cli/devices.c:2674
-#: ../clients/cli/devices.c:2681 ../clients/cli/devices.c:2698
-#: ../clients/cli/devices.c:2706 ../clients/cli/devices.c:2719
-#: ../clients/cli/devices.c:3083 ../clients/cli/devices.c:3090
-#: ../clients/cli/devices.c:3097 ../clients/cli/devices.c:3109
-#: ../clients/cli/devices.c:3122 ../clients/cli/devices.c:3129
-#: ../clients/cli/devices.c:3301 ../clients/cli/devices.c:3308
-#: ../clients/cli/devices.c:3481
+#: ../clients/cli/connections.c:1681 ../clients/cli/connections.c:2389
+#: ../clients/cli/connections.c:2411 ../clients/cli/connections.c:2420
+#: ../clients/cli/connections.c:2429 ../clients/cli/connections.c:2588
+#: ../clients/cli/connections.c:10156 ../clients/cli/connections.c:10273
+#: ../clients/cli/connections.c:10405 ../clients/cli/connections.c:10538
+#: ../clients/cli/connections.c:10648 ../clients/cli/connections.c:10659
+#: ../clients/cli/connections.c:10758 ../clients/cli/devices.c:2344
+#: ../clients/cli/devices.c:2352 ../clients/cli/devices.c:2675
+#: ../clients/cli/devices.c:2682 ../clients/cli/devices.c:2696
+#: ../clients/cli/devices.c:2703 ../clients/cli/devices.c:2720
+#: ../clients/cli/devices.c:2728 ../clients/cli/devices.c:2741
+#: ../clients/cli/devices.c:3105 ../clients/cli/devices.c:3112
+#: ../clients/cli/devices.c:3119 ../clients/cli/devices.c:3131
+#: ../clients/cli/devices.c:3144 ../clients/cli/devices.c:3151
+#: ../clients/cli/devices.c:3323 ../clients/cli/devices.c:3330
+#: ../clients/cli/devices.c:3503
#, c-format
msgid "Error: %s argument is missing."
msgstr "Fel: %s-argument saknas."
-#: ../clients/cli/connections.c:1693
+#: ../clients/cli/connections.c:1696
#, c-format
msgid "Error: %s - no such connection profile."
msgstr "Fel: %s - inga sådana anslutningsprofiler."
-#: ../clients/cli/connections.c:1752 ../clients/cli/connections.c:2456
-#: ../clients/cli/connections.c:11163 ../clients/cli/devices.c:3270
-#: ../clients/cli/devices.c:3751 ../clients/cli/general.c:536
-#: ../clients/cli/general.c:585 ../clients/cli/general.c:602
-#: ../clients/cli/general.c:641 ../clients/cli/general.c:655
-#: ../clients/cli/general.c:773 ../clients/cli/general.c:820
-#: ../clients/cli/general.c:840
+#: ../clients/cli/connections.c:1755 ../clients/cli/connections.c:2452
+#: ../clients/cli/connections.c:11162 ../clients/cli/devices.c:3292
+#: ../clients/cli/devices.c:3779 ../clients/cli/general.c:539
+#: ../clients/cli/general.c:588 ../clients/cli/general.c:605
+#: ../clients/cli/general.c:644 ../clients/cli/general.c:658
+#: ../clients/cli/general.c:776 ../clients/cli/general.c:823
+#: ../clients/cli/general.c:843
#, c-format
msgid "Error: %s."
msgstr "Fel: %s."
-#: ../clients/cli/connections.c:1848
+#: ../clients/cli/connections.c:1851
#, c-format
msgid "no active connection on device '%s'"
msgstr "ingen aktiv anslutning på enheten ”%s”"
-#: ../clients/cli/connections.c:1856
+#: ../clients/cli/connections.c:1859
msgid "no active connection or device"
msgstr "ingen aktiv anslutning eller enhet"
-#: ../clients/cli/connections.c:1907
+#: ../clients/cli/connections.c:1910
#, c-format
msgid "device '%s' not compatible with connection '%s'"
msgstr "enheten ”%s” är inte kompatibel med anslutningen ”%s”"
-#: ../clients/cli/connections.c:1910
+#: ../clients/cli/connections.c:1913
#, c-format
msgid "no device found for connection '%s'"
msgstr "ingen enhet hittades för anslutningen ”%s”"
-#: ../clients/cli/connections.c:1922
+#: ../clients/cli/connections.c:1925
msgid "unknown reason"
msgstr "okänd anledning"
-#: ../clients/cli/connections.c:1924 ../clients/cli/general.c:277
+#: ../clients/cli/connections.c:1927 ../clients/cli/general.c:277
msgid "none"
msgstr "ingen"
-#: ../clients/cli/connections.c:1926
+#: ../clients/cli/connections.c:1929
msgid "the user was disconnected"
msgstr "användaren kopplades från"
-#: ../clients/cli/connections.c:1928
+#: ../clients/cli/connections.c:1931
msgid "the base network connection was interrupted"
msgstr "basnätverksanslutningen avbröts"
-#: ../clients/cli/connections.c:1930
+#: ../clients/cli/connections.c:1933
msgid "the VPN service stopped unexpectedly"
msgstr "VPN-tjänsten stoppades oväntat"
-#: ../clients/cli/connections.c:1932
+#: ../clients/cli/connections.c:1935
msgid "the VPN service returned invalid configuration"
msgstr "VPN-tjänsten returnerade en ogiltig konfiguration"
-#: ../clients/cli/connections.c:1934
+#: ../clients/cli/connections.c:1937
msgid "the connection attempt timed out"
msgstr "anslutningsförsöket översteg tidsgränsen"
-#: ../clients/cli/connections.c:1936
+#: ../clients/cli/connections.c:1939
msgid "the VPN service did not start in time"
msgstr "VPN-tjänsten startade inte i tid"
-#: ../clients/cli/connections.c:1938
+#: ../clients/cli/connections.c:1941
msgid "the VPN service failed to start"
msgstr "VPN-tjänsten misslyckades med att starta"
-#: ../clients/cli/connections.c:1940
+#: ../clients/cli/connections.c:1943
msgid "no valid VPN secrets"
msgstr "inga giltiga VPN-hemligheter"
-#: ../clients/cli/connections.c:1942
+#: ../clients/cli/connections.c:1945
msgid "invalid VPN secrets"
msgstr "ogiltiga VPN-hemligheter"
-#: ../clients/cli/connections.c:1944
+#: ../clients/cli/connections.c:1947
msgid "the connection was removed"
msgstr "anslutningen togs bort"
-#: ../clients/cli/connections.c:1966 ../clients/cli/connections.c:2001
-#: ../clients/cli/connections.c:2162 ../clients/cli/connections.c:8458
+#: ../clients/cli/connections.c:1969 ../clients/cli/connections.c:1997
+#: ../clients/cli/connections.c:2158 ../clients/cli/connections.c:8454
#, c-format
msgid "Connection successfully activated (D-Bus active path: %s)\n"
msgstr "Anslutning aktiverades (aktiv sökväg för D-Bus: %s)\n"
-#: ../clients/cli/connections.c:1974
+#: ../clients/cli/connections.c:1976
#, c-format
msgid ""
"Connection successfully activated (master waiting for slaves) (D-Bus active "
@@ -1745,204 +1745,203 @@ msgstr ""
"Anslutning aktiverades (master väntar på slavar) (aktiv sökväg för D-Bus: "
"%s)\n"
-#: ../clients/cli/connections.c:1981 ../clients/cli/connections.c:1984
-#: ../clients/cli/connections.c:2006
+#: ../clients/cli/connections.c:1980 ../clients/cli/connections.c:2002
#, c-format
msgid "Error: Connection activation failed."
msgstr "Fel: Aktivering av anslutning misslyckades."
-#: ../clients/cli/connections.c:2057
+#: ../clients/cli/connections.c:2053
#, c-format
msgid "VPN connection successfully activated (D-Bus active path: %s)\n"
msgstr "VPN-anslutning aktiverad (aktiv sökväg för D-Bus: %s)\n"
-#: ../clients/cli/connections.c:2065
+#: ../clients/cli/connections.c:2061
#, c-format
msgid "Error: Connection activation failed: %s."
msgstr "Fel: Aktivering av anslutning misslyckades: %s."
-#: ../clients/cli/connections.c:2084 ../clients/cli/devices.c:1426
+#: ../clients/cli/connections.c:2080 ../clients/cli/devices.c:1426
#, c-format
msgid "Error: Timeout %d sec expired."
msgstr "Fel: Tidsgränsen %d sekunder gick ut."
-#: ../clients/cli/connections.c:2144
+#: ../clients/cli/connections.c:2140
#, c-format
msgid "Error: Connection activation failed: %s"
msgstr "Fel: Aktivering av anslutning misslyckades: %s"
-#: ../clients/cli/connections.c:2229
+#: ../clients/cli/connections.c:2225
#, c-format
msgid "failed to read passwd-file '%s': %s"
msgstr "misslyckades med att läsa lösenordsfilen ”%s”: %s"
-#: ../clients/cli/connections.c:2241
+#: ../clients/cli/connections.c:2237
#, c-format
msgid "missing colon in 'password' entry '%s'"
msgstr "saknar kolon i ”password”-posten ”%s”"
-#: ../clients/cli/connections.c:2249
+#: ../clients/cli/connections.c:2245
#, c-format
msgid "missing dot in 'password' entry '%s'"
msgstr "saknar punkt i ”password”-posten ”%s”"
-#: ../clients/cli/connections.c:2262
+#: ../clients/cli/connections.c:2258
#, c-format
msgid "invalid setting name in 'password' entry '%s'"
msgstr "ogiltig inställning i ”password”-posten ”%s”"
-#: ../clients/cli/connections.c:2318
+#: ../clients/cli/connections.c:2314
#, c-format
msgid "unknown device '%s'."
msgstr "okänd enhet ”%s”."
-#: ../clients/cli/connections.c:2323
+#: ../clients/cli/connections.c:2319
msgid "neither a valid connection nor device given"
msgstr "ingen aktiv anslutning eller enhet angiven"
-#: ../clients/cli/connections.c:2406
+#: ../clients/cli/connections.c:2402
#, c-format
msgid "Error: Connection '%s' does not exist."
msgstr "Fel: anslutningen ”%s” finns inte."
-#: ../clients/cli/connections.c:2441 ../clients/cli/devices.c:1325
-#: ../clients/cli/devices.c:2336 ../clients/cli/devices.c:2730
-#: ../clients/cli/devices.c:3314
+#: ../clients/cli/connections.c:2437 ../clients/cli/devices.c:1325
+#: ../clients/cli/devices.c:2358 ../clients/cli/devices.c:2752
+#: ../clients/cli/devices.c:3336
#, c-format
msgid "Unknown parameter: %s\n"
msgstr "Okänd parameter: %s\n"
-#: ../clients/cli/connections.c:2466
+#: ../clients/cli/connections.c:2462
msgid "preparing"
msgstr "förbereder"
-#: ../clients/cli/connections.c:2487
+#: ../clients/cli/connections.c:2483
#, c-format
msgid "Connection '%s' (%s) successfully deleted.\n"
msgstr "Anslutningen ”%s” (%s) togs bort.\n"
-#: ../clients/cli/connections.c:2503
+#: ../clients/cli/connections.c:2499
#, c-format
msgid "Connection '%s' successfully deactivated (D-Bus active path: %s)\n"
msgstr "Anslutningen ”%s” inaktiverades (aktiv sökväg för D-Bus: %s)\n"
-#: ../clients/cli/connections.c:2574 ../clients/cli/connections.c:10395
-#: ../clients/cli/connections.c:10594
+#: ../clients/cli/connections.c:2570 ../clients/cli/connections.c:10391
+#: ../clients/cli/connections.c:10590
#, c-format
msgid "Error: No connection specified."
msgstr "Fel: Ingen anslutning angiven."
-#: ../clients/cli/connections.c:2606
+#: ../clients/cli/connections.c:2602
#, c-format
msgid "Error: '%s' is not an active connection.\n"
msgstr "Fel: ”%s” är inte en aktiv anslutning.\n"
-#: ../clients/cli/connections.c:2607 ../clients/cli/connections.c:10424
+#: ../clients/cli/connections.c:2603 ../clients/cli/connections.c:10420
#, c-format
msgid "Error: not all active connections found."
msgstr "Fel: hittade inte alla aktiva anslutningar."
-#: ../clients/cli/connections.c:2616
+#: ../clients/cli/connections.c:2612
#, c-format
msgid "Error: no active connection provided."
msgstr "Fel: inga aktiva anslutningar tillhandahållna."
-#: ../clients/cli/connections.c:2959 ../clients/cli/utils.c:648
+#: ../clients/cli/connections.c:2955 ../clients/cli/utils.c:702
#, c-format
msgid "'%s' not among [%s]"
msgstr "”%s” inte bland [%s]"
-#: ../clients/cli/connections.c:3036
+#: ../clients/cli/connections.c:3032
#, c-format
msgid "Error: '%s': '%s' is not a valid %s MAC address."
msgstr "Fel: ”%s”: ”%s” är inte en giltig %s-MAC-adress."
#. Ask for optional arguments
-#: ../clients/cli/connections.c:3037 ../clients/cli/connections.c:3569
+#: ../clients/cli/connections.c:3033 ../clients/cli/connections.c:3565
#: ../clients/tui/nm-editor-utils.c:163 ../libnm-core/nm-connection.c:1716
#: ../libnm-glib/nm-device.c:1861 ../libnm/nm-device.c:1812
msgid "InfiniBand"
msgstr "InfiniBand"
-#: ../clients/cli/connections.c:3037 ../clients/tui/nm-editor-utils.c:146
+#: ../clients/cli/connections.c:3033 ../clients/tui/nm-editor-utils.c:146
#: ../libnm-glib/nm-device.c:1849 ../libnm/nm-device.c:1800
msgid "Ethernet"
msgstr "Ethernet"
-#: ../clients/cli/connections.c:3057
+#: ../clients/cli/connections.c:3053
#, c-format
msgid "Error: 'mtu': '%s' is not a valid MTU."
msgstr "Fel: ”mtu”: ”%s” är inte ett giltigt MTU."
-#: ../clients/cli/connections.c:3073
+#: ../clients/cli/connections.c:3069
#, c-format
msgid "Error: 'parent': '%s' is not a valid interface name."
msgstr "Fel: ”parent”: ”%s” är inte ett giltigt gränssnittsnamn."
-#: ../clients/cli/connections.c:3094
+#: ../clients/cli/connections.c:3090
#, c-format
msgid "Error: 'p-key': '%s' is not a valid InfiniBand P_KEY."
msgstr "Fel: ”p-key”: ”%s” är inte en giltig InfiniBand P_KEY."
-#: ../clients/cli/connections.c:3109
+#: ../clients/cli/connections.c:3105
#, c-format
msgid "Error: '%s' is not a valid UID/GID."
msgstr "Fel: ”%s” är inte ett giltigt UID/GID."
-#: ../clients/cli/connections.c:3153
+#: ../clients/cli/connections.c:3149
#, c-format
msgid "Error: '%s': '%s' is not a valid %s %s."
msgstr "Fel: ”%s”: ”%s” är inte en giltig %s %s."
-#: ../clients/cli/connections.c:3166
+#: ../clients/cli/connections.c:3162
msgid "Wi-Fi mode"
msgstr "Wi-Fi-läge"
-#: ../clients/cli/connections.c:3175
+#: ../clients/cli/connections.c:3171
msgid "InfiniBand transport mode"
msgstr "InfiniBand transportläge"
-#: ../clients/cli/connections.c:3187
+#: ../clients/cli/connections.c:3183
msgid "ADSL protocol"
msgstr "ADSL-protokoll"
-#: ../clients/cli/connections.c:3198
+#: ../clients/cli/connections.c:3194
msgid "ADSL encapsulation"
msgstr "ADSL-inkapsling"
-#: ../clients/cli/connections.c:3207
+#: ../clients/cli/connections.c:3203
msgid "TUN device mode"
msgstr "TUN-enhetsläge"
-#: ../clients/cli/connections.c:3220
+#: ../clients/cli/connections.c:3216
#, c-format
msgid "Error: 'flags': '%s' is not valid; use <0-7>."
msgstr "Fel: ”flags”: ”%s” är inte giltig; använd <0-7>."
-#: ../clients/cli/connections.c:3242
+#: ../clients/cli/connections.c:3238
#, c-format
msgid "Error: '%s': '%s' is not valid; %s "
msgstr "Fel: ”%s”: ”%s” är inte giltig; %s "
-#: ../clients/cli/connections.c:3420
+#: ../clients/cli/connections.c:3416
#, c-format
msgid "Warning: master='%s' doesn't refer to any existing profile.\n"
msgstr "Varning: master=”%s” hänvisar inte till någon befintlig profil.\n"
-#: ../clients/cli/connections.c:3445
+#: ../clients/cli/connections.c:3441
#, c-format
msgid "Error: '%s': '%s' is not valid; use <%u-%u>."
msgstr "Fel: ”%s”: ”%s” är inte giltig; använd <%u-%u>."
#. Ask for optional arguments.
-#: ../clients/cli/connections.c:3501
+#: ../clients/cli/connections.c:3497
#, c-format
msgid "There is %d optional argument for '%s' connection type.\n"
msgid_plural "There are %d optional arguments for '%s' connection type.\n"
msgstr[0] "Det finns %d valfritt argument för anslutningstypen ”%s”.\n"
msgstr[1] "Det finns %d valfria argument för anslutningstypen ”%s”.\n"
-#: ../clients/cli/connections.c:3504
+#: ../clients/cli/connections.c:3500
#, c-format
msgid "Do you want to provide it? %s"
msgid_plural "Do you want to provide them? %s"
@@ -1950,879 +1949,879 @@ msgstr[0] "Vill du tillhandahålla det? %s"
msgstr[1] "Vill du tillhandahålla dem? %s"
#. Ask for optional arguments
-#: ../clients/cli/connections.c:3521
+#: ../clients/cli/connections.c:3517
msgid "ethernet"
msgstr "ethernet"
-#: ../clients/cli/connections.c:3526 ../clients/cli/connections.c:3574
-#: ../clients/cli/connections.c:3708 ../clients/cli/connections.c:3787
+#: ../clients/cli/connections.c:3522 ../clients/cli/connections.c:3570
+#: ../clients/cli/connections.c:3704 ../clients/cli/connections.c:3783
msgid "MTU [auto]: "
msgstr "MTU [auto]: "
-#: ../clients/cli/connections.c:3537 ../clients/cli/connections.c:3585
-#: ../clients/cli/connections.c:3680 ../clients/cli/connections.c:3719
-#: ../clients/cli/connections.c:4105
+#: ../clients/cli/connections.c:3533 ../clients/cli/connections.c:3581
+#: ../clients/cli/connections.c:3676 ../clients/cli/connections.c:3715
+#: ../clients/cli/connections.c:4101
msgid "MAC [none]: "
msgstr "MAC [ingen]: "
-#: ../clients/cli/connections.c:3548
+#: ../clients/cli/connections.c:3544
msgid "Cloned MAC [none]: "
msgstr "Klonad MAC [ingen]: "
-#: ../clients/cli/connections.c:3596
+#: ../clients/cli/connections.c:3592
#, c-format
msgid "Transport mode %s"
msgstr "Transportläge %s"
-#: ../clients/cli/connections.c:3609
+#: ../clients/cli/connections.c:3605
msgid "Parent interface [none]: "
msgstr "Överordnat gränssnitt [inget]: "
-#: ../clients/cli/connections.c:3620
+#: ../clients/cli/connections.c:3616
msgid "P_KEY [none]: "
msgstr "P_KEY [ingen]: "
-#: ../clients/cli/connections.c:3630
+#: ../clients/cli/connections.c:3626
#, c-format
msgid "Error: 'p-key' is mandatory when 'parent' is specified.\n"
msgstr "Fel: ”p-key” är obligatoriskt när ”parent” är angett.\n"
#. Ask for optional arguments
-#: ../clients/cli/connections.c:3647 ../clients/tui/nm-editor-utils.c:154
+#: ../clients/cli/connections.c:3643 ../clients/tui/nm-editor-utils.c:154
#: ../libnm-glib/nm-device.c:1851 ../libnm/nm-device.c:1802
msgid "Wi-Fi"
msgstr "Wi-Fi"
-#: ../clients/cli/connections.c:3655 ../clients/cli/connections.c:6203
+#: ../clients/cli/connections.c:3651 ../clients/cli/connections.c:6199
#, c-format
msgid "Mode %s"
msgstr "Läge %s"
#. Ask for optional 'wimax' arguments.
-#: ../clients/cli/connections.c:3675 ../libnm-glib/nm-device.c:1857
+#: ../clients/cli/connections.c:3671 ../libnm-glib/nm-device.c:1857
#: ../libnm/nm-device.c:1808
msgid "WiMAX"
msgstr "WiMAX"
#. Ask for optional 'pppoe' arguments.
-#: ../clients/cli/connections.c:3698
+#: ../clients/cli/connections.c:3694
msgid "PPPoE"
msgstr "PPPoE"
-#: ../clients/cli/connections.c:3702 ../clients/cli/connections.c:3740
-#: ../clients/cli/connections.c:4227
+#: ../clients/cli/connections.c:3698 ../clients/cli/connections.c:3736
+#: ../clients/cli/connections.c:4223
msgid "Password [none]: "
msgstr "Lösenord [inget]: "
-#: ../clients/cli/connections.c:3704
+#: ../clients/cli/connections.c:3700
msgid "Service [none]: "
msgstr "Tjänst [ingen]: "
#. Ask for optional 'gsm' or 'cdma' arguments.
-#: ../clients/cli/connections.c:3734
+#: ../clients/cli/connections.c:3730
msgid "mobile broadband"
msgstr "mobilt bredband"
-#: ../clients/cli/connections.c:3738 ../clients/cli/connections.c:4177
+#: ../clients/cli/connections.c:3734 ../clients/cli/connections.c:4173
msgid "Username [none]: "
msgstr "Användarnamn [inget]: "
#. Ask for optional 'bluetooth' arguments.
-#: ../clients/cli/connections.c:3753
+#: ../clients/cli/connections.c:3749
msgid "bluetooth"
msgstr "bluetooth"
-#: ../clients/cli/connections.c:3760
+#: ../clients/cli/connections.c:3756
#, c-format
msgid "Bluetooth type %s"
msgstr "Bluetooth-typen %s"
-#: ../clients/cli/connections.c:3766
+#: ../clients/cli/connections.c:3762
#, c-format
msgid "Error: 'bt-type': '%s' is not a valid bluetooth type.\n"
msgstr "Fel: ”bt-type”: ”%s” är inte en giltig Bluetoothtyp.\n"
#. Ask for optional 'vlan' arguments.
#. 13
-#: ../clients/cli/connections.c:3782 ../clients/cli/devices.c:239
+#: ../clients/cli/connections.c:3778 ../clients/cli/devices.c:239
#: ../clients/tui/nm-editor-utils.c:217 ../clients/tui/nmt-page-vlan.c:94
#: ../libnm-core/nm-connection.c:1714 ../libnm-glib/nm-device.c:1869
#: ../libnm-util/nm-connection.c:1632 ../libnm/nm-device.c:1820
msgid "VLAN"
msgstr "VLAN"
-#: ../clients/cli/connections.c:3798
+#: ../clients/cli/connections.c:3794
msgid "VLAN flags (<0-7>) [none]: "
msgstr "VLAN-flaggor (<0-7>) [inga]: "
-#: ../clients/cli/connections.c:3809
+#: ../clients/cli/connections.c:3805
msgid "Ingress priority maps [none]: "
msgstr "Inträdesprioritetshash [ingen]: "
-#: ../clients/cli/connections.c:3820
+#: ../clients/cli/connections.c:3816
msgid "Egress priority maps [none]: "
msgstr "Utträdesprioritetshash [ingen]: "
-#: ../clients/cli/connections.c:3831
+#: ../clients/cli/connections.c:3827
msgid "Bonding mode [balance-rr]: "
msgstr "Kombineringsläge [balance-rr]: "
#. Ask for optional 'bond' arguments.
-#: ../clients/cli/connections.c:3847
+#: ../clients/cli/connections.c:3843
msgid "bond"
msgstr "kombinera"
-#: ../clients/cli/connections.c:3869
+#: ../clients/cli/connections.c:3865
msgid "Bonding primary interface [none]: "
msgstr "Primärt kombineringsgränssnitt [inget]: "
-#: ../clients/cli/connections.c:3872
+#: ../clients/cli/connections.c:3868
#, c-format
msgid "Error: 'primary': '%s' is not a valid interface name.\n"
msgstr "Fel: ”primary”: ”%s” är inte ett giltigt gränssnittsnamn.\n"
-#: ../clients/cli/connections.c:3880
+#: ../clients/cli/connections.c:3876
#, c-format
msgid "Bonding monitoring mode %s"
msgstr "Övervakningsläge %s för kombinering"
-#: ../clients/cli/connections.c:3886
+#: ../clients/cli/connections.c:3882
#, c-format
msgid "Error: '%s' is not a valid monitoring mode; use '%s' or '%s'.\n"
msgstr ""
"Fel: ”%s”: är inte ett giltigt övervakningsläge; använd ”%s” eller ”%s”.\n"
-#: ../clients/cli/connections.c:3895
+#: ../clients/cli/connections.c:3891
msgid "Bonding miimon [100]: "
msgstr "Kombinerings-miimon [100]: "
-#: ../clients/cli/connections.c:3898
+#: ../clients/cli/connections.c:3894
#, c-format
msgid "Error: 'miimon': '%s' is not a valid number <0-%u>.\n"
msgstr "Fel: ”miimon” : ”%s” är inte ett giltigt nummer <0-%u>.\n"
-#: ../clients/cli/connections.c:3906
+#: ../clients/cli/connections.c:3902
msgid "Bonding downdelay [0]: "
msgstr "Nedfördröjning för kombinering [0]: "
-#: ../clients/cli/connections.c:3909
+#: ../clients/cli/connections.c:3905
#, c-format
msgid "Error: 'downdelay': '%s' is not a valid number <0-%u>.\n"
msgstr "Fel: ”downdelay”: ”%s” är inte ett giltigt nummer <0-%u>.\n"
-#: ../clients/cli/connections.c:3917
+#: ../clients/cli/connections.c:3913
msgid "Bonding updelay [0]: "
msgstr "Uppfördröjning för kombinering [0]: "
-#: ../clients/cli/connections.c:3920
+#: ../clients/cli/connections.c:3916
#, c-format
msgid "Error: 'updelay': '%s' is not a valid number <0-%u>.\n"
msgstr "Fel: ”updelay”: ”%s” är inte ett giltigt nummer <0-%u>.\n"
-#: ../clients/cli/connections.c:3929
+#: ../clients/cli/connections.c:3925
msgid "Bonding arp-interval [0]: "
msgstr "arp-intervall för kombinering [0]: "
-#: ../clients/cli/connections.c:3932
+#: ../clients/cli/connections.c:3928
#, c-format
msgid "Error: 'arp-interval': '%s' is not a valid number <0-%u>.\n"
msgstr "Fel: ”arp-interval”: ”%s” är inte ett giltigt nummer <0-%u>.\n"
#. FIXME: verify the string
-#: ../clients/cli/connections.c:3940
+#: ../clients/cli/connections.c:3936
msgid "Bonding arp-ip-target [none]: "
msgstr "arp-ip-target för kombinering [inget]: "
-#: ../clients/cli/connections.c:3947
+#: ../clients/cli/connections.c:3943
msgid "LACP rate ('slow' or 'fast') [slow]: "
msgstr "LACP-hastighet (\"slow\" eller \"fast\") [slow]: "
-#: ../clients/cli/connections.c:3953
+#: ../clients/cli/connections.c:3949
#, c-format
msgid "Error: 'lacp_rate': '%s' is invalid ('slow' or 'fast').\n"
msgstr "Fel: ”lacp-rate”: ”%s” är ogiltig (”slow” eller ”fast”).\n"
-#: ../clients/cli/connections.c:3976
+#: ../clients/cli/connections.c:3972
msgid "Team JSON configuration [none]: "
msgstr "JSON-konfiguration för grupp [ingen]: "
-#: ../clients/cli/connections.c:3993
+#: ../clients/cli/connections.c:3989
msgid "team"
msgstr "grupp"
-#: ../clients/cli/connections.c:3999
+#: ../clients/cli/connections.c:3995
msgid "team-slave"
msgstr "grupp-slav"
#. Ask for optional 'bridge' arguments.
-#: ../clients/cli/connections.c:4011
+#: ../clients/cli/connections.c:4007
msgid "bridge"
msgstr "brygga"
-#: ../clients/cli/connections.c:4017
+#: ../clients/cli/connections.c:4013
#, c-format
msgid "Enable STP %s"
msgstr "Aktivera STP %s"
-#: ../clients/cli/connections.c:4022
+#: ../clients/cli/connections.c:4018
#, c-format
msgid "Error: 'stp': %s.\n"
msgstr "Fel: ”stp”: %s.\n"
-#: ../clients/cli/connections.c:4030
+#: ../clients/cli/connections.c:4026
msgid "STP priority [32768]: "
msgstr "STP-prioritet [32768]: "
-#: ../clients/cli/connections.c:4034
+#: ../clients/cli/connections.c:4030
#, c-format
msgid "Error: 'priority': '%s' is not a valid number <0-%d>.\n"
msgstr "Fel: ”priority”: ”%s” är inte ett giltigt nummer <0-%d>.\n"
-#: ../clients/cli/connections.c:4042
+#: ../clients/cli/connections.c:4038
msgid "Forward delay [15]: "
msgstr "Framåtfördröjning [15]: "
-#: ../clients/cli/connections.c:4046
+#: ../clients/cli/connections.c:4042
#, c-format
msgid "Error: 'forward-delay': '%s' is not a valid number <2-30>.\n"
msgstr "Fel: ”forward-delay”: ”%s” är inte ett giltigt nummer <2-30>.\n"
-#: ../clients/cli/connections.c:4055
+#: ../clients/cli/connections.c:4051
msgid "Hello time [2]: "
msgstr "Hallå-tid [2]: "
-#: ../clients/cli/connections.c:4059
+#: ../clients/cli/connections.c:4055
#, c-format
msgid "Error: 'hello-time': '%s' is not a valid number <1-10>.\n"
msgstr "Fel: ”hello-time”: ”%s” är inte ett giltigt nummer <1-10>.\n"
-#: ../clients/cli/connections.c:4067
+#: ../clients/cli/connections.c:4063
msgid "Max age [20]: "
msgstr "Max ålder [20]: "
-#: ../clients/cli/connections.c:4071
+#: ../clients/cli/connections.c:4067
#, c-format
msgid "Error: 'max-age': '%s' is not a valid number <6-40>.\n"
msgstr "Fel: ”max-age”: ”%s” är inte ett giltig nummer <6-40>.\n"
-#: ../clients/cli/connections.c:4079
+#: ../clients/cli/connections.c:4075
msgid "MAC address ageing time [300]: "
msgstr "Livstid för MAC-adress [300]: "
-#: ../clients/cli/connections.c:4083
+#: ../clients/cli/connections.c:4079
#, c-format
msgid "Error: 'ageing-time': '%s' is not a valid number <0-1000000>.\n"
msgstr "Fel: ”ageing-time”: ”%s” är inte ett giltig nummer <0-1000000>.\n"
-#: ../clients/cli/connections.c:4092
+#: ../clients/cli/connections.c:4088
#, c-format
msgid "Enable IGMP snooping %s"
msgstr "Aktivera IGMP-avlyssning %s"
-#: ../clients/cli/connections.c:4097
+#: ../clients/cli/connections.c:4093
#, c-format
msgid "Error: 'multicast-snooping': %s.\n"
msgstr "Fel: ”multicast-avlyssning”: %s.\n"
#. Ask for optional 'bridge-slave' arguments.
-#: ../clients/cli/connections.c:4124
+#: ../clients/cli/connections.c:4120
msgid "bridge-slave"
msgstr "brygga-slav"
-#: ../clients/cli/connections.c:4129
+#: ../clients/cli/connections.c:4125
msgid "Bridge port priority [32]: "
msgstr "Prioritet för bryggport [32]: "
-#: ../clients/cli/connections.c:4142
+#: ../clients/cli/connections.c:4138
msgid "Bridge port STP path cost [100]: "
msgstr "STP-sökvägskostnad för bryggport [100]: "
-#: ../clients/cli/connections.c:4156
+#: ../clients/cli/connections.c:4152
#, c-format
msgid "Hairpin %s"
msgstr "Hårnål %s"
-#: ../clients/cli/connections.c:4161
+#: ../clients/cli/connections.c:4157
#, c-format
msgid "Error: 'hairpin': %s.\n"
msgstr "Fel: ”hairpin”: %s.\n"
#. Ask for optional 'olpc' arguments.
-#: ../clients/cli/connections.c:4188 ../libnm-glib/nm-device.c:1855
+#: ../clients/cli/connections.c:4184 ../libnm-glib/nm-device.c:1855
#: ../libnm/nm-device.c:1806
msgid "OLPC Mesh"
msgstr "OLPC-mesh"
-#: ../clients/cli/connections.c:4193
+#: ../clients/cli/connections.c:4189
msgid "OLPC Mesh channel [1]: "
msgstr "OLPC-meshkanal [1]: "
-#: ../clients/cli/connections.c:4196
+#: ../clients/cli/connections.c:4192
#, c-format
msgid "Error: 'channel': '%s' is not a valid number <1-13>.\n"
msgstr "Fel: ”channel”: ”%s” är inte ett giltigt nummer <1-13>.\n"
-#: ../clients/cli/connections.c:4204
+#: ../clients/cli/connections.c:4200
msgid "DHCP anycast MAC address [none]: "
msgstr "DHCP-anycast MAC-adress [ingen]: "
#. Ask for optional 'adsl' arguments.
-#: ../clients/cli/connections.c:4223 ../libnm-glib/nm-device.c:1871
+#: ../clients/cli/connections.c:4219 ../libnm-glib/nm-device.c:1871
#: ../libnm/nm-device.c:1822
msgid "ADSL"
msgstr "ADSL"
-#: ../clients/cli/connections.c:4231
+#: ../clients/cli/connections.c:4227
#, c-format
msgid "ADSL encapsulation %s"
msgstr "ADSL-inkapsling %s"
#. Ask for optional 'macvlan' arguments.
-#: ../clients/cli/connections.c:4249
+#: ../clients/cli/connections.c:4245
msgid "macvlan"
msgstr "macvlan"
-#: ../clients/cli/connections.c:4255
+#: ../clients/cli/connections.c:4251
#, c-format
msgid "Tap %s"
msgstr "Tap %s"
-#: ../clients/cli/connections.c:4260
+#: ../clients/cli/connections.c:4256
#, c-format
msgid "Error: 'tap': %s.\n"
msgstr "Fel: ”tap”: %s.\n"
#. Ask for optional 'vxlan' arguments.
-#: ../clients/cli/connections.c:4276 ../libnm-glib/nm-device.c:1875
+#: ../clients/cli/connections.c:4272 ../libnm-glib/nm-device.c:1875
#: ../libnm/nm-device.c:1826
msgid "VXLAN"
msgstr "VXLAN"
-#: ../clients/cli/connections.c:4281 ../clients/cli/connections.c:4605
+#: ../clients/cli/connections.c:4277 ../clients/cli/connections.c:4601
msgid "Parent device [none]: "
msgstr "Överordnad enhet [ingen]: "
-#: ../clients/cli/connections.c:4286 ../clients/cli/connections.c:4610
+#: ../clients/cli/connections.c:4282 ../clients/cli/connections.c:4606
#, c-format
msgid "Error: 'dev': '%s' is neither UUID nor interface name.\n"
msgstr "Fel: ”dev”: ”%s” är varken UUID eller gränssnittsnamn.\n"
-#: ../clients/cli/connections.c:4295
+#: ../clients/cli/connections.c:4291
msgid "Local address [none]: "
msgstr "Lokal adress [ingen]: "
-#: ../clients/cli/connections.c:4300
+#: ../clients/cli/connections.c:4296
#, c-format
msgid "Error: 'local': '%s' is not a valid IP address.\n"
msgstr "Fel: ”local”: ”%s” är inte en giltig IP-adress.\n"
-#: ../clients/cli/connections.c:4309
+#: ../clients/cli/connections.c:4305
msgid "Minimum source port [0]: "
msgstr "Lägsta källport [0]: "
-#: ../clients/cli/connections.c:4313
+#: ../clients/cli/connections.c:4309
#, c-format
msgid "Error: 'source-port-min': '%s' is not a valid number <0-65535>.\n"
msgstr "Fel: ”source-port-min”: ”%s” är inte ett giltigt nummer <0-65535>.\n"
-#: ../clients/cli/connections.c:4322
+#: ../clients/cli/connections.c:4318
msgid "Maximum source port [0]: "
msgstr "Högsta källport [0]: "
-#: ../clients/cli/connections.c:4326
+#: ../clients/cli/connections.c:4322
#, c-format
msgid "Error: 'source-port-max': '%s' is not a valid number <0-65535>.\n"
msgstr "Fel: ”source-port-max”: ”%s” är inte ett giltigt nummer <0-65535>.\n"
-#: ../clients/cli/connections.c:4335
+#: ../clients/cli/connections.c:4331
msgid "Destination port [8472]: "
msgstr "Destinationsport [8472]: "
-#: ../clients/cli/connections.c:4339
+#: ../clients/cli/connections.c:4335
#, c-format
msgid "Error: 'destination-port': '%s' is not a valid number <0-65535>.\n"
msgstr ""
"Fel: ”destination-port” : ”%s” är inte ett giltigt nummer <0-65535>.\n"
-#: ../clients/cli/connections.c:4378
+#: ../clients/cli/connections.c:4374
msgid "IPv4 address (IP[/plen]) [none]: "
msgstr "IPv4-adress (IP[/plen]) [ingen]: "
-#: ../clients/cli/connections.c:4380
+#: ../clients/cli/connections.c:4376
msgid "IPv6 address (IP[/plen]) [none]: "
msgstr "IPv6-adress (IP[/plen]) [ingen]: "
-#: ../clients/cli/connections.c:4394
+#: ../clients/cli/connections.c:4390
#, c-format
msgid " Address successfully added: %s\n"
msgstr " Adress lades till: %s\n"
-#: ../clients/cli/connections.c:4396
+#: ../clients/cli/connections.c:4392
#, c-format
msgid " Warning: address already present: %s\n"
msgstr " Varning: adressen finns redan: %s\n"
-#: ../clients/cli/connections.c:4398
+#: ../clients/cli/connections.c:4394
#, c-format
msgid " Warning: ignoring garbage at the end: '%s'\n"
msgstr " Varning: ignorerar skräp på slutet: ”%s”\n"
-#: ../clients/cli/connections.c:4400 ../clients/cli/connections.c:5609
-#: ../clients/cli/connections.c:5656 ../clients/cli/connections.c:6573
-#: ../clients/cli/connections.c:6606
+#: ../clients/cli/connections.c:4396 ../clients/cli/connections.c:5605
+#: ../clients/cli/connections.c:5652 ../clients/cli/connections.c:6569
+#: ../clients/cli/connections.c:6602
msgid "Error: "
msgstr "Fel: "
-#: ../clients/cli/connections.c:4420
+#: ../clients/cli/connections.c:4416
msgid "IPv4 gateway [none]: "
msgstr "IPv4-gateway [ingen]: "
-#: ../clients/cli/connections.c:4423
+#: ../clients/cli/connections.c:4419
msgid "IPv6 gateway [none]: "
msgstr "IPv6-gateway [ingen]: "
-#: ../clients/cli/connections.c:4443
+#: ../clients/cli/connections.c:4439
#, c-format
msgid "Error: invalid gateway address '%s'\n"
msgstr "Fel: ogiltig gateway-adress ”%s”\n"
#. Ask for IP addresses
-#: ../clients/cli/connections.c:4456
+#: ../clients/cli/connections.c:4452
#, c-format
msgid "Do you want to add IP addresses? %s"
msgstr "Vill du lägga till IP-adresser? %s"
-#: ../clients/cli/connections.c:4464
+#: ../clients/cli/connections.c:4460
#, c-format
msgid "Press <Enter> to finish adding addresses.\n"
msgstr "Tryck <Retur> för att sluta lägga till adresser.\n"
#. Ask for optional 'tun' arguments.
-#: ../clients/cli/connections.c:4508 ../libnm-glib/nm-device.c:1879
+#: ../clients/cli/connections.c:4504 ../libnm-glib/nm-device.c:1879
#: ../libnm/nm-device.c:1830
msgid "Tun"
msgstr "Tun"
-#: ../clients/cli/connections.c:4513
+#: ../clients/cli/connections.c:4509
msgid "User ID [none]: "
msgstr "Användar-ID [inget]: "
-#: ../clients/cli/connections.c:4526
+#: ../clients/cli/connections.c:4522
msgid "Group ID [none]: "
msgstr "Grupp-ID [inget]: "
-#: ../clients/cli/connections.c:4540
+#: ../clients/cli/connections.c:4536
#, c-format
msgid "Enable PI %s"
msgstr "Aktivera PI %s"
-#: ../clients/cli/connections.c:4545
+#: ../clients/cli/connections.c:4541
#, c-format
msgid "Error: 'pi': %s.\n"
msgstr "Fel: ”pi”: %s.\n"
-#: ../clients/cli/connections.c:4553
+#: ../clients/cli/connections.c:4549
#, c-format
msgid "Enable VNET header %s"
msgstr "Aktivera VNET-huvud %s"
-#: ../clients/cli/connections.c:4558
+#: ../clients/cli/connections.c:4554
#, c-format
msgid "Error: 'vnet-hdr': %s.\n"
msgstr "Fel: ”vnet-hdr”: %s.\n"
-#: ../clients/cli/connections.c:4566
+#: ../clients/cli/connections.c:4562
#, c-format
msgid "Enable multi queue %s"
msgstr "Aktivera multikö %s"
-#: ../clients/cli/connections.c:4571
+#: ../clients/cli/connections.c:4567
#, c-format
msgid "Error: 'multi-queue': %s.\n"
msgstr "Fel: ”multi-queue”: %s.\n"
#. Ask for optional 'ip-tunnel' arguments.
-#: ../clients/cli/connections.c:4585
+#: ../clients/cli/connections.c:4581
msgid "IP Tunnel"
msgstr "IP-tunnel"
-#: ../clients/cli/connections.c:4590
+#: ../clients/cli/connections.c:4586
msgid "Local endpoint [none]: "
msgstr "Lokal ändpunkt [ingen]: "
-#: ../clients/cli/connections.c:4596
+#: ../clients/cli/connections.c:4592
#, c-format
msgid "Error: 'local': '%s' is not valid; must be an IP address\n"
msgstr "Fel: ”local”: ”%s” är inte giltig, måste vara en IP-adress\n"
-#: ../clients/cli/connections.c:4662 ../clients/cli/connections.c:10188
+#: ../clients/cli/connections.c:4658 ../clients/cli/connections.c:10184
#, c-format
msgid "Error: <setting>.<property> argument is missing."
msgstr "Fel: <inställning>.<egenskap>-argument saknas."
-#: ../clients/cli/connections.c:4667
+#: ../clients/cli/connections.c:4663
#, c-format
msgid "Error: value for '%s' is missing."
msgstr "Fel: värdet för ”%s” saknas."
-#: ../clients/cli/connections.c:4685
+#: ../clients/cli/connections.c:4681
#, c-format
msgid "Error: invalid <setting>.<property> '%s'."
msgstr "Fel: ogiltig <inställning>.<egenskap> ”%s”."
-#: ../clients/cli/connections.c:4693
+#: ../clients/cli/connections.c:4689
#, c-format
msgid "Error: invalid or not allowed setting '%s': %s."
msgstr "Fel: ogiltig eller ej tillåten inställning: ”%s”: %s."
-#: ../clients/cli/connections.c:4704
+#: ../clients/cli/connections.c:4700
#, c-format
msgid "Error: don't know how to create '%s' setting."
msgstr "Fel: vet inte hur man skapar en ”%s”-inställning."
-#: ../clients/cli/connections.c:4714
+#: ../clients/cli/connections.c:4710
#, c-format
msgid "Error: invalid property '%s': %s."
msgstr "Fel: ogiltig egenskap ”%s”: %s."
-#: ../clients/cli/connections.c:4726
+#: ../clients/cli/connections.c:4722
#, c-format
msgid "Error: failed to modify %s.%s: %s."
msgstr "Fel: misslyckades med att ändra %s.%s: %s."
-#: ../clients/cli/connections.c:4745
+#: ../clients/cli/connections.c:4741
#, c-format
msgid "Error: failed to remove a value from %s.%s: %s."
msgstr "Fel: misslyckades att ta bort ett värde från %s.%s: %s."
-#: ../clients/cli/connections.c:4779
+#: ../clients/cli/connections.c:4775
#, c-format
msgid ""
"Warning: 'type' is ignored. Use 'nmcli connection add \"%s\" ...' instead."
msgstr ""
"Varning: ”type” ignoreras. Använd ”nmcli connection add \"%s\"…” istället."
-#: ../clients/cli/connections.c:4787
+#: ../clients/cli/connections.c:4783
msgid "Error: redundant 'master' option."
msgstr "Fel: redundant ”master”-flagga."
-#: ../clients/cli/connections.c:4800
+#: ../clients/cli/connections.c:4796
msgid "Error: 'master' is required."
msgstr "Fel: ”master” krävs."
-#: ../clients/cli/connections.c:4954
+#: ../clients/cli/connections.c:4950
#, c-format
msgid "Error: 'parent': not valid without 'p-key'."
msgstr "Fel: ”parent”: inte giltig utan ”p-key”."
-#: ../clients/cli/connections.c:5009 ../clients/cli/connections.c:5971
+#: ../clients/cli/connections.c:5005 ../clients/cli/connections.c:5967
msgid "SSID: "
msgstr "SSID: "
-#: ../clients/cli/connections.c:5012 ../clients/cli/connections.c:5974
+#: ../clients/cli/connections.c:5008 ../clients/cli/connections.c:5970
msgid "Error: 'ssid' is required."
msgstr "Fel: ”ssid” krävs."
-#: ../clients/cli/connections.c:5076
+#: ../clients/cli/connections.c:5072
msgid "WiMAX NSP name: "
msgstr "WiMAX NSP-lista: "
-#: ../clients/cli/connections.c:5079
+#: ../clients/cli/connections.c:5075
msgid "Error: 'nsp' is required."
msgstr "Fel: ”nsp” krävs."
-#: ../clients/cli/connections.c:5131
+#: ../clients/cli/connections.c:5127
msgid "PPPoE username: "
msgstr "PPPoE-användarnamn: "
-#: ../clients/cli/connections.c:5134 ../clients/cli/connections.c:6041
+#: ../clients/cli/connections.c:5130 ../clients/cli/connections.c:6037
msgid "Error: 'username' is required."
msgstr "Fel: ”username” krävs."
-#: ../clients/cli/connections.c:5203
+#: ../clients/cli/connections.c:5199
msgid "APN: "
msgstr "APN: "
-#: ../clients/cli/connections.c:5206
+#: ../clients/cli/connections.c:5202
msgid "Error: 'apn' is required."
msgstr "Fel: ”apn” krävs."
-#: ../clients/cli/connections.c:5264
+#: ../clients/cli/connections.c:5260
msgid "Bluetooth device address: "
msgstr "Adress för Bluetooth-enhet: "
-#: ../clients/cli/connections.c:5267
+#: ../clients/cli/connections.c:5263
msgid "Error: 'addr' is required."
msgstr "Fel: ”addr” krävs."
-#: ../clients/cli/connections.c:5308
+#: ../clients/cli/connections.c:5304
#, c-format
msgid "Error: 'bt-type': '%s' not valid; use [%s, %s (%s), %s]."
msgstr "Fel: ”bt-type”: ”%s” inte giltig; använd [%s, %s (%s), %s]."
-#: ../clients/cli/connections.c:5352
+#: ../clients/cli/connections.c:5348
msgid "VLAN parent device or connection UUID: "
msgstr "Överordnad VLAN-enhet eller anslutnings-UUID: "
-#: ../clients/cli/connections.c:5355 ../clients/cli/connections.c:6112
+#: ../clients/cli/connections.c:5351 ../clients/cli/connections.c:6108
msgid "Error: 'dev' is required."
msgstr "Fel: ”dev” krävs."
-#: ../clients/cli/connections.c:5359
+#: ../clients/cli/connections.c:5355
msgid "VLAN ID <0-4094>: "
msgstr "VLAN-ID <0-4094>: "
-#: ../clients/cli/connections.c:5362 ../clients/cli/connections.c:6428
+#: ../clients/cli/connections.c:5358 ../clients/cli/connections.c:6424
msgid "Error: 'id' is required."
msgstr "Fel: ”id” krävs."
-#: ../clients/cli/connections.c:5368
+#: ../clients/cli/connections.c:5364
#, c-format
msgid "Error: 'id': '%s' is not valid; use <0-4094>."
msgstr "Fel: ”id”: ”%s” är inte giltigt: använd <0-4094>."
-#: ../clients/cli/connections.c:5378 ../clients/cli/connections.c:6120
+#: ../clients/cli/connections.c:5374 ../clients/cli/connections.c:6116
#, c-format
msgid "Error: 'dev': '%s' is neither UUID, interface name, nor MAC."
msgstr "Fel: ”dev”: ”%s” är varken UUID, gränssnittsnamn eller MAC."
-#: ../clients/cli/connections.c:5510
+#: ../clients/cli/connections.c:5506
#, c-format
msgid "Error: 'mode': %s."
msgstr "Fel: ”mode”: %s."
-#: ../clients/cli/connections.c:5519
+#: ../clients/cli/connections.c:5515
#, c-format
msgid "Error: 'primary': '%s' is not a valid interface name."
msgstr "Fel: ”primary”: ”%s” är inte ett giltigt gränssnittsnamn."
-#: ../clients/cli/connections.c:5742
+#: ../clients/cli/connections.c:5738
#, c-format
msgid "Error: 'stp': %s."
msgstr "Fel: ”stp”: %s."
-#: ../clients/cli/connections.c:5751
+#: ../clients/cli/connections.c:5747
#, c-format
msgid "Error: 'multicast-snooping': %s."
msgstr "Fel: ”multicast-avlyssning”: %s."
-#: ../clients/cli/connections.c:5870
+#: ../clients/cli/connections.c:5866
#, c-format
msgid "Error: 'hairpin': %s."
msgstr "Fel: ”hairpin”: %s."
-#: ../clients/cli/connections.c:5919
+#: ../clients/cli/connections.c:5915
msgid "Error: 'vpn-type' is required."
msgstr "Fel: ”vpn-type” krävs."
-#: ../clients/cli/connections.c:5926
+#: ../clients/cli/connections.c:5922
#, c-format
msgid "Warning: 'vpn-type': %s not known.\n"
msgstr "Varning: ”vpn-type”: %s okänd.\n"
-#: ../clients/cli/connections.c:5987
+#: ../clients/cli/connections.c:5983
#, c-format
msgid "Error: 'channel': '%s' is not valid; use <1-13>."
msgstr "Fel: ”channel”: ”%s” är inte giltigt; använd <1-13>."
-#: ../clients/cli/connections.c:6038
+#: ../clients/cli/connections.c:6034
msgid "Username: "
msgstr "Användarnamn: "
-#: ../clients/cli/connections.c:6047
+#: ../clients/cli/connections.c:6043
#, c-format
msgid "Protocol %s"
msgstr "Protokoll %s"
-#: ../clients/cli/connections.c:6050
+#: ../clients/cli/connections.c:6046
msgid "Error: 'protocol' is required."
msgstr "Fel: ”protocol” krävs."
-#: ../clients/cli/connections.c:6109
+#: ../clients/cli/connections.c:6105
msgid "MACVLAN parent device or connection UUID: "
msgstr "Överordnad MACVLAN-enhet eller anslutnings-UUID: "
-#: ../clients/cli/connections.c:6129 ../clients/cli/connections.c:6209
-#: ../clients/cli/connections.c:6311
+#: ../clients/cli/connections.c:6125 ../clients/cli/connections.c:6205
+#: ../clients/cli/connections.c:6307
msgid "Error: 'mode' is required."
msgstr "Fel: ”mode” krävs."
-#: ../clients/cli/connections.c:6135
+#: ../clients/cli/connections.c:6131
msgid "Error: 'mode' is not valid."
msgstr "Fel: ”mode” är inte giltigt."
-#: ../clients/cli/connections.c:6148
+#: ../clients/cli/connections.c:6144
#, c-format
msgid "Error: 'tap': %s."
msgstr "Fel: ”tap”: %s."
-#: ../clients/cli/connections.c:6234
+#: ../clients/cli/connections.c:6230
#, c-format
msgid "Error: 'pi': %s."
msgstr "Fel: ”pi”: %s."
-#: ../clients/cli/connections.c:6245
+#: ../clients/cli/connections.c:6241
#, c-format
msgid "Error: 'vnet-hdr': %s."
msgstr "Fel: ”vnet-hdr”: %s."
-#: ../clients/cli/connections.c:6256
+#: ../clients/cli/connections.c:6252
#, c-format
msgid "Error: 'multi-queue': %s."
msgstr "Fel: ”multi-queue”: %s."
-#: ../clients/cli/connections.c:6325
+#: ../clients/cli/connections.c:6321
#, c-format
msgid "Error: 'mode': '%s' is not valid, use one of %s"
msgstr "Fel: ”mode”: ”%s” är inte giltigt, använd ett av %s"
-#: ../clients/cli/connections.c:6331
+#: ../clients/cli/connections.c:6327
msgid "Remote endpoint: "
msgstr "Fjärrändpunkt: "
-#: ../clients/cli/connections.c:6334 ../clients/cli/connections.c:6436
+#: ../clients/cli/connections.c:6330 ../clients/cli/connections.c:6432
msgid "Error: 'remote' is required."
msgstr "Fel: ”remote” krävs."
-#: ../clients/cli/connections.c:6341
+#: ../clients/cli/connections.c:6337
#, c-format
msgid "Error: 'remote': '%s' is not valid; must be an IP address"
msgstr "Fel: ”remote”: ”%s” är inte giltig, måste vara en IP-adress"
-#: ../clients/cli/connections.c:6355
+#: ../clients/cli/connections.c:6351
#, c-format
msgid "Error: 'local': '%s' is not valid; must be an IP address"
msgstr "Fel: ”local”: ”%s” är inte giltig, måste vara en IP-adress"
-#: ../clients/cli/connections.c:6364 ../clients/cli/connections.c:6459
+#: ../clients/cli/connections.c:6360 ../clients/cli/connections.c:6455
#, c-format
msgid "Error: 'dev': '%s' is neither UUID nor interface name."
msgstr "Fel: ”dev”: ”%s” är varken UUID eller gränssnittsnamn."
-#: ../clients/cli/connections.c:6425
+#: ../clients/cli/connections.c:6421
msgid "VXLAN ID: "
msgstr "VXLAN-ID: "
-#: ../clients/cli/connections.c:6433
+#: ../clients/cli/connections.c:6429
msgid "Remote: "
msgstr "Fjärr: "
-#: ../clients/cli/connections.c:6442
+#: ../clients/cli/connections.c:6438
#, c-format
msgid "Error: 'id': '%s' is not valid; use <0-16777215>."
msgstr "Fel: ”id”: ”%s” är inte giltigt: använd <0-16777215>."
-#: ../clients/cli/connections.c:6468
+#: ../clients/cli/connections.c:6464
#, c-format
msgid "Error: 'remote': '%s' is not a valid IP address"
msgstr "Fel: ”remote”: ”%s” är inte en giltig IP-adress"
-#: ../clients/cli/connections.c:6477
+#: ../clients/cli/connections.c:6473
#, c-format
msgid "Error: 'local': '%s' is not a valid IP address"
msgstr "Fel: ”local”: ”%s” är inte en giltig IP-adress"
-#: ../clients/cli/connections.c:6486
+#: ../clients/cli/connections.c:6482
#, c-format
msgid "Error: 'source-port-min': %s is not valid; use <0-65535>."
msgstr "Fel: ”source-port-min”: %s är inte giltig; använd <0-65535>."
-#: ../clients/cli/connections.c:6495
+#: ../clients/cli/connections.c:6491
#, c-format
msgid "Error: 'source-port-max': %s is not valid; use <0-65535>."
msgstr "Fel: ”source-port-max”: %s är inte giltig; använd <0-65535>."
-#: ../clients/cli/connections.c:6504
+#: ../clients/cli/connections.c:6500
#, c-format
msgid "Error: 'destination-port': %s is not valid; use <0-65535>."
msgstr "Fel: ”destination-port”: %s är inte giltig: använd <0-65535>."
-#: ../clients/cli/connections.c:6544
+#: ../clients/cli/connections.c:6540
#, c-format
msgid "Error: '%s' is not a valid connection type."
msgstr "Fel: ”%s” är inte en giltig anslutningstyp."
-#: ../clients/cli/connections.c:6585
+#: ../clients/cli/connections.c:6581
#, c-format
msgid "Error: IPv4 gateway specified without IPv4 addresses"
msgstr "Fel: IPv4-gateway angiven utan IPv4-adresser"
-#: ../clients/cli/connections.c:6589
+#: ../clients/cli/connections.c:6585
#, c-format
msgid "Error: multiple IPv4 gateways specified"
msgstr "Fel: flera IPv4-gateways angivna"
-#: ../clients/cli/connections.c:6593
+#: ../clients/cli/connections.c:6589
#, c-format
msgid "Error: Invalid IPv4 gateway '%s'"
msgstr "Fel: ogiltig IPv4-gateway ”%s”"
-#: ../clients/cli/connections.c:6618
+#: ../clients/cli/connections.c:6614
#, c-format
msgid "Error: IPv6 gateway specified without IPv6 addresses"
msgstr "Fel: IPv6-gateway angiven utan IPv6-adresser"
-#: ../clients/cli/connections.c:6622
+#: ../clients/cli/connections.c:6618
#, c-format
msgid "Error: multiple IPv6 gateways specified"
msgstr "Fel: flera IPv6-gateways angivna"
-#: ../clients/cli/connections.c:6626
+#: ../clients/cli/connections.c:6622
#, c-format
msgid "Error: Invalid IPv6 gateway '%s'"
msgstr "Fel: ogiltig IPv6-gateway ”%s”"
-#: ../clients/cli/connections.c:6674 ../clients/cli/connections.c:10227
+#: ../clients/cli/connections.c:6670 ../clients/cli/connections.c:10223
#, c-format
msgid "Error: Failed to add '%s' connection: %s"
msgstr "Fel: Misslyckades med att lägga till ”%s”-anslutning: %s"
-#: ../clients/cli/connections.c:6679
+#: ../clients/cli/connections.c:6675
#, c-format
msgid "Connection '%s' (%s) successfully added.\n"
msgstr "Anslutning ”%s” (%s) lades till.\n"
-#: ../clients/cli/connections.c:6955 ../clients/cli/connections.c:10682
+#: ../clients/cli/connections.c:6951 ../clients/cli/connections.c:10678
#, c-format
msgid "Error: 'type' argument is required."
msgstr "Fel: ”type”-argument saknas."
-#: ../clients/cli/connections.c:6963
+#: ../clients/cli/connections.c:6959
#, c-format
msgid "Error: invalid connection type; %s."
msgstr "Fel: ogiltig anslutningstyp; %s."
-#: ../clients/cli/connections.c:6972 ../clients/cli/devices.c:2142
+#: ../clients/cli/connections.c:6968 ../clients/cli/devices.c:2164
#, c-format
msgid "Error: 'autoconnect': %s."
msgstr "Fel: ”autoconnect”: %s."
-#: ../clients/cli/connections.c:6982
+#: ../clients/cli/connections.c:6978
#, c-format
msgid "Error: 'save': %s."
msgstr "Fel: ”save”: %s."
-#: ../clients/cli/connections.c:6999
+#: ../clients/cli/connections.c:6995
msgid "Interface name [*]: "
msgstr "Gränssnittsnamn [*]: "
-#: ../clients/cli/connections.c:7004
+#: ../clients/cli/connections.c:7000
#, c-format
msgid "Error: 'ifname' argument is required."
msgstr "Fel: ”ifname”-argument krävs."
-#: ../clients/cli/connections.c:7006
+#: ../clients/cli/connections.c:7002
#, c-format
msgid "Error: mandatory 'ifname' not seen before '%s'."
msgstr "Fel: obligatoriskt ”ifname” inte sett innan ”%s”."
-#: ../clients/cli/connections.c:7015
+#: ../clients/cli/connections.c:7011
#, c-format
msgid "Error: 'ifname': '%s' is not a valid interface nor '*'."
msgstr ""
"Fel: ”ifname”: ”%s” är inte ett giltigt gränssnittsnamn, inte heller ”*”."
-#: ../clients/cli/connections.c:8039
+#: ../clients/cli/connections.c:8035
#, c-format
msgid "['%s' setting values]\n"
msgstr "[”%s”-inställningsvärden]\n"
@@ -2830,7 +2829,7 @@ msgstr "[”%s”-inställningsvärden]\n"
#. TRANSLATORS: do not translate command names and keywords before ::
#. * However, you should translate terms enclosed in <>.
#.
-#: ../clients/cli/connections.c:8121
+#: ../clients/cli/connections.c:8117
#, c-format
msgid ""
"---[ Main menu ]---\n"
@@ -2864,7 +2863,7 @@ msgstr ""
"nmcli <konf-flagga> <value> :: nmcli-konfiguration\n"
"quit :: avsluta nmcli\n"
-#: ../clients/cli/connections.c:8148
+#: ../clients/cli/connections.c:8144
#, c-format
msgid ""
"goto <setting>[.<prop>] | <prop> :: enter setting/property for editing\n"
@@ -2884,7 +2883,7 @@ msgstr ""
" nmcli connection> goto secondaries\n"
" nmcli> goto ipv4.addresses\n"
-#: ../clients/cli/connections.c:8155
+#: ../clients/cli/connections.c:8151
#, c-format
msgid ""
"remove <setting>[.<prop>] :: remove setting or reset property value\n"
@@ -2906,7 +2905,7 @@ msgstr ""
"Exempel: nmcli> remove wifi-sec\n"
" nmcli> remove eth.mtu\n"
-#: ../clients/cli/connections.c:8162
+#: ../clients/cli/connections.c:8158
#, c-format
msgid ""
"set [<setting>.<prop> <value>] :: set property value\n"
@@ -2921,7 +2920,7 @@ msgstr ""
"\n"
"Exempel: nmcli> set con.id My connection\n"
-#: ../clients/cli/connections.c:8167
+#: ../clients/cli/connections.c:8163
#, c-format
msgid ""
"describe [<setting>.<prop>] :: describe property\n"
@@ -2934,7 +2933,7 @@ msgstr ""
"Visar egenskapsbeskrivning. Du kan titta i handboken för nm-settings(5) för "
"att se alla NH-inställningar och egenskaper.\n"
-#: ../clients/cli/connections.c:8172
+#: ../clients/cli/connections.c:8168
#, c-format
msgid ""
"print [all] :: print setting or connection values\n"
@@ -2949,7 +2948,7 @@ msgstr ""
"\n"
"Exempel: nmcli ipv4> print all\n"
-#: ../clients/cli/connections.c:8177
+#: ../clients/cli/connections.c:8173
#, c-format
msgid ""
"verify [all | fix] :: verify setting or connection validity\n"
@@ -2975,7 +2974,7 @@ msgstr ""
" nmcli> verify fix\n"
" nmcli bond> verify\n"
-#: ../clients/cli/connections.c:8186
+#: ../clients/cli/connections.c:8182
#, c-format
msgid ""
"save [persistent|temporary] :: save the connection\n"
@@ -3001,7 +3000,7 @@ msgstr ""
"Om du vill ta bort den sparade anslutningen helt\n"
"måste profilen tas bort.\n"
-#: ../clients/cli/connections.c:8197
+#: ../clients/cli/connections.c:8193
#, c-format
msgid ""
"activate [<ifname>] [/<ap>|<nsp>] :: activate the connection\n"
@@ -3022,7 +3021,7 @@ msgstr ""
"/<ap>|<nsp> - AP (Wi-Fi) eller NSP (WiMAX) (lägg till / i början när "
"<grnamn> inte anges)\n"
-#: ../clients/cli/connections.c:8204 ../clients/cli/connections.c:8363
+#: ../clients/cli/connections.c:8200 ../clients/cli/connections.c:8359
#, c-format
msgid ""
"back :: go to upper menu level\n"
@@ -3031,7 +3030,7 @@ msgstr ""
"back :: gå upp en menynivå\n"
"\n"
-#: ../clients/cli/connections.c:8207
+#: ../clients/cli/connections.c:8203
#, c-format
msgid ""
"help/? [<command>] :: help for the nmcli commands\n"
@@ -3040,7 +3039,7 @@ msgstr ""
"help/? [<kommando>] :: hjälp för nmcli-kommandot\n"
"\n"
-#: ../clients/cli/connections.c:8210
+#: ../clients/cli/connections.c:8206
#, c-format
msgid ""
"nmcli [<conf-option> <value>] :: nmcli configuration\n"
@@ -3067,7 +3066,7 @@ msgstr ""
" nmcli> nmcli save-confirmation no\n"
" nmcli> nmcli prompt-color 3\n"
-#: ../clients/cli/connections.c:8232 ../clients/cli/connections.c:8369
+#: ../clients/cli/connections.c:8228 ../clients/cli/connections.c:8365
#, c-format
msgid ""
"quit :: exit nmcli\n"
@@ -3080,8 +3079,8 @@ msgstr ""
"Kommandot avslutar nmcli. När anslutningen som redigerats inte sparas frågas "
"användaren om att bekräfta åtgärden.\n"
-#: ../clients/cli/connections.c:8237 ../clients/cli/connections.c:8374
-#: ../clients/cli/connections.c:8798 ../clients/cli/connections.c:9746
+#: ../clients/cli/connections.c:8233 ../clients/cli/connections.c:8370
+#: ../clients/cli/connections.c:8794 ../clients/cli/connections.c:9742
#, c-format
msgid "Unknown command: '%s'\n"
msgstr "Okänt kommando: ”%s”\n"
@@ -3089,7 +3088,7 @@ msgstr "Okänt kommando: ”%s”\n"
#. TRANSLATORS: do not translate command names and keywords before ::
#. * However, you should translate terms enclosed in <>.
#.
-#: ../clients/cli/connections.c:8303
+#: ../clients/cli/connections.c:8299
#, c-format
msgid ""
"---[ Property menu ]---\n"
@@ -3118,7 +3117,7 @@ msgstr ""
"kommandobeskrivning\n"
"quit :: avsluta nmcli\n"
-#: ../clients/cli/connections.c:8328
+#: ../clients/cli/connections.c:8324
#, c-format
msgid ""
"set [<value>] :: set new value\n"
@@ -3129,7 +3128,7 @@ msgstr ""
"\n"
"Detta kommando sätter angivet <värde> till denna egenskap\n"
-#: ../clients/cli/connections.c:8332
+#: ../clients/cli/connections.c:8328
#, c-format
msgid ""
"add [<value>] :: append new value to the property\n"
@@ -3144,7 +3143,7 @@ msgstr ""
"egenskapen är av en behållartyp. För egenskaper med ett värde ersätts "
"egenskapsvärdet (samma som ”set”).\n"
-#: ../clients/cli/connections.c:8338
+#: ../clients/cli/connections.c:8334
#, c-format
msgid ""
"change :: change current value\n"
@@ -3155,7 +3154,7 @@ msgstr ""
"\n"
"Visar aktuellt värde och tillåter redigering av det.\n"
-#: ../clients/cli/connections.c:8342
+#: ../clients/cli/connections.c:8338
#, c-format
msgid ""
"remove [<value>|<index>|<option name>] :: delete the value\n"
@@ -3190,7 +3189,7 @@ msgstr ""
" nmcli bond.options> remove downdelay\n"
"\n"
-#: ../clients/cli/connections.c:8353
+#: ../clients/cli/connections.c:8349
#, c-format
msgid ""
"describe :: describe property\n"
@@ -3203,7 +3202,7 @@ msgstr ""
"Visar egenskapsbeskrivning. Se nm-settings(5)-handboken för att se alla NH-"
"inställningar och egenskaper.\n"
-#: ../clients/cli/connections.c:8358
+#: ../clients/cli/connections.c:8354
#, c-format
msgid ""
"print [property|setting|connection] :: print property (setting, connection) "
@@ -3218,7 +3217,7 @@ msgstr ""
"Visar egenskapsvärdet. Med argument kan du också visa värden för hela "
"inställningen eller anslutningen.\n"
-#: ../clients/cli/connections.c:8366
+#: ../clients/cli/connections.c:8362
#, c-format
msgid ""
"help/? [<command>] :: help for nmcli commands\n"
@@ -3227,28 +3226,28 @@ msgstr ""
"help/? [<kommando>] :: hjälp för nmcli-kommandon\n"
"\n"
-#: ../clients/cli/connections.c:8464
+#: ../clients/cli/connections.c:8460
#, c-format
msgid "Error: Connection activation failed.\n"
msgstr "Fel: Aktivering av anslutning misslyckades.\n"
-#: ../clients/cli/connections.c:8547
+#: ../clients/cli/connections.c:8543
#, c-format
msgid "Error: setting '%s' is mandatory and cannot be removed.\n"
msgstr "Fel: inställningen ”%s” är obligatorisk och kan inte tas bort.\n"
#. TRANSLATORS: status line in nmcli connection editor
-#: ../clients/cli/connections.c:8565
+#: ../clients/cli/connections.c:8561
#, c-format
msgid "[ Type: %s | Name: %s | UUID: %s | Dirty: %s | Temp: %s ]\n"
msgstr "[ Typ: %s | Namn: %s | UUID: %s | Dirty: %s | Temp: %s ]\n"
-#: ../clients/cli/connections.c:8601
+#: ../clients/cli/connections.c:8597
#, c-format
msgid "The connection is not saved. Do you really want to quit? %s"
msgstr "Anslutningen sparas inte. Vill du verkligen avsluta? %s"
-#: ../clients/cli/connections.c:8650
+#: ../clients/cli/connections.c:8646
#, c-format
msgid ""
"The connection profile has been removed from another client. You may type "
@@ -3257,66 +3256,66 @@ msgstr ""
"Anslutningsprofilen har tagits bort från en annan klient. Du kan skriva "
"”save” i huvudmenyn för att återställa den.\n"
-#: ../clients/cli/connections.c:8675 ../clients/cli/connections.c:9097
-#: ../clients/cli/connections.c:9155
+#: ../clients/cli/connections.c:8671 ../clients/cli/connections.c:9093
+#: ../clients/cli/connections.c:9151
#, c-format
msgid "Allowed values for '%s' property: %s\n"
msgstr "Tillgängliga värden för ”%s”-egenskapen: %s\n"
-#: ../clients/cli/connections.c:8679 ../clients/cli/connections.c:9101
-#: ../clients/cli/connections.c:9159
+#: ../clients/cli/connections.c:8675 ../clients/cli/connections.c:9097
+#: ../clients/cli/connections.c:9155
#, c-format
msgid "Enter '%s' value: "
msgstr "Ange ”%s”-värde: "
-#: ../clients/cli/connections.c:8694 ../clients/cli/connections.c:8716
-#: ../clients/cli/connections.c:9105 ../clients/cli/connections.c:9164
+#: ../clients/cli/connections.c:8690 ../clients/cli/connections.c:8712
+#: ../clients/cli/connections.c:9101 ../clients/cli/connections.c:9160
#, c-format
msgid "Error: failed to set '%s' property: %s\n"
msgstr "Fel: misslyckades med att sätta ”%s”-egenskapen: %s\n"
-#: ../clients/cli/connections.c:8710
+#: ../clients/cli/connections.c:8706
#, c-format
msgid "Edit '%s' value: "
msgstr "Redigera ”%s”-värde: "
-#: ../clients/cli/connections.c:8739
+#: ../clients/cli/connections.c:8735
#, c-format
msgid "Error: %s\n"
msgstr "Fel: %s\n"
-#: ../clients/cli/connections.c:8745 ../clients/cli/connections.c:9246
-#: ../clients/cli/connections.c:9294
+#: ../clients/cli/connections.c:8741 ../clients/cli/connections.c:9242
+#: ../clients/cli/connections.c:9290
#, c-format
msgid "Error: failed to remove value of '%s': %s\n"
msgstr "Fel: misslyckades med att ta bort värdet ”%s”: %s\n"
-#: ../clients/cli/connections.c:8766
+#: ../clients/cli/connections.c:8762
#, c-format
msgid "Unknown command argument: '%s'\n"
msgstr "Okänt kommandoargument: ”%s”\n"
-#: ../clients/cli/connections.c:8871
+#: ../clients/cli/connections.c:8867
#, c-format
msgid "Available settings: %s\n"
msgstr "Tillgängliga inställningar: %s\n"
-#: ../clients/cli/connections.c:8883
+#: ../clients/cli/connections.c:8879
#, c-format
msgid "Error: invalid setting name; %s\n"
msgstr "Fel: ogiltigt namn på inställning; %s\n"
-#: ../clients/cli/connections.c:8900
+#: ../clients/cli/connections.c:8896
#, c-format
msgid "Available properties: %s\n"
msgstr "Tillgängliga egenskaper: %s\n"
-#: ../clients/cli/connections.c:8908
+#: ../clients/cli/connections.c:8904
#, c-format
msgid "Error: property %s\n"
msgstr "Fel: egenskapen %s\n"
-#: ../clients/cli/connections.c:8949
+#: ../clients/cli/connections.c:8945
#, c-format
msgid ""
"Saving the connection with 'autoconnect=yes'. That might result in an "
@@ -3327,12 +3326,12 @@ msgstr ""
"anslutningen aktiveras omedelbart.\n"
"Vill du fortfarande spara? %s"
-#: ../clients/cli/connections.c:9039
+#: ../clients/cli/connections.c:9035
#, c-format
msgid "You may edit the following settings: %s\n"
msgstr "Du kan redigera följande inställningar: %s\n"
-#: ../clients/cli/connections.c:9067
+#: ../clients/cli/connections.c:9063
#, c-format
msgid ""
"The connection profile has been removed from another client. You may type "
@@ -3341,219 +3340,219 @@ msgstr ""
"Anslutningsprofilen har tagits bort från en annan klient. Du kan skriva "
"”save” för att återställa den.\n"
-#: ../clients/cli/connections.c:9109 ../clients/cli/connections.c:9339
+#: ../clients/cli/connections.c:9105 ../clients/cli/connections.c:9335
#, c-format
msgid "Error: no setting selected; valid are [%s]\n"
msgstr "Fel: ingen inställning vald; giltiga är [%s]\n"
-#: ../clients/cli/connections.c:9110
+#: ../clients/cli/connections.c:9106
#, c-format
msgid "use 'goto <setting>' first, or 'set <setting>.<property>'\n"
msgstr ""
"använd ”goto <inställning>” först eller ”set <inställning>.<egenskap>”\n"
-#: ../clients/cli/connections.c:9124 ../clients/cli/connections.c:9273
-#: ../clients/cli/connections.c:9361
+#: ../clients/cli/connections.c:9120 ../clients/cli/connections.c:9269
+#: ../clients/cli/connections.c:9357
#, c-format
msgid "Error: invalid setting argument '%s'; valid are [%s]\n"
msgstr "Fel: ogiltigt argument för inställningen ”%s”; giltiga är [%s]\n"
-#: ../clients/cli/connections.c:9134
+#: ../clients/cli/connections.c:9130
#, c-format
msgid "Error: missing setting for '%s' property\n"
msgstr "Fel: saknar inställning för egenskapen ”%s”\n"
-#: ../clients/cli/connections.c:9141
+#: ../clients/cli/connections.c:9137
#, c-format
msgid "Error: invalid property: %s\n"
msgstr "Fel: ogiltig egenskap: %s\n"
-#: ../clients/cli/connections.c:9194
+#: ../clients/cli/connections.c:9190
#, c-format
msgid "Error: unknown setting '%s'\n"
msgstr "Fel: Okänd inställning: ”%s”\n"
-#: ../clients/cli/connections.c:9207
+#: ../clients/cli/connections.c:9203
#, c-format
msgid "You may edit the following properties: %s\n"
msgstr "Du kan redigera följande egenskaper: %s\n"
-#: ../clients/cli/connections.c:9251
+#: ../clients/cli/connections.c:9247
#, c-format
msgid "Error: no argument given; valid are [%s]\n"
msgstr "Fel: inga argument givna; giltiga är [%s]\n"
-#: ../clients/cli/connections.c:9270
+#: ../clients/cli/connections.c:9266
#, c-format
msgid "Setting '%s' is not present in the connection.\n"
msgstr "Inställningen ”%s” finns inte i anslutningen.\n"
-#: ../clients/cli/connections.c:9315
+#: ../clients/cli/connections.c:9311
#, c-format
msgid "Error: %s properties, nor it is a setting name.\n"
msgstr "Fel: %s-egenskaper, inte heller ett inställningsnamn.\n"
-#: ../clients/cli/connections.c:9340
+#: ../clients/cli/connections.c:9336
#, c-format
msgid "use 'goto <setting>' first, or 'describe <setting>.<property>'\n"
msgstr ""
"använd ”goto <inställning>” först, eller ”describe <inställning>."
"<egenskap>”\n"
-#: ../clients/cli/connections.c:9389
+#: ../clients/cli/connections.c:9385
#, c-format
msgid "Error: invalid property: %s, neither a valid setting name.\n"
msgstr ""
"Fel: ogiltig egenskap: %s, och inte heller ett giltigt inställningsnamn.\n"
-#: ../clients/cli/connections.c:9421
+#: ../clients/cli/connections.c:9417
#, c-format
msgid "Error: unknown setting: '%s'\n"
msgstr "Fel: okänd inställning: ”%s”\n"
-#: ../clients/cli/connections.c:9426
+#: ../clients/cli/connections.c:9422
#, c-format
msgid "Error: '%s' setting not present in the connection\n"
msgstr "Fel: inställningen ”%s” finns inte i anslutningen\n"
-#: ../clients/cli/connections.c:9454
+#: ../clients/cli/connections.c:9450
#, c-format
msgid "Error: invalid property: %s%s\n"
msgstr "Fel: ogiltig egenskap: %s%s\n"
-#: ../clients/cli/connections.c:9456
+#: ../clients/cli/connections.c:9452
msgid ", neither a valid setting name"
msgstr ", inte heller ett giltigt inställningsnamn"
-#: ../clients/cli/connections.c:9473
+#: ../clients/cli/connections.c:9469
#, c-format
msgid "Invalid verify option: %s\n"
msgstr "Ogiltigt verify-argument ”%s”\n"
-#: ../clients/cli/connections.c:9481
+#: ../clients/cli/connections.c:9477
#, c-format
msgid "Verify setting '%s': %s\n"
msgstr "Verifiera inställningen ”%s”: %s\n"
-#: ../clients/cli/connections.c:9496
+#: ../clients/cli/connections.c:9492
#, c-format
msgid "Verify connection: %s\n"
msgstr "Verifiera anslutningen: %s\n"
-#: ../clients/cli/connections.c:9499
+#: ../clients/cli/connections.c:9495
#, c-format
msgid "The error cannot be fixed automatically.\n"
msgstr "Felet kan inte lagas automatiskt.\n"
-#: ../clients/cli/connections.c:9516
+#: ../clients/cli/connections.c:9512
#, c-format
msgid "Error: invalid argument '%s'\n"
msgstr "Fel: ogiltigt argument ”%s”\n"
-#: ../clients/cli/connections.c:9549
+#: ../clients/cli/connections.c:9545
#, c-format
msgid "Error: Failed to save '%s' (%s) connection: %s\n"
msgstr "Fel: Misslyckades med att spara ”%s” (%s)-anslutning %s\n"
-#: ../clients/cli/connections.c:9556
+#: ../clients/cli/connections.c:9552
#, c-format
msgid "Connection '%s' (%s) successfully saved.\n"
msgstr "Anslutningen ”%s” (%s) sparades.\n"
-#: ../clients/cli/connections.c:9557
+#: ../clients/cli/connections.c:9553
#, c-format
msgid "Connection '%s' (%s) successfully updated.\n"
msgstr "Anslutningen ”%s” (%s) uppdaterades.\n"
-#: ../clients/cli/connections.c:9590
+#: ../clients/cli/connections.c:9586
#, c-format
msgid "Error: connection verification failed: %s\n"
msgstr "Fel: verifiering av anslutning misslyckades: %s\n"
-#: ../clients/cli/connections.c:9591
+#: ../clients/cli/connections.c:9587
msgid "(unknown error)"
msgstr "(okänt fel)"
-#: ../clients/cli/connections.c:9592
+#: ../clients/cli/connections.c:9588
#, c-format
msgid "You may try running 'verify fix' to fix errors.\n"
msgstr "Du kan prova att köra ”verify fix” för att laga fel.\n"
-#: ../clients/cli/connections.c:9614
+#: ../clients/cli/connections.c:9610
#, c-format
msgid "Error: connection is not saved. Type 'save' first.\n"
msgstr "Fel: anslutningen sparas ej. Skriv ”save” först.\n"
-#: ../clients/cli/connections.c:9618
+#: ../clients/cli/connections.c:9614
#, c-format
msgid "Error: connection is not valid: %s\n"
msgstr "Fel: anslutningen är inte giltig: %s\n"
-#: ../clients/cli/connections.c:9628
+#: ../clients/cli/connections.c:9624
#, c-format
msgid "Error: Cannot activate connection: %s.\n"
msgstr "Fel: Kan inte aktivera anslutningen: %s.\n"
-#: ../clients/cli/connections.c:9638
+#: ../clients/cli/connections.c:9634
#, c-format
msgid "Error: Failed to activate '%s' (%s) connection: %s\n"
msgstr "Fel: Misslyckades med att aktivera ”%s” (%s)-anslutning: %s\n"
-#: ../clients/cli/connections.c:9644
+#: ../clients/cli/connections.c:9640
#, c-format
msgid "Monitoring connection activation (press any key to continue)\n"
msgstr ""
"Övervakar anslutningsaktivering (tryck valfri tangent för att fortsätta)\n"
-#: ../clients/cli/connections.c:9682
+#: ../clients/cli/connections.c:9678
#, c-format
msgid "Error: status-line: %s\n"
msgstr "Fel: status-line: %s\n"
-#: ../clients/cli/connections.c:9690
+#: ../clients/cli/connections.c:9686
#, c-format
msgid "Error: save-confirmation: %s\n"
msgstr "Fel: save-confirmation: %s\n"
-#: ../clients/cli/connections.c:9698
+#: ../clients/cli/connections.c:9694
#, c-format
msgid "Error: show-secrets: %s\n"
msgstr "Fel: show-secrets: %s\n"
-#: ../clients/cli/connections.c:9707
+#: ../clients/cli/connections.c:9703
#, c-format
msgid "Error: bad color: %s\n"
msgstr "Fel: dålig färg: %s\n"
-#: ../clients/cli/connections.c:9721
+#: ../clients/cli/connections.c:9717
#, c-format
msgid "Current nmcli configuration:\n"
msgstr "Aktuell nmcli-konfiguration:\n"
-#: ../clients/cli/connections.c:9731
+#: ../clients/cli/connections.c:9727
#, c-format
msgid "Invalid configuration option '%s'; allowed [%s]\n"
msgstr "Ogiltigt konfigurationsalternativ ”%s”; tillåtet [%s]\n"
-#: ../clients/cli/connections.c:9986
+#: ../clients/cli/connections.c:9982
#, c-format
msgid "Error: only one of 'id', uuid, or 'path' can be provided."
msgstr "Fel: endast en av ”id”, uuid eller ”path” kan ges."
-#: ../clients/cli/connections.c:9998 ../clients/cli/connections.c:10175
-#: ../clients/cli/connections.c:10182 ../clients/cli/connections.c:10310
-#: ../clients/cli/connections.c:10786
+#: ../clients/cli/connections.c:9994 ../clients/cli/connections.c:10171
+#: ../clients/cli/connections.c:10178 ../clients/cli/connections.c:10306
+#: ../clients/cli/connections.c:10782
#, c-format
msgid "Error: Unknown connection '%s'."
msgstr "Fel: Okänd anslutning: ”%s”."
-#: ../clients/cli/connections.c:10016
+#: ../clients/cli/connections.c:10012
#, c-format
msgid "Warning: editing existing connection '%s'; 'type' argument is ignored\n"
msgstr ""
"Varning: redigerar befintliga anslutningen ”%s”; ”type”-argument ignoreras\n"
-#: ../clients/cli/connections.c:10019
+#: ../clients/cli/connections.c:10015
#, c-format
msgid ""
"Warning: editing existing connection '%s'; 'con-name' argument is ignored\n"
@@ -3561,223 +3560,223 @@ msgstr ""
"Varning: redigerar befintliga anslutningen ”%s”; ”con-name”-argument "
"ignoreras\n"
-#: ../clients/cli/connections.c:10033
+#: ../clients/cli/connections.c:10029
#, c-format
msgid "Valid connection types: %s\n"
msgstr "Giltiga anslutningstyper: %s\n"
-#: ../clients/cli/connections.c:10035
+#: ../clients/cli/connections.c:10031
#, c-format
msgid "Error: invalid connection type; %s\n"
msgstr "Fel: ogiltig anslutningstyp: %s\n"
-#: ../clients/cli/connections.c:10074
+#: ../clients/cli/connections.c:10070
#, c-format
msgid "===| nmcli interactive connection editor |==="
msgstr "===| nmcli interaktiv anslutningsredigerare |==="
-#: ../clients/cli/connections.c:10077
+#: ../clients/cli/connections.c:10073
#, c-format
msgid "Editing existing '%s' connection: '%s'"
msgstr "Redigerar befintlig ”%s”-anslutning: ”%s”"
-#: ../clients/cli/connections.c:10079
+#: ../clients/cli/connections.c:10075
#, c-format
msgid "Adding a new '%s' connection"
msgstr "Lägger till en ny ”%s”-anslutning"
-#: ../clients/cli/connections.c:10081
+#: ../clients/cli/connections.c:10077
#, c-format
msgid "Type 'help' or '?' for available commands."
msgstr "Skriv ”help” eller ”?” för tillgängliga kommandon."
-#: ../clients/cli/connections.c:10083
+#: ../clients/cli/connections.c:10079
#, c-format
msgid "Type 'describe [<setting>.<prop>]' for detailed property description."
msgstr ""
"Skriv ”describe [<inställning>.<egenskap>]” för en detaljerad "
"egenskapsbeskrivning."
-#: ../clients/cli/connections.c:10121
+#: ../clients/cli/connections.c:10117
#, c-format
msgid "Error: Failed to modify connection '%s': %s"
msgstr "Fel: Misslyckades med att ändra anslutningen ”%s”: %s"
-#: ../clients/cli/connections.c:10128
+#: ../clients/cli/connections.c:10124
#, c-format
msgid "Connection '%s' (%s) successfully modified.\n"
msgstr "Anslutningen ”%s” (%s) ändrades.\n"
-#: ../clients/cli/connections.c:10150 ../clients/cli/connections.c:10266
-#: ../clients/cli/connections.c:10643 ../clients/cli/connections.c:10751
+#: ../clients/cli/connections.c:10146 ../clients/cli/connections.c:10262
+#: ../clients/cli/connections.c:10639 ../clients/cli/connections.c:10747
#, c-format
msgid "Error: No arguments provided."
msgstr "Fel: Inga argument angavs."
-#: ../clients/cli/connections.c:10169 ../clients/cli/connections.c:10298
-#: ../clients/cli/connections.c:10780
+#: ../clients/cli/connections.c:10165 ../clients/cli/connections.c:10294
+#: ../clients/cli/connections.c:10776
#, c-format
msgid "Error: connection ID is missing."
msgstr "Fel: anslutnings-ID saknas."
-#: ../clients/cli/connections.c:10232
+#: ../clients/cli/connections.c:10228
#, c-format
msgid "%s (%s) cloned as %s (%s).\n"
msgstr "%s (%s) klonad som %s (%s).\n"
-#: ../clients/cli/connections.c:10264
+#: ../clients/cli/connections.c:10260
msgid "New connection name: "
msgstr "Nytt anslutningsnamn: "
-#: ../clients/cli/connections.c:10285 ../clients/cli/connections.c:10303
+#: ../clients/cli/connections.c:10281 ../clients/cli/connections.c:10299
#, c-format
msgid "Error: <new name> argument is missing."
msgstr "Fel: <nytt namn>-argument saknas."
-#: ../clients/cli/connections.c:10291
+#: ../clients/cli/connections.c:10287
#, c-format
msgid "Error: unexpected extra argument '%s'."
msgstr "Fel: oväntat extra argument ”%s”."
-#: ../clients/cli/connections.c:10360
+#: ../clients/cli/connections.c:10356
#, c-format
msgid "Error: not all connections deleted."
msgstr "Fel: alla anslutningar är inte borttagna."
-#: ../clients/cli/connections.c:10361
+#: ../clients/cli/connections.c:10357
#, c-format
msgid "Error: Connection deletion failed: %s"
msgstr "Fel: Borttagning av anslutningen misslyckades: %s"
-#: ../clients/cli/connections.c:10423 ../clients/cli/connections.c:10551
+#: ../clients/cli/connections.c:10419 ../clients/cli/connections.c:10547
#, c-format
msgid "Error: unknown connection '%s'\n"
msgstr "Fel: Okänd anslutning: ”%s”\n"
-#: ../clients/cli/connections.c:10437
+#: ../clients/cli/connections.c:10433
#, c-format
msgid "Error: no connection provided."
msgstr "Fel: ingen anslutning tillhandahållen."
#. truncate trailing ", "
-#: ../clients/cli/connections.c:10462
+#: ../clients/cli/connections.c:10458
#, c-format
msgid "Error: cannot delete unknown connection(s): %s."
msgstr "Fel: kan inte ta bort okänd(a) anslutning(ar): %s."
-#: ../clients/cli/connections.c:10474
+#: ../clients/cli/connections.c:10470
#, c-format
msgid "%s: connection profile changed\n"
msgstr "%s: anslutningsprofil ändrad\n"
-#: ../clients/cli/connections.c:10500
+#: ../clients/cli/connections.c:10496
#, c-format
msgid "%s: connection profile created\n"
msgstr "%s: anslutningsprofil skapad\n"
-#: ../clients/cli/connections.c:10509
+#: ../clients/cli/connections.c:10505
#, c-format
msgid "%s: connection profile removed\n"
msgstr "%s: anslutningsprofil borttagen\n"
-#: ../clients/cli/connections.c:10552
+#: ../clients/cli/connections.c:10548
#, c-format
msgid "Error: not all connections found."
msgstr "Fel: hittade inte alla anslutningar."
-#: ../clients/cli/connections.c:10575
+#: ../clients/cli/connections.c:10571
#, c-format
msgid "Error: failed to reload connections: %s."
msgstr "Fel: Misslyckades med att läsa om anslutningar: %s."
-#: ../clients/cli/connections.c:10607
+#: ../clients/cli/connections.c:10603
#, c-format
msgid "Error: failed to load connection: %s."
msgstr "Fel: misslyckades med att läsa in anslutningen: %s."
-#: ../clients/cli/connections.c:10615
+#: ../clients/cli/connections.c:10611
#, c-format
msgid "Could not load file '%s'\n"
msgstr "Kunde inte läsa in filen: ”%s”\n"
-#: ../clients/cli/connections.c:10624
+#: ../clients/cli/connections.c:10620
msgid "File to import: "
msgstr "Fil att importera: "
-#: ../clients/cli/connections.c:10659
+#: ../clients/cli/connections.c:10655
#, c-format
msgid "Warning: 'type' already specified, ignoring extra one.\n"
msgstr "Varning: ”type” redan angiven, ignorerar extra förekomst.\n"
-#: ../clients/cli/connections.c:10670
+#: ../clients/cli/connections.c:10666
#, c-format
msgid "Warning: 'file' already specified, ignoring extra one.\n"
msgstr "Varning: ”file” redan angiven, ignorerar extra förekomst.\n"
-#: ../clients/cli/connections.c:10672
+#: ../clients/cli/connections.c:10668
#, c-format
msgid "Unknown parameter: %s"
msgstr "Okänd parameter: %s"
-#: ../clients/cli/connections.c:10687
+#: ../clients/cli/connections.c:10683
#, c-format
msgid "Error: 'file' argument is required."
msgstr "Fel: ”file”-argument krävs."
-#: ../clients/cli/connections.c:10695 ../clients/cli/connections.c:10802
+#: ../clients/cli/connections.c:10691 ../clients/cli/connections.c:10798
#, c-format
msgid "Error: failed to load VPN plugin: %s."
msgstr "Fel: misslyckades med att läsa in VPN-insticksmodul: %s."
-#: ../clients/cli/connections.c:10703
+#: ../clients/cli/connections.c:10699
#, c-format
msgid "Error: failed to import '%s': %s."
msgstr "Fel: misslyckades med att importera ”%s”: %s."
-#: ../clients/cli/connections.c:10749
+#: ../clients/cli/connections.c:10745
msgid "Output file name: "
msgstr "Utdatafilnamn: "
-#: ../clients/cli/connections.c:10773
+#: ../clients/cli/connections.c:10769
#, c-format
msgid "Error: unknown extra argument: '%s'."
msgstr "Fel: okänt extra argument: ”%s”."
-#: ../clients/cli/connections.c:10793
+#: ../clients/cli/connections.c:10789
#, c-format
msgid "Error: the connection is not VPN."
msgstr "Fel: anslutningen är inte VPN."
-#: ../clients/cli/connections.c:10814
+#: ../clients/cli/connections.c:10810
#, c-format
msgid "Error: failed to create temporary file %s."
msgstr "Fel: misslyckades med att skapa temporära filen %s."
-#: ../clients/cli/connections.c:10823
+#: ../clients/cli/connections.c:10819
#, c-format
msgid "Error: failed to export '%s': %s."
msgstr "Fel: misslyckades med att exportera ”%s”: %s"
-#: ../clients/cli/connections.c:10834
+#: ../clients/cli/connections.c:10830
#, c-format
msgid "Error: failed to read temporary file '%s': %s."
msgstr "Fel: misslyckades med att läsa temporära filen ”%s”: %s."
-#: ../clients/cli/connections.c:10980
+#: ../clients/cli/connections.c:10976
#, c-format
msgid "incorrect string '%s' of '--order' option"
msgstr "fel sträng ”%s” för flaggan ”--order”"
-#: ../clients/cli/connections.c:11006
+#: ../clients/cli/connections.c:11002
#, c-format
msgid "incorrect item '%s' in '--order' option"
msgstr "fel objekt ”%s” i flaggan ”--order”"
-#: ../clients/cli/connections.c:11090
+#: ../clients/cli/connections.c:11089
msgid "'--order' argument is missing"
msgstr "”--order”-argumentet saknas"
-#: ../clients/cli/connections.c:11155
+#: ../clients/cli/connections.c:11154
#, c-format
msgid "Error: '%s' is not valid 'connection' command."
msgstr "Fel: ”%s” är inte ett giltigt ”connection”-kommando."
@@ -4210,7 +4209,7 @@ msgid ""
"\n"
" connect <ifname>\n"
"\n"
-" reapply <ifname>\n"
+" reapply <ifname> ...\n"
"\n"
" disconnect <ifname> ...\n"
"\n"
@@ -4246,7 +4245,7 @@ msgstr ""
"\n"
" connect <grnamn>\n"
"\n"
-" reapply <grnamn>\n"
+" reapply <grnamn> …\n"
"\n"
" disconnect <grnamn> …\n"
"\n"
@@ -4347,7 +4346,7 @@ msgstr ""
msgid ""
"Usage: nmcli device reapply { ARGUMENTS | help }\n"
"\n"
-"ARGUMENTS := <ifname>\n"
+"ARGUMENTS := <ifname> ...\n"
"\n"
"Attempts to update device with changes to the currently active connection\n"
"made since it was last applied.\n"
@@ -4355,7 +4354,7 @@ msgid ""
msgstr ""
"Användning: nmcli device reapply { ARGUMENT | help }\n"
"\n"
-"ARGUMENT := <grnamn>\n"
+"ARGUMENT := <grnamn> …\n"
"\n"
"Försöker uppdatera enhet med ändringar till den aktuellt aktiva "
"anslutningen\n"
@@ -4581,23 +4580,23 @@ msgstr ""
"\n"
#: ../clients/cli/devices.c:527 ../clients/cli/devices.c:1676
-#: ../clients/cli/devices.c:1685 ../clients/cli/devices.c:1876
-#: ../clients/cli/devices.c:2081 ../clients/cli/devices.c:2088
+#: ../clients/cli/devices.c:1685 ../clients/cli/devices.c:1879
+#: ../clients/cli/devices.c:2103 ../clients/cli/devices.c:2110
#, c-format
msgid "Error: No interface specified."
msgstr "Fel: Inget gränssnitt angivet."
-#: ../clients/cli/devices.c:547
+#: ../clients/cli/devices.c:547 ../clients/cli/devices.c:1899
#, c-format
msgid "Warning: argument '%s' is duplicated.\n"
msgstr "Varning: argumentet ”%s” är duplicerat.\n"
-#: ../clients/cli/devices.c:549
+#: ../clients/cli/devices.c:549 ../clients/cli/devices.c:1901
#, c-format
msgid "Error: Device '%s' not found.\n"
msgstr "Fel: Enheten ”%s” hittades inte.\n"
-#: ../clients/cli/devices.c:550
+#: ../clients/cli/devices.c:550 ../clients/cli/devices.c:1902
#, c-format
msgid "Error: not all devices found."
msgstr "Fel: hittade inte alla enheter."
@@ -4672,14 +4671,14 @@ msgstr "Fel: ”device status”: %s"
msgid "Status of devices"
msgstr "Status för enheter"
-#: ../clients/cli/devices.c:1380 ../clients/cli/devices.c:3487
+#: ../clients/cli/devices.c:1380 ../clients/cli/devices.c:3509
#, c-format
msgid "Error: invalid extra argument '%s'."
msgstr "Fel: ogiltigt extra argument: ”%s”."
#: ../clients/cli/devices.c:1397 ../clients/cli/devices.c:1707
-#: ../clients/cli/devices.c:2104 ../clients/cli/devices.c:2374
-#: ../clients/cli/devices.c:3526
+#: ../clients/cli/devices.c:2126 ../clients/cli/devices.c:2396
+#: ../clients/cli/devices.c:3548
#, c-format
msgid "Error: Device '%s' not found."
msgstr "Fel: Enheten ”%s” hittades inte."
@@ -4745,7 +4744,7 @@ msgid "Error: extra argument not allowed: '%s'."
msgstr "Fel: extra argument saknas: ”%s”."
#: ../clients/cli/devices.c:1776 ../clients/cli/devices.c:1791
-#: ../clients/cli/devices.c:1942
+#: ../clients/cli/devices.c:1964
#, c-format
msgid "Device '%s' successfully disconnected.\n"
msgstr "Lyckades: Enheten ”%s” kopplades från.\n"
@@ -4757,94 +4756,95 @@ msgstr "Enheten ”%s” togs bort.\n"
#: ../clients/cli/devices.c:1838
#, c-format
-msgid "Error: Reapplying connection to device '%s' (%s) failed: %s"
-msgstr "Fel: Uppdatering av anslutning till enheten ”%s” (%s) misslyckades: %s"
+msgid "Error: not all connections reapplied."
+msgstr "Fel: alla anslutningar har inte uppdaterats."
-#: ../clients/cli/devices.c:1848
+#: ../clients/cli/devices.c:1839
#, c-format
-msgid "Connection successfully reapplied to device '%s'.\n"
-msgstr "Anslutning uppdaterades till enheten ”%s”.\n"
+msgid "Error: Reapplying connection to device '%s' (%s) failed: %s\n"
+msgstr ""
+"Fel: Uppdatering av anslutning till enheten ”%s” (%s) misslyckades: %s\n"
-#: ../clients/cli/devices.c:1885
+#: ../clients/cli/devices.c:1849
#, c-format
-msgid "Error: unsupported argument '%s'."
-msgstr "Fel: argument ”%s” stöds inte."
+msgid "Connection successfully reapplied to device '%s'.\n"
+msgstr "Anslutning uppdaterades till enheten ”%s”.\n"
-#: ../clients/cli/devices.c:1899
+#: ../clients/cli/devices.c:1912
#, c-format
-msgid "Error: device '%s' not found."
-msgstr "Fel: enheten ”%s” hittades inte."
+msgid "Error: no valid device provided."
+msgstr "Fel: ingen giltig enhet tillhandahållen."
-#: ../clients/cli/devices.c:1927
+#: ../clients/cli/devices.c:1949
#, c-format
msgid "Error: not all devices disconnected."
msgstr "Fel: alla anslutningar inte frånkopplade."
-#: ../clients/cli/devices.c:1928
+#: ../clients/cli/devices.c:1950
#, c-format
msgid "Error: Device '%s' (%s) disconnecting failed: %s\n"
msgstr "Fel: Frånkoppling av enheten ”%s” (%s) misslyckades: %s\n"
-#: ../clients/cli/devices.c:2003
+#: ../clients/cli/devices.c:2025
#, c-format
msgid "Error: not all devices deleted."
msgstr "Fel: alla enheter inte borttagna."
-#: ../clients/cli/devices.c:2004
+#: ../clients/cli/devices.c:2026
#, c-format
msgid "Error: Device '%s' (%s) deletion failed: %s\n"
msgstr "Fel: Borttagning av enheten ”%s” (%s) misslyckades: %s\n"
-#: ../clients/cli/devices.c:2110
+#: ../clients/cli/devices.c:2132
#, c-format
msgid "Error: No property specified."
msgstr "Fel: Ingen egenskap angiven."
-#: ../clients/cli/devices.c:2122 ../clients/cli/devices.c:2137
+#: ../clients/cli/devices.c:2144 ../clients/cli/devices.c:2159
#, c-format
msgid "Error: '%s' argument is missing."
msgstr "Fel: ”%s”-argument saknas."
-#: ../clients/cli/devices.c:2127
+#: ../clients/cli/devices.c:2149
#, c-format
msgid "Error: 'managed': %s."
msgstr "Fel: ”managed”: %s."
-#: ../clients/cli/devices.c:2152
+#: ../clients/cli/devices.c:2174
#, c-format
msgid "Error: property '%s' is not known."
msgstr "Fel: egenskapen ”%s” är okänd."
-#: ../clients/cli/devices.c:2198
+#: ../clients/cli/devices.c:2220
#, c-format
msgid "%s: using connection '%s'\n"
msgstr "%s: använder anslutningen ”%s”\n"
-#: ../clients/cli/devices.c:2224
+#: ../clients/cli/devices.c:2246
#, c-format
msgid "%s: device created\n"
msgstr "%s: enhet skapad\n"
-#: ../clients/cli/devices.c:2231
+#: ../clients/cli/devices.c:2253
#, c-format
msgid "%s: device removed\n"
msgstr "%s: enhet borttagen\n"
-#: ../clients/cli/devices.c:2317
+#: ../clients/cli/devices.c:2339
msgid "Wi-Fi scan list"
msgstr "Trådlös avsökningslista"
-#: ../clients/cli/devices.c:2355
+#: ../clients/cli/devices.c:2377
#, c-format
msgid "Error: 'device wifi': %s"
msgstr "Fel: ”device wifi”: %s"
-#: ../clients/cli/devices.c:2397 ../clients/cli/devices.c:2478
+#: ../clients/cli/devices.c:2419 ../clients/cli/devices.c:2500
#, c-format
msgid "Error: Access point with bssid '%s' not found."
msgstr "Fel: Accesspunkt med bssid ”%s” hittades inte."
-#: ../clients/cli/devices.c:2424
+#: ../clients/cli/devices.c:2446
#, c-format
msgid ""
"Error: Device '%s' was not recognized as a Wi-Fi device, check "
@@ -4853,27 +4853,27 @@ msgstr ""
"Fel: Enheten ”%s” kändes inte igen som en trådlös enhet, kontrollera "
"insticksmodulen NetworkManager Wi-Fi."
-#: ../clients/cli/devices.c:2426 ../clients/cli/devices.c:2758
-#: ../clients/cli/devices.c:3178 ../clients/cli/devices.c:3327
+#: ../clients/cli/devices.c:2448 ../clients/cli/devices.c:2780
+#: ../clients/cli/devices.c:3200 ../clients/cli/devices.c:3349
#, c-format
msgid "Error: Device '%s' is not a Wi-Fi device."
msgstr "Fel: Enheten ”%s” är inte en trådlös enhet."
-#: ../clients/cli/devices.c:2638
+#: ../clients/cli/devices.c:2660
msgid "SSID or BSSID: "
msgstr "SSID eller BSSID: "
-#: ../clients/cli/devices.c:2643
+#: ../clients/cli/devices.c:2665
#, c-format
msgid "Error: SSID or BSSID are missing."
msgstr "Fel: SSID eller BSSID saknas."
-#: ../clients/cli/devices.c:2667
+#: ../clients/cli/devices.c:2689
#, c-format
msgid "Error: bssid argument value '%s' is not a valid BSSID."
msgstr "Fel: bssid-argumentvärdet ”%s” är inte ett giltigt BSSID."
-#: ../clients/cli/devices.c:2691
+#: ../clients/cli/devices.c:2713
#, c-format
msgid ""
"Error: wep-key-type argument value '%s' is invalid, use 'key' or 'phrase'."
@@ -4881,44 +4881,44 @@ msgstr ""
"Fel: wep-key-type-argumentvärdet ”%s” är ogiltigt, använd ”key” eller "
"”phrase”."
-#: ../clients/cli/devices.c:2711 ../clients/cli/devices.c:2724
+#: ../clients/cli/devices.c:2733 ../clients/cli/devices.c:2746
#, c-format
msgid "Error: %s: %s."
msgstr "Fel: %s %s."
-#: ../clients/cli/devices.c:2739
+#: ../clients/cli/devices.c:2761
#, c-format
msgid "Error: BSSID to connect to (%s) differs from bssid argument (%s)."
msgstr ""
"Fel: BSSID att ansluta till (%s) skiljer sig från bssid-argumentet (%s)."
-#: ../clients/cli/devices.c:2745
+#: ../clients/cli/devices.c:2767
#, c-format
msgid "Error: Parameter '%s' is neither SSID nor BSSID."
msgstr "Fel: Parameter ”%s” är varken SSID eller BSSID."
-#: ../clients/cli/devices.c:2760 ../clients/cli/devices.c:3180
-#: ../clients/cli/devices.c:3329
+#: ../clients/cli/devices.c:2782 ../clients/cli/devices.c:3202
+#: ../clients/cli/devices.c:3351
#, c-format
msgid "Error: No Wi-Fi device found."
msgstr "Fel: Ingen trådlös enhet hittades."
-#: ../clients/cli/devices.c:2780
+#: ../clients/cli/devices.c:2802
#, c-format
msgid "Error: Failed to scan hidden SSID: %s."
msgstr "Fel: Misslyckades att söka av dolt SSID: %s."
-#: ../clients/cli/devices.c:2805
+#: ../clients/cli/devices.c:2827
#, c-format
msgid "Error: No network with SSID '%s' found."
msgstr "Fel: Inget nätverk med SSID ”%s” hittades."
-#: ../clients/cli/devices.c:2807
+#: ../clients/cli/devices.c:2829
#, c-format
msgid "Error: No access point with BSSID '%s' found."
msgstr "Fel: Ingen accesspunkt med BSSID ”%s” hittades."
-#: ../clients/cli/devices.c:2849
+#: ../clients/cli/devices.c:2871
#, c-format
msgid ""
"Warning: '%s' should be SSID for hidden APs; but it looks like a BSSID.\n"
@@ -4926,87 +4926,87 @@ msgstr ""
"Varning: ”%s” borde vara SSID för dolda accesspunkter, men det ser ut som "
"ett BSSID.\n"
-#: ../clients/cli/devices.c:2863
+#: ../clients/cli/devices.c:2885
msgid "Password: "
msgstr "Lösenord: "
-#: ../clients/cli/devices.c:3012
+#: ../clients/cli/devices.c:3034
#, c-format
msgid "'%s' is not valid WPA PSK"
msgstr "”%s” inte giltig WPA PSK"
-#: ../clients/cli/devices.c:3029
+#: ../clients/cli/devices.c:3051
#, c-format
msgid "'%s' is not valid WEP key (it should be 5 or 13 ASCII chars)"
msgstr "”%s” är inte en giltig WEP-nyckel (ska vara 5 eller 13 ASCII-tecken)"
-#: ../clients/cli/devices.c:3045
+#: ../clients/cli/devices.c:3067
#, c-format
msgid "Hotspot password: %s\n"
msgstr "Lösenord för surfzon: %s\n"
-#: ../clients/cli/devices.c:3103
+#: ../clients/cli/devices.c:3125
#, c-format
msgid "Error: ssid is too long."
msgstr "Fel: ssid är för långt."
-#: ../clients/cli/devices.c:3115
+#: ../clients/cli/devices.c:3137
#, c-format
msgid "Error: band argument value '%s' is invalid; use 'a' or 'bg'."
msgstr "Fel: argumentvärdet ”%s” för band är ogiltigt, använd ”a” eller ”bg”."
-#: ../clients/cli/devices.c:3139
+#: ../clients/cli/devices.c:3161
#, c-format
msgid "Error: Unknown parameter %s."
msgstr "Fel: Okänd parameter %s."
-#: ../clients/cli/devices.c:3158
+#: ../clients/cli/devices.c:3180
#, c-format
msgid "Error: channel requires band too."
msgstr "Fel: kanal kräver även band."
-#: ../clients/cli/devices.c:3164
+#: ../clients/cli/devices.c:3186
#, c-format
msgid "Error: channel '%s' not valid for band '%s'."
msgstr "Fel: kanal ”%s” är inte giltig för bandet ”%s”."
-#: ../clients/cli/devices.c:3192
+#: ../clients/cli/devices.c:3214
#, c-format
msgid "Error: Device '%s' supports neither AP nor Ad-Hoc mode."
msgstr "Fel: Enheten ”%s” stöder varken accesspunkts- eller Ad-Hoc-läge."
-#: ../clients/cli/devices.c:3227
+#: ../clients/cli/devices.c:3249
#, c-format
msgid "Error: Invalid 'password': %s."
msgstr "Fel: ogiltigt ”password”: %s."
# flaggan "ssid" kan upprepas
-#: ../clients/cli/devices.c:3296
+#: ../clients/cli/devices.c:3318
#, c-format
msgid "Error: '%s' cannot repeat."
msgstr "Fel: ”%s” kan inte upprepas."
-#: ../clients/cli/devices.c:3377
+#: ../clients/cli/devices.c:3399
#, c-format
msgid "Error: 'device wifi' command '%s' is not valid."
msgstr "Fel: ”device wifi”-kommandot ”%s” är inte giltigt."
#. Main header name
-#: ../clients/cli/devices.c:3403
+#: ../clients/cli/devices.c:3425
msgid "Device LLDP neighbors"
msgstr "LLDP-grannar för enhet"
-#: ../clients/cli/devices.c:3506
+#: ../clients/cli/devices.c:3528
#, c-format
msgid "Error: 'device lldp list': %s"
msgstr "Fel: ”device lldp list”: %s"
-#: ../clients/cli/devices.c:3553
+#: ../clients/cli/devices.c:3575
#, c-format
msgid "Error: 'device lldp' command '%s' is not valid."
msgstr "Fel: ”device lldp”-kommandot ”%s” är inte giltigt."
-#: ../clients/cli/devices.c:3742
+#: ../clients/cli/devices.c:3770
#, c-format
msgid "Error: 'dev' command '%s' is not valid."
msgstr "Fel: ”dev”-kommandot ”%s” är inte giltigt."
@@ -5382,158 +5382,158 @@ msgstr "full"
msgid "Error: only these fields are allowed: %s"
msgstr "Fel: endast dessa fält är tillåtna: %s"
-#: ../clients/cli/general.c:357
+#: ../clients/cli/general.c:360
msgid "NetworkManager status"
msgstr "Status för Nätverkshanteraren"
-#: ../clients/cli/general.c:362
+#: ../clients/cli/general.c:365
msgid "running"
msgstr "kör"
-#: ../clients/cli/general.c:365
+#: ../clients/cli/general.c:368
msgid "starting"
msgstr "startar"
-#: ../clients/cli/general.c:365
+#: ../clients/cli/general.c:368
msgid "started"
msgstr "startad"
-#: ../clients/cli/general.c:367 ../clients/cli/general.c:368
-#: ../clients/cli/general.c:369 ../clients/cli/general.c:370
-#: ../clients/cli/general.c:371
+#: ../clients/cli/general.c:370 ../clients/cli/general.c:371
+#: ../clients/cli/general.c:372 ../clients/cli/general.c:373
+#: ../clients/cli/general.c:374
msgid "enabled"
msgstr "aktiverad"
-#: ../clients/cli/general.c:367 ../clients/cli/general.c:368
-#: ../clients/cli/general.c:369 ../clients/cli/general.c:370
-#: ../clients/cli/general.c:371
+#: ../clients/cli/general.c:370 ../clients/cli/general.c:371
+#: ../clients/cli/general.c:372 ../clients/cli/general.c:373
+#: ../clients/cli/general.c:374
msgid "disabled"
msgstr "inaktiverad"
-#: ../clients/cli/general.c:443
+#: ../clients/cli/general.c:446
msgid "auth"
msgstr "aute"
-#: ../clients/cli/general.c:472
+#: ../clients/cli/general.c:475
#, c-format
msgid "Error: 'general permissions': %s"
msgstr "Fel: ”general permissions”: %s"
-#: ../clients/cli/general.c:486
+#: ../clients/cli/general.c:489
msgid "NetworkManager permissions"
msgstr "Rättigheter för Nätverkshanteraren"
-#: ../clients/cli/general.c:527
+#: ../clients/cli/general.c:530
#, c-format
msgid "Error: 'general logging': %s"
msgstr "Fel: ”general logging”: %s"
-#: ../clients/cli/general.c:542
+#: ../clients/cli/general.c:545
msgid "NetworkManager logging"
msgstr "Loggning för Nätverkshanteraren"
-#: ../clients/cli/general.c:564
+#: ../clients/cli/general.c:567
#, c-format
msgid "Error: failed to set hostname: %s"
msgstr "Fel: misslyckades med att sätta värdnamn: %s"
-#: ../clients/cli/general.c:677
+#: ../clients/cli/general.c:680
#, c-format
msgid "Error: failed to set logging: %s"
msgstr "Fel: misslyckades att sätta loggning: %s"
-#: ../clients/cli/general.c:686
+#: ../clients/cli/general.c:689
#, c-format
msgid "Error: 'general' command '%s' is not valid."
msgstr "Fel: ”general”-kommandot ”%s” är inte giltigt."
-#: ../clients/cli/general.c:704
+#: ../clients/cli/general.c:707
#, c-format
msgid "Error: '--fields' value '%s' is not valid here (allowed field: %s)"
msgstr ""
"Fel: värdet ”%s” för ”--fields” är inte giltigt här (tillåtna fält: %s)"
-#: ../clients/cli/general.c:729
+#: ../clients/cli/general.c:732
#, c-format
msgid "Error: invalid '%s' argument: '%s' (use on/off)."
msgstr "Fel: ogiltigt ”%s”-argument: ”%s” (använd på/av)."
-#: ../clients/cli/general.c:740
+#: ../clients/cli/general.c:743
msgid "Connectivity"
msgstr "Anslutning"
-#: ../clients/cli/general.c:755
+#: ../clients/cli/general.c:758
msgid "Networking"
msgstr "Nätverk"
-#: ../clients/cli/general.c:780
+#: ../clients/cli/general.c:783
#, c-format
msgid "Error: 'networking connectivity' command '%s' is not valid."
msgstr "Fel: ”networking connectivity”-kommandot ”%s” är inte giltigt."
-#: ../clients/cli/general.c:796
+#: ../clients/cli/general.c:799
#, c-format
msgid "Error: 'networking' command '%s' is not valid."
msgstr "Fel: ”networking”-kommandot ”%s” är inte giltigt."
-#: ../clients/cli/general.c:825 ../clients/cli/general.c:845
+#: ../clients/cli/general.c:828 ../clients/cli/general.c:848
msgid "Radio switches"
msgstr "Radioväxlar"
#. no argument, show current WiFi state
-#: ../clients/cli/general.c:863
+#: ../clients/cli/general.c:866
msgid "Wi-Fi radio switch"
msgstr "Trådlös radioväxel"
#. no argument, show current WWAN (mobile broadband) state
-#: ../clients/cli/general.c:879
+#: ../clients/cli/general.c:882
msgid "WWAN radio switch"
msgstr "WWAN radioväxel"
-#: ../clients/cli/general.c:890
+#: ../clients/cli/general.c:893
#, c-format
msgid "Error: 'radio' command '%s' is not valid."
msgstr "Fel: ”radio”-kommandot ”%s” är inte giltigt."
-#: ../clients/cli/general.c:911
+#: ../clients/cli/general.c:914
msgid "NetworkManager has started"
msgstr "Nätverkshanteraren har startats"
-#: ../clients/cli/general.c:914
+#: ../clients/cli/general.c:917
msgid "NetworkManager has stopped"
msgstr "Nätverkshanteraren har stoppats"
-#: ../clients/cli/general.c:928
+#: ../clients/cli/general.c:931
#, c-format
msgid "Hostname set to '%s'\n"
msgstr "Värdnamnet sattes till ”%s”\n"
-#: ../clients/cli/general.c:943
+#: ../clients/cli/general.c:946
#, c-format
msgid "'%s' is now the primary connection\n"
msgstr "”%s” är nu den primära anslutningen\n"
-#: ../clients/cli/general.c:945
+#: ../clients/cli/general.c:948
#, c-format
msgid "There's no primary connection\n"
msgstr "Det finns ingen primär anslutning\n"
-#: ../clients/cli/general.c:957
+#: ../clients/cli/general.c:960
#, c-format
msgid "Connectivity is now '%s'\n"
msgstr "Anslutbarhet är nu ”%s”\n"
-#: ../clients/cli/general.c:970
+#: ../clients/cli/general.c:973
#, c-format
msgid "Networkmanager is now in the '%s' state\n"
msgstr "Nätverkshanteraren är nu i tillståndet ”%s”\n"
-#: ../clients/cli/general.c:981
+#: ../clients/cli/general.c:984
#, c-format
msgid "Error: 'monitor' command '%s' is not valid."
msgstr "Fel: ”monitor”-kommandot ”%s” är inte giltigt."
-#: ../clients/cli/general.c:995
+#: ../clients/cli/general.c:998
msgid "Networkmanager is not running (waiting for it)\n"
msgstr "Nätverkshanteraren är inte startad (väntar på den)\n"
@@ -5595,64 +5595,64 @@ msgstr ""
" m[onitor] övervaka ändringar för Nätverkshanteraren\n"
"\n"
-#: ../clients/cli/nmcli.c:142
+#: ../clients/cli/nmcli.c:143
#, c-format
msgid "Error: Object '%s' is unknown, try 'nmcli help'."
msgstr "Fel: Objektet ”%s” är okänt, prova ”nmcli help”."
-#: ../clients/cli/nmcli.c:172
+#: ../clients/cli/nmcli.c:173
#, c-format
msgid "Error: Option '--terse' is specified the second time."
msgstr "Fel: Flaggan ”--terse” har angivits en andra gång."
-#: ../clients/cli/nmcli.c:177
+#: ../clients/cli/nmcli.c:178
#, c-format
msgid "Error: Option '--terse' is mutually exclusive with '--pretty'."
msgstr "Fel: Flaggan ”--terse” är ömsesidigt uteslutande med ”--pretty”."
-#: ../clients/cli/nmcli.c:185
+#: ../clients/cli/nmcli.c:186
#, c-format
msgid "Error: Option '--pretty' is specified the second time."
msgstr "Fel: Flaggan ”--pretty” har angivits en andra gång."
-#: ../clients/cli/nmcli.c:190
+#: ../clients/cli/nmcli.c:191
#, c-format
msgid "Error: Option '--pretty' is mutually exclusive with '--terse'."
msgstr "Fel: Flaggan ”--pretty” är ömsesidigt uteslutande med ”--terse”."
-#: ../clients/cli/nmcli.c:200 ../clients/cli/nmcli.c:216
-#: ../clients/cli/nmcli.c:234 ../clients/cli/nmcli.c:265
+#: ../clients/cli/nmcli.c:201 ../clients/cli/nmcli.c:217
+#: ../clients/cli/nmcli.c:235 ../clients/cli/nmcli.c:266
#, c-format
msgid "Error: missing argument for '%s' option."
msgstr "Fel: argument för flaggan ”%s” saknas."
-#: ../clients/cli/nmcli.c:209 ../clients/cli/nmcli.c:227
-#: ../clients/cli/nmcli.c:243
+#: ../clients/cli/nmcli.c:210 ../clients/cli/nmcli.c:228
+#: ../clients/cli/nmcli.c:244
#, c-format
msgid "Error: '%s' is not valid argument for '%s' option."
msgstr "Fel: ”%s” är inte ett giltigt argument för flaggan ”%s”."
-#: ../clients/cli/nmcli.c:250
+#: ../clients/cli/nmcli.c:251
#, c-format
msgid "Error: fields for '%s' options are missing."
msgstr "Fel: fält för ”%s”-flaggor saknas."
-#: ../clients/cli/nmcli.c:270
+#: ../clients/cli/nmcli.c:271
#, c-format
msgid "Error: '%s' is not a valid timeout for '%s' option."
msgstr "Fel: ”%s” är inte en giltig tidsgräns för flaggan ”%s”."
-#: ../clients/cli/nmcli.c:277
+#: ../clients/cli/nmcli.c:278
#, c-format
msgid "nmcli tool, version %s\n"
msgstr "nmcli-verktyg, version %s\n"
-#: ../clients/cli/nmcli.c:283
+#: ../clients/cli/nmcli.c:284
#, c-format
msgid "Error: Option '%s' is unknown, try 'nmcli -help'."
msgstr "Fel: Flaggan ”%s” är okänd, prova ”nmcli -help”."
-#: ../clients/cli/nmcli.c:366 ../clients/cli/nmcli.c:376
+#: ../clients/cli/nmcli.c:367 ../clients/cli/nmcli.c:377
#, c-format
msgid ""
"\n"
@@ -5661,22 +5661,22 @@ msgstr ""
"\n"
"Fel: nmcli dödad av signalen %s (%d)\n"
-#: ../clients/cli/nmcli.c:407
+#: ../clients/cli/nmcli.c:408
#, c-format
msgid "Failed to set signal mask: %d\n"
msgstr "Misslyckades med att sätta signalmasken: %d\n"
-#: ../clients/cli/nmcli.c:414
+#: ../clients/cli/nmcli.c:415
#, c-format
msgid "Failed to create signal handling thread: %d\n"
msgstr "Misslyckades med att skapa signalhanteringstråd: %d\n"
-#: ../clients/cli/nmcli.c:511 ../clients/nm-online.c:193
+#: ../clients/cli/nmcli.c:512 ../clients/nm-online.c:193
#, c-format
msgid "Error: Could not create NMClient object: %s."
msgstr "Fel: Kunde inte skapa NMClient-objektet: %s."
-#: ../clients/cli/nmcli.c:528
+#: ../clients/cli/nmcli.c:529
msgid "Success"
msgstr "Lyckades"
@@ -5837,112 +5837,112 @@ msgstr "ogiltigt läge ”%s”, använd en av %s"
msgid "always"
msgstr "alltid"
-#: ../clients/cli/settings.c:1999 ../clients/cli/settings.c:3279
-#: ../clients/cli/settings.c:4471 ../clients/cli/settings.c:4974
+#: ../clients/cli/settings.c:1999 ../clients/cli/settings.c:3286
+#: ../clients/cli/settings.c:4478 ../clients/cli/settings.c:4981
#: ../libnm-core/nm-keyfile-reader.c:573
#, c-format
msgid "invalid option '%s', use one of [%s]"
msgstr "ogiltig flagga ”%s”, använd en av [%s]"
-#: ../clients/cli/settings.c:2109
+#: ../clients/cli/settings.c:2116
#, c-format
msgid "Do you also want to set '%s' to '%s'? [yes]: "
msgstr "Vill du också sätta ”%s” till ”%s”? [yes]: "
-#: ../clients/cli/settings.c:2111
+#: ../clients/cli/settings.c:2118
#, c-format
msgid "Do you also want to clear '%s'? [yes]: "
msgstr "Vill du också rensa ”%s”? [yes]: "
-#: ../clients/cli/settings.c:2272
+#: ../clients/cli/settings.c:2279
#, c-format
msgid ""
"Warning: %s.%s set to '%s', but it might be ignored in infrastructure mode\n"
msgstr ""
"Varning: %s.%s sätts till ”%s”, men kan ignoreras i infrastrukturläge\n"
-#: ../clients/cli/settings.c:2291
+#: ../clients/cli/settings.c:2298
#, c-format
msgid "Warning: setting %s.%s requires removing ipv4 and ipv6 settings\n"
msgstr ""
"Varning: inställningen %s.%s kräver att inställningar för ipv4 och ipv6 tas "
"bort\n"
-#: ../clients/cli/settings.c:2293
+#: ../clients/cli/settings.c:2300
msgid "Do you want to remove them? [yes] "
msgstr "Vill du ta bort dem? [ja] "
-#: ../clients/cli/settings.c:2389 ../clients/cli/settings.c:2784
-#: ../clients/cli/settings.c:5175
+#: ../clients/cli/settings.c:2396 ../clients/cli/settings.c:2791
+#: ../clients/cli/settings.c:5182
#, c-format
msgid "'%s' is not valid"
msgstr "”%s” är inte giltigt"
-#: ../clients/cli/settings.c:2412
+#: ../clients/cli/settings.c:2419
#, c-format
msgid "'%d' is not valid; use <%d-%d>"
msgstr "”%d” är inte giltigt; använd <%d-%d>"
-#: ../clients/cli/settings.c:2434
+#: ../clients/cli/settings.c:2441
#, c-format
msgid "'%lld' is not valid; use <%lld-%lld>"
msgstr "”%lld” är inte giltigt; använd <%lld-%lld>"
-#: ../clients/cli/settings.c:2456
+#: ../clients/cli/settings.c:2463
#, c-format
msgid "'%u' is not valid; use <%u-%u>"
msgstr "”%u” är inte giltigt; använd <%u-%u>"
-#: ../clients/cli/settings.c:2495
+#: ../clients/cli/settings.c:2502
#, c-format
msgid "'%u' flags are not valid; use combination of %s"
msgstr "”%u”-flaggor är inte giltiga; använd en kombination av %s"
-#: ../clients/cli/settings.c:2562
+#: ../clients/cli/settings.c:2569
#, c-format
msgid "'%s' is not valid; use <option>=<value>"
msgstr "”%s” är inte giltigt; använd <flagga>=<värde>"
-#: ../clients/cli/settings.c:2596
+#: ../clients/cli/settings.c:2603
#, c-format
msgid "index '%s' is not valid"
msgstr "indexet ”%s” är inte giltigt"
-#: ../clients/cli/settings.c:2601 ../clients/cli/settings.c:2626
+#: ../clients/cli/settings.c:2608 ../clients/cli/settings.c:2633
msgid "no item to remove"
msgstr "inget objekt att ta bort"
-#: ../clients/cli/settings.c:2605 ../clients/cli/settings.c:2630
+#: ../clients/cli/settings.c:2612 ../clients/cli/settings.c:2637
#, c-format
msgid "index '%d' is not in range <0-%d>"
msgstr "index ”%d” är inte i intervallet <0-%d>"
-#: ../clients/cli/settings.c:2645
+#: ../clients/cli/settings.c:2652
#, c-format
msgid "invalid option '%s'"
msgstr "ogiltig flagga ”%s”"
-#: ../clients/cli/settings.c:2647
+#: ../clients/cli/settings.c:2654
msgid "missing option"
msgstr "saknad flagga"
-#: ../clients/cli/settings.c:2674 ../clients/cli/settings.c:2694
-#: ../clients/cli/settings.c:2714 ../clients/cli/settings.c:2734
+#: ../clients/cli/settings.c:2681 ../clients/cli/settings.c:2701
+#: ../clients/cli/settings.c:2721 ../clients/cli/settings.c:2741
#, c-format
msgid "'%s' is not a valid number (or out of range)"
msgstr "”%s” är inte ett giltigt nummer (eller utanför intervallet)"
-#: ../clients/cli/settings.c:2768
+#: ../clients/cli/settings.c:2775
#, c-format
msgid "'%s' is not a valid value; use -1, 0 or 1"
msgstr "”%s” är inte ett giltigt värde; använd -1, 0 eller 1"
-#: ../clients/cli/settings.c:2800
+#: ../clients/cli/settings.c:2807
#, c-format
msgid "'%s' is not a valid Ethernet MAC"
msgstr "”%s” är inte en giltig Ethernet MAC"
-#: ../clients/cli/settings.c:2825 ../libnm-core/nm-setting-connection.c:864
+#: ../clients/cli/settings.c:2832 ../libnm-core/nm-setting-connection.c:864
#: ../libnm-core/nm-setting-infiniband.c:255
#: ../libnm-util/nm-setting-connection.c:834
#: ../libnm-util/nm-setting-infiniband.c:269
@@ -5950,38 +5950,38 @@ msgstr "”%s” är inte en giltig Ethernet MAC"
msgid "'%s' is not a valid interface name"
msgstr "”%s” är inte ett giltigt gränssnittsnamn"
-#: ../clients/cli/settings.c:2849
+#: ../clients/cli/settings.c:2856
#, c-format
msgid "'%s' is not a valid flag number; use <0-%d>"
msgstr "”%s” är inte ett giltigt flaggnummer; använd <0-%d>"
-#: ../clients/cli/settings.c:2861
+#: ../clients/cli/settings.c:2868
#, c-format
msgid "Warning: '%s' sum is higher than all flags => all flags set\n"
msgstr "Varning: ”%s”-summan är högre än alla flaggor => alla flaggor satta\n"
-#: ../clients/cli/settings.c:2902
+#: ../clients/cli/settings.c:2909
#, c-format
msgid "'%s' is not a valid hex character"
msgstr "”%s” är inte ett giltigt hextecken"
-#: ../clients/cli/settings.c:2932
+#: ../clients/cli/settings.c:2939
#, c-format
msgid "'%s' is not a valid MAC"
msgstr "”%s” är inte ett giltigt MAC"
-#: ../clients/cli/settings.c:2958 ../libnm-core/nm-setting-connection.c:853
+#: ../clients/cli/settings.c:2965 ../libnm-core/nm-setting-connection.c:853
#: ../libnm-util/nm-setting-connection.c:791
#, c-format
msgid "'%s' is not a valid UUID"
msgstr "”%s” är inte ett giltigt UUID"
-#: ../clients/cli/settings.c:3025
+#: ../clients/cli/settings.c:3032
#, c-format
msgid "the property doesn't contain permission '%s'"
msgstr "egenskapen innehåller inte rättigheten ”%s”"
-#: ../clients/cli/settings.c:3037
+#: ../clients/cli/settings.c:3044
msgid ""
"Enter a list of user permissions. This is a list of user names formatted "
"as:\n"
@@ -5997,37 +5997,37 @@ msgstr ""
"\n"
"Exempel: anders maria sebastian\n"
-#: ../clients/cli/settings.c:3056
+#: ../clients/cli/settings.c:3063
#, c-format
msgid "'%s' is not valid master; use ifname or connection UUID"
msgstr "”%s” är inte en giltig master; använd grnamn eller anslutnings-UUID"
-#: ../clients/cli/settings.c:3100
+#: ../clients/cli/settings.c:3107
#, c-format
msgid "Warning: %s is not an UUID of any existing connection profile\n"
msgstr "Varning: %s är inte ett UUID på någon befintlig anslutningsprofil\n"
-#: ../clients/cli/settings.c:3104 ../clients/cli/settings.c:3120
+#: ../clients/cli/settings.c:3111 ../clients/cli/settings.c:3127
#, c-format
msgid "'%s' is not a VPN connection profile"
msgstr "”%s” är inte en giltig VPN-anslutningsprofil"
-#: ../clients/cli/settings.c:3113
+#: ../clients/cli/settings.c:3120
#, c-format
msgid "'%s' is not a name of any exiting profile"
msgstr "”%s” är inte ett namn på någon befintlig profil"
-#: ../clients/cli/settings.c:3147
+#: ../clients/cli/settings.c:3154
#, c-format
msgid "the value '%s' is not a valid UUID"
msgstr "värdet ”%s” är inte ett giltigt UUID"
-#: ../clients/cli/settings.c:3154
+#: ../clients/cli/settings.c:3161
#, c-format
msgid "the property doesn't contain UUID '%s'"
msgstr "egenskapen innehåller inte UUID ”%s”"
-#: ../clients/cli/settings.c:3166
+#: ../clients/cli/settings.c:3173
msgid ""
"Enter secondary connections that should be activated when this connection "
"is\n"
@@ -6048,7 +6048,7 @@ msgstr ""
"\n"
"Exempel: private-openvpn, fe6ba5d8-c2fc-4aae-b2e3-97efddd8d9a7\n"
-#: ../clients/cli/settings.c:3233
+#: ../clients/cli/settings.c:3240
msgid ""
"Enter a value which indicates whether the connection is subject to a data\n"
"quota, usage costs or other limitations. Accepted options are:\n"
@@ -6064,16 +6064,16 @@ msgstr ""
"”unknown” för att låta Nätverkshanteraren välja ett värde enligt någon "
"heuristik\n"
-#: ../clients/cli/settings.c:3357
+#: ../clients/cli/settings.c:3364
msgid "private key password not provided"
msgstr "lösenord för privat nyckel inte angivet"
-#: ../clients/cli/settings.c:3385
+#: ../clients/cli/settings.c:3392
#, c-format
msgid "the property doesn't contain EAP method '%s'"
msgstr "egenskapen innehåller inte EAP-metoden ”%s”"
-#: ../clients/cli/settings.c:3402
+#: ../clients/cli/settings.c:3409
msgid ""
"Enter file path to CA certificate (optionally prefixed with file://).\n"
" [file://]<file path>\n"
@@ -6085,12 +6085,12 @@ msgstr ""
"Observera att nmcli inte stödjer att ange certifikat som rå blob-data.\n"
"Exempel: /home/cimrman/cacert.crt\n"
-#: ../clients/cli/settings.c:3421
+#: ../clients/cli/settings.c:3428
#, c-format
msgid "the property doesn't contain alternative subject match '%s'"
msgstr "egenskapen innehåller inte alternativa ämnesmatchningen ”%s”"
-#: ../clients/cli/settings.c:3437
+#: ../clients/cli/settings.c:3444
msgid ""
"Enter file path to client certificate (optionally prefixed with file://).\n"
" [file://]<file path>\n"
@@ -6102,7 +6102,7 @@ msgstr ""
"Observera att nmcli inte stödjer att ange certifikat som rå blob-data.\n"
"Exempel: /home/cimrman/jara.crt\n"
-#: ../clients/cli/settings.c:3449
+#: ../clients/cli/settings.c:3456
msgid ""
"Enter file path to CA certificate for inner authentication (optionally "
"prefixed\n"
@@ -6118,12 +6118,12 @@ msgstr ""
"Observera att nmcli inte stödjer att ange certifikat som rå blob-data.\n"
"Exempel: /home/cimrman/ca-zweite-phase.crt\n"
-#: ../clients/cli/settings.c:3469
+#: ../clients/cli/settings.c:3476
#, c-format
msgid "the property doesn't contain \"phase2\" alternative subject match '%s'"
msgstr "egenskapen innehåller inte ”phase2”-alternativa ämnesmatchningen ”%s”"
-#: ../clients/cli/settings.c:3485
+#: ../clients/cli/settings.c:3492
msgid ""
"Enter file path to client certificate for inner authentication (optionally "
"prefixed\n"
@@ -6139,7 +6139,7 @@ msgstr ""
"Observera att nmcli inte stödjer att ange certifikat som rå blob-data.\n"
"Exempel: /home/cimrman/jara-zweite-phase.crt\n"
-#: ../clients/cli/settings.c:3505
+#: ../clients/cli/settings.c:3512
msgid ""
"Enter path to a private key and the key password (if not set yet):\n"
" [file://]<file path> [<password>]\n"
@@ -6152,7 +6152,7 @@ msgstr ""
"Observera att nmcli inte stödjer att ange privat nyckel som rå blob-data.\n"
"Exempel: /home/cimrman/jara-priv-key Dardanely\n"
-#: ../clients/cli/settings.c:3576
+#: ../clients/cli/settings.c:3583
msgid ""
"Enter bytes as a list of hexadecimal values.\n"
"Two formats are accepted:\n"
@@ -6174,7 +6174,7 @@ msgstr ""
"Exempel: ab0455a6ea3a74C2\n"
" ab 4 55 0xa6 ea 3a 74 C2\n"
-#: ../clients/cli/settings.c:3697
+#: ../clients/cli/settings.c:3704
#, c-format
msgid ""
"Enter a list of bonding options formatted as:\n"
@@ -6205,32 +6205,32 @@ msgstr ""
"\n"
"Exempel: mode=2,miimon=120\n"
-#: ../clients/cli/settings.c:3728
+#: ../clients/cli/settings.c:3735
#, c-format
msgid "'%s' is not a valid InfiniBand MAC"
msgstr "”%s” är inte en giltig InfiniBand MAC"
-#: ../clients/cli/settings.c:3765
+#: ../clients/cli/settings.c:3772
#, c-format
msgid "'%s' is not a valid IBoIP P_Key"
msgstr "”%s” är inte en giltig IBoIP P_Key"
-#: ../clients/cli/settings.c:3796
+#: ../clients/cli/settings.c:3803
#, c-format
msgid "'%s' is not valid (the format is: ip[/prefix] [next-hop] [metric])"
msgstr "”%s” är inte giltigt (formatet är: ip[/prefix] [next-hop] [metric])"
-#: ../clients/cli/settings.c:3844 ../clients/cli/settings.c:3863
+#: ../clients/cli/settings.c:3851 ../clients/cli/settings.c:3870
#, c-format
msgid "invalid IPv4 address '%s'"
msgstr "ogiltig IPv4-adress ”%s”"
-#: ../clients/cli/settings.c:3869 ../clients/cli/settings.c:4177
+#: ../clients/cli/settings.c:3876 ../clients/cli/settings.c:4184
#, c-format
msgid "the property doesn't contain DNS server '%s'"
msgstr "egenskapen innehåller inte DNS-servern ”%s”"
-#: ../clients/cli/settings.c:3881
+#: ../clients/cli/settings.c:3888
msgid ""
"Enter a list of IPv4 addresses of DNS servers.\n"
"\n"
@@ -6240,22 +6240,22 @@ msgstr ""
"\n"
"Exempel: 8.8.8.8, 8.8.4.4\n"
-#: ../clients/cli/settings.c:3917 ../clients/cli/settings.c:4231
+#: ../clients/cli/settings.c:3924 ../clients/cli/settings.c:4238
#, c-format
msgid "the property doesn't contain DNS search domain '%s'"
msgstr "egenskapen innehåller inte DNS-sökdomänen ”%s”"
-#: ../clients/cli/settings.c:3955 ../clients/cli/settings.c:4269
+#: ../clients/cli/settings.c:3962 ../clients/cli/settings.c:4276
#, c-format
msgid "the property doesn't contain DNS option '%s'"
msgstr "egenskapen stöder inte DNS-alternativet ”%s”"
-#: ../clients/cli/settings.c:4009 ../clients/cli/settings.c:4322
+#: ../clients/cli/settings.c:4016 ../clients/cli/settings.c:4329
#, c-format
msgid "the property doesn't contain IP address '%s'"
msgstr "egenskapen innehåller inte IP-adressen ”%s”"
-#: ../clients/cli/settings.c:4022
+#: ../clients/cli/settings.c:4029
msgid ""
"Enter a list of IPv4 addresses formatted as:\n"
" ip[/prefix], ip[/prefix],...\n"
@@ -6269,17 +6269,17 @@ msgstr ""
"\n"
"Exempel: 192.168.1.5/24 192.168.1.1, 10.0.0.11/24\n"
-#: ../clients/cli/settings.c:4038 ../clients/cli/settings.c:4351
+#: ../clients/cli/settings.c:4045 ../clients/cli/settings.c:4358
#, c-format
msgid "invalid gateway address '%s'"
msgstr "ogiltig gateway-adress ”%s”"
-#: ../clients/cli/settings.c:4093 ../clients/cli/settings.c:4406
+#: ../clients/cli/settings.c:4100 ../clients/cli/settings.c:4413
#, c-format
msgid "the property doesn't contain route '%s'"
msgstr "egenskapen innehåller inte rutten ”%s”"
-#: ../clients/cli/settings.c:4106
+#: ../clients/cli/settings.c:4113
msgid ""
"Enter a list of IPv4 routes formatted as:\n"
" ip[/prefix] [next-hop] [metric],...\n"
@@ -6302,12 +6302,12 @@ msgstr ""
"Exempel: 192.168.2.0/24 192.168.2.1 3, 10.1.0.0/16 10.0.0.254\n"
" 10.1.2.0/24\n"
-#: ../clients/cli/settings.c:4152 ../clients/cli/settings.c:4171
+#: ../clients/cli/settings.c:4159 ../clients/cli/settings.c:4178
#, c-format
msgid "invalid IPv6 address '%s'"
msgstr "ogiltig IPv6-adress ”%s”"
-#: ../clients/cli/settings.c:4189
+#: ../clients/cli/settings.c:4196
msgid ""
"Enter a list of IPv6 addresses of DNS servers. If the IPv6 configuration "
"method is 'auto' these DNS servers are appended to those (if any) returned "
@@ -6327,7 +6327,7 @@ msgstr ""
"\n"
"Exempel: 2607:f0d0:1002:51::4, 2607:f0d0:1002:51::1\n"
-#: ../clients/cli/settings.c:4335
+#: ../clients/cli/settings.c:4342
msgid ""
"Enter a list of IPv6 addresses formatted as:\n"
" ip[/prefix], ip[/prefix],...\n"
@@ -6342,7 +6342,7 @@ msgstr ""
"Exempel: 2607:f0d0:1002:51::4/64 2607:f0d0:1002:51::1, "
"1050:0:0:0:5:600:300c:326b\n"
-#: ../clients/cli/settings.c:4419
+#: ../clients/cli/settings.c:4426
msgid ""
"Enter a list of IPv6 routes formatted as:\n"
" ip[/prefix] [next-hop] [metric],...\n"
@@ -6366,28 +6366,28 @@ msgstr ""
"db8:beef::3 2\n"
" abbe::/64 55\n"
-#: ../clients/cli/settings.c:4436 ../libnm-core/nm-setting-gsm.c:363
+#: ../clients/cli/settings.c:4443 ../libnm-core/nm-setting-gsm.c:363
#: ../libnm-util/nm-setting-gsm.c:364
#, c-format
msgid "'%s' is not a number"
msgstr "”%s” är inte ett nummer"
-#: ../clients/cli/settings.c:4443
+#: ../clients/cli/settings.c:4450
#, c-format
msgid "'%s' is not valid; use 0, 1, or 2"
msgstr "”%s” är inte giltig; använd 0, 1 eller 2"
-#: ../clients/cli/settings.c:4490
+#: ../clients/cli/settings.c:4497
#, c-format
msgid "'%s' is not a valid channel; use <1-13>"
msgstr "”%s” är inte en giltig kanal; använd <1-13>"
-#: ../clients/cli/settings.c:4527
+#: ../clients/cli/settings.c:4534
#, c-format
msgid "'%s' is not valid; use [e, o, n]"
msgstr "”%s” är inte giltig; använd [e, o, n]"
-#: ../clients/cli/settings.c:4555
+#: ../clients/cli/settings.c:4562
msgid ""
"nmcli can accepts both direct JSON configuration data and a file name "
"containing the configuration. In the latter case the file is read and the "
@@ -6405,32 +6405,32 @@ msgstr ""
"\"roundrobin\"}, \"ports\": {\"eth1\": {}, \"eth2\": {}} }\n"
" set team.config /etc/my-team.conf\n"
-#: ../clients/cli/settings.c:4595
+#: ../clients/cli/settings.c:4602
msgid "no priority to remove"
msgstr "ingen prioritet att ta bort"
-#: ../clients/cli/settings.c:4599
+#: ../clients/cli/settings.c:4606
#, c-format
msgid "index '%d' is not in the range of <0-%d>"
msgstr "index ”%d” är inte i intervallet för <0-%d>"
-#: ../clients/cli/settings.c:4638
+#: ../clients/cli/settings.c:4645
#, c-format
msgid ""
"Warning: only one mapping at a time is supported; taking the first one (%s)\n"
msgstr "Varning: endast en mappning åt gången stöds; tar den första (%s)\n"
-#: ../clients/cli/settings.c:4645
+#: ../clients/cli/settings.c:4652
#, c-format
msgid "the property doesn't contain mapping '%s'"
msgstr "egenskapen stöder inte mappningen ”%s”"
-#: ../clients/cli/settings.c:4693
+#: ../clients/cli/settings.c:4700
#, c-format
msgid "'%s' cannot be empty"
msgstr "”%s” kan inte vara tomt"
-#: ../clients/cli/settings.c:4767 ../clients/cli/settings.c:4934
+#: ../clients/cli/settings.c:4774 ../clients/cli/settings.c:4941
#: ../libnm-core/nm-setting-wired.c:651 ../libnm-core/nm-setting-wireless.c:820
#: ../libnm-core/nm-setting-wireless.c:832 ../libnm-util/nm-setting-wired.c:646
#: ../libnm-util/nm-setting-wireless.c:859
@@ -6439,17 +6439,17 @@ msgstr "”%s” kan inte vara tomt"
msgid "'%s' is not a valid MAC address"
msgstr "”%s” är inte en giltig MAC-adress"
-#: ../clients/cli/settings.c:4773 ../clients/cli/settings.c:4940
+#: ../clients/cli/settings.c:4780 ../clients/cli/settings.c:4947
#, c-format
msgid "the property doesn't contain MAC address '%s'"
msgstr "egenskapen innehåller inte MAC-adress ”%s”"
-#: ../clients/cli/settings.c:4792
+#: ../clients/cli/settings.c:4799
#, c-format
msgid "'%s' is not valid; 2 or 3 strings should be provided"
msgstr "”%s” är ogiltig; Två eller tre strängar ska anges"
-#: ../clients/cli/settings.c:4806
+#: ../clients/cli/settings.c:4813
msgid ""
"Enter a list of subchannels (comma or space separated).\n"
"\n"
@@ -6459,12 +6459,12 @@ msgstr ""
"\n"
"Exempel: 0.0.0e20 0.0.0e21 0.0.0e22\n"
-#: ../clients/cli/settings.c:4828
+#: ../clients/cli/settings.c:4835
#, c-format
msgid "'%s' string value should consist of 1 - 199 characters"
msgstr "”%s”-strängvärde ska bestå av 1 - 199 tecken"
-#: ../clients/cli/settings.c:4860
+#: ../clients/cli/settings.c:4867
#, c-format
msgid ""
"Enter a list of S/390 options formatted as:\n"
@@ -6475,28 +6475,28 @@ msgstr ""
" option = <värde>, option = <värde>,…\n"
"Giltiga val är: %s\n"
-#: ../clients/cli/settings.c:4906
+#: ../clients/cli/settings.c:4913
#, c-format
msgid "'%s' is not a valid channel"
msgstr "”%s” är inte en giltig kanal"
-#: ../clients/cli/settings.c:4912
+#: ../clients/cli/settings.c:4919
#, c-format
msgid "'%ld' is not a valid channel"
msgstr "”%ld” är en ogiltig kanal"
-#: ../clients/cli/settings.c:5006
+#: ../clients/cli/settings.c:5013
#, c-format
msgid "invalid option '%s', use 'default', 'never' or 'always'"
msgstr "ogiltig flagga ”%s”, använd ”default”, ”never” eller ”always”"
-#: ../clients/cli/settings.c:5067 ../clients/cli/settings.c:5106
-#: ../clients/cli/settings.c:5145
+#: ../clients/cli/settings.c:5074 ../clients/cli/settings.c:5113
+#: ../clients/cli/settings.c:5152
#, c-format
msgid "the property doesn't contain protocol '%s'"
msgstr "egenskapen innehåller inte protokollet ”%s”"
-#: ../clients/cli/settings.c:5184
+#: ../clients/cli/settings.c:5191
#, c-format
msgid ""
"'%s' not compatible with %s '%s', please change the key or set the right %s "
@@ -6504,23 +6504,23 @@ msgid ""
msgstr ""
"”%s” är inte kompatibel med %s ”%s”, ändra nyckeln eller sätt rätt %s först."
-#: ../clients/cli/settings.c:5192
+#: ../clients/cli/settings.c:5199
#, c-format
msgid "WEP key is guessed to be of '%s'\n"
msgstr "WEP-nyckel antas vara ”%s”\n"
-#: ../clients/cli/settings.c:5194
+#: ../clients/cli/settings.c:5201
#, c-format
msgid "WEP key index set to '%d'\n"
msgstr "index för WEP-nyckel satt till ”%d”\n"
-#: ../clients/cli/settings.c:5217
+#: ../clients/cli/settings.c:5224
#, c-format
msgid "'%s' not among [0 (unknown), 1 (key), 2 (passphrase)]"
msgstr "”%s” inte bland [0 (okänd), 1 (nyckel), 2 (lösenfras)]"
-#: ../clients/cli/settings.c:5233 ../clients/cli/settings.c:5236
-#: ../clients/cli/settings.c:5239 ../clients/cli/settings.c:5242
+#: ../clients/cli/settings.c:5240 ../clients/cli/settings.c:5243
+#: ../clients/cli/settings.c:5246 ../clients/cli/settings.c:5249
#, c-format
msgid ""
"Warning: '%s' is not compatible with '%s' type, please change or delete the "
@@ -6528,7 +6528,7 @@ msgid ""
msgstr ""
"Varning:”%s” är inte kompatibel med ”%s”-typ, ändra eller ta bort nyckeln.\n"
-#: ../clients/cli/settings.c:5255
+#: ../clients/cli/settings.c:5262
#, c-format
msgid ""
"Enter the type of WEP keys. The accepted values are: 0 or unknown, 1 or key, "
@@ -6537,36 +6537,36 @@ msgstr ""
"Ange typ på WEP-nycklarna. Accepterade värden är: 0 eller okänd, 1 eller "
"nyckel, 2 eller lösenfras.\n"
-#: ../clients/cli/settings.c:5268
+#: ../clients/cli/settings.c:5275
#, c-format
msgid "'%s' is not a valid PSK"
msgstr "”%s” inte en giltig PSK"
-#: ../clients/cli/settings.c:5312
+#: ../clients/cli/settings.c:5319
#, c-format
msgid "'%s' is not a valid DCB flag"
msgstr "”%s” är inte en giltig DCB-flagga"
-#: ../clients/cli/settings.c:5335
+#: ../clients/cli/settings.c:5342
#, c-format
msgid "'%s' is not a DCB app priority"
msgstr "”%s” är inte en giltig DCB-programprioritet"
-#: ../clients/cli/settings.c:5361
+#: ../clients/cli/settings.c:5368
msgid "must contain 8 comma-separated numbers"
msgstr "måste innehålla 8 kommaseparerade siffror"
-#: ../clients/cli/settings.c:5378
+#: ../clients/cli/settings.c:5385
#, c-format
msgid "'%s' not a number between 0 and %u (inclusive) or %u"
msgstr "”%s” inte en siffra mellan 0 och %u (inklusive) eller %u"
-#: ../clients/cli/settings.c:5381
+#: ../clients/cli/settings.c:5388
#, c-format
msgid "'%s' not a number between 0 and %u (inclusive)"
msgstr "”%s” inte en siffra mellan 0 och %u (inklusive)"
-#: ../clients/cli/settings.c:5403
+#: ../clients/cli/settings.c:5410
#, c-format
msgid ""
"Warning: changes will have no effect until '%s' includes 1 (enabled)\n"
@@ -6576,42 +6576,42 @@ msgstr ""
"(aktiverad)\n"
"\n"
-#: ../clients/cli/settings.c:5456
+#: ../clients/cli/settings.c:5463
#, c-format
msgid "bandwidth percentages must total 100%%"
msgstr "summan för bandbreddsprocenten måste vara 100%%"
-#: ../clients/cli/settings.c:5542 ../clients/cli/settings.c:5548
+#: ../clients/cli/settings.c:5549 ../clients/cli/settings.c:5555
msgid "SIM operator ID must be a 5 or 6 number MCCMNC code"
msgstr "SIM-operatörs-ID måste vara en 5- eller 6-siffrig MCCMNC-kod"
-#: ../clients/cli/settings.c:5591
+#: ../clients/cli/settings.c:5598
#, c-format
msgid "invalid option '%s', use '%s' or '%s'"
msgstr "ogiltig flagga ”%s”, använd ”%s” eller ”%s”"
-#: ../clients/cli/settings.c:7637
+#: ../clients/cli/settings.c:7644
msgid "don't know how to get the property value"
msgstr "vet inte hur egenskapsvärdet ska hämtas"
-#: ../clients/cli/settings.c:7690 ../clients/cli/settings.c:7730
+#: ../clients/cli/settings.c:7697 ../clients/cli/settings.c:7737
msgid "the property can't be changed"
msgstr "egenskapen kan inte ändras"
-#: ../clients/cli/settings.c:7814
+#: ../clients/cli/settings.c:7821
msgid "(not available)"
msgstr "(ej tillgänglig)"
-#: ../clients/cli/settings.c:7839
+#: ../clients/cli/settings.c:7846
msgid "[NM property description]"
msgstr "[NH egenskapsbeskrivning]"
-#: ../clients/cli/settings.c:7844
+#: ../clients/cli/settings.c:7851
msgid "[nmcli specific description]"
msgstr "[nmcli specifik beskrivning]"
#. ----------------------------------------------------------------------------
-#: ../clients/cli/settings.c:7893
+#: ../clients/cli/settings.c:7900
msgid "<hidden>"
msgstr "<dold>"
@@ -6630,49 +6630,59 @@ msgstr "Fel: Förväntade argumentet ”%s” men gavs ”%s”."
msgid "Error: Unexpected argument '%s'"
msgstr "Fel: Oväntat argument ”%s”"
+#: ../clients/cli/utils.c:202
+#, c-format
+msgid "Error converting IP4 address '0x%X' to text form"
+msgstr "Fel vid konvertering av IP4-adress ”0x%X” till textformat"
+
+#: ../clients/cli/utils.c:230
+#, c-format
+msgid "Error converting IP6 address '%s' to text form"
+msgstr "Fel vid konvertering av IP6-adress ”%s” till textformat"
+
#. Translators: the first %s is the partial value entered by
#. * the user, the second %s a list of compatible values.
#.
-#: ../clients/cli/utils.c:492 ../clients/cli/utils.c:523
+#: ../clients/cli/utils.c:546 ../clients/cli/utils.c:577
#, c-format
msgid "'%s' is ambiguous (%s)"
msgstr "”%s” är dubbeltydig (%s)"
-#: ../clients/cli/utils.c:502
+#: ../clients/cli/utils.c:556
#, c-format
msgid "'%s' is not valid; use [%s] or [%s]"
msgstr "”%s” är inte giltig; använd [%s] eller [%s]"
-#: ../clients/cli/utils.c:535
+#: ../clients/cli/utils.c:589
#, c-format
msgid "'%s' is not valid; use [%s], [%s] or [%s]"
msgstr "”%s” är inte giltig; använd [%s], [%s] eller [%s]"
-#: ../clients/cli/utils.c:634
+#: ../clients/cli/utils.c:688
#, c-format
msgid "'%s' is ambiguous (%s x %s)"
msgstr "”%s” är dubbeltydig (%s x %s)"
-#: ../clients/cli/utils.c:646
+#: ../clients/cli/utils.c:700
#, c-format
msgid "missing name, try one of [%s]"
msgstr "saknat namn, prova en av [%s]"
-#: ../clients/cli/utils.c:893
+#: ../clients/cli/utils.c:964
#, c-format
msgid "field '%s' has to be alone"
msgstr "fältet ”%s” måste vara ensamt"
-#: ../clients/cli/utils.c:896
+#: ../clients/cli/utils.c:967
#, c-format
msgid "invalid field '%s'; allowed fields: %s"
msgstr "ogiltigt fält ”%s”; tillåtna fält: %s"
-#: ../clients/cli/utils.c:953
+#: ../clients/cli/utils.c:1024
msgid "Option '--terse' requires specifying '--fields'"
msgstr "Flaggan ”--terse” kräver att ”--fields” anges"
-#: ../clients/cli/utils.c:957
+#: ../clients/cli/utils.c:1028
#, c-format
msgid "Option '--terse' requires specific '--fields' option values , not '%s'"
msgstr ""
@@ -6701,8 +6711,7 @@ msgstr "Användarnamn"
#: ../clients/common/nm-secret-agent-simple.c:525
#: ../clients/common/nm-vpn-helpers.c:101
#: ../clients/common/nm-vpn-helpers.c:102
-#: ../clients/common/nm-vpn-helpers.c:106
-#: ../clients/common/nm-vpn-helpers.c:109 ../clients/tui/nmt-page-dsl.c:75
+#: ../clients/common/nm-vpn-helpers.c:105 ../clients/tui/nmt-page-dsl.c:75
#: ../clients/tui/nmt-page-wifi.c:277 ../clients/tui/nmt-page-wifi.c:308
#: ../clients/tui/nmt-page-wifi.c:341
msgid "Password"
@@ -6786,28 +6795,20 @@ msgid "could not get VPN plugin info"
msgstr "kunde inte hämta VPN-insticksinfo"
#: ../clients/common/nm-vpn-helpers.c:103
-msgid "Certificate password"
-msgstr "Certifikatlösenord"
-
-#: ../clients/common/nm-vpn-helpers.c:104
-msgid "HTTP proxy password"
-msgstr "HTTP-proxylösenord"
-
-#: ../clients/common/nm-vpn-helpers.c:107
-#: ../clients/common/nm-vpn-helpers.c:110
+#: ../clients/common/nm-vpn-helpers.c:106
msgid "Group password"
msgstr "Grupplösenord"
-#: ../clients/common/nm-vpn-helpers.c:112 ../clients/tui/nmt-page-ip4.c:143
+#: ../clients/common/nm-vpn-helpers.c:108 ../clients/tui/nmt-page-ip4.c:143
#: ../clients/tui/nmt-page-ip6.c:143
msgid "Gateway"
msgstr "Gateway"
-#: ../clients/common/nm-vpn-helpers.c:113
+#: ../clients/common/nm-vpn-helpers.c:109
msgid "Cookie"
msgstr "Kaka"
-#: ../clients/common/nm-vpn-helpers.c:114
+#: ../clients/common/nm-vpn-helpers.c:110
msgid "Gateway certificate hash"
msgstr "Certifikathash för gateway"
@@ -6914,7 +6915,7 @@ msgstr "DSL-anslutning %d"
#: ../clients/tui/nm-editor-utils.c:190 ../libnm-core/nm-connection.c:1708
#: ../libnm-glib/nm-device.c:1863 ../libnm-util/nm-connection.c:1626
-#: ../libnm/nm-device.c:1814 ../src/settings/plugins/ifcfg-rh/reader.c:4182
+#: ../libnm/nm-device.c:1814 ../src/settings/plugins/ifcfg-rh/reader.c:4190
msgid "Bond"
msgstr "Kombinera"
@@ -6925,7 +6926,7 @@ msgstr "Kombinationsanslutning %d"
#: ../clients/tui/nm-editor-utils.c:199 ../libnm-core/nm-connection.c:1712
#: ../libnm-glib/nm-device.c:1867 ../libnm-util/nm-connection.c:1630
-#: ../libnm/nm-device.c:1818 ../src/settings/plugins/ifcfg-rh/reader.c:4479
+#: ../libnm/nm-device.c:1818 ../src/settings/plugins/ifcfg-rh/reader.c:4487
msgid "Bridge"
msgstr "Brygga"
@@ -6936,7 +6937,7 @@ msgstr "Brygganslutning %d"
#: ../clients/tui/nm-editor-utils.c:208 ../libnm-core/nm-connection.c:1710
#: ../libnm-glib/nm-device.c:1865 ../libnm-util/nm-connection.c:1628
-#: ../libnm/nm-device.c:1816 ../src/settings/plugins/ifcfg-rh/reader.c:4288
+#: ../libnm/nm-device.c:1816 ../src/settings/plugins/ifcfg-rh/reader.c:4296
msgid "Team"
msgstr "Grupp"
@@ -7978,7 +7979,7 @@ msgstr "Oväntat misslyckande med att normalisera anslutningen"
#: ../libnm-core/nm-setting-connection.c:837
#: ../libnm-core/nm-setting-connection.c:876
#: ../libnm-core/nm-setting-connection.c:989
-#: ../libnm-core/nm-setting-ip-config.c:2167
+#: ../libnm-core/nm-setting-ip-config.c:2162
#: ../libnm-core/nm-setting-olpc-mesh.c:120
#: ../libnm-core/nm-setting-pppoe.c:142 ../libnm-core/nm-setting-vpn.c:419
#: ../libnm-core/nm-setting-vxlan.c:360 ../libnm-core/nm-setting-wimax.c:126
@@ -8216,7 +8217,7 @@ msgstr "ogiltig privat nyckel för phase2"
#: ../libnm-core/nm-setting-connection.c:844
#: ../libnm-core/nm-setting-connection.c:887 ../libnm-core/nm-setting-gsm.c:281
#: ../libnm-core/nm-setting-gsm.c:338 ../libnm-core/nm-setting-gsm.c:375
-#: ../libnm-core/nm-setting-gsm.c:384 ../libnm-core/nm-setting-ip-config.c:2174
+#: ../libnm-core/nm-setting-gsm.c:384 ../libnm-core/nm-setting-ip-config.c:2169
#: ../libnm-core/nm-setting-ip4-config.c:198
#: ../libnm-core/nm-setting-ip4-config.c:205
#: ../libnm-core/nm-setting-pppoe.c:149 ../libnm-core/nm-setting-pppoe.c:158
@@ -8579,55 +8580,55 @@ msgstr "Ogiltig IPv4-adress ”%s”"
msgid "Invalid IPv6 address '%s'"
msgstr "Ogiltig IPv6-adress ”%s”"
-#: ../libnm-core/nm-setting-ip-config.c:153
+#: ../libnm-core/nm-setting-ip-config.c:152
#, c-format
msgid "Invalid IPv4 address prefix '%u'"
msgstr "Ogiltig IPv4-adressprefix ”%u”"
-#: ../libnm-core/nm-setting-ip-config.c:153
+#: ../libnm-core/nm-setting-ip-config.c:152
#, c-format
msgid "Invalid IPv6 address prefix '%u'"
msgstr "Ogiltigt IPv6-adressprefix ”%u”"
-#: ../libnm-core/nm-setting-ip-config.c:168
+#: ../libnm-core/nm-setting-ip-config.c:170
#, c-format
msgid "Invalid routing metric '%s'"
msgstr "Ogiltigt ruttmätvärde ”%s”"
-#: ../libnm-core/nm-setting-ip-config.c:2187
+#: ../libnm-core/nm-setting-ip-config.c:2182
#, c-format
msgid "%d. DNS server address is invalid"
msgstr "%d. DNS-serveradressen är ogiltig"
-#: ../libnm-core/nm-setting-ip-config.c:2203
+#: ../libnm-core/nm-setting-ip-config.c:2198
#, c-format
msgid "%d. IP address is invalid"
msgstr "%d. IP-adressen är ogiltig"
-#: ../libnm-core/nm-setting-ip-config.c:2215
+#: ../libnm-core/nm-setting-ip-config.c:2210
#, c-format
msgid "%d. IP address has 'label' property with invalid type"
msgstr "%d. IP-adressen har ”label”-egenskap med ogiltig typ"
-#: ../libnm-core/nm-setting-ip-config.c:2224
+#: ../libnm-core/nm-setting-ip-config.c:2219
#, c-format
msgid "%d. IP address has invalid label '%s'"
msgstr "%d. IP-adressen har ogiltig etikett ”%s”"
-#: ../libnm-core/nm-setting-ip-config.c:2238
+#: ../libnm-core/nm-setting-ip-config.c:2233
msgid "gateway cannot be set if there are no addresses configured"
msgstr "gateway kan inte bestämmas om det inte finns adresser konfigurerade"
-#: ../libnm-core/nm-setting-ip-config.c:2247
+#: ../libnm-core/nm-setting-ip-config.c:2242
msgid "gateway is invalid"
msgstr "ogiltig gateway"
-#: ../libnm-core/nm-setting-ip-config.c:2261
+#: ../libnm-core/nm-setting-ip-config.c:2256
#, c-format
msgid "%d. route is invalid"
msgstr "%d.-rutt ogiltig"
-#: ../libnm-core/nm-setting-ip-config.c:2270
+#: ../libnm-core/nm-setting-ip-config.c:2265
#, c-format
msgid "%d. route cannot be a default route"
msgstr "%d. rutt kan inte vara en standardrutt"
@@ -8962,39 +8963,39 @@ msgstr "libtool-arkiv stöds inte (%s)"
msgid "Could not find \"%s\" binary"
msgstr "Kunde inte hitta binären ”%s”"
-#: ../libnm-core/nm-vpn-editor-plugin.c:142
+#: ../libnm-core/nm-vpn-editor-plugin.c:132
#, c-format
-msgid "cannot load plugin \"%s\": %s"
-msgstr "kan inte läsa in insticksmodulen ”%s”: %s"
+msgid "cannot load plugin %s"
+msgstr "kan inte läsa in insticksmodulen %s"
-#: ../libnm-core/nm-vpn-editor-plugin.c:153
+#: ../libnm-core/nm-vpn-editor-plugin.c:160
#, c-format
-msgid "failed to load nm_vpn_editor_plugin_factory() from %s (%s)"
+msgid "cannot load VPN plugin in '%s': missing plugin name"
msgstr ""
-"misslyckades med att läsa in nm_vpn_editor_plugin_factory() från %s (%s)"
+"kan inte läsa in VPN-insticksmodul i ”%s”: saknar namn på insticksmodul"
-#: ../libnm-core/nm-vpn-editor-plugin.c:178
+#: ../libnm-core/nm-vpn-editor-plugin.c:167
+#, c-format
+msgid "cannot load VPN plugin in '%s': invalid service name"
+msgstr "kan inte läsa in VPN-insticksmodul i ”%s”: ogiltigt namn på tjänst"
+
+#: ../libnm-core/nm-vpn-editor-plugin.c:183
#, c-format
msgid "unknown error initializing plugin %s"
msgstr "okänt fel vid initiering av insticksmodulen %s"
#: ../libnm-core/nm-vpn-editor-plugin.c:195
#, c-format
-msgid "cannot load VPN plugin in '%s': missing plugin name"
+msgid "failed to load nm_vpn_editor_plugin_factory() from %s (%s)"
msgstr ""
-"kan inte läsa in VPN-insticksmodul i ”%s”: saknar namn på insticksmodul"
-
-#: ../libnm-core/nm-vpn-editor-plugin.c:204
-#, c-format
-msgid "cannot load VPN plugin in '%s': invalid service name"
-msgstr "kan inte läsa in VPN-insticksmodul i ”%s”: ogiltigt namn på tjänst"
+"misslyckades med att läsa in nm_vpn_editor_plugin_factory() från %s (%s)"
-#: ../libnm-core/nm-vpn-editor-plugin.c:310
+#: ../libnm-core/nm-vpn-editor-plugin.c:256
#, c-format
msgid "the plugin does not support import capability"
msgstr "insticksmodulen stöder inte importförmåga"
-#: ../libnm-core/nm-vpn-editor-plugin.c:330
+#: ../libnm-core/nm-vpn-editor-plugin.c:276
#, c-format
msgid "the plugin does not support export capability"
msgstr "insticksmodulen stöder inte exportförmåga"
@@ -9460,17 +9461,17 @@ msgid ""
msgstr ""
"Systemets policy förhindrar ändring av bestående global DNS-konfiguration"
-#: ../shared/nm-shared-utils.c:185
+#: ../shared/nm-shared-utils.c:174
#, c-format
msgid "object class '%s' has no property named '%s'"
msgstr "objektklassen ”%s” har ingen egenskap med namnet ”%s”"
-#: ../shared/nm-shared-utils.c:192
+#: ../shared/nm-shared-utils.c:181
#, c-format
msgid "property '%s' of object class '%s' is not writable"
msgstr "egenskapen ”%s” för objektklassen ”%s” är inte skrivbar"
-#: ../shared/nm-shared-utils.c:199
+#: ../shared/nm-shared-utils.c:188
#, c-format
msgid ""
"construct property \"%s\" for object '%s' can't be set after construction"
@@ -9478,19 +9479,19 @@ msgstr ""
"konstruktionsegenskap ”%s” för objektet ”%s” kan inte ställas in efter att "
"det skapats"
-#: ../shared/nm-shared-utils.c:207
+#: ../shared/nm-shared-utils.c:196
#, c-format
msgid "'%s::%s' is not a valid property name; '%s' is not a GObject subtype"
msgstr ""
"”%s::%s” är inte ett giltigt egenskapsnamn; ”%s” är inte en undertyp till "
"GObject"
-#: ../shared/nm-shared-utils.c:216
+#: ../shared/nm-shared-utils.c:205
#, c-format
msgid "unable to set property '%s' of type '%s' from value of type '%s'"
msgstr "kan inte sätta egenskapen ”%s” av typen ”%s” från värdet av typen ”%s”"
-#: ../shared/nm-shared-utils.c:227
+#: ../shared/nm-shared-utils.c:216
#, c-format
msgid ""
"value \"%s\" of type '%s' is invalid or out of range for property '%s' of "
@@ -9515,25 +9516,25 @@ msgid "Failed to read configuration: %s\n"
msgstr "Misslyckades med att läsa konfiguration: %s\n"
#. Logging/debugging
-#: ../src/main.c:234 ../src/nm-iface-helper.c:298
+#: ../src/main.c:234 ../src/nm-iface-helper.c:297
msgid "Print NetworkManager version and exit"
msgstr "Skriv ut version för Nätverkshanteraren och avsluta"
-#: ../src/main.c:235 ../src/nm-iface-helper.c:299
+#: ../src/main.c:235 ../src/nm-iface-helper.c:298
msgid "Don't become a daemon"
msgstr "Bli inte en demon"
-#: ../src/main.c:236 ../src/nm-iface-helper.c:301
+#: ../src/main.c:236 ../src/nm-iface-helper.c:300
#, c-format
msgid "Log level: one of [%s]"
msgstr "Loggnivå: en av [%s]"
-#: ../src/main.c:238 ../src/nm-iface-helper.c:303
+#: ../src/main.c:238 ../src/nm-iface-helper.c:302
#, c-format
msgid "Log domains separated by ',': any combination of [%s]"
msgstr "Logga domäner separerade med ”,”: vilken kombination som helst av [%s]"
-#: ../src/main.c:240 ../src/nm-iface-helper.c:305
+#: ../src/main.c:240 ../src/nm-iface-helper.c:304
msgid "Make all warnings fatal"
msgstr "Gör alla varningar till ödesdigra"
@@ -9561,12 +9562,12 @@ msgstr ""
"att användaren anger trådlösa accesspunkter som trådlösa nätverks-\n"
"kort i datorn ska associeras med."
-#: ../src/main.c:343 ../src/main-utils.c:269 ../src/nm-iface-helper.c:393
+#: ../src/main.c:343 ../src/main-utils.c:269 ../src/nm-iface-helper.c:392
#, c-format
msgid "%s. Please use --help to see a list of valid options.\n"
msgstr "%s. Använd --help för att se en lista över giltiga flaggor.\n"
-#: ../src/main.c:348 ../src/nm-iface-helper.c:398
+#: ../src/main.c:348 ../src/nm-iface-helper.c:397
#, c-format
msgid "Ignoring unrecognized log domain(s) '%s' passed on command line.\n"
msgstr "Ignorerar okända loggdomän(en|er) ”%s” given via kommandoraden.\n"
@@ -9581,7 +9582,7 @@ msgstr "Fel i konfigurationsfilen: %s.\n"
msgid "Ignoring unrecognized log domain(s) '%s' from config files.\n"
msgstr "Ignorerar okända loggdomän(en|er) ”%s” från konfigurationsfiler.\n"
-#: ../src/main.c:389 ../src/nm-iface-helper.c:408
+#: ../src/main.c:389 ../src/nm-iface-helper.c:407
#, c-format
msgid "Could not daemonize: %s [error %u]\n"
msgstr "Kunde inte bli demon: %s [fel %u]\n"
@@ -9674,8 +9675,8 @@ msgid "Unknown/unhandled Bluetooth connection type"
msgstr "Okänd/ohanterad Bluetooth-anslutningstyp"
#: ../src/devices/bluetooth/nm-device-bt.c:336
-#: ../src/devices/nm-device-ethernet.c:1420
-#: ../src/devices/nm-device-infiniband.c:193
+#: ../src/devices/nm-device-ethernet.c:1415
+#: ../src/devices/nm-device-infiniband.c:192
#: ../src/devices/wifi/nm-device-wifi.c:872
msgid "connection does not match device"
msgstr "anslutning matchar inte enhet"
@@ -9688,11 +9689,11 @@ msgstr "Kombinationsanslutning"
msgid "Bridge connection"
msgstr "Brygganslutning"
-#: ../src/devices/nm-device-ethernet.c:1401
+#: ../src/devices/nm-device-ethernet.c:1396
msgid "PPPoE connection"
msgstr "PPPoE-anslutning"
-#: ../src/devices/nm-device-ethernet.c:1401
+#: ../src/devices/nm-device-ethernet.c:1396
msgid "Wired connection"
msgstr "Trådbunden anslutning"
@@ -9701,7 +9702,7 @@ msgstr "Trådbunden anslutning"
msgid "Wired connection %d"
msgstr "Trådbunden anslutning %d"
-#: ../src/devices/nm-device-infiniband.c:175
+#: ../src/devices/nm-device-infiniband.c:174
msgid "InfiniBand connection"
msgstr "InfiniBand-anslutning"
@@ -9709,7 +9710,7 @@ msgstr "InfiniBand-anslutning"
msgid "IP tunnel connection"
msgstr "IP-tunnelanslutning"
-#: ../src/devices/nm-device-macvlan.c:435
+#: ../src/devices/nm-device-macvlan.c:428
msgid "MACVLAN connection"
msgstr "MACVLAN-anslutning"
@@ -9717,7 +9718,7 @@ msgstr "MACVLAN-anslutning"
msgid "TUN connection"
msgstr "TUN-anslutning"
-#: ../src/devices/nm-device-vlan.c:457
+#: ../src/devices/nm-device-vlan.c:447
msgid "VLAN connection"
msgstr "VLAN-anslutning"
@@ -9930,7 +9931,7 @@ msgstr "Lista över insticksmoduler separerade med ”,”"
msgid "Quit after initial configuration"
msgstr "Avsluta efter initial konfiguration"
-#: ../src/nm-config.c:472 ../src/nm-iface-helper.c:300
+#: ../src/nm-config.c:472 ../src/nm-iface-helper.c:299
msgid "Don't become a daemon, and log to stderr"
msgstr "Bli inte en demon, och logga till stderr"
@@ -9948,94 +9949,94 @@ msgid "The expected start of the response"
msgstr "Den förväntade starten på svaret"
#. Interface/IP config
-#: ../src/nm-iface-helper.c:281
+#: ../src/nm-iface-helper.c:280
msgid "The interface to manage"
msgstr "Gränssnittet att hantera"
-#: ../src/nm-iface-helper.c:281
+#: ../src/nm-iface-helper.c:280
msgid "eth0"
msgstr "eth0"
-#: ../src/nm-iface-helper.c:282
+#: ../src/nm-iface-helper.c:281
msgid "Connection UUID"
msgstr "UUID för anslutning"
-#: ../src/nm-iface-helper.c:282
+#: ../src/nm-iface-helper.c:281
msgid "661e8cd0-b618-46b8-9dc9-31a52baaa16b"
msgstr "661e8cd0-b618-46b8-9dc9-31a52baaa16b"
-#: ../src/nm-iface-helper.c:283
+#: ../src/nm-iface-helper.c:282
msgid "Whether to manage IPv6 SLAAC"
msgstr "Huruvida IPv6 SLAAC ska hanteras"
-#: ../src/nm-iface-helper.c:284
+#: ../src/nm-iface-helper.c:283
msgid "Whether SLAAC must be successful"
msgstr "Huruvida SLAAC måste lyckas"
-#: ../src/nm-iface-helper.c:285
+#: ../src/nm-iface-helper.c:284
msgid "Use an IPv6 temporary privacy address"
msgstr "Använd en temporär IPv6-adress för sekretess"
-#: ../src/nm-iface-helper.c:286
+#: ../src/nm-iface-helper.c:285
msgid "Current DHCPv4 address"
msgstr "Aktuell DCHPv4-adress"
-#: ../src/nm-iface-helper.c:287
+#: ../src/nm-iface-helper.c:286
msgid "Whether DHCPv4 must be successful"
msgstr "Huruvida DHCPv4 måste lyckas"
-#: ../src/nm-iface-helper.c:288
+#: ../src/nm-iface-helper.c:287
msgid "Hex-encoded DHCPv4 client ID"
msgstr "Hexkodat DHCPv4 klient-ID"
-#: ../src/nm-iface-helper.c:289
+#: ../src/nm-iface-helper.c:288
msgid "Hostname to send to DHCP server"
msgstr "Värdnamn att skicka till DHCP-server"
-#: ../src/nm-iface-helper.c:289
+#: ../src/nm-iface-helper.c:288
msgid "barbar"
msgstr "barbar"
-#: ../src/nm-iface-helper.c:290
+#: ../src/nm-iface-helper.c:289
msgid "FQDN to send to DHCP server"
msgstr "FQDN att skicka till DHCP-server"
-#: ../src/nm-iface-helper.c:290
+#: ../src/nm-iface-helper.c:289
msgid "host.domain.org"
msgstr "host.domain.org"
-#: ../src/nm-iface-helper.c:291
+#: ../src/nm-iface-helper.c:290
msgid "Route priority for IPv4"
msgstr "Ruttprioritet för IPv4"
-#: ../src/nm-iface-helper.c:291
+#: ../src/nm-iface-helper.c:290
msgid "0"
msgstr "0"
-#: ../src/nm-iface-helper.c:292
+#: ../src/nm-iface-helper.c:291
msgid "Route priority for IPv6"
msgstr "Ruttprioritet för IPv6"
-#: ../src/nm-iface-helper.c:292
+#: ../src/nm-iface-helper.c:291
msgid "1024"
msgstr "1024"
-#: ../src/nm-iface-helper.c:293
+#: ../src/nm-iface-helper.c:292
msgid "Hex-encoded Interface Identifier"
msgstr "Hexkodad gränssnittsidentifierare"
-#: ../src/nm-iface-helper.c:294
+#: ../src/nm-iface-helper.c:293
msgid "IPv6 SLAAC address generation mode"
msgstr "SLAAC-adressgenereringsläge för IPv6"
-#: ../src/nm-iface-helper.c:295
+#: ../src/nm-iface-helper.c:294
msgid ""
"The logging backend configuration value. See logging.backend in "
"NetworkManager.conf"
msgstr ""
"Loggbakändens konfigurationsvärde. Se logging.backend i NetworkManager.conf"
-#: ../src/nm-iface-helper.c:315
+#: ../src/nm-iface-helper.c:314
msgid ""
"nm-iface-helper is a small, standalone process that manages a single network "
"interface."
@@ -10043,17 +10044,17 @@ msgstr ""
"nm-iface-helper är en liten fristående process som hanterar ett enstaka "
"nätverksgränssnitt."
-#: ../src/nm-iface-helper.c:374
+#: ../src/nm-iface-helper.c:373
#, c-format
msgid "An interface name and UUID are required\n"
msgstr "Kräver ett gränssnittsnamn och UUID\n"
-#: ../src/nm-iface-helper.c:380
+#: ../src/nm-iface-helper.c:379
#, c-format
msgid "Failed to find interface index for %s (%s)\n"
msgstr "Misslyckades med att hitta gränssnittsindex för %s (%s)\n"
-#: ../src/nm-iface-helper.c:442
+#: ../src/nm-iface-helper.c:441
#, c-format
msgid "(%s): Invalid IID %s\n"
msgstr "(%s): Ogiltig IID %s\n"
@@ -10068,7 +10069,7 @@ msgstr "Okänd loggnivå ”%s”"
msgid "Unknown log domain '%s'"
msgstr "Okänd loggdomän ”%s”"
-#: ../src/nm-manager.c:3635
+#: ../src/nm-manager.c:3625
msgid "VPN connection"
msgstr "VPN-anslutning"
@@ -10080,18 +10081,6 @@ msgstr "Nätverkshanteraren behöver stänga av nätverk"
msgid "System"
msgstr "System"
-#~ msgid "Error: not all connections reapplied."
-#~ msgstr "Fel: alla anslutningar har inte uppdaterats."
-
-#~ msgid "Error: no valid device provided."
-#~ msgstr "Fel: ingen giltig enhet tillhandahållen."
-
-#~ msgid "Error converting IP4 address '0x%X' to text form"
-#~ msgstr "Fel vid konvertering av IP4-adress ”0x%X” till textformat"
-
-#~ msgid "Error converting IP6 address '%s' to text form"
-#~ msgstr "Fel vid konvertering av IP6-adress ”%s” till textformat"
-
#~ msgid "Error: unknown parameter: %s"
#~ msgstr "Fel: okänd parameter: %s"
diff --git a/shared/nm-macros-internal.h b/shared/nm-macros-internal.h
index e584b9d031..7a5c90fc53 100644
--- a/shared/nm-macros-internal.h
+++ b/shared/nm-macros-internal.h
@@ -27,6 +27,9 @@
/********************************************************/
#define _nm_packed __attribute__ ((packed))
+#define _nm_unused __attribute__ ((unused))
+#define _nm_pure __attribute__ ((pure))
+#define _nm_const __attribute__ ((const))
#define nm_auto(fcn) __attribute__ ((cleanup(fcn)))
@@ -296,6 +299,22 @@ _NM_IN_STRSET_streq (const char *x, const char *s)
/*****************************************************************************/
+/* glib/C provides the following kind of assertions:
+ * - assert() -- disable with NDEBUG
+ * - g_return_if_fail() -- disable with G_DISABLE_CHECKS
+ * - g_assert() -- disable with G_DISABLE_ASSERT
+ * but they are all enabled by default and usually even production builds have
+ * these kind of assertions enabled. It also means, that disabling assertions
+ * is an untested configuration, and might have bugs.
+ *
+ * Add our own assertion macro nm_assert(), which is disabled by default and must
+ * be explicitly enabled. They are useful for more expensive checks or checks that
+ * depend less on runtime conditions (that is, are generally expected to be true). */
+
+#ifndef NM_MORE_ASSERTS
+#define NM_MORE_ASSERTS 0
+#endif
+
#if NM_MORE_ASSERTS
#define nm_assert(cond) G_STMT_START { g_assert (cond); } G_STMT_END
#define nm_assert_not_reached() G_STMT_START { g_assert_not_reached (); } G_STMT_END
diff --git a/shared/nm-test-utils.h b/shared/nm-test-utils.h
index b792a69c85..ad3cad650f 100644
--- a/shared/nm-test-utils.h
+++ b/shared/nm-test-utils.h
@@ -101,13 +101,6 @@
#include "nm-utils.h"
-#ifdef __NETWORKMANAGER_LOGGING_H__
-/* We are running tests under src/. Let's include some files by default.
- * They are useful, and affect how nm-test-utils.h itself behaves. */
-#include "NetworkManagerUtils.h"
-#include "nm-keyfile-internal.h"
-#endif
-
/*******************************************************************************/
/* general purpose functions that have no dependency on other nmtst functions */
@@ -153,13 +146,11 @@
g_assert_not_reached (); \
} G_STMT_END
-inline static void
-_nmtst_assert_success (gboolean success, GError *error, const char *file, int line)
-{
- if (!success || error)
- g_error ("(%s:%d) FAILURE success=%d, error=%s", file, line, success, error ? error->message : "(no error)");
-}
-#define nmtst_assert_success(success, error) _nmtst_assert_success ((success), (error), __FILE__, __LINE__)
+#define nmtst_assert_success(success, error) \
+ G_STMT_START { \
+ g_assert_no_error (error); \
+ g_assert ((success)); \
+ } G_STMT_END
#define nmtst_assert_no_success(success, error) \
G_STMT_START { \
@@ -512,7 +503,7 @@ __nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_
if (!__nmtst_internal.assert_logging) {
gboolean success = TRUE;
-#ifdef __NETWORKMANAGER_LOGGING_H__
+#ifdef _NMTST_INSIDE_CORE
success = nm_logging_setup (log_level, log_domains, NULL, NULL);
*out_set_logging = TRUE;
#endif
@@ -529,7 +520,7 @@ __nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_
* This transforms g_test_expect_message() into a NOP, but we also have to relax
* g_log_set_always_fatal(), which was set by g_test_init(). */
g_log_set_always_fatal (G_LOG_FATAL_MASK);
-#ifdef __NETWORKMANAGER_LOGGING_H__
+#ifdef _NMTST_INSIDE_CORE
if (c_log_domains || c_log_level) {
/* Normally, tests with assert_logging do not overwrite the logging level/domains because
* the logging statements are part of the assertions. But if the test is run with
@@ -590,27 +581,7 @@ __nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_
#endif
}
-#ifdef __NETWORKMANAGER_LOGGING_H__
-inline static void
-nmtst_init_with_logging (int *argc, char ***argv, const char *log_level, const char *log_domains)
-{
- __nmtst_init (argc, argv, FALSE, log_level, log_domains, NULL);
-}
-inline static void
-nmtst_init_assert_logging (int *argc, char ***argv, const char *log_level, const char *log_domains)
-{
- gboolean set_logging;
-
- __nmtst_init (argc, argv, TRUE, NULL, NULL, &set_logging);
-
- if (!set_logging) {
- gboolean success;
-
- success = nm_logging_setup (log_level, log_domains, NULL, NULL);
- g_assert (success);
- }
-}
-#else
+#ifndef _NMTST_INSIDE_CORE
inline static void
nmtst_init (int *argc, char ***argv, gboolean assert_logging)
{
@@ -1177,247 +1148,6 @@ _nmtst_assert_resolve_relative_path_equals (const char *f1, const char *f2, cons
/*******************************************************************************/
-#ifdef __NETWORKMANAGER_PLATFORM_H__
-
-inline static NMPlatformIP4Address *
-nmtst_platform_ip4_address (const char *address, const char *peer_address, guint plen)
-{
- static NMPlatformIP4Address addr;
-
- g_assert (plen <= 32);
-
- memset (&addr, 0, sizeof (addr));
- addr.address = nmtst_inet4_from_string (address);
- if (peer_address)
- addr.peer_address = nmtst_inet4_from_string (peer_address);
- else
- addr.peer_address = addr.address;
- addr.plen = plen;
-
- return &addr;
-}
-
-inline static NMPlatformIP4Address *
-nmtst_platform_ip4_address_full (const char *address, const char *peer_address, guint plen,
- int ifindex, NMIPConfigSource source, guint32 timestamp,
- guint32 lifetime, guint32 preferred, guint32 flags,
- const char *label)
-{
- NMPlatformIP4Address *addr = nmtst_platform_ip4_address (address, peer_address, plen);
-
- G_STATIC_ASSERT (IFNAMSIZ == sizeof (addr->label));
- g_assert (!label || strlen (label) < IFNAMSIZ);
-
- addr->ifindex = ifindex;
- addr->source = source;
- addr->timestamp = timestamp;
- addr->lifetime = lifetime;
- addr->preferred = preferred;
- addr->n_ifa_flags = flags;
- if (label)
- g_strlcpy (addr->label, label, sizeof (addr->label));
-
- return addr;
-}
-
-inline static NMPlatformIP6Address *
-nmtst_platform_ip6_address (const char *address, const char *peer_address, guint plen)
-{
- static NMPlatformIP6Address addr;
-
- g_assert (plen <= 128);
-
- memset (&addr, 0, sizeof (addr));
- addr.address = *nmtst_inet6_from_string (address);
- addr.peer_address = *nmtst_inet6_from_string (peer_address);
- addr.plen = plen;
-
- return &addr;
-}
-
-inline static NMPlatformIP6Address *
-nmtst_platform_ip6_address_full (const char *address, const char *peer_address, guint plen,
- int ifindex, NMIPConfigSource source, guint32 timestamp,
- guint32 lifetime, guint32 preferred, guint32 flags)
-{
- NMPlatformIP6Address *addr = nmtst_platform_ip6_address (address, peer_address, plen);
-
- addr->ifindex = ifindex;
- addr->source = source;
- addr->timestamp = timestamp;
- addr->lifetime = lifetime;
- addr->preferred = preferred;
- addr->n_ifa_flags = flags;
-
- return addr;
-}
-
-inline static NMPlatformIP4Route *
-nmtst_platform_ip4_route (const char *network, guint plen, const char *gateway)
-{
- static NMPlatformIP4Route route;
-
- g_assert (plen <= 32);
-
- memset (&route, 0, sizeof (route));
- route.network = nmtst_inet4_from_string (network);
- route.plen = plen;
- route.gateway = nmtst_inet4_from_string (gateway);
-
- return &route;
-}
-
-inline static NMPlatformIP4Route *
-nmtst_platform_ip4_route_full (const char *network, guint plen, const char *gateway,
- int ifindex, NMIPConfigSource source,
- guint metric, guint mss,
- guint8 scope,
- const char *pref_src)
-{
- NMPlatformIP4Route *route = nmtst_platform_ip4_route (network, plen, gateway);
-
- route->ifindex = ifindex;
- route->source = source;
- route->metric = metric;
- route->mss = mss;
- route->scope_inv = nm_platform_route_scope_inv (scope);
- route->pref_src = nmtst_inet4_from_string (pref_src);
-
- return route;
-}
-
-inline static NMPlatformIP6Route *
-nmtst_platform_ip6_route (const char *network, guint plen, const char *gateway)
-{
- static NMPlatformIP6Route route;
-
- nm_assert (plen <= 128);
-
- memset (&route, 0, sizeof (route));
- route.network = *nmtst_inet6_from_string (network);
- route.plen = plen;
- route.gateway = *nmtst_inet6_from_string (gateway);
-
- return &route;
-}
-
-inline static NMPlatformIP6Route *
-nmtst_platform_ip6_route_full (const char *network, guint plen, const char *gateway,
- int ifindex, NMIPConfigSource source,
- guint metric, guint mss)
-{
- NMPlatformIP6Route *route = nmtst_platform_ip6_route (network, plen, gateway);
-
- route->ifindex = ifindex;
- route->source = source;
- route->metric = metric;
- route->mss = mss;
-
- return route;
-}
-
-inline static int
-_nmtst_platform_ip4_routes_equal_sort (gconstpointer a, gconstpointer b, gpointer user_data)
-{
- return nm_platform_ip4_route_cmp ((const NMPlatformIP4Route *) a, (const NMPlatformIP4Route *) b);
-}
-
-inline static void
-nmtst_platform_ip4_routes_equal (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b, gsize len, gboolean ignore_order)
-{
- gsize i;
- gs_free const NMPlatformIP4Route *c_a = NULL, *c_b = NULL;
-
- g_assert (a);
- g_assert (b);
-
- if (ignore_order) {
- a = c_a = g_memdup (a, sizeof (NMPlatformIP4Route) * len);
- b = c_b = g_memdup (b, sizeof (NMPlatformIP4Route) * len);
- g_qsort_with_data (c_a, len, sizeof (NMPlatformIP4Route), _nmtst_platform_ip4_routes_equal_sort, NULL);
- g_qsort_with_data (c_b, len, sizeof (NMPlatformIP4Route), _nmtst_platform_ip4_routes_equal_sort, NULL);
- }
-
- for (i = 0; i < len; i++) {
- if (nm_platform_ip4_route_cmp (&a[i], &b[i]) != 0) {
- char buf[sizeof (_nm_utils_to_string_buffer)];
-
- g_error ("Error comparing IPv4 route[%lu]: %s vs %s", (long unsigned) i,
- nm_platform_ip4_route_to_string (&a[i], NULL, 0),
- nm_platform_ip4_route_to_string (&b[i], buf, sizeof (buf)));
- g_assert_not_reached ();
- }
- }
-}
-
-inline static int
-_nmtst_platform_ip6_routes_equal_sort (gconstpointer a, gconstpointer b, gpointer user_data)
-{
- return nm_platform_ip6_route_cmp ((const NMPlatformIP6Route *) a, (const NMPlatformIP6Route *) b);
-}
-
-inline static void
-nmtst_platform_ip6_routes_equal (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b, gsize len, gboolean ignore_order)
-{
- gsize i;
- gs_free const NMPlatformIP6Route *c_a = NULL, *c_b = NULL;
-
- g_assert (a);
- g_assert (b);
-
- if (ignore_order) {
- a = c_a = g_memdup (a, sizeof (NMPlatformIP6Route) * len);
- b = c_b = g_memdup (b, sizeof (NMPlatformIP6Route) * len);
- g_qsort_with_data (c_a, len, sizeof (NMPlatformIP6Route), _nmtst_platform_ip6_routes_equal_sort, NULL);
- g_qsort_with_data (c_b, len, sizeof (NMPlatformIP6Route), _nmtst_platform_ip6_routes_equal_sort, NULL);
- }
-
- for (i = 0; i < len; i++) {
- if (nm_platform_ip6_route_cmp (&a[i], &b[i]) != 0) {
- char buf[sizeof (_nm_utils_to_string_buffer)];
-
- g_error ("Error comparing IPv6 route[%lu]: %s vs %s", (long unsigned) i,
- nm_platform_ip6_route_to_string (&a[i], NULL, 0),
- nm_platform_ip6_route_to_string (&b[i], buf, sizeof (buf)));
- g_assert_not_reached ();
- }
- }
-}
-
-#endif
-
-
-#ifdef __NETWORKMANAGER_IP4_CONFIG_H__
-
-inline static NMIP4Config *
-nmtst_ip4_config_clone (NMIP4Config *config)
-{
- NMIP4Config *copy = nm_ip4_config_new (-1);
-
- g_assert (copy);
- g_assert (config);
- nm_ip4_config_replace (copy, config, NULL);
- return copy;
-}
-
-#endif
-
-
-#ifdef __NETWORKMANAGER_IP6_CONFIG_H__
-
-inline static NMIP6Config *
-nmtst_ip6_config_clone (NMIP6Config *config)
-{
- NMIP6Config *copy = nm_ip6_config_new (-1);
-
- g_assert (copy);
- g_assert (config);
- nm_ip6_config_replace (copy, config, NULL);
- return copy;
-}
-
-#endif
-
#ifdef NM_SETTING_IP_CONFIG_H
inline static void
nmtst_setting_ip_config_add_address (NMSettingIPConfig *s_ip,
diff --git a/shared/nm-version-macros.h.in b/shared/nm-version-macros.h.in
index 3e0ef361c0..3df95ffe51 100644
--- a/shared/nm-version-macros.h.in
+++ b/shared/nm-version-macros.h.in
@@ -70,7 +70,6 @@
#define NM_VERSION_1_2 (NM_ENCODE_VERSION (1, 2, 0))
#define NM_VERSION_1_2_2 (NM_ENCODE_VERSION (1, 2, 2))
#define NM_VERSION_1_2_4 (NM_ENCODE_VERSION (1, 2, 4))
-#define NM_VERSION_1_4 (NM_ENCODE_VERSION (1, 4, 0))
#define NM_VERSION_CUR_STABLE NM_VERSION_1_2_2
#define NM_VERSION_NEXT_STABLE NM_VERSION_1_2_4
diff --git a/src/Makefile.am b/src/Makefile.am
index 652aae6f9b..e61e5aa9dd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -74,6 +74,8 @@ libsystemd_nm_la_SOURCES = \
systemd/src/basic/escape.h \
systemd/src/basic/ether-addr-util.c \
systemd/src/basic/ether-addr-util.h \
+ systemd/src/basic/extract-word.c \
+ systemd/src/basic/extract-word.h \
systemd/src/basic/fd-util.c \
systemd/src/basic/fd-util.h \
systemd/src/basic/fileio.c \
@@ -107,6 +109,7 @@ libsystemd_nm_la_SOURCES = \
systemd/src/basic/random-util.h \
systemd/src/basic/refcnt.h \
systemd/src/basic/set.h \
+ systemd/src/basic/signal-util.h \
systemd/src/basic/siphash24.c \
systemd/src/basic/siphash24.h \
systemd/src/basic/socket-util.c \
@@ -394,8 +397,6 @@ libNetworkManager_la_SOURCES = \
nm-config.h \
nm-config-data.c \
nm-config-data.h \
- nm-connection-provider.c \
- nm-connection-provider.h \
nm-connectivity.c \
nm-connectivity.h \
nm-dcb.c \
@@ -478,6 +479,7 @@ AM_CPPFLAGS += \
$(SYSTEMD_LOGIN_CFLAGS) \
$(SYSTEMD_JOURNAL_CFLAGS) \
$(SYSTEMD_NM_CFLAGS_PATHS) \
+ $(CODE_COVERAGE_CFLAGS) \
\
-DBINDIR=\"$(bindir)\" \
-DDATADIR=\"$(datadir)\" \
@@ -501,6 +503,8 @@ AM_CPPFLAGS += \
\
$(NULL)
+AM_LDFLAGS = $(CODE_COVERAGE_LDFLAGS)
+
libNetworkManager_la_LIBADD = \
$(top_builddir)/libnm-core/libnm-core.la \
$(top_builddir)/introspection/libnmdbus.la \
@@ -626,6 +630,7 @@ dbusservice_DATA = org.freedesktop.NetworkManager.conf
EXTRA_DIST = \
$(dbusservice_DATA) \
$(NetworkManager_DATA) \
+ nm-test-utils-core.h \
NetworkManager.ver
rundir=$(runstatedir)/NetworkManager
diff --git a/src/NetworkManager.ver b/src/NetworkManager.ver
index b4397b9c20..c91affcb5f 100644
--- a/src/NetworkManager.ver
+++ b/src/NetworkManager.ver
@@ -1,6 +1,7 @@
{
global:
- nm*;
+ nm_*;
+ nmp_*;
_nm*;
NM*;
_NM*;
diff --git a/src/devices/bluetooth/nm-bluez-device.c b/src/devices/bluetooth/nm-bluez-device.c
index dcfa5eec24..3463da6be8 100644
--- a/src/devices/bluetooth/nm-bluez-device.c
+++ b/src/devices/bluetooth/nm-bluez-device.c
@@ -28,6 +28,7 @@
#include "nm-bt-error.h"
#include "nm-bluez-common.h"
#include "nm-bluez-device.h"
+#include "nm-settings.h"
#include "nm-settings-connection.h"
#include "NetworkManagerUtils.h"
@@ -67,7 +68,7 @@ typedef struct {
NMBluez5DunContext *b5_dun_context;
#endif
- NMConnectionProvider *provider;
+ NMSettings *settings;
GSList *connections;
NMConnection *pan_connection;
@@ -96,7 +97,7 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
-static void cp_connection_added (NMConnectionProvider *provider,
+static void cp_connection_added (NMSettings *settings,
NMConnection *connection, NMBluezDevice *self);
static gboolean connection_compatible (NMBluezDevice *self, NMConnection *connection);
@@ -233,9 +234,9 @@ pan_connection_check_create (NMBluezDevice *self)
/* Adding a new connection raises a signal which eventually calls check_emit_usable (again)
* which then already finds the suitable connection in priv->connections. This is confusing,
* so block the signal. check_emit_usable will succeed after this function call returns. */
- g_signal_handlers_block_by_func (priv->provider, cp_connection_added, self);
- added = nm_connection_provider_add_connection (priv->provider, connection, FALSE, &error);
- g_signal_handlers_unblock_by_func (priv->provider, cp_connection_added, self);
+ g_signal_handlers_block_by_func (priv->settings, cp_connection_added, self);
+ added = NM_CONNECTION (nm_settings_add_connection (priv->settings, connection, FALSE, &error));
+ g_signal_handlers_unblock_by_func (priv->settings, cp_connection_added, self);
if (added) {
g_assert (!g_slist_find (priv->connections, added));
@@ -367,7 +368,7 @@ _internal_track_connection (NMBluezDevice *self, NMConnection *connection, gbool
}
static void
-cp_connection_added (NMConnectionProvider *provider,
+cp_connection_added (NMSettings *settings,
NMConnection *connection,
NMBluezDevice *self)
{
@@ -378,7 +379,7 @@ cp_connection_added (NMConnectionProvider *provider,
}
static void
-cp_connection_removed (NMConnectionProvider *provider,
+cp_connection_removed (NMSettings *settings,
NMConnection *connection,
NMBluezDevice *self)
{
@@ -387,8 +388,9 @@ cp_connection_removed (NMConnectionProvider *provider,
}
static void
-cp_connection_updated (NMConnectionProvider *provider,
+cp_connection_updated (NMSettings *settings,
NMConnection *connection,
+ gboolean by_user,
NMBluezDevice *self)
{
if (_internal_track_connection (self, connection,
@@ -400,12 +402,13 @@ static void
load_connections (NMBluezDevice *self)
{
NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
- const GSList *connections, *iter;
+ NMSettingsConnection *const*connections;
+ guint i;
gboolean changed = FALSE;
- connections = nm_connection_provider_get_connections (priv->provider);
- for (iter = connections; iter; iter = g_slist_next (iter)) {
- NMConnection *connection = iter->data;
+ connections = nm_settings_get_connections (priv->settings, NULL);
+ for (i = 0; connections[i]; i++) {
+ NMConnection *connection = (NMConnection *) connections[i];
if (connection_compatible (self, connection))
changed |= _internal_track_connection (self, connection, TRUE);
@@ -1029,7 +1032,7 @@ on_bus_acquired (GObject *object, GAsyncResult *res, NMBluezDevice *self)
NMBluezDevice *
nm_bluez_device_new (const char *path,
const char *adapter_address,
- NMConnectionProvider *provider,
+ NMSettings *settings,
int bluez_version)
{
NMBluezDevice *self;
@@ -1037,7 +1040,7 @@ nm_bluez_device_new (const char *path,
const char *interface_name = NULL;
g_return_val_if_fail (path != NULL, NULL);
- g_return_val_if_fail (NM_IS_CONNECTION_PROVIDER (provider), NULL);
+ g_return_val_if_fail (NM_IS_SETTINGS (settings), NULL);
g_return_val_if_fail (bluez_version == 4 || bluez_version == 5, NULL);
self = (NMBluezDevice *) g_object_new (NM_TYPE_BLUEZ_DEVICE,
@@ -1051,14 +1054,14 @@ nm_bluez_device_new (const char *path,
priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
priv->bluez_version = bluez_version;
- priv->provider = g_object_ref (provider);
+ priv->settings = g_object_ref (settings);
g_return_val_if_fail (bluez_version == 5 || (bluez_version == 4 && adapter_address), NULL);
if (adapter_address)
set_adapter_address (self, adapter_address);
- g_signal_connect (priv->provider, NM_CP_SIGNAL_CONNECTION_ADDED, G_CALLBACK (cp_connection_added), self);
- g_signal_connect (priv->provider, NM_CP_SIGNAL_CONNECTION_REMOVED, G_CALLBACK (cp_connection_removed), self);
- g_signal_connect (priv->provider, NM_CP_SIGNAL_CONNECTION_UPDATED, G_CALLBACK (cp_connection_updated), self);
+ g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, G_CALLBACK (cp_connection_added), self);
+ g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, G_CALLBACK (cp_connection_removed), self);
+ g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, G_CALLBACK (cp_connection_updated), self);
g_bus_get (G_BUS_TYPE_SYSTEM,
NULL,
@@ -1116,10 +1119,10 @@ dispose (GObject *object)
}
#endif
- if (priv->provider) {
- g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_added, self);
- g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_removed, self);
- g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_updated, self);
+ if (priv->settings) {
+ g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_added, self);
+ g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_removed, self);
+ g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_updated, self);
}
g_slist_free_full (priv->connections, g_object_unref);
@@ -1137,7 +1140,7 @@ dispose (GObject *object)
g_object_unref (to_delete);
}
- g_clear_object (&priv->provider);
+ g_clear_object (&priv->settings);
}
static void
diff --git a/src/devices/bluetooth/nm-bluez-device.h b/src/devices/bluetooth/nm-bluez-device.h
index c956054074..66a349e0db 100644
--- a/src/devices/bluetooth/nm-bluez-device.h
+++ b/src/devices/bluetooth/nm-bluez-device.h
@@ -22,7 +22,6 @@
#define __NETWORKMANAGER_BLUEZ_DEVICE_H__
#include "nm-connection.h"
-#include "nm-connection-provider.h"
#define NM_TYPE_BLUEZ_DEVICE (nm_bluez_device_get_type ())
#define NM_BLUEZ_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BLUEZ_DEVICE, NMBluezDevice))
@@ -59,7 +58,7 @@ GType nm_bluez_device_get_type (void);
NMBluezDevice *nm_bluez_device_new (const char *path,
const char *adapter_address,
- NMConnectionProvider *provider,
+ NMSettings *settings,
int bluez_version);
const char *nm_bluez_device_get_path (NMBluezDevice *self);
diff --git a/src/devices/bluetooth/nm-bluez-manager.c b/src/devices/bluetooth/nm-bluez-manager.c
index 766ecc0abc..0d2e302cfc 100644
--- a/src/devices/bluetooth/nm-bluez-manager.c
+++ b/src/devices/bluetooth/nm-bluez-manager.c
@@ -20,19 +20,20 @@
#include "nm-default.h"
+#include "nm-bluez-manager.h"
+
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <gmodule.h>
-#include "nm-bluez-manager.h"
#include "nm-device-factory.h"
#include "nm-setting-bluetooth.h"
+#include "nm-settings.h"
#include "nm-bluez4-manager.h"
#include "nm-bluez5-manager.h"
#include "nm-bluez-device.h"
#include "nm-bluez-common.h"
-#include "nm-connection-provider.h"
#include "nm-device-bt.h"
#include "nm-core-internal.h"
#include "nm-platform.h"
@@ -51,7 +52,7 @@
typedef struct {
int bluez_version;
- NMConnectionProvider *provider;
+ NMSettings *settings;
NMBluez4Manager *manager4;
NMBluez5Manager *manager5;
@@ -190,7 +191,7 @@ setup_bluez4 (NMBluezManager *self)
g_return_if_fail (!priv->manager4 && !priv->manager5 && !priv->bluez_version);
setup_version_number (self, 4);
- priv->manager4 = manager = nm_bluez4_manager_new (priv->provider);
+ priv->manager4 = manager = nm_bluez4_manager_new (priv->settings);
g_signal_connect (manager,
NM_BLUEZ_MANAGER_BDADDR_ADDED,
@@ -209,7 +210,7 @@ setup_bluez5 (NMBluezManager *self)
g_return_if_fail (!priv->manager4 && !priv->manager5 && !priv->bluez_version);
setup_version_number (self, 5);
- priv->manager5 = manager = nm_bluez5_manager_new (priv->provider);
+ priv->manager5 = manager = nm_bluez5_manager_new (priv->settings);
g_signal_connect (manager,
NM_BLUEZ_MANAGER_BDADDR_ADDED,
@@ -407,9 +408,9 @@ dispose (GObject *object)
priv->bluez_version = 0;
- g_clear_object (&priv->provider);
-
G_OBJECT_CLASS (nm_bluez_manager_parent_class)->dispose (object);
+
+ g_clear_object (&priv->settings);
}
static void
@@ -417,7 +418,7 @@ nm_bluez_manager_init (NMBluezManager *self)
{
NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self);
- priv->provider = g_object_ref (nm_connection_provider_get ());
+ priv->settings = g_object_ref (NM_SETTINGS_GET);
}
static NMDevice *
diff --git a/src/devices/bluetooth/nm-bluez-manager.h b/src/devices/bluetooth/nm-bluez-manager.h
index 1f5597d831..d23b33a7d8 100644
--- a/src/devices/bluetooth/nm-bluez-manager.h
+++ b/src/devices/bluetooth/nm-bluez-manager.h
@@ -22,10 +22,6 @@
#ifndef __NETWORKMANAGER_BLUEZ_MANAGER_H__
#define __NETWORKMANAGER_BLUEZ_MANAGER_H__
-#include "nm-default.h"
-
-G_BEGIN_DECLS
-
#define NM_TYPE_BLUEZ_MANAGER (nm_bluez_manager_get_type ())
#define NM_BLUEZ_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BLUEZ_MANAGER, NMBluezManager))
diff --git a/src/devices/bluetooth/nm-bluez4-adapter.c b/src/devices/bluetooth/nm-bluez4-adapter.c
index 9d8fd21056..2ef071a8bf 100644
--- a/src/devices/bluetooth/nm-bluez4-adapter.c
+++ b/src/devices/bluetooth/nm-bluez4-adapter.c
@@ -20,13 +20,15 @@
#include "nm-default.h"
+#include "nm-bluez4-adapter.h"
+
#include <string.h>
#include "nm-dbus-interface.h"
-#include "nm-bluez4-adapter.h"
#include "nm-bluez-device.h"
#include "nm-bluez-common.h"
#include "nm-core-internal.h"
+#include "nm-settings.h"
G_DEFINE_TYPE (NMBluez4Adapter, nm_bluez4_adapter, G_TYPE_OBJECT)
@@ -41,7 +43,7 @@ typedef struct {
GHashTable *devices;
/* Cached for devices */
- NMConnectionProvider *provider;
+ NMSettings *settings;
} NMBluez4AdapterPrivate;
@@ -160,7 +162,7 @@ device_created (GDBusProxy *proxy, const char *path, gpointer user_data)
NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self);
NMBluezDevice *device;
- device = nm_bluez_device_new (path, priv->address, priv->provider, 4);
+ device = nm_bluez_device_new (path, priv->address, priv->settings, 4);
g_signal_connect (device, "initialized", G_CALLBACK (device_initialized), self);
g_signal_connect (device, "notify::usable", G_CALLBACK (device_usable), self);
g_hash_table_insert (priv->devices, (gpointer) nm_bluez_device_get_path (device), device);
@@ -234,17 +236,19 @@ query_properties (NMBluez4Adapter *self)
/***********************************************************/
NMBluez4Adapter *
-nm_bluez4_adapter_new (const char *path, NMConnectionProvider *provider)
+nm_bluez4_adapter_new (const char *path, NMSettings *settings)
{
NMBluez4Adapter *self;
NMBluez4AdapterPrivate *priv;
+ g_return_val_if_fail (NM_IS_SETTINGS (settings), NULL);
+
self = (NMBluez4Adapter *) g_object_new (NM_TYPE_BLUEZ4_ADAPTER,
NM_BLUEZ4_ADAPTER_PATH, path,
NULL);
priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self);
- priv->provider = provider;
+ priv->settings = g_object_ref (settings);
priv->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
@@ -301,6 +305,8 @@ finalize (GObject *object)
g_object_unref (priv->proxy);
G_OBJECT_CLASS (nm_bluez4_adapter_parent_class)->finalize (object);
+
+ g_object_unref (priv->settings);
}
static void
diff --git a/src/devices/bluetooth/nm-bluez4-adapter.h b/src/devices/bluetooth/nm-bluez4-adapter.h
index a8a2bfb4d2..ee61112f2e 100644
--- a/src/devices/bluetooth/nm-bluez4-adapter.h
+++ b/src/devices/bluetooth/nm-bluez4-adapter.h
@@ -21,10 +21,7 @@
#ifndef __NETWORKMANAGER_BLUEZ4_ADAPTER_H__
#define __NETWORKMANAGER_BLUEZ4_ADAPTER_H__
-
-#include "nm-default.h"
#include "nm-bluez-device.h"
-#include "nm-connection-provider.h"
#define NM_TYPE_BLUEZ4_ADAPTER (nm_bluez4_adapter_get_type ())
#define NM_BLUEZ4_ADAPTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BLUEZ4_ADAPTER, NMBluez4Adapter))
@@ -54,7 +51,7 @@ typedef struct {
GType nm_bluez4_adapter_get_type (void);
NMBluez4Adapter *nm_bluez4_adapter_new (const char *path,
- NMConnectionProvider *provider);
+ NMSettings *settings);
const char *nm_bluez4_adapter_get_path (NMBluez4Adapter *self);
diff --git a/src/devices/bluetooth/nm-bluez4-manager.c b/src/devices/bluetooth/nm-bluez4-manager.c
index 146612a890..36bc30e59c 100644
--- a/src/devices/bluetooth/nm-bluez4-manager.c
+++ b/src/devices/bluetooth/nm-bluez4-manager.c
@@ -21,20 +21,22 @@
#include "nm-default.h"
+#include "nm-bluez4-manager.h"
+
#include <signal.h>
#include <string.h>
#include <stdlib.h>
-#include "nm-bluez-manager.h"
-#include "nm-bluez4-manager.h"
#include "nm-bluez4-adapter.h"
+#include "nm-bluez-manager.h"
#include "nm-bluez-common.h"
#include "nm-core-internal.h"
+#include "nm-settings.h"
typedef struct {
gulong name_owner_changed_id;
- NMConnectionProvider *provider;
+ NMSettings *settings;
GDBusProxy *proxy;
@@ -155,7 +157,7 @@ default_adapter_changed (GDBusProxy *proxy, const char *path, NMBluez4Manager *s
/* Add the new default adapter */
if (path) {
- priv->adapter = nm_bluez4_adapter_new (path, priv->provider);
+ priv->adapter = nm_bluez4_adapter_new (path, priv->settings);
g_signal_connect (priv->adapter, "initialized", G_CALLBACK (adapter_initialized), self);
}
}
@@ -223,12 +225,14 @@ name_owner_changed_cb (GObject *object,
/****************************************************************/
NMBluez4Manager *
-nm_bluez4_manager_new (NMConnectionProvider *provider)
+nm_bluez4_manager_new (NMSettings *settings)
{
NMBluez4Manager *instance;
+ g_return_val_if_fail (NM_IS_SETTINGS (settings), NULL);
+
instance = g_object_new (NM_TYPE_BLUEZ4_MANAGER, NULL);
- NM_BLUEZ4_MANAGER_GET_PRIVATE (instance)->provider = provider;
+ NM_BLUEZ4_MANAGER_GET_PRIVATE (instance)->settings = g_object_ref (settings);
return instance;
}
@@ -264,6 +268,8 @@ dispose (GObject *object)
g_clear_object (&priv->adapter);
G_OBJECT_CLASS (nm_bluez4_manager_parent_class)->dispose (object);
+
+ g_clear_object (&priv->settings);
}
static void
diff --git a/src/devices/bluetooth/nm-bluez4-manager.h b/src/devices/bluetooth/nm-bluez4-manager.h
index f6bf76586b..dbf7688940 100644
--- a/src/devices/bluetooth/nm-bluez4-manager.h
+++ b/src/devices/bluetooth/nm-bluez4-manager.h
@@ -1,4 +1,3 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager -- Network link manager
*
* This program is free software; you can redistribute it and/or modify
@@ -23,7 +22,6 @@
#define __NETWORKMANAGER_BLUEZ4_MANAGER_H__
#include "nm-default.h"
-#include "nm-connection-provider.h"
G_BEGIN_DECLS
@@ -51,7 +49,7 @@ typedef struct {
GType nm_bluez4_manager_get_type (void);
-NMBluez4Manager *nm_bluez4_manager_new (NMConnectionProvider *provider);
+NMBluez4Manager *nm_bluez4_manager_new (NMSettings *settings);
void nm_bluez4_manager_query_devices (NMBluez4Manager *manager);
diff --git a/src/devices/bluetooth/nm-bluez5-manager.c b/src/devices/bluetooth/nm-bluez5-manager.c
index 66d171bf2e..183f23c1e4 100644
--- a/src/devices/bluetooth/nm-bluez5-manager.c
+++ b/src/devices/bluetooth/nm-bluez5-manager.c
@@ -22,19 +22,21 @@
#include "nm-default.h"
+#include "nm-bluez5-manager.h"
+
#include <signal.h>
#include <string.h>
#include <stdlib.h>
+#include "nm-core-internal.h"
+
#include "nm-bluez-manager.h"
-#include "nm-bluez5-manager.h"
#include "nm-bluez-device.h"
#include "nm-bluez-common.h"
-
-#include "nm-core-internal.h"
+#include "nm-settings.h"
typedef struct {
- NMConnectionProvider *provider;
+ NMSettings *settings;
GDBusProxy *proxy;
@@ -140,7 +142,7 @@ device_added (GDBusProxy *proxy, const gchar *path, NMBluez5Manager *self)
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
NMBluezDevice *device;
- device = nm_bluez_device_new (path, NULL, priv->provider, 5);
+ device = nm_bluez_device_new (path, NULL, priv->settings, 5);
g_signal_connect (device, "initialized", G_CALLBACK (device_initialized), self);
g_signal_connect (device, "notify::usable", G_CALLBACK (device_usable), self);
g_hash_table_insert (priv->devices, (gpointer) nm_bluez_device_get_path (device), device);
@@ -309,12 +311,14 @@ bluez_cleanup (NMBluez5Manager *self, gboolean do_signal)
/****************************************************************/
NMBluez5Manager *
-nm_bluez5_manager_new (NMConnectionProvider *provider)
+nm_bluez5_manager_new (NMSettings *settings)
{
NMBluez5Manager *instance = NULL;
+ g_return_val_if_fail (NM_IS_SETTINGS (settings), NULL);
+
instance = g_object_new (NM_TYPE_BLUEZ5_MANAGER, NULL);
- NM_BLUEZ5_MANAGER_GET_PRIVATE (instance)->provider = provider;
+ NM_BLUEZ5_MANAGER_GET_PRIVATE (instance)->settings = g_object_ref (settings);
return instance;
}
@@ -347,6 +351,8 @@ finalize (GObject *object)
g_hash_table_destroy (priv->devices);
G_OBJECT_CLASS (nm_bluez5_manager_parent_class)->finalize (object);
+
+ g_object_unref (priv->settings);
}
static void
diff --git a/src/devices/bluetooth/nm-bluez5-manager.h b/src/devices/bluetooth/nm-bluez5-manager.h
index 1c531090b7..0e309d33a3 100644
--- a/src/devices/bluetooth/nm-bluez5-manager.h
+++ b/src/devices/bluetooth/nm-bluez5-manager.h
@@ -22,11 +22,6 @@
#ifndef __NETWORKMANAGER_BLUEZ5_MANAGER_H__
#define __NETWORKMANAGER_BLUEZ5_MANAGER_H__
-#include "nm-default.h"
-#include "nm-connection-provider.h"
-
-G_BEGIN_DECLS
-
#define NM_TYPE_BLUEZ5_MANAGER (nm_bluez5_manager_get_type ())
#define NM_BLUEZ5_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BLUEZ5_MANAGER, NMBluez5Manager))
#define NM_BLUEZ5_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_BLUEZ5_MANAGER, NMBluez5ManagerClass))
@@ -51,7 +46,7 @@ typedef struct {
GType nm_bluez5_manager_get_type (void);
-NMBluez5Manager *nm_bluez5_manager_new (NMConnectionProvider *provider);
+NMBluez5Manager *nm_bluez5_manager_new (NMSettings *settings);
void nm_bluez5_manager_query_devices (NMBluez5Manager *manager);
diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c
index eef4ed0a1b..8f3772c69b 100644
--- a/src/devices/bluetooth/nm-device-bt.c
+++ b/src/devices/bluetooth/nm-device-bt.c
@@ -362,6 +362,7 @@ static void
ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
+ NMDeviceBt *self = NM_DEVICE_BT (user_data);
switch (nm_device_get_state (device)) {
case NM_DEVICE_STATE_PREPARE:
@@ -375,7 +376,18 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
case NM_DEVICE_STATE_ACTIVATED:
if (nm_device_activate_ip4_state_in_conf (device))
nm_device_activate_schedule_ip4_config_timeout (device);
- else {
+ else if (nm_device_activate_ip6_state_in_conf (device))
+ nm_device_activate_schedule_ip6_config_timeout (device);
+ else if (nm_device_activate_ip4_state_done (device)) {
+ nm_device_ip_method_failed (device,
+ AF_INET,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ } else if (nm_device_activate_ip6_state_done (device)) {
+ nm_device_ip_method_failed (device,
+ AF_INET6,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ } else {
+ _LOGW (LOGD_MB, "PPP failure in unexpected state %u", (guint) nm_device_get_state (device));
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
@@ -502,8 +514,9 @@ modem_ip4_config_result (NMModem *modem,
_LOGW (LOGD_MB | LOGD_IP4 | LOGD_BT,
"retrieving IP4 configuration failed: %s",
error->message);
-
- nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ nm_device_ip_method_failed (device,
+ AF_INET,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
} else
nm_device_activate_schedule_ip4_config_result (device, config);
}
diff --git a/src/devices/nm-device-ethernet-utils.c b/src/devices/nm-device-ethernet-utils.c
index d034ddfc77..298e6dff95 100644
--- a/src/devices/nm-device-ethernet-utils.c
+++ b/src/devices/nm-device-ethernet-utils.c
@@ -25,30 +25,26 @@
#include "nm-device-ethernet-utils.h"
char *
-nm_device_ethernet_utils_get_default_wired_name (const GSList *connections)
+nm_device_ethernet_utils_get_default_wired_name (NMConnection *const *connections)
{
- const GSList *iter;
- char *cname = NULL;
- int i = 0;
+ char *temp;
+ guint j;
+ int i;
/* Find the next available unique connection name */
- while (!cname && (i++ < 10000)) {
- char *temp;
- gboolean found = FALSE;
-
+ for (i = 1; i <= 10000; i++) {
temp = g_strdup_printf (_("Wired connection %d"), i);
- for (iter = connections; iter; iter = iter->next) {
- if (g_strcmp0 (nm_connection_get_id (NM_CONNECTION (iter->data)), temp) == 0) {
- found = TRUE;
+ for (j = 0; connections[j]; j++) {
+ if (nm_streq0 (nm_connection_get_id (connections[j]), temp)) {
g_free (temp);
- break;
+ goto next;
}
}
-
- if (found == FALSE)
- cname = temp;
+ return temp;
+next:
+ ;
}
- return cname;
+ return NULL;
}
diff --git a/src/devices/nm-device-ethernet-utils.h b/src/devices/nm-device-ethernet-utils.h
index 31d645d851..197d0a9ea4 100644
--- a/src/devices/nm-device-ethernet-utils.h
+++ b/src/devices/nm-device-ethernet-utils.h
@@ -19,8 +19,6 @@
#ifndef __NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H__
#define __NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H__
-#include "nm-default.h"
-
-char *nm_device_ethernet_utils_get_default_wired_name (const GSList *connections);
+char *nm_device_ethernet_utils_get_default_wired_name (NMConnection *const *connections);
#endif /* NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H */
diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c
index d27f7dcaf1..1367555b3e 100644
--- a/src/devices/nm-device-ethernet.c
+++ b/src/devices/nm-device-ethernet.c
@@ -21,6 +21,8 @@
#include "nm-default.h"
+#include "nm-device-ethernet.h"
+
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
@@ -29,7 +31,6 @@
#include <gudev/gudev.h>
-#include "nm-device-ethernet.h"
#include "nm-device-private.h"
#include "nm-activation-request.h"
#include "NetworkManagerUtils.h"
@@ -44,7 +45,7 @@
#include "nm-settings-connection.h"
#include "nm-config.h"
#include "nm-device-ethernet-utils.h"
-#include "nm-connection-provider.h"
+#include "nm-settings.h"
#include "nm-device-factory.h"
#include "nm-core-internal.h"
#include "NetworkManagerUtils.h"
@@ -1435,7 +1436,7 @@ static NMConnection *
new_default_connection (NMDevice *self)
{
NMConnection *connection;
- const GSList *connections;
+ NMSettingsConnection *const*connections;
NMSetting *setting;
const char *hw_address;
gs_free char *defname = NULL;
@@ -1453,8 +1454,8 @@ new_default_connection (NMDevice *self)
setting = nm_setting_connection_new ();
nm_connection_add_setting (connection, setting);
- connections = nm_connection_provider_get_connections (nm_connection_provider_get ());
- defname = nm_device_ethernet_utils_get_default_wired_name (connections);
+ connections = nm_settings_get_connections (nm_device_get_settings (self), NULL);
+ defname = nm_device_ethernet_utils_get_default_wired_name ((NMConnection *const*) connections);
if (!defname)
return NULL;
@@ -1581,7 +1582,6 @@ link_changed (NMDevice *device, NMPlatformLink *info)
{
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
- static const guint8 zero_hwaddr[ETH_ALEN];
const guint8 *hwaddr;
gsize hwaddrlen = 0;
@@ -1593,7 +1593,7 @@ link_changed (NMDevice *device, NMPlatformLink *info)
hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET,
nm_device_get_ifindex (self),
&hwaddrlen);
- if (!nm_utils_hwaddr_matches (hwaddr, hwaddrlen, zero_hwaddr, ETH_ALEN)) {
+ if (!nm_utils_hwaddr_matches (hwaddr, hwaddrlen, nm_ip_addr_zero.addr_eth, sizeof (nm_ip_addr_zero.addr_eth))) {
_LOGD (LOGD_DEVICE, "device got a valid hw address");
nm_device_update_hw_address (self);
nm_device_update_initial_hw_address (self);
diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c
index 089b10352c..785010ebfa 100644
--- a/src/devices/nm-device-ip-tunnel.c
+++ b/src/devices/nm-device-ip-tunnel.c
@@ -20,19 +20,20 @@
#include "nm-default.h"
+#include "nm-device-ip-tunnel.h"
+
#include <string.h>
#include <netinet/in.h>
#include <linux/if.h>
#include <linux/ip.h>
#include <linux/if_tunnel.h>
-#include "nm-device-ip-tunnel.h"
#include "nm-device-private.h"
#include "nm-manager.h"
#include "nm-platform.h"
#include "nm-device-factory.h"
#include "nm-core-internal.h"
-#include "nm-connection-provider.h"
+#include "nm-settings.h"
#include "nm-activation-request.h"
#include "nm-ip4-config.h"
@@ -385,8 +386,8 @@ update_connection (NMDevice *device, NMConnection *connection)
NMConnection *parent_connection;
/* Don't change a parent specified by UUID if it's still valid */
- parent_connection = nm_connection_provider_get_connection_by_uuid (nm_connection_provider_get (),
- setting_parent);
+ parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (nm_device_get_settings (device),
+ setting_parent);
if (parent_connection && nm_device_check_connection_compatible (parent, parent_connection))
new_parent = NULL;
}
diff --git a/src/devices/nm-device-macvlan.c b/src/devices/nm-device-macvlan.c
index c431fe891c..c5443ecd23 100644
--- a/src/devices/nm-device-macvlan.c
+++ b/src/devices/nm-device-macvlan.c
@@ -20,11 +20,12 @@
#include "nm-default.h"
+#include "nm-device-macvlan.h"
+
#include <string.h>
-#include "nm-device-macvlan.h"
#include "nm-device-private.h"
-#include "nm-connection-provider.h"
+#include "nm-settings.h"
#include "nm-activation-request.h"
#include "nm-manager.h"
#include "nm-platform.h"
@@ -488,7 +489,7 @@ update_connection (NMDevice *device, NMConnection *connection)
NMConnection *parent_connection;
/* Don't change a parent specified by UUID if it's still valid */
- parent_connection = nm_connection_provider_get_connection_by_uuid (nm_connection_provider_get (), setting_parent);
+ parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (nm_device_get_settings (device), setting_parent);
if (parent_connection && nm_device_check_connection_compatible (priv->parent, parent_connection))
new_parent = NULL;
}
diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h
index 602c2c8575..418ae2d9ca 100644
--- a/src/devices/nm-device-private.h
+++ b/src/devices/nm-device-private.h
@@ -42,6 +42,8 @@ enum NMActStageReturn {
#define NM_DEVICE_CAP_INTERNAL_MASK 0xc0000000
+NMSettings *nm_device_get_settings (NMDevice *self);
+
void nm_device_set_ip_iface (NMDevice *self, const char *iface);
void nm_device_activate_schedule_stage3_ip_config_start (NMDevice *device);
@@ -70,9 +72,11 @@ void nm_device_activate_schedule_ip6_config_timeout (NMDevice *device);
gboolean nm_device_activate_ip4_state_in_conf (NMDevice *device);
gboolean nm_device_activate_ip4_state_in_wait (NMDevice *device);
+gboolean nm_device_activate_ip4_state_done (NMDevice *device);
gboolean nm_device_activate_ip6_state_in_conf (NMDevice *device);
gboolean nm_device_activate_ip6_state_in_wait (NMDevice *device);
+gboolean nm_device_activate_ip6_state_done (NMDevice *device);
void nm_device_set_dhcp_timeout (NMDevice *device, guint32 timeout);
void nm_device_set_dhcp_anycast_address (NMDevice *device, const char *addr);
@@ -103,6 +107,8 @@ void nm_device_queue_recheck_available (NMDevice *device,
void nm_device_set_wwan_ip4_config (NMDevice *device, NMIP4Config *config);
void nm_device_set_wwan_ip6_config (NMDevice *device, NMIP6Config *config);
+void nm_device_ip_method_failed (NMDevice *self, int family, NMDeviceStateReason reason);
+
gboolean nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value);
#define NM_DEVICE_CLASS_DECLARE_TYPES(klass, conn_type, ...) \
diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c
index eb6527de8e..95f36298f5 100644
--- a/src/devices/nm-device-vlan.c
+++ b/src/devices/nm-device-vlan.c
@@ -20,15 +20,16 @@
#include "nm-default.h"
+#include "nm-device-vlan.h"
+
#include <sys/socket.h>
-#include "nm-device-vlan.h"
#include "nm-manager.h"
#include "nm-utils.h"
#include "NetworkManagerUtils.h"
#include "nm-device-private.h"
#include "nm-enum-types.h"
-#include "nm-connection-provider.h"
+#include "nm-settings.h"
#include "nm-activation-request.h"
#include "nm-ip4-config.h"
#include "nm-platform.h"
@@ -515,7 +516,7 @@ update_connection (NMDevice *device, NMConnection *connection)
NMConnection *parent_connection;
/* Don't change a parent specified by UUID if it's still valid */
- parent_connection = nm_connection_provider_get_connection_by_uuid (nm_connection_provider_get (), setting_parent);
+ parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (nm_device_get_settings (device), setting_parent);
if (parent_connection && nm_device_check_connection_compatible (priv->parent, parent_connection))
new_parent = NULL;
}
diff --git a/src/devices/nm-device-vxlan.c b/src/devices/nm-device-vxlan.c
index d308d47abc..f3dfbd9ef5 100644
--- a/src/devices/nm-device-vxlan.c
+++ b/src/devices/nm-device-vxlan.c
@@ -20,9 +20,10 @@
#include "nm-default.h"
+#include "nm-device-vxlan.h"
+
#include <string.h>
-#include "nm-device-vxlan.h"
#include "nm-device-private.h"
#include "nm-manager.h"
#include "nm-platform.h"
@@ -30,7 +31,7 @@
#include "nm-device-factory.h"
#include "nm-setting-vxlan.h"
#include "nm-setting-wired.h"
-#include "nm-connection-provider.h"
+#include "nm-settings.h"
#include "nm-activation-request.h"
#include "nm-ip4-config.h"
@@ -411,8 +412,8 @@ update_connection (NMDevice *device, NMConnection *connection)
NMConnection *parent_connection;
/* Don't change a parent specified by UUID if it's still valid */
- parent_connection = nm_connection_provider_get_connection_by_uuid (nm_connection_provider_get (),
- setting_parent);
+ parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (nm_device_get_settings (device),
+ setting_parent);
if (parent_connection && nm_device_check_connection_compatible (parent, parent_connection))
new_parent = NULL;
}
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 5ece950900..88cebe4886 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -21,6 +21,8 @@
#include "nm-default.h"
+#include "nm-device.h"
+
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
@@ -34,7 +36,6 @@
#include <netlink/route/addr.h>
#include <linux/if_addr.h>
-#include "nm-device.h"
#include "nm-device-private.h"
#include "NetworkManagerUtils.h"
#include "nm-manager.h"
@@ -52,7 +53,7 @@
#include "nm-firewall-manager.h"
#include "nm-enum-types.h"
#include "nm-settings-connection.h"
-#include "nm-connection-provider.h"
+#include "nm-settings.h"
#include "nm-auth-utils.h"
#include "nm-dispatcher.h"
#include "nm-config.h"
@@ -72,7 +73,18 @@ _LOG_DECLARE_SELF (NMDevice);
G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_EXPORTED_OBJECT)
-#define NM_DEVICE_GET_PRIVATE(o) ((o)->priv)
+#define NM_DEVICE_GET_PRIVATE(self) \
+ ({ \
+ /* preserve the const-ness of self. Unfortunately, that
+ * way, @self cannot be a void pointer */ \
+ typeof (self) _self = (self); \
+ \
+ /* Get compiler error if variable is of wrong type */ \
+ _nm_unused const NMDevice *_self2 = (_self); \
+ \
+ nm_assert (NM_IS_DEVICE (_self)); \
+ _self->priv; \
+ })
enum {
STATE_CHANGED,
@@ -134,6 +146,9 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDevice,
#define PENDING_ACTION_DHCP6 "dhcp6"
#define PENDING_ACTION_AUTOCONF6 "autoconf6"
+#define DHCP_RESTART_TIMEOUT 120
+#define DHCP_NUM_TRIES_MAX 3
+
typedef void (*ActivationHandleFunc) (NMDevice *self);
typedef struct {
@@ -163,9 +178,9 @@ typedef struct {
typedef struct {
NMDevice *slave;
- gboolean slave_is_enslaved;
- gboolean configure;
gulong watch_id;
+ bool slave_is_enslaved;
+ bool configure;
} SlaveInfo;
typedef struct {
@@ -193,7 +208,7 @@ typedef struct {
} ArpingData;
typedef struct _NMDevicePrivate {
- gboolean in_state_changed;
+ bool in_state_changed;
guint device_link_changed_id;
guint device_ip_link_changed_id;
@@ -209,7 +224,7 @@ typedef struct _NMDevicePrivate {
char * udi;
char * iface; /* may change, could be renamed by user */
int ifindex;
- gboolean real;
+ bool real;
char * ip_iface;
int ip_ifindex;
NMDeviceType type;
@@ -221,8 +236,8 @@ typedef struct _NMDevicePrivate {
char * driver_version;
char * firmware_version;
RfKillType rfkill_type;
- gboolean firmware_missing;
- gboolean nm_plugin_missing;
+ bool firmware_missing;
+ bool nm_plugin_missing;
GHashTable * available_connections;
char * hw_addr;
guint hw_addr_len;
@@ -233,7 +248,7 @@ typedef struct _NMDevicePrivate {
NMUnmanagedFlags unmanaged_mask;
NMUnmanagedFlags unmanaged_flags;
- gboolean is_nm_owned; /* whether the device is a device owned and created by NM */
+ bool is_nm_owned; /* whether the device is a device owned and created by NM */
DeleteOnDeactivateData *delete_on_deactivate_data; /* data for scheduled cleanup when deleting link (g_idle_add) */
GCancellable *deactivating_cancellable;
@@ -241,7 +256,7 @@ typedef struct _NMDevicePrivate {
guint32 ip4_address;
NMActRequest * queued_act_request;
- gboolean queued_act_request_is_waiting_for_carrier;
+ bool queued_act_request_is_waiting_for_carrier;
NMActRequest * act_request;
ActivationHandleData act_handle4; /* for layer2 and IPv4. */
ActivationHandleData act_handle6;
@@ -261,11 +276,12 @@ typedef struct _NMDevicePrivate {
guint link_connected_id;
guint link_disconnected_id;
guint carrier_defer_id;
- gboolean carrier;
+ bool carrier;
guint carrier_wait_id;
- gboolean ignore_carrier;
+ bool ignore_carrier;
+ gulong ignore_carrier_id;
guint32 mtu;
- gboolean up; /* IFF_UP */
+ bool up; /* IFF_UP */
/* Generic DHCP stuff */
guint32 dhcp_timeout;
@@ -288,14 +304,17 @@ typedef struct _NMDevicePrivate {
NMPlatformIP6Route v6;
} default_route;
- gboolean v4_commit_first_time;
- gboolean v6_commit_first_time;
+ bool v4_commit_first_time;
+ bool v6_commit_first_time;
/* DHCPv4 tracking */
- NMDhcpClient * dhcp4_client;
- gulong dhcp4_state_sigid;
- NMDhcp4Config * dhcp4_config;
- guint dhcp4_restart_id;
+ struct {
+ NMDhcpClient * client;
+ gulong state_sigid;
+ NMDhcp4Config * config;
+ guint restart_id;
+ guint num_tries_left;
+ } dhcp4;
PingInfo gw_ping;
@@ -304,7 +323,7 @@ typedef struct _NMDevicePrivate {
gulong dnsmasq_state_id;
/* Firewall */
- gboolean fw_ready;
+ bool fw_ready;
NMFirewallManagerCallId fw_call;
/* IPv4LL stuff */
@@ -325,8 +344,9 @@ typedef struct _NMDevicePrivate {
NMIP6Config * ext_ip6_config; /* Stuff added outside NM */
NMIP6Config * ext_ip6_config_captured; /* Configuration captured from platform. */
GSList * vpn6_configs; /* VPNs which use this device */
- gboolean nm_ipv6ll; /* TRUE if NM handles the device's IPv6LL address */
+ bool nm_ipv6ll; /* TRUE if NM handles the device's IPv6LL address */
guint32 ip6_mtu;
+ NMIP6Config * dad6_ip6_config;
NMRDisc * rdisc;
gulong rdisc_changed_id;
@@ -340,32 +360,36 @@ typedef struct _NMDevicePrivate {
GHashTable * ip6_saved_properties;
- NMDhcpClient * dhcp6_client;
- NMRDiscDHCPLevel dhcp6_mode;
- gulong dhcp6_state_sigid;
- NMDhcp6Config * dhcp6_config;
- /* IP6 config from DHCP */
- NMIP6Config * dhcp6_ip6_config;
- /* Event ID of the current IP6 config from DHCP */
- char * dhcp6_event_id;
- guint dhcp6_restart_id;
+ struct {
+ NMDhcpClient * client;
+ NMRDiscDHCPLevel mode;
+ gulong state_sigid;
+ NMDhcp6Config * config;
+ /* IP6 config from DHCP */
+ NMIP6Config * ip6_config;
+ /* Event ID of the current IP6 config from DHCP */
+ char * event_id;
+ guint restart_id;
+ guint num_tries_left;
+ } dhcp6;
/* allow autoconnect feature */
- gboolean autoconnect;
+ bool autoconnect;
/* master interface for bridge/bond/team slave */
NMDevice * master;
- gboolean is_enslaved;
- gboolean master_ready_handled;
+ bool is_enslaved;
+ bool master_ready_handled;
gulong master_ready_id;
/* slave management */
- gboolean is_master;
+ bool is_master;
GSList * slaves; /* list of SlaveInfo */
NMMetered metered;
- NMConnectionProvider *con_provider;
+ NMSettings *settings;
+
NMLldpListener *lldp_listener;
guint check_delete_unrealized_id;
@@ -418,6 +442,8 @@ static void nm_device_start_ip_check (NMDevice *self);
static void realize_start_setup (NMDevice *self, const NMPlatformLink *plink);
static void nm_device_set_mtu (NMDevice *self, guint32 mtu);
+static void dhcp_schedule_restart (NMDevice *self, int family, const char *reason);
+
/***********************************************************/
#define QUEUED_PREFIX "queued state change to "
@@ -524,6 +550,40 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_reason_to_string, NMDeviceStateReason,
/***********************************************************/
+NMSettings *
+nm_device_get_settings (NMDevice *self)
+{
+ return NM_DEVICE_GET_PRIVATE (self)->settings;
+}
+
+static void
+init_ip4_config_dns_priority (NMDevice *self, NMIP4Config *config)
+{
+ gs_free char *value = NULL;
+ gint priority;
+
+ value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
+ "ipv4.dns-priority",
+ self);
+ priority = _nm_utils_ascii_str_to_int64 (value, 10, G_MININT, G_MAXINT, 0);
+ nm_ip4_config_set_dns_priority (config, priority ?: NM_DNS_PRIORITY_DEFAULT_NORMAL);
+}
+
+static void
+init_ip6_config_dns_priority (NMDevice *self, NMIP6Config *config)
+{
+ gs_free char *value = NULL;
+ gint priority;
+
+ value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
+ "ipv6.dns-priority",
+ self);
+ priority = _nm_utils_ascii_str_to_int64 (value, 10, G_MININT, G_MAXINT, 0);
+ nm_ip6_config_set_dns_priority (config, priority ?: NM_DNS_PRIORITY_DEFAULT_NORMAL);
+}
+
+/***********************************************************/
+
gboolean
nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value)
{
@@ -542,6 +602,17 @@ nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps)
return NM_FLAGS_ANY (NM_DEVICE_GET_PRIVATE (self)->capabilities, caps);
}
+static void
+_add_capabilities (NMDevice *self, NMDeviceCapabilities capabilities)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+
+ if (!NM_FLAGS_ALL (priv->capabilities, capabilities)) {
+ priv->capabilities |= capabilities;
+ _notify (self, PROP_CAPABILITIES);
+ }
+}
+
/***********************************************************/
const char *
@@ -664,39 +735,72 @@ static gboolean
get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- NMLinkType link_type;
- const guint8 *hwaddr = NULL;
- size_t hwaddr_len = 0;
+ const NMPlatformLink *pllink;
int ifindex;
gboolean success;
/* If we get here, we *must* have a kernel netdev, which implies an ifindex */
ifindex = nm_device_get_ip_ifindex (self);
- g_assert (ifindex);
+ g_return_val_if_fail (ifindex > 0, FALSE);
- link_type = nm_platform_link_get_type (NM_PLATFORM_GET, ifindex);
- g_return_val_if_fail (link_type > NM_LINK_TYPE_UNKNOWN, 0);
+ pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex);
+ if ( !pllink
+ || NM_IN_SET (pllink->type, NM_LINK_TYPE_NONE, NM_LINK_TYPE_UNKNOWN))
+ return FALSE;
- hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &hwaddr_len);
- if (!hwaddr_len)
+ if (pllink->addr.len <= 0)
return FALSE;
+ if (pllink->addr.len > NM_UTILS_HWADDR_LEN_MAX)
+ g_return_val_if_reached (FALSE);
- success = nm_utils_get_ipv6_interface_identifier (link_type,
- hwaddr,
- hwaddr_len,
+ success = nm_utils_get_ipv6_interface_identifier (pllink->type,
+ pllink->addr.data,
+ pllink->addr.len,
priv->dev_id,
out_iid);
if (!success) {
_LOGW (LOGD_HW, "failed to generate interface identifier "
- "for link type %u hwaddr_len %zu", link_type, hwaddr_len);
+ "for link type %u hwaddr_len %u", pllink->type, (unsigned) pllink->addr.len);
}
return success;
}
+/**
+ * nm_device_get_ip_iface_identifier:
+ * @self: an #NMDevice
+ * @iid: where to place the interface identifier
+ * @ignore_token: force creation of a non-tokenized address
+ *
+ * Return the interface's identifier for the EUI64 address generation mode.
+ * It's either a manually set token or and identifier generated in a
+ * hardware-specific way.
+ *
+ * Unless @ignore_token is set the token is preferred. That is the case
+ * for link-local addresses (to mimic kernel behavior).
+ *
+ * Returns: #TRUE if the @iid could be set
+ */
static gboolean
-nm_device_get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *iid)
+nm_device_get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *iid, gboolean ignore_token)
{
- return NM_DEVICE_GET_CLASS (self)->get_ip_iface_identifier (self, iid);
+ NMSettingIP6Config *s_ip6;
+ const char *token = NULL;
+ NMConnection *connection;
+
+ g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
+
+ connection = nm_device_get_applied_connection (self);
+ nm_assert (connection);
+
+ s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection));
+ nm_assert (s_ip6);
+
+ if (!ignore_token)
+ token = nm_setting_ip6_config_get_token (s_ip6);
+ if (token)
+ return nm_utils_ipv6_interface_identifier_get_from_token (iid, token);
+ else
+ return NM_DEVICE_GET_CLASS (self)->get_ip_iface_identifier (self, iid);
}
const char *
@@ -1327,7 +1431,7 @@ nm_device_update_dynamic_ip_setup (NMDevice *self)
g_hash_table_remove_all (priv->ip6_saved_properties);
- if (priv->dhcp4_client) {
+ if (priv->dhcp4.client) {
if (!nm_device_dhcp4_renew (self, FALSE)) {
nm_device_state_changed (self,
NM_DEVICE_STATE_FAILED,
@@ -1335,7 +1439,7 @@ nm_device_update_dynamic_ip_setup (NMDevice *self)
return;
}
}
- if (priv->dhcp6_client) {
+ if (priv->dhcp6.client) {
if (!nm_device_dhcp6_renew (self, FALSE)) {
nm_device_state_changed (self,
NM_DEVICE_STATE_FAILED,
@@ -1535,13 +1639,13 @@ device_link_changed (NMDevice *self)
{
NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- NMUtilsIPv6IfaceId token_iid;
gboolean ip_ifname_changed = FALSE;
const char *udi;
NMPlatformLink info;
const NMPlatformLink *pllink;
int ifindex;
gboolean was_up;
+ gboolean update_unmanaged_specs = FALSE;
priv->device_link_changed_id = 0;
@@ -1588,6 +1692,11 @@ device_link_changed (NMDevice *self)
/* If the device has no explicit ip_iface, then changing iface changes ip_iface too. */
ip_ifname_changed = !priv->ip_iface;
+ if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT))
+ nm_device_set_unmanaged_by_user_settings (self, nm_settings_get_unmanaged_specs (priv->settings));
+ else
+ update_unmanaged_specs = TRUE;
+
_notify (self, PROP_IFACE);
if (ip_ifname_changed)
_notify (self, PROP_IP_IFACE);
@@ -1601,10 +1710,11 @@ device_link_changed (NMDevice *self)
nm_device_emit_recheck_auto_activate (self);
}
- if (priv->rdisc && nm_platform_link_get_ipv6_token (NM_PLATFORM_GET, priv->ifindex, &token_iid)) {
- _LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface);
- if (nm_rdisc_set_iid (priv->rdisc, token_iid))
+ if (priv->rdisc && info.inet6_token.id) {
+ if (nm_rdisc_set_iid (priv->rdisc, info.inet6_token)) {
+ _LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface);
nm_rdisc_start (priv->rdisc);
+ }
}
if (klass->link_changed)
@@ -1623,18 +1733,23 @@ device_link_changed (NMDevice *self)
nm_device_set_unmanaged_by_user_udev (self);
+ reason = NM_DEVICE_STATE_REASON_NOW_MANAGED;
+
/* If the device is a external-down candidated but no longer has external
* down set, we must clear the platform-unmanaged flag with reason
* "assumed". */
if ( nm_device_get_unmanaged_mask (self, NM_UNMANAGED_EXTERNAL_DOWN)
&& !nm_device_get_unmanaged_flags (self, NM_UNMANAGED_EXTERNAL_DOWN)) {
- /* Ensure the assume check is queued before any queued state changes
- * from the transition to UNAVAILABLE.
- */
- nm_device_queue_recheck_assume (self);
- reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED;
- } else
- reason = NM_DEVICE_STATE_REASON_NOW_MANAGED;
+ /* actually, user-udev overwrites external-down. So we only assume the device,
+ * when it is a external-down candidate, which is not managed via udev. */
+ if (!nm_device_get_unmanaged_mask (self, NM_UNMANAGED_USER_UDEV)) {
+ /* Ensure the assume check is queued before any queued state changes
+ * from the transition to UNAVAILABLE.
+ */
+ nm_device_queue_recheck_assume (self);
+ reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED;
+ }
+ }
nm_device_set_unmanaged_by_flags (self, NM_UNMANAGED_PLATFORM_INIT, FALSE, reason);
}
@@ -1656,6 +1771,9 @@ device_link_changed (NMDevice *self)
}
}
+ if (update_unmanaged_specs)
+ nm_device_set_unmanaged_by_user_settings (self, nm_settings_get_unmanaged_specs (priv->settings));
+
return G_SOURCE_REMOVE;
}
@@ -1934,6 +2052,8 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
NMDevicePrivate *priv;
NMDeviceClass *klass;
static guint32 id = 0;
+ NMDeviceCapabilities capabilities = 0;
+ NMConfig *config;
g_return_if_fail (NM_IS_DEVICE (self));
@@ -1966,7 +2086,7 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
priv->dev_id = nm_platform_link_get_dev_id (NM_PLATFORM_GET, priv->ifindex);
if (nm_platform_link_is_software (NM_PLATFORM_GET, priv->ifindex))
- priv->capabilities |= NM_DEVICE_CAP_IS_SOFTWARE;
+ capabilities |= NM_DEVICE_CAP_IS_SOFTWARE;
priv->mtu = nm_platform_link_get_mtu (NM_PLATFORM_GET, priv->ifindex);
_notify (self, PROP_MTU);
@@ -1986,7 +2106,9 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
}
if (klass->get_generic_capabilities)
- priv->capabilities |= klass->get_generic_capabilities (self);
+ capabilities |= klass->get_generic_capabilities (self);
+
+ _add_capabilities (self, capabilities);
if (!priv->udi) {
/* Use a placeholder UDI until we get a real one */
@@ -2002,15 +2124,16 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
nm_device_update_initial_hw_address (self);
/* Note: initial hardware address must be read before calling get_ignore_carrier() */
- if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
- NMConfig *config = nm_config_get ();
-
- priv->ignore_carrier = nm_config_data_get_ignore_carrier (nm_config_get_data (config), self);
- g_signal_connect (G_OBJECT (config),
- NM_CONFIG_SIGNAL_CONFIG_CHANGED,
- G_CALLBACK (config_changed_update_ignore_carrier),
- self);
+ config = nm_config_get ();
+ priv->ignore_carrier = nm_config_data_get_ignore_carrier (nm_config_get_data (config), self);
+ if (!priv->ignore_carrier_id) {
+ priv->ignore_carrier_id = g_signal_connect (config,
+ NM_CONFIG_SIGNAL_CONFIG_CHANGED,
+ G_CALLBACK (config_changed_update_ignore_carrier),
+ self);
+ }
+ if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
check_carrier (self);
_LOGD (LOGD_HW,
"carrier is %s%s",
@@ -2021,8 +2144,6 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
priv->carrier = TRUE;
}
- _notify (self, PROP_CAPABILITIES);
-
klass->realize_start_notify (self, plink);
/* Do not manage externally created software devices until they are IFF_UP
@@ -2202,6 +2323,8 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self);
_notify (self, PROP_CAPABILITIES);
+ nm_clear_g_signal_handler (nm_config_get (), &priv->ignore_carrier_id);
+
priv->real = FALSE;
_notify (self, PROP_REAL);
@@ -2971,6 +3094,7 @@ nm_device_generate_connection (NMDevice *self, NMDevice *master)
gs_free char *uuid = NULL;
const char *ip4_method, *ip6_method;
GError *error = NULL;
+ const NMPlatformLink *pllink;
/* If update_connection() is not implemented, just fail. */
if (!klass->update_connection)
@@ -3017,6 +3141,15 @@ nm_device_generate_connection (NMDevice *self, NMDevice *master)
s_ip6 = nm_ip6_config_create_setting (priv->ip6_config);
nm_connection_add_setting (connection, s_ip6);
+
+ pllink = nm_platform_link_get (NM_PLATFORM_GET, priv->ifindex);
+ if (pllink && pllink->inet6_token.id) {
+ _LOGD (LOGD_IP6, "IPv6 tokenized identifier present");
+ g_object_set (s_ip6,
+ NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, NM_IN6_ADDR_GEN_MODE_EUI64,
+ NM_SETTING_IP6_CONFIG_TOKEN, nm_utils_inet6_interface_identifier_to_token (pllink->inet6_token, NULL),
+ NULL);
+ }
}
klass->update_connection (self, connection);
@@ -3323,7 +3456,7 @@ dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer us
switch (status) {
case NM_DNSMASQ_STATUS_DEAD:
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
+ nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
break;
default:
break;
@@ -3787,6 +3920,26 @@ check_ip_failed (NMDevice *self, gboolean may_fail)
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
}
+void
+nm_device_ip_method_failed (NMDevice *self, int family, NMDeviceStateReason reason)
+{
+ NMDevicePrivate *priv;
+
+ g_return_if_fail (NM_IS_DEVICE (self));
+ g_return_if_fail (family == AF_INET || family == AF_INET6);
+ priv = NM_DEVICE_GET_PRIVATE (self);
+
+ if (family == AF_INET)
+ priv->ip4_state = IP_FAIL;
+ else
+ priv->ip6_state = IP_FAIL;
+
+ if (get_ip_config_may_fail (self, family))
+ check_ip_failed (self, FALSE);
+ else
+ nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
+}
+
/*
* check_ip_done
*
@@ -4022,14 +4175,14 @@ ipv4ll_get_ip4_config (NMDevice *self, guint32 lla)
memset (&address, 0, sizeof (address));
nm_platform_ip4_address_set_addr (&address, lla, 16);
- address.source = NM_IP_CONFIG_SOURCE_IP4LL;
+ address.addr_source = NM_IP_CONFIG_SOURCE_IP4LL;
nm_ip4_config_add_address (config, &address);
/* Add a multicast route for link-local connections: destination= 224.0.0.0, netmask=240.0.0.0 */
memset (&route, 0, sizeof (route));
route.network = htonl (0xE0000000L);
route.plen = 4;
- route.source = NM_IP_CONFIG_SOURCE_IP4LL;
+ route.rt_source = NM_IP_CONFIG_SOURCE_IP4LL;
route.metric = nm_device_get_ip4_route_metric (self);
nm_ip4_config_add_route (config, &route);
@@ -4066,23 +4219,20 @@ nm_device_handle_ipv4ll_event (sd_ipv4ll *ll, int event, void *data)
r = sd_ipv4ll_get_address (ll, &address);
if (r < 0) {
_LOGE (LOGD_AUTOIP4, "invalid IPv4 link-local address received, error %d.", r);
- priv->ip4_state = IP_FAIL;
- check_ip_failed (self, FALSE);
+ nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED);
return;
}
if ((address.s_addr & IPV4LL_NETMASK) != IPV4LL_NETWORK) {
_LOGE (LOGD_AUTOIP4, "invalid address %08x received (not link-local).", address.s_addr);
- priv->ip4_state = IP_FAIL;
- check_ip_failed (self, FALSE);
+ nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_ERROR);
return;
}
config = ipv4ll_get_ip4_config (self, address.s_addr);
if (config == NULL) {
_LOGE (LOGD_AUTOIP4, "failed to get IPv4LL config");
- priv->ip4_state = IP_FAIL;
- check_ip_failed (self, FALSE);
+ nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED);
return;
}
@@ -4092,8 +4242,7 @@ nm_device_handle_ipv4ll_event (sd_ipv4ll *ll, int event, void *data)
} else if (priv->ip4_state == IP_DONE) {
if (!ip4_config_merge_and_apply (self, config, TRUE, NULL)) {
_LOGE (LOGD_AUTOIP4, "failed to update IP4 config for autoip change.");
- priv->ip4_state = IP_FAIL;
- check_ip_failed (self, FALSE);
+ nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED);
}
} else
g_assert_not_reached ();
@@ -4102,8 +4251,7 @@ nm_device_handle_ipv4ll_event (sd_ipv4ll *ll, int event, void *data)
break;
default:
_LOGW (LOGD_AUTOIP4, "IPv4LL address no longer valid after event %d.", event);
- priv->ip4_state = IP_FAIL;
- check_ip_failed (self, FALSE);
+ nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED);
}
}
@@ -4160,9 +4308,9 @@ ipv4ll_start (NMDevice *self, NMDeviceStateReason *reason)
goto fail;
}
- r = sd_ipv4ll_set_index (priv->ipv4ll, ifindex);
+ r = sd_ipv4ll_set_ifindex (priv->ipv4ll, ifindex);
if (r < 0) {
- _LOGE (LOGD_AUTOIP4, "IPv4LL: set_index() failed with error %d", r);
+ _LOGE (LOGD_AUTOIP4, "IPv4LL: set_ifindex() failed with error %d", r);
goto fail;
}
@@ -4297,23 +4445,23 @@ dhcp4_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- nm_clear_g_source (&priv->dhcp4_restart_id);
+ nm_clear_g_source (&priv->dhcp4.restart_id);
- if (priv->dhcp4_client) {
+ if (priv->dhcp4.client) {
/* Stop any ongoing DHCP transaction on this device */
- nm_clear_g_signal_handler (priv->dhcp4_client, &priv->dhcp4_state_sigid);
+ nm_clear_g_signal_handler (priv->dhcp4.client, &priv->dhcp4.state_sigid);
nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE);
if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE
|| cleanup_type == CLEANUP_TYPE_REMOVED)
- nm_dhcp_client_stop (priv->dhcp4_client, release);
+ nm_dhcp_client_stop (priv->dhcp4.client, release);
- g_clear_object (&priv->dhcp4_client);
+ g_clear_object (&priv->dhcp4.client);
}
- if (priv->dhcp4_config) {
- nm_exported_object_clear_and_unexport (&priv->dhcp4_config);
+ if (priv->dhcp4.config) {
+ nm_exported_object_clear_and_unexport (&priv->dhcp4.config);
_notify (self, PROP_DHCP4_CONFIG);
}
}
@@ -4368,6 +4516,7 @@ ip4_config_merge_and_apply (NMDevice *self,
}
composite = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
+ init_ip4_config_dns_priority (self, composite);
if (commit)
ensure_con_ip4_config (self);
@@ -4466,7 +4615,7 @@ ip4_config_merge_and_apply (NMDevice *self,
priv->default_route.v4_has = TRUE;
memset (&priv->default_route.v4, 0, sizeof (priv->default_route.v4));
- priv->default_route.v4.source = NM_IP_CONFIG_SOURCE_USER;
+ priv->default_route.v4.rt_source = NM_IP_CONFIG_SOURCE_USER;
priv->default_route.v4.gateway = gateway;
priv->default_route.v4.metric = default_route_metric;
priv->default_route.v4.mss = nm_ip4_config_get_mss (composite);
@@ -4512,28 +4661,30 @@ END_ADD_DEFAULT_ROUTE:
return success;
}
-static void
+static gboolean
dhcp4_lease_change (NMDevice *self, NMIP4Config *config)
{
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
- g_return_if_fail (config != NULL);
+ g_return_val_if_fail (config != NULL, FALSE);
if (!ip4_config_merge_and_apply (self, config, TRUE, &reason)) {
_LOGW (LOGD_DHCP4, "failed to update IPv4 config for DHCP change.");
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
- } else {
- /* Notify dispatcher scripts of new DHCP4 config */
- nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE,
- nm_device_get_settings_connection (self),
- nm_device_get_applied_connection (self),
- self,
- NULL,
- NULL,
- NULL);
-
- nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE);
+ return FALSE;
}
+
+ /* Notify dispatcher scripts of new DHCP4 config */
+ nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE,
+ nm_device_get_settings_connection (self),
+ nm_device_get_applied_connection (self),
+ self,
+ NULL,
+ NULL,
+ NULL);
+
+ nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE);
+
+ return TRUE;
}
static gboolean
@@ -4547,11 +4698,11 @@ dhcp4_restart_cb (gpointer user_data)
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
priv = NM_DEVICE_GET_PRIVATE (self);
- priv->dhcp4_restart_id = 0;
+ priv->dhcp4.restart_id = 0;
connection = nm_device_get_applied_connection (self);
if (dhcp4_start (self, connection, &reason) == NM_ACT_STAGE_RETURN_FAILURE)
- priv->dhcp4_restart_id = g_timeout_add_seconds (120, dhcp4_restart_cb, self);
+ dhcp_schedule_restart (self, AF_INET, NULL);
return FALSE;
}
@@ -4561,6 +4712,9 @@ dhcp4_fail (NMDevice *self, gboolean timeout)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ _LOGD (LOGD_DHCP4, "DHCPv4 failed: timeout %d, num tries left %u",
+ timeout, priv->dhcp4.num_tries_left);
+
dhcp4_cleanup (self, CLEANUP_TYPE_DECONFIGURE, FALSE);
/* Don't fail if there are static addresses configured on
@@ -4569,8 +4723,7 @@ dhcp4_fail (NMDevice *self, gboolean timeout)
if ( priv->ip4_state == IP_DONE
&& priv->con_ip4_config
&& nm_ip4_config_get_num_addresses (priv->con_ip4_config) > 0) {
- _LOGI (LOGD_DHCP4, "Scheduling DHCPv4 restart because device has IP addresses");
- priv->dhcp4_restart_id = g_timeout_add_seconds (120, dhcp4_restart_cb, self);
+ dhcp_schedule_restart (self, AF_INET, "device has IP addresses");
return;
}
@@ -4579,16 +4732,23 @@ dhcp4_fail (NMDevice *self, gboolean timeout)
* retry DHCP again.
*/
if (nm_device_uses_assumed_connection (self)) {
- _LOGI (LOGD_DHCP4, "Scheduling DHCPv4 restart because the connection is assumed");
- priv->dhcp4_restart_id = g_timeout_add_seconds (120, dhcp4_restart_cb, self);
+ dhcp_schedule_restart (self, AF_INET, "connection is assumed");
return;
}
- if (timeout || (priv->ip4_state == IP_CONF))
+ if ( priv->dhcp4.num_tries_left == DHCP_NUM_TRIES_MAX
+ && (timeout || (priv->ip4_state == IP_CONF)))
nm_device_activate_schedule_ip4_config_timeout (self);
- else if (priv->ip4_state == IP_DONE)
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
- else
+ else if (priv->ip4_state == IP_DONE) {
+ /* Don't fail immediately when the lease expires but try to
+ * restart DHCP for a predefined number of times.
+ */
+ if (priv->dhcp4.num_tries_left) {
+ priv->dhcp4.num_tries_left--;
+ dhcp_schedule_restart (self, AF_INET, "lease expired");
+ } else
+ nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
+ } else
g_warn_if_reached ();
}
@@ -4625,14 +4785,13 @@ dhcp4_state_changed (NMDhcpClient *client,
case NM_DHCP_STATE_BOUND:
if (!ip4_config) {
_LOGW (LOGD_DHCP4, "failed to get IPv4 config in response to DHCP event.");
- nm_device_state_changed (self,
- NM_DEVICE_STATE_FAILED,
- NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ dhcp4_fail (self, FALSE);
break;
}
- nm_dhcp4_config_set_options (priv->dhcp4_config, options);
+ nm_dhcp4_config_set_options (priv->dhcp4.config, options);
_notify (self, PROP_DHCP4_CONFIG);
+ priv->dhcp4.num_tries_left = DHCP_NUM_TRIES_MAX;
if (priv->ip4_state == IP_CONF) {
connection = nm_device_get_applied_connection (self);
@@ -4649,8 +4808,10 @@ dhcp4_state_changed (NMDhcpClient *client,
ipv4_dad_start (self, configs, dhcp4_dad_cb);
} else if (priv->ip4_state == IP_DONE) {
- dhcp4_lease_change (self, ip4_config);
- nm_device_update_metered (self);
+ if (dhcp4_lease_change (self, ip4_config))
+ nm_device_update_metered (self);
+ else
+ dhcp4_fail (self, FALSE);
}
break;
case NM_DHCP_STATE_TIMEOUT:
@@ -4706,8 +4867,8 @@ dhcp4_start (NMDevice *self,
s_ip4 = nm_connection_get_setting_ip4_config (connection);
/* Clear old exported DHCP options */
- nm_exported_object_clear_and_unexport (&priv->dhcp4_config);
- priv->dhcp4_config = nm_dhcp4_config_new ();
+ nm_exported_object_clear_and_unexport (&priv->dhcp4.config);
+ priv->dhcp4.config = nm_dhcp4_config_new ();
hw_addr = nm_platform_link_get_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), &hw_addr_len);
if (hw_addr_len) {
@@ -4716,8 +4877,8 @@ dhcp4_start (NMDevice *self,
}
/* Begin DHCP on the interface */
- g_warn_if_fail (priv->dhcp4_client == NULL);
- priv->dhcp4_client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (),
+ g_warn_if_fail (priv->dhcp4.client == NULL);
+ priv->dhcp4.client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (),
nm_device_get_ip_iface (self),
nm_device_get_ip_ifindex (self),
tmp,
@@ -4734,12 +4895,12 @@ dhcp4_start (NMDevice *self,
if (tmp)
g_byte_array_free (tmp, TRUE);
- if (!priv->dhcp4_client) {
+ if (!priv->dhcp4.client) {
*reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED;
return NM_ACT_STAGE_RETURN_FAILURE;
}
- priv->dhcp4_state_sigid = g_signal_connect (priv->dhcp4_client,
+ priv->dhcp4.state_sigid = g_signal_connect (priv->dhcp4.client,
NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
G_CALLBACK (dhcp4_state_changed),
self);
@@ -4758,7 +4919,7 @@ nm_device_dhcp4_renew (NMDevice *self, gboolean release)
NMDeviceStateReason reason;
NMConnection *connection;
- g_return_val_if_fail (priv->dhcp4_client != NULL, FALSE);
+ g_return_val_if_fail (priv->dhcp4.client != NULL, FALSE);
_LOGI (LOGD_DHCP4, "DHCPv4 lease renewal requested");
@@ -4833,7 +4994,7 @@ shared4_new_config (NMDevice *self, NMConnection *connection, NMDeviceStateReaso
}
config = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
- address.source = NM_IP_CONFIG_SOURCE_SHARED;
+ address.addr_source = NM_IP_CONFIG_SOURCE_SHARED;
nm_ip4_config_add_address (config, &address);
/* Remove the address lock when the object gets disposed */
@@ -4984,6 +5145,7 @@ act_stage3_ip4_config_start (NMDevice *self,
}
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
+ priv->dhcp4.num_tries_left = DHCP_NUM_TRIES_MAX;
/* Start IPv4 addressing based on the method requested */
if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0)
@@ -5027,25 +5189,25 @@ dhcp6_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_NONE;
- g_clear_object (&priv->dhcp6_ip6_config);
- g_clear_pointer (&priv->dhcp6_event_id, g_free);
- nm_clear_g_source (&priv->dhcp6_restart_id);
+ priv->dhcp6.mode = NM_RDISC_DHCP_LEVEL_NONE;
+ g_clear_object (&priv->dhcp6.ip6_config);
+ g_clear_pointer (&priv->dhcp6.event_id, g_free);
+ nm_clear_g_source (&priv->dhcp6.restart_id);
- if (priv->dhcp6_client) {
- nm_clear_g_signal_handler (priv->dhcp6_client, &priv->dhcp6_state_sigid);
+ if (priv->dhcp6.client) {
+ nm_clear_g_signal_handler (priv->dhcp6.client, &priv->dhcp6.state_sigid);
if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE
|| cleanup_type == CLEANUP_TYPE_REMOVED)
- nm_dhcp_client_stop (priv->dhcp6_client, release);
+ nm_dhcp_client_stop (priv->dhcp6.client, release);
- g_clear_object (&priv->dhcp6_client);
+ g_clear_object (&priv->dhcp6.client);
}
nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE);
- if (priv->dhcp6_config) {
- nm_exported_object_clear_and_unexport (&priv->dhcp6_config);
+ if (priv->dhcp6.config) {
+ nm_exported_object_clear_and_unexport (&priv->dhcp6.config);
_notify (self, PROP_DHCP6_CONFIG);
}
}
@@ -5075,6 +5237,7 @@ ip6_config_merge_and_apply (NMDevice *self,
gboolean ignore_auto_routes = FALSE;
gboolean ignore_auto_dns = FALSE;
gboolean auto_method = FALSE;
+ const char *token = NULL;
/* Apply ignore-auto-routes and ignore-auto-dns settings */
connection = nm_device_get_applied_connection (self);
@@ -5082,9 +5245,14 @@ ip6_config_merge_and_apply (NMDevice *self,
NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config (connection);
if (s_ip6) {
+ NMSettingIP6Config *ip6 = NM_SETTING_IP6_CONFIG (s_ip6);
+
ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes (s_ip6);
ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns (s_ip6);
+ if (nm_setting_ip6_config_get_addr_gen_mode (ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64)
+ token = nm_setting_ip6_config_get_token (ip6);
+
if (NM_IN_STRSET (nm_setting_ip_config_get_method (s_ip6),
NM_SETTING_IP6_CONFIG_METHOD_AUTO,
NM_SETTING_IP6_CONFIG_METHOD_DHCP))
@@ -5094,9 +5262,11 @@ ip6_config_merge_and_apply (NMDevice *self,
/* If no config was passed in, create a new one */
composite = nm_ip6_config_new (nm_device_get_ip_ifindex (self));
+ init_ip6_config_dns_priority (self, composite);
if (commit)
ensure_con_ip6_config (self);
+
g_assert (composite);
/* Merge all the IP configs into the composite config */
@@ -5105,8 +5275,8 @@ ip6_config_merge_and_apply (NMDevice *self,
(ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
| (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
}
- if (priv->dhcp6_ip6_config) {
- nm_ip6_config_merge (composite, priv->dhcp6_ip6_config,
+ if (priv->dhcp6.ip6_config) {
+ nm_ip6_config_merge (composite, priv->dhcp6.ip6_config,
(ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
| (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
}
@@ -5199,7 +5369,7 @@ ip6_config_merge_and_apply (NMDevice *self,
priv->default_route.v6_has = TRUE;
memset (&priv->default_route.v6, 0, sizeof (priv->default_route.v6));
- priv->default_route.v6.source = NM_IP_CONFIG_SOURCE_USER;
+ priv->default_route.v6.rt_source = NM_IP_CONFIG_SOURCE_USER;
priv->default_route.v6.gateway = *gateway;
priv->default_route.v6.metric = nm_device_get_ip6_route_metric (self);
priv->default_route.v6.mss = nm_ip6_config_get_mss (composite);
@@ -5230,6 +5400,14 @@ END_ADD_DEFAULT_ROUTE:
/* Allow setting MTU etc */
if (commit) {
+ NMUtilsIPv6IfaceId iid;
+
+ if (token && nm_utils_ipv6_interface_identifier_get_from_token (&iid, token)) {
+ nm_platform_link_set_ipv6_token (NM_PLATFORM_GET,
+ nm_device_get_ip_ifindex (self),
+ iid);
+ }
+
if (NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit)
NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit (self, composite);
}
@@ -5245,37 +5423,38 @@ END_ADD_DEFAULT_ROUTE:
return success;
}
-static void
+static gboolean
dhcp6_lease_change (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMSettingsConnection *settings_connection;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
- if (priv->dhcp6_ip6_config == NULL) {
+ if (priv->dhcp6.ip6_config == NULL) {
_LOGW (LOGD_DHCP6, "failed to get DHCPv6 config for rebind");
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
- return;
+ return FALSE;
}
- g_assert (priv->dhcp6_client); /* sanity check */
+ g_assert (priv->dhcp6.client); /* sanity check */
settings_connection = nm_device_get_settings_connection (self);
g_assert (settings_connection);
/* Apply the updated config */
- if (ip6_config_merge_and_apply (self, TRUE, &reason) == FALSE) {
- _LOGW (LOGD_DHCP6, "failed to update IPv6 config in response to DHCP event.");
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
- } else {
- /* Notify dispatcher scripts of new DHCPv6 config */
- nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE,
- settings_connection,
- nm_device_get_applied_connection (self),
- self, NULL, NULL, NULL);
-
- nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE);
+ if (!ip6_config_merge_and_apply (self, TRUE, &reason)) {
+ _LOGW (LOGD_DHCP6, "failed to update IPv6 config in response to DHCP event");
+ return FALSE;
}
+
+ /* Notify dispatcher scripts of new DHCPv6 config */
+ nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE,
+ settings_connection,
+ nm_device_get_applied_connection (self),
+ self, NULL, NULL, NULL);
+
+ nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE);
+
+ return TRUE;
}
static gboolean
@@ -5288,30 +5467,63 @@ dhcp6_restart_cb (gpointer user_data)
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
priv = NM_DEVICE_GET_PRIVATE (self);
- priv->dhcp6_restart_id = 0;
+ priv->dhcp6.restart_id = 0;
if (!dhcp6_start (self, FALSE, &reason))
- priv->dhcp6_restart_id = g_timeout_add_seconds (120, dhcp6_restart_cb, self);
+ dhcp_schedule_restart (self, AF_INET6, NULL);
return FALSE;
}
static void
+dhcp_schedule_restart (NMDevice *self, int family, const char *reason)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ gboolean inet4;
+ guint tries_left;
+ gs_free char *tries_str = NULL;
+
+ g_return_if_fail (family == AF_INET || family == AF_INET6);
+ inet4 = family == AF_INET;
+
+ tries_left = inet4 ? priv->dhcp4.num_tries_left : priv->dhcp6.num_tries_left;
+ if (tries_left != DHCP_NUM_TRIES_MAX)
+ tries_str = g_strdup_printf (", %u tries left", tries_left + 1);
+
+ _LOGI (inet4 ? LOGD_DHCP4 : LOGD_DHCP6,
+ "scheduling DHCPv%c restart in %u seconds%s%s%s%s",
+ inet4 ? '4' : '6',
+ DHCP_RESTART_TIMEOUT,
+ tries_str ? tries_str : "",
+ NM_PRINT_FMT_QUOTED (reason, " (reason: ", reason, ")", ""));
+
+ if (inet4) {
+ priv->dhcp4.restart_id = g_timeout_add_seconds (DHCP_RESTART_TIMEOUT,
+ dhcp4_restart_cb, self);
+ } else {
+ priv->dhcp6.restart_id = g_timeout_add_seconds (DHCP_RESTART_TIMEOUT,
+ dhcp6_restart_cb, self);
+ }
+}
+
+static void
dhcp6_fail (NMDevice *self, gboolean timeout)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ _LOGD (LOGD_DHCP6, "DHCPv6 failed: timeout %d, num tries left %u",
+ timeout, priv->dhcp6.num_tries_left);
+
dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, FALSE);
- if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) {
+ if (priv->dhcp6.mode == NM_RDISC_DHCP_LEVEL_MANAGED) {
/* Don't fail if there are static addresses configured on
* the device, instead retry after some time.
*/
if ( priv->ip6_state == IP_DONE
&& priv->con_ip6_config
&& nm_ip6_config_get_num_addresses (priv->con_ip6_config)) {
- _LOGI (LOGD_DHCP6, "Scheduling DHCPv6 restart because device has IP addresses");
- priv->dhcp6_restart_id = g_timeout_add_seconds (120, dhcp6_restart_cb, self);
+ dhcp_schedule_restart (self, AF_INET6, "device has IP addresses");
return;
}
@@ -5320,16 +5532,23 @@ dhcp6_fail (NMDevice *self, gboolean timeout)
* retry DHCP again.
*/
if (nm_device_uses_assumed_connection (self)) {
- _LOGI (LOGD_DHCP6, "Scheduling DHCPv6 restart because the connection is assumed");
- priv->dhcp6_restart_id = g_timeout_add_seconds (120, dhcp6_restart_cb, self);
+ dhcp_schedule_restart (self, AF_INET6, "connection is assumed");
return;
}
- if (timeout || (priv->ip6_state == IP_CONF))
+ if ( priv->dhcp6.num_tries_left == DHCP_NUM_TRIES_MAX
+ && (timeout || (priv->ip6_state == IP_CONF)))
nm_device_activate_schedule_ip6_config_timeout (self);
- else if (priv->ip6_state == IP_DONE)
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
- else
+ else if (priv->ip6_state == IP_DONE) {
+ /* Don't fail immediately when the lease expires but try to
+ * restart DHCP for a predefined number of times.
+ */
+ if (priv->dhcp6.num_tries_left) {
+ priv->dhcp6.num_tries_left--;
+ dhcp_schedule_restart (self, AF_INET6, "lease expired");
+ } else
+ nm_device_ip_method_failed (self, AF_INET6, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
+ } else
g_warn_if_reached ();
} else {
/* not a hard failure; just live with the RA info */
@@ -5343,7 +5562,7 @@ dhcp6_timeout (NMDevice *self, NMDhcpClient *client)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED)
+ if (priv->dhcp6.mode == NM_RDISC_DHCP_LEVEL_MANAGED)
dhcp6_fail (self, TRUE);
else {
/* not a hard failure; just live with the RA info */
@@ -5378,32 +5597,34 @@ dhcp6_state_changed (NMDhcpClient *client,
*/
if ( ip6_config
&& event_id
- && priv->dhcp6_event_id
- && !strcmp (event_id, priv->dhcp6_event_id)) {
+ && priv->dhcp6.event_id
+ && !strcmp (event_id, priv->dhcp6.event_id)) {
for (i = 0; i < nm_ip6_config_get_num_addresses (ip6_config); i++) {
- nm_ip6_config_add_address (priv->dhcp6_ip6_config,
+ nm_ip6_config_add_address (priv->dhcp6.ip6_config,
nm_ip6_config_get_address (ip6_config, i));
}
} else {
- g_clear_object (&priv->dhcp6_ip6_config);
- g_clear_pointer (&priv->dhcp6_event_id, g_free);
+ g_clear_object (&priv->dhcp6.ip6_config);
+ g_clear_pointer (&priv->dhcp6.event_id, g_free);
if (ip6_config) {
- priv->dhcp6_ip6_config = g_object_ref (ip6_config);
- priv->dhcp6_event_id = g_strdup (event_id);
- nm_dhcp6_config_set_options (priv->dhcp6_config, options);
+ priv->dhcp6.ip6_config = g_object_ref (ip6_config);
+ priv->dhcp6.event_id = g_strdup (event_id);
+ nm_dhcp6_config_set_options (priv->dhcp6.config, options);
_notify (self, PROP_DHCP6_CONFIG);
}
}
+ priv->dhcp6.num_tries_left = DHCP_NUM_TRIES_MAX;
+
if (priv->ip6_state == IP_CONF) {
- if (priv->dhcp6_ip6_config == NULL) {
- /* FIXME: Initial DHCP failed; should we fail IPv6 entirely then? */
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED);
+ if (priv->dhcp6.ip6_config == NULL) {
+ nm_device_ip_method_failed (self, AF_INET6, NM_DEVICE_STATE_REASON_DHCP_FAILED);
break;
}
nm_device_activate_schedule_ip6_config_result (self);
} else if (priv->ip6_state == IP_DONE)
- dhcp6_lease_change (self);
+ if (!dhcp6_lease_change (self))
+ dhcp6_fail (self, FALSE);
break;
case NM_DHCP_STATE_TIMEOUT:
dhcp6_timeout (self, client);
@@ -5418,7 +5639,7 @@ dhcp6_state_changed (NMDhcpClient *client,
* may exit right after getting a response from the server. That's
* normal. In that case we just ignore the exit.
*/
- if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_OTHERCONF)
+ if (priv->dhcp6.mode == NM_RDISC_DHCP_LEVEL_OTHERCONF)
break;
/* Otherwise, fall through */
case NM_DHCP_STATE_FAIL:
@@ -5454,7 +5675,7 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection)
g_return_val_if_fail (ll_addr, FALSE);
- priv->dhcp6_client = nm_dhcp_manager_start_ip6 (nm_dhcp_manager_get (),
+ priv->dhcp6.client = nm_dhcp_manager_start_ip6 (nm_dhcp_manager_get (),
nm_device_get_ip_iface (self),
nm_device_get_ip_ifindex (self),
tmp,
@@ -5465,19 +5686,19 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection)
nm_setting_ip_config_get_dhcp_hostname (s_ip6),
priv->dhcp_timeout,
priv->dhcp_anycast_address,
- (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE,
+ (priv->dhcp6.mode == NM_RDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE,
nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6)));
if (tmp)
g_byte_array_free (tmp, TRUE);
- if (priv->dhcp6_client) {
- priv->dhcp6_state_sigid = g_signal_connect (priv->dhcp6_client,
+ if (priv->dhcp6.client) {
+ priv->dhcp6.state_sigid = g_signal_connect (priv->dhcp6.client,
NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
G_CALLBACK (dhcp6_state_changed),
self);
}
- return !!priv->dhcp6_client;
+ return !!priv->dhcp6.client;
}
static gboolean
@@ -5487,12 +5708,12 @@ dhcp6_start (NMDevice *self, gboolean wait_for_ll, NMDeviceStateReason *reason)
NMConnection *connection;
NMSettingIPConfig *s_ip6;
- nm_exported_object_clear_and_unexport (&priv->dhcp6_config);
- priv->dhcp6_config = nm_dhcp6_config_new ();
+ nm_exported_object_clear_and_unexport (&priv->dhcp6.config);
+ priv->dhcp6.config = nm_dhcp6_config_new ();
- g_warn_if_fail (priv->dhcp6_ip6_config == NULL);
- g_clear_object (&priv->dhcp6_ip6_config);
- g_clear_pointer (&priv->dhcp6_event_id, g_free);
+ g_warn_if_fail (priv->dhcp6.ip6_config == NULL);
+ g_clear_object (&priv->dhcp6.ip6_config);
+ g_clear_pointer (&priv->dhcp6.event_id, g_free);
connection = nm_device_get_applied_connection (self);
g_assert (connection);
@@ -5528,7 +5749,7 @@ nm_device_dhcp6_renew (NMDevice *self, gboolean release)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- g_return_val_if_fail (priv->dhcp6_client != NULL, FALSE);
+ g_return_val_if_fail (priv->dhcp6.client != NULL, FALSE);
_LOGI (LOGD_DHCP6, "DHCPv6 lease renewal requested");
@@ -5659,13 +5880,13 @@ check_and_add_ipv6ll_addr (NMDevice *self)
return;
}
- if (!nm_device_get_ip_iface_identifier (self, &iid)) {
+ if (!nm_device_get_ip_iface_identifier (self, &iid, TRUE)) {
_LOGW (LOGD_IP6, "linklocal6: failed to get interface identifier; IPv6 cannot continue");
return;
}
_LOGD (LOGD_IP6, "linklocal6: using EUI-64 identifier to generate IPv6LL address");
- nm_utils_ipv6_addr_set_interface_identfier (&lladdr, iid);
+ nm_utils_ipv6_addr_set_interface_identifier (&lladdr, iid);
}
_LOGD (LOGD_IP6, "linklocal6: adding IPv6LL address %s", nm_utils_inet6_ntop (&lladdr, NULL));
@@ -5828,7 +6049,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self)
address.preferred = discovered_address->preferred;
if (address.preferred > address.lifetime)
address.preferred = address.lifetime;
- address.source = NM_IP_CONFIG_SOURCE_RDISC;
+ address.addr_source = NM_IP_CONFIG_SOURCE_RDISC;
address.n_ifa_flags = ifa_flags;
nm_ip6_config_add_address (priv->ac_ip6_config, &address);
@@ -5853,7 +6074,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self)
nm_assert (discovered_route->plen <= 128);
route.plen = discovered_route->plen;
route.gateway = discovered_route->gateway;
- route.source = NM_IP_CONFIG_SOURCE_RDISC;
+ route.rt_source = NM_IP_CONFIG_SOURCE_RDISC;
route.metric = nm_device_get_ip6_route_metric (self);
nm_ip6_config_add_route (priv->ac_ip6_config, &route);
@@ -5886,15 +6107,15 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self)
if (changed & NM_RDISC_CONFIG_DHCP_LEVEL) {
dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, TRUE);
- priv->dhcp6_mode = rdisc->dhcp_level;
- if (priv->dhcp6_mode != NM_RDISC_DHCP_LEVEL_NONE) {
+ priv->dhcp6.mode = rdisc->dhcp_level;
+ if (priv->dhcp6.mode != NM_RDISC_DHCP_LEVEL_NONE) {
NMDeviceStateReason reason;
_LOGD (LOGD_DEVICE | LOGD_DHCP6,
"Activation: Stage 3 of 5 (IP Configure Start) starting DHCPv6"
" as requested by IPv6 router...");
if (!dhcp6_start (self, FALSE, &reason)) {
- if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) {
+ if (priv->dhcp6.mode == NM_RDISC_DHCP_LEVEL_MANAGED) {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
return;
}
@@ -5944,10 +6165,7 @@ addrconf6_start_with_link_ready (NMDevice *self)
g_assert (priv->rdisc);
- if (nm_platform_link_get_ipv6_token (NM_PLATFORM_GET, priv->ifindex, &iid)) {
- _LOGD (LOGD_IP6, "addrconf6: IPv6 tokenized identifier present");
- nm_rdisc_set_iid (priv->rdisc, iid);
- } else if (nm_device_get_ip_iface_identifier (self, &iid)) {
+ if (nm_device_get_ip_iface_identifier (self, &iid, FALSE)) {
_LOGD (LOGD_IP6, "addrconf6: using the device EUI-64 identifier");
nm_rdisc_set_iid (priv->rdisc, iid);
} else {
@@ -6255,7 +6473,8 @@ act_stage3_ip6_config_start (NMDevice *self,
}
}
- priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_NONE;
+ priv->dhcp6.mode = NM_RDISC_DHCP_LEVEL_NONE;
+ priv->dhcp6.num_tries_left = DHCP_NUM_TRIES_MAX;
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
@@ -6303,7 +6522,7 @@ act_stage3_ip6_config_start (NMDevice *self,
} else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) {
ret = linklocal6_start (self);
} else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) {
- priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_MANAGED;
+ priv->dhcp6.mode = NM_RDISC_DHCP_LEVEL_MANAGED;
if (!dhcp6_start (self, TRUE, reason)) {
/* IPv6 might be disabled; allow IPv4 to proceed */
ret = NM_ACT_STAGE_RETURN_STOP;
@@ -6580,7 +6799,6 @@ act_stage4_ip4_config_timeout (NMDevice *self, NMDeviceStateReason *reason)
return NM_ACT_STAGE_RETURN_SUCCESS;
}
-
/*
* nm_device_activate_stage4_ip4_config_timeout
*
@@ -6608,7 +6826,6 @@ activate_stage4_ip4_config_timeout (NMDevice *self)
check_ip_failed (self, FALSE);
}
-
/*
* nm_device_activate_schedule_ip4_config_timeout
*
@@ -6628,7 +6845,6 @@ nm_device_activate_schedule_ip4_config_timeout (NMDevice *self)
activation_source_schedule (self, activate_stage4_ip4_config_timeout, AF_INET);
}
-
static NMActStageReturn
act_stage4_ip6_config_timeout (NMDevice *self, NMDeviceStateReason *reason)
{
@@ -6640,7 +6856,6 @@ act_stage4_ip6_config_timeout (NMDevice *self, NMDeviceStateReason *reason)
return NM_ACT_STAGE_RETURN_SUCCESS;
}
-
/*
* activate_stage4_ip6_config_timeout
*
@@ -6668,7 +6883,6 @@ activate_stage4_ip6_config_timeout (NMDevice *self)
check_ip_failed (self, FALSE);
}
-
/*
* nm_device_activate_schedule_ip6_config_timeout
*
@@ -6875,7 +7089,7 @@ activate_stage5_ip4_config_commit (NMDevice *self)
/* NULL to use the existing priv->dev_ip4_config */
if (!ip4_config_merge_and_apply (self, NULL, TRUE, &reason)) {
_LOGD (LOGD_DEVICE | LOGD_IP4, "Activation: Stage 5 of 5 (IPv4 Commit) failed");
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
+ nm_device_ip_method_failed (self, AF_INET, reason);
return;
}
@@ -6893,7 +7107,7 @@ activate_stage5_ip4_config_commit (NMDevice *self)
/* If IPv4 wasn't the first to complete, and DHCP was used, then ensure
* dispatcher scripts get the DHCP lease information.
*/
- if ( priv->dhcp4_client
+ if ( priv->dhcp4.client
&& nm_device_activate_ip4_state_in_conf (self)
&& (nm_device_get_state (self) > NM_DEVICE_STATE_IP_CONFIG)) {
/* Notify dispatcher scripts of new DHCP4 config */
@@ -6944,6 +7158,64 @@ nm_device_activate_ip4_state_in_wait (NMDevice *self)
return NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_WAIT;
}
+gboolean
+nm_device_activate_ip4_state_done (NMDevice *self)
+{
+ g_return_val_if_fail (self != NULL, FALSE);
+ return NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_DONE;
+}
+
+/*
+ * Returns a NMIP6Config containing NM-configured addresses which
+ * have the tentative flag, or NULL if none is present.
+ */
+static NMIP6Config *
+dad6_get_pending_addresses (NMDevice *self)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ NMIP6Config *confs[] = { priv->ac_ip6_config,
+ priv->dhcp6.ip6_config,
+ priv->con_ip6_config,
+ priv->wwan_ip6_config };
+ const NMPlatformIP6Address *addr, *pl_addr;
+ NMIP6Config *dad6_config = NULL;
+ guint i, j, num;
+ int ifindex;
+
+ ifindex = nm_device_get_ip_ifindex (self);
+ g_return_val_if_fail (ifindex > 0, NULL);
+
+ /* We are interested only in addresses that we have explicitly configured,
+ * not in externally added ones.
+ */
+ for (i = 0; i < G_N_ELEMENTS (confs); i++) {
+ if (confs[i]) {
+ num = nm_ip6_config_get_num_addresses (confs[i]);
+ for (j = 0; j < num; j++) {
+ addr = nm_ip6_config_get_address (confs[i], j);
+ pl_addr = nm_platform_ip6_address_get (NM_PLATFORM_GET,
+ ifindex,
+ addr->address,
+ addr->plen);
+ if ( pl_addr
+ && NM_FLAGS_HAS (pl_addr->n_ifa_flags, IFA_F_TENTATIVE)
+ && !NM_FLAGS_HAS (pl_addr->n_ifa_flags, IFA_F_DADFAILED)
+ && !NM_FLAGS_HAS (pl_addr->n_ifa_flags, IFA_F_OPTIMISTIC)) {
+ _LOGt (LOGD_DEVICE, "IPv6 DAD: pending address %s",
+ nm_platform_ip6_address_to_string (pl_addr, NULL, 0));
+
+ if (!dad6_config)
+ dad6_config = nm_ip6_config_new (ifindex);
+
+ nm_ip6_config_add_address (dad6_config, pl_addr);
+ }
+ }
+ }
+ }
+
+ return dad6_config;
+}
+
static void
activate_stage5_ip6_config_commit (NMDevice *self)
{
@@ -6967,9 +7239,9 @@ activate_stage5_ip6_config_commit (NMDevice *self)
}
if (ip6_config_merge_and_apply (self, TRUE, &reason)) {
- if ( priv->dhcp6_mode != NM_RDISC_DHCP_LEVEL_NONE
+ if ( priv->dhcp6.mode != NM_RDISC_DHCP_LEVEL_NONE
&& priv->ip6_state == IP_CONF) {
- if (priv->dhcp6_ip6_config) {
+ if (priv->dhcp6.ip6_config) {
/* If IPv6 wasn't the first IP to complete, and DHCP was used,
* then ensure dispatcher scripts get the DHCP lease information.
*/
@@ -6985,16 +7257,23 @@ activate_stage5_ip6_config_commit (NMDevice *self)
return;
}
}
-
nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE);
nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE);
- /* Enter the IP_CHECK state if this is the first method to complete */
- priv->ip6_state = IP_DONE;
- check_ip_done (self);
+ /* Check if we have to wait for DAD */
+ if (priv->ip6_state == IP_CONF && !priv->dad6_ip6_config) {
+ priv->dad6_ip6_config = dad6_get_pending_addresses (self);
+ if (priv->dad6_ip6_config) {
+ _LOGD (LOGD_DEVICE | LOGD_IP6, "IPv6 DAD: waiting termination");
+ } else {
+ /* No tentative addresses, proceed right away */
+ priv->ip6_state = IP_DONE;
+ check_ip_done (self);
+ }
+ }
} else {
_LOGW (LOGD_DEVICE | LOGD_IP6, "Activation: Stage 5 of 5 (IPv6 Commit) failed");
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
+ nm_device_ip_method_failed (self, AF_INET6, reason);
}
}
@@ -7028,6 +7307,13 @@ nm_device_activate_ip6_state_in_wait (NMDevice *self)
return NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_WAIT;
}
+gboolean
+nm_device_activate_ip6_state_done (NMDevice *self)
+{
+ g_return_val_if_fail (self != NULL, FALSE);
+ return NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_DONE;
+}
+
static void
clear_act_request (NMDevice *self)
{
@@ -7192,6 +7478,7 @@ _cleanup_ip6_pre (NMDevice *self, CleanupType cleanup_type)
if (nm_clear_g_source (&priv->queued_ip6_config_id))
_LOGD (LOGD_DEVICE, "clearing queued IP6 config change");
+ g_clear_object (&priv->dad6_ip6_config);
dhcp6_cleanup (self, cleanup_type, FALSE);
linklocal6_cleanup (self);
addrconf6_cleanup (self);
@@ -7939,7 +8226,7 @@ nm_device_get_dhcp4_config (NMDevice *self)
{
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
- return NM_DEVICE_GET_PRIVATE (self)->dhcp4_config;
+ return NM_DEVICE_GET_PRIVATE (self)->dhcp4.config;
}
NMIP4Config *
@@ -8256,7 +8543,7 @@ nm_device_get_dhcp6_config (NMDevice *self)
{
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
- return NM_DEVICE_GET_PRIVATE (self)->dhcp6_config;
+ return NM_DEVICE_GET_PRIVATE (self)->dhcp6.config;
}
NMIP6Config *
@@ -8564,6 +8851,7 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
gboolean device_is_up = FALSE;
+ NMDeviceCapabilities capabilities;
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
@@ -8574,6 +8862,10 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware)
return FALSE;
}
+ /* Store carrier immediately. */
+ if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT))
+ check_carrier (self);
+
device_is_up = nm_device_is_up (self);
if (block && !device_is_up) {
int ifindex = nm_device_get_ip_ifindex (self);
@@ -8595,6 +8887,13 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware)
return FALSE;
}
+ /* some ethernet devices fail to report capabilities unless the device
+ * is up. Re-read the capabilities. */
+ capabilities = 0;
+ if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities)
+ capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self);
+ _add_capabilities (self, capabilities);
+
/* Devices that support carrier detect must be IFF_UP to report carrier
* changes; so after setting the device IFF_UP we must suppress startup
* complete (via a pending action) until either the carrier turns on, or
@@ -8638,10 +8937,6 @@ bring_up (NMDevice *self, gboolean *no_firmware)
result = nm_platform_link_set_up (NM_PLATFORM_GET, ifindex, no_firmware);
- /* Store carrier immediately. */
- if (result && nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT))
- check_carrier (self);
-
return result;
}
@@ -8777,7 +9072,7 @@ capture_lease_config (NMDevice *self,
NMIP6Config **out_ip6_config)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- const GSList *connections, *citer;
+ NMSettingsConnection *const*connections;
guint i;
gboolean dhcp_used = FALSE;
@@ -8810,9 +9105,9 @@ capture_lease_config (NMDevice *self,
if (!dhcp_used)
return;
- connections = nm_connection_provider_get_connections (priv->con_provider);
- for (citer = connections; citer; citer = citer->next) {
- NMConnection *candidate = citer->data;
+ connections = nm_settings_get_connections (priv->settings, NULL);
+ for (i = 0; connections[i]; i++) {
+ NMConnection *candidate = (NMConnection *) connections[i];
const char *method;
if (!nm_device_check_connection_compatible (self, candidate))
@@ -8858,7 +9153,6 @@ update_ip4_config (NMDevice *self, gboolean initial)
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
int ifindex;
gboolean capture_resolv_conf;
- NMDnsManagerResolvConfMode resolv_conf_mode;
/* If a commit is scheduled, this function would potentially interfere with
* it changing IP configurations before they are applied. Postpone the
@@ -8877,8 +9171,8 @@ update_ip4_config (NMDevice *self, gboolean initial)
if (!ifindex)
return;
- resolv_conf_mode = nm_dns_manager_get_resolv_conf_mode (nm_dns_manager_get ());
- capture_resolv_conf = initial && (resolv_conf_mode == NM_DNS_MANAGER_RESOLV_CONF_EXPLICIT);
+ capture_resolv_conf = initial
+ && nm_dns_manager_get_resolv_conf_explicit (nm_dns_manager_get ());
/* IPv4 */
g_clear_object (&priv->ext_ip4_config);
@@ -8949,7 +9243,6 @@ update_ip6_config (NMDevice *self, gboolean initial)
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
int ifindex;
gboolean capture_resolv_conf;
- NMDnsManagerResolvConfMode resolv_conf_mode;
/* If a commit is scheduled, this function would potentially interfere with
* it changing IP configurations before they are applied. Postpone the
@@ -8968,8 +9261,8 @@ update_ip6_config (NMDevice *self, gboolean initial)
if (!ifindex)
return;
- resolv_conf_mode = nm_dns_manager_get_resolv_conf_mode (nm_dns_manager_get ());
- capture_resolv_conf = initial && (resolv_conf_mode == NM_DNS_MANAGER_RESOLV_CONF_EXPLICIT);
+ capture_resolv_conf = initial
+ && nm_dns_manager_get_resolv_conf_explicit (nm_dns_manager_get ());
/* IPv6 */
g_clear_object (&priv->ext_ip6_config);
@@ -8987,8 +9280,8 @@ update_ip6_config (NMDevice *self, gboolean initial)
nm_ip6_config_intersect (priv->con_ip6_config, priv->ext_ip6_config);
if (priv->ac_ip6_config)
nm_ip6_config_intersect (priv->ac_ip6_config, priv->ext_ip6_config);
- if (priv->dhcp6_ip6_config)
- nm_ip6_config_intersect (priv->dhcp6_ip6_config, priv->ext_ip6_config);
+ if (priv->dhcp6.ip6_config)
+ nm_ip6_config_intersect (priv->dhcp6.ip6_config, priv->ext_ip6_config);
if (priv->wwan_ip6_config)
nm_ip6_config_intersect (priv->wwan_ip6_config, priv->ext_ip6_config);
g_slist_foreach (priv->vpn6_configs, _ip6_config_intersect, priv->ext_ip6_config);
@@ -9000,8 +9293,8 @@ update_ip6_config (NMDevice *self, gboolean initial)
nm_ip6_config_subtract (priv->ext_ip6_config, priv->con_ip6_config);
if (priv->ac_ip6_config)
nm_ip6_config_subtract (priv->ext_ip6_config, priv->ac_ip6_config);
- if (priv->dhcp6_ip6_config)
- nm_ip6_config_subtract (priv->ext_ip6_config, priv->dhcp6_ip6_config);
+ if (priv->dhcp6.ip6_config)
+ nm_ip6_config_subtract (priv->ext_ip6_config, priv->dhcp6.ip6_config);
if (priv->wwan_ip6_config)
nm_ip6_config_subtract (priv->ext_ip6_config, priv->wwan_ip6_config);
g_slist_foreach (priv->vpn6_configs, _ip6_config_subtract, priv->ext_ip6_config);
@@ -9041,9 +9334,7 @@ queued_ip4_config_change (gpointer user_data)
return TRUE;
priv->queued_ip4_config_id = 0;
- g_object_ref (self);
update_ip4_config (self, FALSE);
- g_object_unref (self);
set_unmanaged_external_down (self, TRUE);
@@ -9067,16 +9358,15 @@ queued_ip6_config_change (gpointer user_data)
return TRUE;
priv->queued_ip6_config_id = 0;
- g_object_ref (self);
update_ip6_config (self, FALSE);
if ( nm_platform_link_get (NM_PLATFORM_GET, priv->ifindex)
&& priv->state < NM_DEVICE_STATE_DEACTIVATING) {
- /* Handle DAD falures */
+ /* Handle DAD failures */
for (iter = priv->dad6_failed_addrs; iter; iter = g_slist_next (iter)) {
NMPlatformIP6Address *addr = iter->data;
- if (addr->source >= NM_IP_CONFIG_SOURCE_USER)
+ if (addr->addr_source >= NM_IP_CONFIG_SOURCE_USER)
continue;
_LOGI (LOGD_IP6, "ipv6: duplicate address check failed for the %s address",
@@ -9103,7 +9393,18 @@ queued_ip6_config_change (gpointer user_data)
g_slist_free_full (priv->dad6_failed_addrs, g_free);
priv->dad6_failed_addrs = NULL;
- g_object_unref (self);
+ /* Check if DAD is still pending */
+ if ( priv->ip6_state == IP_CONF
+ && priv->dad6_ip6_config
+ && priv->ext_ip6_config_captured) {
+ if (!nm_ip6_config_has_any_dad_pending (priv->ext_ip6_config_captured,
+ priv->dad6_ip6_config)) {
+ _LOGD (LOGD_DEVICE | LOGD_IP6, "IPv6 DAD terminated");
+ g_clear_object (&priv->dad6_ip6_config);
+ priv->ip6_state = IP_DONE;
+ check_ip_done (self);
+ }
+ }
set_unmanaged_external_down (self, TRUE);
@@ -9261,6 +9562,9 @@ _get_managed_by_flags(NMUnmanagedFlags flags, NMUnmanagedFlags mask, gboolean fo
/* configuration from udev or nm-config overwrites the by-default flag
* which is based on the device type. */
flags &= ~NM_UNMANAGED_BY_DEFAULT;
+
+ /* configuration from udev overwrites external-down */
+ flags &= ~NM_UNMANAGED_EXTERNAL_DOWN;
}
if ( NM_FLAGS_HAS (mask, NM_UNMANAGED_IS_SLAVE)
@@ -9499,7 +9803,7 @@ nm_device_set_unmanaged_by_flags_queue (NMDevice *self,
}
void
-nm_device_set_unmanaged_by_user_config (NMDevice *self, const GSList *unmanaged_specs)
+nm_device_set_unmanaged_by_user_settings (NMDevice *self, const GSList *unmanaged_specs)
{
NMDevicePrivate *priv;
gboolean unmanaged;
@@ -9851,50 +10155,45 @@ void
nm_device_recheck_available_connections (NMDevice *self)
{
NMDevicePrivate *priv;
- const GSList *connections, *iter;
+ NMSettingsConnection *const*connections;
gboolean changed = FALSE;
GHashTableIter h_iter;
NMConnection *connection;
+ guint i;
+ gs_unref_hashtable GHashTable *prune_list = NULL;
g_return_if_fail (NM_IS_DEVICE (self));
priv = NM_DEVICE_GET_PRIVATE(self);
- if (priv->con_provider) {
- gs_unref_hashtable GHashTable *prune_list = NULL;
-
- if (g_hash_table_size (priv->available_connections) > 0) {
- prune_list = g_hash_table_new (g_direct_hash, g_direct_equal);
- g_hash_table_iter_init (&h_iter, priv->available_connections);
- while (g_hash_table_iter_next (&h_iter, (gpointer *) &connection, NULL))
- g_hash_table_add (prune_list, connection);
- }
-
- connections = nm_connection_provider_get_connections (priv->con_provider);
- for (iter = connections; iter; iter = g_slist_next (iter)) {
- connection = NM_CONNECTION (iter->data);
-
- if (nm_device_check_connection_available (self,
- connection,
- NM_DEVICE_CHECK_CON_AVAILABLE_NONE,
- NULL)) {
- if (available_connections_add (self, connection))
- changed = TRUE;
- if (prune_list)
- g_hash_table_remove (prune_list, connection);
- }
+ if (g_hash_table_size (priv->available_connections) > 0) {
+ prune_list = g_hash_table_new (g_direct_hash, g_direct_equal);
+ g_hash_table_iter_init (&h_iter, priv->available_connections);
+ while (g_hash_table_iter_next (&h_iter, (gpointer *) &connection, NULL))
+ g_hash_table_add (prune_list, connection);
+ }
+
+ connections = nm_settings_get_connections (priv->settings, NULL);
+ for (i = 0; connections[i]; i++) {
+ connection = (NMConnection *) connections[i];
+
+ if (nm_device_check_connection_available (self,
+ connection,
+ NM_DEVICE_CHECK_CON_AVAILABLE_NONE,
+ NULL)) {
+ if (available_connections_add (self, connection))
+ changed = TRUE;
+ if (prune_list)
+ g_hash_table_remove (prune_list, connection);
}
+ }
- if (prune_list) {
- g_hash_table_iter_init (&h_iter, prune_list);
- while (g_hash_table_iter_next (&h_iter, (gpointer *) &connection, NULL)) {
- if (available_connections_del (self, connection))
- changed = TRUE;
- }
+ if (prune_list) {
+ g_hash_table_iter_init (&h_iter, prune_list);
+ while (g_hash_table_iter_next (&h_iter, (gpointer *) &connection, NULL)) {
+ if (available_connections_del (self, connection))
+ changed = TRUE;
}
- } else {
- if (available_connections_del_all (self))
- changed = TRUE;
}
if (changed)
@@ -9955,10 +10254,9 @@ nm_device_get_best_connection (NMDevice *self,
}
static void
-cp_connection_added_or_updated (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
+cp_connection_added_or_updated (NMDevice *self, NMConnection *connection)
{
gboolean changed;
- NMDevice *self = user_data;
g_return_if_fail (NM_IS_DEVICE (self));
g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection));
@@ -9978,6 +10276,18 @@ cp_connection_added_or_updated (NMConnectionProvider *cp, NMConnection *connecti
}
static void
+cp_connection_added (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
+{
+ cp_connection_added_or_updated (user_data, connection);
+}
+
+static void
+cp_connection_updated (NMConnectionProvider *cp, NMConnection *connection, gboolean by_user, gpointer user_data)
+{
+ cp_connection_added_or_updated (user_data, connection);
+}
+
+static void
cp_connection_removed (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
{
NMDevice *self = user_data;
@@ -10184,6 +10494,7 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type)
g_clear_object (&priv->ext_ip6_config_captured);
g_clear_object (&priv->wwan_ip6_config);
g_clear_object (&priv->ip6_config);
+ g_clear_object (&priv->dad6_ip6_config);
g_slist_free_full (priv->vpn4_configs, g_object_unref);
priv->vpn4_configs = NULL;
@@ -10300,7 +10611,7 @@ find_dhcp4_address (NMDevice *self)
for (i = 0; i < n; i++) {
const NMPlatformIP4Address *a = nm_ip4_config_get_address (priv->ip4_config, i);
- if (a->source == NM_IP_CONFIG_SOURCE_DHCP)
+ if (a->addr_source == NM_IP_CONFIG_SOURCE_DHCP)
return g_strdup (nm_utils_inet4_ntop (a->address, NULL));
}
return NULL;
@@ -10364,11 +10675,11 @@ nm_device_spawn_iface_helper (NMDevice *self)
if (nm_setting_ip_config_get_may_fail (s_ip4) == FALSE)
g_ptr_array_add (argv, g_strdup ("--dhcp4-required"));
- if (priv->dhcp4_client) {
+ if (priv->dhcp4.client) {
const char *hostname, *fqdn;
GBytes *client_id;
- client_id = nm_dhcp_client_get_client_id (priv->dhcp4_client);
+ client_id = nm_dhcp_client_get_client_id (priv->dhcp4.client);
if (client_id) {
g_ptr_array_add (argv, g_strdup ("--dhcp4-clientid"));
hex_client_id = bin2hexstr (g_bytes_get_data (client_id, NULL),
@@ -10376,13 +10687,13 @@ nm_device_spawn_iface_helper (NMDevice *self)
g_ptr_array_add (argv, hex_client_id);
}
- hostname = nm_dhcp_client_get_hostname (priv->dhcp4_client);
+ hostname = nm_dhcp_client_get_hostname (priv->dhcp4.client);
if (hostname) {
g_ptr_array_add (argv, g_strdup ("--dhcp4-hostname"));
g_ptr_array_add (argv, g_strdup (hostname));
}
- fqdn = nm_dhcp_client_get_fqdn (priv->dhcp4_client);
+ fqdn = nm_dhcp_client_get_fqdn (priv->dhcp4.client);
if (fqdn) {
g_ptr_array_add (argv, g_strdup ("--dhcp4-fqdn"));
g_ptr_array_add (argv, g_strdup (fqdn));
@@ -10412,7 +10723,7 @@ nm_device_spawn_iface_helper (NMDevice *self)
g_ptr_array_add (argv, g_strdup ("--slaac-tempaddr"));
g_ptr_array_add (argv, g_strdup_printf ("%d", priv->rdisc_use_tempaddr));
- if (nm_device_get_ip_iface_identifier (self, &iid)) {
+ if (nm_device_get_ip_iface_identifier (self, &iid, FALSE)) {
g_ptr_array_add (argv, g_strdup ("--iid"));
hex_iid = bin2hexstr ((const char *) iid.id_u8, sizeof (NMUtilsIPv6IfaceId));
g_ptr_array_add (argv, hex_iid);
@@ -10720,11 +11031,9 @@ _set_state_full (NMDevice *self,
case NM_DEVICE_STATE_DEACTIVATING:
_cancel_activation (self);
- if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
- /* We cache the ignore_carrier state to not react on config-reloads while the connection
- * is active. But on deactivating, reset the ignore-carrier flag to the current state. */
- priv->ignore_carrier = nm_config_data_get_ignore_carrier (NM_CONFIG_GET_DATA, self);
- }
+ /* We cache the ignore_carrier state to not react on config-reloads while the connection
+ * is active. But on deactivating, reset the ignore-carrier flag to the current state. */
+ priv->ignore_carrier = nm_config_data_get_ignore_carrier (NM_CONFIG_GET_DATA, self);
if (quitting) {
nm_dispatcher_call_sync (DISPATCHER_ACTION_PRE_DOWN,
@@ -11007,7 +11316,6 @@ nm_device_update_hw_address (NMDevice *self)
int ifindex = nm_device_get_ifindex (self);
const guint8 *hwaddr;
gsize hwaddrlen = 0;
- static const guint8 zero_hwaddr[ETH_ALEN];
if (ifindex <= 0)
return;
@@ -11015,7 +11323,7 @@ nm_device_update_hw_address (NMDevice *self)
hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &hwaddrlen);
if ( priv->type == NM_DEVICE_TYPE_ETHERNET
- && nm_utils_hwaddr_matches (hwaddr, hwaddrlen, zero_hwaddr, sizeof (zero_hwaddr)))
+ && nm_utils_hwaddr_matches (hwaddr, hwaddrlen, nm_ip_addr_zero.addr_eth, sizeof (nm_ip_addr_zero.addr_eth)))
hwaddrlen = 0;
if (hwaddrlen) {
@@ -11280,33 +11588,31 @@ constructed (GObject *object)
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMPlatform *platform;
- platform = nm_platform_get ();
-
if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities)
priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self);
/* Watch for external IP config changes */
+ platform = NM_PLATFORM_GET;
g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (device_ipx_changed), self);
g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (device_ipx_changed), self);
g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (device_ipx_changed), self);
g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (device_ipx_changed), self);
g_signal_connect (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (link_changed_cb), self);
- priv->con_provider = nm_connection_provider_get ();
- g_assert (priv->con_provider);
- g_signal_connect (priv->con_provider,
- NM_CP_SIGNAL_CONNECTION_ADDED,
- G_CALLBACK (cp_connection_added_or_updated),
- self);
+ priv->settings = g_object_ref (NM_SETTINGS_GET);
+ g_assert (priv->settings);
- g_signal_connect (priv->con_provider,
- NM_CP_SIGNAL_CONNECTION_REMOVED,
- G_CALLBACK (cp_connection_removed),
+ g_signal_connect (priv->settings,
+ NM_SETTINGS_SIGNAL_CONNECTION_ADDED,
+ G_CALLBACK (cp_connection_added),
self);
-
- g_signal_connect (priv->con_provider,
- NM_CP_SIGNAL_CONNECTION_UPDATED,
- G_CALLBACK (cp_connection_added_or_updated),
+ g_signal_connect (priv->settings,
+ NM_SETTINGS_SIGNAL_CONNECTION_UPDATED,
+ G_CALLBACK (cp_connection_updated),
+ self);
+ g_signal_connect (priv->settings,
+ NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
+ G_CALLBACK (cp_connection_removed),
self);
G_OBJECT_CLASS (nm_device_parent_class)->constructed (object);
@@ -11323,7 +11629,7 @@ dispose (GObject *object)
_LOGD (LOGD_DEVICE, "disposing");
- platform = nm_platform_get ();
+ platform = NM_PLATFORM_GET;
g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (device_ipx_changed), self);
g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (link_changed_cb), self);
@@ -11332,7 +11638,7 @@ dispose (GObject *object)
arp_cleanup (self);
- g_signal_handlers_disconnect_by_func (nm_config_get (), config_changed_update_ignore_carrier, self);
+ nm_clear_g_signal_handler (nm_config_get (), &priv->ignore_carrier_id);
dispatcher_cleanup (self);
@@ -11355,10 +11661,10 @@ dispose (GObject *object)
link_disconnect_action_cancel (self);
- if (priv->con_provider) {
- g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_added_or_updated, self);
- g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_removed, self);
- priv->con_provider = NULL;
+ if (priv->settings) {
+ g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_added, self);
+ g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_updated, self);
+ g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_removed, self);
}
available_connections_del_all (self);
@@ -11416,6 +11722,11 @@ finalize (GObject *object)
g_hash_table_unref (priv->available_connections);
G_OBJECT_CLASS (nm_device_parent_class)->finalize (object);
+
+ /* for testing, NMDeviceTest does not invoke NMDevice::constructed,
+ * and thus @settings might be unset. */
+ if (priv->settings)
+ g_object_unref (priv->settings);
}
static void
@@ -11447,11 +11758,11 @@ set_property (GObject *object, guint prop_id,
break;
case PROP_DRIVER_VERSION:
g_free (priv->driver_version);
- priv->driver_version = g_strdup (g_value_get_string (value));
+ priv->driver_version = g_value_dup_string (value);
break;
case PROP_FIRMWARE_VERSION:
g_free (priv->firmware_version);
- priv->firmware_version = g_strdup (g_value_get_string (value));
+ priv->firmware_version = g_value_dup_string (value);
break;
case PROP_MTU:
priv->mtu = g_value_get_uint (value);
@@ -11588,13 +11899,13 @@ get_property (GObject *object, guint prop_id,
nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip4_config : NULL);
break;
case PROP_DHCP4_CONFIG:
- nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp4_config : NULL);
+ nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp4.config : NULL);
break;
case PROP_IP6_CONFIG:
nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip6_config : NULL);
break;
case PROP_DHCP6_CONFIG:
- nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp6_config : NULL);
+ nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp6.config : NULL);
break;
case PROP_STATE:
g_value_set_uint (value, priv->state);
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 2180439631..5f1a168352 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -26,7 +26,6 @@
#include "nm-exported-object.h"
#include "nm-dbus-interface.h"
-#include "nm-default.h"
#include "nm-connection.h"
#include "nm-rfkill-manager.h"
#include "NetworkManagerUtils.h"
@@ -493,7 +492,7 @@ void nm_device_set_unmanaged_by_flags_queue (NMDevice *self,
NMUnmanagedFlags flags,
NMUnmanFlagOp set_op,
NMDeviceStateReason reason);
-void nm_device_set_unmanaged_by_user_config (NMDevice *self, const GSList *unmanaged_specs);
+void nm_device_set_unmanaged_by_user_settings (NMDevice *self, const GSList *unmanaged_specs);
void nm_device_set_unmanaged_by_user_udev (NMDevice *self);
void nm_device_set_unmanaged_by_quitting (NMDevice *device);
diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c
index 60842c18ab..fd71899622 100644
--- a/src/devices/team/nm-device-team.c
+++ b/src/devices/team/nm-device-team.c
@@ -45,12 +45,18 @@ G_DEFINE_TYPE (NMDeviceTeam, nm_device_team, NM_TYPE_DEVICE)
#define NM_DEVICE_TEAM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_TEAM, NMDeviceTeamPrivate))
+NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceTeam,
+ PROP_CONFIG,
+);
+
typedef struct {
struct teamdctl *tdc;
GPid teamd_pid;
guint teamd_process_watch;
guint teamd_timeout;
guint teamd_dbus_watch;
+ gboolean teamd_dbus_name_owned;
+ char *config;
} NMDeviceTeamPrivate;
static gboolean teamd_start (NMDevice *device, NMSettingTeam *s_team);
@@ -148,6 +154,27 @@ ensure_teamd_connection (NMDevice *device)
}
static void
+teamd_read_config (NMDevice *device)
+{
+ NMDeviceTeam *self = NM_DEVICE_TEAM (device);
+ NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self);
+ char *config = NULL;
+ int err;
+
+ if (priv->tdc) {
+ err = teamdctl_config_get_raw_direct (priv->tdc, &config);
+ if (err)
+ _LOGI (LOGD_TEAM, "failed to read teamd config (err=%d)", err);
+ }
+
+ if (!nm_streq0 (config, priv->config)) {
+ g_free (priv->config);
+ priv->config = g_strdup (config);
+ _notify (self, PROP_CONFIG);
+ }
+}
+
+static void
update_connection (NMDevice *device, NMConnection *connection)
{
NMDeviceTeam *self = NM_DEVICE_TEAM (device);
@@ -158,19 +185,12 @@ update_connection (NMDevice *device, NMConnection *connection)
s_team = (NMSettingTeam *) nm_setting_team_new ();
nm_connection_add_setting (connection, (NMSetting *) s_team);
}
- g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, NULL, NULL);
- if (priv->tdc) {
- const char *config = NULL;
- int err;
+ /* Read the configuration only if not already set */
+ if (!priv->config && ensure_teamd_connection (device))
+ teamd_read_config (device);
- err = teamdctl_config_get_raw_direct (NM_DEVICE_TEAM_GET_PRIVATE (device)->tdc,
- (char **)&config);
- if (err == 0)
- g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, config, NULL);
- else
- _LOGE (LOGD_TEAM, "failed to read teamd config (err=%d)", err);
- }
+ g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, priv->config, NULL);
}
/******************************************************************/
@@ -279,6 +299,11 @@ teamd_timeout_cb (gpointer user_data)
g_warn_if_fail (nm_device_is_activating (device));
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED);
+ } else {
+ /* Read again the configuration after the timeout since it might
+ * have changed.
+ */
+ teamd_read_config (device);
}
return G_SOURCE_REMOVE;
@@ -296,6 +321,7 @@ teamd_dbus_appeared (GDBusConnection *connection,
gboolean success;
g_return_if_fail (priv->teamd_dbus_watch);
+ priv->teamd_dbus_name_owned = TRUE;
_LOGI (LOGD_TEAM, "teamd appeared on D-Bus");
nm_device_queue_recheck_assume (device);
@@ -330,9 +356,10 @@ teamd_dbus_appeared (GDBusConnection *connection,
*/
success = ensure_teamd_connection (device);
if (nm_device_get_state (device) == NM_DEVICE_STATE_PREPARE) {
- if (success)
+ if (success) {
+ teamd_read_config (device);
nm_device_activate_schedule_stage2_device_config (device);
- else if (!nm_device_uses_assumed_connection (device))
+ } else if (!nm_device_uses_assumed_connection (device))
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED);
}
}
@@ -349,7 +376,7 @@ teamd_dbus_vanished (GDBusConnection *dbus_connection,
g_return_if_fail (priv->teamd_dbus_watch);
- if (!priv->tdc) {
+ if (!priv->teamd_dbus_name_owned) {
/* g_bus_watch_name will always raise an initial signal, to indicate whether the
* name exists/not exists initially. Do not take this as a failure if it hadn't
* previously appeared.
@@ -358,6 +385,8 @@ teamd_dbus_vanished (GDBusConnection *dbus_connection,
return;
}
+ priv->teamd_dbus_name_owned = FALSE;
+
_LOGI (LOGD_TEAM, "teamd vanished from D-Bus");
teamd_cleanup (device, TRUE);
@@ -693,6 +722,23 @@ nm_device_team_new (const char *iface)
}
static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMDeviceTeam *self = NM_DEVICE_TEAM (object);
+ NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self);
+
+ switch (prop_id) {
+ case PROP_CONFIG:
+ g_value_set_string (value, priv->config);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
nm_device_team_init (NMDeviceTeam * self)
{
}
@@ -730,6 +776,7 @@ dispose (GObject *object)
}
teamd_cleanup (device, TRUE);
+ g_clear_pointer (&priv->config, g_free);
G_OBJECT_CLASS (nm_device_team_parent_class)->dispose (object);
}
@@ -746,6 +793,7 @@ nm_device_team_class_init (NMDeviceTeamClass *klass)
object_class->constructed = constructed;
object_class->dispose = dispose;
+ object_class->get_property = get_property;
parent_class->create_and_realize = create_and_realize;
parent_class->get_generic_capabilities = get_generic_capabilities;
@@ -762,6 +810,14 @@ nm_device_team_class_init (NMDeviceTeamClass *klass)
parent_class->enslave_slave = enslave_slave;
parent_class->release_slave = release_slave;
+ obj_properties[PROP_CONFIG] =
+ g_param_spec_string (NM_DEVICE_TEAM_CONFIG, "", "",
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
NMDBUS_TYPE_DEVICE_TEAM_SKELETON,
NULL);
diff --git a/src/devices/team/nm-device-team.h b/src/devices/team/nm-device-team.h
index 0e81afa744..27bd8227db 100644
--- a/src/devices/team/nm-device-team.h
+++ b/src/devices/team/nm-device-team.h
@@ -32,6 +32,9 @@ G_BEGIN_DECLS
#define NM_IS_DEVICE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_TEAM))
#define NM_DEVICE_TEAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass))
+/* Properties */
+#define NM_DEVICE_TEAM_CONFIG "config"
+
typedef NMDevice NMDeviceTeam;
typedef NMDeviceClass NMDeviceTeamClass;
diff --git a/src/devices/tests/test-lldp.c b/src/devices/tests/test-lldp.c
index bff85e6c94..ff6f42a970 100644
--- a/src/devices/tests/test-lldp.c
+++ b/src/devices/tests/test-lldp.c
@@ -33,7 +33,7 @@
#include "test-common.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
/*****************************************************************************/
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index 6d83b82fba..9e511a0982 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -21,13 +21,14 @@
#include "nm-default.h"
+#include "nm-device-wifi.h"
+
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "nm-device.h"
-#include "nm-device-wifi.h"
#include "nm-device-private.h"
#include "nm-utils.h"
#include "NetworkManagerUtils.h"
@@ -45,8 +46,8 @@
#include "nm-platform.h"
#include "nm-auth-utils.h"
#include "nm-settings-connection.h"
+#include "nm-settings.h"
#include "nm-enum-types.h"
-#include "nm-connection-provider.h"
#include "nm-core-internal.h"
#include "nm-config.h"
@@ -1198,7 +1199,7 @@ check_scanning_allowed (NMDeviceWifi *self)
}
static gboolean
-hidden_filter_func (NMConnectionProvider *provider,
+hidden_filter_func (NMSettings *settings,
NMConnection *connection,
gpointer user_data)
{
@@ -1225,12 +1226,12 @@ build_hidden_probe_list (NMDeviceWifi *self)
if (G_UNLIKELY (nullssid == NULL))
nullssid = g_byte_array_new ();
- connections = nm_connection_provider_get_best_connections (nm_connection_provider_get (),
- max_scan_ssids - 1,
- NM_SETTING_WIRELESS_SETTING_NAME,
- NULL,
- hidden_filter_func,
- NULL);
+ connections = nm_settings_get_best_connections (nm_device_get_settings ((NMDevice *) self),
+ max_scan_ssids - 1,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL,
+ hidden_filter_func,
+ NULL);
if (connections && connections->data) {
ssids = g_ptr_array_new_full (max_scan_ssids - 1, (GDestroyNotify) g_byte_array_unref);
g_ptr_array_add (ssids, g_byte_array_ref (nullssid)); /* Add wildcard SSID */
@@ -1457,10 +1458,12 @@ schedule_ap_list_dump (NMDeviceWifi *self)
}
static void
-try_fill_ssid_for_hidden_ap (NMAccessPoint *ap)
+try_fill_ssid_for_hidden_ap (NMDeviceWifi *self,
+ NMAccessPoint *ap)
{
const char *bssid;
- const GSList *connections, *iter;
+ NMSettingsConnection *const*connections;
+ guint i;
g_return_if_fail (nm_ap_get_ssid (ap) == NULL);
@@ -1469,9 +1472,9 @@ try_fill_ssid_for_hidden_ap (NMAccessPoint *ap)
/* Look for this AP's BSSID in the seen-bssids list of a connection,
* and if a match is found, copy over the SSID */
- connections = nm_connection_provider_get_connections (nm_connection_provider_get ());
- for (iter = connections; iter; iter = g_slist_next (iter)) {
- NMConnection *connection = NM_CONNECTION (iter->data);
+ connections = nm_settings_get_connections (nm_device_get_settings ((NMDevice *) self), NULL);
+ for (i = 0; connections[i]; i++) {
+ NMConnection *connection = (NMConnection *) connections[i];
NMSettingWireless *s_wifi;
s_wifi = nm_connection_get_setting_wireless (connection);
@@ -1521,7 +1524,7 @@ supplicant_iface_new_bss_cb (NMSupplicantInterface *iface,
ssid = nm_ap_get_ssid (ap);
if (!ssid || nm_utils_is_empty_ssid (ssid->data, ssid->len)) {
/* Try to fill the SSID from the AP database */
- try_fill_ssid_for_hidden_ap (ap);
+ try_fill_ssid_for_hidden_ap (self, ap);
ssid = nm_ap_get_ssid (ap);
if (ssid && (nm_utils_is_empty_ssid (ssid->data, ssid->len) == FALSE)) {
diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c
index a0c2570996..d0704b4ea9 100644
--- a/src/devices/wifi/nm-wifi-ap.c
+++ b/src/devices/wifi/nm-wifi-ap.c
@@ -42,29 +42,48 @@ typedef struct
char *supplicant_path; /* D-Bus object path of this AP from wpa_supplicant */
/* Scanned or cached values */
- GByteArray * ssid;
- char * address;
- NM80211Mode mode;
- guint8 strength;
- guint32 freq; /* Frequency in MHz; ie 2412 (== 2.412 GHz) */
- guint32 max_bitrate;/* Maximum bitrate of the AP in Kbit/s (ie 54000 Kb/s == 54Mbit/s) */
+ GByteArray * ssid;
+ char * address;
+ NM80211Mode mode;
+ guint8 strength;
+ guint32 freq; /* Frequency in MHz; ie 2412 (== 2.412 GHz) */
+ guint32 max_bitrate; /* Maximum bitrate of the AP in Kbit/s (ie 54000 Kb/s == 54Mbit/s) */
NM80211ApFlags flags; /* General flags */
NM80211ApSecurityFlags wpa_flags; /* WPA-related flags */
NM80211ApSecurityFlags rsn_flags; /* RSN (WPA2) -related flags */
/* Non-scanned attributes */
- gboolean fake; /* Whether or not the AP is from a scan */
- gboolean hotspot; /* Whether the AP is a local device's hotspot network */
+ bool fake; /* Whether or not the AP is from a scan */
+ bool hotspot; /* Whether the AP is a local device's hotspot network */
gint32 last_seen; /* Timestamp when the AP was seen lastly (obtained via nm_utils_get_monotonic_timestamp_s()) */
} NMAccessPointPrivate;
-#define NM_AP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_AP, NMAccessPointPrivate))
+struct _NMAccessPoint {
+ NMExportedObject parent;
+ NMAccessPointPrivate _priv;
+};
+
+struct _NMAccessPointClass{
+ NMExportedObjectClass parent;
+};
+
+#define NM_AP_GET_PRIVATE(self) \
+ ({ \
+ /* preserve the const-ness of self. Unfortunately, that
+ * way, @self cannot be a void pointer */ \
+ typeof (self) _self = (self); \
+ \
+ /* Get compiler error if variable is of wrong type */ \
+ _nm_unused const NMAccessPoint *_self2 = (_self); \
+ \
+ nm_assert (NM_IS_AP (_self)); \
+ &_self->_priv; \
+ })
G_DEFINE_TYPE (NMAccessPoint, nm_ap, NM_TYPE_EXPORTED_OBJECT)
-enum {
- PROP_0,
+NM_GOBJECT_PROPERTIES_DEFINE (NMAccessPoint,
PROP_FLAGS,
PROP_WPA_FLAGS,
PROP_RSN_FLAGS,
@@ -75,8 +94,7 @@ enum {
PROP_MAX_BITRATE,
PROP_STRENGTH,
PROP_LAST_SEEN,
- LAST_PROP
-};
+);
/*****************************************************************/
@@ -130,7 +148,7 @@ nm_ap_set_ssid (NMAccessPoint *ap, const guint8 *ssid, gsize len)
g_byte_array_append (priv->ssid, ssid, len);
}
- g_object_notify (G_OBJECT (ap), NM_AP_SSID);
+ _notify (ap, PROP_SSID);
}
static void
@@ -144,7 +162,7 @@ nm_ap_set_flags (NMAccessPoint *ap, NM80211ApFlags flags)
if (priv->flags != flags) {
priv->flags = flags;
- g_object_notify (G_OBJECT (ap), NM_AP_FLAGS);
+ _notify (ap, PROP_FLAGS);
}
}
@@ -158,7 +176,7 @@ nm_ap_set_wpa_flags (NMAccessPoint *ap, NM80211ApSecurityFlags flags)
priv = NM_AP_GET_PRIVATE (ap);
if (priv->wpa_flags != flags) {
priv->wpa_flags = flags;
- g_object_notify (G_OBJECT (ap), NM_AP_WPA_FLAGS);
+ _notify (ap, PROP_WPA_FLAGS);
}
}
@@ -172,7 +190,7 @@ nm_ap_set_rsn_flags (NMAccessPoint *ap, NM80211ApSecurityFlags flags)
priv = NM_AP_GET_PRIVATE (ap);
if (priv->rsn_flags != flags) {
priv->rsn_flags = flags;
- g_object_notify (G_OBJECT (ap), NM_AP_RSN_FLAGS);
+ _notify (ap, PROP_RSN_FLAGS);
}
}
@@ -198,7 +216,7 @@ nm_ap_set_address (NMAccessPoint *ap, const char *addr)
if (!priv->address || !nm_utils_hwaddr_matches (addr, -1, priv->address, -1)) {
g_free (priv->address);
priv->address = g_strdup (addr);
- g_object_notify (G_OBJECT (ap), NM_AP_HW_ADDRESS);
+ _notify (ap, PROP_HW_ADDRESS);
}
}
@@ -223,7 +241,7 @@ nm_ap_set_mode (NMAccessPoint *ap, const NM80211Mode mode)
if (priv->mode != mode) {
priv->mode = mode;
- g_object_notify (G_OBJECT (ap), NM_AP_MODE);
+ _notify (ap, PROP_MODE);
}
}
@@ -254,7 +272,7 @@ nm_ap_set_strength (NMAccessPoint *ap, const gint8 strength)
if (priv->strength != strength) {
priv->strength = strength;
- g_object_notify (G_OBJECT (ap), NM_AP_STRENGTH);
+ _notify (ap, PROP_STRENGTH);
}
}
@@ -278,7 +296,7 @@ nm_ap_set_freq (NMAccessPoint *ap,
if (priv->freq != freq) {
priv->freq = freq;
- g_object_notify (G_OBJECT (ap), NM_AP_FREQUENCY);
+ _notify (ap, PROP_FREQUENCY);
}
}
@@ -302,7 +320,7 @@ nm_ap_set_max_bitrate (NMAccessPoint *ap, guint32 bitrate)
if (priv->max_bitrate != bitrate) {
priv->max_bitrate = bitrate;
- g_object_notify (G_OBJECT (ap), NM_AP_MAX_BITRATE);
+ _notify (ap, PROP_MAX_BITRATE);
}
}
@@ -333,7 +351,7 @@ nm_ap_set_last_seen (NMAccessPoint *ap, gint32 last_seen)
if (priv->last_seen != last_seen) {
priv->last_seen = last_seen;
- g_object_notify (G_OBJECT (ap), NM_AP_LAST_SEEN);
+ _notify (ap, PROP_LAST_SEEN);
}
}
@@ -879,7 +897,7 @@ nm_ap_init (NMAccessPoint *ap)
static void
finalize (GObject *object)
{
- NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE (object);
+ NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE ((NMAccessPoint *) object);
g_free (priv->supplicant_path);
if (priv->ssid)
@@ -891,16 +909,16 @@ finalize (GObject *object)
static void
set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
+ const GValue *value, GParamSpec *pspec)
{
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
static void
get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
+ GValue *value, GParamSpec *pspec)
{
- NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE (object);
+ NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE ((NMAccessPoint *) object);
GVariant *ssid;
switch (prop_id) {
@@ -965,8 +983,6 @@ nm_ap_class_init (NMAccessPointClass *ap_class)
| NM_802_11_AP_SEC_KEY_MGMT_PSK
| NM_802_11_AP_SEC_KEY_MGMT_802_1X;
- g_type_class_add_private (ap_class, sizeof (NMAccessPointPrivate));
-
exported_object_class->export_path = NM_DBUS_PATH_ACCESS_POINT "/%u";
/* virtual methods */
@@ -975,72 +991,64 @@ nm_ap_class_init (NMAccessPointClass *ap_class)
object_class->finalize = finalize;
/* properties */
- g_object_class_install_property
- (object_class, PROP_FLAGS,
- g_param_spec_uint (NM_AP_FLAGS, "", "",
- NM_802_11_AP_FLAGS_NONE,
- NM_802_11_AP_FLAGS_PRIVACY,
- NM_802_11_AP_FLAGS_NONE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property
- (object_class, PROP_WPA_FLAGS,
- g_param_spec_uint (NM_AP_WPA_FLAGS, "", "",
- NM_802_11_AP_SEC_NONE,
- all_sec_flags,
- NM_802_11_AP_SEC_NONE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property
- (object_class, PROP_RSN_FLAGS,
- g_param_spec_uint (NM_AP_RSN_FLAGS, "", "",
- NM_802_11_AP_SEC_NONE,
- all_sec_flags,
- NM_802_11_AP_SEC_NONE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property
- (object_class, PROP_SSID,
- g_param_spec_variant (NM_AP_SSID, "", "",
- G_VARIANT_TYPE ("ay"),
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property
- (object_class, PROP_FREQUENCY,
- g_param_spec_uint (NM_AP_FREQUENCY, "", "",
- 0, 10000, 0,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property
- (object_class, PROP_HW_ADDRESS,
- g_param_spec_string (NM_AP_HW_ADDRESS, "", "",
+ obj_properties[PROP_FLAGS] =
+ g_param_spec_uint (NM_AP_FLAGS, "", "",
+ NM_802_11_AP_FLAGS_NONE,
+ NM_802_11_AP_FLAGS_PRIVACY,
+ NM_802_11_AP_FLAGS_NONE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ obj_properties[PROP_WPA_FLAGS] =
+ g_param_spec_uint (NM_AP_WPA_FLAGS, "", "",
+ NM_802_11_AP_SEC_NONE,
+ all_sec_flags,
+ NM_802_11_AP_SEC_NONE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ obj_properties[PROP_RSN_FLAGS] =
+ g_param_spec_uint (NM_AP_RSN_FLAGS, "", "",
+ NM_802_11_AP_SEC_NONE,
+ all_sec_flags,
+ NM_802_11_AP_SEC_NONE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ obj_properties[PROP_SSID] =
+ g_param_spec_variant (NM_AP_SSID, "", "",
+ G_VARIANT_TYPE ("ay"),
NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property
- (object_class, PROP_MODE,
- g_param_spec_uint (NM_AP_MODE, "", "",
- NM_802_11_MODE_ADHOC, NM_802_11_MODE_INFRA, NM_802_11_MODE_INFRA,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property
- (object_class, PROP_MAX_BITRATE,
- g_param_spec_uint (NM_AP_MAX_BITRATE, "", "",
- 0, G_MAXUINT16, 0,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property
- (object_class, PROP_STRENGTH,
- g_param_spec_uchar (NM_AP_STRENGTH, "", "",
- 0, G_MAXINT8, 0,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property
- (object_class, PROP_LAST_SEEN,
- g_param_spec_int (NM_AP_LAST_SEEN, "", "",
- -1, G_MAXINT, -1,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ obj_properties[PROP_FREQUENCY] =
+ g_param_spec_uint (NM_AP_FREQUENCY, "", "",
+ 0, 10000, 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ obj_properties[PROP_HW_ADDRESS] =
+ g_param_spec_string (NM_AP_HW_ADDRESS, "", "",
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ obj_properties[PROP_MODE] =
+ g_param_spec_uint (NM_AP_MODE, "", "",
+ NM_802_11_MODE_ADHOC, NM_802_11_MODE_INFRA, NM_802_11_MODE_INFRA,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ obj_properties[PROP_MAX_BITRATE] =
+ g_param_spec_uint (NM_AP_MAX_BITRATE, "", "",
+ 0, G_MAXUINT16, 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ obj_properties[PROP_STRENGTH] =
+ g_param_spec_uchar (NM_AP_STRENGTH, "", "",
+ 0, G_MAXINT8, 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ obj_properties[PROP_LAST_SEEN] =
+ g_param_spec_int (NM_AP_LAST_SEEN, "", "",
+ -1, G_MAXINT, -1,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (ap_class),
NMDBUS_TYPE_ACCESS_POINT_SKELETON,
diff --git a/src/devices/wifi/nm-wifi-ap.h b/src/devices/wifi/nm-wifi-ap.h
index 84aff983c2..035d1b5e57 100644
--- a/src/devices/wifi/nm-wifi-ap.h
+++ b/src/devices/wifi/nm-wifi-ap.h
@@ -44,14 +44,8 @@
#define NM_AP_STRENGTH "strength"
#define NM_AP_LAST_SEEN "last-seen"
-typedef struct {
- NMExportedObject parent;
-} NMAccessPoint;
-
-typedef struct {
- NMExportedObjectClass parent;
-
-} NMAccessPointClass;
+typedef struct _NMAccessPoint NMAccessPoint;
+typedef struct _NMAccessPointClass NMAccessPointClass;
GType nm_ap_get_type (void);
diff --git a/src/devices/wifi/tests/test-wifi-ap-utils.c b/src/devices/wifi/tests/test-wifi-ap-utils.c
index 838368c479..dbe185b3a8 100644
--- a/src/devices/wifi/tests/test-wifi-ap-utils.c
+++ b/src/devices/wifi/tests/test-wifi-ap-utils.c
@@ -26,7 +26,7 @@
#include "nm-core-internal.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
#define DEBUG 1
diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c
index a8361c4976..0f96dafbfc 100644
--- a/src/devices/wwan/nm-device-modem.c
+++ b/src/devices/wwan/nm-device-modem.c
@@ -60,6 +60,7 @@ static void
ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
+ NMDeviceModem *self = NM_DEVICE_MODEM (user_data);
switch (nm_device_get_state (device)) {
case NM_DEVICE_STATE_PREPARE:
@@ -73,7 +74,18 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
case NM_DEVICE_STATE_ACTIVATED:
if (nm_device_activate_ip4_state_in_conf (device))
nm_device_activate_schedule_ip4_config_timeout (device);
- else {
+ else if (nm_device_activate_ip6_state_in_conf (device))
+ nm_device_activate_schedule_ip6_config_timeout (device);
+ else if (nm_device_activate_ip4_state_done (device)) {
+ nm_device_ip_method_failed (device,
+ AF_INET,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ } else if (nm_device_activate_ip6_state_done (device)) {
+ nm_device_ip_method_failed (device,
+ AF_INET6,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ } else {
+ _LOGW (LOGD_MB, "PPP failure in unexpected state %u", (guint) nm_device_get_state (device));
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
@@ -159,8 +171,9 @@ modem_ip4_config_result (NMModem *modem,
if (error) {
_LOGW (LOGD_MB | LOGD_IP4, "retrieving IPv4 configuration failed: %s",
error->message);
-
- nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ nm_device_ip_method_failed (device,
+ AF_INET,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
} else {
nm_device_set_wwan_ip4_config (device, config);
nm_device_activate_schedule_ip4_config_result (device, NULL);
@@ -184,9 +197,11 @@ modem_ip6_config_result (NMModem *modem,
g_return_if_fail (nm_device_activate_ip6_state_in_conf (device) == TRUE);
if (error) {
- _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: %s", error->message);
-
- nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: %s",
+ error->message);
+ nm_device_ip_method_failed (device,
+ AF_INET6,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
return;
}
@@ -201,7 +216,9 @@ modem_ip6_config_result (NMModem *modem,
nm_device_activate_schedule_ip6_config_result (device);
else {
_LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: SLAAC not requested and no addresses");
- nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ nm_device_ip_method_failed (device,
+ AF_INET6,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
}
return;
}
@@ -211,7 +228,7 @@ modem_ip6_config_result (NMModem *modem,
g_assert (ignored == NULL);
switch (ret) {
case NM_ACT_STAGE_RETURN_FAILURE:
- nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
+ nm_device_ip_method_failed (device, AF_INET6, reason);
break;
case NM_ACT_STAGE_RETURN_STOP:
/* all done */
diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c
index 1a6e6b2524..105cf4ddf3 100644
--- a/src/devices/wwan/nm-modem-broadband.c
+++ b/src/devices/wwan/nm-modem-broadband.c
@@ -89,8 +89,35 @@ enum {
/*****************************************************************************/
+#define _NMLOG_DOMAIN LOGD_MB
+#define _NMLOG_PREFIX_NAME "modem-broadband"
+#define _NMLOG(level, ...) \
+ G_STMT_START { \
+ const NMLogLevel _level = (level); \
+ \
+ if (nm_logging_enabled (_level, (_NMLOG_DOMAIN))) { \
+ NMModemBroadband *const __self = (self); \
+ char __prefix_name[128]; \
+ const char *__uid; \
+ \
+ _nm_log (_level, (_NMLOG_DOMAIN), 0, \
+ "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
+ _NMLOG_PREFIX_NAME, \
+ (__self \
+ ? ({ \
+ ((__uid = nm_modem_get_uid ((NMModem *) __self)) \
+ ? nm_sprintf_buf (__prefix_name, "[%s]", __uid) \
+ : "(null)"); \
+ }) \
+ : "") \
+ _NM_UTILS_MACRO_REST(__VA_ARGS__)); \
+ } \
+ } G_STMT_END
+
+/*****************************************************************************/
+
static NMDeviceStateReason
-translate_mm_error (GError *error)
+translate_mm_error (NMModemBroadband *self, GError *error)
{
NMDeviceStateReason reason;
@@ -122,7 +149,7 @@ translate_mm_error (GError *error)
reason = NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT;
else {
/* unable to map the ModemManager error to a NM_DEVICE_STATE_REASON */
- nm_log_dbg (LOGD_MB, "unmapped error detected: '%s'", error->message);
+ _LOGD ("unmapped error detected: '%s'", error->message);
reason = NM_DEVICE_STATE_REASON_UNKNOWN;
}
@@ -288,7 +315,7 @@ connect_context_clear (NMModemBroadband *self)
g_clear_error (&ctx->first_error);
g_clear_pointer (&ctx->ip_types, (GDestroyNotify) g_array_unref);
- g_clear_object (&ctx->cancellable);
+ nm_clear_g_cancellable (&ctx->cancellable);
g_clear_object (&ctx->connection);
g_clear_object (&ctx->connect_properties);
g_clear_object (&ctx->self);
@@ -360,8 +387,7 @@ connect_ready (MMModemSimple *simple_iface,
if (ip4_method == NM_MODEM_IP_METHOD_UNKNOWN &&
ip6_method == NM_MODEM_IP_METHOD_UNKNOWN) {
- nm_log_warn (LOGD_MB, "(%s): failed to connect modem: invalid bearer IP configuration",
- nm_modem_get_uid (NM_MODEM (self)));
+ _LOGW ("failed to connect modem: invalid bearer IP configuration");
g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
connect_context_clear (self);
return;
@@ -389,7 +415,7 @@ send_pin_ready (MMSim *sim, GAsyncResult *result, NMModemBroadband *self)
return;
if (!self->priv->ctx || self->priv->ctx->step != CONNECT_STEP_UNLOCK)
- return;
+ g_return_if_reached ();
if (error) {
if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN) ||
@@ -397,7 +423,7 @@ send_pin_ready (MMSim *sim, GAsyncResult *result, NMModemBroadband *self)
mm_modem_get_unlock_required (self->priv->modem_iface) == MM_MODEM_LOCK_SIM_PIN)) {
ask_for_pin (self);
} else {
- g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (error));
+ g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (self, error));
}
return;
}
@@ -459,9 +485,8 @@ connect_context_step (NMModemBroadband *self)
else if (MODEM_CAPS_3GPP2 (ctx->caps))
ctx->connect_properties = create_cdma_connect_properties (ctx->connection);
else {
- nm_log_warn (LOGD_MB, "(%s): Failed to connect '%s': not a mobile broadband modem",
- nm_modem_get_uid (NM_MODEM (self)),
- nm_connection_get_id (ctx->connection));
+ _LOGW ("failed to connect '%s': not a mobile broadband modem",
+ nm_connection_get_id (ctx->connection));
g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
connect_context_clear (self);
@@ -472,10 +497,9 @@ connect_context_step (NMModemBroadband *self)
/* Build up list of IP types that we need to use in the retries */
ctx->ip_types = nm_modem_get_connection_ip_type (NM_MODEM (self), ctx->connection, &error);
if (!ctx->ip_types) {
- nm_log_warn (LOGD_MB, "(%s): Failed to connect '%s': %s",
- nm_modem_get_uid (NM_MODEM (self)),
- nm_connection_get_id (ctx->connection),
- error->message);
+ _LOGW ("failed to connect '%s': %s",
+ nm_connection_get_id (ctx->connection),
+ error->message);
g_clear_error (&error);
g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
@@ -502,10 +526,9 @@ connect_context_step (NMModemBroadband *self)
else
g_assert_not_reached ();
- nm_log_dbg (LOGD_MB, "(%s): launching connection with ip type '%s' (try %d)",
- nm_modem_get_uid (NM_MODEM (self)),
- nm_modem_ip_type_to_string (current),
- ctx->ip_type_tries + 1);
+ _LOGD ("launching connection with ip type '%s' (try %d)",
+ nm_modem_ip_type_to_string (current),
+ ctx->ip_type_tries + 1);
mm_modem_simple_connect (self->priv->simple_iface,
ctx->connect_properties,
@@ -528,10 +551,9 @@ connect_context_step (NMModemBroadband *self)
NM_DEVICE_ERROR_INVALID_CONNECTION,
"invalid bearer IP configuration");
- nm_log_warn (LOGD_MB, "(%s): failed to connect modem: %s",
- nm_modem_get_uid (NM_MODEM (self)),
- ctx->first_error->message);
- g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (ctx->first_error));
+ _LOGW ("failed to connect modem: %s",
+ ctx->first_error->message);
+ g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (self, ctx->first_error));
}
connect_context_clear (self);
@@ -550,8 +572,7 @@ act_stage1_prepare (NMModem *_self,
if (!self->priv->simple_iface) {
self->priv->simple_iface = mm_object_get_modem_simple (self->priv->modem_object);
if (!self->priv->simple_iface) {
- nm_log_warn (LOGD_MB, "(%s) cannot access the Simple mobile broadband modem interface",
- nm_modem_get_uid (NM_MODEM (self)));
+ _LOGW ("cannot access the Simple mobile broadband modem interface");
*reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED;
return NM_ACT_STAGE_RETURN_FAILURE;
}
@@ -745,9 +766,8 @@ set_power_state_low_ready (MMModem *modem,
if (!mm_modem_set_power_state_finish (modem, result, &error)) {
/* Log but ignore errors; not all modems support low power state */
- nm_log_dbg (LOGD_MB, "(%s): failed to set modem low power state: %s",
- nm_modem_get_uid (NM_MODEM (self)),
- NM_G_ERROR_MSG (error));
+ _LOGD ("failed to set modem low power state: %s",
+ NM_G_ERROR_MSG (error));
g_clear_error (&error);
}
@@ -770,9 +790,8 @@ modem_disable_ready (MMModem *modem_iface,
(GAsyncReadyCallback) set_power_state_low_ready,
g_object_ref (self));
} else {
- nm_log_warn (LOGD_MB, "(%s): failed to disable modem: %s",
- nm_modem_get_uid (NM_MODEM (self)),
- NM_G_ERROR_MSG (error));
+ _LOGW ("failed to disable modem: %s",
+ NM_G_ERROR_MSG (error));
nm_modem_set_prev_state (NM_MODEM (self), "disable failed");
g_clear_error (&error);
}
@@ -789,9 +808,8 @@ modem_enable_ready (MMModem *modem_iface,
GError *error = NULL;
if (!mm_modem_enable_finish (modem_iface, res, &error)) {
- nm_log_warn (LOGD_MB, "(%s) failed to enable modem: %s",
- nm_modem_get_uid (NM_MODEM (self)),
- NM_G_ERROR_MSG (error));
+ _LOGW ("failed to enable modem: %s",
+ NM_G_ERROR_MSG (error));
nm_modem_set_prev_state (NM_MODEM (self), "enable failed");
g_clear_error (&error);
}
@@ -854,8 +872,7 @@ static_stage3_ip4_done (NMModemBroadband *self)
g_assert (self->priv->ipv4_config);
g_assert (self->priv->bearer);
- nm_log_info (LOGD_MB, "(%s): IPv4 static configuration:",
- nm_modem_get_uid (NM_MODEM (self)));
+ _LOGI ("IPv4 static configuration:");
/* Fully fail if invalid IP address retrieved */
address_string = mm_bearer_ip_config_get_address (self->priv->ipv4_config);
@@ -880,15 +897,15 @@ static_stage3_ip4_done (NMModemBroadband *self)
address.address = address_network;
address.peer_address = address_network;
address.plen = mm_bearer_ip_config_get_prefix (self->priv->ipv4_config);
- address.source = NM_IP_CONFIG_SOURCE_WWAN;
+ address.addr_source = NM_IP_CONFIG_SOURCE_WWAN;
if (address.plen <= 32)
nm_ip4_config_add_address (config, &address);
- nm_log_info (LOGD_MB, " address %s/%d", address_string, address.plen);
+ _LOGI (" address %s/%d", address_string, address.plen);
if (gw) {
nm_ip4_config_set_gateway (config, gw);
- nm_log_info (LOGD_MB, " gateway %s", gw_string);
+ _LOGI (" gateway %s", gw_string);
}
/* DNS servers */
@@ -897,7 +914,7 @@ static_stage3_ip4_done (NMModemBroadband *self)
if ( ip4_string_to_num (dns[i], &address_network)
&& address_network > 0) {
nm_ip4_config_add_nameserver (config, address_network);
- nm_log_info (LOGD_MB, " DNS %s", dns[i]);
+ _LOGI (" DNS %s", dns[i]);
}
}
@@ -964,8 +981,7 @@ stage3_ip6_done (NMModemBroadband *self)
goto out;
}
- nm_log_info (LOGD_MB, "(%s): IPv6 base configuration:",
- nm_modem_get_uid (NM_MODEM (self)));
+ _LOGI ("IPv6 base configuration:");
data_port = mm_bearer_get_interface (self->priv->bearer);
g_assert (data_port);
@@ -975,7 +991,7 @@ stage3_ip6_done (NMModemBroadband *self)
if (address.plen <= 128)
nm_ip6_config_add_address (config, &address);
- nm_log_info (LOGD_MB, " address %s/%d", address_string, address.plen);
+ _LOGI (" address %s/%d", address_string, address.plen);
address_string = mm_bearer_ip_config_get_gateway (self->priv->ipv6_config);
if (address_string) {
@@ -987,7 +1003,7 @@ stage3_ip6_done (NMModemBroadband *self)
address_string);
goto out;
}
- nm_log_info (LOGD_MB, " gateway %s", address_string);
+ _LOGI (" gateway %s", address_string);
nm_ip6_config_set_gateway (config, &address.address);
} else if (ip_method == NM_MODEM_IP_METHOD_STATIC) {
/* Gateway required for the 'static' method */
@@ -1005,7 +1021,7 @@ stage3_ip6_done (NMModemBroadband *self)
if (inet_pton (AF_INET6, dns[i], &addr)) {
nm_ip6_config_add_nameserver (config, &addr);
- nm_log_info (LOGD_MB, " DNS %s", dns[i]);
+ _LOGI (" DNS %s", dns[i]);
}
}
@@ -1050,19 +1066,6 @@ disconnect_context_complete (DisconnectContext *ctx)
}
static gboolean
-disconnect_context_complete_if_cancelled (DisconnectContext *ctx)
-{
- GError *error = NULL;
-
- if (g_cancellable_set_error_if_cancelled (ctx->cancellable, &error)) {
- g_simple_async_result_take_error (ctx->result, error);
- disconnect_context_complete (ctx);
- return TRUE;
- }
- return FALSE;
-}
-
-static gboolean
disconnect_finish (NMModem *self,
GAsyncResult *res,
GError **error)
@@ -1079,9 +1082,10 @@ simple_disconnect_ready (MMModemSimple *modem_iface,
if (!mm_modem_simple_disconnect_finish (modem_iface, res, &error)) {
if (ctx->warn && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) {
- nm_log_warn (LOGD_MB, "(%s) failed to disconnect modem: %s",
- nm_modem_get_uid (NM_MODEM (ctx->self)),
- error->message);
+ NMModemBroadband *self = ctx->self;
+
+ _LOGW ("failed to disconnect modem: %s",
+ error->message);
}
g_simple_async_result_take_error (ctx->result, error);
}
@@ -1098,9 +1102,11 @@ disconnect (NMModem *modem,
{
NMModemBroadband *self = NM_MODEM_BROADBAND (modem);
DisconnectContext *ctx;
+ GError *error = NULL;
connect_context_clear (self);
ctx = g_slice_new (DisconnectContext);
+ ctx->cancellable = NULL;
ctx->self = g_object_ref (self);
ctx->result = g_simple_async_result_new (G_OBJECT (self),
callback,
@@ -1109,10 +1115,12 @@ disconnect (NMModem *modem,
/* Don't bother warning on FAILED since the modem is already gone */
ctx->warn = warn;
- /* Setup cancellable */
- ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
- if (disconnect_context_complete_if_cancelled (ctx))
+ /* Already cancelled? */
+ if (g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+ g_simple_async_result_take_error (ctx->result, error);
+ disconnect_context_complete (ctx);
return;
+ }
/* If no simple iface, we're done */
if (!ctx->self->priv->simple_iface) {
@@ -1120,14 +1128,13 @@ disconnect (NMModem *modem,
return;
}
- nm_log_dbg (LOGD_MB, "(%s): notifying ModemManager about the modem disconnection",
- nm_modem_get_uid (NM_MODEM (ctx->self)));
- mm_modem_simple_disconnect (
- ctx->self->priv->simple_iface,
- NULL, /* bearer path; if NULL given ALL get disconnected */
- cancellable,
- (GAsyncReadyCallback)simple_disconnect_ready,
- ctx);
+ _LOGD ("notifying ModemManager about the modem disconnection");
+ ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
+ mm_modem_simple_disconnect (ctx->self->priv->simple_iface,
+ NULL, /* bearer path; if NULL given ALL get disconnected */
+ cancellable,
+ (GAsyncReadyCallback) simple_disconnect_ready,
+ ctx);
}
/*****************************************************************************/
@@ -1274,9 +1281,8 @@ get_sim_ready (MMModem *modem,
if (self->priv->ctx && self->priv->ctx->step == CONNECT_STEP_WAIT_FOR_SIM)
connect_context_step (self);
} else {
- nm_log_warn (LOGD_MB, "(%s): failed to retrieve SIM object: %s",
- nm_modem_get_uid (NM_MODEM (self)),
- NM_G_ERROR_MSG (error));
+ _LOGW ("failed to retrieve SIM object: %s",
+ NM_G_ERROR_MSG (error));
}
g_clear_error (&error);
g_object_unref (self);
diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c
index c102581733..eab6132b2a 100644
--- a/src/dhcp-manager/nm-dhcp-client.c
+++ b/src/dhcp-manager/nm-dhcp-client.c
@@ -559,51 +559,49 @@ nm_dhcp_client_start_ip6 (NMDhcpClient *self,
void
nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name)
{
- char *pid_contents = NULL, *proc_contents = NULL, *proc_path = NULL;
- long int tmp;
+ guint64 start_time;
+ pid_t pid, ppid;
+ const char *exe;
+ char proc_path[NM_STRLEN ("/proc/%lu/cmdline") + 100];
+ gs_free char *pid_contents = NULL, *proc_contents = NULL;
/* Check for an existing instance and stop it */
if (!g_file_get_contents (pid_file, &pid_contents, NULL, NULL))
return;
- errno = 0;
- tmp = strtol (pid_contents, NULL, 10);
- if ((errno == 0) && (tmp > 1)) {
- guint64 start_time;
- const char *exe;
- pid_t ppid;
-
- /* Ensure the process is a DHCP client */
- start_time = nm_utils_get_start_time_for_pid (tmp, NULL, &ppid);
- proc_path = g_strdup_printf ("/proc/%ld/cmdline", tmp);
- if ( start_time
- && g_file_get_contents (proc_path, &proc_contents, NULL, NULL)) {
- exe = strrchr (proc_contents, '/');
- if (exe)
- exe++;
- else
- exe = proc_contents;
-
- if (!strcmp (exe, binary_name)) {
- if (ppid == getpid ()) {
- /* the process is our own child. */
- nm_utils_kill_child_sync (tmp, SIGTERM, LOGD_DHCP, "dhcp-client", NULL, 1000 / 2, 1000 / 20);
- } else {
- nm_utils_kill_process_sync (tmp, start_time, SIGTERM, LOGD_DHCP,
- "dhcp-client", 1000 / 2, 1000 / 20, 2000);
- }
- }
- }
+ pid = _nm_utils_ascii_str_to_int64 (pid_contents, 10, 1, G_MAXINT64, 0);
+ if (pid <= 0)
+ goto out;
+
+ start_time = nm_utils_get_start_time_for_pid (pid, NULL, &ppid);
+ if (start_time == 0)
+ goto out;
+
+ nm_sprintf_buf (proc_path, "/proc/%lu/cmdline", (long unsigned) pid);
+ if (!g_file_get_contents (proc_path, &proc_contents, NULL, NULL))
+ goto out;
+
+ exe = strrchr (proc_contents, '/');
+ if (exe)
+ exe++;
+ else
+ exe = proc_contents;
+ if (!nm_streq0 (exe, binary_name))
+ goto out;
+
+ if (ppid == getpid ()) {
+ /* the process is our own child. */
+ nm_utils_kill_child_sync (pid, SIGTERM, LOGD_DHCP, "dhcp-client", NULL, 1000 / 2, 1000 / 20);
+ } else {
+ nm_utils_kill_process_sync (pid, start_time, SIGTERM, LOGD_DHCP,
+ "dhcp-client", 1000 / 2, 1000 / 20, 2000);
}
+out:
if (remove (pid_file) == -1) {
nm_log_dbg (LOGD_DHCP, "dhcp: could not remove pid file \"%s\": %d (%s)",
pid_file, errno, g_strerror (errno));
}
-
- g_free (proc_path);
- g_free (pid_contents);
- g_free (proc_contents);
}
void
@@ -836,7 +834,7 @@ set_property (GObject *object, guint prop_id,
switch (prop_id) {
case PROP_IFACE:
/* construct-only */
- priv->iface = g_strdup (g_value_get_string (value));
+ priv->iface = g_value_dup_string (value);
break;
case PROP_IFINDEX:
/* construct-only */
diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.c b/src/dhcp-manager/nm-dhcp-dhclient-utils.c
index 008f8af2ba..8d4c54ae15 100644
--- a/src/dhcp-manager/nm-dhcp-dhclient-utils.c
+++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.c
@@ -720,7 +720,7 @@ nm_dhcp_dhclient_read_lease_ip_configs (const char *iface,
address.timestamp = now_monotonic_ts;
address.lifetime = address.preferred = expiry;
- address.source = NM_IP_CONFIG_SOURCE_DHCP;
+ address.addr_source = NM_IP_CONFIG_SOURCE_DHCP;
ip4 = nm_ip4_config_new (ifindex);
nm_ip4_config_add_address (ip4, &address);
diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c
index 4b6d301b50..ade206bad9 100644
--- a/src/dhcp-manager/nm-dhcp-dhclient.c
+++ b/src/dhcp-manager/nm-dhcp-dhclient.c
@@ -18,7 +18,8 @@
* Copyright (C) 2005 - 2012 Red Hat, Inc.
*/
-#include "config.h"
+#include <config.h>
+#define __CONFIG_H__
#define _XOPEN_SOURCE
#include <time.h>
@@ -177,6 +178,9 @@ merge_dhclient_config (NMDhcpDhclient *self,
}
}
+ if (is_ip6 && hostname && !strchr (hostname, '.'))
+ _LOGW ("hostname is not a FQDN, it will be ignored");
+
new = nm_dhcp_dhclient_create_config (iface, is_ip6, client_id, anycast_addr, hostname, fqdn, orig_path, orig, out_new_client_id);
g_assert (new);
success = g_file_set_contents (conf_file, new, -1, error);
diff --git a/src/dhcp-manager/nm-dhcp-systemd.c b/src/dhcp-manager/nm-dhcp-systemd.c
index 82cb335076..28a8988613 100644
--- a/src/dhcp-manager/nm-dhcp-systemd.c
+++ b/src/dhcp-manager/nm-dhcp-systemd.c
@@ -256,7 +256,7 @@ lease_to_ip4_config (const char *iface,
SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME,
end_time);
- address.source = NM_IP_CONFIG_SOURCE_DHCP;
+ address.addr_source = NM_IP_CONFIG_SOURCE_DHCP;
nm_ip4_config_add_address (ip4_config, &address);
/* DNS Servers */
@@ -323,7 +323,7 @@ lease_to_ip4_config (const char *iface,
route.gateway = a.s_addr;
if (route.plen) {
- route.source = NM_IP_CONFIG_SOURCE_DHCP;
+ route.rt_source = NM_IP_CONFIG_SOURCE_DHCP;
route.metric = default_priority;
nm_ip4_config_add_route (ip4_config, &route);
@@ -578,6 +578,8 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last
return FALSE;
}
+ _LOGT ("dhcp-client4: set %p", priv->client4);
+
r = sd_dhcp_client_attach_event (priv->client4, NULL, 0);
if (r < 0) {
_LOGW ("failed to attach event (%d)", r);
@@ -602,9 +604,9 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last
}
}
- r = sd_dhcp_client_set_index (priv->client4, nm_dhcp_client_get_ifindex (client));
+ r = sd_dhcp_client_set_ifindex (priv->client4, nm_dhcp_client_get_ifindex (client));
if (r < 0) {
- _LOGW ("failed to set ifindex (%d)", r);
+ _LOGW ("failed to set ififindex (%d)", r);
goto error;
}
@@ -741,7 +743,7 @@ lease_to_ip6_config (const char *iface,
.timestamp = ts,
.lifetime = lft_valid,
.preferred = lft_pref,
- .source = NM_IP_CONFIG_SOURCE_DHCP,
+ .addr_source = NM_IP_CONFIG_SOURCE_DHCP,
};
nm_ip6_config_add_address (ip6_config, &address);
@@ -895,6 +897,8 @@ ip6_start (NMDhcpClient *client,
return FALSE;
}
+ _LOGT ("dhcp-client6: set %p", priv->client4);
+
if (info_only)
sd_dhcp6_client_set_information_request (priv->client6, 1);
@@ -928,7 +932,7 @@ ip6_start (NMDhcpClient *client,
}
}
- r = sd_dhcp6_client_set_index (priv->client6, nm_dhcp_client_get_ifindex (client));
+ r = sd_dhcp6_client_set_ifindex (priv->client6, nm_dhcp_client_get_ifindex (client));
if (r < 0) {
_LOGW ("failed to set ifindex (%d)", r);
goto error;
@@ -973,6 +977,10 @@ stop (NMDhcpClient *client, gboolean release, const GByteArray *duid)
NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self);
int r = 0;
+ _LOGT ("dhcp-client%d: stop %p",
+ priv->client4 ? '4' : '6',
+ priv->client4 ? (gpointer) priv->client4 : (gpointer) priv->client6);
+
if (priv->client4) {
sd_dhcp_client_set_callback (priv->client4, NULL, NULL);
r = sd_dhcp_client_stop (priv->client4);
diff --git a/src/dhcp-manager/nm-dhcp-utils.c b/src/dhcp-manager/nm-dhcp-utils.c
index a88a7e6d51..3c397ce1f6 100644
--- a/src/dhcp-manager/nm-dhcp-utils.c
+++ b/src/dhcp-manager/nm-dhcp-utils.c
@@ -84,7 +84,7 @@ ip4_process_dhcpcd_rfc3442_routes (const char *str,
route.network = rt_addr;
route.plen = rt_cidr;
route.gateway = rt_route;
- route.source = NM_IP_CONFIG_SOURCE_DHCP;
+ route.rt_source = NM_IP_CONFIG_SOURCE_DHCP;
route.metric = priority;
nm_ip4_config_add_route (ip4_config, &route);
}
@@ -192,7 +192,7 @@ ip4_process_dhclient_rfc3442_routes (const char *str,
char addr[INET_ADDRSTRLEN];
/* normal route */
- route.source = NM_IP_CONFIG_SOURCE_DHCP;
+ route.rt_source = NM_IP_CONFIG_SOURCE_DHCP;
route.metric = priority;
nm_ip4_config_add_route (ip4_config, &route);
@@ -314,7 +314,7 @@ process_classful_routes (GHashTable *options, guint32 priority, NMIP4Config *ip4
route.plen = 32;
}
route.gateway = rt_route;
- route.source = NM_IP_CONFIG_SOURCE_DHCP;
+ route.rt_source = NM_IP_CONFIG_SOURCE_DHCP;
route.metric = priority;
nm_ip4_config_add_route (ip4_config, &route);
@@ -465,7 +465,7 @@ nm_dhcp_utils_ip4_config_from_options (int ifindex,
route.plen = 32;
/* this will be a device route if gwaddr is 0 */
route.gateway = gwaddr;
- route.source = NM_IP_CONFIG_SOURCE_DHCP;
+ route.rt_source = NM_IP_CONFIG_SOURCE_DHCP;
route.metric = priority;
nm_ip4_config_add_route (ip4_config, &route);
nm_log_dbg (LOGD_IP, "adding route for server identifier: %s",
@@ -482,7 +482,7 @@ nm_dhcp_utils_ip4_config_from_options (int ifindex,
nm_log_info (LOGD_DHCP4, " lease time %u", address.lifetime);
}
- address.source = NM_IP_CONFIG_SOURCE_DHCP;
+ address.addr_source = NM_IP_CONFIG_SOURCE_DHCP;
nm_ip4_config_add_address (ip4_config, &address);
str = g_hash_table_lookup (options, "host_name");
@@ -642,7 +642,7 @@ nm_dhcp_utils_ip6_config_from_options (int ifindex,
}
address.address = tmp_addr;
- address.source = NM_IP_CONFIG_SOURCE_DHCP;
+ address.addr_source = NM_IP_CONFIG_SOURCE_DHCP;
nm_ip6_config_add_address (ip6_config, &address);
nm_log_info (LOGD_DHCP6, " address %s", str);
} else if (info_only == FALSE) {
diff --git a/src/dhcp-manager/tests/test-dhcp-dhclient.c b/src/dhcp-manager/tests/test-dhcp-dhclient.c
index 046dd7e242..77849c8c38 100644
--- a/src/dhcp-manager/tests/test-dhcp-dhclient.c
+++ b/src/dhcp-manager/tests/test-dhcp-dhclient.c
@@ -31,7 +31,7 @@
#include "nm-ip4-config.h"
#include "nm-platform.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
#define DEBUG 1
diff --git a/src/dhcp-manager/tests/test-dhcp-utils.c b/src/dhcp-manager/tests/test-dhcp-utils.c
index f477c061fb..89d693ed11 100644
--- a/src/dhcp-manager/tests/test-dhcp-utils.c
+++ b/src/dhcp-manager/tests/test-dhcp-utils.c
@@ -28,7 +28,7 @@
#include "nm-dhcp-utils.h"
#include "nm-platform.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
typedef struct {
const char *name;
diff --git a/src/dns-manager/nm-dns-dnsmasq.c b/src/dns-manager/nm-dns-dnsmasq.c
index 8868b4bb9f..8c7c8c3ecb 100644
--- a/src/dns-manager/nm-dns-dnsmasq.c
+++ b/src/dns-manager/nm-dns-dnsmasq.c
@@ -26,6 +26,7 @@
#include <sys/wait.h>
#include <arpa/inet.h>
#include <sys/stat.h>
+#include <linux/if.h>
#include "nm-dns-dnsmasq.h"
#include "nm-utils.h"
@@ -90,13 +91,16 @@ add_dnsmasq_nameserver (NMDnsDnsmasq *self,
}
static gboolean
-add_ip4_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP4Config *ip4, gboolean split)
+add_ip4_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP4Config *ip4,
+ const char *iface, gboolean split)
{
- char buf[INET_ADDRSTRLEN];
+ char buf[INET_ADDRSTRLEN + 1 + IFNAMSIZ];
+ char buf2[INET_ADDRSTRLEN];
in_addr_t addr;
int nnameservers, i_nameserver, n, i;
gboolean added = FALSE;
+ g_return_val_if_fail (iface, FALSE);
nnameservers = nm_ip4_config_get_num_nameservers (ip4);
if (split) {
@@ -107,7 +111,8 @@ add_ip4_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP4Config *ip4,
for (i_nameserver = 0; i_nameserver < nnameservers; i_nameserver++) {
addr = nm_ip4_config_get_nameserver (ip4, i_nameserver);
- nm_utils_inet4_ntop (addr, buf);
+ g_snprintf (buf, sizeof (buf), "%s@%s",
+ nm_utils_inet4_ntop (addr, buf2), iface);
/* searches are preferred over domains */
n = nm_ip4_config_get_num_searches (ip4);
@@ -147,8 +152,9 @@ add_ip4_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP4Config *ip4,
if (!added) {
for (i = 0; i < nnameservers; i++) {
addr = nm_ip4_config_get_nameserver (ip4, i);
- add_dnsmasq_nameserver (self, servers,
- nm_utils_inet4_ntop (addr, NULL), NULL);
+ g_snprintf (buf, sizeof (buf), "%s@%s",
+ nm_utils_inet4_ntop (addr, buf2), iface);
+ add_dnsmasq_nameserver (self, servers, buf, NULL);
}
}
@@ -158,23 +164,22 @@ add_ip4_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP4Config *ip4,
static char *
ip6_addr_to_string (const struct in6_addr *addr, const char *iface)
{
- char *buf;
+ char buf[NM_UTILS_INET_ADDRSTRLEN];
- if (IN6_IS_ADDR_V4MAPPED (addr)) {
- buf = g_malloc (INET_ADDRSTRLEN);
+ if (IN6_IS_ADDR_V4MAPPED (addr))
nm_utils_inet4_ntop (addr->s6_addr32[3], buf);
- } else if (!iface || !iface[0] || !IN6_IS_ADDR_LINKLOCAL (addr)) {
- buf = g_malloc (INET6_ADDRSTRLEN);
+ else
nm_utils_inet6_ntop (addr, buf);
- } else {
- /* Need to scope the address with %<zone-id>. Before dnsmasq 2.58,
- * only '@' was supported as delimiter. Since 2.58, '@' and '%'
- * are supported. Due to a bug, since 2.73 only '%' works properly
- * as "server" address.
- */
- buf = g_strconcat (nm_utils_inet6_ntop (addr, NULL), "%", iface, NULL);
- }
- return buf;
+
+ /* Need to scope link-local addresses with %<zone-id>. Before dnsmasq 2.58,
+ * only '@' was supported as delimiter. Since 2.58, '@' and '%' are
+ * supported. Due to a bug, since 2.73 only '%' works properly as "server"
+ * address.
+ */
+ return g_strdup_printf ("%s%c%s",
+ buf,
+ IN6_IS_ADDR_LINKLOCAL (addr) ? '%' : '@',
+ iface);
}
static void
@@ -202,19 +207,17 @@ add_global_config (NMDnsDnsmasq *self, GVariantBuilder *dnsmasq_servers, const N
}
static gboolean
-add_ip6_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP6Config *ip6, gboolean split)
+add_ip6_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP6Config *ip6,
+ const char *iface, gboolean split)
{
const struct in6_addr *addr;
char *buf = NULL;
int nnameservers, i_nameserver, n, i;
gboolean added = FALSE;
- const char *iface;
+ g_return_val_if_fail (iface, FALSE);
nnameservers = nm_ip6_config_get_num_nameservers (ip6);
- iface = g_object_get_data (G_OBJECT (ip6), IP_CONFIG_IFACE_TAG);
- g_assert (iface);
-
if (split) {
if (nnameservers == 0)
return FALSE;
@@ -249,7 +252,7 @@ add_ip6_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP6Config *ip6,
}
}
- /* If no searches or domains, just add the namservers */
+ /* If no searches or domains, just add the nameservers */
if (!added) {
for (i = 0; i < nnameservers; i++) {
addr = nm_ip6_config_get_nameserver (ip6, i);
@@ -264,6 +267,25 @@ add_ip6_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP6Config *ip6,
return TRUE;
}
+static gboolean
+add_ip_config_data (NMDnsDnsmasq *self, GVariantBuilder *servers, const NMDnsIPConfigData *data)
+{
+ if (NM_IS_IP4_CONFIG (data->config)) {
+ return add_ip4_config (self,
+ servers,
+ (NMIP4Config *) data->config,
+ data->iface,
+ data->type == NM_DNS_IP_CONFIG_TYPE_VPN);
+ } else if (NM_IS_IP6_CONFIG (data->config)) {
+ return add_ip6_config (self,
+ servers,
+ (NMIP6Config *) data->config,
+ data->iface,
+ data->type == NM_DNS_IP_CONFIG_TYPE_VPN);
+ } else
+ g_return_val_if_reached (FALSE);
+}
+
static void
dnsmasq_clear_cache_done (GDBusProxy *proxy, GAsyncResult *res, gpointer user_data)
{
@@ -465,15 +487,12 @@ start_dnsmasq (NMDnsDnsmasq *self)
static gboolean
update (NMDnsPlugin *plugin,
- const GSList *vpn_configs,
- const GSList *dev_configs,
- const GSList *other_configs,
+ const NMDnsIPConfigData **configs,
const NMGlobalDnsConfig *global_config,
const char *hostname)
{
NMDnsDnsmasq *self = NM_DNS_DNSMASQ (plugin);
NMDnsDnsmasqPrivate *priv = NM_DNS_DNSMASQ_GET_PRIVATE (self);
- const GSList *iter;
GVariantBuilder servers;
start_dnsmasq (self);
@@ -483,28 +502,9 @@ update (NMDnsPlugin *plugin,
if (global_config)
add_global_config (self, &servers, global_config);
else {
- /* Use split DNS for VPN configs */
- for (iter = vpn_configs; iter; iter = g_slist_next (iter)) {
- if (NM_IS_IP4_CONFIG (iter->data))
- add_ip4_config (self, &servers, iter->data, TRUE);
- else if (NM_IS_IP6_CONFIG (iter->data))
- add_ip6_config (self, &servers, iter->data, TRUE);
- }
-
- /* Now add interface configs without split DNS */
- for (iter = dev_configs; iter; iter = g_slist_next (iter)) {
- if (NM_IS_IP4_CONFIG (iter->data))
- add_ip4_config (self, &servers, iter->data, FALSE);
- else if (NM_IS_IP6_CONFIG (iter->data))
- add_ip6_config (self, &servers, iter->data, FALSE);
- }
-
- /* And any other random configs */
- for (iter = other_configs; iter; iter = g_slist_next (iter)) {
- if (NM_IS_IP4_CONFIG (iter->data))
- add_ip4_config (self, &servers, iter->data, FALSE);
- else if (NM_IS_IP6_CONFIG (iter->data))
- add_ip6_config (self, &servers, iter->data, FALSE);
+ while (*configs) {
+ add_ip_config_data (self, &servers, *configs);
+ configs++;
}
}
@@ -518,24 +518,6 @@ update (NMDnsPlugin *plugin,
/****************************************************************/
-static const char *
-dm_exit_code_to_msg (int status)
-{
- if (status == 1)
- return "Configuration problem";
- else if (status == 2)
- return "Network access problem (address in use; permissions; etc)";
- else if (status == 3)
- return "Filesystem problem (missing file/directory; permissions; etc)";
- else if (status == 4)
- return "Memory allocation failure";
- else if (status == 5)
- return "Other problem";
- else if (status >= 11)
- return "Lease-script 'init' process failure";
- return "Unknown error";
-}
-
static void
child_quit (NMDnsPlugin *plugin, gint status)
{
@@ -546,9 +528,8 @@ child_quit (NMDnsPlugin *plugin, gint status)
if (WIFEXITED (status)) {
err = WEXITSTATUS (status);
if (err) {
- _LOGW ("dnsmasq exited with error: %s (%d)",
- dm_exit_code_to_msg (err),
- err);
+ _LOGW ("dnsmasq exited with error: %s",
+ nm_utils_dnsmasq_status_to_string (err, NULL, 0));
} else
failed = FALSE;
} else if (WIFSTOPPED (status))
diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c
index 7285b89d99..a6aef6fe92 100644
--- a/src/dns-manager/nm-dns-manager.c
+++ b/src/dns-manager/nm-dns-manager.c
@@ -63,21 +63,15 @@
G_DEFINE_TYPE (NMDnsManager, nm_dns_manager, G_TYPE_OBJECT)
-#define NM_DNS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
- NM_TYPE_DNS_MANAGER, \
- NMDnsManagerPrivate))
+#define NM_DNS_MANAGER_GET_PRIVATE(o) ((o)->priv)
#define HASH_LEN 20
-#ifdef RESOLVCONF_PATH
-#define RESOLVCONF_SELECTED
-#else
+#ifndef RESOLVCONF_PATH
#define RESOLVCONF_PATH "/sbin/resolvconf"
#endif
-#ifdef NETCONFIG_PATH
-#define NETCONFIG_SELECTED
-#else
+#ifndef NETCONFIG_PATH
#define NETCONFIG_PATH "/sbin/netconfig"
#endif
@@ -111,23 +105,18 @@ NM_DEFINE_SINGLETON_INSTANCE (NMDnsManager);
/*********************************************************************************************/
-typedef struct {
- NMIP4Config *ip4_vpn_config;
- NMIP4Config *ip4_device_config;
- NMIP6Config *ip6_vpn_config;
- NMIP6Config *ip6_device_config;
- GSList *configs;
+typedef struct _NMDnsManagerPrivate {
+ GPtrArray *configs;
+ NMDnsIPConfigData *best_conf4, *best_conf6;
+ gboolean need_sort;
+
char *hostname;
guint updates_queue;
guint8 hash[HASH_LEN]; /* SHA1 hash of current DNS config */
guint8 prev_hash[HASH_LEN]; /* Hash when begin_updates() was called */
- NMDnsManagerResolvConfMode resolv_conf_mode;
NMDnsManagerResolvConfManager rc_manager;
- char *last_mode;
- bool last_immutable:1;
- bool mode_initialized:1;
NMDnsPlugin *plugin;
NMConfig *config;
@@ -166,13 +155,88 @@ typedef struct {
NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_rc_manager_to_string, NMDnsManagerResolvConfManager,
NM_UTILS_LOOKUP_DEFAULT_WARN (NULL),
- NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE, "none"),
- NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE, "file"),
- NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF, "resolvconf"),
- NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG, "netconfig"),
- NM_UTILS_LOOKUP_ITEM_IGNORE (_NM_DNS_MANAGER_RESOLV_CONF_MAN_INTERNAL_ONLY),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN, "unknown"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED, "unmanaged"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE, "immutable"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK, "symlink"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE, "file"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF, "resolvconf"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG, "netconfig"),
+);
+
+NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_config_type_to_string, NMDnsIPConfigType,
+ NM_UTILS_LOOKUP_DEFAULT_WARN ("<unknown>"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_IP_CONFIG_TYPE_DEFAULT, "default"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE, "best"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_IP_CONFIG_TYPE_VPN, "vpn"),
);
+static NMDnsIPConfigData *
+ip_config_data_new (gpointer config, NMDnsIPConfigType type, const char *iface)
+{
+ NMDnsIPConfigData *data;
+
+ data = g_slice_new0 (NMDnsIPConfigData);
+ data->config = g_object_ref (config);
+ data->iface = g_strdup (iface);
+ data->type = type;
+
+ return data;
+}
+
+static void
+ip_config_data_destroy (gpointer ptr)
+{
+ NMDnsIPConfigData *data = ptr;
+
+ if (!data)
+ return;
+
+ g_object_unref (data->config);
+ g_free (data->iface);
+ g_slice_free (NMDnsIPConfigData, data);
+}
+
+static gint
+ip_config_data_compare (const NMDnsIPConfigData *a, const NMDnsIPConfigData *b)
+{
+ gboolean a_v4, b_v4;
+ gint a_prio, b_prio;
+
+ a_v4 = NM_IS_IP4_CONFIG (a->config);
+ b_v4 = NM_IS_IP4_CONFIG (b->config);
+
+ a_prio = a_v4 ?
+ nm_ip4_config_get_dns_priority ((NMIP4Config *) a->config) :
+ nm_ip6_config_get_dns_priority ((NMIP6Config *) a->config);
+
+ b_prio = b_v4 ?
+ nm_ip4_config_get_dns_priority ((NMIP4Config *) b->config) :
+ nm_ip6_config_get_dns_priority ((NMIP6Config *) b->config);
+
+ /* Configurations with lower priority value first */
+ if (a_prio < b_prio)
+ return -1;
+ else if (a_prio > b_prio)
+ return 1;
+
+ /* Sort also according to type */
+ if (a->type > b->type)
+ return -1;
+ else if (a->type < b->type)
+ return 1;
+
+ return 0;
+}
+
+static gint
+ip_config_data_ptr_compare (gconstpointer a, gconstpointer b)
+{
+ const NMDnsIPConfigData *const *ptr_a = a, *const *ptr_b = b;
+
+ return ip_config_data_compare (*ptr_a, *ptr_b);
+}
+
static void
add_string_item (GPtrArray *array, const char *str)
{
@@ -257,12 +321,9 @@ merge_one_ip4_config (NMResolvConfData *rc, NMIP4Config *src)
}
static void
-merge_one_ip6_config (NMResolvConfData *rc, NMIP6Config *src)
+merge_one_ip6_config (NMResolvConfData *rc, NMIP6Config *src, const char *iface)
{
guint32 num, num_domains, num_searches, i;
- const char *iface;
-
- iface = g_object_get_data (G_OBJECT (src), IP_CONFIG_IFACE_TAG);
num = nm_ip6_config_get_num_nameservers (src);
for (i = 0; i < num; i++) {
@@ -276,7 +337,7 @@ merge_one_ip6_config (NMResolvConfData *rc, NMIP6Config *src)
nm_utils_inet4_ntop (addr->s6_addr32[3], buf);
else {
nm_utils_inet6_ntop (addr, buf);
- if (iface && IN6_IS_ADDR_LINKLOCAL (addr)) {
+ if (IN6_IS_ADDR_LINKLOCAL (addr)) {
g_strlcat (buf, "%", sizeof (buf));
g_strlcat (buf, iface, sizeof (buf));
}
@@ -316,6 +377,19 @@ merge_one_ip6_config (NMResolvConfData *rc, NMIP6Config *src)
}
}
+static void
+merge_one_ip_config_data (NMDnsManager *self,
+ NMResolvConfData *rc,
+ NMDnsIPConfigData *data)
+{
+ if (NM_IS_IP4_CONFIG (data->config))
+ merge_one_ip4_config (rc, (NMIP4Config *) data->config);
+ else if (NM_IS_IP6_CONFIG (data->config))
+ merge_one_ip6_config (rc, (NMIP6Config *) data->config, data->iface);
+ else
+ g_return_if_reached ();
+}
+
static GPid
run_netconfig (NMDnsManager *self, GError **error, gint *stdin_fd)
{
@@ -470,12 +544,16 @@ write_resolv_conf_contents (FILE *f,
const char *content,
GError **error)
{
+ int errsv;
+
if (fprintf (f, "%s", content) < 0) {
+ errsv = errno;
g_set_error (error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_FAILED,
"Could not write " _PATH_RESCONF ": %s",
- g_strerror (errno));
+ g_strerror (errsv));
+ errno = errsv;
return FALSE;
}
@@ -574,6 +652,7 @@ update_resolv_conf (NMDnsManager *self,
gboolean success;
gs_free char *content = NULL;
SpawnResult write_file_result = SR_SUCCESS;
+ int errsv;
/* If we are not managing /etc/resolv.conf and it points to
* MY_RESOLV_CONF, don't write the private DNS configuration to
@@ -582,12 +661,12 @@ update_resolv_conf (NMDnsManager *self,
*
* This is the only situation, where we don't try to update our
* internal resolv.conf file. */
- if (rc_manager == _NM_DNS_MANAGER_RESOLV_CONF_MAN_INTERNAL_ONLY) {
+ if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED) {
gs_free char *path = g_file_read_link (_PATH_RESCONF, NULL);
if (g_strcmp0 (path, MY_RESOLV_CONF) == 0) {
- _LOGD ("not updating " MY_RESOLV_CONF
- " since it points to " _PATH_RESCONF);
+ _LOGD ("update-resolv-conf: not updating " _PATH_RESCONF
+ " since it points to " MY_RESOLV_CONF);
return SR_SUCCESS;
}
}
@@ -595,29 +674,46 @@ update_resolv_conf (NMDnsManager *self,
content = create_resolv_conf (searches, nameservers, options);
if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE) {
+ GError *local = NULL;
+
/* we first write to /etc/resolv.conf directly. If that fails,
* we still continue to write to runstatedir but remember the
* error. */
- if (!g_file_set_contents (_PATH_RESCONF, content, -1, error)) {
+ if (!g_file_set_contents (_PATH_RESCONF, content, -1, &local)) {
+ _LOGT ("update-resolv-conf: write to %s failed (rc-managed=file, %s)",
+ _PATH_RESCONF, local->message);
write_file_result = SR_ERROR;
+ g_propagate_error (error, local);
error = NULL;
+ } else {
+ _LOGT ("update-resolv-conf: write to %s succeeded (rc-managed=file)",
+ _PATH_RESCONF);
}
}
if ((f = fopen (MY_RESOLV_CONF_TMP, "w")) == NULL) {
+ errsv = errno;
g_set_error (error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_FAILED,
"Could not open %s: %s",
MY_RESOLV_CONF_TMP,
- g_strerror (errno));
+ g_strerror (errsv));
+ _LOGT ("update-resolv-conf: open temporary file %s failed (%s)",
+ MY_RESOLV_CONF_TMP, g_strerror (errsv));
return SR_ERROR;
}
success = write_resolv_conf_contents (f, content, error);
+ if (!success) {
+ errsv = errno;
+ _LOGT ("update-resolv-conf: write temporary file %s failed (%s)",
+ MY_RESOLV_CONF_TMP, g_strerror (errsv));
+ }
if (fclose (f) < 0) {
if (success) {
+ errsv = errno;
/* only set an error here if write_resolv_conf() was successful,
* since its error is more important.
*/
@@ -626,39 +722,66 @@ update_resolv_conf (NMDnsManager *self,
NM_MANAGER_ERROR_FAILED,
"Could not close %s: %s",
MY_RESOLV_CONF_TMP,
- g_strerror (errno));
+ g_strerror (errsv));
+ _LOGT ("update-resolv-conf: close temporary file %s failed (%s)",
+ MY_RESOLV_CONF_TMP, g_strerror (errsv));
}
return SR_ERROR;
} else if (!success)
return SR_ERROR;
if (rename (MY_RESOLV_CONF_TMP, MY_RESOLV_CONF) < 0) {
+ errsv = errno;
g_set_error (error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_FAILED,
"Could not replace %s: %s",
MY_RESOLV_CONF,
g_strerror (errno));
+ _LOGT ("update-resolv-conf: failed to rename temporary file %s to %s (%s)",
+ MY_RESOLV_CONF_TMP, MY_RESOLV_CONF, g_strerror (errsv));
return SR_ERROR;
}
- if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE)
+ if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE) {
+ _LOGT ("update-resolv-conf: write internal file %s succeeded (rc-manager=file)",
+ MY_RESOLV_CONF);
return write_file_result;
+ }
- if (rc_manager != NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE)
+ if (rc_manager != NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK) {
+ _LOGT ("update-resolv-conf: write internal file %s succeeded", MY_RESOLV_CONF);
return SR_SUCCESS;
+ }
/* A symlink pointing to NM's own resolv.conf (MY_RESOLV_CONF) is always
* overwritten to ensure that changes are indicated with inotify. Symlinks
* pointing to any other file are never overwritten.
*/
- if (lstat (_PATH_RESCONF, &st) != -1) {
+ if (lstat (_PATH_RESCONF, &st) != 0) {
+ errsv = errno;
+ if (errsv != ENOENT) {
+ /* NM cannot read /etc/resolv.conf */
+ _LOGT ("update-resolv-conf: write internal file %s succeeded but lstat(%s) failed (%s)",
+ MY_RESOLV_CONF, _PATH_RESCONF, g_strerror (errsv));
+ g_set_error (error,
+ NM_MANAGER_ERROR,
+ NM_MANAGER_ERROR_FAILED,
+ "Could not lstat %s: %s",
+ _PATH_RESCONF,
+ g_strerror (errsv));
+ return SR_ERROR;
+ }
+ } else {
if (S_ISLNK (st.st_mode)) {
if (stat (_PATH_RESCONF, &st) != -1) {
gs_free char *path = g_file_read_link (_PATH_RESCONF, NULL);
- if (g_strcmp0 (path, MY_RESOLV_CONF) != 0) {
+ if (!path || !nm_streq (path, MY_RESOLV_CONF)) {
/* It's not NM's symlink; do nothing */
+ _LOGT ("update-resolv-conf: write internal file %s succeeded "
+ "but don't update %s as it points to %s",
+ MY_RESOLV_CONF, _PATH_RESCONF, path ?: "");
return SR_SUCCESS;
}
@@ -669,56 +792,64 @@ update_resolv_conf (NMDnsManager *self,
* some other program is probably managing resolv.conf and
* NM should not touch it.
*/
+ _LOGT ("update-resolv-conf: write internal file %s succeeded "
+ "but don't update %s as the symlinks points somewhere else",
+ MY_RESOLV_CONF, _PATH_RESCONF);
return SR_SUCCESS;
}
}
- } else if (errno != ENOENT) {
- /* NM cannot read /etc/resolv.conf */
- g_set_error (error,
- NM_MANAGER_ERROR,
- NM_MANAGER_ERROR_FAILED,
- "Could not lstat %s: %s",
- _PATH_RESCONF,
- g_strerror (errno));
- return SR_ERROR;
}
/* By this point, either /etc/resolv.conf does not exist, is a regular
* file, or is a symlink already owned by NM. In all cases /etc/resolv.conf
* is replaced with a symlink pointing to NM's resolv.conf in /var/run/.
*/
- if (unlink (RESOLV_CONF_TMP) == -1 && errno != ENOENT) {
+ if ( unlink (RESOLV_CONF_TMP) != 0
+ && ((errsv = errno) != ENOENT)) {
g_set_error (error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_FAILED,
"Could not unlink %s: %s",
RESOLV_CONF_TMP,
- g_strerror (errno));
+ g_strerror (errsv));
+ _LOGT ("update-resolv-conf: write internal file %s succeeded "
+ "but canot delete temporary file %s: %s",
+ MY_RESOLV_CONF, RESOLV_CONF_TMP, g_strerror (errsv));
return SR_ERROR;
}
if (symlink (MY_RESOLV_CONF, RESOLV_CONF_TMP) == -1) {
+ errsv = errno;
g_set_error (error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_FAILED,
"Could not create symlink %s pointing to %s: %s",
RESOLV_CONF_TMP,
MY_RESOLV_CONF,
- g_strerror (errno));
+ g_strerror (errsv));
+ _LOGT ("update-resolv-conf: write internal file %s succeeded "
+ "but failed to symlink %s: %s",
+ MY_RESOLV_CONF, RESOLV_CONF_TMP, g_strerror (errsv));
return SR_ERROR;
}
if (rename (RESOLV_CONF_TMP, _PATH_RESCONF) == -1) {
+ errsv = errno;
g_set_error (error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_FAILED,
"Could not rename %s to %s: %s",
RESOLV_CONF_TMP,
_PATH_RESCONF,
- g_strerror (errno));
+ g_strerror (errsv));
+ _LOGT ("update-resolv-conf: write internal file %s succeeded "
+ "but failed to rename temporary symlink %s to %s: %s",
+ MY_RESOLV_CONF, RESOLV_CONF_TMP, _PATH_RESCONF, g_strerror (errsv));
return SR_ERROR;
}
+ _LOGT ("update-resolv-conf: write internal file %s succeeded and update symlink %s",
+ MY_RESOLV_CONF, _PATH_RESCONF);
return SR_SUCCESS;
}
@@ -727,79 +858,29 @@ compute_hash (NMDnsManager *self, const NMGlobalDnsConfig *global, guint8 buffer
{
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
GChecksum *sum;
- GSList *iter;
gsize len = HASH_LEN;
+ guint i;
sum = g_checksum_new (G_CHECKSUM_SHA1);
g_assert (len == g_checksum_type_get_length (G_CHECKSUM_SHA1));
if (global)
nm_global_dns_config_update_checksum (global, sum);
+ else {
+ for (i = 0; i < priv->configs->len; i++) {
+ NMDnsIPConfigData *data = priv->configs->pdata[i];
- if (priv->ip4_vpn_config)
- nm_ip4_config_hash (priv->ip4_vpn_config, sum, TRUE);
- if (priv->ip4_device_config)
- nm_ip4_config_hash (priv->ip4_device_config, sum, TRUE);
-
- if (priv->ip6_vpn_config)
- nm_ip6_config_hash (priv->ip6_vpn_config, sum, TRUE);
- if (priv->ip6_device_config)
- nm_ip6_config_hash (priv->ip6_device_config, sum, TRUE);
-
- /* add any other configs we know about */
- for (iter = priv->configs; iter; iter = g_slist_next (iter)) {
- if (NM_IN_SET (iter->data, priv->ip4_vpn_config,
- priv->ip4_device_config,
- priv->ip6_vpn_config,
- priv->ip6_device_config))
- continue;
-
- if (NM_IS_IP4_CONFIG (iter->data))
- nm_ip4_config_hash (NM_IP4_CONFIG (iter->data), sum, TRUE);
- else if (NM_IS_IP6_CONFIG (iter->data))
- nm_ip6_config_hash (NM_IP6_CONFIG (iter->data), sum, TRUE);
+ if (NM_IS_IP4_CONFIG (data->config))
+ nm_ip4_config_hash ((NMIP4Config *) data->config, sum, TRUE);
+ else if (NM_IS_IP6_CONFIG (data->config))
+ nm_ip6_config_hash ((NMIP6Config *) data->config, sum, TRUE);
+ }
}
g_checksum_get_digest (sum, buffer, &len);
g_checksum_free (sum);
}
-static void
-build_plugin_config_lists (NMDnsManager *self,
- GSList **out_vpn_configs,
- GSList **out_dev_configs,
- GSList **out_other_configs)
-{
- NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
- GSList *iter;
-
- g_return_if_fail (out_vpn_configs && !*out_vpn_configs);
- g_return_if_fail (out_dev_configs && !*out_dev_configs);
- g_return_if_fail (out_other_configs && !*out_other_configs);
-
- /* Build up config lists for plugins; we use the raw configs here, not the
- * merged information that we write to resolv.conf so that the plugins can
- * still use the domain information in each config to provide split DNS if
- * they want to.
- */
- if (priv->ip4_vpn_config)
- *out_vpn_configs = g_slist_append (*out_vpn_configs, priv->ip4_vpn_config);
- if (priv->ip6_vpn_config)
- *out_vpn_configs = g_slist_append (*out_vpn_configs, priv->ip6_vpn_config);
- if (priv->ip4_device_config)
- *out_dev_configs = g_slist_append (*out_dev_configs, priv->ip4_device_config);
- if (priv->ip6_device_config)
- *out_dev_configs = g_slist_append (*out_dev_configs, priv->ip6_device_config);
-
- for (iter = priv->configs; iter; iter = g_slist_next (iter)) {
- if (!NM_IN_SET (iter->data, priv->ip4_vpn_config,
- priv->ip4_device_config,
- priv->ip6_vpn_config,
- priv->ip6_device_config))
- *out_other_configs = g_slist_append (*out_other_configs, iter->data);
- }
-}
-
static gboolean
merge_global_dns_config (NMResolvConfData *rc, NMGlobalDnsConfig *global_conf)
{
@@ -839,7 +920,6 @@ update_dns (NMDnsManager *self,
{
NMDnsManagerPrivate *priv;
NMResolvConfData rc;
- GSList *iter;
const char *nis_domain = NULL;
char **searches = NULL;
char **options = NULL;
@@ -851,13 +931,15 @@ update_dns (NMDnsManager *self,
SpawnResult result = SR_ERROR;
NMConfigData *data;
NMGlobalDnsConfig *global_config;
+ gs_free NMDnsIPConfigData **plugin_confs = NULL;
g_return_val_if_fail (!error || !*error, FALSE);
priv = NM_DNS_MANAGER_GET_PRIVATE (self);
nm_clear_g_source (&priv->plugin_ratelimit.timer);
- if (priv->resolv_conf_mode == NM_DNS_MANAGER_RESOLV_CONF_UNMANAGED) {
+ if (NM_IN_SET (priv->rc_manager, NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED,
+ NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE)) {
update = FALSE;
_LOGD ("update-dns: not updating resolv.conf");
} else {
@@ -868,6 +950,11 @@ update_dns (NMDnsManager *self,
data = nm_config_get_data (priv->config);
global_config = nm_config_data_get_global_dns_config (data);
+ if (priv->need_sort) {
+ g_ptr_array_sort (priv->configs, ip_config_data_ptr_compare);
+ priv->need_sort = FALSE;
+ }
+
/* Update hash with config we're applying */
compute_hash (self, global_config, priv->hash);
@@ -880,34 +967,40 @@ update_dns (NMDnsManager *self,
if (global_config)
merge_global_dns_config (&rc, global_config);
else {
- if (priv->ip4_vpn_config)
- merge_one_ip4_config (&rc, priv->ip4_vpn_config);
- if (priv->ip4_device_config)
- merge_one_ip4_config (&rc, priv->ip4_device_config);
-
- if (priv->ip6_vpn_config)
- merge_one_ip6_config (&rc, priv->ip6_vpn_config);
- if (priv->ip6_device_config)
- merge_one_ip6_config (&rc, priv->ip6_device_config);
-
- for (iter = priv->configs; iter; iter = g_slist_next (iter)) {
- if (NM_IN_SET (iter->data, priv->ip4_vpn_config,
- priv->ip4_device_config,
- priv->ip6_vpn_config,
- priv->ip6_device_config))
- continue;
+ int prio, prev_prio = 0;
+ NMDnsIPConfigData *current;
+ gboolean skip = FALSE, v4;
+
+ plugin_confs = g_new (NMDnsIPConfigData *, priv->configs->len + 1);
+
+ for (i = 0; i < priv->configs->len; i++) {
+ current = priv->configs->pdata[i];
+ v4 = NM_IS_IP4_CONFIG (current->config);
+
+ prio = v4 ?
+ nm_ip4_config_get_dns_priority ((NMIP4Config *) current->config) :
+ nm_ip6_config_get_dns_priority ((NMIP6Config *) current->config);
+
+ if (prev_prio < 0 && prio != prev_prio) {
+ skip = TRUE;
+ plugin_confs[i] = NULL;
+ }
- if (NM_IS_IP4_CONFIG (iter->data)) {
- NMIP4Config *config = NM_IP4_CONFIG (iter->data);
+ prev_prio = prio;
- merge_one_ip4_config (&rc, config);
- } else if (NM_IS_IP6_CONFIG (iter->data)) {
- NMIP6Config *config = NM_IP6_CONFIG (iter->data);
+ _LOGT ("config: %8d %-7s v%c %-16s %s",
+ prio,
+ _config_type_to_string (current->type),
+ v4 ? '4' : '6',
+ current->iface,
+ skip ? "<SKIP>" : "");
- merge_one_ip6_config (&rc, config);
- } else
- g_assert_not_reached ();
+ if (!skip) {
+ merge_one_ip_config_data (self, &rc, current);
+ plugin_confs[i] = current;
+ }
}
+ plugin_confs[i] = NULL;
}
/* If the hostname is a FQDN ("dcbw.example.com"), then add the domain part of it
@@ -970,7 +1063,6 @@ update_dns (NMDnsManager *self,
if (priv->plugin) {
NMDnsPlugin *plugin = priv->plugin;
const char *plugin_name = nm_dns_plugin_get_name (plugin);
- GSList *vpn_configs = NULL, *dev_configs = NULL, *other_configs = NULL;
if (nm_dns_plugin_is_caching (plugin)) {
if (no_caching) {
@@ -981,14 +1073,9 @@ update_dns (NMDnsManager *self,
caching = TRUE;
}
- if (!global_config)
- build_plugin_config_lists (self, &vpn_configs, &dev_configs, &other_configs);
-
_LOGD ("update-dns: updating plugin %s", plugin_name);
if (!nm_dns_plugin_update (plugin,
- vpn_configs,
- dev_configs,
- other_configs,
+ (const NMDnsIPConfigData **) plugin_confs,
global_config,
priv->hostname)) {
_LOGW ("update-dns: plugin %s update failed", plugin_name);
@@ -998,9 +1085,6 @@ update_dns (NMDnsManager *self,
*/
caching = FALSE;
}
- g_slist_free (vpn_configs);
- g_slist_free (dev_configs);
- g_slist_free (other_configs);
skip:
;
@@ -1019,7 +1103,7 @@ update_dns (NMDnsManager *self,
if (update) {
switch (priv->rc_manager) {
- case NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE:
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK:
case NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE:
result = update_resolv_conf (self, searches, nameservers, options, error, priv->rc_manager);
resolv_conf_updated = TRUE;
@@ -1038,7 +1122,7 @@ update_dns (NMDnsManager *self,
if (result == SR_NOTFOUND) {
_LOGD ("update-dns: program not available, writing to resolv.conf");
g_clear_error (error);
- result = update_resolv_conf (self, searches, nameservers, options, error, NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE);
+ result = update_resolv_conf (self, searches, nameservers, options, error, NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK);
resolv_conf_updated = TRUE;
}
}
@@ -1046,7 +1130,7 @@ update_dns (NMDnsManager *self,
/* Unless we've already done it, update private resolv.conf in NMRUNDIR
ignoring any errors */
if (!resolv_conf_updated)
- update_resolv_conf (self, searches, nameservers, options, NULL, _NM_DNS_MANAGER_RESOLV_CONF_MAN_INTERNAL_ONLY);
+ update_resolv_conf (self, searches, nameservers, options, NULL, NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED);
/* signal that resolv.conf was changed */
if (update && result == SR_SUCCESS)
@@ -1124,166 +1208,148 @@ plugin_child_quit (NMDnsPlugin *plugin, int exit_status, gpointer user_data)
plugin_child_quit_update_dns (self);
}
-gboolean
-nm_dns_manager_add_ip4_config (NMDnsManager *self,
- const char *iface,
- NMIP4Config *config,
- NMDnsIPConfigType cfg_type)
+static void
+ip_config_dns_priority_changed (gpointer config,
+ GParamSpec *pspec,
+ NMDnsManager *self)
{
- NMDnsManagerPrivate *priv;
- GError *error = NULL;
-
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (config != NULL, FALSE);
-
- priv = NM_DNS_MANAGER_GET_PRIVATE (self);
-
- g_object_set_data_full (G_OBJECT (config), IP_CONFIG_IFACE_TAG, g_strdup (iface), g_free);
-
- switch (cfg_type) {
- case NM_DNS_IP_CONFIG_TYPE_VPN:
- if (priv->ip4_vpn_config && priv->ip4_vpn_config != config) {
- priv->configs = g_slist_remove (priv->configs, priv->ip4_vpn_config);
- g_object_unref (priv->ip4_vpn_config);
- }
- priv->ip4_vpn_config = config;
- break;
- case NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE:
- if (priv->ip4_device_config && priv->ip4_device_config != config) {
- priv->configs = g_slist_remove (priv->configs, priv->ip4_device_config);
- g_object_unref (priv->ip4_device_config);
- }
- priv->ip4_device_config = config;
- break;
- default:
- break;
- }
+ NM_DNS_MANAGER_GET_PRIVATE (self)->need_sort = TRUE;
+}
- /* Don't allow the same zone added twice */
- if (!g_slist_find (priv->configs, config))
- priv->configs = g_slist_append (priv->configs, g_object_ref (config));
+static void
+forget_data (NMDnsManager *self, NMDnsIPConfigData *data)
+{
+ NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
- if (!priv->updates_queue && !update_dns (self, FALSE, &error)) {
- _LOGW ("could not commit DNS changes: %s", error->message);
- g_clear_error (&error);
- }
+ if (data == priv->best_conf4)
+ priv->best_conf4 = NULL;
+ else if (data == priv->best_conf6)
+ priv->best_conf6 = NULL;
- return TRUE;
+ g_signal_handlers_disconnect_by_func (data->config, ip_config_dns_priority_changed, self);
}
-gboolean
-nm_dns_manager_remove_ip4_config (NMDnsManager *self, NMIP4Config *config)
+static gboolean
+nm_dns_manager_add_ip_config (NMDnsManager *self,
+ const char *iface,
+ gpointer config,
+ NMDnsIPConfigType cfg_type)
{
NMDnsManagerPrivate *priv;
GError *error = NULL;
+ NMDnsIPConfigData *data;
+ gboolean v4 = NM_IS_IP4_CONFIG (config);
+ guint i;
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (config != NULL, FALSE);
+ g_return_val_if_fail (NM_IS_DNS_MANAGER (self), FALSE);
+ g_return_val_if_fail (config, FALSE);
+ g_return_val_if_fail (iface && iface[0], FALSE);
priv = NM_DNS_MANAGER_GET_PRIVATE (self);
- /* Can't remove it if it wasn't in the list to begin with */
- if (!g_slist_find (priv->configs, config))
- return FALSE;
-
- priv->configs = g_slist_remove (priv->configs, config);
-
- if (config == priv->ip4_vpn_config)
- priv->ip4_vpn_config = NULL;
- if (config == priv->ip4_device_config)
- priv->ip4_device_config = NULL;
+ for (i = 0; i < priv->configs->len; i++) {
+ data = priv->configs->pdata[i];
+ if (data->config == config) {
+ if ( nm_streq (data->iface, iface)
+ && data->type == cfg_type)
+ return FALSE;
+ else {
+ forget_data (self, data);
+ g_ptr_array_remove_index_fast (priv->configs, i);
+ break;
+ }
+ }
+ }
- g_object_unref (config);
+ data = ip_config_data_new (config, cfg_type, iface);
+ g_ptr_array_add (priv->configs, data);
+ g_signal_connect (config,
+ v4 ?
+ "notify::" NM_IP4_CONFIG_DNS_PRIORITY :
+ "notify::" NM_IP6_CONFIG_DNS_PRIORITY,
+ (GCallback) ip_config_dns_priority_changed, self);
+ priv->need_sort = TRUE;
+
+ if (cfg_type == NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE) {
+ /* Only one best-device per IP version is allowed */
+ if (v4) {
+ if (priv->best_conf4)
+ priv->best_conf4->type = NM_DNS_IP_CONFIG_TYPE_DEFAULT;
+ priv->best_conf4 = data;
+ } else {
+ if (priv->best_conf6)
+ priv->best_conf6->type = NM_DNS_IP_CONFIG_TYPE_DEFAULT;
+ priv->best_conf6 = data;
+ }
+ }
if (!priv->updates_queue && !update_dns (self, FALSE, &error)) {
_LOGW ("could not commit DNS changes: %s", error->message);
g_clear_error (&error);
}
- g_object_set_data (G_OBJECT (config), IP_CONFIG_IFACE_TAG, NULL);
-
return TRUE;
}
gboolean
+nm_dns_manager_add_ip4_config (NMDnsManager *self,
+ const char *iface,
+ NMIP4Config *config,
+ NMDnsIPConfigType cfg_type)
+{
+ return nm_dns_manager_add_ip_config (self, iface, config, cfg_type);
+}
+
+gboolean
nm_dns_manager_add_ip6_config (NMDnsManager *self,
const char *iface,
NMIP6Config *config,
NMDnsIPConfigType cfg_type)
{
+ return nm_dns_manager_add_ip_config (self, iface, config, cfg_type);
+}
+
+static gboolean
+nm_dns_manager_remove_ip_config (NMDnsManager *self, gpointer config)
+{
NMDnsManagerPrivate *priv;
GError *error = NULL;
+ NMDnsIPConfigData *data;
+ guint i;
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (config != NULL, FALSE);
+ g_return_val_if_fail (NM_IS_DNS_MANAGER (self), FALSE);
+ g_return_val_if_fail (config, FALSE);
priv = NM_DNS_MANAGER_GET_PRIVATE (self);
- g_object_set_data_full (G_OBJECT (config), IP_CONFIG_IFACE_TAG, g_strdup (iface), g_free);
+ for (i = 0; i < priv->configs->len; i++) {
+ data = priv->configs->pdata[i];
- switch (cfg_type) {
- case NM_DNS_IP_CONFIG_TYPE_VPN:
- if (priv->ip6_vpn_config && priv->ip6_vpn_config != config) {
- priv->configs = g_slist_remove (priv->configs, priv->ip6_vpn_config);
- g_object_unref (priv->ip6_vpn_config);
- }
- priv->ip6_vpn_config = config;
- break;
- case NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE:
- if (priv->ip6_device_config && priv->ip6_device_config != config) {
- priv->configs = g_slist_remove (priv->configs, priv->ip6_device_config);
- g_object_unref (priv->ip6_device_config);
- }
- priv->ip6_device_config = config;
- break;
- default:
- break;
- }
+ if (data->config == config) {
+ forget_data (self, data);
+ g_ptr_array_remove_index (priv->configs, i);
- /* Don't allow the same zone added twice */
- if (!g_slist_find (priv->configs, config))
- priv->configs = g_slist_append (priv->configs, g_object_ref (config));
+ if (!priv->updates_queue && !update_dns (self, FALSE, &error)) {
+ _LOGW ("could not commit DNS changes: %s", error->message);
+ g_clear_error (&error);
+ }
- if (!priv->updates_queue && !update_dns (self, FALSE, &error)) {
- _LOGW ("could not commit DNS changes: %s", error->message);
- g_clear_error (&error);
+ return TRUE;
+ }
}
+ return FALSE;
+}
- return TRUE;
+gboolean
+nm_dns_manager_remove_ip4_config (NMDnsManager *self, NMIP4Config *config)
+{
+ return nm_dns_manager_remove_ip_config (self, config);
}
gboolean
nm_dns_manager_remove_ip6_config (NMDnsManager *self, NMIP6Config *config)
{
- NMDnsManagerPrivate *priv;
- GError *error = NULL;
-
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (config != NULL, FALSE);
-
- priv = NM_DNS_MANAGER_GET_PRIVATE (self);
-
- /* Can't remove it if it wasn't in the list to begin with */
- if (!g_slist_find (priv->configs, config))
- return FALSE;
-
- priv->configs = g_slist_remove (priv->configs, config);
-
- if (config == priv->ip6_vpn_config)
- priv->ip6_vpn_config = NULL;
- if (config == priv->ip6_device_config)
- priv->ip6_device_config = NULL;
-
- g_object_unref (config);
-
- if (!priv->updates_queue && !update_dns (self, FALSE, &error)) {
- _LOGW ("could not commit DNS changes: %s", error->message);
- g_clear_error (&error);
- }
-
- g_object_set_data (G_OBJECT (config), IP_CONFIG_IFACE_TAG, NULL);
-
- return TRUE;
+ return nm_dns_manager_remove_ip_config (self, config);
}
void
@@ -1324,10 +1390,21 @@ nm_dns_manager_set_hostname (NMDnsManager *self,
}
}
-NMDnsManagerResolvConfMode
-nm_dns_manager_get_resolv_conf_mode (NMDnsManager *self)
+gboolean
+nm_dns_manager_get_resolv_conf_explicit (NMDnsManager *self)
{
- return NM_DNS_MANAGER_GET_PRIVATE (self)->resolv_conf_mode;
+ NMDnsManagerPrivate *priv;
+
+ g_return_val_if_fail (NM_IS_DNS_MANAGER (self), FALSE);
+
+ priv = NM_DNS_MANAGER_GET_PRIVATE (self);
+
+ if ( NM_IN_SET (priv->rc_manager, NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED,
+ NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE)
+ || priv->plugin)
+ return FALSE;
+
+ return TRUE;
}
void
@@ -1360,6 +1437,11 @@ nm_dns_manager_end_updates (NMDnsManager *self, const char *func)
priv = NM_DNS_MANAGER_GET_PRIVATE (self);
g_return_if_fail (priv->updates_queue > 0);
+ if (priv->need_sort) {
+ g_ptr_array_sort (priv->configs, ip_config_data_ptr_compare);
+ priv->need_sort = FALSE;
+ }
+
compute_hash (self, nm_config_data_get_global_dns_config (nm_config_get_data (priv->config)), new);
changed = (memcmp (new, priv->prev_hash, sizeof (new)) != 0) ? TRUE : FALSE;
_LOGD ("(%s): DNS configuration %s", func, changed ? "changed" : "did not change");
@@ -1382,22 +1464,31 @@ nm_dns_manager_end_updates (NMDnsManager *self, const char *func)
/******************************************************************/
+static gboolean
+_clear_plugin (NMDnsManager *self)
+{
+ NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
+
+ if (priv->plugin) {
+ g_signal_handlers_disconnect_by_func (priv->plugin, plugin_failed, self);
+ g_signal_handlers_disconnect_by_func (priv->plugin, plugin_child_quit, self);
+ g_clear_object (&priv->plugin);
+ return TRUE;
+ }
+ return FALSE;
+}
+
static bool
-_get_resconf_immutable (int *immutable_cached)
+_get_resconf_immutable (void)
{
int fd, flags;
- int immutable;
-
- immutable = *immutable_cached;
- if (!NM_IN_SET (immutable, FALSE, TRUE)) {
- immutable = FALSE;
- fd = open (_PATH_RESCONF, O_RDONLY);
- if (fd != -1) {
- if (ioctl (fd, FS_IOC_GETFLAGS, &flags) != -1)
- immutable = NM_FLAGS_HAS (flags, FS_IMMUTABLE_FL);
- close (fd);
- }
- *immutable_cached = immutable;
+ bool immutable = FALSE;
+
+ fd = open (_PATH_RESCONF, O_RDONLY);
+ if (fd != -1) {
+ if (ioctl (fd, FS_IOC_GETFLAGS, &flags) != -1)
+ immutable = NM_FLAGS_HAS (flags, FS_IMMUTABLE_FL);
+ close (fd);
}
return immutable;
}
@@ -1408,96 +1499,80 @@ static void
init_resolv_conf_mode (NMDnsManager *self)
{
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
- const char *mode, *mode_unknown;
- int immutable = -1;
+ NMDnsManagerResolvConfManager rc_manager;
+ const char *mode;
+ gboolean plugin_changed = FALSE;
mode = nm_config_data_get_dns_mode (nm_config_get_data (priv->config));
- if ( priv->mode_initialized
- && nm_streq0 (mode, priv->last_mode)
- && ( nm_streq0 (mode, "none")
- || priv->last_immutable == _get_resconf_immutable (&immutable))) {
- /* we call init_resolv_conf_mode() on every SIGHUP to possibly reload
- * when either "mode" or "immutable" changed. However, we don't want to
- * re-create the plugin, when the paramters didn't actually change. So
- * detect that we would recreate the same plugin and return early. */
- return;
- }
-
- priv->mode_initialized = TRUE;
- g_free (priv->last_mode);
- priv->last_mode = g_strdup (mode);
- priv->last_immutable = FALSE;
- g_clear_object (&priv->plugin);
- priv->resolv_conf_mode = NM_DNS_MANAGER_RESOLV_CONF_UNMANAGED;
-
- if (nm_streq0 (mode, "none")) {
- _LOGI ("%s%s", "set resolv-conf-mode: ", "none");
- return;
+ if (nm_streq0 (mode, "none"))
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED;
+ else if (_get_resconf_immutable ())
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE;
+ else {
+ const char *man;
+
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN;
+ man = nm_config_data_get_rc_manager (nm_config_get_data (priv->config));
+
+again:
+ if (!man) {
+ /* nop */
+ } else if (NM_IN_STRSET (man, "symlink", "none"))
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK;
+ else if (nm_streq (man, "file"))
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE;
+ else if (nm_streq (man, "resolvconf"))
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF;
+ else if (nm_streq (man, "netconfig"))
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG;
+ else if (nm_streq (man, "unmanaged"))
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED;
+
+ if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN) {
+ if (man) {
+ _LOGW ("init: unknown resolv.conf manager \"%s\", fallback to \"%s\"",
+ man, ""NM_CONFIG_DEFAULT_DNS_RC_MANAGER);
+ }
+ man = ""NM_CONFIG_DEFAULT_DNS_RC_MANAGER;
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK;
+ goto again;
+ }
}
- priv->last_immutable = _get_resconf_immutable (&immutable);
-
- if (NM_IN_STRSET (mode, "dnsmasq", "unbound")) {
- if (!immutable)
- priv->resolv_conf_mode = NM_DNS_MANAGER_RESOLV_CONF_PROXY;
- if (nm_streq (mode, "dnsmasq"))
+ if (nm_streq0 (mode, "dnsmasq")) {
+ if (!NM_IS_DNS_DNSMASQ (priv->plugin)) {
+ _clear_plugin (self);
priv->plugin = nm_dns_dnsmasq_new ();
- else
+ plugin_changed = TRUE;
+ }
+ } else if (nm_streq0 (mode, "unbound")) {
+ if (!NM_IS_DNS_UNBOUND (priv->plugin)) {
+ _clear_plugin (self);
priv->plugin = nm_dns_unbound_new ();
+ plugin_changed = TRUE;
+ }
+ } else {
+ if (!NM_IN_STRSET (mode, NULL, "none", "default")) {
+ _LOGW ("init: unknown dns mode '%s'", mode);
+ mode = "default";
+ }
+ if (_clear_plugin (self))
+ plugin_changed = TRUE;
+ }
+ if (plugin_changed && priv->plugin) {
g_signal_connect (priv->plugin, NM_DNS_PLUGIN_FAILED, G_CALLBACK (plugin_failed), self);
g_signal_connect (priv->plugin, NM_DNS_PLUGIN_CHILD_QUIT, G_CALLBACK (plugin_child_quit), self);
-
- _NMLOG (immutable ? LOGL_WARN : LOGL_INFO,
- "%s%s%s%s%s%s",
- "set resolv-conf-mode: ",
- immutable ? "none" : mode,
- ", plugin=\"", nm_dns_plugin_get_name (priv->plugin), "\"",
- immutable ? ", resolv.conf immutable" : "");
- return;
}
- if (!immutable)
- priv->resolv_conf_mode = NM_DNS_MANAGER_RESOLV_CONF_EXPLICIT;
-
- mode_unknown = mode && !nm_streq (mode, "default") ? mode : NULL;
- _NMLOG (mode_unknown ? LOGL_WARN : LOGL_INFO,
- "%s%s%s%s%s%s",
- "set resolv-conf-mode: ",
- immutable ? "none" : "default",
- NM_PRINT_FMT_QUOTED (mode_unknown, " -- unknown configuration '", mode_unknown, "'", ""),
- immutable ? ", resolv.conf immutable" : "");
-}
-
-static void
-init_resolv_conf_manager (NMDnsManager *self)
-{
- NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
- const char *man;
-
- man = nm_config_data_get_rc_manager (nm_config_get_data (priv->config));
- if (!g_strcmp0 (man, "none"))
- priv->rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE;
- else if (nm_streq0 (man, "file"))
- priv->rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE;
- else if (!g_strcmp0 (man, "resolvconf"))
- priv->rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF;
- else if (!g_strcmp0 (man, "netconfig"))
- priv->rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG;
- else {
-#if defined(RESOLVCONF_SELECTED)
- priv->rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF;
-#elif defined(NETCONFIG_SELECTED)
- priv->rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG;
-#else
- priv->rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE;
-#endif
- if (man)
- _LOGW ("unknown resolv.conf manager '%s'", man);
+ if ( plugin_changed
+ || priv->rc_manager != rc_manager) {
+ priv->rc_manager = rc_manager;
+ _LOGI ("init: dns=%s, rc-manager=%s%s%s%s",
+ mode, _rc_manager_to_string (rc_manager),
+ NM_PRINT_FMT_QUOTED (priv->plugin, ", plugin=", nm_dns_plugin_get_name (priv->plugin), "", ""));
}
-
- _LOGI ("using resolv.conf manager '%s'", _rc_manager_to_string (priv->rc_manager));
}
static void
@@ -1510,6 +1585,7 @@ config_changed_cb (NMConfig *config,
GError *error = NULL;
if (NM_FLAGS_ANY (changes, NM_CONFIG_CHANGE_DNS_MODE |
+ NM_CONFIG_CHANGE_RC_MANAGER |
NM_CONFIG_CHANGE_SIGHUP)) {
/* reload the resolv-conf mode also on SIGHUP (when DNS_MODE didn't change).
* The reason is, that the configuration also depends on whether resolv.conf
@@ -1518,15 +1594,12 @@ config_changed_cb (NMConfig *config,
init_resolv_conf_mode (self);
}
- if (NM_FLAGS_HAS (changes, NM_CONFIG_CHANGE_RC_MANAGER))
- init_resolv_conf_manager (self);
-
if (NM_FLAGS_ANY (changes, NM_CONFIG_CHANGE_SIGHUP |
NM_CONFIG_CHANGE_SIGUSR1 |
NM_CONFIG_CHANGE_DNS_MODE |
NM_CONFIG_CHANGE_RC_MANAGER |
NM_CONFIG_CHANGE_GLOBAL_DNS_CONFIG)) {
- if (!update_dns (self, TRUE, &error)) {
+ if (!update_dns (self, FALSE, &error)) {
_LOGW ("could not commit DNS changes: %s", error->message);
g_clear_error (&error);
}
@@ -1536,21 +1609,23 @@ config_changed_cb (NMConfig *config,
static void
nm_dns_manager_init (NMDnsManager *self)
{
- NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
+ NMDnsManagerPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_DNS_MANAGER, NMDnsManagerPrivate);
+
+ self->priv = priv;
_LOGT ("creating...");
priv->config = g_object_ref (nm_config_get ());
+ priv->configs = g_ptr_array_new_full (8, ip_config_data_destroy);
+
/* Set the initial hash */
- compute_hash (self, nm_config_data_get_global_dns_config (nm_config_get_data (priv->config)),
- NM_DNS_MANAGER_GET_PRIVATE (self)->hash);
+ compute_hash (self, NULL, NM_DNS_MANAGER_GET_PRIVATE (self)->hash);
g_signal_connect (G_OBJECT (priv->config),
NM_CONFIG_SIGNAL_CONFIG_CHANGED,
G_CALLBACK (config_changed_cb),
self);
init_resolv_conf_mode (self);
- init_resolv_conf_manager (self);
}
static void
@@ -1558,17 +1633,13 @@ dispose (GObject *object)
{
NMDnsManager *self = NM_DNS_MANAGER (object);
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
+ NMDnsIPConfigData *data;
GError *error = NULL;
+ guint i;
_LOGT ("disposing");
- if (priv->plugin) {
- g_signal_handlers_disconnect_by_func (priv->plugin, plugin_failed, self);
- g_signal_handlers_disconnect_by_func (priv->plugin, plugin_child_quit, self);
- g_clear_object (&priv->plugin);
- }
-
- g_clear_pointer (&priv->last_mode, g_free);
+ _clear_plugin (self);
/* If we're quitting, leave a valid resolv.conf in place, not one
* pointing to 127.0.0.1 if any plugins were active. Thus update
@@ -1586,8 +1657,14 @@ dispose (GObject *object)
g_clear_object (&priv->config);
}
- g_slist_free_full (priv->configs, g_object_unref);
- priv->configs = NULL;
+ if (priv->configs) {
+ for (i = 0; i < priv->configs->len; i++) {
+ data = priv->configs->pdata[i];
+ forget_data (self, data);
+ }
+ g_ptr_array_free (priv->configs, TRUE);
+ priv->configs = NULL;
+ }
G_OBJECT_CLASS (nm_dns_manager_parent_class)->dispose (object);
}
@@ -1595,7 +1672,8 @@ dispose (GObject *object)
static void
finalize (GObject *object)
{
- NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (object);
+ NMDnsManager *self = NM_DNS_MANAGER (object);
+ NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
g_free (priv->hostname);
diff --git a/src/dns-manager/nm-dns-manager.h b/src/dns-manager/nm-dns-manager.h
index f1293f7ebb..a82fdfc036 100644
--- a/src/dns-manager/nm-dns-manager.h
+++ b/src/dns-manager/nm-dns-manager.h
@@ -28,13 +28,24 @@
#include "nm-ip4-config.h"
#include "nm-ip6-config.h"
+G_BEGIN_DECLS
+
typedef enum {
NM_DNS_IP_CONFIG_TYPE_DEFAULT = 0,
NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE,
NM_DNS_IP_CONFIG_TYPE_VPN
} NMDnsIPConfigType;
-G_BEGIN_DECLS
+enum {
+ NM_DNS_PRIORITY_DEFAULT_NORMAL = 100,
+ NM_DNS_PRIORITY_DEFAULT_VPN = 50,
+};
+
+typedef struct {
+ gpointer config;
+ NMDnsIPConfigType type;
+ char *iface;
+} NMDnsIPConfigData;
#define NM_TYPE_DNS_MANAGER (nm_dns_manager_get_type ())
#define NM_DNS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NM_TYPE_DNS_MANAGER, NMDnsManager))
@@ -45,8 +56,12 @@ G_BEGIN_DECLS
#define NM_DNS_MANAGER_CONFIG_CHANGED "config-changed"
+struct _NMDnsManagerPrivate;
+
typedef struct {
GObject parent;
+ /* private */
+ struct _NMDnsManagerPrivate *priv;
} NMDnsManager;
typedef struct {
@@ -84,32 +99,17 @@ void nm_dns_manager_set_hostname (NMDnsManager *self,
const char *hostname);
/**
- * NMDnsManagerResolvConfMode:
- * @NM_DNS_MANAGER_RESOLV_CONF_UNMANAGED: NM is not managing resolv.conf
- * @NM_DNS_MANAGER_RESOLV_CONF_EXPLICIT: NM is managing resolv.conf by
- * adding and removing "nameserver" lines corresponding to the currently
- * active connections
- * @NM_DNS_MANAGER_RESOLV_CONF_PROXY: NM is managing resolv.conf by
- * pointing it to some other service (eg, dnsmasq) that knows the
- * nameservers corresponding to the currently active connections.
- *
- * NMDnsManager's behavior toward /etc/resolv.conf.
- */
-typedef enum {
- NM_DNS_MANAGER_RESOLV_CONF_UNMANAGED,
- NM_DNS_MANAGER_RESOLV_CONF_EXPLICIT,
- NM_DNS_MANAGER_RESOLV_CONF_PROXY
-} NMDnsManagerResolvConfMode;
-
-/**
* NMDnsManagerResolvConfManager
- * @_NM_DNS_MANAGER_RESOLV_CONF_MAN_INTERNAL_ONLY: dummy-manager
- * to not write resolv.conf at all, only the internal file in
- * NM's run state directory.
- * @NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE: NM writes resolv.conf
+ * @NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN: unspecified rc-manager.
+ * @NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED: do not touch /etc/resolv.conf
+ * (but still write the internal copy -- unless it is symlinked by
+ * /etc/resolv.conf)
+ * @NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE: similar to "unmanaged",
+ * but indicates that resolv.conf cannot be modified.
+ * @NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK: NM writes resolv.conf
* by symlinking it to the run state directory.
- * @NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE: Like NONE, but instead of symlinking
- * resolv.conf, write it as a file.
+ * @NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE: Like SYMLINK, but instead of
+ * symlinking /etc/resolv.conf, write it as a file.
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF: NM is managing resolv.conf
through resolvconf
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG: NM is managing resolv.conf
@@ -118,14 +118,16 @@ typedef enum {
* NMDnsManager's management of resolv.conf
*/
typedef enum {
- _NM_DNS_MANAGER_RESOLV_CONF_MAN_INTERNAL_ONLY,
- NM_DNS_MANAGER_RESOLV_CONF_MAN_NONE,
+ NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN,
+ NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED,
+ NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE,
+ NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK,
NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE,
NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF,
NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG,
} NMDnsManagerResolvConfManager;
-NMDnsManagerResolvConfMode nm_dns_manager_get_resolv_conf_mode (NMDnsManager *self);
+gboolean nm_dns_manager_get_resolv_conf_explicit (NMDnsManager *self);
G_END_DECLS
diff --git a/src/dns-manager/nm-dns-plugin.c b/src/dns-manager/nm-dns-plugin.c
index 6ab18faa9c..38eaf060c0 100644
--- a/src/dns-manager/nm-dns-plugin.c
+++ b/src/dns-manager/nm-dns-plugin.c
@@ -74,18 +74,14 @@ static guint signals[LAST_SIGNAL] = { 0 };
gboolean
nm_dns_plugin_update (NMDnsPlugin *self,
- const GSList *vpn_configs,
- const GSList *dev_configs,
- const GSList *other_configs,
+ const NMDnsIPConfigData **configs,
const NMGlobalDnsConfig *global_config,
const char *hostname)
{
g_return_val_if_fail (NM_DNS_PLUGIN_GET_CLASS (self)->update != NULL, FALSE);
return NM_DNS_PLUGIN_GET_CLASS (self)->update (self,
- vpn_configs,
- dev_configs,
- other_configs,
+ configs,
global_config,
hostname);
}
diff --git a/src/dns-manager/nm-dns-plugin.h b/src/dns-manager/nm-dns-plugin.h
index 7ecaa424dc..d715582cbe 100644
--- a/src/dns-manager/nm-dns-plugin.h
+++ b/src/dns-manager/nm-dns-plugin.h
@@ -20,6 +20,7 @@
#define __NETWORKMANAGER_DNS_PLUGIN_H__
#include "nm-default.h"
+#include "nm-dns-manager.h"
#include "nm-config-data.h"
@@ -33,8 +34,6 @@
#define NM_DNS_PLUGIN_FAILED "failed"
#define NM_DNS_PLUGIN_CHILD_QUIT "child-quit"
-#define IP_CONFIG_IFACE_TAG "dns-manager-iface"
-
typedef struct {
GObject parent;
} NMDnsPlugin;
@@ -44,18 +43,13 @@ typedef struct {
/* Methods */
- /* Called when DNS information is changed. 'vpn_configs' is a list of
- * NMIP4Config or NMIP6Config objects from VPN connections, while
- * 'dev_configs' is a list of NMPI4Config or NMIP6Config objects from
- * active devices. 'other_configs' represent other IP configuration that
- * may be in-use. 'global_config' is the optional global DNS
- * configuration. Configs of the same IP version are sorted in priority
- * order.
+ /* Called when DNS information is changed. 'configs' is an array
+ * of pointers to NMDnsIPConfigData sorted by priority.
+ * 'global_config' is the optional global DNS
+ * configuration.
*/
gboolean (*update) (NMDnsPlugin *self,
- const GSList *vpn_configs,
- const GSList *dev_configs,
- const GSList *other_configs,
+ const NMDnsIPConfigData **configs,
const NMGlobalDnsConfig *global_config,
const char *hostname);
@@ -92,9 +86,7 @@ gboolean nm_dns_plugin_is_caching (NMDnsPlugin *self);
const char *nm_dns_plugin_get_name (NMDnsPlugin *self);
gboolean nm_dns_plugin_update (NMDnsPlugin *self,
- const GSList *vpn_configs,
- const GSList *dev_configs,
- const GSList *other_configs,
+ const NMDnsIPConfigData **configs,
const NMGlobalDnsConfig *global_config,
const char *hostname);
diff --git a/src/dns-manager/nm-dns-unbound.c b/src/dns-manager/nm-dns-unbound.c
index 4c1af1039f..66a287fdf5 100644
--- a/src/dns-manager/nm-dns-unbound.c
+++ b/src/dns-manager/nm-dns-unbound.c
@@ -28,9 +28,7 @@ G_DEFINE_TYPE (NMDnsUnbound, nm_dns_unbound, NM_TYPE_DNS_PLUGIN)
static gboolean
update (NMDnsPlugin *plugin,
- const GSList *vpn_configs,
- const GSList *dev_configs,
- const GSList *other_configs,
+ const NMDnsIPConfigData **configs,
const NMGlobalDnsConfig *global_config,
const char *hostname)
{
diff --git a/src/dnsmasq-manager/nm-dnsmasq-manager.c b/src/dnsmasq-manager/nm-dnsmasq-manager.c
index 764aba2905..7b72594434 100644
--- a/src/dnsmasq-manager/nm-dnsmasq-manager.c
+++ b/src/dnsmasq-manager/nm-dnsmasq-manager.c
@@ -65,60 +65,6 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
-static void
-nm_dnsmasq_manager_init (NMDnsMasqManager *manager)
-{
-}
-
-static void
-finalize (GObject *object)
-{
- NMDnsMasqManagerPrivate *priv = NM_DNSMASQ_MANAGER_GET_PRIVATE (object);
-
- nm_dnsmasq_manager_stop (NM_DNSMASQ_MANAGER (object));
-
- g_free (priv->iface);
- g_free (priv->pidfile);
-
- G_OBJECT_CLASS (nm_dnsmasq_manager_parent_class)->finalize (object);
-}
-
-static void
-nm_dnsmasq_manager_class_init (NMDnsMasqManagerClass *manager_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
-
- g_type_class_add_private (manager_class, sizeof (NMDnsMasqManagerPrivate));
-
- object_class->finalize = finalize;
-
- /* signals */
- signals[STATE_CHANGED] =
- g_signal_new (NM_DNS_MASQ_MANAGER_STATE_CHANGED,
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMDnsMasqManagerClass, state_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE, 1,
- G_TYPE_UINT);
-}
-
-NMDnsMasqManager *
-nm_dnsmasq_manager_new (const char *iface)
-{
- NMDnsMasqManager *manager;
- NMDnsMasqManagerPrivate *priv;
-
- manager = (NMDnsMasqManager *) g_object_new (NM_TYPE_DNSMASQ_MANAGER, NULL);
-
- priv = NM_DNSMASQ_MANAGER_GET_PRIVATE (manager);
- priv->iface = g_strdup (iface);
- priv->pidfile = g_strdup_printf (RUNSTATEDIR "/nm-dnsmasq-%s.pid", iface);
-
- return manager;
-}
-
typedef struct {
GPtrArray *array;
GStringChunk *chunk;
@@ -165,36 +111,6 @@ nm_cmd_line_add_string (NMCmdLine *cmd, const char *str)
/*******************************************/
static void
-dm_exit_code (guint dm_exit_status)
-{
- char *msg = "Unknown error";
-
- switch (dm_exit_status) {
- case 1:
- msg = "Configuration problem";
- break;
- case 2:
- msg = "Network access problem (address in use; permissions; etc)";
- break;
- case 3:
- msg = "Filesystem problem (missing file/directory; permissions; etc)";
- break;
- case 4:
- msg = "Memory allocation failure";
- break;
- case 5:
- msg = "Other problem";
- break;
- default:
- if (dm_exit_status >= 11)
- msg = "Lease-script 'init' process failure";
- break;
- }
-
- _LOGW ("dnsmasq exited with error: %s (%d)", msg, dm_exit_status);
-}
-
-static void
dm_watch_cb (GPid pid, gint status, gpointer user_data)
{
NMDnsMasqManager *manager = NM_DNSMASQ_MANAGER (user_data);
@@ -203,8 +119,10 @@ dm_watch_cb (GPid pid, gint status, gpointer user_data)
if (WIFEXITED (status)) {
err = WEXITSTATUS (status);
- if (err != 0)
- dm_exit_code (err);
+ if (err != 0) {
+ _LOGW ("dnsmasq exited with error: %s",
+ nm_utils_dnsmasq_status_to_string (err, NULL, 0));
+ }
} else if (WIFSTOPPED (status)) {
_LOGW ("dnsmasq stopped unexpectedly with signal %d", WSTOPSIG (status));
} else if (WIFSIGNALED (status)) {
@@ -415,3 +333,56 @@ nm_dnsmasq_manager_stop (NMDnsMasqManager *manager)
unlink (priv->pidfile);
}
+
+NMDnsMasqManager *
+nm_dnsmasq_manager_new (const char *iface)
+{
+ NMDnsMasqManager *manager;
+ NMDnsMasqManagerPrivate *priv;
+
+ manager = (NMDnsMasqManager *) g_object_new (NM_TYPE_DNSMASQ_MANAGER, NULL);
+
+ priv = NM_DNSMASQ_MANAGER_GET_PRIVATE (manager);
+ priv->iface = g_strdup (iface);
+ priv->pidfile = g_strdup_printf (RUNSTATEDIR "/nm-dnsmasq-%s.pid", iface);
+
+ return manager;
+}
+
+static void
+nm_dnsmasq_manager_init (NMDnsMasqManager *manager)
+{
+}
+
+static void
+finalize (GObject *object)
+{
+ NMDnsMasqManagerPrivate *priv = NM_DNSMASQ_MANAGER_GET_PRIVATE (object);
+
+ nm_dnsmasq_manager_stop (NM_DNSMASQ_MANAGER (object));
+
+ g_free (priv->iface);
+ g_free (priv->pidfile);
+
+ G_OBJECT_CLASS (nm_dnsmasq_manager_parent_class)->finalize (object);
+}
+
+static void
+nm_dnsmasq_manager_class_init (NMDnsMasqManagerClass *manager_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
+
+ g_type_class_add_private (manager_class, sizeof (NMDnsMasqManagerPrivate));
+
+ object_class->finalize = finalize;
+
+ /* signals */
+ signals[STATE_CHANGED] =
+ g_signal_new (NM_DNS_MASQ_MANAGER_STATE_CHANGED,
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1,
+ G_TYPE_UINT);
+}
diff --git a/src/dnsmasq-manager/nm-dnsmasq-manager.h b/src/dnsmasq-manager/nm-dnsmasq-manager.h
index 47c88e6ea4..cc095d66c8 100644
--- a/src/dnsmasq-manager/nm-dnsmasq-manager.h
+++ b/src/dnsmasq-manager/nm-dnsmasq-manager.h
@@ -48,9 +48,6 @@ typedef struct {
typedef struct {
GObjectClass parent;
-
- /* Signals */
- void (*state_changed) (NMDnsMasqManager *manager, NMDnsMasqStatus status);
} NMDnsMasqManagerClass;
GType nm_dnsmasq_manager_get_type (void);
diff --git a/src/dnsmasq-manager/tests/test-dnsmasq-utils.c b/src/dnsmasq-manager/tests/test-dnsmasq-utils.c
index aeec5879a1..cf6dab50bb 100644
--- a/src/dnsmasq-manager/tests/test-dnsmasq-utils.c
+++ b/src/dnsmasq-manager/tests/test-dnsmasq-utils.c
@@ -24,7 +24,7 @@
#include "nm-dnsmasq-utils.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
static void
test_address_ranges (void)
diff --git a/src/main-utils.c b/src/main-utils.c
index 8624280221..b94e8b2199 100644
--- a/src/main-utils.c
+++ b/src/main-utils.c
@@ -31,7 +31,6 @@
#include <glib/gstdio.h>
#include <glib-unix.h>
-#include <gmodule.h>
#include "main-utils.h"
#include "NetworkManagerUtils.h"
diff --git a/src/main.c b/src/main.c
index 4616155d9a..c4782b609e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -31,7 +31,6 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <gmodule.h>
#include <string.h>
#include <sys/resource.h>
@@ -71,81 +70,10 @@ static struct {
char *opt_log_level;
char *opt_log_domains;
char *pidfile;
- char *state_file;
} global_opt = {
.become_daemon = TRUE,
};
-static gboolean
-parse_state_file (const char *filename,
- gboolean *net_enabled,
- gboolean *wifi_enabled,
- gboolean *wwan_enabled,
- GError **error)
-{
- GKeyFile *state_file;
- GError *tmp_error = NULL;
- gboolean wifi, net, wwan;
-
- g_return_val_if_fail (net_enabled != NULL, FALSE);
- g_return_val_if_fail (wifi_enabled != NULL, FALSE);
- g_return_val_if_fail (wwan_enabled != NULL, FALSE);
-
- state_file = g_key_file_new ();
- g_key_file_set_list_separator (state_file, ',');
- if (!g_key_file_load_from_file (state_file, filename, G_KEY_FILE_KEEP_COMMENTS, &tmp_error)) {
- gboolean ret = FALSE;
-
- /* This is kinda ugly; create the file and directory if it doesn't
- * exist yet. We can't rely on distros necessarily creating the
- * /var/lib/NetworkManager for us since we have to ensure that
- * users upgrading NM get this working too.
- */
- if (g_error_matches (tmp_error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
- char *data;
- gsize len = 0;
-
- g_clear_error (&tmp_error);
-
- /* Write out the initial state to the state file */
- g_key_file_set_boolean (state_file, "main", "NetworkingEnabled", *net_enabled);
- g_key_file_set_boolean (state_file, "main", "WirelessEnabled", *wifi_enabled);
- g_key_file_set_boolean (state_file, "main", "WWANEnabled", *wwan_enabled);
-
- data = g_key_file_to_data (state_file, &len, NULL);
- if (data)
- ret = g_file_set_contents (filename, data, len, error);
- g_free (data);
- } else {
- /* the error is not "No such file or directory" - propagate the error */
- g_propagate_error (error, tmp_error);
- }
-
- return ret;
- }
-
- /* Reading state bits of NetworkManager; an error leaves the passed-in state
- * value unchanged.
- */
- net = g_key_file_get_boolean (state_file, "main", "NetworkingEnabled", &tmp_error);
- if (tmp_error == NULL)
- *net_enabled = net;
- g_clear_error (&tmp_error);
-
- wifi = g_key_file_get_boolean (state_file, "main", "WirelessEnabled", &tmp_error);
- if (tmp_error == NULL)
- *wifi_enabled = wifi;
- g_clear_error (&tmp_error);
-
- wwan = g_key_file_get_boolean (state_file, "main", "WWANEnabled", &tmp_error);
- if (tmp_error == NULL)
- *wwan_enabled = wwan;
- g_clear_error (&tmp_error);
-
- g_key_file_free (state_file);
- return TRUE;
-}
-
static void
_set_g_fatal_warnings (void)
{
@@ -239,7 +167,6 @@ do_early_setup (int *argc, char **argv[], NMConfigCmdLineOptions *config_cli)
"PLATFORM,RFKILL,WIFI" },
{ "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &global_opt.g_fatal_warnings, N_("Make all warnings fatal"), NULL },
{ "pid-file", 'p', 0, G_OPTION_ARG_FILENAME, &global_opt.pidfile, N_("Specify the location of a PID file"), N_(NM_DEFAULT_PID_FILE) },
- { "state-file", 0, 0, G_OPTION_ARG_FILENAME, &global_opt.state_file, N_("State file location"), N_(NM_DEFAULT_SYSTEM_STATE_FILE) },
{ "run-from-build-dir", 0, 0, G_OPTION_ARG_NONE, &global_opt.run_from_build_dir, "Run from build directory", NULL },
{ "print-config", 0, 0, G_OPTION_ARG_NONE, &global_opt.print_config, N_("Print NetworkManager configuration and exit"), NULL },
{NULL}
@@ -255,7 +182,6 @@ do_early_setup (int *argc, char **argv[], NMConfigCmdLineOptions *config_cli)
exit (1);
global_opt.pidfile = global_opt.pidfile ? global_opt.pidfile : g_strdup (NM_DEFAULT_PID_FILE);
- global_opt.state_file = global_opt.state_file ? global_opt.state_file : g_strdup (NM_DEFAULT_SYSTEM_STATE_FILE);
}
/*
@@ -265,7 +191,6 @@ do_early_setup (int *argc, char **argv[], NMConfigCmdLineOptions *config_cli)
int
main (int argc, char *argv[])
{
- gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE;
gboolean success = FALSE;
NMConfig *config;
GError *error = NULL;
@@ -406,17 +331,12 @@ main (int argc, char *argv[])
nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting...");
- /* Parse the state file */
- if (!parse_state_file (global_opt.state_file, &net_enabled, &wifi_enabled, &wwan_enabled, &error)) {
- nm_log_err (LOGD_CORE, "State file %s parsing failed: %s",
- global_opt.state_file,
- error->message);
- /* Not a hard failure */
- }
- g_clear_error (&error);
-
nm_log_info (LOGD_CORE, "Read config: %s", nm_config_data_get_config_description (nm_config_get_data (config)));
nm_config_data_log (nm_config_get_data (config), "CONFIG: ", " ", NULL);
+
+ /* the first access to State causes the file to be read (and possibly print a warning) */
+ nm_config_state_get (config);
+
nm_log_dbg (LOGD_CORE, "WEXT support is %s",
#if HAVE_WEXT
"enabled"
@@ -427,10 +347,7 @@ main (int argc, char *argv[])
nm_auth_manager_setup (nm_config_get_auth_polkit (config));
- nm_manager_setup (global_opt.state_file,
- net_enabled,
- wifi_enabled,
- wwan_enabled);
+ nm_manager_setup ();
if (!nm_bus_manager_get_connection (nm_bus_manager_get ())) {
nm_log_warn (LOGD_CORE, "Failed to connect to D-Bus; only private bus is available");
@@ -482,6 +399,8 @@ done:
nm_manager_stop (nm_manager_get ());
+ nm_config_state_set (config, TRUE, TRUE);
+
if (global_opt.pidfile && wrote_pidfile)
unlink (global_opt.pidfile);
diff --git a/src/nm-audit-manager.c b/src/nm-audit-manager.c
index 728575f663..7096e81934 100644
--- a/src/nm-audit-manager.c
+++ b/src/nm-audit-manager.c
@@ -233,10 +233,10 @@ nm_audit_manager_audit_enabled (NMAuditManager *self)
void
_nm_audit_manager_log_connection_op (NMAuditManager *self, const char *file, guint line,
const char *func, const char *op, NMSettingsConnection *connection,
- gboolean result, gpointer subject_context, const char *reason)
+ gboolean result, const char *args, gpointer subject_context, const char *reason)
{
gs_unref_ptrarray GPtrArray *fields = NULL;
- AuditField uuid_field = { }, name_field = { };
+ AuditField uuid_field = { }, name_field = { }, args_field = { };
g_return_if_fail (op);
@@ -252,6 +252,11 @@ _nm_audit_manager_log_connection_op (NMAuditManager *self, const char *file, gui
g_ptr_array_add (fields, &name_field);
}
+ if (args) {
+ _audit_field_init_string (&args_field, "args", args, FALSE, BACKEND_ALL);
+ g_ptr_array_add (fields, &args_field);
+ }
+
_audit_log_helper (self, fields, file, line, func, op, result, subject_context, reason);
}
diff --git a/src/nm-audit-manager.h b/src/nm-audit-manager.h
index ed53be6921..ecf581efed 100644
--- a/src/nm-audit-manager.h
+++ b/src/nm-audit-manager.h
@@ -67,13 +67,13 @@ GType nm_audit_manager_get_type (void);
NMAuditManager *nm_audit_manager_get (void);
gboolean nm_audit_manager_audit_enabled (NMAuditManager *self);
-#define nm_audit_log_connection_op(op, connection, result, subject_context, reason) \
+#define nm_audit_log_connection_op(op, connection, result, args, subject_context, reason) \
G_STMT_START { \
NMAuditManager *_audit = nm_audit_manager_get (); \
\
if (nm_audit_manager_audit_enabled (_audit)) { \
_nm_audit_manager_log_connection_op (_audit, __FILE__, __LINE__, G_STRFUNC, \
- (op), (connection), (result), (subject_context), \
+ (op), (connection), (result), (args), (subject_context), \
(reason)); \
} \
} G_STMT_END
@@ -100,7 +100,8 @@ gboolean nm_audit_manager_audit_enabled (NMAuditManager *self);
void _nm_audit_manager_log_connection_op (NMAuditManager *self, const char *file, guint line,
const char *func, const char *op, NMSettingsConnection *connection,
- gboolean result, gpointer subject_context, const char *reason);
+ gboolean result, const char *args, gpointer subject_context,
+ const char *reason);
void _nm_audit_manager_log_control_op (NMAuditManager *self, const char *file, guint line,
const char *func, const char *op, const char *arg,
diff --git a/src/nm-auth-subject.c b/src/nm-auth-subject.c
index 86b873f0f2..eb496b28cb 100644
--- a/src/nm-auth-subject.c
+++ b/src/nm-auth-subject.c
@@ -37,10 +37,6 @@
#include "nm-enum-types.h"
#include "NetworkManagerUtils.h"
-G_DEFINE_TYPE (NMAuthSubject, nm_auth_subject, G_TYPE_OBJECT)
-
-#define NM_AUTH_SUBJECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_AUTH_SUBJECT, NMAuthSubjectPrivate))
-
enum {
PROP_0,
PROP_SUBJECT_TYPE,
@@ -61,6 +57,30 @@ typedef struct {
} unix_process;
} NMAuthSubjectPrivate;
+struct _NMAuthSubject {
+ GObject parent;
+ NMAuthSubjectPrivate _priv;
+};
+
+struct _NMAuthSubjectClass {
+ GObjectClass parent;
+};
+
+G_DEFINE_TYPE (NMAuthSubject, nm_auth_subject, G_TYPE_OBJECT)
+
+#define NM_AUTH_SUBJECT_GET_PRIVATE(self) \
+ ({ \
+ /* preserve the const-ness of self. Unfortunately, that
+ * way, @self cannot be a void pointer */ \
+ typeof (self) _self = (self); \
+ \
+ /* Get compiler error if variable is of wrong type */ \
+ _nm_unused const NMAuthSubject *_self2 = (_self); \
+ \
+ nm_assert (NM_IS_AUTH_SUBJECT (_self)); \
+ &_self->_priv; \
+ })
+
/**************************************************************/
#define CHECK_SUBJECT(self, error_value) \
@@ -252,7 +272,7 @@ nm_auth_subject_new_internal (void)
static void
get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
- NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (object);
+ NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE ((NMAuthSubject *) object);
switch (prop_id) {
case PROP_SUBJECT_TYPE:
@@ -276,7 +296,7 @@ get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
static void
set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
- NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (object);
+ NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE ((NMAuthSubject *) object);
NMAuthSubjectType subject_type;
const char *str;
gulong id;
@@ -317,8 +337,10 @@ set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *p
}
static void
-_clear_private (NMAuthSubjectPrivate *priv)
+_clear_private (NMAuthSubject *self)
{
+ NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (self);
+
priv->subject_type = NM_AUTH_SUBJECT_TYPE_INVALID;
priv->unix_process.pid = G_MAXULONG;
priv->unix_process.uid = G_MAXULONG;
@@ -328,7 +350,7 @@ _clear_private (NMAuthSubjectPrivate *priv)
static void
nm_auth_subject_init (NMAuthSubject *self)
{
- _clear_private (NM_AUTH_SUBJECT_GET_PRIVATE (self));
+ _clear_private (self);
}
static void
@@ -363,7 +385,7 @@ constructed (GObject *object)
/* Is the process already gone? Then fail creation of the auth subject
* by clearing the type. */
if (kill (priv->unix_process.pid, 0) != 0)
- _clear_private (priv);
+ _clear_private (self);
/* Otherwise, although we didn't detect a start_time, the process is still around.
* That could be due to procfs mounted with hidepid. So just accept the request.
@@ -378,16 +400,14 @@ constructed (GObject *object)
break;
}
- _clear_private (priv);
+ _clear_private (self);
g_return_if_reached ();
}
static void
finalize (GObject *object)
{
- NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (object);
-
- _clear_private (priv);
+ _clear_private ((NMAuthSubject *) object);
G_OBJECT_CLASS (nm_auth_subject_parent_class)->finalize (object);
}
@@ -397,8 +417,6 @@ nm_auth_subject_class_init (NMAuthSubjectClass *config_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (config_class);
- g_type_class_add_private (config_class, sizeof (NMAuthSubjectPrivate));
-
/* virtual methods */
object_class->get_property = get_property;
object_class->set_property = set_property;
diff --git a/src/nm-auth-subject.h b/src/nm-auth-subject.h
index 5f50705810..a0b6d14b2a 100644
--- a/src/nm-auth-subject.h
+++ b/src/nm-auth-subject.h
@@ -39,13 +39,7 @@ typedef enum {
#define NM_AUTH_SUBJECT_UNIX_PROCESS_PID "unix-process-pid"
#define NM_AUTH_SUBJECT_UNIX_PROCESS_UID "unix-process-uid"
-struct _NMAuthSubject {
- GObject parent;
-};
-
-typedef struct {
- GObjectClass parent;
-} NMAuthSubjectClass;
+typedef struct _NMAuthSubjectClass NMAuthSubjectClass;
GType nm_auth_subject_get_type (void);
diff --git a/src/nm-config.c b/src/nm-config.c
index 003a661f9e..e79bd68902 100644
--- a/src/nm-config.c
+++ b/src/nm-config.c
@@ -38,12 +38,27 @@
#define DEFAULT_SYSTEM_CONFIG_DIR NMLIBDIR "/conf.d"
#define DEFAULT_NO_AUTO_DEFAULT_FILE NMSTATEDIR "/no-auto-default.state"
#define DEFAULT_INTERN_CONFIG_FILE NMSTATEDIR "/NetworkManager-intern.conf"
+#define DEFAULT_STATE_FILE NMSTATEDIR "/NetworkManager.state"
+
+/*****************************************************************************/
+
+#define _NMLOG_PREFIX_NAME "config"
+#define _NMLOG_DOMAIN LOGD_CORE
+
+#define _NMLOG(level, ...) \
+ nm_log (level, _NMLOG_DOMAIN, \
+ "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
+ _NMLOG_PREFIX_NAME \
+ _NM_UTILS_MACRO_REST(__VA_ARGS__))
+
+/*****************************************************************************/
struct NMConfigCmdLineOptions {
char *config_main_file;
char *intern_config_file;
char *config_dir;
char *system_config_dir;
+ char *state_file;
char *no_auto_default_file;
char *plugins;
gboolean configure_and_quit;
@@ -58,6 +73,10 @@ struct NMConfigCmdLineOptions {
};
typedef struct {
+ NMConfigState p;
+} State;
+
+typedef struct {
NMConfigCmdLineOptions cli;
NMConfigData *config_data;
@@ -81,6 +100,19 @@ typedef struct {
gboolean configure_and_quit;
char **atomic_section_prefixes;
+
+ /* The state. This is actually a mutable data member and it makes sense:
+ * The regular config is immutable (NMConfigData) and can old be swapped
+ * as a whole (via nm_config_set_values() or during reload). Thus, it can
+ * be changed, but it is still immutable and is swapped atomically as a
+ * whole. Also, we emit a config-changed signal on that occasion.
+ *
+ * For state, there are no events. You can query it and set it.
+ * It only gets read *once* at startup, and later is cached and only
+ * written out to disk. Hence, no need for the immutable dance here
+ * because the state changes only on explicit actions from the daemon
+ * itself. */
+ State *state;
} NMConfigPrivate;
enum {
@@ -406,6 +438,7 @@ _nm_config_cmd_line_options_clear (NMConfigCmdLineOptions *cli)
g_clear_pointer (&cli->system_config_dir, g_free);
g_clear_pointer (&cli->no_auto_default_file, g_free);
g_clear_pointer (&cli->intern_config_file, g_free);
+ g_clear_pointer (&cli->state_file, g_free);
g_clear_pointer (&cli->plugins, g_free);
cli->configure_and_quit = FALSE;
cli->is_debug = FALSE;
@@ -427,6 +460,7 @@ _nm_config_cmd_line_options_copy (const NMConfigCmdLineOptions *cli, NMConfigCmd
dst->config_main_file = g_strdup (cli->config_main_file);
dst->no_auto_default_file = g_strdup (cli->no_auto_default_file);
dst->intern_config_file = g_strdup (cli->intern_config_file);
+ dst->state_file = g_strdup (cli->state_file);
dst->plugins = g_strdup (cli->plugins);
dst->configure_and_quit = cli->configure_and_quit;
dst->is_debug = cli->is_debug;
@@ -466,6 +500,7 @@ nm_config_cmd_line_options_add_to_entries (NMConfigCmdLineOptions *cli,
{ "config-dir", 0, 0, G_OPTION_ARG_FILENAME, &cli->config_dir, N_("Config directory location"), N_(DEFAULT_CONFIG_DIR) },
{ "system-config-dir", 0, 0, G_OPTION_ARG_FILENAME, &cli->system_config_dir, N_("System config directory location"), N_(DEFAULT_SYSTEM_CONFIG_DIR) },
{ "intern-config", 0, 0, G_OPTION_ARG_FILENAME, &cli->intern_config_file, N_("Internal config file location"), N_(DEFAULT_INTERN_CONFIG_FILE) },
+ { "state-file", 0, 0, G_OPTION_ARG_FILENAME, &cli->state_file, N_("State file location"), N_(DEFAULT_STATE_FILE) },
{ "no-auto-default", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME, &cli->no_auto_default_file, N_("State file for no-auto-default devices"), N_(DEFAULT_NO_AUTO_DEFAULT_FILE) },
{ "plugins", 0, 0, G_OPTION_ARG_STRING, &cli->plugins, N_("List of plugins separated by ','"), N_(CONFIG_PLUGINS_DEFAULT) },
{ "configure-and-quit", 0, 0, G_OPTION_ARG_NONE, &cli->configure_and_quit, N_("Quit after initial configuration"), NULL },
@@ -1644,7 +1679,190 @@ nm_config_set_values (NMConfig *self,
g_key_file_unref (keyfile_new);
}
-/************************************************************************/
+/******************************************************************************
+ * State
+ ******************************************************************************/
+
+static const char *
+state_get_filename (const NMConfigCmdLineOptions *cli)
+{
+ /* For an empty filename, we assume the user wants to disable
+ * state. NMConfig will not try to read it nor write it out. */
+ if (!cli->state_file)
+ return DEFAULT_STATE_FILE;
+ return cli->state_file[0] ? cli->state_file : NULL;
+}
+
+static State *
+state_new (void)
+{
+ State *state;
+
+ state = g_slice_new0 (State);
+ state->p.net_enabled = TRUE;
+ state->p.wifi_enabled = TRUE;
+ state->p.wwan_enabled = TRUE;
+
+ return state;
+}
+
+static void
+state_free (State *state)
+{
+ if (!state)
+ return;
+ g_slice_free (State, state);
+}
+
+static State *
+state_new_from_file (const char *filename)
+{
+ GKeyFile *keyfile;
+ gs_free_error GError *error = NULL;
+ State *state;
+
+ state = state_new ();
+
+ if (!filename)
+ return state;
+
+ keyfile = g_key_file_new ();
+ g_key_file_set_list_separator (keyfile, ',');
+ if (!g_key_file_load_from_file (keyfile, filename, G_KEY_FILE_NONE, &error)) {
+ if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
+ _LOGD ("state: missing state file \"%s\": %s", filename, error->message);
+ else
+ _LOGW ("state: error reading state file \"%s\": %s", filename, error->message);
+ goto out;
+ }
+
+ _LOGD ("state: successfully read state file \"%s\"", filename);
+
+ state->p.net_enabled = nm_config_keyfile_get_boolean (keyfile, "main", "NetworkingEnabled", state->p.net_enabled);
+ state->p.wifi_enabled = nm_config_keyfile_get_boolean (keyfile, "main", "WirelessEnabled", state->p.wifi_enabled);
+ state->p.wwan_enabled = nm_config_keyfile_get_boolean (keyfile, "main", "WWANEnabled", state->p.wwan_enabled);
+
+out:
+ g_key_file_unref (keyfile);
+ return state;
+}
+
+const NMConfigState *
+nm_config_state_get (NMConfig *self)
+{
+ NMConfigPrivate *priv;
+
+ g_return_val_if_fail (NM_IS_CONFIG (self), NULL);
+
+ priv = NM_CONFIG_GET_PRIVATE (self);
+
+ if (G_UNLIKELY (!priv->state)) {
+ /* read the state from file lazy on first access. The reason is that
+ * we want to log a failure to read the file via nm-logging.
+ *
+ * So we cannot read the state during construction of NMConfig,
+ * because at that time nm-logging is not yet configured.
+ */
+ priv->state = state_new_from_file (state_get_filename (&priv->cli));
+ }
+
+ return &priv->state->p;
+}
+
+static void
+state_write (NMConfig *self)
+{
+ NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (self);
+ const char *filename;
+ GString *str;
+ GError *error = NULL;
+
+ filename = state_get_filename (&priv->cli);
+
+ if (!filename) {
+ priv->state->p.dirty = FALSE;
+ return;
+ }
+
+ str = g_string_sized_new (256);
+
+ /* Let's construct the keyfile data by hand. */
+
+ g_string_append (str, "[main]\n");
+ g_string_append_printf (str, "NetworkingEnabled=%s\n", priv->state->p.net_enabled ? "true" : "false");
+ g_string_append_printf (str, "WirelessEnabled=%s\n", priv->state->p.wifi_enabled ? "true" : "false");
+ g_string_append_printf (str, "WWANEnabled=%s\n", priv->state->p.wwan_enabled ? "true" : "false");
+
+ if (!g_file_set_contents (filename,
+ str->str, str->len,
+ &error)) {
+ _LOGD ("state: error writing state file \"%s\": %s", filename, error->message);
+ g_clear_error (&error);
+ /* we leave the state dirty. That potentally means, that we try to
+ * write the file over and over again, although it isn't possible. */
+ priv->state->p.dirty = TRUE;
+ } else
+ priv->state->p.dirty = FALSE;
+
+ _LOGT ("state: success writing state file \"%s\"", filename);
+
+ g_string_free (str, TRUE);
+}
+
+void
+_nm_config_state_set (NMConfig *self,
+ gboolean allow_persist,
+ gboolean force_persist,
+ ...)
+{
+ NMConfigPrivate *priv;
+ va_list ap;
+ NMConfigRunStatePropertyType property_type;
+
+ g_return_if_fail (NM_IS_CONFIG (self));
+
+ priv = NM_CONFIG_GET_PRIVATE (self);
+
+ va_start (ap, force_persist);
+
+ /* We expect that the NMConfigRunStatePropertyType is an integer type <= sizeof (int).
+ * Smaller would be fine, since the variadic arguments get promoted to int.
+ * Larger would be a problem, also, because we want that "0" is a valid sentinel. */
+ G_STATIC_ASSERT_EXPR (sizeof (NMConfigRunStatePropertyType) <= sizeof (int));
+
+ while ((property_type = va_arg (ap, int)) != NM_CONFIG_STATE_PROPERTY_NONE) {
+ bool *p_bool, v_bool;
+
+ switch (property_type) {
+ case NM_CONFIG_STATE_PROPERTY_NETWORKING_ENABLED:
+ p_bool = &priv->state->p.net_enabled;
+ break;
+ case NM_CONFIG_STATE_PROPERTY_WIFI_ENABLED:
+ p_bool = &priv->state->p.wifi_enabled;
+ break;
+ case NM_CONFIG_STATE_PROPERTY_WWAN_ENABLED:
+ p_bool = &priv->state->p.wwan_enabled;
+ break;
+ default:
+ va_end (ap);
+ g_return_if_reached ();
+ }
+
+ v_bool = va_arg (ap, gboolean);
+ if (*p_bool == v_bool)
+ continue;
+ *p_bool = v_bool;
+ priv->state->p.dirty = TRUE;
+ }
+
+ va_end (ap);
+
+ if ( allow_persist
+ && (force_persist || priv->state->p.dirty))
+ state_write (self);
+}
+
+/*****************************************************************************/
void
nm_config_reload (NMConfig *self, int signal)
@@ -1917,6 +2135,8 @@ finalize (GObject *gobject)
{
NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (gobject);
+ state_free (priv->state);
+
g_free (priv->config_dir);
g_free (priv->system_config_dir);
g_free (priv->no_auto_default_file);
diff --git a/src/nm-config.h b/src/nm-config.h
index 8bbab2ac6f..82e3a00481 100644
--- a/src/nm-config.h
+++ b/src/nm-config.h
@@ -83,6 +83,24 @@ G_BEGIN_DECLS
typedef struct NMConfigCmdLineOptions NMConfigCmdLineOptions;
+typedef enum {
+ NM_CONFIG_STATE_PROPERTY_NONE,
+
+ /* 1 set-argument: (gboolean enabled) */
+ NM_CONFIG_STATE_PROPERTY_NETWORKING_ENABLED,
+ NM_CONFIG_STATE_PROPERTY_WIFI_ENABLED,
+ NM_CONFIG_STATE_PROPERTY_WWAN_ENABLED,
+} NMConfigRunStatePropertyType;
+
+typedef struct {
+ bool net_enabled;
+ bool wifi_enabled;
+ bool wwan_enabled;
+
+ /* Whether the runstate is modified and not saved to disk. */
+ bool dirty;
+} NMConfigState;
+
struct _NMConfig {
GObject parent;
};
@@ -131,6 +149,15 @@ NMConfig *nm_config_new (const NMConfigCmdLineOptions *cli, char **atomic_sectio
NMConfig *nm_config_setup (const NMConfigCmdLineOptions *cli, char **atomic_section_prefixes, GError **error);
void nm_config_reload (NMConfig *config, int signal);
+const NMConfigState *nm_config_state_get (NMConfig *config);
+
+void _nm_config_state_set (NMConfig *config,
+ gboolean allow_persist,
+ gboolean force_persist,
+ ...);
+#define nm_config_state_set(config, allow_persist, force_persist, ...) \
+ _nm_config_state_set (config, allow_persist, force_persist, ##__VA_ARGS__, 0)
+
gint nm_config_parse_boolean (const char *str, gint default_value);
GKeyFile *nm_config_create_keyfile (void);
diff --git a/src/nm-connection-provider.c b/src/nm-connection-provider.c
deleted file mode 100644
index e04cab928e..0000000000
--- a/src/nm-connection-provider.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2012 Red Hat, Inc.
- */
-
-#include "nm-default.h"
-
-#include "nm-connection-provider.h"
-#include "nm-utils.h"
-
-G_DEFINE_INTERFACE (NMConnectionProvider, nm_connection_provider, G_TYPE_OBJECT)
-
-GSList *
-nm_connection_provider_get_best_connections (NMConnectionProvider *self,
- guint max_requested,
- const char *ctype1,
- const char *ctype2,
- NMConnectionFilterFunc func,
- gpointer func_data)
-{
- g_return_val_if_fail (NM_IS_CONNECTION_PROVIDER (self), NULL);
-
- if (NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->get_best_connections)
- return NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->get_best_connections (self, max_requested, ctype1, ctype2, func, func_data);
- return NULL;
-}
-
-const GSList *
-nm_connection_provider_get_connections (NMConnectionProvider *self)
-{
- g_return_val_if_fail (NM_IS_CONNECTION_PROVIDER (self), NULL);
-
- if (NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->get_connections)
- return NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->get_connections (self);
- return NULL;
-}
-
-/**
- * nm_connection_provider_add_connection:
- * @self: the #NMConnectionProvider
- * @connection: the source connection to create a new #NMSettingsConnection from
- * @save_to_disk: %TRUE to save the connection to disk immediately, %FALSE to
- * not save to disk
- * @error: on return, a location to store any errors that may occur
- *
- * Creates a new #NMSettingsConnection for the given source @connection.
- * The plugin owns the returned object and the caller must reference the object
- * to continue using it.
- *
- * Returns: the new #NMSettingsConnection or %NULL
- */
-NMConnection *
-nm_connection_provider_add_connection (NMConnectionProvider *self,
- NMConnection *connection,
- gboolean save_to_disk,
- GError **error)
-{
- g_return_val_if_fail (NM_IS_CONNECTION_PROVIDER (self), NULL);
-
- g_assert (NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->add_connection);
- return NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->add_connection (self, connection, save_to_disk, error);
-}
-
-/**
- * nm_connection_provider_get_connection_by_uuid:
- * @self: the #NMConnectionProvider
- * @uuid: the UUID to search for
- *
- * Returns: the connection with the given @uuid, or %NULL
- */
-NMConnection *
-nm_connection_provider_get_connection_by_uuid (NMConnectionProvider *self,
- const char *uuid)
-{
- g_return_val_if_fail (NM_IS_CONNECTION_PROVIDER (self), NULL);
- g_return_val_if_fail (uuid != NULL, NULL);
- g_return_val_if_fail (nm_utils_is_uuid (uuid), NULL);
-
- g_assert (NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->get_connection_by_uuid);
- return NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->get_connection_by_uuid (self, uuid);
-}
-
-/*****************************************************************************/
-
-static void
-nm_connection_provider_default_init (NMConnectionProviderInterface *g_iface)
-{
- GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
- static gboolean initialized = FALSE;
-
- if (initialized)
- return;
- initialized = TRUE;
-
- /* Signals */
- g_signal_new (NM_CP_SIGNAL_CONNECTION_ADDED,
- iface_type,
- G_SIGNAL_RUN_FIRST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1, G_TYPE_OBJECT);
-
- g_signal_new (NM_CP_SIGNAL_CONNECTION_UPDATED,
- iface_type,
- G_SIGNAL_RUN_FIRST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1, G_TYPE_OBJECT);
-
- g_signal_new (NM_CP_SIGNAL_CONNECTION_REMOVED,
- iface_type,
- G_SIGNAL_RUN_FIRST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1, G_TYPE_OBJECT);
-}
diff --git a/src/nm-connection-provider.h b/src/nm-connection-provider.h
deleted file mode 100644
index b31af05fbe..0000000000
--- a/src/nm-connection-provider.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2012 Red Hat, Inc.
- */
-
-#ifndef __NETWORKMANAGER_CONNECTION_PROVIDER_H__
-#define __NETWORKMANAGER_CONNECTION_PROVIDER_H__
-
-#include <nm-connection.h>
-
-#include "nm-default.h"
-
-#define NM_TYPE_CONNECTION_PROVIDER (nm_connection_provider_get_type ())
-#define NM_CONNECTION_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONNECTION_PROVIDER, NMConnectionProvider))
-#define NM_IS_CONNECTION_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CONNECTION_PROVIDER))
-#define NM_CONNECTION_PROVIDER_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_CONNECTION_PROVIDER, NMConnectionProviderInterface))
-
-#define NM_CP_SIGNAL_CONNECTION_ADDED "cp-connection-added"
-#define NM_CP_SIGNAL_CONNECTION_UPDATED "cp-connection-updated"
-#define NM_CP_SIGNAL_CONNECTION_REMOVED "cp-connection-removed"
-
-
-/**
- * NMConnectionFilterFunc:
- * @provider: The provider requesting the filtering
- * @connection: the connection to be filtered
- * @func_data: the caller-provided data pointer
- *
- * Returns: %TRUE to allow the connection, %FALSE to ignore it
- */
-typedef gboolean (*NMConnectionFilterFunc) (NMConnectionProvider *provider,
- NMConnection *connection,
- gpointer func_data);
-
-
-typedef struct {
- GTypeInterface g_iface;
-
- /* Methods */
- GSList * (*get_best_connections) (NMConnectionProvider *self,
- guint max_requested,
- const char *ctype1,
- const char *ctype2,
- NMConnectionFilterFunc func,
- gpointer func_data);
-
- const GSList * (*get_connections) (NMConnectionProvider *self);
-
- NMConnection * (*add_connection) (NMConnectionProvider *self,
- NMConnection *connection,
- gboolean save_to_disk,
- GError **error);
-
- NMConnection * (*get_connection_by_uuid) (NMConnectionProvider *self,
- const char *uuid);
-} NMConnectionProviderInterface;
-
-GType nm_connection_provider_get_type (void);
-
-/**
- * nm_connection_provider_get:
- *
- * Returns: the global #NMConnectionProvider
- */
-NMConnectionProvider *nm_connection_provider_get (void);
-
-/**
- * nm_connection_provider_get_best_connections:
- * @self: the #NMConnectionProvider
- * @max_requested: if non-zero, the maximum number of connections to return
- * @ctype1: an #NMSetting base type (eg NM_SETTING_WIRELESS_SETTING_NAME) to
- * filter connections against
- * @ctype2: a second #NMSetting base type (eg NM_SETTING_WIRELESS_SETTING_NAME)
- * to filter connections against
- * @func: caller-supplied function for filtering connections
- * @func_data: caller-supplied data passed to @func
- *
- * Returns: a #GSList of #NMConnection objects in sorted order representing the
- * "best" or highest-priority connections filtered by @ctype1 and/or @ctype2,
- * and/or @func. Caller is responsible for freeing the returned #GSList, but
- * the contained values do not need to be unreffed.
- */
-GSList *nm_connection_provider_get_best_connections (NMConnectionProvider *self,
- guint max_requested,
- const char *ctype1,
- const char *ctype2,
- NMConnectionFilterFunc func,
- gpointer func_data);
-
-/**
- * nm_connection_provider_get_connections:
- * @self: the #NMConnectionProvider
- *
- * Returns: a #GSList of #NMConnection objects representing all known
- * connections. Returned list is owned by the connection provider and must
- * not be freed.
- */
-const GSList *nm_connection_provider_get_connections (NMConnectionProvider *self);
-
-/**
- * nm_connection_provider_add_connection:
- * @self: the #NMConnectionProvider
- * @connection: the connection to be added
- * @save_to_disk: whether to store the connection on disk
- * @error: returns any error if adding fails
- *
- * returns: a newly added #NMConnection.
- */
-NMConnection *nm_connection_provider_add_connection (NMConnectionProvider *self,
- NMConnection *connection,
- gboolean save_to_disk,
- GError **error);
-
-NMConnection *nm_connection_provider_get_connection_by_uuid (NMConnectionProvider *self,
- const char *uuid);
-
-#endif /* __NETWORKMANAGER_CONNECTION_PROVIDER_H__ */
diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c
index 1c93ca81ee..276dc1c406 100644
--- a/src/nm-core-utils.c
+++ b/src/nm-core-utils.c
@@ -199,6 +199,27 @@ nm_ethernet_address_is_valid (gconstpointer addr, gssize len)
return TRUE;
}
+gconstpointer
+nm_utils_ipx_address_clear_host_address (int family, gpointer dst, gconstpointer src, guint8 plen)
+{
+ g_return_val_if_fail (src, NULL);
+ g_return_val_if_fail (dst, NULL);
+
+ switch (family) {
+ case AF_INET:
+ g_return_val_if_fail (plen <= 32, NULL);
+ *((guint32 *) dst) = nm_utils_ip4_address_clear_host_address (*((guint32 *) src), plen);
+ break;
+ case AF_INET6:
+ g_return_val_if_fail (plen <= 128, NULL);
+ nm_utils_ip6_address_clear_host_address (dst, src, plen);
+ break;
+ default:
+ g_return_val_if_reached (NULL);
+ }
+ return dst;
+}
+
/* nm_utils_ip4_address_clear_host_address:
* @addr: source ip6 address
* @plen: prefix length of network
@@ -445,8 +466,7 @@ nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid)
gs_strfreev gchar **tokens = NULL;
guint num_tokens;
gchar *p;
- gchar *endp;
- char state = '\0';
+ char state = ' ';
gint64 ppid = 0;
start_time = 0;
@@ -457,7 +477,7 @@ nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid)
nm_sprintf_buf (filename, "/proc/%"G_GUINT64_FORMAT"/stat", (guint64) pid);
if (!g_file_get_contents (filename, &contents, &length, NULL))
- goto out;
+ goto fail;
/* start time is the token at index 19 after the '(process name)' entry - since only this
* field can contain the ')' character, search backwards for this to avoid malicious
@@ -465,10 +485,10 @@ nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid)
*/
p = strrchr (contents, ')');
if (p == NULL)
- goto out;
+ goto fail;
p += 2; /* skip ') ' */
if (p - contents >= (int) length)
- goto out;
+ goto fail;
state = p[0];
@@ -477,23 +497,26 @@ nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid)
num_tokens = g_strv_length (tokens);
if (num_tokens < 20)
- goto out;
+ goto fail;
- if (out_ppid)
+ if (out_ppid) {
ppid = _nm_utils_ascii_str_to_int64 (tokens[1], 10, 1, G_MAXINT, 0);
+ if (ppid == 0)
+ goto fail;
+ }
- errno = 0;
- start_time = strtoull (tokens[19], &endp, 10);
- if (*endp != '\0' || errno != 0)
- start_time = 0;
-
-out:
- if (out_state)
- *out_state = state;
- if (out_ppid)
- *out_ppid = ppid;
+ start_time = _nm_utils_ascii_str_to_int64 (tokens[19], 10, 1, G_MAXINT64, 0);
+ if (start_time == 0)
+ goto fail;
+ NM_SET_OUT (out_state, state);
+ NM_SET_OUT (out_ppid, ppid);
return start_time;
+
+fail:
+ NM_SET_OUT (out_state, ' ');
+ NM_SET_OUT (out_ppid, 0);
+ return 0;
}
/******************************************************************************************/
@@ -1900,6 +1923,33 @@ nm_utils_new_vlan_name (const char *parent_iface, guint32 vlan_id)
return ifname;
}
+/* nm_utils_new_infiniband_name:
+ * @name: the output-buffer where the value will be written. Must be
+ * not %NULL and point to a string buffer of at least IFNAMSIZ bytes.
+ * @parent_name: the parent interface name
+ * @p_key: the partition key.
+ *
+ * Returns: the infiniband name will be written to @name and @name
+ * is returned.
+ */
+const char *
+nm_utils_new_infiniband_name (char *name, const char *parent_name, int p_key)
+{
+ g_return_val_if_fail (name, NULL);
+ g_return_val_if_fail (parent_name && parent_name[0], NULL);
+ g_return_val_if_fail (strlen (parent_name) < IFNAMSIZ, NULL);
+
+ /* technically, p_key of 0x0000 and 0x8000 is not allowed either. But we don't
+ * want to assert against that in nm_utils_new_infiniband_name(). So be more
+ * resilient here, and accept those. */
+ g_return_val_if_fail (p_key >= 0 && p_key <= 0xffff, NULL);
+
+ /* If parent+suffix is too long, kernel would just truncate
+ * the name. We do the same. See ipoib_vlan_add(). */
+ g_snprintf (name, IFNAMSIZ, "%s.%04x", parent_name, p_key);
+ return name;
+}
+
/**
* nm_utils_read_resolv_conf_nameservers():
* @rc_contents: contents of a resolv.conf; or %NULL to read /etc/resolv.conf
@@ -2816,20 +2866,92 @@ nm_utils_get_ipv6_interface_identifier (NMLinkType link_type,
}
return FALSE;
}
+
+/*****************************************************************************/
+
+/**
+ * nm_utils_ipv6_addr_set_interface_identifier:
+ * @addr: output token encoded as %in6_addr
+ * @iid: %NMUtilsIPv6IfaceId interface identifier
+ *
+ * Converts the %NMUtilsIPv6IfaceId to an %in6_addr (suitable for use
+ * with Linux platform). This only copies the lower 8 bytes, ignoring
+ * the /64 network prefix which is expected to be all-zero for a valid
+ * token.
+ */
void
-nm_utils_ipv6_addr_set_interface_identfier (struct in6_addr *addr,
+nm_utils_ipv6_addr_set_interface_identifier (struct in6_addr *addr,
const NMUtilsIPv6IfaceId iid)
{
memcpy (addr->s6_addr + 8, &iid.id_u8, 8);
}
+/**
+ * nm_utils_ipv6_interface_identifier_get_from_addr:
+ * @iid: output %NMUtilsIPv6IfaceId interface identifier set from the token
+ * @addr: token encoded as %in6_addr
+ *
+ * Converts the %in6_addr encoded token (as used by Linux platform) to
+ * the interface identifier.
+ */
void
-nm_utils_ipv6_interface_identfier_get_from_addr (NMUtilsIPv6IfaceId *iid,
+nm_utils_ipv6_interface_identifier_get_from_addr (NMUtilsIPv6IfaceId *iid,
const struct in6_addr *addr)
{
memcpy (iid, addr->s6_addr + 8, 8);
}
+/**
+ * nm_utils_ipv6_interface_identifier_get_from_token:
+ * @iid: output %NMUtilsIPv6IfaceId interface identifier set from the token
+ * @token: token encoded as string
+ *
+ * Converts the %in6_addr encoded token (as used in ip6 settings) to
+ * the interface identifier.
+ *
+ * Returns: %TRUE if the @token is a valid token, %FALSE otherwise
+ */
+gboolean
+nm_utils_ipv6_interface_identifier_get_from_token (NMUtilsIPv6IfaceId *iid,
+ const char *token)
+{
+ struct in6_addr i6_token;
+
+ g_return_val_if_fail (token, FALSE);
+
+ if (!inet_pton (AF_INET6, token, &i6_token))
+ return FALSE;
+
+ if (!_nm_utils_inet6_is_token (&i6_token))
+ return FALSE;
+
+ nm_utils_ipv6_interface_identifier_get_from_addr (iid, &i6_token);
+ return TRUE;
+}
+
+/**
+ * nm_utils_inet6_interface_identifier_to_token:
+ * @iid: %NMUtilsIPv6IfaceId interface identifier
+ * @buf: the destination buffer or %NULL
+ *
+ * Converts the interface identifier to a string token.
+ * If the destination buffer it set, set it is used to store the
+ * resulting token, otherwise an internal static buffer is used.
+ * The buffer needs to be %NM_UTILS_INET_ADDRSTRLEN characters long.
+ *
+ * Returns: a statically allocated array. Do not g_free().
+ */
+const char *
+nm_utils_inet6_interface_identifier_to_token (NMUtilsIPv6IfaceId iid, char *buf)
+{
+ struct in6_addr i6_token = { .s6_addr = { 0, } };
+
+ nm_utils_ipv6_addr_set_interface_identifier (&i6_token, iid);
+ return nm_utils_inet6_ntop (&i6_token, buf);
+}
+
+/*****************************************************************************/
+
static gboolean
_set_stable_privacy (struct in6_addr *addr,
const char *ifname,
@@ -3119,3 +3241,40 @@ nm_utils_lifetime_get (guint32 timestamp,
return TRUE;
}
+const char *
+nm_utils_dnsmasq_status_to_string (int status, char *dest, guint size)
+{
+ static char buffer[128];
+ char *msg, *ret;
+ gs_free char *msg_free = NULL;
+ int len;
+
+ if (status == 0)
+ msg = "Success";
+ else if (status == 1)
+ msg = "Configuration problem";
+ else if (status == 2)
+ msg = "Network access problem (address in use, permissions)";
+ else if (status == 3)
+ msg = "Filesystem problem (missing file/directory, permissions)";
+ else if (status == 4)
+ msg = "Memory allocation failure";
+ else if (status == 5)
+ msg = "Other problem";
+ else if (status >= 11)
+ msg = msg_free = g_strdup_printf ("Lease script failed with error %d", status - 10);
+ else
+ msg = "Unknown problem";
+
+ if (dest) {
+ ret = dest;
+ len = size;
+ } else {
+ ret = buffer;
+ len = sizeof (buffer);
+ }
+
+ g_snprintf (ret, len, "%s (%d)", msg, status);
+
+ return ret;
+}
diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h
index 40ea39eddd..a203a8ef71 100644
--- a/src/nm-core-utils.h
+++ b/src/nm-core-utils.h
@@ -93,6 +93,7 @@ GETTER (void) \
gboolean nm_ethernet_address_is_valid (gconstpointer addr, gssize len);
+gconstpointer nm_utils_ipx_address_clear_host_address (int family, gpointer dst, gconstpointer src, guint8 plen);
in_addr_t nm_utils_ip4_address_clear_host_address (in_addr_t addr, guint8 plen);
const struct in6_addr *nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_addr *src, guint8 plen);
gboolean nm_utils_ip6_address_same_prefix (const struct in6_addr *addr_a, const struct in6_addr *addr_b, guint8 plen);
@@ -283,6 +284,7 @@ const char *nm_utils_get_ip_config_method (NMConnection *connection,
GType ip_setting_type);
char *nm_utils_new_vlan_name (const char *parent_iface, guint32 vlan_id);
+const char *nm_utils_new_infiniband_name (char *name, const char *parent_name, int p_key);
GPtrArray *nm_utils_read_resolv_conf_nameservers (const char *rc_contents);
GPtrArray *nm_utils_read_resolv_conf_dns_options (const char *rc_contents);
@@ -333,24 +335,30 @@ struct _NMUtilsIPv6IfaceId {
#define NM_UTILS_IPV6_IFACE_ID_INIT { { .id = 0 } }
+void nm_utils_ipv6_addr_set_interface_identifier (struct in6_addr *addr,
+ const NMUtilsIPv6IfaceId iid);
+
+void nm_utils_ipv6_interface_identifier_get_from_addr (NMUtilsIPv6IfaceId *iid,
+ const struct in6_addr *addr);
+
+gboolean nm_utils_ipv6_interface_identifier_get_from_token (NMUtilsIPv6IfaceId *iid,
+ const char *token);
+
+const char *nm_utils_inet6_interface_identifier_to_token (NMUtilsIPv6IfaceId iid,
+ char *buf);
+
gboolean nm_utils_get_ipv6_interface_identifier (NMLinkType link_type,
const guint8 *hwaddr,
guint len,
guint dev_id,
NMUtilsIPv6IfaceId *out_iid);
-void nm_utils_ipv6_addr_set_interface_identfier (struct in6_addr *addr,
- const NMUtilsIPv6IfaceId iid);
-
gboolean nm_utils_ipv6_addr_set_stable_privacy (struct in6_addr *addr,
const char *ifname,
const char *uuid,
guint dad_counter,
GError **error);
-void nm_utils_ipv6_interface_identfier_get_from_addr (NMUtilsIPv6IfaceId *iid,
- const struct in6_addr *addr);
-
void nm_utils_array_remove_at_indexes (GArray *array, const guint *indexes_to_delete, gsize len);
void nm_utils_setpgid (gpointer unused);
@@ -396,4 +404,6 @@ gboolean nm_utils_lifetime_get (guint32 timestamp,
gboolean nm_utils_ip4_address_is_link_local (in_addr_t addr);
+const char *nm_utils_dnsmasq_status_to_string (int status, char *dest, guint size);
+
#endif /* __NM_CORE_UTILS_H__ */
diff --git a/src/nm-default-route-manager.c b/src/nm-default-route-manager.c
index 3ee634a7b7..2fd2c7db47 100644
--- a/src/nm-default-route-manager.c
+++ b/src/nm-default-route-manager.c
@@ -200,7 +200,7 @@ _vt_routes_has_entry (const VTableIP *vtable, GArray *routes, const Entry *entry
for (i = 0; i < routes->len; i++) {
NMPlatformIP4Route *r = &g_array_index (routes, NMPlatformIP4Route, i);
- route.rx.source = r->source;
+ route.rx.rt_source = r->rt_source;
if (nm_platform_ip4_route_cmp (r, &route.r4) == 0)
return TRUE;
}
@@ -208,7 +208,7 @@ _vt_routes_has_entry (const VTableIP *vtable, GArray *routes, const Entry *entry
for (i = 0; i < routes->len; i++) {
NMPlatformIP6Route *r = &g_array_index (routes, NMPlatformIP6Route, i);
- route.rx.source = r->source;
+ route.rx.rt_source = r->rt_source;
if (nm_platform_ip6_route_cmp (r, &route.r6) == 0)
return TRUE;
}
@@ -289,7 +289,7 @@ _platform_route_sync_add (const VTableIP *vtable, NMDefaultRouteManager *self, g
if (vtable->vt->is_ip4) {
success = nm_platform_ip4_route_add (priv->platform,
entry->route.rx.ifindex,
- entry->route.rx.source,
+ entry->route.rx.rt_source,
0,
0,
entry->route.r4.gateway,
@@ -299,7 +299,7 @@ _platform_route_sync_add (const VTableIP *vtable, NMDefaultRouteManager *self, g
} else {
success = nm_platform_ip6_route_add (priv->platform,
entry->route.rx.ifindex,
- entry->route.rx.source,
+ entry->route.rx.rt_source,
in6addr_any,
0,
entry->route.r6.gateway,
@@ -727,16 +727,8 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self,
if (device)
ip_ifindex = nm_device_get_ip_ifindex (device);
- else {
- ip_ifindex = nm_vpn_connection_get_ip_ifindex (vpn);
-
- if (ip_ifindex <= 0) {
- NMDevice *parent = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn));
-
- if (parent)
- ip_ifindex = nm_device_get_ip_ifindex (parent);
- }
- }
+ else
+ ip_ifindex = nm_vpn_connection_get_ip_ifindex (vpn, TRUE);
entries = vtable->get_entries (priv);
entry = _entry_find_by_source (entries, source, &entry_idx);
@@ -773,7 +765,7 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self,
* the device. */
memset (&rt, 0, sizeof (rt));
rt.rx.ifindex = ip_ifindex;
- rt.rx.source = NM_IP_CONFIG_SOURCE_UNKNOWN;
+ rt.rx.rt_source = NM_IP_CONFIG_SOURCE_UNKNOWN;
rt.rx.metric = G_MAXUINT32;
default_route = &rt.rx;
@@ -795,7 +787,7 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self,
if (vpn_config) {
never_default = nm_ip4_config_get_never_default (vpn_config);
rt.r4.ifindex = ip_ifindex;
- rt.r4.source = NM_IP_CONFIG_SOURCE_VPN;
+ rt.r4.rt_source = NM_IP_CONFIG_SOURCE_VPN;
rt.r4.gateway = nm_ip4_config_get_gateway (vpn_config);
rt.r4.metric = nm_vpn_connection_get_ip4_route_metric (vpn);
rt.r4.mss = nm_ip4_config_get_mss (vpn_config);
@@ -810,7 +802,7 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self,
never_default = nm_ip6_config_get_never_default (vpn_config);
rt.r6.ifindex = ip_ifindex;
- rt.r6.source = NM_IP_CONFIG_SOURCE_VPN;
+ rt.r6.rt_source = NM_IP_CONFIG_SOURCE_VPN;
rt.r6.gateway = int_gw ? *int_gw : in6addr_any;
rt.r6.metric = nm_vpn_connection_get_ip6_route_metric (vpn);
rt.r6.mss = nm_ip6_config_get_mss (vpn_config);
@@ -818,7 +810,7 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self,
}
}
}
- if (nm_vpn_connection_get_ip_ifindex (vpn) > 0)
+ if (nm_vpn_connection_get_ip_ifindex (vpn, FALSE) > 0)
synced = TRUE;
else {
/* a VPN connection without tunnel device cannot have a non-synced, missing default route.
@@ -1149,7 +1141,7 @@ _ipx_get_best_config (const VTableIP *vtable,
if (out_ac)
*out_ac = NM_ACTIVE_CONNECTION (vpn);
if (out_ip_iface)
- *out_ip_iface = nm_vpn_connection_get_ip_iface (vpn);
+ *out_ip_iface = nm_vpn_connection_get_ip_iface (vpn, TRUE);
} else {
NMDevice *device = entry->source.device;
NMActRequest *req;
diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c
index 20f7729a43..1058e76f4c 100644
--- a/src/nm-iface-helper.c
+++ b/src/nm-iface-helper.c
@@ -194,7 +194,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
address.preferred = discovered_address->preferred;
if (address.preferred > address.lifetime)
address.preferred = address.lifetime;
- address.source = NM_IP_CONFIG_SOURCE_RDISC;
+ address.addr_source = NM_IP_CONFIG_SOURCE_RDISC;
address.n_ifa_flags = ifa_flags;
nm_ip6_config_add_address (rdisc_config, &address);
@@ -219,7 +219,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
route.network = discovered_route->network;
route.plen = discovered_route->plen;
route.gateway = discovered_route->gateway;
- route.source = NM_IP_CONFIG_SOURCE_RDISC;
+ route.rt_source = NM_IP_CONFIG_SOURCE_RDISC;
route.metric = global_opt.priority_v6;
nm_ip6_config_add_route (rdisc_config, &route);
diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c
index 75caf7e33c..929b823622 100644
--- a/src/nm-ip4-config.c
+++ b/src/nm-ip4-config.c
@@ -35,11 +35,7 @@
#include "nmdbus-ip4-config.h"
-G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_EXPORTED_OBJECT)
-
-#define NM_IP4_CONFIG_GET_PRIVATE(o) ((o)->priv)
-
-typedef struct _NMIP4ConfigPrivate {
+typedef struct {
gboolean never_default;
guint32 gateway;
gboolean has_gateway;
@@ -58,8 +54,33 @@ typedef struct _NMIP4ConfigPrivate {
int ifindex;
gint64 route_metric;
gboolean metered;
+ gint dns_priority;
} NMIP4ConfigPrivate;
+struct _NMIP4Config {
+ NMExportedObject parent;
+ NMIP4ConfigPrivate _priv;
+};
+
+struct _NMIP4ConfigClass {
+ NMExportedObjectClass parent;
+};
+
+G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_EXPORTED_OBJECT)
+
+#define NM_IP4_CONFIG_GET_PRIVATE(self) \
+ ({ \
+ /* preserve the const-ness of self. Unfortunately, that
+ * way, @self cannot be a void pointer */ \
+ typeof (self) _self = (self); \
+ \
+ /* Get compiler error if variable is of wrong type */ \
+ _nm_unused const NMIP4Config *_self2 = (_self); \
+ \
+ nm_assert (NM_IS_IP4_CONFIG (_self)); \
+ &_self->_priv; \
+ })
+
/* internal guint32 are assigned to gobject properties of type uint. Ensure, that uint is large enough */
G_STATIC_ASSERT (sizeof (uint) >= sizeof (guint32));
G_STATIC_ASSERT (G_MAXUINT >= 0xFFFFFFFF);
@@ -76,6 +97,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMIP4Config,
PROP_SEARCHES,
PROP_DNS_OPTIONS,
PROP_WINS_SERVERS,
+ PROP_DNS_PRIORITY,
);
NMIP4Config *
@@ -207,8 +229,8 @@ _addresses_sort_cmp (gconstpointer a, gconstpointer b)
return p1 > p2 ? -1 : 1;
/* Sort the addresses based on their source. */
- if (a1->source != a2->source)
- return a1->source > a2->source ? -1 : 1;
+ if (a1->addr_source != a2->addr_source)
+ return a1->addr_source > a2->addr_source ? -1 : 1;
if ((a1->label[0] == '\0') != (a2->label[0] == '\0'))
return (a1->label[0] == '\0') ? -1 : 1;
@@ -335,7 +357,7 @@ nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf)
gboolean
nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gboolean routes_full_sync, gint64 default_route_metric)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
int i;
gs_unref_ptrarray GPtrArray *added_addresses = NULL;
@@ -368,7 +390,7 @@ nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gboolean routes_fu
nm_assert (addr->plen <= 32);
route.ifindex = ifindex;
- route.source = NM_IP_CONFIG_SOURCE_KERNEL;
+ route.rt_source = NM_IP_CONFIG_SOURCE_KERNEL;
/* The destination network depends on the peer-address. */
route.network = nm_utils_ip4_address_clear_host_address (addr->peer_address, addr->plen);
@@ -427,7 +449,7 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu
{
NMIP4ConfigPrivate *priv;
guint naddresses, nroutes, nnameservers, nsearches;
- int i;
+ int i, priority;
if (!setting)
return;
@@ -471,7 +493,7 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu
nm_assert (address.plen <= 32);
address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT;
address.preferred = NM_PLATFORM_LIFETIME_PERMANENT;
- address.source = NM_IP_CONFIG_SOURCE_USER;
+ address.addr_source = NM_IP_CONFIG_SOURCE_USER;
label = nm_ip_address_get_attribute (s_addr, "label");
if (label)
@@ -500,7 +522,7 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu
route.metric = default_route_metric;
else
route.metric = nm_ip_route_get_metric (s_route);
- route.source = NM_IP_CONFIG_SOURCE_USER;
+ route.rt_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip4_config_add_route (config, &route);
}
@@ -526,6 +548,10 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu
i++;
}
+ priority = nm_setting_ip_config_get_dns_priority (setting);
+ if (priority)
+ nm_ip4_config_set_dns_priority (config, priority);
+
g_object_thaw_notify (G_OBJECT (config));
}
@@ -606,7 +632,7 @@ nm_ip4_config_create_setting (const NMIP4Config *config)
continue;
/* Ignore routes provided by external sources */
- if (route->source != NM_IP_CONFIG_SOURCE_USER)
+ if (route->rt_source != nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER))
continue;
s_route = nm_ip_route_new_binary (AF_INET,
@@ -635,6 +661,11 @@ nm_ip4_config_create_setting (const NMIP4Config *config)
nm_setting_ip_config_add_dns_option (s_ip4, option);
}
+ g_object_set (s_ip4,
+ NM_SETTING_IP_CONFIG_DNS_PRIORITY,
+ nm_ip4_config_get_dns_priority (config),
+ NULL);
+
return NM_SETTING (s_ip4);
}
@@ -643,7 +674,8 @@ nm_ip4_config_create_setting (const NMIP4Config *config)
void
nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFlags merge_flags)
{
- NMIP4ConfigPrivate *dst_priv, *src_priv;
+ NMIP4ConfigPrivate *dst_priv;
+ const NMIP4ConfigPrivate *src_priv;
guint32 i;
g_return_if_fail (src != NULL);
@@ -725,6 +757,10 @@ nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFl
nm_ip4_config_set_metered (dst, nm_ip4_config_get_metered (dst) ||
nm_ip4_config_get_metered (src));
+ /* DNS priority */
+ if (nm_ip4_config_get_dns_priority (src))
+ nm_ip4_config_set_dns_priority (dst, nm_ip4_config_get_dns_priority (src));
+
g_object_thaw_notify (G_OBJECT (dst));
}
@@ -733,7 +769,7 @@ nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFl
static int
_addresses_get_index (const NMIP4Config *self, const NMPlatformIP4Address *addr)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
guint i;
for (i = 0; i < priv->addresses->len; i++) {
@@ -748,7 +784,7 @@ _addresses_get_index (const NMIP4Config *self, const NMPlatformIP4Address *addr)
static int
_nameservers_get_index (const NMIP4Config *self, guint32 ns)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
guint i;
for (i = 0; i < priv->nameservers->len; i++) {
@@ -763,7 +799,7 @@ _nameservers_get_index (const NMIP4Config *self, guint32 ns)
static int
_routes_get_index (const NMIP4Config *self, const NMPlatformIP4Route *route)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
guint i;
for (i = 0; i < priv->routes->len; i++) {
@@ -779,7 +815,7 @@ _routes_get_index (const NMIP4Config *self, const NMPlatformIP4Route *route)
static int
_domains_get_index (const NMIP4Config *self, const char *domain)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
guint i;
for (i = 0; i < priv->domains->len; i++) {
@@ -794,7 +830,7 @@ _domains_get_index (const NMIP4Config *self, const char *domain)
static int
_searches_get_index (const NMIP4Config *self, const char *search)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
guint i;
for (i = 0; i < priv->searches->len; i++) {
@@ -809,7 +845,7 @@ _searches_get_index (const NMIP4Config *self, const char *search)
static int
_dns_options_get_index (const NMIP4Config *self, const char *option)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
guint i;
for (i = 0; i < priv->dns_options->len; i++) {
@@ -824,7 +860,7 @@ _dns_options_get_index (const NMIP4Config *self, const char *option)
static int
_nis_servers_get_index (const NMIP4Config *self, guint32 nis_server)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
guint i;
for (i = 0; i < priv->nis->len; i++) {
@@ -839,7 +875,7 @@ _nis_servers_get_index (const NMIP4Config *self, guint32 nis_server)
static int
_wins_get_index (const NMIP4Config *self, guint32 wins_server)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
guint i;
for (i = 0; i < priv->wins->len; i++) {
@@ -948,6 +984,10 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src)
nm_ip4_config_del_wins (dst, idx);
}
+ /* DNS priority */
+ if (nm_ip4_config_get_dns_priority (src) == nm_ip4_config_get_dns_priority (dst))
+ nm_ip4_config_set_dns_priority (dst, 0);
+
g_object_thaw_notify (G_OBJECT (dst));
}
@@ -1022,7 +1062,8 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
#endif
gboolean has_minor_changes = FALSE, has_relevant_changes = FALSE, are_equal;
guint i, num;
- NMIP4ConfigPrivate *dst_priv, *src_priv;
+ NMIP4ConfigPrivate *dst_priv;
+ const NMIP4ConfigPrivate *src_priv;
const NMPlatformIP4Address *dst_addr, *src_addr;
const NMPlatformIP4Route *dst_route, *src_route;
@@ -1188,6 +1229,12 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
has_relevant_changes = TRUE;
}
+ /* DNS priority */
+ if (src_priv->dns_priority != dst_priv->dns_priority) {
+ nm_ip4_config_set_dns_priority (dst, src_priv->dns_priority);
+ has_minor_changes = TRUE;
+ }
+
/* mss */
if (src_priv->mss != dst_priv->mss) {
nm_ip4_config_set_mss (dst, src_priv->mss);
@@ -1311,6 +1358,7 @@ nm_ip4_config_dump (const NMIP4Config *config, const char *detail)
for (i = 0; i < nm_ip4_config_get_num_dns_options (config); i++)
g_message (" dnsopt: %s", nm_ip4_config_get_dns_option (config, i));
+ g_message (" dnspri: %d", nm_ip4_config_get_dns_priority (config));
g_message (" mss: %"G_GUINT32_FORMAT, nm_ip4_config_get_mss (config));
g_message (" mtu: %"G_GUINT32_FORMAT, nm_ip4_config_get_mtu (config));
@@ -1372,7 +1420,7 @@ nm_ip4_config_set_never_default (NMIP4Config *config, gboolean never_default)
gboolean
nm_ip4_config_get_never_default (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->never_default;
}
@@ -1414,7 +1462,7 @@ nm_ip4_config_unset_gateway (NMIP4Config *config)
gboolean
nm_ip4_config_has_gateway (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->has_gateway;
}
@@ -1422,7 +1470,7 @@ nm_ip4_config_has_gateway (const NMIP4Config *config)
guint32
nm_ip4_config_get_gateway (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->gateway;
}
@@ -1430,7 +1478,7 @@ nm_ip4_config_get_gateway (const NMIP4Config *config)
gint64
nm_ip4_config_get_route_metric (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->route_metric;
}
@@ -1481,14 +1529,14 @@ nm_ip4_config_add_address (NMIP4Config *config, const NMPlatformIP4Address *new)
*item = *new;
/* But restore highest priority source */
- item->source = MAX (item_old.source, new->source);
+ item->addr_source = MAX (item_old.addr_source, new->addr_source);
/* for addresses that we read from the kernel, we keep the timestamps as defined
* by the previous source (item_old). The reason is, that the other source configured the lifetimes
* with "what should be" and the kernel values are "what turned out after configuring it".
*
* For other sources, the longer lifetime wins. */
- if ( (new->source == NM_IP_CONFIG_SOURCE_KERNEL && new->source != item_old.source)
+ if ( (new->addr_source == NM_IP_CONFIG_SOURCE_KERNEL && new->addr_source != item_old.addr_source)
|| nm_platform_ip_address_cmp_expiry ((const NMPlatformIPAddress *) &item_old, (const NMPlatformIPAddress *) new) > 0) {
item->timestamp = item_old.timestamp;
item->lifetime = item_old.lifetime;
@@ -1521,7 +1569,7 @@ nm_ip4_config_del_address (NMIP4Config *config, guint i)
guint
nm_ip4_config_get_num_addresses (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->addresses->len;
}
@@ -1529,7 +1577,7 @@ nm_ip4_config_get_num_addresses (const NMIP4Config *config)
const NMPlatformIP4Address *
nm_ip4_config_get_address (const NMIP4Config *config, guint i)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return &g_array_index (priv->addresses, NMPlatformIP4Address, i);
}
@@ -1582,10 +1630,10 @@ nm_ip4_config_add_route (NMIP4Config *config, const NMPlatformIP4Route *new)
if (routes_are_duplicate (item, new, FALSE)) {
if (nm_platform_ip4_route_cmp (item, new) == 0)
return;
- old_source = item->source;
+ old_source = item->rt_source;
memcpy (item, new, sizeof (*item));
/* Restore highest priority source */
- item->source = MAX (old_source, new->source);
+ item->rt_source = MAX (old_source, new->rt_source);
item->ifindex = priv->ifindex;
goto NOTIFY;
}
@@ -1613,7 +1661,7 @@ nm_ip4_config_del_route (NMIP4Config *config, guint i)
guint
nm_ip4_config_get_num_routes (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->routes->len;
}
@@ -1621,7 +1669,7 @@ nm_ip4_config_get_num_routes (const NMIP4Config *config)
const NMPlatformIP4Route *
nm_ip4_config_get_route (const NMIP4Config *config, guint i)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return &g_array_index (priv->routes, NMPlatformIP4Route, i);
}
@@ -1629,7 +1677,7 @@ nm_ip4_config_get_route (const NMIP4Config *config, guint i)
const NMPlatformIP4Route *
nm_ip4_config_get_direct_route_for_host (const NMIP4Config *config, guint32 host)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
guint i;
NMPlatformIP4Route *best_route = NULL;
@@ -1699,7 +1747,7 @@ nm_ip4_config_del_nameserver (NMIP4Config *config, guint i)
guint32
nm_ip4_config_get_num_nameservers (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->nameservers->len;
}
@@ -1707,7 +1755,7 @@ nm_ip4_config_get_num_nameservers (const NMIP4Config *config)
guint32
nm_ip4_config_get_nameserver (const NMIP4Config *config, guint i)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return g_array_index (priv->nameservers, guint32, i);
}
@@ -1756,7 +1804,7 @@ nm_ip4_config_del_domain (NMIP4Config *config, guint i)
guint32
nm_ip4_config_get_num_domains (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->domains->len;
}
@@ -1764,7 +1812,7 @@ nm_ip4_config_get_num_domains (const NMIP4Config *config)
const char *
nm_ip4_config_get_domain (const NMIP4Config *config, guint i)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return g_ptr_array_index (priv->domains, i);
}
@@ -1828,7 +1876,7 @@ nm_ip4_config_del_search (NMIP4Config *config, guint i)
guint32
nm_ip4_config_get_num_searches (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->searches->len;
}
@@ -1836,7 +1884,7 @@ nm_ip4_config_get_num_searches (const NMIP4Config *config)
const char *
nm_ip4_config_get_search (const NMIP4Config *config, guint i)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return g_ptr_array_index (priv->searches, i);
}
@@ -1885,7 +1933,7 @@ nm_ip4_config_del_dns_option(NMIP4Config *config, guint i)
guint32
nm_ip4_config_get_num_dns_options (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->dns_options->len;
}
@@ -1893,7 +1941,7 @@ nm_ip4_config_get_num_dns_options (const NMIP4Config *config)
const char *
nm_ip4_config_get_dns_option (const NMIP4Config *config, guint i)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return g_ptr_array_index (priv->dns_options, i);
}
@@ -1901,6 +1949,27 @@ nm_ip4_config_get_dns_option (const NMIP4Config *config, guint i)
/******************************************************************/
void
+nm_ip4_config_set_dns_priority (NMIP4Config *config, gint priority)
+{
+ NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+
+ if (priority != priv->dns_priority) {
+ priv->dns_priority = priority;
+ _notify (config, PROP_DNS_PRIORITY);
+ }
+}
+
+gint
+nm_ip4_config_get_dns_priority (const NMIP4Config *config)
+{
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+
+ return priv->dns_priority;
+}
+
+/******************************************************************/
+
+void
nm_ip4_config_set_mss (NMIP4Config *config, guint32 mss)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
@@ -1911,7 +1980,7 @@ nm_ip4_config_set_mss (NMIP4Config *config, guint32 mss)
guint32
nm_ip4_config_get_mss (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->mss;
}
@@ -1952,7 +2021,7 @@ nm_ip4_config_del_nis_server (NMIP4Config *config, guint i)
guint32
nm_ip4_config_get_num_nis_servers (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->nis->len;
}
@@ -1960,7 +2029,7 @@ nm_ip4_config_get_num_nis_servers (const NMIP4Config *config)
guint32
nm_ip4_config_get_nis_server (const NMIP4Config *config, guint i)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return g_array_index (priv->nis, guint32, i);
}
@@ -1977,7 +2046,7 @@ nm_ip4_config_set_nis_domain (NMIP4Config *config, const char *domain)
const char *
nm_ip4_config_get_nis_domain (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->nis_domain;
}
@@ -2025,7 +2094,7 @@ nm_ip4_config_del_wins (NMIP4Config *config, guint i)
guint32
nm_ip4_config_get_num_wins (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->wins->len;
}
@@ -2033,7 +2102,7 @@ nm_ip4_config_get_num_wins (const NMIP4Config *config)
guint32
nm_ip4_config_get_wins (const NMIP4Config *config, guint i)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return g_array_index (priv->wins, guint32, i);
}
@@ -2055,7 +2124,7 @@ nm_ip4_config_set_mtu (NMIP4Config *config, guint32 mtu, NMIPConfigSource source
guint32
nm_ip4_config_get_mtu (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->mtu;
}
@@ -2063,7 +2132,7 @@ nm_ip4_config_get_mtu (const NMIP4Config *config)
NMIPConfigSource
nm_ip4_config_get_mtu_source (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->mtu_source;
}
@@ -2081,7 +2150,7 @@ nm_ip4_config_set_metered (NMIP4Config *config, gboolean metered)
gboolean
nm_ip4_config_get_metered (const NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return priv->metered;
}
@@ -2151,7 +2220,6 @@ nm_ip4_config_hash (const NMIP4Config *config, GChecksum *sum, gboolean dns_only
s = nm_ip4_config_get_dns_option (config, i);
g_checksum_update (sum, (const guint8 *) s, strlen (s));
}
-
}
/**
@@ -2199,10 +2267,7 @@ nm_ip4_config_equal (const NMIP4Config *a, const NMIP4Config *b)
static void
nm_ip4_config_init (NMIP4Config *config)
{
- NMIP4ConfigPrivate *priv;
-
- priv = G_TYPE_INSTANCE_GET_PRIVATE (config, NM_TYPE_IP4_CONFIG, NMIP4ConfigPrivate);
- config->priv = priv;
+ NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
priv->addresses = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP4Address));
priv->routes = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP4Route));
@@ -2386,6 +2451,9 @@ get_property (GObject *object, guint prop_id,
case PROP_DNS_OPTIONS:
nm_utils_g_value_set_strv (value, priv->dns_options);
break;
+ case PROP_DNS_PRIORITY:
+ g_value_set_int (value, priv->dns_priority);
+ break;
case PROP_WINS_SERVERS:
g_value_take_variant (value,
g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
@@ -2424,8 +2492,6 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class)
GObjectClass *object_class = G_OBJECT_CLASS (config_class);
NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (config_class);
- g_type_class_add_private (config_class, sizeof (NMIP4ConfigPrivate));
-
exported_object_class->export_path = NM_DBUS_PATH "/IP4Config/%u";
object_class->get_property = get_property;
@@ -2488,7 +2554,11 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class)
G_TYPE_STRV,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
-
+ obj_properties[PROP_DNS_PRIORITY] =
+ g_param_spec_int (NM_IP4_CONFIG_DNS_PRIORITY, "", "",
+ G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
obj_properties[PROP_WINS_SERVERS] =
g_param_spec_variant (NM_IP4_CONFIG_WINS_SERVERS, "", "",
G_VARIANT_TYPE ("au"),
diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h
index b1a5768740..f302630a0c 100644
--- a/src/nm-ip4-config.h
+++ b/src/nm-ip4-config.h
@@ -31,18 +31,7 @@
#define NM_IS_IP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_IP4_CONFIG))
#define NM_IP4_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IP4_CONFIG, NMIP4ConfigClass))
-struct _NMIP4ConfigPrivate;
-
-struct _NMIP4Config {
- NMExportedObject parent;
-
- /* private */
- struct _NMIP4ConfigPrivate *priv;
-};
-
-typedef struct {
- NMExportedObjectClass parent;
-} NMIP4ConfigClass;
+typedef struct _NMIP4ConfigClass NMIP4ConfigClass;
/* internal */
#define NM_IP4_CONFIG_IFINDEX "ifindex"
@@ -55,6 +44,7 @@ typedef struct {
#define NM_IP4_CONFIG_DOMAINS "domains"
#define NM_IP4_CONFIG_SEARCHES "searches"
#define NM_IP4_CONFIG_DNS_OPTIONS "dns-options"
+#define NM_IP4_CONFIG_DNS_PRIORITY "dns-priority"
#define NM_IP4_CONFIG_WINS_SERVERS "wins-servers"
/* deprecated */
@@ -137,6 +127,10 @@ void nm_ip4_config_del_dns_option (NMIP4Config *config, guint i);
guint32 nm_ip4_config_get_num_dns_options (const NMIP4Config *config);
const char * nm_ip4_config_get_dns_option (const NMIP4Config *config, guint i);
+/* DNS priority */
+void nm_ip4_config_set_dns_priority (NMIP4Config *config, gint priority);
+gint nm_ip4_config_get_dns_priority (const NMIP4Config *config);
+
/* MSS */
void nm_ip4_config_set_mss (NMIP4Config *config, guint32 mss);
guint32 nm_ip4_config_get_mss (const NMIP4Config *config);
diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c
index 8e7bd22cc1..89975f8207 100644
--- a/src/nm-ip6-config.c
+++ b/src/nm-ip6-config.c
@@ -28,17 +28,14 @@
#include "nm-utils.h"
#include "nm-platform.h"
+#include "nm-platform-utils.h"
#include "nm-route-manager.h"
#include "nm-core-internal.h"
#include "NetworkManagerUtils.h"
#include "nmdbus-ip6-config.h"
-G_DEFINE_TYPE (NMIP6Config, nm_ip6_config, NM_TYPE_EXPORTED_OBJECT)
-
-#define NM_IP6_CONFIG_GET_PRIVATE(o) ((o)->priv)
-
-typedef struct _NMIP6ConfigPrivate {
+typedef struct {
gboolean never_default;
struct in6_addr gateway;
GArray *addresses;
@@ -50,8 +47,32 @@ typedef struct _NMIP6ConfigPrivate {
guint32 mss;
int ifindex;
gint64 route_metric;
+ gint dns_priority;
} NMIP6ConfigPrivate;
+struct _NMIP6Config {
+ NMExportedObject parent;
+ NMIP6ConfigPrivate _priv;
+};
+
+struct _NMIP6ConfigClass {
+ NMExportedObjectClass parent;
+};
+
+G_DEFINE_TYPE (NMIP6Config, nm_ip6_config, NM_TYPE_EXPORTED_OBJECT)
+
+#define NM_IP6_CONFIG_GET_PRIVATE(self) \
+ ({ \
+ /* preserve the const-ness of self. Unfortunately, that
+ * way, @self cannot be a void pointer */ \
+ typeof (self) _self = (self); \
+ \
+ /* Get compiler error if variable is of wrong type */ \
+ _nm_unused const NMIP6Config *_self2 = (_self); \
+ \
+ nm_assert (NM_IS_IP6_CONFIG (_self)); \
+ &_self->_priv; \
+ })
NM_GOBJECT_PROPERTIES_DEFINE (NMIP6Config,
PROP_IFINDEX,
@@ -64,6 +85,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMIP6Config,
PROP_DOMAINS,
PROP_SEARCHES,
PROP_DNS_OPTIONS,
+ PROP_DNS_PRIORITY,
);
NMIP6Config *
@@ -240,8 +262,8 @@ _addresses_sort_cmp (gconstpointer a, gconstpointer b, gpointer user_data)
}
/* Sort the addresses based on their source. */
- if (a1->source != a2->source)
- return a1->source > a2->source ? -1 : 1;
+ if (a1->addr_source != a2->addr_source)
+ return a1->addr_source > a2->addr_source ? -1 : 1;
/* sort permanent addresses before non-permanent. */
perm1 = (a1->n_ifa_flags & IFA_F_PERMANENT);
@@ -372,7 +394,7 @@ nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf, NMSettingIP6Co
gboolean
nm_ip6_config_commit (const NMIP6Config *config, int ifindex, gboolean routes_full_sync)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
int i;
gboolean success;
@@ -414,7 +436,7 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, gu
NMIP6ConfigPrivate *priv;
guint naddresses, nroutes, nnameservers, nsearches;
const char *gateway_str;
- int i;
+ int i, priority;
if (!setting)
return;
@@ -457,7 +479,7 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, gu
nm_assert (address.plen <= 128);
address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT;
address.preferred = NM_PLATFORM_LIFETIME_PERMANENT;
- address.source = NM_IP_CONFIG_SOURCE_USER;
+ address.addr_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip6_config_add_address (config, &address);
}
@@ -482,7 +504,7 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, gu
route.metric = default_route_metric;
else
route.metric = nm_ip_route_get_metric (s_route);
- route.source = NM_IP_CONFIG_SOURCE_USER;
+ route.rt_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip6_config_add_route (config, &route);
}
@@ -508,6 +530,10 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, gu
i++;
}
+ priority = nm_setting_ip_config_get_dns_priority (setting);
+ if (priority)
+ nm_ip6_config_set_dns_priority (config, priority);
+
g_object_thaw_notify (G_OBJECT (config));
}
@@ -596,7 +622,7 @@ nm_ip6_config_create_setting (const NMIP6Config *config)
continue;
/* Ignore routes provided by external sources */
- if (route->source != NM_IP_CONFIG_SOURCE_USER)
+ if (route->rt_source != nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER))
continue;
s_route = nm_ip_route_new_binary (AF_INET6,
@@ -624,6 +650,10 @@ nm_ip6_config_create_setting (const NMIP6Config *config)
nm_setting_ip_config_add_dns_option (s_ip6, option);
}
+ g_object_set (s_ip6,
+ NM_SETTING_IP_CONFIG_DNS_PRIORITY,
+ nm_ip6_config_get_dns_priority (config),
+ NULL);
return NM_SETTING (s_ip6);
}
@@ -633,7 +663,8 @@ nm_ip6_config_create_setting (const NMIP6Config *config)
void
nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src, NMIPConfigMergeFlags merge_flags)
{
- NMIP6ConfigPrivate *dst_priv, *src_priv;
+ NMIP6ConfigPrivate *dst_priv;
+ const NMIP6ConfigPrivate *src_priv;
guint32 i;
g_return_if_fail (src != NULL);
@@ -690,6 +721,10 @@ nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src, NMIPConfigMergeFl
if (nm_ip6_config_get_mss (src))
nm_ip6_config_set_mss (dst, nm_ip6_config_get_mss (src));
+ /* DNS priority */
+ if (nm_ip6_config_get_dns_priority (src))
+ nm_ip6_config_set_dns_priority (dst, nm_ip6_config_get_dns_priority (src));
+
g_object_thaw_notify (G_OBJECT (dst));
}
@@ -719,7 +754,7 @@ nm_ip6_config_destination_is_direct (const NMIP6Config *config, const struct in6
static int
_addresses_get_index (const NMIP6Config *self, const NMPlatformIP6Address *addr)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
guint i;
for (i = 0; i < priv->addresses->len; i++) {
@@ -734,7 +769,7 @@ _addresses_get_index (const NMIP6Config *self, const NMPlatformIP6Address *addr)
static int
_nameservers_get_index (const NMIP6Config *self, const struct in6_addr *ns)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
guint i;
for (i = 0; i < priv->nameservers->len; i++) {
@@ -749,7 +784,7 @@ _nameservers_get_index (const NMIP6Config *self, const struct in6_addr *ns)
static int
_routes_get_index (const NMIP6Config *self, const NMPlatformIP6Route *route)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
guint i;
for (i = 0; i < priv->routes->len; i++) {
@@ -764,7 +799,7 @@ _routes_get_index (const NMIP6Config *self, const NMPlatformIP6Route *route)
static int
_domains_get_index (const NMIP6Config *self, const char *domain)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
guint i;
for (i = 0; i < priv->domains->len; i++) {
@@ -779,7 +814,7 @@ _domains_get_index (const NMIP6Config *self, const char *domain)
static int
_searches_get_index (const NMIP6Config *self, const char *search)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
guint i;
for (i = 0; i < priv->searches->len; i++) {
@@ -794,7 +829,7 @@ _searches_get_index (const NMIP6Config *self, const char *search)
static int
_dns_options_get_index (const NMIP6Config *self, const char *option)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
guint i;
for (i = 0; i < priv->dns_options->len; i++) {
@@ -883,6 +918,10 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src)
if (nm_ip6_config_get_mss (src) == nm_ip6_config_get_mss (dst))
nm_ip6_config_set_mss (dst, 0);
+ /* DNS priority */
+ if (nm_ip6_config_get_dns_priority (src) == nm_ip6_config_get_dns_priority (dst))
+ nm_ip6_config_set_dns_priority (dst, 0);
+
g_object_thaw_notify (G_OBJECT (dst));
}
@@ -958,7 +997,8 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev
#endif
gboolean has_minor_changes = FALSE, has_relevant_changes = FALSE, are_equal;
guint i, num;
- NMIP6ConfigPrivate *dst_priv, *src_priv;
+ NMIP6ConfigPrivate *dst_priv;
+ const NMIP6ConfigPrivate *src_priv;
const NMPlatformIP6Address *dst_addr, *src_addr;
const NMPlatformIP6Route *dst_route, *src_route;
@@ -1129,6 +1169,12 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev
has_minor_changes = TRUE;
}
+ /* DNS priority */
+ if (src_priv->dns_priority != dst_priv->dns_priority) {
+ nm_ip6_config_set_dns_priority (dst, src_priv->dns_priority);
+ has_minor_changes = TRUE;
+ }
+
#if NM_MORE_ASSERTS
/* config_equal does not compare *all* the fields, therefore, we might have has_minor_changes
* regardless of config_equal. But config_equal must correspond to has_relevant_changes. */
@@ -1189,6 +1235,8 @@ nm_ip6_config_dump (const NMIP6Config *config, const char *detail)
for (i = 0; i < nm_ip6_config_get_num_dns_options (config); i++)
g_message (" dnsopt: %s", nm_ip6_config_get_dns_option (config, i));
+ g_message (" dnspri: %d", nm_ip6_config_get_dns_priority (config));
+
g_message (" mss: %"G_GUINT32_FORMAT, nm_ip6_config_get_mss (config));
g_message (" n-dflt: %d", nm_ip6_config_get_never_default (config));
}
@@ -1206,7 +1254,7 @@ nm_ip6_config_set_never_default (NMIP6Config *config, gboolean never_default)
gboolean
nm_ip6_config_get_never_default (const NMIP6Config *config)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return priv->never_default;
}
@@ -1231,7 +1279,7 @@ nm_ip6_config_set_gateway (NMIP6Config *config, const struct in6_addr *gateway)
const struct in6_addr *
nm_ip6_config_get_gateway (const NMIP6Config *config)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return IN6_IS_ADDR_UNSPECIFIED (&priv->gateway) ? NULL : &priv->gateway;
}
@@ -1239,7 +1287,7 @@ nm_ip6_config_get_gateway (const NMIP6Config *config)
gint64
nm_ip6_config_get_route_metric (const NMIP6Config *config)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return priv->route_metric;
}
@@ -1290,14 +1338,14 @@ nm_ip6_config_add_address (NMIP6Config *config, const NMPlatformIP6Address *new)
*item = *new;
/* But restore highest priority source */
- item->source = MAX (item_old.source, new->source);
+ item->addr_source = MAX (item_old.addr_source, new->addr_source);
/* for addresses that we read from the kernel, we keep the timestamps as defined
* by the previous source (item_old). The reason is, that the other source configured the lifetimes
* with "what should be" and the kernel values are "what turned out after configuring it".
*
* For other sources, the longer lifetime wins. */
- if ( (new->source == NM_IP_CONFIG_SOURCE_KERNEL && new->source != item_old.source)
+ if ( (new->addr_source == NM_IP_CONFIG_SOURCE_KERNEL && new->addr_source != item_old.addr_source)
|| nm_platform_ip_address_cmp_expiry ((const NMPlatformIPAddress *) &item_old, (const NMPlatformIPAddress *) new) > 0) {
item->timestamp = item_old.timestamp;
item->lifetime = item_old.lifetime;
@@ -1330,7 +1378,7 @@ nm_ip6_config_del_address (NMIP6Config *config, guint i)
guint
nm_ip6_config_get_num_addresses (const NMIP6Config *config)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return priv->addresses->len;
}
@@ -1338,7 +1386,7 @@ nm_ip6_config_get_num_addresses (const NMIP6Config *config)
const NMPlatformIP6Address *
nm_ip6_config_get_address (const NMIP6Config *config, guint i)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return &g_array_index (priv->addresses, NMPlatformIP6Address, i);
}
@@ -1353,7 +1401,7 @@ nm_ip6_config_address_exists (const NMIP6Config *config,
const NMPlatformIP6Address *
nm_ip6_config_get_address_first_nontentative (const NMIP6Config *config, gboolean linklocal)
{
- NMIP6ConfigPrivate *priv;
+ const NMIP6ConfigPrivate *priv;
guint i;
g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
@@ -1373,6 +1421,47 @@ nm_ip6_config_get_address_first_nontentative (const NMIP6Config *config, gboolea
return NULL;
}
+/**
+ * nm_ip6_config_has_dad_pending_addresses
+ * @self: configuration containing the addresses to check
+ * @candidates: configuration with the list of addresses we are
+ * interested in
+ *
+ * Check whether there are addresses with DAD pending in @self, that
+ * are also contained in @candidates.
+ *
+ * Returns: %TRUE if at least one matching address was found, %FALSE
+ * otherwise
+ */
+gboolean
+nm_ip6_config_has_any_dad_pending (const NMIP6Config *self,
+ const NMIP6Config *candidates)
+{
+ const NMPlatformIP6Address *addr, *addr_c;
+ guint i, j, num, num_c;
+
+ num = nm_ip6_config_get_num_addresses (self);
+
+ for (i = 0; i < num; i++) {
+ addr = nm_ip6_config_get_address (self, i);
+ if ( NM_FLAGS_HAS (addr->n_ifa_flags, IFA_F_TENTATIVE)
+ && !NM_FLAGS_HAS (addr->n_ifa_flags, IFA_F_DADFAILED)
+ && !NM_FLAGS_HAS (addr->n_ifa_flags, IFA_F_OPTIMISTIC)) {
+
+ num_c = nm_ip6_config_get_num_addresses (candidates);
+
+ for (j = 0; j < num_c; j++) {
+ addr_c = nm_ip6_config_get_address (candidates, j);
+ if ( addresses_are_duplicate (addr, addr_c)
+ && addr->plen == addr_c->plen)
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
/******************************************************************/
void
@@ -1414,10 +1503,10 @@ nm_ip6_config_add_route (NMIP6Config *config, const NMPlatformIP6Route *new)
if (routes_are_duplicate (item, new, FALSE)) {
if (nm_platform_ip6_route_cmp (item, new) == 0)
return;
- old_source = item->source;
+ old_source = item->rt_source;
*item = *new;
/* Restore highest priority source */
- item->source = MAX (old_source, new->source);
+ item->rt_source = MAX (old_source, new->rt_source);
item->ifindex = priv->ifindex;
goto NOTIFY;
}
@@ -1445,7 +1534,7 @@ nm_ip6_config_del_route (NMIP6Config *config, guint i)
guint
nm_ip6_config_get_num_routes (const NMIP6Config *config)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return priv->routes->len;
}
@@ -1453,7 +1542,7 @@ nm_ip6_config_get_num_routes (const NMIP6Config *config)
const NMPlatformIP6Route *
nm_ip6_config_get_route (const NMIP6Config *config, guint i)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return &g_array_index (priv->routes, NMPlatformIP6Route, i);
}
@@ -1461,7 +1550,7 @@ nm_ip6_config_get_route (const NMIP6Config *config, guint i)
const NMPlatformIP6Route *
nm_ip6_config_get_direct_route_for_host (const NMIP6Config *config, const struct in6_addr *host)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
guint i;
NMPlatformIP6Route *best_route = NULL;
@@ -1492,7 +1581,7 @@ nm_ip6_config_get_direct_route_for_host (const NMIP6Config *config, const struct
const NMPlatformIP6Address *
nm_ip6_config_get_subnet_for_host (const NMIP6Config *config, const struct in6_addr *host)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
guint i;
NMPlatformIP6Address *subnet = NULL;
struct in6_addr subnet2, host2;
@@ -1559,7 +1648,7 @@ nm_ip6_config_del_nameserver (NMIP6Config *config, guint i)
guint32
nm_ip6_config_get_num_nameservers (const NMIP6Config *config)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return priv->nameservers->len;
}
@@ -1567,7 +1656,7 @@ nm_ip6_config_get_num_nameservers (const NMIP6Config *config)
const struct in6_addr *
nm_ip6_config_get_nameserver (const NMIP6Config *config, guint i)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return &g_array_index (priv->nameservers, struct in6_addr, i);
}
@@ -1616,7 +1705,7 @@ nm_ip6_config_del_domain (NMIP6Config *config, guint i)
guint32
nm_ip6_config_get_num_domains (const NMIP6Config *config)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return priv->domains->len;
}
@@ -1624,7 +1713,7 @@ nm_ip6_config_get_num_domains (const NMIP6Config *config)
const char *
nm_ip6_config_get_domain (const NMIP6Config *config, guint i)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return g_ptr_array_index (priv->domains, i);
}
@@ -1688,7 +1777,7 @@ nm_ip6_config_del_search (NMIP6Config *config, guint i)
guint32
nm_ip6_config_get_num_searches (const NMIP6Config *config)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return priv->searches->len;
}
@@ -1696,7 +1785,7 @@ nm_ip6_config_get_num_searches (const NMIP6Config *config)
const char *
nm_ip6_config_get_search (const NMIP6Config *config, guint i)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return g_ptr_array_index (priv->searches, i);
}
@@ -1745,7 +1834,7 @@ nm_ip6_config_del_dns_option (NMIP6Config *config, guint i)
guint32
nm_ip6_config_get_num_dns_options (const NMIP6Config *config)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return priv->dns_options->len;
}
@@ -1753,7 +1842,7 @@ nm_ip6_config_get_num_dns_options (const NMIP6Config *config)
const char *
nm_ip6_config_get_dns_option (const NMIP6Config *config, guint i)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return g_ptr_array_index (priv->dns_options, i);
}
@@ -1761,6 +1850,27 @@ nm_ip6_config_get_dns_option (const NMIP6Config *config, guint i)
/******************************************************************/
void
+nm_ip6_config_set_dns_priority (NMIP6Config *config, gint priority)
+{
+ NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+
+ if (priority != priv->dns_priority) {
+ priv->dns_priority = priority;
+ _notify (config, PROP_DNS_PRIORITY);
+ }
+}
+
+gint
+nm_ip6_config_get_dns_priority (const NMIP6Config *config)
+{
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+
+ return priv->dns_priority;
+}
+
+/******************************************************************/
+
+void
nm_ip6_config_set_mss (NMIP6Config *config, guint32 mss)
{
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
@@ -1771,7 +1881,7 @@ nm_ip6_config_set_mss (NMIP6Config *config, guint32 mss)
guint32
nm_ip6_config_get_mss (const NMIP6Config *config)
{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return priv->mss;
}
@@ -1839,7 +1949,6 @@ nm_ip6_config_hash (const NMIP6Config *config, GChecksum *sum, gboolean dns_only
s = nm_ip6_config_get_dns_option (config, i);
g_checksum_update (sum, (const guint8 *) s, strlen (s));
}
-
}
/**
@@ -1887,10 +1996,7 @@ nm_ip6_config_equal (const NMIP6Config *a, const NMIP6Config *b)
static void
nm_ip6_config_init (NMIP6Config *config)
{
- NMIP6ConfigPrivate *priv;
-
- priv = G_TYPE_INSTANCE_GET_PRIVATE (config, NM_TYPE_IP6_CONFIG, NMIP6ConfigPrivate);
- config->priv = priv;
+ NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
priv->addresses = g_array_new (FALSE, TRUE, sizeof (NMPlatformIP6Address));
priv->routes = g_array_new (FALSE, TRUE, sizeof (NMPlatformIP6Route));
@@ -2079,6 +2185,9 @@ get_property (GObject *object, guint prop_id,
case PROP_DNS_OPTIONS:
nm_utils_g_value_set_strv (value, priv->dns_options);
break;
+ case PROP_DNS_PRIORITY:
+ g_value_set_int (value, priv->dns_priority);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -2110,8 +2219,6 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class)
GObjectClass *object_class = G_OBJECT_CLASS (config_class);
NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (config_class);
- g_type_class_add_private (config_class, sizeof (NMIP6ConfigPrivate));
-
exported_object_class->export_path = NM_DBUS_PATH "/IP6Config/%u";
/* virtual methods */
@@ -2176,6 +2283,11 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class)
G_TYPE_STRV,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_DNS_PRIORITY] =
+ g_param_spec_int (NM_IP6_CONFIG_DNS_PRIORITY, "", "",
+ G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h
index 5e66d500e4..c3f8d9f879 100644
--- a/src/nm-ip6-config.h
+++ b/src/nm-ip6-config.h
@@ -33,18 +33,7 @@
#define NM_IS_IP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_IP6_CONFIG))
#define NM_IP6_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IP6_CONFIG, NMIP6ConfigClass))
-struct _NMIP6ConfigPrivate;
-
-struct _NMIP6Config {
- NMExportedObject parent;
-
- /* private */
- struct _NMIP6ConfigPrivate *priv;
-};
-
-typedef struct {
- NMExportedObjectClass parent;
-} NMIP6ConfigClass;
+typedef struct _NMIP6ConfigClass NMIP6ConfigClass;
/* internal */
#define NM_IP6_CONFIG_IFINDEX "ifindex"
@@ -57,6 +46,7 @@ typedef struct {
#define NM_IP6_CONFIG_DOMAINS "domains"
#define NM_IP6_CONFIG_SEARCHES "searches"
#define NM_IP6_CONFIG_DNS_OPTIONS "dns-options"
+#define NM_IP6_CONFIG_DNS_PRIORITY "dns-priority"
/* deprecated */
#define NM_IP6_CONFIG_ADDRESSES "addresses"
@@ -100,6 +90,8 @@ const NMPlatformIP6Address *nm_ip6_config_get_address (const NMIP6Config *config
const NMPlatformIP6Address *nm_ip6_config_get_address_first_nontentative (const NMIP6Config *config, gboolean linklocal);
gboolean nm_ip6_config_address_exists (const NMIP6Config *config, const NMPlatformIP6Address *address);
gboolean nm_ip6_config_addresses_sort (NMIP6Config *config, NMSettingIP6ConfigPrivacy use_temporary);
+gboolean nm_ip6_config_has_any_dad_pending (const NMIP6Config *self,
+ const NMIP6Config *candidates);
/* Routes */
void nm_ip6_config_reset_routes (NMIP6Config *config);
@@ -139,6 +131,10 @@ void nm_ip6_config_del_dns_option (NMIP6Config *config, guint i);
guint32 nm_ip6_config_get_num_dns_options (const NMIP6Config *config);
const char * nm_ip6_config_get_dns_option (const NMIP6Config *config, guint i);
+/* DNS priority */
+void nm_ip6_config_set_dns_priority (NMIP6Config *config, gint priority);
+gint nm_ip6_config_get_dns_priority (const NMIP6Config *config);
+
/* MSS */
void nm_ip6_config_set_mss (NMIP6Config *config, guint32 mss);
guint32 nm_ip6_config_get_mss (const NMIP6Config *config);
diff --git a/src/nm-logging.c b/src/nm-logging.c
index 935b34a8e3..4d9b3fbd45 100644
--- a/src/nm-logging.c
+++ b/src/nm-logging.c
@@ -93,16 +93,31 @@ typedef struct {
typedef struct {
const char *name;
const char *level_str;
+
+ /* nm-logging uses syslog internally. Note that the three most-verbose syslog levels
+ * are LOG_DEBUG, LOG_INFO and LOG_NOTICE. Journal already highlights LOG_NOTICE
+ * as special.
+ *
+ * On the other hand, we have three levels LOGL_TRACE, LOGL_DEBUG and LOGL_INFO,
+ * which are regular messages not to be highlighted. For that reason, we must map
+ * LOGL_TRACE and LOGL_DEBUG both to syslog level LOG_DEBUG. */
int syslog_level;
+
GLogLevelFlags g_log_level;
LogFormatFlags log_format_level;
} LogLevelDesc;
+NMLogDomain _nm_logging_enabled_state[_LOGL_N_REAL] = {
+ /* nm_logging_setup ("INFO", LOGD_DEFAULT_STRING, NULL, NULL); */
+ [LOGL_INFO] = LOGD_DEFAULT,
+ [LOGL_WARN] = LOGD_DEFAULT,
+ [LOGL_ERR] = LOGD_DEFAULT,
+};
+
static struct {
NMLogLevel log_level;
- NMLogDomain logging[_LOGL_N_REAL];
- gboolean logging_set_up;
LogFormatFlags log_format_flags;
+ bool uses_syslog:1;
enum {
LOG_BACKEND_GLIB,
LOG_BACKEND_SYSLOG,
@@ -111,17 +126,18 @@ static struct {
char *logging_domains_to_string;
const LogLevelDesc level_desc[_LOGL_N];
-#define _DOMAIN_DESC_LEN 37
+#define _DOMAIN_DESC_LEN 38
/* Would be nice to use C99 flexible array member here,
* but that feature doesn't seem well supported. */
const LogDesc domain_desc[_DOMAIN_DESC_LEN];
} global = {
+ /* nm_logging_setup ("INFO", LOGD_DEFAULT_STRING, NULL, NULL); */
.log_level = LOGL_INFO,
.log_backend = LOG_BACKEND_GLIB,
.log_format_flags = _LOG_FORMAT_FLAG_DEFAULT,
.level_desc = {
[LOGL_TRACE] = { "TRACE", "<trace>", LOG_DEBUG, G_LOG_LEVEL_DEBUG, _LOG_FORMAT_FLAG_LEVEL_DEBUG },
- [LOGL_DEBUG] = { "DEBUG", "<debug>", LOG_INFO, G_LOG_LEVEL_DEBUG, _LOG_FORMAT_FLAG_LEVEL_DEBUG },
+ [LOGL_DEBUG] = { "DEBUG", "<debug>", LOG_DEBUG, G_LOG_LEVEL_DEBUG, _LOG_FORMAT_FLAG_LEVEL_DEBUG },
[LOGL_INFO] = { "INFO", "<info>", LOG_INFO, G_LOG_LEVEL_INFO, _LOG_FORMAT_FLAG_LEVEL_INFO },
[LOGL_WARN] = { "WARN", "<warn>", LOG_WARNING, G_LOG_LEVEL_MESSAGE, _LOG_FORMAT_FLAG_LEVEL_INFO },
[LOGL_ERR] = { "ERR", "<error>", LOG_ERR, G_LOG_LEVEL_MESSAGE, _LOG_FORMAT_FLAG_LEVEL_ERROR },
@@ -165,6 +181,7 @@ static struct {
{ LOGD_DISPATCH, "DISPATCH" },
{ LOGD_AUDIT, "AUDIT" },
{ LOGD_SYSTEMD, "SYSTEMD" },
+ { LOGD_VPN_PLUGIN,"VPN_PLUGIN" },
{ 0, NULL }
/* keep _DOMAIN_DESC_LEN in sync */
},
@@ -185,19 +202,6 @@ static char *_domains_to_string (gboolean include_level_override);
/************************************************************************/
-static void
-_ensure_initialized (void)
-{
- if (G_UNLIKELY (!global.logging_set_up)) {
- int errsv = errno;
-
- nm_logging_setup ("INFO", LOGD_DEFAULT_STRING, NULL, NULL);
-
- /* must ensure that errno is not modified. */
- errno = errsv;
- }
-}
-
static gboolean
match_log_level (const char *level,
NMLogLevel *out_level,
@@ -224,7 +228,7 @@ nm_logging_setup (const char *level,
GError **error)
{
GString *unrecognized = NULL;
- NMLogDomain new_logging[G_N_ELEMENTS (global.logging)];
+ NMLogDomain new_logging[G_N_ELEMENTS (_nm_logging_enabled_state)];
NMLogLevel new_log_level = global.log_level;
char **tmp, **iter;
int i;
@@ -235,13 +239,8 @@ nm_logging_setup (const char *level,
g_return_val_if_fail (!error || !*error, FALSE);
/* domains */
- if (!domains || !*domains) {
- domains = global.logging_set_up
- ? (domains_free = _domains_to_string (FALSE))
- : LOGD_DEFAULT_STRING;
- }
-
- global.logging_set_up = TRUE;
+ if (!domains || !*domains)
+ domains = (domains_free = _domains_to_string (FALSE));
for (i = 0; i < G_N_ELEMENTS (new_logging); i++)
new_logging[i] = 0;
@@ -253,7 +252,7 @@ nm_logging_setup (const char *level,
if (new_log_level == _LOGL_KEEP) {
new_log_level = global.log_level;
for (i = 0; i < G_N_ELEMENTS (new_logging); i++)
- new_logging[i] = global.logging[i];
+ new_logging[i] = _nm_logging_enabled_state[i];
}
}
@@ -321,7 +320,7 @@ nm_logging_setup (const char *level,
if (domain_log_level == _LOGL_KEEP) {
for (i = 0; i < G_N_ELEMENTS (new_logging); i++)
- new_logging[i] = (new_logging[i] & ~bits) | (global.logging[i] & bits);
+ new_logging[i] = (new_logging[i] & ~bits) | (_nm_logging_enabled_state[i] & bits);
} else {
for (i = 0; i < G_N_ELEMENTS (new_logging); i++) {
if (i < domain_log_level)
@@ -339,7 +338,7 @@ nm_logging_setup (const char *level,
global.log_level = new_log_level;
for (i = 0; i < G_N_ELEMENTS (new_logging); i++)
- global.logging[i] = new_logging[i];
+ _nm_logging_enabled_state[i] = new_logging[i];
if ( had_platform_debug
&& _nm_logging_clear_platform_logging_cache
@@ -384,8 +383,6 @@ nm_logging_all_levels_to_string (void)
const char *
nm_logging_domains_to_string (void)
{
- _ensure_initialized ();
-
if (G_UNLIKELY (!global.logging_domains_to_string))
global.logging_domains_to_string = _domains_to_string (TRUE);
@@ -406,7 +403,7 @@ _domains_to_string (gboolean include_level_override)
str = g_string_sized_new (75);
for (diter = &global.domain_desc[0]; diter->name; diter++) {
/* If it's set for any lower level, it will also be set for LOGL_ERR */
- if (!(diter->num & global.logging[LOGL_ERR]))
+ if (!(diter->num & _nm_logging_enabled_state[LOGL_ERR]))
continue;
if (str->len)
@@ -418,15 +415,15 @@ _domains_to_string (gboolean include_level_override)
/* Check if it's logging at a lower level than the default. */
for (i = 0; i < global.log_level; i++) {
- if (diter->num & global.logging[i]) {
+ if (diter->num & _nm_logging_enabled_state[i]) {
g_string_append_printf (str, ":%s", global.level_desc[i].name);
break;
}
}
/* Check if it's logging at a higher level than the default. */
- if (!(diter->num & global.logging[global.log_level])) {
- for (i = global.log_level + 1; i < G_N_ELEMENTS (global.logging); i++) {
- if (diter->num & global.logging[i]) {
+ if (!(diter->num & _nm_logging_enabled_state[global.log_level])) {
+ for (i = global.log_level + 1; i < G_N_ELEMENTS (_nm_logging_enabled_state); i++) {
+ if (diter->num & _nm_logging_enabled_state[i]) {
g_string_append_printf (str, ":%s", global.level_desc[i].name);
break;
}
@@ -459,16 +456,25 @@ nm_logging_all_domains_to_string (void)
return str->str;
}
-gboolean
-nm_logging_enabled (NMLogLevel level, NMLogDomain domain)
+/**
+ * nm_logging_get_level:
+ * @domain: find the lowest enabled logging level for the
+ * given domain. If this is a set of multiple
+ * domains, the most verbose level will be returned.
+ *
+ * Returns: the lowest (most verbose) logging level for the
+ * give @domain, or %_LOGL_OFF if it is disabled.
+ **/
+NMLogLevel
+nm_logging_get_level (NMLogDomain domain)
{
- if ((guint) level >= G_N_ELEMENTS (global.logging))
- g_return_val_if_reached (FALSE);
-
- /* This function is guaranteed not to modify errno. */
- _ensure_initialized ();
+ NMLogLevel sl = _LOGL_OFF;
- return !!(global.logging[level] & domain);
+ G_STATIC_ASSERT (LOGL_TRACE == 0);
+ while ( sl > LOGL_TRACE
+ && nm_logging_enabled (sl - 1, domain))
+ sl--;
+ return sl;
}
#if SYSTEMD_JOURNAL
@@ -515,12 +521,10 @@ _nm_log_impl (const char *file,
char s_buf_location[1024];
GTimeVal tv;
- if ((guint) level >= G_N_ELEMENTS (global.logging))
+ if ((guint) level >= G_N_ELEMENTS (_nm_logging_enabled_state))
g_return_if_reached ();
- _ensure_initialized ();
-
- if (!(global.logging[level] & domain))
+ if (!(_nm_logging_enabled_state[level] & domain))
return;
/* Make sure that %m maps to the specified error */
@@ -609,7 +613,7 @@ _nm_log_impl (const char *file,
const char *s_domain_1 = NULL;
GString *s_domain_all = NULL;
NMLogDomain dom_all = domain;
- NMLogDomain dom = dom_all & global.logging[level];
+ NMLogDomain dom = dom_all & _nm_logging_enabled_state[level];
for (diter = &global.domain_desc[0]; diter->name; diter++) {
if (!NM_FLAGS_HAS (dom_all, diter->num))
@@ -744,6 +748,12 @@ nm_log_handler (const gchar *log_domain,
}
}
+gboolean
+nm_logging_syslog_enabled (void)
+{
+ return global.uses_syslog;
+}
+
void
nm_logging_syslog_openlog (const char *logging_backend)
{
@@ -763,6 +773,7 @@ nm_logging_syslog_openlog (const char *logging_backend)
#if SYSTEMD_JOURNAL
} else if (strcmp (logging_backend, "syslog") != 0) {
global.log_backend = LOG_BACKEND_JOURNAL;
+ global.uses_syslog = TRUE;
/* ensure we read a monotonic timestamp. Reading the timestamp the first
* time causes a logging message. We don't want to do that during _nm_log_impl. */
@@ -770,6 +781,7 @@ nm_logging_syslog_openlog (const char *logging_backend)
#endif
} else {
global.log_backend = LOG_BACKEND_SYSLOG;
+ global.uses_syslog = TRUE;
openlog (G_LOG_DOMAIN, LOG_PID, LOG_DAEMON);
}
diff --git a/src/nm-logging.h b/src/nm-logging.h
index 27f89f5d5b..f49f6ec67b 100644
--- a/src/nm-logging.h
+++ b/src/nm-logging.h
@@ -65,12 +65,16 @@ typedef enum { /*< skip >*/
LOGD_DISPATCH = (1LL << 33),
LOGD_AUDIT = (1LL << 34),
LOGD_SYSTEMD = (1LL << 35),
+ LOGD_VPN_PLUGIN = (1LL << 36),
__LOGD_MAX,
- LOGD_ALL = ((__LOGD_MAX - 1LL) << 1) - 1LL,
+ LOGD_ALL = (((__LOGD_MAX - 1LL) << 1) - 1LL) & ~(
+ LOGD_VPN_PLUGIN | /*not even part of ALL, because it might expose sensitive information. */
+ 0),
LOGD_DEFAULT = LOGD_ALL & ~(
LOGD_DBUS_PROPS |
LOGD_WIFI_SCAN |
+ LOGD_VPN_PLUGIN |
0),
/* aliases: */
@@ -158,7 +162,17 @@ void _nm_log_impl (const char *file,
const char *nm_logging_level_to_string (void);
const char *nm_logging_domains_to_string (void);
-gboolean nm_logging_enabled (NMLogLevel level, NMLogDomain domain);
+
+extern NMLogDomain _nm_logging_enabled_state[_LOGL_N_REAL];
+static inline gboolean
+nm_logging_enabled (NMLogLevel level, NMLogDomain domain)
+{
+ nm_assert (((guint) level) < G_N_ELEMENTS (_nm_logging_enabled_state));
+ return (((guint) level) < G_N_ELEMENTS (_nm_logging_enabled_state))
+ && !!(_nm_logging_enabled_state[level] & domain);
+}
+
+NMLogLevel nm_logging_get_level (NMLogDomain domain);
const char *nm_logging_all_levels_to_string (void);
const char *nm_logging_all_domains_to_string (void);
@@ -168,6 +182,7 @@ gboolean nm_logging_setup (const char *level,
char **bad_domains,
GError **error);
void nm_logging_syslog_openlog (const char *logging_backend);
+gboolean nm_logging_syslog_enabled (void);
/*****************************************************************************/
diff --git a/src/nm-manager.c b/src/nm-manager.c
index b4e832dfb0..333e47366f 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -21,13 +21,14 @@
#include "nm-default.h"
+#include "nm-manager.h"
+
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
-#include "nm-manager.h"
#include "nm-bus-manager.h"
#include "nm-vpn-manager.h"
#include "nm-device.h"
@@ -45,7 +46,6 @@
#include "nm-sleep-monitor.h"
#include "nm-connectivity.h"
#include "nm-policy.h"
-#include "nm-connection-provider.h"
#include "nm-session-monitor.h"
#include "nm-activation-request.h"
#include "nm-core-internal.h"
@@ -90,15 +90,13 @@ typedef struct {
gboolean sw_enabled;
gboolean hw_enabled;
RfKillType rtype;
+ NMConfigRunStatePropertyType key;
const char *desc;
- const char *key;
const char *prop;
const char *hw_prop;
} RadioState;
typedef struct {
- char *state_file;
-
GSList *active_connections;
GSList *authorizing_connections;
guint ac_cleanup_id;
@@ -144,7 +142,16 @@ typedef struct {
gboolean devices_inited;
} NMManagerPrivate;
-#define NM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MANAGER, NMManagerPrivate))
+struct _NMManager {
+ NMExportedObject parent;
+ NMManagerPrivate priv;
+};
+
+typedef struct {
+ NMExportedObjectClass parent;
+} NMManagerClass;
+
+#define NM_MANAGER_GET_PRIVATE(o) ({ nm_assert (NM_IS_MANAGER (o)); &((o)->priv); })
G_DEFINE_TYPE (NMManager, nm_manager, NM_TYPE_EXPORTED_OBJECT)
@@ -167,7 +174,6 @@ static guint signals[LAST_SIGNAL] = { 0 };
NM_GOBJECT_PROPERTIES_DEFINE (NMManager,
PROP_VERSION,
PROP_STATE,
- PROP_STATE_FILE,
PROP_STARTUP,
PROP_NETWORKING_ENABLED,
PROP_WIRELESS_ENABLED,
@@ -401,7 +407,7 @@ find_ac_for_connection (NMManager *manager, NMConnection *connection)
}
/* Filter out connections that are already active.
- * nm_settings_get_connections() returns sorted list. We need to preserve the
+ * nm_settings_get_connections_sorted() returns sorted list. We need to preserve the
* order so that we didn't change auto-activation order (recent timestamps
* are first).
* Caller is responsible for freeing the returned list with g_slist_free().
@@ -410,7 +416,7 @@ GSList *
nm_manager_get_activatable_connections (NMManager *manager)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
- GSList *all_connections = nm_settings_get_connections (priv->settings);
+ GSList *all_connections = nm_settings_get_connections_sorted (priv->settings);
GSList *connections = NULL, *iter;
NMSettingsConnection *connection;
@@ -1125,7 +1131,7 @@ system_create_virtual_device (NMManager *self, NMConnection *connection)
}
/* Create backing resources if the device has any autoconnect connections */
- connections = nm_settings_get_connections (priv->settings);
+ connections = nm_settings_get_connections_sorted (priv->settings);
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMConnection *candidate = iter->data;
NMSettingConnection *s_con;
@@ -1160,7 +1166,7 @@ retry_connections_for_parent_device (NMManager *self, NMDevice *device)
g_return_if_fail (device);
- connections = nm_settings_get_connections (priv->settings);
+ connections = nm_settings_get_connections_sorted (priv->settings);
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMConnection *candidate = iter->data;
gs_free_error GError *error = NULL;
@@ -1229,7 +1235,7 @@ system_unmanaged_devices_changed_cb (NMSettings *settings,
unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings);
for (iter = priv->devices; iter; iter = g_slist_next (iter))
- nm_device_set_unmanaged_by_user_config (NM_DEVICE (iter->data), unmanaged_specs);
+ nm_device_set_unmanaged_by_user_settings (NM_DEVICE (iter->data), unmanaged_specs);
}
static void
@@ -1268,54 +1274,6 @@ system_hostname_changed_cb (NMSettings *settings,
/* General NMManager stuff */
/*******************************************************************/
-/* Store value into key-file; supported types: boolean, int, string */
-static gboolean
-write_value_to_state_file (const char *filename,
- const char *group,
- const char *key,
- GType value_type,
- gpointer value,
- GError **error)
-{
- GKeyFile *key_file;
- char *data;
- gsize len = 0;
- gboolean ret = FALSE;
-
- g_return_val_if_fail (filename != NULL, FALSE);
- g_return_val_if_fail (group != NULL, FALSE);
- g_return_val_if_fail (key != NULL, FALSE);
- g_return_val_if_fail (value_type == G_TYPE_BOOLEAN ||
- value_type == G_TYPE_INT ||
- value_type == G_TYPE_STRING,
- FALSE);
-
- key_file = g_key_file_new ();
-
- g_key_file_set_list_separator (key_file, ',');
- g_key_file_load_from_file (key_file, filename, G_KEY_FILE_KEEP_COMMENTS, NULL);
- switch (value_type) {
- case G_TYPE_BOOLEAN:
- g_key_file_set_boolean (key_file, group, key, *((gboolean *) value));
- break;
- case G_TYPE_INT:
- g_key_file_set_integer (key_file, group, key, *((gint *) value));
- break;
- case G_TYPE_STRING:
- g_key_file_set_string (key_file, group, key, *((const gchar **) value));
- break;
- }
-
- data = g_key_file_to_data (key_file, &len, NULL);
- if (data) {
- ret = g_file_set_contents (filename, data, len, error);
- g_free (data);
- }
- g_key_file_free (key_file);
-
- return ret;
-}
-
static gboolean
radio_enabled_for_rstate (RadioState *rstate, gboolean check_changeable)
{
@@ -1944,7 +1902,7 @@ add_device (NMManager *self, NMDevice *device, GError **error)
type_desc = nm_device_get_type_desc (device);
g_assert (type_desc);
- nm_device_set_unmanaged_by_user_config (device, nm_settings_get_unmanaged_specs (priv->settings));
+ nm_device_set_unmanaged_by_user_settings (device, nm_settings_get_unmanaged_specs (priv->settings));
nm_device_set_unmanaged_flags (device,
NM_UNMANAGED_SLEEPING,
@@ -1999,11 +1957,12 @@ factory_component_added_cb (NMDeviceFactory *factory,
GObject *component,
gpointer user_data)
{
+ NMManager *self = user_data;
GSList *iter;
- g_return_val_if_fail (NM_IS_MANAGER (user_data), FALSE);
+ g_return_val_if_fail (self, FALSE);
- for (iter = NM_MANAGER_GET_PRIVATE (user_data)->devices; iter; iter = iter->next) {
+ for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) {
if (nm_device_notify_component_added ((NMDevice *) iter->data, component))
return TRUE;
}
@@ -2079,6 +2038,9 @@ platform_link_added (NMManager *self,
if (!ignore) {
_LOGW (LOGD_HW, "%s: factory failed to create device: %s",
plink->name, error->message);
+ } else {
+ _LOGD (LOGD_HW, "%s: factory failed to create device: %s",
+ plink->name, error->message);
}
return;
}
@@ -2641,7 +2603,7 @@ find_slaves (NMManager *manager,
* even if a slave was already active, it might be deactivated during
* master reactivation.
*/
- all_connections = nm_settings_get_connections (priv->settings);
+ all_connections = nm_settings_get_connections_sorted (priv->settings);
for (iter = all_connections; iter; iter = iter->next) {
NMSettingsConnection *master_connection = NULL;
NMDevice *master_device = NULL;
@@ -3375,7 +3337,7 @@ _activation_auth_done (NMActiveConnection *active,
g_dbus_method_invocation_return_value (context,
g_variant_new ("(o)",
nm_exported_object_get_path (NM_EXPORTED_OBJECT (active))));
- nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, TRUE,
+ nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, TRUE, NULL,
subject, NULL);
g_object_unref (active);
return;
@@ -3387,7 +3349,7 @@ _activation_auth_done (NMActiveConnection *active,
}
g_assert (error);
- nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE,
+ nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE, NULL,
subject, error->message);
_internal_activation_failed (self, active, error->message);
@@ -3475,7 +3437,7 @@ impl_manager_activate_connection (NMManager *self,
error:
if (connection) {
- nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE,
+ nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE, NULL,
subject, error->message);
}
g_clear_object (&active);
@@ -3524,6 +3486,7 @@ activation_add_done (NMSettings *settings,
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
nm_active_connection_get_settings_connection (active),
TRUE,
+ NULL,
nm_active_connection_get_subject (active),
NULL);
return;
@@ -3538,6 +3501,7 @@ activation_add_done (NMSettings *settings,
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
NULL,
FALSE,
+ NULL,
nm_active_connection_get_subject (active),
error->message);
g_clear_error (&local);
@@ -3582,6 +3546,7 @@ _add_and_activate_auth_done (NMActiveConnection *active,
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
NULL,
FALSE,
+ NULL,
nm_active_connection_get_subject (active),
error->message);
g_dbus_method_invocation_take_error (context, error);
@@ -3633,7 +3598,7 @@ impl_manager_add_and_activate_connection (NMManager *self,
if (!subject)
goto error;
- all_connections = nm_settings_get_connections (priv->settings);
+ all_connections = nm_settings_get_connections_sorted (priv->settings);
if (vpn) {
/* Try to fill the VPN's connection setting and name at least */
if (!nm_connection_get_setting_vpn (connection)) {
@@ -3683,7 +3648,7 @@ impl_manager_add_and_activate_connection (NMManager *self,
return;
error:
- nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE, NULL, FALSE, subject, error->message);
+ nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE, NULL, FALSE, NULL, subject, error->message);
g_clear_object (&connection);
g_slist_free (all_connections);
g_clear_object (&subject);
@@ -3779,6 +3744,7 @@ deactivate_net_auth_done_cb (NMAuthChain *chain,
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE,
nm_active_connection_get_settings_connection (active),
!error,
+ NULL,
nm_auth_chain_get_subject (chain),
error ? error->message : NULL);
}
@@ -3852,7 +3818,7 @@ impl_manager_deactivate_connection (NMManager *self,
done:
if (error) {
if (connection) {
- nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, connection, FALSE,
+ nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, connection, FALSE, NULL,
subject, error->message);
}
g_dbus_method_invocation_take_error (context, error);
@@ -4192,21 +4158,9 @@ static void
_internal_enable (NMManager *self, gboolean enable)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- GError *error = NULL;
- /* Update "NetworkingEnabled" key in state file */
- if (priv->state_file) {
- if (!write_value_to_state_file (priv->state_file,
- "main", "NetworkingEnabled",
- G_TYPE_BOOLEAN, (gpointer) &enable,
- &error)) {
- /* Not a hard error */
- _LOGW (LOGD_SUSPEND, "writing to state file %s failed: %s",
- priv->state_file,
- error->message);
- g_clear_error (&error);
- }
- }
+ nm_config_state_set (priv->config, TRUE, FALSE,
+ NM_CONFIG_STATE_PROPERTY_NETWORKING_ENABLED, enable);
_LOGI (LOGD_SUSPEND, "%s requested (sleeping: %s enabled: %s)",
enable ? "enable" : "disable",
@@ -4592,7 +4546,7 @@ nm_manager_start (NMManager *self, GError **error)
* connection-added signals thus devices have to be created manually.
*/
_LOGD (LOGD_CORE, "creating virtual devices...");
- connections = nm_settings_get_connections (priv->settings);
+ connections = nm_settings_get_connections_sorted (priv->settings);
for (iter = connections; iter; iter = iter->next)
connection_changed (self, NM_CONNECTION (iter->data));
g_slist_free (connections);
@@ -5144,7 +5098,6 @@ manager_radio_user_toggled (NMManager *self,
gboolean enabled)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- GError *error = NULL;
gboolean old_enabled, new_enabled;
/* Don't touch devices if asleep/networking disabled */
@@ -5158,17 +5111,8 @@ manager_radio_user_toggled (NMManager *self,
}
/* Update enabled key in state file */
- if (priv->state_file) {
- if (!write_value_to_state_file (priv->state_file,
- "main", rstate->key,
- G_TYPE_BOOLEAN, (gpointer) &enabled,
- &error)) {
- _LOGW (LOGD_CORE, "writing to state file %s failed: %s",
- priv->state_file,
- error->message);
- g_clear_error (&error);
- }
- }
+ nm_config_state_set (priv->config, TRUE, FALSE,
+ rstate->key, enabled);
/* When the user toggles the radio, their request should override any
* daemon (like ModemManager) enabled state that can be changed. For WWAN
@@ -5230,34 +5174,22 @@ nm_manager_get (void)
return singleton_instance;
}
-NMConnectionProvider *
-nm_connection_provider_get (void)
+NMSettings *
+nm_settings_get (void)
{
- NMConnectionProvider *p;
-
g_return_val_if_fail (singleton_instance, NULL);
- p = NM_CONNECTION_PROVIDER (NM_MANAGER_GET_PRIVATE (singleton_instance)->settings);
- g_return_val_if_fail (p, NULL);
- return p;
+ return NM_MANAGER_GET_PRIVATE (singleton_instance)->settings;
}
NMManager *
-nm_manager_setup (const char *state_file,
- gboolean initial_net_enabled,
- gboolean initial_wifi_enabled,
- gboolean initial_wwan_enabled)
+nm_manager_setup (void)
{
NMManager *self;
g_return_val_if_fail (!singleton_instance, singleton_instance);
- self = g_object_new (NM_TYPE_MANAGER,
- NM_MANAGER_NETWORKING_ENABLED, initial_net_enabled,
- NM_MANAGER_WIRELESS_ENABLED, initial_wifi_enabled,
- NM_MANAGER_WWAN_ENABLED, initial_wwan_enabled,
- NM_MANAGER_STATE_FILE, state_file,
- NULL);
+ self = g_object_new (NM_TYPE_MANAGER, NULL);
nm_assert (NM_IS_MANAGER (self));
singleton_instance = self;
@@ -5275,6 +5207,7 @@ constructed (GObject *object)
NMManager *self = NM_MANAGER (object);
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
NMConfigData *config_data;
+ const NMConfigState *state;
G_OBJECT_CLASS (nm_manager_parent_class)->constructed (object);
@@ -5320,6 +5253,13 @@ constructed (GObject *object)
g_signal_connect (priv->connectivity, "notify::" NM_CONNECTIVITY_STATE,
G_CALLBACK (connectivity_changed), self);
+ state = nm_config_state_get (priv->config);
+
+ priv->net_enabled = state->net_enabled;
+
+ priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = state->wifi_enabled;
+ priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = state->wwan_enabled;
+
priv->rfkill_mgr = nm_rfkill_manager_new ();
g_signal_connect (priv->rfkill_mgr,
"rfkill-changed",
@@ -5346,14 +5286,14 @@ nm_manager_init (NMManager *self)
memset (priv->radio_states, 0, sizeof (priv->radio_states));
priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = TRUE;
- priv->radio_states[RFKILL_TYPE_WLAN].key = "WirelessEnabled";
+ priv->radio_states[RFKILL_TYPE_WLAN].key = NM_CONFIG_STATE_PROPERTY_WIFI_ENABLED;
priv->radio_states[RFKILL_TYPE_WLAN].prop = NM_MANAGER_WIRELESS_ENABLED;
priv->radio_states[RFKILL_TYPE_WLAN].hw_prop = NM_MANAGER_WIRELESS_HARDWARE_ENABLED;
priv->radio_states[RFKILL_TYPE_WLAN].desc = "WiFi";
priv->radio_states[RFKILL_TYPE_WLAN].rtype = RFKILL_TYPE_WLAN;
priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = TRUE;
- priv->radio_states[RFKILL_TYPE_WWAN].key = "WWANEnabled";
+ priv->radio_states[RFKILL_TYPE_WWAN].key = NM_CONFIG_STATE_PROPERTY_WWAN_ENABLED;
priv->radio_states[RFKILL_TYPE_WWAN].prop = NM_MANAGER_WWAN_ENABLED;
priv->radio_states[RFKILL_TYPE_WWAN].hw_prop = NM_MANAGER_WWAN_HARDWARE_ENABLED;
priv->radio_states[RFKILL_TYPE_WWAN].desc = "WWAN";
@@ -5516,33 +5456,15 @@ set_property (GObject *object, guint prop_id,
GError *error = NULL;
switch (prop_id) {
- case PROP_STATE_FILE:
- /* construct-only */
- priv->state_file = g_value_dup_string (value);
- break;
- case PROP_NETWORKING_ENABLED:
- /* construct-only */
- priv->net_enabled = g_value_get_boolean (value);
- break;
case PROP_WIRELESS_ENABLED:
- if (!priv->rfkill_mgr) {
- /* called during object construction. */
- priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = g_value_get_boolean (value);
- } else {
- manager_radio_user_toggled (NM_MANAGER (object),
- &priv->radio_states[RFKILL_TYPE_WLAN],
- g_value_get_boolean (value));
- }
+ manager_radio_user_toggled (NM_MANAGER (object),
+ &priv->radio_states[RFKILL_TYPE_WLAN],
+ g_value_get_boolean (value));
break;
case PROP_WWAN_ENABLED:
- if (!priv->rfkill_mgr) {
- /* called during object construction. */
- priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = g_value_get_boolean (value);
- } else {
- manager_radio_user_toggled (NM_MANAGER (object),
- &priv->radio_states[RFKILL_TYPE_WWAN],
- g_value_get_boolean (value));
- }
+ manager_radio_user_toggled (NM_MANAGER (object),
+ &priv->radio_states[RFKILL_TYPE_WWAN],
+ g_value_get_boolean (value));
break;
case PROP_WIMAX_ENABLED:
/* WIMAX is depreacted. This does nothing. */
@@ -5620,7 +5542,6 @@ dispose (GObject *object)
g_clear_object (&priv->settings);
}
- g_clear_pointer (&priv->state_file, g_free);
g_clear_object (&priv->vpn_manager);
/* Unregister property filter */
@@ -5665,8 +5586,6 @@ nm_manager_class_init (NMManagerClass *manager_class)
GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (manager_class);
- g_type_class_add_private (manager_class, sizeof (NMManagerPrivate));
-
exported_object_class->export_path = NM_DBUS_PATH;
/* virtual methods */
@@ -5682,13 +5601,6 @@ nm_manager_class_init (NMManagerClass *manager_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_STATE_FILE] =
- g_param_spec_string (NM_MANAGER_STATE_FILE, "", "",
- NULL,
- G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
-
obj_properties[PROP_STATE] =
g_param_spec_uint (NM_MANAGER_STATE, "", "",
0, NM_STATE_DISCONNECTED, 0,
@@ -5704,14 +5616,13 @@ nm_manager_class_init (NMManagerClass *manager_class)
obj_properties[PROP_NETWORKING_ENABLED] =
g_param_spec_boolean (NM_MANAGER_NETWORKING_ENABLED, "", "",
TRUE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_WIRELESS_ENABLED] =
g_param_spec_boolean (NM_MANAGER_WIRELESS_ENABLED, "", "",
TRUE,
G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_WIRELESS_HARDWARE_ENABLED] =
@@ -5724,7 +5635,6 @@ nm_manager_class_init (NMManagerClass *manager_class)
g_param_spec_boolean (NM_MANAGER_WWAN_ENABLED, "", "",
TRUE,
G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_WWAN_HARDWARE_ENABLED] =
@@ -5844,8 +5754,7 @@ nm_manager_class_init (NMManagerClass *manager_class)
g_signal_new (NM_MANAGER_DEVICE_ADDED,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMManagerClass, device_added),
- NULL, NULL, NULL,
+ 0, NULL, NULL, NULL,
G_TYPE_NONE, 1, NM_TYPE_DEVICE);
/* Emitted for both realized devices and placeholder devices */
@@ -5861,8 +5770,7 @@ nm_manager_class_init (NMManagerClass *manager_class)
g_signal_new (NM_MANAGER_DEVICE_REMOVED,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMManagerClass, device_removed),
- NULL, NULL, NULL,
+ 0, NULL, NULL, NULL,
G_TYPE_NONE, 1, NM_TYPE_DEVICE);
/* Emitted for both realized devices and placeholder devices */
@@ -5877,8 +5785,7 @@ nm_manager_class_init (NMManagerClass *manager_class)
g_signal_new (NM_MANAGER_STATE_CHANGED,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMManagerClass, state_changed),
- NULL, NULL, NULL,
+ 0, NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_UINT);
signals[CHECK_PERMISSIONS] =
diff --git a/src/nm-manager.h b/src/nm-manager.h
index 5401b002c1..d436f0516b 100644
--- a/src/nm-manager.h
+++ b/src/nm-manager.h
@@ -55,7 +55,6 @@
/* Not exported */
#define NM_MANAGER_HOSTNAME "hostname"
#define NM_MANAGER_SLEEPING "sleeping"
-#define NM_MANAGER_STATE_FILE "state-file"
/* signals */
#define NM_MANAGER_CHECK_PERMISSIONS "check-permissions"
@@ -72,26 +71,10 @@
#define NM_MANAGER_INTERNAL_DEVICE_REMOVED "internal-device-removed"
-struct _NMManager {
- NMExportedObject parent;
-};
-
-typedef struct {
- NMExportedObjectClass parent;
-
- /* Signals */
- void (*device_added) (NMManager *manager, NMDevice *device);
- void (*device_removed) (NMManager *manager, NMDevice *device);
- void (*state_changed) (NMManager *manager, guint state);
-} NMManagerClass;
-
GType nm_manager_get_type (void);
/* nm_manager_setup() should only be used by main.c */
-NMManager * nm_manager_setup (const char *state_file,
- gboolean initial_net_enabled,
- gboolean initial_wifi_enabled,
- gboolean initial_wwan_enabled);
+NMManager * nm_manager_setup (void);
NMManager * nm_manager_get (void);
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 9695ad605c..0c63b1cba6 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -862,7 +862,7 @@ reset_autoconnect_all (NMPolicy *self, NMDevice *device)
} else
_LOGD (LOGD_DEVICE, "re-enabling autoconnect for all connections");
- connections = nm_settings_get_connections (priv->settings);
+ connections = nm_settings_get_connections_sorted (priv->settings);
for (iter = connections; iter; iter = g_slist_next (iter)) {
if (!device || nm_device_check_connection_compatible (device, iter->data)) {
nm_settings_connection_reset_autoconnect_retries (iter->data);
@@ -880,7 +880,7 @@ reset_autoconnect_for_failed_secrets (NMPolicy *self)
_LOGD (LOGD_DEVICE, "re-enabling autoconnect for all connections with failed secrets");
- connections = nm_settings_get_connections (priv->settings);
+ connections = nm_settings_get_connections_sorted (priv->settings);
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMSettingsConnection *connection = NM_SETTINGS_CONNECTION (iter->data);
@@ -908,7 +908,7 @@ block_autoconnect_for_device (NMPolicy *self, NMDevice *device)
if (!nm_device_is_software (device))
return;
- connections = nm_settings_get_connections (priv->settings);
+ connections = nm_settings_get_connections_sorted (priv->settings);
for (iter = connections; iter; iter = g_slist_next (iter)) {
if (nm_device_check_connection_compatible (device, iter->data)) {
nm_settings_connection_set_autoconnect_blocked_reason (NM_SETTINGS_CONNECTION (iter->data),
@@ -991,7 +991,7 @@ reset_connections_retries (gpointer user_data)
min_stamp = 0;
now = nm_utils_get_monotonic_timestamp_s ();
- connections = nm_settings_get_connections (priv->settings);
+ connections = nm_settings_get_connections_sorted (priv->settings);
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMSettingsConnection *connection = NM_SETTINGS_CONNECTION (iter->data);
@@ -1044,7 +1044,7 @@ activate_slave_connections (NMPolicy *self, NMDevice *device)
}
}
- connections = nm_settings_get_connections (priv->settings);
+ connections = nm_settings_get_connections_sorted (priv->settings);
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMConnection *slave;
NMSettingConnection *s_slave_con;
@@ -1442,7 +1442,7 @@ vpn_connection_activated (NMPolicy *self, NMVpnConnection *vpn)
nm_dns_manager_begin_updates (priv->dns_manager, __func__);
- ip_iface = nm_vpn_connection_get_ip_iface (vpn);
+ ip_iface = nm_vpn_connection_get_ip_iface (vpn, TRUE);
/* Add the VPN connection's IP configs from DNS */
diff --git a/src/nm-route-manager.c b/src/nm-route-manager.c
index 05e28c7426..2d4c7d9595 100644
--- a/src/nm-route-manager.c
+++ b/src/nm-route-manager.c
@@ -873,7 +873,7 @@ next:
|| !_route_equals_ignoring_ifindex (vtable, cur_plat_route, cur_ipx_route, *p_effective_metric)) {
if (!vtable->vt->route_add (priv->platform, ifindex, cur_ipx_route, *p_effective_metric)) {
- if (cur_ipx_route->rx.source < NM_IP_CONFIG_SOURCE_USER) {
+ if (cur_ipx_route->rx.rt_source < NM_IP_CONFIG_SOURCE_USER) {
_LOGD (vtable->vt->addr_family,
"ignore error adding IPv%c route to kernel: %s",
vtable->vt->is_ip4 ? '4' : '6',
@@ -1024,7 +1024,7 @@ _ip4_device_routes_ip4_route_changed (NMPlatform *platform,
if (change_type == NM_PLATFORM_SIGNAL_REMOVED)
return;
- if ( route->source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL
+ if ( route->rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL
|| route->metric != 0) {
/* we don't have an automatically created device route at hand. Bail out early. */
return;
diff --git a/src/nm-session-monitor.c b/src/nm-session-monitor.c
index 467094270b..279a888672 100644
--- a/src/nm-session-monitor.c
+++ b/src/nm-session-monitor.c
@@ -279,45 +279,6 @@ ck_finalize (NMSessionMonitor *monitor)
NM_DEFINE_SINGLETON_GETTER (NMSessionMonitor, nm_session_monitor_get, NM_TYPE_SESSION_MONITOR);
/**
- * nm_session_monitor_connect:
- * @self: the session monitor
- * @callback: The callback.
- * @user_data: User data for the callback.
- *
- * Connect a callback to the session monitor.
- *
- * Returns: Handler ID to be used with nm_session_monitor_disconnect().
- */
-gulong
-nm_session_monitor_connect (NMSessionMonitor *self,
- NMSessionCallback callback,
- gpointer user_data)
-{
- g_return_val_if_fail (NM_IS_SESSION_MONITOR (self), 0);
-
- return g_signal_connect (self,
- NM_SESSION_MONITOR_CHANGED,
- G_CALLBACK (callback),
- user_data);
-}
-
-/**
- * nm_session_monitor_disconnect:
- * @self: the session monitor
- * @handler_id: Handler ID returned by nm_session_monitor-connect().
- *
- * Disconnect callback from the session handler.
- */
-void
-nm_session_monitor_disconnect (NMSessionMonitor *self,
- gulong handler_id)
-{
- g_return_if_fail (NM_IS_SESSION_MONITOR (self));
-
- g_signal_handler_disconnect (self, handler_id);
-}
-
-/**
* nm_session_monitor_uid_to_user:
* @uid: UID.
* @out_user: Return location for user name.
diff --git a/src/nm-session-monitor.h b/src/nm-session-monitor.h
index af50b71ba3..e776ef25ab 100644
--- a/src/nm-session-monitor.h
+++ b/src/nm-session-monitor.h
@@ -43,12 +43,6 @@ GType nm_session_monitor_get_type (void) G_GNUC_CONST;
NMSessionMonitor *nm_session_monitor_get (void);
-gulong nm_session_monitor_connect (NMSessionMonitor *self,
- NMSessionCallback callback,
- gpointer user_data);
-void nm_session_monitor_disconnect (NMSessionMonitor *self,
- gulong handler_id);
-
gboolean nm_session_monitor_uid_to_user (uid_t uid, const char **out_user);
gboolean nm_session_monitor_user_to_uid (const char *user, uid_t *out_uid);
gboolean nm_session_monitor_session_exists (NMSessionMonitor *self,
diff --git a/src/nm-test-utils-core.h b/src/nm-test-utils-core.h
new file mode 100644
index 0000000000..8fd3be55ae
--- /dev/null
+++ b/src/nm-test-utils-core.h
@@ -0,0 +1,296 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2014 - 2016 Red Hat, Inc.
+ */
+
+#ifndef __NM_TEST_UTILS_CORE_H__
+#define __NM_TEST_UTILS_CORE_H__
+
+#include "NetworkManagerUtils.h"
+#include "nm-keyfile-internal.h"
+
+#define _NMTST_INSIDE_CORE 1
+
+#include "nm-test-utils.h"
+
+/*****************************************************************************/
+
+inline static void
+nmtst_init_with_logging (int *argc, char ***argv, const char *log_level, const char *log_domains)
+{
+ __nmtst_init (argc, argv, FALSE, log_level, log_domains, NULL);
+}
+inline static void
+nmtst_init_assert_logging (int *argc, char ***argv, const char *log_level, const char *log_domains)
+{
+ gboolean set_logging;
+
+ __nmtst_init (argc, argv, TRUE, NULL, NULL, &set_logging);
+
+ if (!set_logging) {
+ gboolean success;
+
+ success = nm_logging_setup (log_level, log_domains, NULL, NULL);
+ g_assert (success);
+ }
+}
+
+/*****************************************************************************/
+
+#ifdef __NETWORKMANAGER_PLATFORM_H__
+
+inline static NMPlatformIP4Address *
+nmtst_platform_ip4_address (const char *address, const char *peer_address, guint plen)
+{
+ static NMPlatformIP4Address addr;
+
+ g_assert (plen <= 32);
+
+ memset (&addr, 0, sizeof (addr));
+ addr.address = nmtst_inet4_from_string (address);
+ if (peer_address)
+ addr.peer_address = nmtst_inet4_from_string (peer_address);
+ else
+ addr.peer_address = addr.address;
+ addr.plen = plen;
+
+ return &addr;
+}
+
+inline static NMPlatformIP4Address *
+nmtst_platform_ip4_address_full (const char *address, const char *peer_address, guint plen,
+ int ifindex, NMIPConfigSource source, guint32 timestamp,
+ guint32 lifetime, guint32 preferred, guint32 flags,
+ const char *label)
+{
+ NMPlatformIP4Address *addr = nmtst_platform_ip4_address (address, peer_address, plen);
+
+ G_STATIC_ASSERT (IFNAMSIZ == sizeof (addr->label));
+ g_assert (!label || strlen (label) < IFNAMSIZ);
+
+ addr->ifindex = ifindex;
+ addr->addr_source = source;
+ addr->timestamp = timestamp;
+ addr->lifetime = lifetime;
+ addr->preferred = preferred;
+ addr->n_ifa_flags = flags;
+ if (label)
+ g_strlcpy (addr->label, label, sizeof (addr->label));
+
+ return addr;
+}
+
+inline static NMPlatformIP6Address *
+nmtst_platform_ip6_address (const char *address, const char *peer_address, guint plen)
+{
+ static NMPlatformIP6Address addr;
+
+ g_assert (plen <= 128);
+
+ memset (&addr, 0, sizeof (addr));
+ addr.address = *nmtst_inet6_from_string (address);
+ addr.peer_address = *nmtst_inet6_from_string (peer_address);
+ addr.plen = plen;
+
+ return &addr;
+}
+
+inline static NMPlatformIP6Address *
+nmtst_platform_ip6_address_full (const char *address, const char *peer_address, guint plen,
+ int ifindex, NMIPConfigSource source, guint32 timestamp,
+ guint32 lifetime, guint32 preferred, guint32 flags)
+{
+ NMPlatformIP6Address *addr = nmtst_platform_ip6_address (address, peer_address, plen);
+
+ addr->ifindex = ifindex;
+ addr->addr_source = source;
+ addr->timestamp = timestamp;
+ addr->lifetime = lifetime;
+ addr->preferred = preferred;
+ addr->n_ifa_flags = flags;
+
+ return addr;
+}
+
+inline static NMPlatformIP4Route *
+nmtst_platform_ip4_route (const char *network, guint plen, const char *gateway)
+{
+ static NMPlatformIP4Route route;
+
+ g_assert (plen <= 32);
+
+ memset (&route, 0, sizeof (route));
+ route.network = nmtst_inet4_from_string (network);
+ route.plen = plen;
+ route.gateway = nmtst_inet4_from_string (gateway);
+
+ return &route;
+}
+
+inline static NMPlatformIP4Route *
+nmtst_platform_ip4_route_full (const char *network, guint plen, const char *gateway,
+ int ifindex, NMIPConfigSource source,
+ guint metric, guint mss,
+ guint8 scope,
+ const char *pref_src)
+{
+ NMPlatformIP4Route *route = nmtst_platform_ip4_route (network, plen, gateway);
+
+ route->ifindex = ifindex;
+ route->rt_source = source;
+ route->metric = metric;
+ route->mss = mss;
+ route->scope_inv = nm_platform_route_scope_inv (scope);
+ route->pref_src = nmtst_inet4_from_string (pref_src);
+
+ return route;
+}
+
+inline static NMPlatformIP6Route *
+nmtst_platform_ip6_route (const char *network, guint plen, const char *gateway)
+{
+ static NMPlatformIP6Route route;
+
+ nm_assert (plen <= 128);
+
+ memset (&route, 0, sizeof (route));
+ route.network = *nmtst_inet6_from_string (network);
+ route.plen = plen;
+ route.gateway = *nmtst_inet6_from_string (gateway);
+
+ return &route;
+}
+
+inline static NMPlatformIP6Route *
+nmtst_platform_ip6_route_full (const char *network, guint plen, const char *gateway,
+ int ifindex, NMIPConfigSource source,
+ guint metric, guint mss)
+{
+ NMPlatformIP6Route *route = nmtst_platform_ip6_route (network, plen, gateway);
+
+ route->ifindex = ifindex;
+ route->rt_source = source;
+ route->metric = metric;
+ route->mss = mss;
+
+ return route;
+}
+
+inline static int
+_nmtst_platform_ip4_routes_equal_sort (gconstpointer a, gconstpointer b, gpointer user_data)
+{
+ return nm_platform_ip4_route_cmp ((const NMPlatformIP4Route *) a, (const NMPlatformIP4Route *) b);
+}
+
+inline static void
+nmtst_platform_ip4_routes_equal (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b, gsize len, gboolean ignore_order)
+{
+ gsize i;
+ gs_free const NMPlatformIP4Route *c_a = NULL, *c_b = NULL;
+
+ g_assert (a);
+ g_assert (b);
+
+ if (ignore_order) {
+ a = c_a = g_memdup (a, sizeof (NMPlatformIP4Route) * len);
+ b = c_b = g_memdup (b, sizeof (NMPlatformIP4Route) * len);
+ g_qsort_with_data (c_a, len, sizeof (NMPlatformIP4Route), _nmtst_platform_ip4_routes_equal_sort, NULL);
+ g_qsort_with_data (c_b, len, sizeof (NMPlatformIP4Route), _nmtst_platform_ip4_routes_equal_sort, NULL);
+ }
+
+ for (i = 0; i < len; i++) {
+ if (nm_platform_ip4_route_cmp (&a[i], &b[i]) != 0) {
+ char buf[sizeof (_nm_utils_to_string_buffer)];
+
+ g_error ("Error comparing IPv4 route[%lu]: %s vs %s", (long unsigned) i,
+ nm_platform_ip4_route_to_string (&a[i], NULL, 0),
+ nm_platform_ip4_route_to_string (&b[i], buf, sizeof (buf)));
+ g_assert_not_reached ();
+ }
+ }
+}
+
+inline static int
+_nmtst_platform_ip6_routes_equal_sort (gconstpointer a, gconstpointer b, gpointer user_data)
+{
+ return nm_platform_ip6_route_cmp ((const NMPlatformIP6Route *) a, (const NMPlatformIP6Route *) b);
+}
+
+inline static void
+nmtst_platform_ip6_routes_equal (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b, gsize len, gboolean ignore_order)
+{
+ gsize i;
+ gs_free const NMPlatformIP6Route *c_a = NULL, *c_b = NULL;
+
+ g_assert (a);
+ g_assert (b);
+
+ if (ignore_order) {
+ a = c_a = g_memdup (a, sizeof (NMPlatformIP6Route) * len);
+ b = c_b = g_memdup (b, sizeof (NMPlatformIP6Route) * len);
+ g_qsort_with_data (c_a, len, sizeof (NMPlatformIP6Route), _nmtst_platform_ip6_routes_equal_sort, NULL);
+ g_qsort_with_data (c_b, len, sizeof (NMPlatformIP6Route), _nmtst_platform_ip6_routes_equal_sort, NULL);
+ }
+
+ for (i = 0; i < len; i++) {
+ if (nm_platform_ip6_route_cmp (&a[i], &b[i]) != 0) {
+ char buf[sizeof (_nm_utils_to_string_buffer)];
+
+ g_error ("Error comparing IPv6 route[%lu]: %s vs %s", (long unsigned) i,
+ nm_platform_ip6_route_to_string (&a[i], NULL, 0),
+ nm_platform_ip6_route_to_string (&b[i], buf, sizeof (buf)));
+ g_assert_not_reached ();
+ }
+ }
+}
+
+#endif
+
+
+#ifdef __NETWORKMANAGER_IP4_CONFIG_H__
+
+inline static NMIP4Config *
+nmtst_ip4_config_clone (NMIP4Config *config)
+{
+ NMIP4Config *copy = nm_ip4_config_new (-1);
+
+ g_assert (copy);
+ g_assert (config);
+ nm_ip4_config_replace (copy, config, NULL);
+ return copy;
+}
+
+#endif
+
+
+#ifdef __NETWORKMANAGER_IP6_CONFIG_H__
+
+inline static NMIP6Config *
+nmtst_ip6_config_clone (NMIP6Config *config)
+{
+ NMIP6Config *copy = nm_ip6_config_new (-1);
+
+ g_assert (copy);
+ g_assert (config);
+ nm_ip6_config_replace (copy, config, NULL);
+ return copy;
+}
+
+#endif
+
+#endif /* __NM_TEST_UTILS_CORE_H__ */
diff --git a/src/nm-types.h b/src/nm-types.h
index 997723e607..fa70372c43 100644
--- a/src/nm-types.h
+++ b/src/nm-types.h
@@ -54,13 +54,20 @@ typedef struct _NMLldpListener NMLldpListener;
typedef enum {
/* In priority order; higher number == higher priority */
- NM_IP_CONFIG_SOURCE_UNKNOWN,
- /* platform internal flag used to mark routes with RTM_F_CLONED. */
- _NM_IP_CONFIG_SOURCE_RTM_F_CLONED,
+ NM_IP_CONFIG_SOURCE_UNKNOWN = 0,
- /* routes from platform with protocol RTPROT_KERNEL. */
- NM_IP_CONFIG_SOURCE_RTPROT_KERNEL,
+ /* for routes, the source is mapped to the uint8 field rtm_protocol.
+ * Reserve the range [1,0x100] for native RTPROT values. */
+
+ NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC = 1 + 0,
+ NM_IP_CONFIG_SOURCE_RTPROT_REDIRECT = 1 + 1,
+ NM_IP_CONFIG_SOURCE_RTPROT_KERNEL = 1 + 2,
+ NM_IP_CONFIG_SOURCE_RTPROT_BOOT = 1 + 3,
+ NM_IP_CONFIG_SOURCE_RTPROT_STATIC = 1 + 4,
+ NM_IP_CONFIG_SOURCE_RTPROT_RA = 1 + 9,
+ NM_IP_CONFIG_SOURCE_RTPROT_DHCP = 1 + 16,
+ _NM_IP_CONFIG_SOURCE_RTPROT_LAST = 1 + 0xFF,
NM_IP_CONFIG_SOURCE_KERNEL,
NM_IP_CONFIG_SOURCE_SHARED,
@@ -73,6 +80,12 @@ typedef enum {
NM_IP_CONFIG_SOURCE_USER,
} NMIPConfigSource;
+inline static gboolean
+NM_IS_IP_CONFIG_SOURCE_RTPROT (NMIPConfigSource source)
+{
+ return source > NM_IP_CONFIG_SOURCE_UNKNOWN && source <= _NM_IP_CONFIG_SOURCE_RTPROT_LAST;
+}
+
/* platform */
typedef struct _NMPlatform NMPlatform;
typedef struct _NMPlatformIP4Address NMPlatformIP4Address;
diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c
index 7b54507696..d0fb277462 100644
--- a/src/platform/nm-fake-platform.c
+++ b/src/platform/nm-fake-platform.c
@@ -31,9 +31,10 @@
#include "nm-utils.h"
#include "nm-core-utils.h"
+#include "nm-platform-utils.h"
#include "nmp-object.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
/*********************************************************************************************/
@@ -709,12 +710,13 @@ static gboolean
infiniband_partition_add (NMPlatform *platform, int parent, int p_key, const NMPlatformLink **out_link)
{
NMFakePlatformLink *device, *parent_device;
- gs_free char *name = NULL;
+ char name[IFNAMSIZ];
parent_device = link_get (platform, parent);
g_return_val_if_fail (parent_device != NULL, FALSE);
- name = g_strdup_printf ("%s.%04x", parent_device->link.name, p_key);
+ nm_utils_new_infiniband_name (name, parent_device->link.name, p_key);
+
if (!link_add (platform, name, NM_LINK_TYPE_INFINIBAND, NULL, 0, out_link))
return FALSE;
@@ -726,7 +728,6 @@ infiniband_partition_add (NMPlatform *platform, int parent, int p_key, const NMP
device->lnk->lnk_infiniband.p_key = p_key;
device->lnk->lnk_infiniband.mode = "datagram";
device->link.parent = parent;
-
return TRUE;
}
@@ -739,7 +740,7 @@ infiniband_partition_delete (NMPlatform *platform, int parent, int p_key)
parent_device = link_get (platform, parent);
g_return_val_if_fail (parent_device != NULL, FALSE);
- name = g_strdup_printf ("%s.%04x", parent_device->link.name, p_key);
+ nm_utils_new_infiniband_name (name, parent_device->link.name, p_key);
return link_delete (platform, nm_platform_link_get_ifindex (platform, name));
}
@@ -911,7 +912,7 @@ ip4_address_add (NMPlatform *platform,
int i;
memset (&address, 0, sizeof (address));
- address.source = NM_IP_CONFIG_SOURCE_KERNEL;
+ address.addr_source = NM_IP_CONFIG_SOURCE_KERNEL;
address.ifindex = ifindex;
address.address = addr;
address.peer_address = peer_addr;
@@ -962,7 +963,7 @@ ip6_address_add (NMPlatform *platform,
int i;
memset (&address, 0, sizeof (address));
- address.source = NM_IP_CONFIG_SOURCE_KERNEL;
+ address.addr_source = NM_IP_CONFIG_SOURCE_KERNEL;
address.ifindex = ifindex;
address.address = addr;
address.peer_address = (IN6_IS_ADDR_UNSPECIFIED (&peer_addr) || IN6_ARE_ADDR_EQUAL (&addr, &peer_addr)) ? in6addr_any : peer_addr;
@@ -1207,9 +1208,8 @@ ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source,
scope = gateway == 0 ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE;
memset (&route, 0, sizeof (route));
- route.source = NM_IP_CONFIG_SOURCE_KERNEL;
route.ifindex = ifindex;
- route.source = source;
+ route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (source);
route.network = nm_utils_ip4_address_clear_host_address (network, plen);
route.plen = plen;
route.gateway = gateway;
@@ -1273,9 +1273,8 @@ ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source,
metric = nm_utils_ip6_route_metric_normalize (metric);
memset (&route, 0, sizeof (route));
- route.source = NM_IP_CONFIG_SOURCE_KERNEL;
route.ifindex = ifindex;
- route.source = source;
+ route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (source);
nm_utils_ip6_address_clear_host_address (&route.network, &network, plen);
route.plen = plen;
route.gateway = gateway;
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 3eb7ff3f8d..4e41bc9b27 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -176,6 +176,11 @@
* Forward declarations and enums
******************************************************************/
+typedef enum {
+ INFINIBAND_ACTION_CREATE_CHILD,
+ INFINIBAND_ACTION_DELETE_CHILD,
+} InfinibandAction;
+
enum {
DELAYED_ACTION_IDX_REFRESH_ALL_LINKS,
DELAYED_ACTION_IDX_REFRESH_ALL_IP4_ADDRESSES,
@@ -303,23 +308,6 @@ _support_user_ipv6ll_detect (struct nlattr **tb)
* Various utilities
******************************************************************/
-static void
-clear_host_address (int family, const void *network, guint8 plen, void *dst)
-{
- g_return_if_fail (network);
-
- switch (family) {
- case AF_INET:
- *((in_addr_t *) dst) = nm_utils_ip4_address_clear_host_address (*((in_addr_t *) network), plen);
- break;
- case AF_INET6:
- nm_utils_ip6_address_clear_host_address ((struct in6_addr *) dst, (const struct in6_addr *) network, plen);
- break;
- default:
- g_assert_not_reached ();
- }
-}
-
static int
_vlan_qos_mapping_cmp_from (gconstpointer a, gconstpointer b, gpointer user_data)
{
@@ -588,12 +576,17 @@ _lookup_cached_link (const NMPCache *cache, int ifindex, gboolean *completed_fro
#define DEVTYPE_PREFIX "DEVTYPE="
static char *
-_linktype_read_devtype (const char *sysfs_path)
+_linktype_read_devtype (const char *ifname)
{
- gs_free char *uevent = g_strdup_printf ("%s/uevent", sysfs_path);
+ char uevent[NM_STRLEN ("/sys/class/net/123456789012345/uevent\0") + 100 /*safety*/];
char *contents = NULL;
char *cont, *end;
+ nm_sprintf_buf (uevent,
+ "/sys/class/net/%s/uevent",
+ NM_ASSERT_VALID_PATH_COMPONENT (ifname));
+ nm_assert (strlen (uevent) < sizeof (uevent) - 1);
+
if (!g_file_get_contents (uevent, &contents, NULL, NULL))
return NULL;
for (cont = contents; cont; cont = end) {
@@ -690,9 +683,8 @@ _linktype_get_type (NMPlatform *platform,
return NM_LINK_TYPE_IP6TNL;
if (ifname) {
+ char anycast_mask[NM_STRLEN ("/sys/class/net/123456789012345/anycast_mask\0") + 100 /*safety*/];
gs_free char *driver = NULL;
- gs_free char *sysfs_path = NULL;
- gs_free char *anycast_mask = NULL;
gs_free char *devtype = NULL;
/* Fallback OVS detection for kernel <= 3.16 */
@@ -709,12 +701,15 @@ _linktype_get_type (NMPlatform *platform,
}
}
- sysfs_path = g_strdup_printf ("/sys/class/net/%s", ifname);
- anycast_mask = g_strdup_printf ("%s/anycast_mask", sysfs_path);
+ nm_sprintf_buf (anycast_mask,
+ "/sys/class/net/%s/anycast_mask",
+ NM_ASSERT_VALID_PATH_COMPONENT (ifname));
+ nm_assert (strlen (anycast_mask) < sizeof (anycast_mask) - 1);
+
if (g_file_test (anycast_mask, G_FILE_TEST_EXISTS))
return NM_LINK_TYPE_OLPC_MESH;
- devtype = _linktype_read_devtype (sysfs_path);
+ devtype = _linktype_read_devtype (ifname);
for (i = 0; devtype && i < G_N_ELEMENTS (linktypes); i++) {
if (g_strcmp0 (devtype, linktypes[i].devtype) == 0) {
if (linktypes[i].nm_type == NM_LINK_TYPE_BNEP) {
@@ -729,7 +724,7 @@ _linktype_get_type (NMPlatform *platform,
}
/* Fallback for drivers that don't call SET_NETDEV_DEVTYPE() */
- if (wifi_utils_is_wifi (ifname, sysfs_path))
+ if (wifi_utils_is_wifi (ifname))
return NM_LINK_TYPE_WIFI;
if (arptype == ARPHRD_ETHER) {
@@ -803,9 +798,10 @@ _nl_nlmsg_type_to_str (guint16 type, char *buf, gsize len)
static gboolean
_parse_af_inet6 (NMPlatform *platform,
struct nlattr *attr,
- NMUtilsIPv6IfaceId *out_iid,
- guint8 *out_iid_is_valid,
- guint8 *out_addr_gen_mode_inv)
+ NMUtilsIPv6IfaceId *out_token,
+ gboolean *out_token_valid,
+ guint8 *out_addr_gen_mode_inv,
+ gboolean *out_addr_gen_mode_valid)
{
static struct nla_policy policy[IFLA_INET6_MAX+1] = {
[IFLA_INET6_FLAGS] = { .type = NLA_U32 },
@@ -819,7 +815,8 @@ _parse_af_inet6 (NMPlatform *platform,
struct nlattr *tb[IFLA_INET6_MAX+1];
int err;
struct in6_addr i6_token;
- gboolean iid_is_valid = FALSE;
+ gboolean token_valid = FALSE;
+ gboolean addr_gen_mode_valid = FALSE;
guint8 i6_addr_gen_mode_inv = 0;
gboolean success = FALSE;
@@ -836,8 +833,7 @@ _parse_af_inet6 (NMPlatform *platform,
if (_check_addr_or_errout (tb, IFLA_INET6_TOKEN, sizeof (struct in6_addr))) {
nla_memcpy (&i6_token, tb[IFLA_INET6_TOKEN], sizeof (struct in6_addr));
- if (!IN6_IS_ADDR_UNSPECIFIED (&i6_token))
- iid_is_valid = TRUE;
+ token_valid = TRUE;
}
/* Hack to detect support addrgenmode of the kernel. We only parse
@@ -852,21 +848,18 @@ _parse_af_inet6 (NMPlatform *platform,
* to signal "unset". */
goto errout;
}
+ addr_gen_mode_valid = TRUE;
}
success = TRUE;
- if (iid_is_valid) {
- out_iid->id_u8[7] = i6_token.s6_addr[15];
- out_iid->id_u8[6] = i6_token.s6_addr[14];
- out_iid->id_u8[5] = i6_token.s6_addr[13];
- out_iid->id_u8[4] = i6_token.s6_addr[12];
- out_iid->id_u8[3] = i6_token.s6_addr[11];
- out_iid->id_u8[2] = i6_token.s6_addr[10];
- out_iid->id_u8[1] = i6_token.s6_addr[9];
- out_iid->id_u8[0] = i6_token.s6_addr[8];
- *out_iid_is_valid = TRUE;
+ if (token_valid) {
+ *out_token_valid = token_valid;
+ nm_utils_ipv6_interface_identifier_get_from_addr (out_token, &i6_token);
+ }
+ if (addr_gen_mode_valid) {
+ *out_addr_gen_mode_valid = addr_gen_mode_valid;
+ *out_addr_gen_mode_inv = i6_addr_gen_mode_inv;
}
- *out_addr_gen_mode_inv = i6_addr_gen_mode_inv;
errout:
return success;
}
@@ -1441,6 +1434,8 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
NMPObject *lnk_data = NULL;
gboolean address_complete_from_cache = TRUE;
gboolean lnk_data_complete_from_cache = TRUE;
+ gboolean af_inet6_token_valid = FALSE;
+ gboolean af_inet6_addr_gen_mode_valid = FALSE;
if (!nlmsg_valid_hdr (nlh, sizeof (*ifi)))
return NULL;
@@ -1517,9 +1512,10 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
case AF_INET6:
_parse_af_inet6 (platform,
af_attr,
- &obj->link.inet6_token.iid,
- &obj->link.inet6_token.is_valid,
- &obj->link.inet6_addr_gen_mode_inv);
+ &obj->link.inet6_token,
+ &af_inet6_token_valid,
+ &obj->link.inet6_addr_gen_mode_inv,
+ &af_inet6_addr_gen_mode_valid);
break;
}
}
@@ -1561,7 +1557,9 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
if ( completed_from_cache
&& ( lnk_data_complete_from_cache
- || address_complete_from_cache)) {
+ || address_complete_from_cache
+ || !af_inet6_token_valid
+ || !af_inet6_addr_gen_mode_valid)) {
_lookup_cached_link (cache, obj->link.ifindex, completed_from_cache, &link_cached);
if (link_cached) {
if ( lnk_data_complete_from_cache
@@ -1580,6 +1578,10 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
}
if (address_complete_from_cache)
obj->link.addr = link_cached->link.addr;
+ if (!af_inet6_token_valid)
+ obj->link.inet6_token = link_cached->link.inet6_token;
+ if (!af_inet6_addr_gen_mode_valid)
+ obj->link.inet6_addr_gen_mode_inv = link_cached->link.inet6_addr_gen_mode_inv;
}
}
@@ -1666,7 +1668,7 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only)
}
}
- obj->ip_address.source = NM_IP_CONFIG_SOURCE_KERNEL;
+ obj->ip_address.addr_source = NM_IP_CONFIG_SOURCE_KERNEL;
obj->ip_address.n_ifa_flags = tb[IFA_FLAGS]
? nla_get_u32 (tb[IFA_FLAGS])
@@ -1896,9 +1898,10 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
*
* This happens, because this route is not nmp_object_is_alive().
* */
- obj->ip_route.source = _NM_IP_CONFIG_SOURCE_RTM_F_CLONED;
- } else
- obj->ip_route.source = nmp_utils_ip_config_source_from_rtprot (rtm->rtm_protocol);
+ obj->ip_route.rt_cloned = TRUE;
+ }
+
+ obj->ip_route.rt_source = nmp_utils_ip_config_source_from_rtprot (rtm->rtm_protocol);
obj_result = obj;
obj = NULL;
@@ -1951,7 +1954,8 @@ nmp_object_new_from_nl (NMPlatform *platform, const NMPCache *cache, struct nl_m
static gboolean
_nl_msg_new_link_set_afspec (struct nl_msg *msg,
- int addr_gen_mode)
+ int addr_gen_mode,
+ NMUtilsIPv6IfaceId *iid)
{
struct nlattr *af_spec;
struct nlattr *af_attr;
@@ -1961,11 +1965,19 @@ _nl_msg_new_link_set_afspec (struct nl_msg *msg,
if (!(af_spec = nla_nest_start (msg, IFLA_AF_SPEC)))
goto nla_put_failure;
- if (addr_gen_mode >= 0) {
+ if (addr_gen_mode >= 0 || iid) {
if (!(af_attr = nla_nest_start (msg, AF_INET6)))
goto nla_put_failure;
- NLA_PUT_U8 (msg, IFLA_INET6_ADDR_GEN_MODE, addr_gen_mode);
+ if (addr_gen_mode >= 0)
+ NLA_PUT_U8 (msg, IFLA_INET6_ADDR_GEN_MODE, addr_gen_mode);
+
+ if (iid) {
+ struct in6_addr i6_token = { .s6_addr = { 0, } };
+
+ nm_utils_ipv6_addr_set_interface_identifier (&i6_token, *iid);
+ NLA_PUT (msg, IFLA_INET6_TOKEN, sizeof (struct in6_addr), &i6_token);
+ }
nla_nest_end (msg, af_attr);
}
@@ -2258,7 +2270,7 @@ _nl_msg_new_route (int nlmsg_type,
.rtm_family = family,
.rtm_tos = 0,
.rtm_table = RT_TABLE_MAIN, /* omit setting RTA_TABLE attribute */
- .rtm_protocol = nmp_utils_ip_config_source_to_rtprot (source),
+ .rtm_protocol = nmp_utils_ip_config_source_coerce_to_rtprot (source),
.rtm_scope = scope,
.rtm_type = RTN_UNICAST,
.rtm_flags = 0,
@@ -2282,7 +2294,7 @@ _nl_msg_new_route (int nlmsg_type,
addr_len = family == AF_INET ? sizeof (in_addr_t) : sizeof (struct in6_addr);
- clear_host_address (family, network, plen, &network_clean);
+ nm_utils_ipx_address_clear_host_address (family, &network_clean, network, plen);
NLA_PUT (msg, RTA_DST, addr_len, &network_clean);
NLA_PUT_U32 (msg, RTA_PRIORITY, metric);
@@ -2485,6 +2497,7 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value)
gsize len;
char *actual;
gs_free char *actual_free = NULL;
+ int errsv;
g_return_val_if_fail (path != NULL, FALSE);
g_return_val_if_fail (value != NULL, FALSE);
@@ -2495,18 +2508,22 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value)
/* Don't write to suspicious locations */
g_assert (!strstr (path, "/../"));
- if (!nm_platform_netns_push (platform, &netns))
+ if (!nm_platform_netns_push (platform, &netns)) {
+ errno = ENETDOWN;
return FALSE;
+ }
fd = open (path, O_WRONLY | O_TRUNC);
if (fd == -1) {
- if (errno == ENOENT) {
+ errsv = errno;
+ if (errsv == ENOENT) {
_LOGD ("sysctl: failed to open '%s': (%d) %s",
- path, errno, strerror (errno));
+ path, errsv, strerror (errsv));
} else {
_LOGE ("sysctl: failed to open '%s': (%d) %s",
- path, errno, strerror (errno));
+ path, errsv, strerror (errsv));
}
+ errno = errsv;
return FALSE;
}
@@ -2527,26 +2544,43 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value)
actual[len] = '\0';
/* Try to write the entire value three times if a partial write occurs */
+ errsv = 0;
for (tries = 0, nwrote = 0; tries < 3 && nwrote != len; tries++) {
nwrote = write (fd, actual, len);
if (nwrote == -1) {
- if (errno == EINTR) {
+ errsv = errno;
+ if (errsv == EINTR) {
_LOGD ("sysctl: interrupted, will try again");
continue;
}
break;
}
}
- if (nwrote == -1 && errno != EEXIST) {
+ if (nwrote == -1 && errsv != EEXIST) {
_LOGE ("sysctl: failed to set '%s' to '%s': (%d) %s",
- path, value, errno, strerror (errno));
+ path, value, errsv, strerror (errsv));
} else if (nwrote < len) {
_LOGE ("sysctl: failed to set '%s' to '%s' after three attempts",
path, value);
}
- close (fd);
- return (nwrote == len);
+ if (nwrote != len) {
+ if (close (fd) != 0) {
+ if (errsv != 0)
+ errno = errsv;
+ } else if (errsv != 0)
+ errno = errsv;
+ else
+ errno = EIO;
+ return FALSE;
+ }
+ if (close (fd) != 0) {
+ /* errno is already properly set. */
+ return FALSE;
+ }
+
+ /* success. errno is undefined (no need to set). */
+ return TRUE;
}
static GSList *sysctl_clear_cache_list;
@@ -3724,6 +3758,16 @@ cache_lookup_link (NMPlatform *platform, int ifindex)
return obj_cache;
}
+const NMPlatformObject *const*
+nm_linux_platform_lookup (NMPlatform *platform, const NMPCacheId *cache_id, guint *out_len)
+{
+ g_return_val_if_fail (NM_IS_LINUX_PLATFORM (platform), NULL);
+ g_return_val_if_fail (cache_id, NULL);
+
+ return nmp_cache_lookup_multi (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache,
+ cache_id, out_len);
+}
+
static GArray *
link_get_all (NMPlatform *platform)
{
@@ -4294,8 +4338,22 @@ link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enable
0,
0);
if ( !nlmsg
- || !_nl_msg_new_link_set_afspec (nlmsg,
- mode))
+ || !_nl_msg_new_link_set_afspec (nlmsg, mode, NULL))
+ g_return_val_if_reached (FALSE);
+
+ return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS;
+}
+
+static gboolean
+link_set_token (NMPlatform *platform, int ifindex, NMUtilsIPv6IfaceId iid)
+{
+ nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
+
+ _LOGD ("link: change %d: token: set IPv6 address generation token to %s",
+ ifindex, nm_utils_inet6_interface_identifier_to_token (iid, NULL));
+
+ nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, NULL, 0, 0);
+ if (!nlmsg || !_nl_msg_new_link_set_afspec (nlmsg, -1, &iid))
g_return_val_if_reached (FALSE);
return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS;
@@ -5095,57 +5153,67 @@ link_release (NMPlatform *platform, int master, int slave)
/******************************************************************/
static gboolean
-_infiniband_partition_action (NMPlatform *platform, int parent, int p_key, const char *action, char **ifname)
+_infiniband_partition_action (NMPlatform *platform,
+ InfinibandAction action,
+ int parent,
+ int p_key,
+ const NMPlatformLink **out_link)
{
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
const NMPObject *obj_parent;
- gs_free char *path = NULL;
- gs_free char *id = NULL;
+ const NMPObject *obj;
+ char path[NM_STRLEN ("/sys/class/net/%s/%s") + IFNAMSIZ + 100];
+ char id[20];
+ char name[IFNAMSIZ];
+ gboolean success;
+
+ nm_assert (NM_IN_SET (action, INFINIBAND_ACTION_CREATE_CHILD, INFINIBAND_ACTION_DELETE_CHILD));
+ nm_assert (p_key > 0 && p_key <= 0xffff && p_key != 0x8000);
obj_parent = nmp_cache_lookup_link (priv->cache, parent);
- if (!obj_parent || !obj_parent->link.name[0])
- g_return_val_if_reached (FALSE);
+ if (!obj_parent || !obj_parent->link.name[0]) {
+ errno = ENOENT;
+ return FALSE;
+ }
- *ifname = g_strdup_printf ("%s.%04x", obj_parent->link.name, p_key);
+ nm_sprintf_buf (path,
+ "/sys/class/net/%s/%s",
+ NM_ASSERT_VALID_PATH_COMPONENT (obj_parent->link.name),
+ (action == INFINIBAND_ACTION_CREATE_CHILD
+ ? "create_child"
+ : "delete_child"));
+ nm_sprintf_buf (id, "0x%04x", p_key);
+ success = nm_platform_sysctl_set (platform, path, id);
+ if (!success) {
+ if ( action == INFINIBAND_ACTION_DELETE_CHILD
+ && errno == ENODEV)
+ return TRUE;
+ return FALSE;
+ }
- path = g_strdup_printf ("/sys/class/net/%s/%s",
- NM_ASSERT_VALID_PATH_COMPONENT (obj_parent->link.name),
- action);
- id = g_strdup_printf ("0x%04x", p_key);
+ nm_utils_new_infiniband_name (name, obj_parent->link.name, p_key);
+ do_request_link (platform, 0, name);
- return nm_platform_sysctl_set (platform, path, id);
-}
+ if (action == INFINIBAND_ACTION_DELETE_CHILD)
+ return TRUE;
+ obj = nmp_cache_lookup_link_full (priv->cache, 0, name, FALSE,
+ NM_LINK_TYPE_INFINIBAND, NULL, NULL);
+ if (out_link)
+ *out_link = obj ? &obj->link : NULL;
+ return !!obj;
+}
static gboolean
infiniband_partition_add (NMPlatform *platform, int parent, int p_key, const NMPlatformLink **out_link)
{
- const NMPObject *obj;
- gs_free char *ifname = NULL;
-
- if (!_infiniband_partition_action (platform, parent, p_key, "create_child", &ifname))
- return FALSE;
-
- do_request_link (platform, 0, ifname);
-
- obj = nmp_cache_lookup_link_full (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache,
- 0, ifname, FALSE, NM_LINK_TYPE_INFINIBAND, NULL, NULL);
- if (out_link)
- *out_link = obj ? &obj->link : NULL;
- return !!obj;
+ return _infiniband_partition_action (platform, INFINIBAND_ACTION_CREATE_CHILD, parent, p_key, out_link);
}
static gboolean
infiniband_partition_delete (NMPlatform *platform, int parent, int p_key)
{
- gs_free char *ifname = NULL;
-
- if (!_infiniband_partition_action (platform, parent, p_key, "delete_child", &ifname)) {
- if (errno != ENODEV)
- return FALSE;
- }
-
- return TRUE;
+ return _infiniband_partition_action (platform, INFINIBAND_ACTION_DELETE_CHILD, parent, p_key, NULL);
}
/******************************************************************/
@@ -5570,7 +5638,7 @@ ipx_route_get_all (NMPlatform *platform, int ifindex, NMPObjectType obj_type, NM
nm_assert (NMP_OBJECT_GET_CLASS (NMP_OBJECT_UP_CAST (routes[i])) == klass);
if ( with_rtprot_kernel
- || routes[i]->source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL)
+ || routes[i]->rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL)
g_array_append_vals (array, routes[i], 1);
}
return array;
@@ -6397,6 +6465,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
platform_class->link_get_udev_device = link_get_udev_device;
platform_class->link_set_user_ipv6ll_enabled = link_set_user_ipv6ll_enabled;
+ platform_class->link_set_token = link_set_token;
platform_class->link_set_address = link_set_address;
platform_class->link_get_permanent_address = link_get_permanent_address;
diff --git a/src/platform/nm-linux-platform.h b/src/platform/nm-linux-platform.h
index 4ae2fd1400..3b2a440e52 100644
--- a/src/platform/nm-linux-platform.h
+++ b/src/platform/nm-linux-platform.h
@@ -52,4 +52,10 @@ NMPlatform *nm_linux_platform_new (gboolean netns_support);
void nm_linux_platform_setup (void);
+struct _NMPCacheId;
+
+const NMPlatformObject *const *nm_linux_platform_lookup (NMPlatform *platform,
+ const struct _NMPCacheId *cache_id,
+ guint *out_len);
+
#endif /* __NETWORKMANAGER_LINUX_PLATFORM_H__ */
diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c
index b4542adf8d..068801ee69 100644
--- a/src/platform/nm-platform-utils.c
+++ b/src/platform/nm-platform-utils.c
@@ -144,8 +144,7 @@ nmp_utils_ethtool_get_permanent_address (const char *ifname,
struct ethtool_perm_addr e;
guint8 _extra_data[NM_UTILS_HWADDR_LEN_MAX + 1];
} edata;
- static const guint8 zeros[NM_UTILS_HWADDR_LEN_MAX] = { 0 };
- static guint8 ones[NM_UTILS_HWADDR_LEN_MAX] = { 0 };
+ guint i;
if (!ifname)
return FALSE;
@@ -157,18 +156,23 @@ nmp_utils_ethtool_get_permanent_address (const char *ifname,
if (!ethtool_get (ifname, &edata.e))
return FALSE;
- g_assert (edata.e.size <= NM_UTILS_HWADDR_LEN_MAX);
-
- /* Some drivers might return a permanent address of all zeros.
- * Reject that (rh#1264024) */
- if (memcmp (edata.e.data, zeros, edata.e.size) == 0)
+ if (edata.e.size > NM_UTILS_HWADDR_LEN_MAX)
+ return FALSE;
+ if (edata.e.size < 1)
return FALSE;
- /* Some drivers return a permanent address of all ones. Reject that too */
- if (G_UNLIKELY (ones[0] != 0xFF))
- memset (ones, 0xFF, sizeof (ones));
- if (memcmp (edata.e.data, ones, edata.e.size) == 0)
+ if (NM_IN_SET (edata.e.data[0], 0, 0xFF)) {
+ /* Some drivers might return a permanent address of all zeros.
+ * Reject that (rh#1264024)
+ *
+ * Some drivers return a permanent address of all ones. Reject that too */
+ for (i = 1; i < edata.e.size; i++) {
+ if (edata.e.data[0] != edata.e.data[i])
+ goto not_all_0or1;
+ }
return FALSE;
+ }
+not_all_0or1:
memcpy (buf, edata.e.data, edata.e.size);
*length = edata.e.size;
@@ -433,14 +437,35 @@ nmp_utils_device_exists (const char *name)
return g_file_test (sysdir, G_FILE_TEST_EXISTS);
}
-guint
-nmp_utils_ip_config_source_to_rtprot (NMIPConfigSource source)
+NMIPConfigSource
+nmp_utils_ip_config_source_from_rtprot (guint8 rtprot)
{
- switch (source) {
- case NM_IP_CONFIG_SOURCE_UNKNOWN:
+ return ((int) rtprot) + 1;
+}
+
+NMIPConfigSource
+nmp_utils_ip_config_source_round_trip_rtprot (NMIPConfigSource source)
+{
+ /* when adding a route to kernel for a give @source, the resulting route
+ * will be put into the cache with a source of NM_IP_CONFIG_SOURCE_RTPROT_*.
+ * This function returns that. */
+ return nmp_utils_ip_config_source_from_rtprot (nmp_utils_ip_config_source_coerce_to_rtprot (source));
+}
+
+guint8
+nmp_utils_ip_config_source_coerce_to_rtprot (NMIPConfigSource source)
+{
+ /* when adding a route to kernel, we coerce the @source field
+ * to rtm_protocol. This is not lossless as we map different
+ * source values to the same RTPROT uint8 value. */
+ if (source <= NM_IP_CONFIG_SOURCE_UNKNOWN)
return RTPROT_UNSPEC;
+
+ if (source <= _NM_IP_CONFIG_SOURCE_RTPROT_LAST)
+ return source - 1;
+
+ switch (source) {
case NM_IP_CONFIG_SOURCE_KERNEL:
- case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL:
return RTPROT_KERNEL;
case NM_IP_CONFIG_SOURCE_DHCP:
return RTPROT_DHCP;
@@ -453,18 +478,32 @@ nmp_utils_ip_config_source_to_rtprot (NMIPConfigSource source)
}
NMIPConfigSource
-nmp_utils_ip_config_source_from_rtprot (guint rtprot)
+nmp_utils_ip_config_source_coerce_from_rtprot (NMIPConfigSource source)
{
- switch (rtprot) {
- case RTPROT_UNSPEC:
+ /* When we receive a route from kernel and put it into the platform cache,
+ * we preserve the protocol field by converting it to a NMIPConfigSource
+ * via nmp_utils_ip_config_source_from_rtprot().
+ *
+ * However, that is not the inverse of nmp_utils_ip_config_source_coerce_to_rtprot().
+ * Instead, to go back to the original value, you need another step:
+ * nmp_utils_ip_config_source_coerce_from_rtprot (nmp_utils_ip_config_source_from_rtprot (rtprot)).
+ *
+ * This might partly restore the original source value, but of course that
+ * is not really possible because nmp_utils_ip_config_source_coerce_to_rtprot()
+ * is not injective.
+ * */
+ switch (source) {
+ case NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC:
return NM_IP_CONFIG_SOURCE_UNKNOWN;
- case RTPROT_KERNEL:
- return NM_IP_CONFIG_SOURCE_RTPROT_KERNEL;
- case RTPROT_REDIRECT:
+
+ case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL:
+ case NM_IP_CONFIG_SOURCE_RTPROT_REDIRECT:
return NM_IP_CONFIG_SOURCE_KERNEL;
- case RTPROT_RA:
+
+ case NM_IP_CONFIG_SOURCE_RTPROT_RA:
return NM_IP_CONFIG_SOURCE_RDISC;
- case RTPROT_DHCP:
+
+ case NM_IP_CONFIG_SOURCE_RTPROT_DHCP:
return NM_IP_CONFIG_SOURCE_DHCP;
default:
@@ -472,3 +511,50 @@ nmp_utils_ip_config_source_from_rtprot (guint rtprot)
}
}
+const char *
+nmp_utils_ip_config_source_to_string (NMIPConfigSource source, char *buf, gsize len)
+{
+ const char *s = NULL;
+ nm_utils_to_string_buffer_init (&buf, &len); \
+
+ if (!len)
+ return buf;
+
+ switch (source) {
+ case NM_IP_CONFIG_SOURCE_UNKNOWN: s = "unknown"; break;
+
+ case NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC: s = "rt-unspec"; break;
+ case NM_IP_CONFIG_SOURCE_RTPROT_REDIRECT: s = "rt-redirect"; break;
+ case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL: s = "rt-kernel"; break;
+ case NM_IP_CONFIG_SOURCE_RTPROT_BOOT: s = "rt-boot"; break;
+ case NM_IP_CONFIG_SOURCE_RTPROT_STATIC: s = "rt-static"; break;
+ case NM_IP_CONFIG_SOURCE_RTPROT_DHCP: s = "rt-dhcp"; break;
+ case NM_IP_CONFIG_SOURCE_RTPROT_RA: s = "rt-ra"; break;
+
+ case NM_IP_CONFIG_SOURCE_KERNEL: s = "kernel"; break;
+ case NM_IP_CONFIG_SOURCE_SHARED: s = "shared"; break;
+ case NM_IP_CONFIG_SOURCE_IP4LL: s = "ipv4ll"; break;
+ case NM_IP_CONFIG_SOURCE_PPP: s = "ppp"; break;
+ case NM_IP_CONFIG_SOURCE_WWAN: s = "wwan"; break;
+ case NM_IP_CONFIG_SOURCE_VPN: s = "vpn"; break;
+ case NM_IP_CONFIG_SOURCE_DHCP: s = "dhcp"; break;
+ case NM_IP_CONFIG_SOURCE_RDISC: s = "rdisc"; break;
+ case NM_IP_CONFIG_SOURCE_USER: s = "user"; break;
+ default:
+ break;
+ }
+
+ if (source >= 1 && source <= 0x100) {
+ if (s)
+ g_snprintf (buf, len, "%s", s);
+ else
+ g_snprintf (buf, len, "rt-%d", ((int) source) - 1);
+ } else {
+ if (s)
+ g_strlcpy (buf, s, len);
+ else
+ g_snprintf (buf, len, "(%d)", source);
+ }
+ return buf;
+}
+
diff --git a/src/platform/nm-platform-utils.h b/src/platform/nm-platform-utils.h
index f259474719..456c08652d 100644
--- a/src/platform/nm-platform-utils.h
+++ b/src/platform/nm-platform-utils.h
@@ -54,7 +54,10 @@ const char *nmp_utils_udev_get_driver (GUdevDevice *device);
gboolean nmp_utils_device_exists (const char *name);
-guint nmp_utils_ip_config_source_to_rtprot (NMIPConfigSource source);
-NMIPConfigSource nmp_utils_ip_config_source_from_rtprot (guint rtprot);
+NMIPConfigSource nmp_utils_ip_config_source_from_rtprot (guint8 rtprot) _nm_const;
+guint8 nmp_utils_ip_config_source_coerce_to_rtprot (NMIPConfigSource source) _nm_const;
+NMIPConfigSource nmp_utils_ip_config_source_coerce_from_rtprot (NMIPConfigSource source) _nm_const;
+NMIPConfigSource nmp_utils_ip_config_source_round_trip_rtprot (NMIPConfigSource source) _nm_const;
+const char * nmp_utils_ip_config_source_to_string (NMIPConfigSource source, char *buf, gsize len);
#endif /* __NM_PLATFORM_UTILS_H__ */
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 26ac766d63..a6afcf33a9 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -387,6 +387,20 @@ nm_platform_sysctl_get_int_checked (NMPlatform *self, const char *path, guint ba
/******************************************************************/
+static int
+_link_get_all_presort (gconstpointer p_a,
+ gconstpointer p_b)
+{
+ const NMPlatformLink *a = p_a;
+ const NMPlatformLink *b = p_b;
+
+ if (a->ifindex < b->ifindex)
+ return -1;
+ if (a->ifindex > b->ifindex)
+ return 1;
+ return 0;
+}
+
/**
* nm_platform_link_get_all:
* self: platform instance
@@ -409,15 +423,17 @@ nm_platform_link_get_all (NMPlatform *self)
if (!links || links->len == 0)
return links;
+ /* first sort the links by their ifindex. Below we will sort further by moving
+ * children/slaves to the end. */
+ g_array_sort (links, _link_get_all_presort);
+
unseen = g_hash_table_new (g_direct_hash, g_direct_equal);
for (i = 0; i < links->len; i++) {
item = &g_array_index (links, NMPlatformLink, i);
- _LOGt ("link-get: %3d: %s", i, nm_platform_link_to_string (item, NULL, 0));
-
- nm_assert (item->ifindex > 0 && !g_hash_table_contains (unseen, GINT_TO_POINTER (item->ifindex)));
-
- g_hash_table_insert (unseen, GINT_TO_POINTER (item->ifindex), NULL);
+ nm_assert (item->ifindex > 0);
+ if (!nm_g_hash_table_insert (unseen, GINT_TO_POINTER (item->ifindex), NULL))
+ nm_assert_not_reached ();
}
#ifndef G_DISABLE_ASSERT
@@ -468,8 +484,6 @@ nm_platform_link_get_all (NMPlatform *self)
if (item->parent > 0 && g_hash_table_contains (unseen, GINT_TO_POINTER (item->parent)))
continue;
- _LOGt ("link-get: add %3d -> %3d: %s", i, j, nm_platform_link_to_string (item, NULL, 0));
-
g_hash_table_remove (unseen, GINT_TO_POINTER (item->ifindex));
g_array_index (result, NMPlatformLink, j++) = *item;
item->ifindex = 0;
@@ -481,8 +495,6 @@ nm_platform_link_get_all (NMPlatform *self)
* This can happen for veth pairs where each peer is parent of the other end. */
item = &g_array_index (links, NMPlatformLink, first_idx);
- _LOGt ("link-get: add (loop) %3d -> %3d: %s", first_idx, j, nm_platform_link_to_string (item, NULL, 0));
-
g_hash_table_remove (unseen, GINT_TO_POINTER (item->ifindex));
g_array_index (result, NMPlatformLink, j++) = *item;
item->ifindex = 0;
@@ -888,33 +900,25 @@ nm_platform_link_uses_arp (NMPlatform *self, int ifindex)
}
/**
- * nm_platform_link_get_ipv6_token:
+ * nm_platform_link_set_ipv6_token:
* @self: platform instance
* @ifindex: Interface index
* @iid: Tokenized interface identifier
*
- * Returns IPv6 tokenized interface identifier. If the platform or OS doesn't
- * support IPv6 tokenized interface identifiers, or the token is not set
- * this call will fail and return %FALSE.
+ * Sets then IPv6 tokenized interface identifier.
*
* Returns: %TRUE a tokenized identifier was available
*/
gboolean
-nm_platform_link_get_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId *iid)
+nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid)
{
- const NMPlatformLink *pllink;
-
_CHECK_SELF (self, klass, FALSE);
g_return_val_if_fail (ifindex >= 0, FALSE);
- g_return_val_if_fail (iid, FALSE);
-
+ g_return_val_if_fail (iid.id, FALSE);
- pllink = nm_platform_link_get (self, ifindex);
- if (pllink && pllink->inet6_token.is_valid) {
- *iid = pllink->inet6_token.iid;
- return TRUE;
- }
+ if (klass->link_set_token)
+ return klass->link_set_token (self, ifindex, iid);
return FALSE;
}
@@ -1895,21 +1899,27 @@ _infiniband_add_add_or_delete (NMPlatform *self,
gboolean add,
const NMPlatformLink **out_link)
{
- gs_free char *parent_name = NULL;
- gs_free char *name = NULL;
+ char name[IFNAMSIZ];
+ const NMPlatformLink *parent_link;
NMPlatformError plerr;
_CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG);
g_return_val_if_fail (parent >= 0, NM_PLATFORM_ERROR_BUG);
- g_return_val_if_fail (p_key >= 0, NM_PLATFORM_ERROR_BUG);
+ g_return_val_if_fail (p_key >= 0 && p_key <= 0xffff, NM_PLATFORM_ERROR_BUG);
+
+ /* the special keys 0x0000 and 0x8000 are not allowed. */
+ if (NM_IN_SET (p_key, 0, 0x8000))
+ return NM_PLATFORM_ERROR_UNSPECIFIED;
+
+ parent_link = nm_platform_link_get (self, parent);
+ if (!parent_link)
+ return NM_PLATFORM_ERROR_NOT_FOUND;
- parent_name = g_strdup (nm_platform_link_get_name (self, parent));
- if ( !parent_name
- || nm_platform_link_get_type (self, parent) != NM_LINK_TYPE_INFINIBAND)
+ if (parent_link->type != NM_LINK_TYPE_INFINIBAND)
return NM_PLATFORM_ERROR_WRONG_TYPE;
- name = g_strdup_printf ("%s.%04x", parent_name, p_key);
+ nm_utils_new_infiniband_name (name, parent_link->name, p_key);
if (add) {
plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_INFINIBAND, out_link);
@@ -1917,7 +1927,7 @@ _infiniband_add_add_or_delete (NMPlatform *self,
return plerr;
_LOGD ("link: adding infiniband partition %s for parent '%s' (%d), key %d",
- name, parent_name, parent, p_key);
+ name, parent_link->name, parent, p_key);
if (!klass->infiniband_partition_add (self, parent, p_key, out_link))
return NM_PLATFORM_ERROR_UNSPECIFIED;
} else {
@@ -2894,7 +2904,7 @@ nm_platform_ip4_route_add (NMPlatform *self,
NMPlatformIP4Route route = { 0 };
route.ifindex = ifindex;
- route.source = source;
+ route.rt_source = source;
route.network = network;
route.plen = plen;
route.gateway = gateway;
@@ -2921,7 +2931,7 @@ nm_platform_ip6_route_add (NMPlatform *self,
NMPlatformIP6Route route = { 0 };
route.ifindex = ifindex;
- route.source = source;
+ route.rt_source = source;
route.network = network;
route.plen = plen;
route.gateway = gateway;
@@ -3012,38 +3022,6 @@ nm_platform_vlan_qos_mapping_to_string (const char *name,
}
static const char *
-source_to_string (NMIPConfigSource source)
-{
- switch (source) {
- case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL:
- return "rtprot-kernel";
- case _NM_IP_CONFIG_SOURCE_RTM_F_CLONED:
- return "rtm-f-cloned";
- case NM_IP_CONFIG_SOURCE_KERNEL:
- return "kernel";
- case NM_IP_CONFIG_SOURCE_SHARED:
- return "shared";
- case NM_IP_CONFIG_SOURCE_IP4LL:
- return "ipv4ll";
- case NM_IP_CONFIG_SOURCE_PPP:
- return "ppp";
- case NM_IP_CONFIG_SOURCE_WWAN:
- return "wwan";
- case NM_IP_CONFIG_SOURCE_VPN:
- return "vpn";
- case NM_IP_CONFIG_SOURCE_DHCP:
- return "dhcp";
- case NM_IP_CONFIG_SOURCE_RDISC:
- return "rdisc";
- case NM_IP_CONFIG_SOURCE_USER:
- return "user";
- default:
- break;
- }
- return "unknown";
-}
-
-static const char *
_lifetime_to_string (guint32 timestamp, guint32 lifetime, gint32 now, char *buf, size_t buf_size)
{
if (lifetime == NM_PLATFORM_LIFETIME_PERMANENT)
@@ -3081,7 +3059,7 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len)
GString *str_flags;
char str_addrmode[30];
gs_free char *str_addr = NULL;
- gs_free char *str_inet6_token = NULL;
+ char str_inet6_token[NM_UTILS_INET_ADDRSTRLEN];
const char *str_link_type;
if (!nm_utils_to_string_buffer_init_null (link, &buf, &len))
@@ -3118,8 +3096,6 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len)
if (link->addr.len)
str_addr = nm_utils_hwaddr_ntoa (link->addr.data, MIN (link->addr.len, sizeof (link->addr.data)));
- if (link->inet6_token.is_valid)
- str_inet6_token = nm_utils_hwaddr_ntoa (&link->inet6_token.iid, sizeof (link->inet6_token.iid));
str_link_type = nm_link_type_to_string (link->type);
@@ -3153,8 +3129,8 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len)
link->inet6_addr_gen_mode_inv ? nm_platform_link_inet6_addrgenmode2str (_nm_platform_uint8_inv (link->inet6_addr_gen_mode_inv), str_addrmode, sizeof (str_addrmode)) : "",
str_addr ? " addr " : "",
str_addr ? str_addr : "",
- str_inet6_token ? " inet6token " : "",
- str_inet6_token ? str_inet6_token : "",
+ link->inet6_token.id ? " inet6token " : "",
+ link->inet6_token.id ? nm_utils_inet6_interface_identifier_to_token (link->inet6_token, str_inet6_token) : "",
link->driver ? " driver " : "",
link->driver ? link->driver : "");
g_string_free (str_flags, TRUE);
@@ -3471,7 +3447,7 @@ nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *bu
char s_peer[INET_ADDRSTRLEN];
char str_dev[TO_STRING_DEV_BUF_SIZE];
char str_label[32];
- char str_lft[30], str_pref[30], str_time[50];
+ char str_lft[30], str_pref[30], str_time[50], s_source[50];
char *str_peer = NULL;
const char *str_lft_p, *str_pref_p, *str_time_p;
gint32 now = nm_utils_get_monotonic_timestamp_s ();
@@ -3510,7 +3486,7 @@ nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *bu
str_dev,
_to_string_ifa_flags (address->n_ifa_flags, s_flags, sizeof (s_flags)),
str_label,
- source_to_string (address->source));
+ nmp_utils_ip_config_source_to_string (address->addr_source, s_source, sizeof (s_source)));
g_free (str_peer);
return buf;
}
@@ -3582,7 +3558,7 @@ nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address, char *bu
char s_flags[TO_STRING_IFA_FLAGS_BUF_SIZE];
char s_address[INET6_ADDRSTRLEN];
char s_peer[INET6_ADDRSTRLEN];
- char str_lft[30], str_pref[30], str_time[50];
+ char str_lft[30], str_pref[30], str_time[50], s_source[50];
char str_dev[TO_STRING_DEV_BUF_SIZE];
char *str_peer = NULL;
const char *str_lft_p, *str_pref_p, *str_time_p;
@@ -3616,7 +3592,7 @@ nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address, char *bu
str_peer ? str_peer : "",
str_dev,
_to_string_ifa_flags (address->n_ifa_flags, s_flags, sizeof (s_flags)),
- source_to_string (address->source));
+ nmp_utils_ip_config_source_to_string (address->addr_source, s_source, sizeof (s_source)));
g_free (str_peer);
return buf;
}
@@ -3639,7 +3615,7 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi
char s_network[INET_ADDRSTRLEN], s_gateway[INET_ADDRSTRLEN];
char s_pref_src[INET_ADDRSTRLEN];
char str_dev[TO_STRING_DEV_BUF_SIZE];
- char str_scope[30];
+ char str_scope[30], s_source[50];
if (!nm_utils_to_string_buffer_init_null (route, &buf, &len))
return buf;
@@ -3656,6 +3632,7 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi
" metric %"G_GUINT32_FORMAT
" mss %"G_GUINT32_FORMAT
" src %s" /* source */
+ "%s" /* cloned */
"%s%s" /* scope */
"%s%s" /* pref-src */
"",
@@ -3665,7 +3642,8 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi
str_dev,
route->metric,
route->mss,
- source_to_string (route->source),
+ nmp_utils_ip_config_source_to_string (route->rt_source, s_source, sizeof (s_source)),
+ route->rt_cloned ? " cloned" : "",
route->scope_inv ? " scope " : "",
route->scope_inv ? (nm_platform_route_scope2str (nm_platform_route_scope_inv (route->scope_inv), str_scope, sizeof (str_scope))) : "",
route->pref_src ? " pref-src " : "",
@@ -3689,7 +3667,7 @@ const char *
nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsize len)
{
char s_network[INET6_ADDRSTRLEN], s_gateway[INET6_ADDRSTRLEN];
- char str_dev[TO_STRING_DEV_BUF_SIZE];
+ char str_dev[TO_STRING_DEV_BUF_SIZE], s_source[50];
if (!nm_utils_to_string_buffer_init_null (route, &buf, &len))
return buf;
@@ -3706,6 +3684,7 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi
" metric %"G_GUINT32_FORMAT
" mss %"G_GUINT32_FORMAT
" src %s" /* source */
+ "%s" /* cloned */
"",
s_network,
route->plen,
@@ -3713,7 +3692,8 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi
str_dev,
route->metric,
route->mss,
- source_to_string (route->source));
+ nmp_utils_ip_config_source_to_string (route->rt_source, s_source, sizeof (s_source)),
+ route->rt_cloned ? " cloned" : "");
return buf;
}
@@ -3808,13 +3788,11 @@ nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b)
_CMP_FIELD (a, b, arptype);
_CMP_FIELD (a, b, addr.len);
_CMP_FIELD (a, b, inet6_addr_gen_mode_inv);
- _CMP_FIELD (a, b, inet6_token.is_valid);
_CMP_FIELD_STR_INTERNED (a, b, kind);
_CMP_FIELD_STR_INTERNED (a, b, driver);
if (a->addr.len)
_CMP_FIELD_MEMCMP_LEN (a, b, addr.data, a->addr.len);
- if (a->inet6_token.is_valid)
- _CMP_FIELD_MEMCMP (a, b, inet6_token.iid);
+ _CMP_FIELD_MEMCMP (a, b, inet6_token);
return 0;
}
@@ -3935,10 +3913,10 @@ nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4A
{
_CMP_SELF (a, b);
_CMP_FIELD (a, b, ifindex);
- _CMP_FIELD (a, b, source);
_CMP_FIELD (a, b, address);
_CMP_FIELD (a, b, plen);
_CMP_FIELD (a, b, peer_address);
+ _CMP_FIELD (a, b, addr_source);
_CMP_FIELD (a, b, timestamp);
_CMP_FIELD (a, b, lifetime);
_CMP_FIELD (a, b, preferred);
@@ -3954,14 +3932,12 @@ nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6A
_CMP_SELF (a, b);
_CMP_FIELD (a, b, ifindex);
- _CMP_FIELD (a, b, source);
_CMP_FIELD_MEMCMP (a, b, address);
-
+ _CMP_FIELD (a, b, plen);
p_a = nm_platform_ip6_address_get_peer (a);
p_b = nm_platform_ip6_address_get_peer (b);
_CMP_DIRECT_MEMCMP (p_a, p_b, sizeof (*p_a));
-
- _CMP_FIELD (a, b, plen);
+ _CMP_FIELD (a, b, addr_source);
_CMP_FIELD (a, b, timestamp);
_CMP_FIELD (a, b, lifetime);
_CMP_FIELD (a, b, preferred);
@@ -3974,14 +3950,15 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route
{
_CMP_SELF (a, b);
_CMP_FIELD (a, b, ifindex);
- _CMP_FIELD (a, b, source);
_CMP_FIELD (a, b, network);
_CMP_FIELD (a, b, plen);
- _CMP_FIELD (a, b, gateway);
_CMP_FIELD (a, b, metric);
+ _CMP_FIELD (a, b, gateway);
+ _CMP_FIELD (a, b, rt_source);
_CMP_FIELD (a, b, mss);
_CMP_FIELD (a, b, scope_inv);
_CMP_FIELD (a, b, pref_src);
+ _CMP_FIELD (a, b, rt_cloned);
return 0;
}
@@ -3990,12 +3967,13 @@ nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route
{
_CMP_SELF (a, b);
_CMP_FIELD (a, b, ifindex);
- _CMP_FIELD (a, b, source);
_CMP_FIELD_MEMCMP (a, b, network);
_CMP_FIELD (a, b, plen);
- _CMP_FIELD_MEMCMP (a, b, gateway);
_CMP_FIELD (a, b, metric);
+ _CMP_FIELD_MEMCMP (a, b, gateway);
+ _CMP_FIELD (a, b, rt_source);
_CMP_FIELD (a, b, mss);
+ _CMP_FIELD (a, b, rt_cloned);
return 0;
}
@@ -4128,7 +4106,7 @@ _vtr_v4_route_add (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *rout
{
return nm_platform_ip4_route_add (self,
ifindex > 0 ? ifindex : route->rx.ifindex,
- route->rx.source,
+ route->rx.rt_source,
route->r4.network,
route->rx.plen,
route->r4.gateway,
@@ -4142,7 +4120,7 @@ _vtr_v6_route_add (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *rout
{
return nm_platform_ip6_route_add (self,
ifindex > 0 ? ifindex : route->rx.ifindex,
- route->rx.source,
+ route->rx.rt_source,
route->r6.network,
route->rx.plen,
route->r6.gateway,
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index 19724f1c19..72f4f6720a 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -49,8 +49,6 @@
/******************************************************************/
-typedef struct _NMPlatform NMPlatform;
-
/* workaround for older libnl version, that does not define these flags. */
#ifndef IFA_F_MANAGETEMPADDR
#define IFA_F_MANAGETEMPADDR 0x100
@@ -98,6 +96,11 @@ typedef struct {
guint8 addr_ptr[1];
in_addr_t addr4;
struct in6_addr addr6;
+
+ /* NMIPAddr is really a union for IP addresses.
+ * However, as ethernet addresses fit in here nicely, ruse
+ * it also for an ethernet MAC address. */
+ guint8 addr_eth[6 /*ETH_ALEN*/];
};
} NMIPAddr;
@@ -144,11 +147,8 @@ struct _NMPlatformLink {
guint8 len;
} addr;
- /* rtnl_link_inet6_get_token() */
- struct {
- NMUtilsIPv6IfaceId iid;
- guint8 is_valid;
- } inet6_token;
+ /* rtnl_link_inet6_get_token(), IFLA_INET6_TOKEN */
+ NMUtilsIPv6IfaceId inet6_token;
/* The bitwise inverse of rtnl_link_inet6_get_addr_gen_mode(). It is inverse
* to have a default of 0 -- meaning: unspecified. That way, a struct
@@ -200,7 +200,7 @@ typedef struct {
#define __NMPlatformIPAddress_COMMON \
__NMPlatformObject_COMMON; \
- NMIPConfigSource source; \
+ NMIPConfigSource addr_source; \
\
/* Timestamp in seconds in the reference system of nm_utils_get_monotonic_timestamp_*().
*
@@ -303,8 +303,21 @@ typedef union {
#define __NMPlatformIPRoute_COMMON \
__NMPlatformObject_COMMON; \
- NMIPConfigSource source; \
+ \
+ /* The NMIPConfigSource. For routes that we receive from cache this corresponds
+ * to the rtm_protocol field (and is one of the NM_IP_CONFIG_SOURCE_RTPROT_* values).
+ * When adding a route, the source will be coerced to the protocol using
+ * nmp_utils_ip_config_source_coerce_to_rtprot(). */ \
+ NMIPConfigSource rt_source; \
+ \
guint8 plen; \
+ \
+ /* the route has rtm_flags set to RTM_F_CLONED. Such a route
+ * is hidden by platform and does not exist from the point-of-view
+ * of platform users. This flag is internal to track those hidden
+ * routes. Such a route is not alive, according to nmp_object_is_alive(). */ \
+ bool rt_cloned:1; \
+ \
guint32 metric; \
guint32 mss; \
;
@@ -507,6 +520,7 @@ typedef struct {
GObject *(*link_get_udev_device) (NMPlatform *self, int ifindex);
gboolean (*link_set_user_ipv6ll_enabled) (NMPlatform *, int ifindex, gboolean enabled);
+ gboolean (*link_set_token) (NMPlatform *, int ifindex, NMUtilsIPv6IfaceId iid);
gboolean (*link_get_permanent_address) (NMPlatform *,
int ifindex,
@@ -717,7 +731,6 @@ gboolean nm_platform_link_is_up (NMPlatform *self, int ifindex);
gboolean nm_platform_link_is_connected (NMPlatform *self, int ifindex);
gboolean nm_platform_link_uses_arp (NMPlatform *self, int ifindex);
guint32 nm_platform_link_get_mtu (NMPlatform *self, int ifindex);
-gboolean nm_platform_link_get_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId *iid);
gboolean nm_platform_link_get_user_ipv6ll_enabled (NMPlatform *self, int ifindex);
gconstpointer nm_platform_link_get_address (NMPlatform *self, int ifindex, size_t *length);
int nm_platform_link_get_master (NMPlatform *self, int slave);
@@ -741,6 +754,7 @@ const char *nm_platform_link_get_udi (NMPlatform *self, int ifindex);
GObject *nm_platform_link_get_udev_device (NMPlatform *self, int ifindex);
gboolean nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolean enabled);
+gboolean nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid);
gboolean nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, guint8 *buf, size_t *length);
gboolean nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length);
diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c
index eb7e1ca401..55ffd7cffb 100644
--- a/src/platform/nmp-object.c
+++ b/src/platform/nmp-object.c
@@ -915,12 +915,12 @@ _vt_cmd_obj_is_alive_ipx_route (const NMPObject *obj)
*
* If nmp_object_from_nl() would just return NULL, we couldn't look
* into the cache to see if it contains a route that now disappears
- * (because it is cloned).
+ * (because it changed to be cloned).
*
* Instead we create a dead object, and nmp_cache_update_netlink()
* will remove the old version of the update.
**/
- return obj->object.ifindex > 0 && (obj->ip_route.source != _NM_IP_CONFIG_SOURCE_RTM_F_CLONED);
+ return obj->object.ifindex > 0 && !obj->ip_route.rt_cloned;
}
gboolean
diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h
index c5241037d5..d295f7a078 100644
--- a/src/platform/nmp-object.h
+++ b/src/platform/nmp-object.h
@@ -94,9 +94,9 @@ typedef enum { /*< skip >*/
NMP_CACHE_ID_TYPE_MAX = __NMP_CACHE_ID_TYPE_MAX - 1,
} NMPCacheIdType;
-typedef struct _NMPObject NMPObject;
+typedef struct _NMPCacheId NMPCacheId;
-typedef struct {
+struct _NMPCacheId {
union {
NMMultiIndexId base;
guint8 _id_type; /* NMPCacheIdType as guint8 */
@@ -136,7 +136,7 @@ typedef struct {
struct in6_addr _misaligned_network;
} routes_by_destination_ip6;
};
-} NMPCacheId;
+};
extern NMPCacheId _nmp_cache_id_static;
#define NMP_CACHE_ID_STATIC (&_nmp_cache_id_static)
diff --git a/src/platform/tests/monitor.c b/src/platform/tests/monitor.c
index 3af34be42c..937eea1154 100644
--- a/src/platform/tests/monitor.c
+++ b/src/platform/tests/monitor.c
@@ -25,7 +25,7 @@
#include "nm-linux-platform.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
NMTST_DEFINE ();
diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h
index 0e3cf10ba4..143b9b5272 100644
--- a/src/platform/tests/test-common.h
+++ b/src/platform/tests/test-common.h
@@ -8,7 +8,7 @@
#include "nm-fake-platform.h"
#include "nm-linux-platform.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
#define DEVICE_NAME "nm-test-device"
diff --git a/src/platform/tests/test-general.c b/src/platform/tests/test-general.c
index d8d925614b..f67f00892f 100644
--- a/src/platform/tests/test-general.c
+++ b/src/platform/tests/test-general.c
@@ -25,7 +25,7 @@
#include "nm-platform-utils.h"
#include "nm-linux-platform.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
/******************************************************************/
diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c
index 9d548aabdb..db8ad5a2e1 100644
--- a/src/platform/tests/test-link.c
+++ b/src/platform/tests/test-link.c
@@ -30,7 +30,7 @@
#include "nm-platform-utils.h"
#include "test-common.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
#define LO_INDEX 1
#define LO_NAME "lo"
@@ -1861,7 +1861,7 @@ _test_netns_setup (gpointer fixture, gconstpointer test_data)
{
/* the singleton platform instance has netns support disabled.
* Destroy the instance before the test and re-create it afterwards. */
- g_object_unref (nm_platform_get ());
+ g_object_unref (NM_PLATFORM_GET);
}
static void
diff --git a/src/platform/tests/test-nmp-object.c b/src/platform/tests/test-nmp-object.c
index d77170b364..9d4f69de4c 100644
--- a/src/platform/tests/test-nmp-object.c
+++ b/src/platform/tests/test-nmp-object.c
@@ -22,7 +22,7 @@
#include "nmp-object.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
struct {
GList *udev_devices;
diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c
index a50392a66f..360404e944 100644
--- a/src/platform/tests/test-route.c
+++ b/src/platform/tests/test-route.c
@@ -23,9 +23,9 @@
#include <linux/rtnetlink.h>
#include "nm-core-utils.h"
-#include "test-common.h"
+#include "nm-platform-utils.h"
-#include "nm-test-utils.h"
+#include "test-common.h"
#define DEVICE_NAME "nm-test-device"
@@ -178,7 +178,7 @@ test_ip4_route (void)
/* Test route listing */
routes = nm_platform_ip4_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT);
memset (rts, 0, sizeof (rts));
- rts[0].source = NM_IP_CONFIG_SOURCE_USER;
+ rts[0].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
rts[0].network = gateway;
rts[0].plen = 32;
rts[0].ifindex = ifindex;
@@ -186,7 +186,7 @@ test_ip4_route (void)
rts[0].metric = metric;
rts[0].mss = mss;
rts[0].scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK);
- rts[1].source = NM_IP_CONFIG_SOURCE_USER;
+ rts[1].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
rts[1].network = network;
rts[1].plen = plen;
rts[1].ifindex = ifindex;
@@ -194,7 +194,7 @@ test_ip4_route (void)
rts[1].metric = metric;
rts[1].mss = mss;
rts[1].scope_inv = nm_platform_route_scope_inv (RT_SCOPE_UNIVERSE);
- rts[2].source = NM_IP_CONFIG_SOURCE_USER;
+ rts[2].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
rts[2].network = 0;
rts[2].plen = 0;
rts[2].ifindex = ifindex;
@@ -265,21 +265,21 @@ test_ip6_route (void)
/* Test route listing */
routes = nm_platform_ip6_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT);
memset (rts, 0, sizeof (rts));
- rts[0].source = NM_IP_CONFIG_SOURCE_USER;
+ rts[0].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
rts[0].network = gateway;
rts[0].plen = 128;
rts[0].ifindex = ifindex;
rts[0].gateway = in6addr_any;
rts[0].metric = nm_utils_ip6_route_metric_normalize (metric);
rts[0].mss = mss;
- rts[1].source = NM_IP_CONFIG_SOURCE_USER;
+ rts[1].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
rts[1].network = network;
rts[1].plen = plen;
rts[1].ifindex = ifindex;
rts[1].gateway = gateway;
rts[1].metric = nm_utils_ip6_route_metric_normalize (metric);
rts[1].mss = mss;
- rts[2].source = NM_IP_CONFIG_SOURCE_USER;
+ rts[2].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
rts[2].network = in6addr_any;
rts[2].plen = 0;
rts[2].ifindex = ifindex;
diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c
index 38e5a0545e..9b981f3b38 100644
--- a/src/platform/wifi/wifi-utils.c
+++ b/src/platform/wifi/wifi-utils.c
@@ -21,16 +21,18 @@
#include "nm-default.h"
+#include "wifi-utils.h"
+
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
-#include "wifi-utils.h"
#include "wifi-utils-private.h"
#include "wifi-utils-nl80211.h"
#if HAVE_WEXT
#include "wifi-utils-wext.h"
#endif
+#include "nm-core-utils.h"
gpointer
wifi_data_new (const char *iface, int ifindex, gsize len)
@@ -162,19 +164,20 @@ wifi_utils_deinit (WifiData *data)
}
gboolean
-wifi_utils_is_wifi (const char *iface, const char *sysfs_path)
+wifi_utils_is_wifi (const char *iface)
{
- char phy80211_path[255];
+ char phy80211_path[NM_STRLEN ("/sys/class/net/123456789012345/phy80211\0") + 100 /*safety*/];
struct stat s;
g_return_val_if_fail (iface != NULL, FALSE);
- if (sysfs_path) {
- /* Check for nl80211 sysfs paths */
- g_snprintf (phy80211_path, sizeof (phy80211_path), "%s/phy80211", sysfs_path);
- if ((stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR)))
- return TRUE;
- }
+ nm_sprintf_buf (phy80211_path,
+ "/sys/class/net/%s/phy80211",
+ NM_ASSERT_VALID_PATH_COMPONENT (iface));
+ nm_assert (strlen (phy80211_path) < sizeof (phy80211_path) - 1);
+
+ if ((stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR)))
+ return TRUE;
#if HAVE_WEXT
if (wifi_wext_is_wifi (iface))
diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h
index 21dac9e9cc..f0a5a7e7f1 100644
--- a/src/platform/wifi/wifi-utils.h
+++ b/src/platform/wifi/wifi-utils.h
@@ -29,7 +29,7 @@
typedef struct WifiData WifiData;
-gboolean wifi_utils_is_wifi (const char *iface, const char *sysfs_path);
+gboolean wifi_utils_is_wifi (const char *iface);
WifiData *wifi_utils_init (const char *iface, int ifindex, gboolean check_scan);
diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c
index 89a7addf84..a51f7cfa6c 100644
--- a/src/ppp-manager/nm-ppp-manager.c
+++ b/src/ppp-manager/nm-ppp-manager.c
@@ -482,7 +482,7 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager,
address.plen = u32;
if (address.address && address.plen && address.plen <= 32) {
- address.source = NM_IP_CONFIG_SOURCE_PPP;
+ address.addr_source = NM_IP_CONFIG_SOURCE_PPP;
nm_ip4_config_add_address (config, &address);
} else {
_LOGE ("invalid IPv4 address received!");
@@ -540,7 +540,7 @@ iid_value_to_ll6_addr (GVariant *dict,
out_addr->s6_addr16[0] = htons (0xfe80);
memcpy (out_addr->s6_addr + 8, &iid, sizeof (iid));
if (out_iid)
- nm_utils_ipv6_interface_identfier_get_from_addr (out_iid, out_addr);
+ nm_utils_ipv6_interface_identifier_get_from_addr (out_iid, out_addr);
return TRUE;
}
@@ -1028,7 +1028,7 @@ nm_ppp_manager_start (NMPPPManager *manager,
NMPPPManagerPrivate *priv;
NMConnection *connection;
NMSettingPpp *s_ppp;
- gboolean s_ppp_created = FALSE;
+ gs_unref_object NMSettingPpp *s_ppp_free = NULL;
NMSettingPppoe *pppoe_setting;
NMSettingAdsl *adsl_setting;
NMCmdLine *ppp_cmd;
@@ -1056,24 +1056,21 @@ nm_ppp_manager_start (NMPPPManager *manager,
nm_utils_modprobe (NULL, FALSE, "ppp_generic", NULL);
connection = nm_act_request_get_applied_connection (req);
- g_assert (connection);
+ g_return_val_if_fail (connection, FALSE);
s_ppp = nm_connection_get_setting_ppp (connection);
if (!s_ppp) {
/* If the PPP settings are all default we may not have a PPP setting yet,
* so just make a default one here.
*/
- s_ppp = NM_SETTING_PPP (nm_setting_ppp_new ());
- s_ppp_created = TRUE;
+ s_ppp = s_ppp_free = NM_SETTING_PPP (nm_setting_ppp_new ());
}
-
+
pppoe_setting = nm_connection_get_setting_pppoe (connection);
if (pppoe_setting) {
/* We can't modify the applied connection's setting, make a copy */
- if (!s_ppp_created) {
- s_ppp = NM_SETTING_PPP (nm_setting_duplicate ((NMSetting *) s_ppp));
- s_ppp_created = TRUE;
- }
+ if (!s_ppp_free)
+ s_ppp = s_ppp_free = NM_SETTING_PPP (nm_setting_duplicate ((NMSetting *) s_ppp));
pppoe_fill_defaults (s_ppp);
}
@@ -1106,9 +1103,6 @@ nm_ppp_manager_start (NMPPPManager *manager,
priv->act_req = g_object_ref (req);
out:
- if (s_ppp_created)
- g_object_unref (s_ppp);
-
if (ppp_cmd)
nm_cmd_line_destroy (ppp_cmd);
diff --git a/src/ppp-manager/nm-pppd-plugin.c b/src/ppp-manager/nm-pppd-plugin.c
index 4c16f1f0f1..9c47c339a3 100644
--- a/src/ppp-manager/nm-pppd-plugin.c
+++ b/src/ppp-manager/nm-pppd-plugin.c
@@ -19,7 +19,7 @@
* Copyright (C) 2008 Red Hat, Inc.
*/
-#include "config.h"
+#include <config.h>
#define ___CONFIG_H__
#include <string.h>
diff --git a/src/rdisc/nm-rdisc.c b/src/rdisc/nm-rdisc.c
index 12e3962b0d..85c803dc79 100644
--- a/src/rdisc/nm-rdisc.c
+++ b/src/rdisc/nm-rdisc.c
@@ -161,7 +161,7 @@ complete_address (NMRDisc *rdisc, NMRDiscAddress *addr)
if (addr->address.s6_addr32[2] == 0x0 && addr->address.s6_addr32[3] == 0x0) {
_LOGD ("complete-address: adding an EUI-64 address");
- nm_utils_ipv6_addr_set_interface_identfier (&addr->address, rdisc->iid);
+ nm_utils_ipv6_addr_set_interface_identifier (&addr->address, rdisc->iid);
return TRUE;
}
diff --git a/src/rdisc/tests/test-rdisc-fake.c b/src/rdisc/tests/test-rdisc-fake.c
index 1c514b9042..dec698d6bf 100644
--- a/src/rdisc/tests/test-rdisc-fake.c
+++ b/src/rdisc/tests/test-rdisc-fake.c
@@ -28,7 +28,7 @@
#include "nm-fake-platform.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
static NMFakeRDisc *
rdisc_new (void)
diff --git a/src/rdisc/tests/test-rdisc-linux.c b/src/rdisc/tests/test-rdisc-linux.c
index e22eb1ade1..c3eadf4eab 100644
--- a/src/rdisc/tests/test-rdisc-linux.c
+++ b/src/rdisc/tests/test-rdisc-linux.c
@@ -28,7 +28,7 @@
#include "nm-linux-platform.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
NMTST_DEFINE ();
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
index 26d1be63cb..ebcf17f888 100644
--- a/src/settings/nm-settings-connection.c
+++ b/src/settings/nm-settings-connection.c
@@ -91,7 +91,7 @@ typedef struct {
NMAgentManager *agent_mgr;
NMSessionMonitor *session_monitor;
- guint session_changed_id;
+ gulong session_changed_id;
NMSettingsConnectionFlags flags;
gboolean ready;
@@ -1527,6 +1527,7 @@ typedef struct {
NMAuthSubject *subject;
NMConnection *new_settings;
gboolean save_to_disk;
+ char *audit_args;
} UpdateInfo;
typedef struct {
@@ -1598,12 +1599,13 @@ update_complete (NMSettingsConnection *self,
else
g_dbus_method_invocation_return_value (info->context, NULL);
- nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, self, !error,
+ nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, self, !error, info->audit_args,
info->subject, error ? error->message : NULL);
g_clear_object (&info->subject);
g_clear_object (&info->agent_mgr);
g_clear_object (&info->new_settings);
+ g_free (info->audit_args);
memset (info, 0, sizeof (*info));
g_free (info);
}
@@ -1635,6 +1637,49 @@ con_update_cb (NMSettingsConnection *self,
update_complete (self, info, error);
}
+static char *
+con_list_changed_props (NMConnection *old, NMConnection *new)
+{
+ gs_unref_hashtable GHashTable *diff = NULL;
+ GHashTable *setting_diff;
+ char *setting_name, *prop_name;
+ GHashTableIter iter, iter2;
+ gboolean same;
+ GString *str;
+
+ same = nm_connection_diff (old, new,
+ NM_SETTING_COMPARE_FLAG_EXACT |
+ NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT,
+ &diff);
+
+ if (same || !diff)
+ return NULL;
+
+ str = g_string_sized_new (32);
+ g_hash_table_iter_init (&iter, diff);
+
+ while (g_hash_table_iter_next (&iter,
+ (gpointer *) &setting_name,
+ (gpointer *) &setting_diff)) {
+ if (!setting_diff)
+ continue;
+
+ g_hash_table_iter_init (&iter2, setting_diff);
+
+ while (g_hash_table_iter_next (&iter2, (gpointer *) &prop_name, NULL)) {
+ g_string_append (str, setting_name);
+ g_string_append_c (str, '.');
+ g_string_append (str, prop_name);
+ g_string_append_c (str, ',');
+ }
+ }
+
+ if (str->len)
+ str->str[str->len - 1] = '\0';
+
+ return g_string_free (str, FALSE);
+}
+
static void
update_auth_cb (NMSettingsConnection *self,
GDBusMethodInvocation *context,
@@ -1664,6 +1709,9 @@ update_auth_cb (NMSettingsConnection *self,
update_agent_secrets_cache (self, info->new_settings);
}
+ if (nm_audit_manager_audit_enabled (nm_audit_manager_get ()))
+ info->audit_args = con_list_changed_props (NM_CONNECTION (self), info->new_settings);
+
if (info->save_to_disk) {
nm_settings_connection_replace_and_commit (self,
info->new_settings,
@@ -1767,7 +1815,7 @@ settings_connection_update_helper (NMSettingsConnection *self,
return;
error:
- nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, self, FALSE, subject,
+ nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, self, FALSE, NULL, subject,
error->message);
g_clear_object (&tmp);
@@ -1816,7 +1864,7 @@ con_delete_cb (NMSettingsConnection *self,
g_dbus_method_invocation_return_value (info->context, NULL);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self,
- !error, info->subject, error ? error->message : NULL);
+ !error, NULL, info->subject, error ? error->message : NULL);
g_free (info);
}
@@ -1830,7 +1878,7 @@ delete_auth_cb (NMSettingsConnection *self,
CallbackInfo *info;
if (error) {
- nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, FALSE, subject,
+ nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, FALSE, NULL, subject,
error->message);
g_dbus_method_invocation_return_gerror (context, error);
return;
@@ -1879,7 +1927,7 @@ impl_settings_connection_delete (NMSettingsConnection *self,
return;
out_err:
- nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, FALSE, subject, error->message);
+ nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, FALSE, NULL, subject, error->message);
g_dbus_method_invocation_take_error (context, error);
}
@@ -1972,7 +2020,7 @@ clear_secrets_cb (NMSettingsConnection *self,
g_dbus_method_invocation_return_value (info->context, NULL);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self,
- !error, info->subject, error ? error->message : NULL);
+ !error, NULL, info->subject, error ? error->message : NULL);
g_free (info);
}
@@ -1989,7 +2037,7 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self,
if (error) {
g_dbus_method_invocation_return_gerror (context, error);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self,
- FALSE, subject, error->message);
+ FALSE, NULL, subject, error->message);
} else {
/* Clear secrets in connection and caches */
nm_connection_clear_secrets (NM_CONNECTION (self));
@@ -2029,7 +2077,7 @@ impl_settings_connection_clear_secrets (NMSettingsConnection *self,
g_object_unref (subject);
} else {
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self,
- FALSE, NULL, error->message);
+ FALSE, NULL, NULL, error->message);
g_dbus_method_invocation_take_error (context, error);
}
}
@@ -2565,7 +2613,9 @@ nm_settings_connection_init (NMSettingsConnection *self)
priv->ready = TRUE;
priv->session_monitor = g_object_ref (nm_session_monitor_get ());
- priv->session_changed_id = nm_session_monitor_connect (priv->session_monitor, session_changed_cb, self);
+ priv->session_changed_id = g_signal_connect (priv->session_monitor,
+ NM_SESSION_MONITOR_CHANGED,
+ G_CALLBACK (session_changed_cb), self);
priv->agent_mgr = g_object_ref (nm_agent_manager_get ());
@@ -2625,11 +2675,9 @@ dispose (GObject *object)
set_visible (self, FALSE);
- if (priv->session_monitor) {
- nm_session_monitor_disconnect (priv->session_monitor, priv->session_changed_id);
- priv->session_changed_id = 0;
- g_clear_object (&priv->session_monitor);
- }
+ nm_clear_g_signal_handler (priv->session_monitor, &priv->session_changed_id);
+ g_clear_object (&priv->session_monitor);
+
g_clear_object (&priv->agent_mgr);
g_clear_pointer (&priv->filename, g_free);
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index 8dd5f2bea5..fab5383c79 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -25,6 +25,8 @@
#include "nm-default.h"
+#include "nm-settings.h"
+
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
@@ -59,7 +61,6 @@
#include "nm-core-internal.h"
#include "nm-device-ethernet.h"
-#include "nm-settings.h"
#include "nm-settings-connection.h"
#include "nm-settings-plugin.h"
#include "nm-bus-manager.h"
@@ -68,7 +69,6 @@
#include "nm-session-monitor.h"
#include "plugins/keyfile/plugin.h"
#include "nm-agent-manager.h"
-#include "nm-connection-provider.h"
#include "nm-config.h"
#include "nm-audit-manager.h"
#include "NetworkManagerUtils.h"
@@ -132,11 +132,11 @@ static void claim_connection (NMSettings *self,
static void unmanaged_specs_changed (NMSettingsPlugin *config, gpointer user_data);
static void unrecognized_specs_changed (NMSettingsPlugin *config, gpointer user_data);
-static void connection_provider_iface_init (NMConnectionProviderInterface *cp_iface);
-
-G_DEFINE_TYPE_EXTENDED (NMSettings, nm_settings, NM_TYPE_EXPORTED_OBJECT, 0,
- G_IMPLEMENT_INTERFACE (NM_TYPE_CONNECTION_PROVIDER, connection_provider_iface_init))
+static void connection_ready_changed (NMSettingsConnection *conn,
+ GParamSpec *pspec,
+ gpointer user_data);
+G_DEFINE_TYPE (NMSettings, nm_settings, NM_TYPE_EXPORTED_OBJECT);
typedef struct {
NMAgentManager *agent_mgr;
@@ -148,9 +148,9 @@ typedef struct {
GSList *plugins;
gboolean connections_loaded;
GHashTable *connections;
+ NMSettingsConnection **connections_cached_list;
GSList *unmanaged_specs;
GSList *unrecognized_specs;
- GSList *get_connections_cache;
gboolean started;
gboolean startup_complete;
@@ -203,6 +203,11 @@ check_startup_complete (NMSettings *self)
return;
}
+ /* the connection_ready_changed signal handler is no longer needed. */
+ g_hash_table_iter_init (&iter, priv->connections);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &conn))
+ g_signal_handlers_disconnect_by_func (conn, G_CALLBACK (connection_ready_changed), self);
+
priv->startup_complete = TRUE;
_notify (self, PROP_STARTUP_COMPLETE);
}
@@ -257,7 +262,7 @@ load_connections (NMSettings *self)
}
priv->connections_loaded = TRUE;
- g_object_notify (G_OBJECT (self), NM_SETTINGS_CONNECTIONS);
+ _notify (self, PROP_CONNECTIONS);
unmanaged_specs_changed (NULL, self);
unrecognized_specs_changed (NULL, self);
@@ -274,7 +279,7 @@ nm_settings_for_each_connection (NMSettings *self,
g_return_if_fail (NM_IS_SETTINGS (self));
g_return_if_fail (for_each_func != NULL);
-
+
priv = NM_SETTINGS_GET_PRIVATE (self);
g_hash_table_iter_init (&iter, priv->connections);
@@ -400,13 +405,60 @@ connection_sort (gconstpointer pa, gconstpointer pb)
return 1;
}
+/**
+ * nm_settings_get_connections:
+ * @self: the #NMSettings
+ * @out_len: (out): (allow-none): returns the number of returned
+ * connections.
+ *
+ * Returns: (transfer-none): a list of NMSettingsConnections. The list is
+ * unsorted and NULL terminated. The result is never %NULL, in case of no
+ * connections, it returns an empty list.
+ * The returned list is cached internally, only valid until the next
+ * NMSettings operation.
+ */
+NMSettingsConnection *const*
+nm_settings_get_connections (NMSettings *self, guint *out_len)
+{
+ GHashTableIter iter;
+ NMSettingsPrivate *priv;
+ guint l, i;
+ NMSettingsConnection **v;
+ NMSettingsConnection *con;
+
+ g_return_val_if_fail (NM_IS_SETTINGS (self), NULL);
+
+ priv = NM_SETTINGS_GET_PRIVATE (self);
+
+ if (priv->connections_cached_list) {
+ NM_SET_OUT (out_len, g_hash_table_size (priv->connections));
+ return priv->connections_cached_list;
+ }
+
+ l = g_hash_table_size (priv->connections);
+
+ v = g_new (NMSettingsConnection *, l + 1);
+
+ i = 0;
+ g_hash_table_iter_init (&iter, priv->connections);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &con))
+ v[i++] = con;
+ v[i] = NULL;
+
+ nm_assert (i == l);
+
+ NM_SET_OUT (out_len, l);
+ priv->connections_cached_list = v;
+ return v;
+}
+
/* Returns a list of NMSettingsConnections.
* The list is sorted in the order suitable for auto-connecting, i.e.
* first go connections with autoconnect=yes and most recent timestamp.
* Caller must free the list with g_slist_free().
*/
GSList *
-nm_settings_get_connections (NMSettings *self)
+nm_settings_get_connections_sorted (NMSettings *self)
{
GHashTableIter iter;
gpointer data = NULL;
@@ -885,7 +937,6 @@ connection_updated (NMSettingsConnection *connection, gboolean by_user, gpointer
0,
connection,
by_user);
- g_signal_emit_by_name (NM_SETTINGS (user_data), NM_CP_SIGNAL_CONNECTION_UPDATED, connection);
}
static void
@@ -919,17 +970,18 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data)
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_removed), self);
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_updated), self);
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_visibility_changed), self);
- g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_ready_changed), self);
+ if (!priv->startup_complete)
+ g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_ready_changed), self);
g_object_unref (self);
/* Forget about the connection internally */
g_hash_table_remove (priv->connections, (gpointer) cpath);
+ g_clear_pointer (&priv->connections_cached_list, g_free);
/* Notify D-Bus */
g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connection);
/* Re-emit for listeners like NMPolicy */
- g_signal_emit_by_name (self, NM_CP_SIGNAL_CONNECTION_REMOVED, connection);
_notify (self, PROP_CONNECTIONS);
if (nm_exported_object_is_exported (NM_EXPORTED_OBJECT (connection)))
nm_exported_object_unexport (NM_EXPORTED_OBJECT (connection));
@@ -1068,6 +1120,7 @@ claim_connection (NMSettings *self, NMSettingsConnection *connection)
g_hash_table_insert (priv->connections,
(gpointer) nm_connection_get_path (NM_CONNECTION (connection)),
g_object_ref (connection));
+ g_clear_pointer (&priv->connections_cached_list, g_free);
nm_utils_log_connection_diff (NM_CONNECTION (connection), NULL, LOGL_DEBUG, LOGD_CORE, "new connection", "++ ");
@@ -1077,7 +1130,6 @@ claim_connection (NMSettings *self, NMSettingsConnection *connection)
if (priv->connections_loaded) {
/* Internal added signal */
g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection);
- g_signal_emit_by_name (self, NM_CP_SIGNAL_CONNECTION_ADDED, connection);
_notify (self, PROP_CONNECTIONS);
/* Exported D-Bus signal */
@@ -1153,16 +1205,6 @@ nm_settings_add_connection (NMSettings *self,
return NULL;
}
-static NMConnection *
-_nm_connection_provider_add_connection (NMConnectionProvider *provider,
- NMConnection *connection,
- gboolean save_to_disk,
- GError **error)
-{
- g_assert (NM_IS_CONNECTION_PROVIDER (provider) && NM_IS_SETTINGS (provider));
- return NM_CONNECTION (nm_settings_add_connection (NM_SETTINGS (provider), connection, save_to_disk, error));
-}
-
static gboolean
secrets_filter_cb (NMSetting *setting,
const char *secret,
@@ -1410,12 +1452,12 @@ impl_settings_add_connection_add_cb (NMSettings *self,
{
if (error) {
g_dbus_method_invocation_return_gerror (context, error);
- nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, NULL, FALSE, subject, error->message);
+ nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, NULL, FALSE, NULL, subject, error->message);
} else {
g_dbus_method_invocation_return_value (
context,
g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (connection))));
- nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, connection, TRUE,
+ nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, connection, TRUE, NULL,
subject, NULL);
}
}
@@ -2070,22 +2112,41 @@ nm_settings_sort_connections (gconstpointer a, gconstpointer b)
return 0;
}
-static GSList *
-get_best_connections (NMConnectionProvider *provider,
- guint max_requested,
- const char *ctype1,
- const char *ctype2,
- NMConnectionFilterFunc func,
- gpointer func_data)
+/**
+ * nm_settings_get_best_connections:
+ * @self: the #NMSetting
+ * @max_requested: if non-zero, the maximum number of connections to return
+ * @ctype1: an #NMSetting base type (eg NM_SETTING_WIRELESS_SETTING_NAME) to
+ * filter connections against
+ * @ctype2: a second #NMSetting base type (eg NM_SETTING_WIRELESS_SETTING_NAME)
+ * to filter connections against
+ * @func: caller-supplied function for filtering connections
+ * @func_data: caller-supplied data passed to @func
+ *
+ * Returns: a #GSList of #NMConnection objects in sorted order representing the
+ * "best" or highest-priority connections filtered by @ctype1 and/or @ctype2,
+ * and/or @func. Caller is responsible for freeing the returned #GSList, but
+ * the contained values do not need to be unreffed.
+ */
+GSList *
+nm_settings_get_best_connections (NMSettings *self,
+ guint max_requested,
+ const char *ctype1,
+ const char *ctype2,
+ NMConnectionFilterFunc func,
+ gpointer func_data)
{
- NMSettings *self = NM_SETTINGS (provider);
- NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ NMSettingsPrivate *priv;
GSList *sorted = NULL;
GHashTableIter iter;
NMSettingsConnection *connection;
guint added = 0;
guint64 oldest = 0;
+ g_return_val_if_fail (NM_IS_SETTINGS (self), NULL);
+
+ priv = NM_SETTINGS_GET_PRIVATE (self);
+
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection)) {
guint64 cur_ts = 0;
@@ -2094,7 +2155,7 @@ get_best_connections (NMConnectionProvider *provider,
continue;
if (ctype2 && !nm_connection_is_type (NM_CONNECTION (connection), ctype2))
continue;
- if (func && !func (provider, NM_CONNECTION (connection), func_data))
+ if (func && !func (self, NM_CONNECTION (connection), func_data))
continue;
/* Don't bother with a connection that's older than the oldest one in the list */
@@ -2120,27 +2181,6 @@ get_best_connections (NMConnectionProvider *provider,
return g_slist_reverse (sorted);
}
-static const GSList *
-get_connections (NMConnectionProvider *provider)
-{
- GSList *list = NULL;
- NMSettings *self = NM_SETTINGS (provider);
- NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
-
- list = _nm_utils_hash_values_to_slist (priv->connections);
-
- /* Cache the list every call so we can keep it 'const' for callers */
- g_slist_free (priv->get_connections_cache);
- priv->get_connections_cache = list;
- return list;
-}
-
-static NMConnection *
-cp_get_connection_by_uuid (NMConnectionProvider *provider, const char *uuid)
-{
- return NM_CONNECTION (nm_settings_get_connection_by_uuid (NM_SETTINGS (provider), uuid));
-}
-
/***************************************************************/
gboolean
@@ -2189,14 +2229,30 @@ setup_hostname_file_monitors (NMSettings *self)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GFileMonitor *monitor;
+ const char *path = HOSTNAME_FILE;
+ char *link_path = NULL;
+ struct stat file_stat;
GFile *file;
priv->hostname.value = nm_settings_get_hostname (self);
+ /* resolve the path to the hostname file if it is a symbolic link */
+ if ( lstat(path, &file_stat) == 0
+ && S_ISLNK (file_stat.st_mode)
+ && (link_path = nm_utils_read_link_absolute (path, NULL))) {
+ path = link_path;
+ if ( lstat(link_path, &file_stat) == 0
+ && S_ISLNK (file_stat.st_mode)) {
+ _LOGW ("only one level of symbolic link indirection is allowed when monitoring "
+ HOSTNAME_FILE);
+ }
+ }
+
/* monitor changes to hostname file */
- file = g_file_new_for_path (HOSTNAME_FILE);
+ file = g_file_new_for_path (path);
monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
g_object_unref (file);
+ g_free(link_path);
if (monitor) {
priv->hostname.monitor_id = g_signal_connect (monitor, "changed",
G_CALLBACK (hostname_file_changed_cb),
@@ -2286,15 +2342,6 @@ nm_settings_start (NMSettings *self, GError **error)
}
static void
-connection_provider_iface_init (NMConnectionProviderInterface *cp_iface)
-{
- cp_iface->get_best_connections = get_best_connections;
- cp_iface->get_connections = get_connections;
- cp_iface->add_connection = _nm_connection_provider_add_connection;
- cp_iface->get_connection_by_uuid = cp_get_connection_by_uuid;
-}
-
-static void
nm_settings_init (NMSettings *self)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
@@ -2358,7 +2405,7 @@ finalize (GObject *object)
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
g_hash_table_destroy (priv->connections);
- g_slist_free (priv->get_connections_cache);
+ g_clear_pointer (&priv->connections_cached_list, g_free);
g_slist_free_full (priv->unmanaged_specs, g_free);
g_slist_free_full (priv->unrecognized_specs, g_free);
diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h
index 5d41e5bc92..a0be42eef3 100644
--- a/src/settings/nm-settings.h
+++ b/src/settings/nm-settings.h
@@ -49,6 +49,18 @@
#define NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED "connection-visibility-changed"
#define NM_SETTINGS_SIGNAL_AGENT_REGISTERED "agent-registered"
+/**
+ * NMConnectionFilterFunc:
+ * @settings: The #NMSettings requesting the filtering
+ * @connection: the connection to be filtered
+ * @func_data: the caller-provided data pointer
+ *
+ * Returns: %TRUE to allow the connection, %FALSE to ignore it
+ */
+typedef gboolean (*NMConnectionFilterFunc) (NMSettings *settings,
+ NMConnection *connection,
+ gpointer func_data);
+
struct _NMSettings {
NMExportedObject parent_instance;
};
@@ -61,6 +73,9 @@ typedef void (*NMSettingsSetHostnameCb) (const char *name, gboolean result, gpoi
GType nm_settings_get_type (void);
+NMSettings *nm_settings_get (void);
+#define NM_SETTINGS_GET (nm_settings_get ())
+
NMSettings *nm_settings_new (void);
gboolean nm_settings_start (NMSettings *self, GError **error);
@@ -86,10 +101,16 @@ void nm_settings_add_connection_dbus (NMSettings *self,
NMSettingsAddCallback callback,
gpointer user_data);
-/* Returns a list of NMSettingsConnections. Caller must free the list with
- * g_slist_free().
- */
-GSList *nm_settings_get_connections (NMSettings *settings);
+NMSettingsConnection *const* nm_settings_get_connections (NMSettings *settings, guint *out_len);
+
+GSList *nm_settings_get_connections_sorted (NMSettings *settings);
+
+GSList *nm_settings_get_best_connections (NMSettings *self,
+ guint max_requested,
+ const char *ctype1,
+ const char *ctype2,
+ NMConnectionFilterFunc func,
+ gpointer func_data);
NMSettingsConnection *nm_settings_add_connection (NMSettings *settings,
NMConnection *connection,
diff --git a/src/settings/plugins/ibft/tests/test-ibft.c b/src/settings/plugins/ibft/tests/test-ibft.c
index 9c98d8912c..cab468dec9 100644
--- a/src/settings/plugins/ibft/tests/test-ibft.c
+++ b/src/settings/plugins/ibft/tests/test-ibft.c
@@ -34,7 +34,7 @@
#include "reader.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
static GPtrArray *
read_block (const char *iscsiadm_path, const char *expected_mac)
diff --git a/src/settings/plugins/ifcfg-rh/common.h b/src/settings/plugins/ifcfg-rh/common.h
index 5d6ebe6d65..d850ac4e75 100644
--- a/src/settings/plugins/ifcfg-rh/common.h
+++ b/src/settings/plugins/ifcfg-rh/common.h
@@ -21,8 +21,6 @@
#ifndef __COMMON_H__
#define __COMMON_H__
-#include "nm-default.h"
-
#define IFCFG_TAG "ifcfg-"
#define KEYS_TAG "keys-"
#define ROUTE_TAG "route-"
@@ -38,7 +36,7 @@
#define AUGNEW_TAG ".augnew"
#define AUGTMP_TAG ".augtmp"
-#define IFCFG_DIR SYSCONFDIR"/sysconfig/network-scripts"
+#define IFCFG_DIR SYSCONFDIR "/sysconfig/network-scripts"
#define IFCFG_PLUGIN_NAME "ifcfg-rh"
#define IFCFG_PLUGIN_INFO "(c) 2007 - 2015 Red Hat, Inc. To report bugs please use the NetworkManager mailing list."
diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c
index b9bbf6d5b0..3efd99a4c5 100644
--- a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c
+++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c
@@ -20,6 +20,8 @@
#include "nm-default.h"
+#include "nm-ifcfg-connection.h"
+
#include <string.h>
#include <glib/gstdio.h>
@@ -37,7 +39,6 @@
#include "common.h"
#include "nm-config.h"
-#include "nm-ifcfg-connection.h"
#include "reader.h"
#include "writer.h"
#include "nm-inotify-helper.h"
diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h
index 44e0298772..57db059b00 100644
--- a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h
+++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h
@@ -21,10 +21,8 @@
#ifndef __NETWORKMANAGER_IFCFG_CONNECTION_H__
#define __NETWORKMANAGER_IFCFG_CONNECTION_H__
-G_BEGIN_DECLS
-
-#include <nm-dbus-interface.h>
-#include <nm-settings-connection.h>
+#include "nm-dbus-interface.h"
+#include "nm-settings-connection.h"
#define NM_TYPE_IFCFG_CONNECTION (nm_ifcfg_connection_get_type ())
#define NM_IFCFG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnection))
@@ -58,6 +56,4 @@ gboolean nm_ifcfg_connection_update (NMIfcfgConnection *self,
GHashTable *new_settings,
GError **error);
-G_END_DECLS
-
#endif /* __NETWORKMANAGER_IFCFG_CONNECTION_H__ */
diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c
index 1fb6b78947..1c0ce918b1 100644
--- a/src/settings/plugins/ifcfg-rh/plugin.c
+++ b/src/settings/plugins/ifcfg-rh/plugin.c
@@ -23,6 +23,8 @@
#include "nm-default.h"
+#include "plugin.h"
+
#include <string.h>
#include <unistd.h>
#include <errno.h>
@@ -31,20 +33,19 @@
#include <gmodule.h>
+#include "nm-dbus-compat.h"
#include "nm-setting-connection.h"
-#include "common.h"
-#include "plugin.h"
#include "nm-settings-plugin.h"
#include "nm-config.h"
#include "NetworkManagerUtils.h"
#include "nm-ifcfg-connection.h"
#include "shvar.h"
+#include "common.h"
#include "reader.h"
#include "writer.h"
#include "utils.h"
-#include "nm-dbus-compat.h"
#include "nm-exported-object.h"
#include "nmdbus-ifcfg-rh.h"
@@ -61,8 +62,6 @@
_NM_UTILS_MACRO_REST(__VA_ARGS__)); \
} G_STMT_END
-#define ERR_GET_MSG(err) (((err) && (err)->message) ? (err)->message : "(unknown)")
-
static NMIfcfgConnection *update_connection (SettingsPluginIfcfg *plugin,
NMConnection *source,
diff --git a/src/settings/plugins/ifcfg-rh/plugin.h b/src/settings/plugins/ifcfg-rh/plugin.h
index eba734cff8..74c4b00a04 100644
--- a/src/settings/plugins/ifcfg-rh/plugin.h
+++ b/src/settings/plugins/ifcfg-rh/plugin.h
@@ -24,8 +24,6 @@
#ifndef _PLUGIN_H_
#define _PLUGIN_H_
-#include "nm-exported-object.h"
-
#define SETTINGS_TYPE_PLUGIN_IFCFG (settings_plugin_ifcfg_get_type ())
#define SETTINGS_PLUGIN_IFCFG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SETTINGS_TYPE_PLUGIN_IFCFG, SettingsPluginIfcfg))
#define SETTINGS_PLUGIN_IFCFG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SETTINGS_TYPE_PLUGIN_IFCFG, SettingsPluginIfcfgClass))
@@ -46,5 +44,5 @@ struct _SettingsPluginIfcfgClass {
GType settings_plugin_ifcfg_get_type (void);
-#endif /* _PLUGIN_H_ */
+#endif /* _PLUGIN_H_ */
diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c
index 39e981f959..b933e1a5fa 100644
--- a/src/settings/plugins/ifcfg-rh/reader.c
+++ b/src/settings/plugins/ifcfg-rh/reader.c
@@ -20,6 +20,8 @@
#include "nm-default.h"
+#include "reader.h"
+
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
@@ -57,35 +59,31 @@
#include "shvar.h"
#include "utils.h"
-#include "reader.h"
+/*****************************************************************************/
-#define PARSE_WARNING(msg...) nm_log_warn (LOGD_SETTINGS, " " msg)
+#define _NMLOG_DOMAIN LOGD_SETTINGS
+#define _NMLOG_PREFIX_NAME "ifcfg-rh"
+#define _NMLOG(level, ...) \
+ G_STMT_START { \
+ nm_log ((level), (_NMLOG_DOMAIN), \
+ "%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
+ _NMLOG_PREFIX_NAME": " \
+ _NM_UTILS_MACRO_REST(__VA_ARGS__)); \
+ } G_STMT_END
-static gboolean
-get_int (const char *str, int *value)
-{
- char *e;
- long int tmp;
+#define PARSE_WARNING(...) _LOGW ("%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), " " _NM_UTILS_MACRO_REST(__VA_ARGS__))
- errno = 0;
- tmp = strtol (str, &e, 0);
- if (errno || *e != '\0' || tmp > G_MAXINT || tmp < G_MININT)
- return FALSE;
- *value = (int) tmp;
- return TRUE;
-}
+/*****************************************************************************/
static gboolean
get_uint (const char *str, guint32 *value)
{
- char *e;
- long unsigned int tmp;
+ gint64 tmp;
- errno = 0;
- tmp = strtoul (str, &e, 0);
- if (errno || *e != '\0')
+ tmp = _nm_utils_ascii_str_to_int64 (str, 0, 0, G_MAXUINT32, -1);
+ if (tmp == -1)
return FALSE;
- *value = (guint32) tmp;
+ *value = tmp;
return TRUE;
}
@@ -242,15 +240,12 @@ make_connection_setting (const char *file,
value = svGetValue (ifcfg, "GATEWAY_PING_TIMEOUT", FALSE);
if (value) {
- long int tmp;
- guint32 timeout;
+ gint64 tmp;
- errno = 0;
- tmp = strtol (value, NULL, 10);
- if (errno == 0 && tmp >= 0 && tmp < G_MAXINT32) {
- timeout = (guint32) tmp;
- g_object_set (s_con, NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, timeout, NULL);
- } else
+ tmp = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXINT32 - 1, -1);
+ if (tmp >= 0)
+ g_object_set (s_con, NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, (guint) tmp, NULL);
+ else
PARSE_WARNING ("invalid GATEWAY_PING_TIMEOUT time");
g_free (value);
}
@@ -541,7 +536,8 @@ read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError *
char **lines = NULL, **iter;
GRegex *regex_to1, *regex_to2, *regex_via, *regex_metric;
GMatchInfo *match_info;
- gint64 prefix_int, metric_int;
+ int prefix_int;
+ gint64 metric_int;
gboolean success = FALSE;
const char *pattern_empty = "^\\s*(\\#.*)?$";
@@ -609,9 +605,8 @@ read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError *
g_match_info_free (match_info);
prefix_int = 32;
if (prefix) {
- errno = 0;
- prefix_int = strtol (prefix, NULL, 10);
- if (errno || prefix_int <= 0 || prefix_int > 32) {
+ prefix_int = _nm_utils_ascii_str_to_int64 (prefix, 10, 1, 32, -1);
+ if (prefix_int == -1) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid IP4 route destination prefix '%s'", prefix);
g_free (prefix);
@@ -641,9 +636,8 @@ read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError *
metric_int = -1;
if (g_match_info_matches (match_info)) {
metric = g_match_info_fetch (match_info, 1);
- errno = 0;
- metric_int = strtol (metric, NULL, 10);
- if (errno || metric_int < 0) {
+ metric_int = _nm_utils_ascii_str_to_int64 (metric, 10, 0, G_MAXUINT32, -1);
+ if (metric_int == -1) {
g_match_info_free (match_info);
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid IP4 route metric '%s'", metric);
@@ -766,7 +760,8 @@ read_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **error
GRegex *regex_to1, *regex_to2, *regex_via, *regex_metric;
GMatchInfo *match_info;
char *dest = NULL, *prefix = NULL, *next_hop = NULL, *metric = NULL;
- gint64 prefix_int, metric_int;
+ int prefix_int;
+ gint64 metric_int;
gboolean success = FALSE;
const char *pattern_empty = "^\\s*(\\#.*)?$";
@@ -828,9 +823,8 @@ read_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **error
g_match_info_free (match_info);
prefix_int = 128;
if (prefix) {
- errno = 0;
- prefix_int = strtol (prefix, NULL, 10);
- if (errno || prefix_int <= 0 || prefix_int > 128) {
+ prefix_int = _nm_utils_ascii_str_to_int64 (prefix, 10, 1, 128, -1);
+ if (prefix_int == -1) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid IP6 route destination prefix '%s'", prefix);
g_free (dest);
@@ -864,9 +858,8 @@ read_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **error
metric_int = -1;
if (g_match_info_matches (match_info)) {
metric = g_match_info_fetch (match_info, 1);
- errno = 0;
- metric_int = strtol (metric, NULL, 10);
- if (errno || metric_int < 0 || metric_int > G_MAXUINT32) {
+ metric_int = _nm_utils_ascii_str_to_int64 (metric, 10, 0, G_MAXUINT32, -1);
+ if (metric_int == -1) {
g_match_info_free (match_info);
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid IP6 route metric '%s'", metric);
@@ -919,6 +912,7 @@ make_ip4_setting (shvarFile *ifcfg,
shvarFile *route_ifcfg;
gboolean never_default = FALSE;
gint64 timeout;
+ gint priority;
s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new ();
@@ -984,6 +978,8 @@ make_ip4_setting (shvarFile *ifcfg,
goto done;
(void) nm_setting_ip_config_add_address (s_ip4, addr);
nm_ip_address_unref (addr);
+ if (never_default)
+ PARSE_WARNING ("GATEWAY will be ignored when DEFROUTE is disabled");
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway, NULL);
}
return NM_SETTING (s_ip4);
@@ -1082,6 +1078,9 @@ make_ip4_setting (shvarFile *ifcfg,
}
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway, NULL);
+ if (gateway && never_default)
+ PARSE_WARNING ("GATEWAY will be ignored when DEFROUTE is disabled");
+
/* DNS servers
* Pick up just IPv4 addresses (IPv6 addresses are taken by make_ip6_setting())
*/
@@ -1136,6 +1135,13 @@ make_ip4_setting (shvarFile *ifcfg,
g_free (dns_options);
dns_options = NULL;
+ /* DNS priority */
+ priority = svGetValueInt64 (ifcfg, "IPV4_DNS_PRIORITY", 10, G_MININT32, G_MAXINT32, 0);
+ g_object_set (s_ip4,
+ NM_SETTING_IP_CONFIG_DNS_PRIORITY,
+ priority,
+ NULL);
+
/* Static routes - route-<name> file */
route_path = utils_get_route_path (ifcfg->fileName);
@@ -1318,6 +1324,7 @@ make_ip6_setting (shvarFile *ifcfg,
char *ipv6addr, *ipv6addr_secondaries;
char **list = NULL, **iter;
guint32 i;
+ gint priority;
shvarFile *network_ifcfg;
gboolean never_default = FALSE;
gboolean ip6_privacy = FALSE, ip6_privacy_prefer_public_ip;
@@ -1520,6 +1527,13 @@ make_ip6_setting (shvarFile *ifcfg,
NULL);
}
+ /* IPv6 tokenized interface identifier */
+ tmp = svGetValue (ifcfg, "IPV6_TOKEN", FALSE);
+ if (tmp) {
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_TOKEN, tmp, NULL);
+ g_free (tmp);
+ }
+
/* DNS servers
* Pick up just IPv6 addresses (IPv4 addresses are taken by make_ip4_setting())
*/
@@ -1567,6 +1581,13 @@ make_ip6_setting (shvarFile *ifcfg,
g_free (value);
g_free (dns_options);
+ /* DNS priority */
+ priority = svGetValueInt64 (ifcfg, "IPV6_DNS_PRIORITY", 10, G_MININT32, G_MAXINT32, 0);
+ g_object_set (s_ip6,
+ NM_SETTING_IP_CONFIG_DNS_PRIORITY,
+ priority,
+ NULL);
+
return NM_SETTING (s_ip6);
error:
@@ -1676,10 +1697,9 @@ read_dcb_app (shvarFile *ifcfg,
tmp = g_strdup_printf ("DCB_APP_%s_PRIORITY", app);
val = svGetValue (ifcfg, tmp, FALSE);
if (val) {
- success = get_int (val, &priority);
- if (success)
- success = (priority >= 0 && priority <= 7);
- if (!success) {
+ priority = _nm_utils_ascii_str_to_int64 (val, 0, 0, 7, -1);
+ if (priority < 0) {
+ success = FALSE;
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid %s value '%s' (expected 0 - 7)",
tmp, val);
@@ -1819,7 +1839,6 @@ read_dcb_percent_array (shvarFile *ifcfg,
char *val;
gboolean success = FALSE;
char **split = NULL, **iter;
- int tmp;
guint i, sum = 0;
val = svGetValue (ifcfg, prop, FALSE);
@@ -1842,7 +1861,10 @@ read_dcb_percent_array (shvarFile *ifcfg,
}
for (iter = split, i = 0; iter && *iter; iter++, i++) {
- if (!get_int (*iter, &tmp) || tmp < 0 || tmp > 100) {
+ int tmp;
+
+ tmp = _nm_utils_ascii_str_to_int64 (*iter, 0, 0, 100, -1);
+ if (tmp < 0) {
PARSE_WARNING ("invalid %s percentage value '%s'", prop, *iter);
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"invalid percent element");
@@ -2164,7 +2186,7 @@ make_wep_setting (shvarFile *ifcfg,
char *value;
shvarFile *keys_ifcfg = NULL;
int default_key_idx = 0;
- gboolean has_default_key = FALSE, success;
+ gboolean has_default_key = FALSE;
NMSettingSecretFlags key_flags;
s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
@@ -2172,18 +2194,17 @@ make_wep_setting (shvarFile *ifcfg,
value = svGetValue (ifcfg, "DEFAULTKEY", FALSE);
if (value) {
- success = get_int (value, &default_key_idx);
- if (success && (default_key_idx >= 1) && (default_key_idx <= 4)) {
- has_default_key = TRUE;
- default_key_idx--; /* convert to [0...3] */
- g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, default_key_idx, NULL);
- } else {
+ default_key_idx = _nm_utils_ascii_str_to_int64 (value, 0, 1, 4, 0);
+ if (default_key_idx == 0) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid default WEP key '%s'", value);
- g_free (value);
+ g_free (value);
goto error;
}
- g_free (value);
+ has_default_key = TRUE;
+ default_key_idx--; /* convert to [0...3] */
+ g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, (guint) default_key_idx, NULL);
+ g_free (value);
}
/* Read WEP key flags */
@@ -3484,17 +3505,16 @@ make_wireless_setting (shvarFile *ifcfg,
value = svGetValue (ifcfg, "MTU", FALSE);
if (value) {
- long int mtu;
+ int mtu;
- errno = 0;
- mtu = strtol (value, NULL, 10);
- if (errno || mtu < 0 || mtu > 50000) {
+ mtu = _nm_utils_ascii_str_to_int64 (value, 10, 0, 50000, -1);
+ if (mtu == -1) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid wireless MTU '%s'", value);
g_free (value);
goto error;
}
- g_object_set (s_wireless, NM_SETTING_WIRELESS_MTU, (guint32) mtu, NULL);
+ g_object_set (s_wireless, NM_SETTING_WIRELESS_MTU, (guint) mtu, NULL);
g_free (value);
}
@@ -3756,20 +3776,19 @@ make_wired_setting (shvarFile *ifcfg,
{
NMSettingWired *s_wired;
char *value = NULL;
- int mtu;
char *nettype;
s_wired = NM_SETTING_WIRED (nm_setting_wired_new ());
value = svGetValue (ifcfg, "MTU", FALSE);
if (value) {
- if (get_int (value, &mtu)) {
- if (mtu >= 0 && mtu < 65536)
- g_object_set (s_wired, NM_SETTING_WIRED_MTU, mtu, NULL);
- } else {
- /* Shouldn't be fatal... */
+ int mtu;
+
+ mtu = _nm_utils_ascii_str_to_int64 (value, 0, 0, 65535, -1);
+ if (mtu >= 0)
+ g_object_set (s_wired, NM_SETTING_WIRED_MTU, (guint) mtu, NULL);
+ else
PARSE_WARNING ("invalid MTU '%s'", value);
- }
g_free (value);
}
@@ -3940,9 +3959,9 @@ parse_infiniband_p_key (shvarFile *ifcfg,
char **out_parent,
GError **error)
{
- char *device = NULL, *physdev = NULL, *pkey_id = NULL, *end;
+ char *device = NULL, *physdev = NULL, *pkey_id = NULL;
char *ifname = NULL;
- guint32 id = G_MAXUINT32;
+ int id;
gboolean ret = FALSE;
device = svGetValue (ifcfg, "DEVICE", FALSE);
@@ -3963,19 +3982,14 @@ parse_infiniband_p_key (shvarFile *ifcfg,
goto done;
}
- if (g_str_has_prefix (pkey_id, "0x"))
- id = strtoul (pkey_id, &end, 16);
- else if (!g_str_has_prefix (pkey_id, "0"))
- id = strtoul (pkey_id, &end, 10);
- else
- end = pkey_id;
- if (end == pkey_id || *end || id > 0xFFFF) {
+ id = _nm_utils_ascii_str_to_int64 (pkey_id, 0, 0, 0xFFFF, -1);
+ if (id == -1) {
PARSE_WARNING ("invalid InfiniBand PKEY_ID '%s'", pkey_id);
goto done;
}
id = (id | 0x8000);
- ifname = g_strdup_printf ("%s.%04x", physdev, id);
+ ifname = g_strdup_printf ("%s.%04x", physdev, (unsigned) id);
if (strcmp (device, ifname) != 0) {
PARSE_WARNING ("InfiniBand DEVICE (%s) does not match PHYSDEV+PKEY_ID (%s)",
device, ifname);
@@ -4007,19 +4021,18 @@ make_infiniband_setting (shvarFile *ifcfg,
{
NMSettingInfiniband *s_infiniband;
char *value = NULL;
- int mtu;
s_infiniband = NM_SETTING_INFINIBAND (nm_setting_infiniband_new ());
value = svGetValue (ifcfg, "MTU", FALSE);
if (value) {
- if (get_int (value, &mtu)) {
- if (mtu >= 0 && mtu < 65536)
- g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MTU, mtu, NULL);
- } else {
- /* Shouldn't be fatal... */
+ int mtu;
+
+ mtu = _nm_utils_ascii_str_to_int64 (value, 0, 0, 65535, -1);
+ if (mtu >= 0)
+ g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MTU, (guint) mtu, NULL);
+ else
PARSE_WARNING ("invalid MTU '%s'", value);
- }
g_free (value);
}
@@ -4643,16 +4656,14 @@ make_vlan_setting (shvarFile *ifcfg,
char *iface_name = NULL;
char *parent = NULL;
const char *p = NULL;
- char *end = NULL;
- gint vlan_id = -1;
+ int vlan_id = -1;
guint32 vlan_flags = 0;
gint gvrp, reorder_hdr;
value = svGetValue (ifcfg, "VLAN_ID", FALSE);
if (value) {
- errno = 0;
- vlan_id = (gint) g_ascii_strtoll (value, NULL, 10);
- if (vlan_id < 0 || vlan_id > 4096 || errno) {
+ vlan_id = _nm_utils_ascii_str_to_int64 (value, 10, 0, 4095, -1);
+ if (vlan_id == -1) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid VLAN_ID '%s'", value);
g_free (value);
@@ -4696,12 +4707,13 @@ make_vlan_setting (shvarFile *ifcfg,
}
if (p) {
+ int device_vlan_id;
+
/* Grab VLAN ID from interface name; this takes precedence over the
* separate VLAN_ID property for backwards compat.
*/
-
- gint device_vlan_id = (gint) g_ascii_strtoll (p, &end, 10);
- if (device_vlan_id >= 0 && device_vlan_id <= 4095 && end != p && !*end)
+ device_vlan_id = _nm_utils_ascii_str_to_int64 (p, 10, 0, 4095, -1);
+ if (device_vlan_id != -1)
vlan_id = device_vlan_id;
}
}
diff --git a/src/settings/plugins/ifcfg-rh/reader.h b/src/settings/plugins/ifcfg-rh/reader.h
index 88f9a72007..35464474f2 100644
--- a/src/settings/plugins/ifcfg-rh/reader.h
+++ b/src/settings/plugins/ifcfg-rh/reader.h
@@ -21,10 +21,7 @@
#ifndef __READER_H__
#define __READER_H__
-#include <nm-connection.h>
-
-#include "nm-default.h"
-#include "shvar.h"
+#include "nm-connection.h"
NMConnection *connection_from_file (const char *filename,
char **out_unhandled,
diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c
index 4e756349ca..75b19d5383 100644
--- a/src/settings/plugins/ifcfg-rh/shvar.c
+++ b/src/settings/plugins/ifcfg-rh/shvar.c
@@ -25,6 +25,8 @@
#include "nm-default.h"
+#include "shvar.h"
+
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
@@ -34,12 +36,8 @@
#include <sys/stat.h>
#include <unistd.h>
-#include "shvar.h"
-
#include "nm-core-internal.h"
-#define PARSE_WARNING(msg...) nm_log_warn (LOGD_SETTINGS, " " msg)
-
/* Open the file <name>, returning a shvarFile on success and NULL on failure.
* Add a wrinkle to let the caller specify whether or not to create the file
* (actually, return a structure anyway) if it doesn't exist.
@@ -273,26 +271,23 @@ svGetValueFull (shvarFile *s, const char *key, gboolean verbatim)
{
char *value = NULL;
char *line;
- char *keyString;
- int len;
+ guint len;
g_return_val_if_fail (s != NULL, NULL);
g_return_val_if_fail (key != NULL, NULL);
- keyString = g_strdup_printf ("%s=", key);
- len = strlen (keyString);
+ len = strlen (key);
for (s->current = s->lineList; s->current; s->current = s->current->next) {
line = s->current->data;
- if (!strncmp (keyString, line, len)) {
+ if (!strncmp (key, line, len) && line[len] == '=') {
/* Strip trailing spaces before unescaping to preserve spaces quoted whitespace */
- value = g_strchomp (g_strdup (line + len));
+ value = g_strchomp (g_strdup (line + len + 1));
if (!verbatim)
svUnescape (value);
break;
}
}
- g_free (keyString);
return value;
}
@@ -373,11 +368,10 @@ svGetValueInt64 (shvarFile *s, const char *key, guint base, gint64 min, gint64 m
result = _nm_utils_ascii_str_to_int64 (tmp, base, min, max, fallback);
errsv = errno;
- if (errsv != 0)
- PARSE_WARNING ("Error reading '%s' value '%s' as integer (%d)", key, tmp, errsv);
g_free (tmp);
+ errno = errsv;
return result;
}
diff --git a/src/settings/plugins/ifcfg-rh/shvar.h b/src/settings/plugins/ifcfg-rh/shvar.h
index 227a44db17..97df81284a 100644
--- a/src/settings/plugins/ifcfg-rh/shvar.h
+++ b/src/settings/plugins/ifcfg-rh/shvar.h
@@ -31,10 +31,6 @@
#ifndef _SHVAR_H
#define _SHVAR_H
-#include "nm-default.h"
-
-G_BEGIN_DECLS
-
typedef struct _shvarFile shvarFile;
struct _shvarFile {
char *fileName; /* read-only */
@@ -95,6 +91,4 @@ const char *svEscape (const char *s, char **to_free);
/* Unescape a string in-place */
void svUnescape (char *s);
-G_END_DECLS
-
-#endif /* ! _SHVAR_H */
+#endif /* _SHVAR_H */
diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c
index 5a0f6451a4..d2a348bb8b 100644
--- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c
+++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c
@@ -28,7 +28,7 @@
#include "common.h"
#include "utils.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
static void
test_get_ifcfg_name (const char *desc,
diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
index 5ed25fda10..c7e741f996 100644
--- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
+++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
@@ -55,7 +55,7 @@
#include "writer.h"
#include "utils.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
/*****************************************************************************/
diff --git a/src/settings/plugins/ifcfg-rh/utils.c b/src/settings/plugins/ifcfg-rh/utils.c
index fda900b20e..b602a7d7c3 100644
--- a/src/settings/plugins/ifcfg-rh/utils.c
+++ b/src/settings/plugins/ifcfg-rh/utils.c
@@ -27,7 +27,8 @@
#include "nm-core-internal.h"
#include "NetworkManagerUtils.h"
-#include "shvar.h"
+
+#include "common.h"
/*
* utils_single_quote_string
diff --git a/src/settings/plugins/ifcfg-rh/utils.h b/src/settings/plugins/ifcfg-rh/utils.h
index 752d08a60b..b8b172e7ce 100644
--- a/src/settings/plugins/ifcfg-rh/utils.h
+++ b/src/settings/plugins/ifcfg-rh/utils.h
@@ -21,10 +21,9 @@
#ifndef _UTILS_H_
#define _UTILS_H_
-#include <nm-connection.h>
-#include "nm-default.h"
+#include "nm-connection.h"
+
#include "shvar.h"
-#include "common.h"
#define NM_IFCFG_CONNECTION_LOG_PATH(path) ((path) ?: "in-memory")
#define NM_IFCFG_CONNECTION_LOG_FMT "%s (%s,\"%s\")"
diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c
index c17824d6fc..2864078a48 100644
--- a/src/settings/plugins/ifcfg-rh/writer.c
+++ b/src/settings/plugins/ifcfg-rh/writer.c
@@ -42,7 +42,6 @@
#include "nm-setting-vlan.h"
#include "nm-setting-team.h"
#include "nm-setting-team-port.h"
-#include "nm-core-internal.h"
#include "nm-utils.h"
#include "nm-core-internal.h"
#include "NetworkManagerUtils.h"
@@ -51,8 +50,20 @@
#include "shvar.h"
#include "reader.h"
#include "utils.h"
-#include "crypto.h"
+/*****************************************************************************/
+
+#define _NMLOG_DOMAIN LOGD_SETTINGS
+#define _NMLOG_PREFIX_NAME "ifcfg-rh"
+#define _NMLOG(level, ...) \
+ G_STMT_START { \
+ nm_log ((level), (_NMLOG_DOMAIN), \
+ "%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
+ _NMLOG_PREFIX_NAME": " \
+ _NM_UTILS_MACRO_REST(__VA_ARGS__)); \
+ } G_STMT_END
+
+/*****************************************************************************/
static void
save_secret_flags (shvarFile *ifcfg,
@@ -100,7 +111,7 @@ set_secret (shvarFile *ifcfg,
{
shvarFile *keyfile;
GError *error = NULL;
-
+
/* Clear the secret from the ifcfg and the associated "keys" file */
svSetValue (ifcfg, key, NULL, FALSE);
@@ -109,7 +120,7 @@ set_secret (shvarFile *ifcfg,
keyfile = utils_get_keys_ifcfg (ifcfg->fileName, TRUE);
if (!keyfile) {
- nm_log_warn (LOGD_SETTINGS, " could not create ifcfg file for '%s'", ifcfg->fileName);
+ _LOGW ("could not create ifcfg file for '%s'", ifcfg->fileName);
goto error;
}
@@ -121,8 +132,8 @@ set_secret (shvarFile *ifcfg,
svSetValue (keyfile, key, value, verbatim);
if (!svWriteFile (keyfile, 0600, &error)) {
- nm_log_warn (LOGD_SETTINGS, " could not update ifcfg file '%s': %s",
- keyfile->fileName, error->message);
+ _LOGW ("could not update ifcfg file '%s': %s",
+ keyfile->fileName, error->message);
g_clear_error (&error);
svCloseFile (keyfile);
goto error;
@@ -715,7 +726,7 @@ write_wireless_security_setting (NMConnection *connection,
key = ascii_key;
}
} else {
- nm_log_warn (LOGD_SETTINGS, " invalid WEP key '%s'", key);
+ _LOGW ("invalid WEP key '%s'", key);
tmp = NULL;
}
@@ -1970,6 +1981,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
gint32 j;
guint32 i, n, num;
gint64 route_metric;
+ gint priority;
int timeout;
GString *searches;
gboolean success = FALSE;
@@ -2281,6 +2293,12 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
svSetValueInt64 (ifcfg, "ARPING_WAIT", (timeout - 1) / 1000 + 1);
}
+ priority = nm_setting_ip_config_get_dns_priority (s_ip4);
+ if (priority)
+ svSetValueInt64 (ifcfg, "IPV4_DNS_PRIORITY", priority);
+ else
+ svSetValue (ifcfg, "IPV4_DNS_PRIORITY", NULL, FALSE);
+
success = TRUE;
out:
@@ -2440,6 +2458,7 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
char *addr_key;
char *tmp;
guint32 i, num, num4;
+ gint priority;
GString *searches;
NMIPAddress *addr;
const char *dns;
@@ -2604,8 +2623,20 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
addr_gen_mode);
svSetValue (ifcfg, "IPV6_ADDR_GEN_MODE", tmp, FALSE);
g_free (tmp);
+ } else {
+ svSetValue (ifcfg, "IPV6_ADDR_GEN_MODE", NULL, FALSE);
}
+ /* IPv6 tokenized interface identifier */
+ value = nm_setting_ip6_config_get_token (NM_SETTING_IP6_CONFIG (s_ip6));
+ svSetValue (ifcfg, "IPV6_TOKEN", value, FALSE);
+
+ priority = nm_setting_ip_config_get_dns_priority (s_ip6);
+ if (priority)
+ svSetValueInt64 (ifcfg, "IPV6_DNS_PRIORITY", priority);
+ else
+ svSetValue (ifcfg, "IPV6_DNS_PRIORITY", NULL, FALSE);
+
/* Static routes go to route6-<dev> file */
route6_path = utils_get_route6_path (ifcfg->fileName);
if (!route6_path) {
diff --git a/src/settings/plugins/ifcfg-rh/writer.h b/src/settings/plugins/ifcfg-rh/writer.h
index 69389361c9..97a9f25252 100644
--- a/src/settings/plugins/ifcfg-rh/writer.h
+++ b/src/settings/plugins/ifcfg-rh/writer.h
@@ -21,11 +21,7 @@
#ifndef _WRITER_H_
#define _WRITER_H_
-#include <sys/types.h>
-
-#include <nm-connection.h>
-
-#include "nm-default.h"
+#include "nm-connection.h"
gboolean writer_can_write_connection (NMConnection *connection,
GError **error);
diff --git a/src/settings/plugins/ifnet/tests/test-ifnet.c b/src/settings/plugins/ifnet/tests/test-ifnet.c
index 3035fdb156..89df9af806 100644
--- a/src/settings/plugins/ifnet/tests/test-ifnet.c
+++ b/src/settings/plugins/ifnet/tests/test-ifnet.c
@@ -38,7 +38,7 @@
#include "connection_parser.h"
#include "nm-config.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
/* Fake NMConfig handling; the values it returns don't matter, so this
* is easier than forcing it to read our own config file, etc.
diff --git a/src/settings/plugins/ifupdown/tests/test-ifupdown.c b/src/settings/plugins/ifupdown/tests/test-ifupdown.c
index f383821c39..ad483fa856 100644
--- a/src/settings/plugins/ifupdown/tests/test-ifupdown.c
+++ b/src/settings/plugins/ifupdown/tests/test-ifupdown.c
@@ -26,7 +26,7 @@
#include "interface_parser.h"
#include "parser.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
typedef struct {
char *key;
diff --git a/src/settings/plugins/keyfile/plugin.c b/src/settings/plugins/keyfile/plugin.c
index 6003c7457f..c5598fc5b4 100644
--- a/src/settings/plugins/keyfile/plugin.c
+++ b/src/settings/plugins/keyfile/plugin.c
@@ -26,7 +26,6 @@
#include <sys/types.h>
#include <string.h>
-#include <gmodule.h>
#include <glib/gstdio.h>
#include "nm-connection.h"
diff --git a/src/settings/plugins/keyfile/tests/test-keyfile.c b/src/settings/plugins/keyfile/tests/test-keyfile.c
index 7b66e19861..00ab140bef 100644
--- a/src/settings/plugins/keyfile/tests/test-keyfile.c
+++ b/src/settings/plugins/keyfile/tests/test-keyfile.c
@@ -34,7 +34,7 @@
#include "writer.h"
#include "utils.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
static void
check_ip_address (NMSettingIPConfig *config, int idx, const char *address, int plen)
diff --git a/src/supplicant-manager/tests/test-supplicant-config.c b/src/supplicant-manager/tests/test-supplicant-config.c
index 881f44f6bf..fd603f3b81 100644
--- a/src/supplicant-manager/tests/test-supplicant-config.c
+++ b/src/supplicant-manager/tests/test-supplicant-config.c
@@ -35,7 +35,7 @@
#include "nm-supplicant-config.h"
#include "nm-supplicant-settings-verify.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
static gboolean
validate_opt (const char *detail,
diff --git a/src/systemd/src/basic/ether-addr-util.c b/src/systemd/src/basic/ether-addr-util.c
index 0219300da9..a793219cc2 100644
--- a/src/systemd/src/basic/ether-addr-util.c
+++ b/src/systemd/src/basic/ether-addr-util.c
@@ -25,6 +25,7 @@
#include "ether-addr-util.h"
#include "macro.h"
+#include "string-util.h"
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
assert(addr);
@@ -56,3 +57,71 @@ bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b) {
a->ether_addr_octet[4] == b->ether_addr_octet[4] &&
a->ether_addr_octet[5] == b->ether_addr_octet[5];
}
+
+int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset) {
+ size_t pos = 0, n, field;
+ char sep = '\0';
+ const char *hex = HEXDIGITS, *hexoff;
+ size_t x;
+ bool touched;
+
+#define parse_fields(v) \
+ for (field = 0; field < ELEMENTSOF(v); field++) { \
+ touched = false; \
+ for (n = 0; n < (2 * sizeof(v[0])); n++) { \
+ if (s[pos] == '\0') \
+ break; \
+ hexoff = strchr(hex, s[pos]); \
+ if (hexoff == NULL) \
+ break; \
+ assert(hexoff >= hex); \
+ x = hexoff - hex; \
+ if (x >= 16) \
+ x -= 6; /* A-F */ \
+ assert(x < 16); \
+ touched = true; \
+ v[field] <<= 4; \
+ v[field] += x; \
+ pos++; \
+ } \
+ if (!touched) \
+ return -EINVAL; \
+ if (field < (ELEMENTSOF(v)-1)) { \
+ if (s[pos] != sep) \
+ return -EINVAL; \
+ else \
+ pos++; \
+ } \
+ }
+
+ assert(s);
+ assert(ret);
+
+ sep = s[strspn(s, hex)];
+ if (sep == '\n')
+ return -EINVAL;
+ if (strchr(":.-", sep) == NULL)
+ return -EINVAL;
+
+ if (sep == '.') {
+ uint16_t shorts[3] = { 0 };
+
+ parse_fields(shorts);
+
+ for (n = 0; n < ELEMENTSOF(shorts); n++) {
+ ret->ether_addr_octet[2*n] = ((shorts[n] & (uint16_t)0xff00) >> 8);
+ ret->ether_addr_octet[2*n + 1] = (shorts[n] & (uint16_t)0x00ff);
+ }
+ } else {
+ struct ether_addr out = { .ether_addr_octet = { 0 } };
+
+ parse_fields(out.ether_addr_octet);
+
+ for (n = 0; n < ELEMENTSOF(out.ether_addr_octet); n++)
+ ret->ether_addr_octet[n] = out.ether_addr_octet[n];
+ }
+
+ if (offset)
+ *offset = pos;
+ return 0;
+}
diff --git a/src/systemd/src/basic/ether-addr-util.h b/src/systemd/src/basic/ether-addr-util.h
index 074363793e..74e125a95f 100644
--- a/src/systemd/src/basic/ether-addr-util.h
+++ b/src/systemd/src/basic/ether-addr-util.h
@@ -35,3 +35,5 @@ bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b);
static inline bool ether_addr_is_null(const struct ether_addr *addr) {
return ether_addr_equal(addr, &ETHER_ADDR_NULL);
}
+
+int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset);
diff --git a/src/systemd/src/basic/extract-word.c b/src/systemd/src/basic/extract-word.c
new file mode 100644
index 0000000000..eb54daa355
--- /dev/null
+++ b/src/systemd/src/basic/extract-word.c
@@ -0,0 +1,302 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "nm-sd-adapt.h"
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+
+#include "alloc-util.h"
+#include "escape.h"
+#include "extract-word.h"
+#include "log.h"
+#include "macro.h"
+#include "string-util.h"
+#include "utf8.h"
+
+int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
+ _cleanup_free_ char *s = NULL;
+ size_t allocated = 0, sz = 0;
+ char c;
+ int r;
+
+ char quote = 0; /* 0 or ' or " */
+ bool backslash = false; /* whether we've just seen a backslash */
+
+ assert(p);
+ assert(ret);
+
+ /* Bail early if called after last value or with no input */
+ if (!*p)
+ goto finish_force_terminate;
+ c = **p;
+
+ if (!separators)
+ separators = WHITESPACE;
+
+ /* Parses the first word of a string, and returns it in
+ * *ret. Removes all quotes in the process. When parsing fails
+ * (because of an uneven number of quotes or similar), leaves
+ * the pointer *p at the first invalid character. */
+
+ if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
+ if (!GREEDY_REALLOC(s, allocated, sz+1))
+ return -ENOMEM;
+
+ for (;; (*p)++, c = **p) {
+ if (c == 0)
+ goto finish_force_terminate;
+ else if (strchr(separators, c)) {
+ if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
+ (*p)++;
+ goto finish_force_next;
+ }
+ } else {
+ /* We found a non-blank character, so we will always
+ * want to return a string (even if it is empty),
+ * allocate it here. */
+ if (!GREEDY_REALLOC(s, allocated, sz+1))
+ return -ENOMEM;
+ break;
+ }
+ }
+
+ for (;; (*p)++, c = **p) {
+ if (backslash) {
+ if (!GREEDY_REALLOC(s, allocated, sz+7))
+ return -ENOMEM;
+
+ if (c == 0) {
+ if ((flags & EXTRACT_CUNESCAPE_RELAX) &&
+ (!quote || flags & EXTRACT_RELAX)) {
+ /* If we find an unquoted trailing backslash and we're in
+ * EXTRACT_CUNESCAPE_RELAX mode, keep it verbatim in the
+ * output.
+ *
+ * Unbalanced quotes will only be allowed in EXTRACT_RELAX
+ * mode, EXTRACT_CUNESCAPE_RELAX mode does not allow them.
+ */
+ s[sz++] = '\\';
+ goto finish_force_terminate;
+ }
+ if (flags & EXTRACT_RELAX)
+ goto finish_force_terminate;
+ return -EINVAL;
+ }
+
+ if (flags & EXTRACT_CUNESCAPE) {
+ bool eight_bit = false;
+ char32_t u;
+
+ r = cunescape_one(*p, (size_t) -1, &u, &eight_bit);
+ if (r < 0) {
+ if (flags & EXTRACT_CUNESCAPE_RELAX) {
+ s[sz++] = '\\';
+ s[sz++] = c;
+ } else
+ return -EINVAL;
+ } else {
+ (*p) += r - 1;
+
+ if (eight_bit)
+ s[sz++] = u;
+ else
+ sz += utf8_encode_unichar(s + sz, u);
+ }
+ } else
+ s[sz++] = c;
+
+ backslash = false;
+
+ } else if (quote) { /* inside either single or double quotes */
+ for (;; (*p)++, c = **p) {
+ if (c == 0) {
+ if (flags & EXTRACT_RELAX)
+ goto finish_force_terminate;
+ return -EINVAL;
+ } else if (c == quote) { /* found the end quote */
+ quote = 0;
+ break;
+ } else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) {
+ backslash = true;
+ break;
+ } else {
+ if (!GREEDY_REALLOC(s, allocated, sz+2))
+ return -ENOMEM;
+
+ s[sz++] = c;
+ }
+ }
+
+ } else {
+ for (;; (*p)++, c = **p) {
+ if (c == 0)
+ goto finish_force_terminate;
+ else if ((c == '\'' || c == '"') && (flags & EXTRACT_QUOTES)) {
+ quote = c;
+ break;
+ } else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) {
+ backslash = true;
+ break;
+ } else if (strchr(separators, c)) {
+ if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
+ (*p)++;
+ goto finish_force_next;
+ }
+ /* Skip additional coalesced separators. */
+ for (;; (*p)++, c = **p) {
+ if (c == 0)
+ goto finish_force_terminate;
+ if (!strchr(separators, c))
+ break;
+ }
+ goto finish;
+
+ } else {
+ if (!GREEDY_REALLOC(s, allocated, sz+2))
+ return -ENOMEM;
+
+ s[sz++] = c;
+ }
+ }
+ }
+ }
+
+finish_force_terminate:
+ *p = NULL;
+finish:
+ if (!s) {
+ *p = NULL;
+ *ret = NULL;
+ return 0;
+ }
+
+finish_force_next:
+ s[sz] = 0;
+ *ret = s;
+ s = NULL;
+
+ return 1;
+}
+
+#if 0 /* NM_IGNORED */
+int extract_first_word_and_warn(
+ const char **p,
+ char **ret,
+ const char *separators,
+ ExtractFlags flags,
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *rvalue) {
+
+ /* Try to unquote it, if it fails, warn about it and try again
+ * but this time using EXTRACT_CUNESCAPE_RELAX to keep the
+ * backslashes verbatim in invalid escape sequences. */
+
+ const char *save;
+ int r;
+
+ save = *p;
+ r = extract_first_word(p, ret, separators, flags);
+ if (r >= 0)
+ return r;
+
+ if (r == -EINVAL && !(flags & EXTRACT_CUNESCAPE_RELAX)) {
+
+ /* Retry it with EXTRACT_CUNESCAPE_RELAX. */
+ *p = save;
+ r = extract_first_word(p, ret, separators, flags|EXTRACT_CUNESCAPE_RELAX);
+ if (r >= 0) {
+ /* It worked this time, hence it must have been an invalid escape sequence we could correct. */
+ log_syntax(unit, LOG_WARNING, filename, line, EINVAL, "Invalid escape sequences in line, correcting: \"%s\"", rvalue);
+ return r;
+ }
+
+ /* If it's still EINVAL; then it must be unbalanced quoting, report this. */
+ if (r == -EINVAL)
+ return log_syntax(unit, LOG_ERR, filename, line, r, "Unbalanced quoting, ignoring: \"%s\"", rvalue);
+ }
+
+ /* Can be any error, report it */
+ return log_syntax(unit, LOG_ERR, filename, line, r, "Unable to decode word \"%s\", ignoring: %m", rvalue);
+}
+
+int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) {
+ va_list ap;
+ char **l;
+ int n = 0, i, c, r;
+
+ /* Parses a number of words from a string, stripping any
+ * quotes if necessary. */
+
+ assert(p);
+
+ /* Count how many words are expected */
+ va_start(ap, flags);
+ for (;;) {
+ if (!va_arg(ap, char **))
+ break;
+ n++;
+ }
+ va_end(ap);
+
+ if (n <= 0)
+ return 0;
+
+ /* Read all words into a temporary array */
+ l = newa0(char*, n);
+ for (c = 0; c < n; c++) {
+
+ r = extract_first_word(p, &l[c], separators, flags);
+ if (r < 0) {
+ int j;
+
+ for (j = 0; j < c; j++)
+ free(l[j]);
+
+ return r;
+ }
+
+ if (r == 0)
+ break;
+ }
+
+ /* If we managed to parse all words, return them in the passed
+ * in parameters */
+ va_start(ap, flags);
+ for (i = 0; i < n; i++) {
+ char **v;
+
+ v = va_arg(ap, char **);
+ assert(v);
+
+ *v = l[i];
+ }
+ va_end(ap);
+
+ return c;
+}
+#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/extract-word.h b/src/systemd/src/basic/extract-word.h
new file mode 100644
index 0000000000..21db5ef33f
--- /dev/null
+++ b/src/systemd/src/basic/extract-word.h
@@ -0,0 +1,35 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "macro.h"
+
+typedef enum ExtractFlags {
+ EXTRACT_RELAX = 1,
+ EXTRACT_CUNESCAPE = 2,
+ EXTRACT_CUNESCAPE_RELAX = 4,
+ EXTRACT_QUOTES = 8,
+ EXTRACT_DONT_COALESCE_SEPARATORS = 16,
+ EXTRACT_RETAIN_ESCAPE = 32,
+} ExtractFlags;
+
+int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags);
+int extract_first_word_and_warn(const char **p, char **ret, const char *separators, ExtractFlags flags, const char *unit, const char *filename, unsigned line, const char *rvalue);
+int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) _sentinel_;
diff --git a/src/systemd/src/basic/fd-util.c b/src/systemd/src/basic/fd-util.c
index e92b3740c8..7a13d28f8c 100644
--- a/src/systemd/src/basic/fd-util.c
+++ b/src/systemd/src/basic/fd-util.c
@@ -27,6 +27,7 @@
#include <unistd.h>
#include "fd-util.h"
+#include "fs-util.h"
#include "macro.h"
#if 0 /* NM_IGNORED */
#include "missing.h"
@@ -34,6 +35,7 @@
#include "parse-util.h"
#include "path-util.h"
#include "socket-util.h"
+#include "stdio-util.h"
#include "util.h"
int close_nointr(int fd) {
@@ -234,7 +236,7 @@ int close_all_fds(const int except[], unsigned n_except) {
while ((de = readdir(d))) {
int fd = -1;
- if (hidden_file(de->d_name))
+ if (hidden_or_backup_file(de->d_name))
continue;
if (safe_atoi(de->d_name, &fd) < 0)
@@ -362,3 +364,17 @@ bool fdname_is_valid(const char *s) {
return p - s < 256;
}
+
+int fd_get_path(int fd, char **ret) {
+ char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
+ int r;
+
+ xsprintf(procfs_path, "/proc/self/fd/%i", fd);
+
+ r = readlink_malloc(procfs_path, ret);
+
+ if (r == -ENOENT) /* If the file doesn't exist the fd is invalid */
+ return -EBADF;
+
+ return r;
+}
diff --git a/src/systemd/src/basic/fd-util.h b/src/systemd/src/basic/fd-util.h
index 44528c6e35..b86e41698a 100644
--- a/src/systemd/src/basic/fd-util.h
+++ b/src/systemd/src/basic/fd-util.h
@@ -72,6 +72,8 @@ void cmsg_close_all(struct msghdr *mh);
bool fdname_is_valid(const char *s);
+int fd_get_path(int fd, char **ret);
+
/* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */
#define ERRNO_IS_DISCONNECT(r) \
IN_SET(r, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, ENETUNREACH)
diff --git a/src/systemd/src/basic/fileio.c b/src/systemd/src/basic/fileio.c
index e940e10e70..b07cb9cb2d 100644
--- a/src/systemd/src/basic/fileio.c
+++ b/src/systemd/src/basic/fileio.c
@@ -1087,30 +1087,6 @@ int mkostemp_safe(char *pattern, int flags) {
return fd;
}
-int open_tmpfile(const char *path, int flags) {
- char *p;
- int fd;
-
- assert(path);
-
-#ifdef O_TMPFILE
- /* Try O_TMPFILE first, if it is supported */
- fd = open(path, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
- if (fd >= 0)
- return fd;
-#endif
-
- /* Fall back to unguessable name + unlinking */
- p = strjoina(path, "/systemd-tmp-XXXXXX");
-
- fd = mkostemp_safe(p, flags);
- if (fd < 0)
- return fd;
-
- unlink(p);
- return fd;
-}
-
int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
const char *fn;
char *t;
@@ -1234,7 +1210,6 @@ int write_timestamp_file_atomic(const char *fn, usec_t n) {
return write_string_file(fn, ln, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
}
-#endif /* NM_IGNORED */
int read_timestamp_file(const char *fn, usec_t *ret) {
_cleanup_free_ char *ln = NULL;
@@ -1255,6 +1230,7 @@ int read_timestamp_file(const char *fn, usec_t *ret) {
*ret = (usec_t) t;
return 0;
}
+#endif /* NM_IGNORED */
int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space) {
int r;
@@ -1284,3 +1260,105 @@ int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space)
return fputs(s, f);
}
+
+#if 0 /* NM_IGNORED */
+int open_tmpfile_unlinkable(const char *directory, int flags) {
+ char *p;
+ int fd;
+
+ assert(directory);
+
+ /* Returns an unlinked temporary file that cannot be linked into the file system anymore */
+
+#ifdef O_TMPFILE
+ /* Try O_TMPFILE first, if it is supported */
+ fd = open(directory, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
+ if (fd >= 0)
+ return fd;
+#endif
+
+ /* Fall back to unguessable name + unlinking */
+ p = strjoina(directory, "/systemd-tmp-XXXXXX");
+
+ fd = mkostemp_safe(p, flags);
+ if (fd < 0)
+ return fd;
+
+ (void) unlink(p);
+
+ return fd;
+}
+
+int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
+ _cleanup_free_ char *tmp = NULL;
+ int r, fd;
+
+ assert(target);
+ assert(ret_path);
+
+ /* Don't allow O_EXCL, as that has a special meaning for O_TMPFILE */
+ assert((flags & O_EXCL) == 0);
+
+ /* Creates a temporary file, that shall be renamed to "target" later. If possible, this uses O_TMPFILE – in
+ * which case "ret_path" will be returned as NULL. If not possible a the tempoary path name used is returned in
+ * "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */
+
+#ifdef O_TMPFILE
+ {
+ _cleanup_free_ char *dn = NULL;
+
+ dn = dirname_malloc(target);
+ if (!dn)
+ return -ENOMEM;
+
+ fd = open(dn, O_TMPFILE|flags, 0640);
+ if (fd >= 0) {
+ *ret_path = NULL;
+ return fd;
+ }
+
+ log_debug_errno(errno, "Failed to use O_TMPFILE on %s: %m", dn);
+ }
+#endif
+
+ r = tempfn_random(target, NULL, &tmp);
+ if (r < 0)
+ return r;
+
+ fd = open(tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, 0640);
+ if (fd < 0)
+ return -errno;
+
+ *ret_path = tmp;
+ tmp = NULL;
+
+ return fd;
+}
+
+int link_tmpfile(int fd, const char *path, const char *target) {
+
+ assert(fd >= 0);
+ assert(target);
+
+ /* Moves a temporary file created with open_tmpfile() above into its final place. if "path" is NULL an fd
+ * created with O_TMPFILE is assumed, and linkat() is used. Otherwise it is assumed O_TMPFILE is not supported
+ * on the directory, and renameat2() is used instead.
+ *
+ * Note that in both cases we will not replace existing files. This is because linkat() does not support this
+ * operation currently (renameat2() does), and there is no nice way to emulate this. */
+
+ if (path) {
+ if (rename_noreplace(AT_FDCWD, path, AT_FDCWD, target) < 0)
+ return -errno;
+ } else {
+ char proc_fd_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
+
+ xsprintf(proc_fd_path, "/proc/self/fd/%i", fd);
+
+ if (linkat(AT_FDCWD, proc_fd_path, AT_FDCWD, target, AT_SYMLINK_FOLLOW) < 0)
+ return -errno;
+ }
+
+ return 0;
+}
+#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/fileio.h b/src/systemd/src/basic/fileio.h
index 8084895ff3..58dbc80c24 100644
--- a/src/systemd/src/basic/fileio.h
+++ b/src/systemd/src/basic/fileio.h
@@ -72,7 +72,6 @@ int fflush_and_check(FILE *f);
int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
int mkostemp_safe(char *pattern, int flags);
-int open_tmpfile(const char *path, int flags);
int tempfn_xxxxxx(const char *p, const char *extra, char **ret);
int tempfn_random(const char *p, const char *extra, char **ret);
@@ -82,3 +81,8 @@ int write_timestamp_file_atomic(const char *fn, usec_t n);
int read_timestamp_file(const char *fn, usec_t *ret);
int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space);
+
+int open_tmpfile_unlinkable(const char *directory, int flags);
+int open_tmpfile_linkable(const char *target, int flags, char **ret_path);
+
+int link_tmpfile(int fd, const char *path, const char *target);
diff --git a/src/systemd/src/basic/fs-util.c b/src/systemd/src/basic/fs-util.c
index 9a84364420..1e09366f20 100644
--- a/src/systemd/src/basic/fs-util.c
+++ b/src/systemd/src/basic/fs-util.c
@@ -44,6 +44,7 @@
#endif /* NM_IGNORED */
#include "parse-util.h"
#include "path-util.h"
+#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
@@ -151,6 +152,7 @@ int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char
return 0;
}
+#endif /* NM_IGNORED */
int readlinkat_malloc(int fd, const char *p, char **ret) {
size_t l = 100;
@@ -189,6 +191,7 @@ int readlink_malloc(const char *p, char **ret) {
return readlinkat_malloc(AT_FDCWD, p, ret);
}
+#if 0 /* NM_IGNORED */
int readlink_value(const char *p, char **ret) {
_cleanup_free_ char *link = NULL;
char *value;
@@ -504,4 +507,18 @@ int get_files_in_directory(const char *path, char ***list) {
return n;
}
+
+int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
+ char path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
+ int r;
+
+ /* This is like inotify_add_watch(), except that the file to watch is not referenced by a path, but by an fd */
+ xsprintf(path, "/proc/self/fd/%i", what);
+
+ r = inotify_add_watch(fd, path, mask);
+ if (r < 0)
+ return -errno;
+
+ return r;
+}
#endif /* NM_IGNORED */
diff --git a/src/systemd/src/basic/fs-util.h b/src/systemd/src/basic/fs-util.h
index 0d23f8635f..517b599d6f 100644
--- a/src/systemd/src/basic/fs-util.h
+++ b/src/systemd/src/basic/fs-util.h
@@ -72,3 +72,5 @@ union inotify_event_buffer {
struct inotify_event ev;
uint8_t raw[INOTIFY_EVENT_MAX];
};
+
+int inotify_add_watch_fd(int fd, int what, uint32_t mask);
diff --git a/src/systemd/src/basic/hashmap.c b/src/systemd/src/basic/hashmap.c
index 4df3ae73ef..d76ee3fabd 100644
--- a/src/systemd/src/basic/hashmap.c
+++ b/src/systemd/src/basic/hashmap.c
@@ -1777,20 +1777,18 @@ int set_consume(Set *s, void *value) {
int set_put_strdup(Set *s, const char *p) {
char *c;
- int r;
assert(s);
assert(p);
+ if (set_contains(s, (char*) p))
+ return 0;
+
c = strdup(p);
if (!c)
return -ENOMEM;
- r = set_consume(s, c);
- if (r == -EEXIST)
- return 0;
-
- return r;
+ return set_consume(s, c);
}
int set_put_strdupv(Set *s, char **l) {
diff --git a/src/systemd/src/basic/hostname-util.c b/src/systemd/src/basic/hostname-util.c
index ee48b86dd2..480f9d9de6 100644
--- a/src/systemd/src/basic/hostname-util.c
+++ b/src/systemd/src/basic/hostname-util.c
@@ -180,16 +180,16 @@ bool is_localhost(const char *hostname) {
assert(hostname);
/* This tries to identify local host and domain names
- * described in RFC6761 plus the redhatism of .localdomain */
+ * described in RFC6761 plus the redhatism of localdomain */
return strcaseeq(hostname, "localhost") ||
strcaseeq(hostname, "localhost.") ||
- strcaseeq(hostname, "localdomain.") ||
- strcaseeq(hostname, "localdomain") ||
+ strcaseeq(hostname, "localhost.localdomain") ||
+ strcaseeq(hostname, "localhost.localdomain.") ||
endswith_no_case(hostname, ".localhost") ||
endswith_no_case(hostname, ".localhost.") ||
- endswith_no_case(hostname, ".localdomain") ||
- endswith_no_case(hostname, ".localdomain.");
+ endswith_no_case(hostname, ".localhost.localdomain") ||
+ endswith_no_case(hostname, ".localhost.localdomain.");
}
#if 0 /* NM_IGNORED */
diff --git a/src/systemd/src/basic/io-util.c b/src/systemd/src/basic/io-util.c
index aaf414f400..61b667f062 100644
--- a/src/systemd/src/basic/io-util.c
+++ b/src/systemd/src/basic/io-util.c
@@ -35,6 +35,11 @@ int flush_fd(int fd) {
.events = POLLIN,
};
+ /* Read from the specified file descriptor, until POLLIN is not set anymore, throwing away everything
+ * read. Note that some file descriptors (notable IP sockets) will trigger POLLIN even when no data can be read
+ * (due to IP packet checksum mismatches), hence this function is only safe to be non-blocking if the fd used
+ * was set to non-blocking too. */
+
for (;;) {
char buf[LINE_MAX];
ssize_t l;
diff --git a/src/systemd/src/basic/parse-util.c b/src/systemd/src/basic/parse-util.c
index eb53c42d75..57893aa523 100644
--- a/src/systemd/src/basic/parse-util.c
+++ b/src/systemd/src/basic/parse-util.c
@@ -28,9 +28,7 @@
#include <xlocale.h>
#include "alloc-util.h"
-#if 0 /* NM_IGNORED */
#include "extract-word.h"
-#endif /* NM_IGNORED */
#include "macro.h"
#include "parse-util.h"
#include "string-util.h"
diff --git a/src/systemd/src/basic/parse-util.h b/src/systemd/src/basic/parse-util.h
index d8dc26a36e..7dc579a159 100644
--- a/src/systemd/src/basic/parse-util.h
+++ b/src/systemd/src/basic/parse-util.h
@@ -90,6 +90,18 @@ static inline int safe_atoli(const char *s, long int *ret_u) {
}
#endif
+#if SIZE_MAX == UINT_MAX
+static inline int safe_atozu(const char *s, size_t *ret_u) {
+ assert_cc(sizeof(size_t) == sizeof(unsigned));
+ return safe_atou(s, (unsigned *) ret_u);
+}
+#else
+static inline int safe_atozu(const char *s, size_t *ret_u) {
+ assert_cc(sizeof(size_t) == sizeof(long unsigned));
+ return safe_atolu(s, ret_u);
+}
+#endif
+
int safe_atod(const char *s, double *ret_d);
int parse_fractional_part_u(const char **s, size_t digits, unsigned *res);
diff --git a/src/systemd/src/basic/path-util.c b/src/systemd/src/basic/path-util.c
index c3b7d187a0..8c4dec5b6c 100644
--- a/src/systemd/src/basic/path-util.c
+++ b/src/systemd/src/basic/path-util.c
@@ -34,9 +34,7 @@
#undef basename
#include "alloc-util.h"
-#if 0 /* NM_IGNORED */
#include "extract-word.h"
-#endif /* NM_IGNORED */
#include "fs-util.h"
#include "log.h"
#include "macro.h"
@@ -580,10 +578,10 @@ static int binary_is_good(const char *binary) {
if (r < 0)
return r;
- return !path_equal(d, "true") &&
- !path_equal(d, "/bin/true") &&
- !path_equal(d, "/usr/bin/true") &&
- !path_equal(d, "/dev/null");
+ return !PATH_IN_SET(d, "true"
+ "/bin/true",
+ "/usr/bin/true",
+ "/dev/null");
}
int fsck_exists(const char *fstype) {
@@ -769,34 +767,53 @@ char *file_in_same_dir(const char *path, const char *filename) {
return ret;
}
-bool hidden_file_allow_backup(const char *filename) {
- assert(filename);
-
- return
- filename[0] == '.' ||
- streq(filename, "lost+found") ||
- streq(filename, "aquota.user") ||
- streq(filename, "aquota.group") ||
- endswith(filename, ".rpmnew") ||
- endswith(filename, ".rpmsave") ||
- endswith(filename, ".rpmorig") ||
- endswith(filename, ".dpkg-old") ||
- endswith(filename, ".dpkg-new") ||
- endswith(filename, ".dpkg-tmp") ||
- endswith(filename, ".dpkg-dist") ||
- endswith(filename, ".dpkg-bak") ||
- endswith(filename, ".dpkg-backup") ||
- endswith(filename, ".dpkg-remove") ||
- endswith(filename, ".swp");
-}
+bool hidden_or_backup_file(const char *filename) {
+ const char *p;
-bool hidden_file(const char *filename) {
assert(filename);
- if (endswith(filename, "~"))
+ if (filename[0] == '.' ||
+ streq(filename, "lost+found") ||
+ streq(filename, "aquota.user") ||
+ streq(filename, "aquota.group") ||
+ endswith(filename, "~"))
return true;
- return hidden_file_allow_backup(filename);
+ p = strrchr(filename, '.');
+ if (!p)
+ return false;
+
+ /* Please, let's not add more entries to the list below. If external projects think it's a good idea to come up
+ * with always new suffixes and that everybody else should just adjust to that, then it really should be on
+ * them. Hence, in future, let's not add any more entries. Instead, let's ask those packages to instead adopt
+ * one of the generic suffixes/prefixes for hidden files or backups, possibly augmented with an additional
+ * string. Specifically: there's now:
+ *
+ * The generic suffixes "~" and ".bak" for backup files
+ * The generic prefix "." for hidden files
+ *
+ * Thus, if a new package manager "foopkg" wants its own set of ".foopkg-new", ".foopkg-old", ".foopkg-dist"
+ * or so registered, let's refuse that and ask them to use ".foopkg.new", ".foopkg.old" or ".foopkg~" instead.
+ */
+
+ return STR_IN_SET(p + 1,
+ "rpmnew",
+ "rpmsave",
+ "rpmorig",
+ "dpkg-old",
+ "dpkg-new",
+ "dpkg-tmp",
+ "dpkg-dist",
+ "dpkg-bak",
+ "dpkg-backup",
+ "dpkg-remove",
+ "ucf-new",
+ "ucf-old",
+ "ucf-dist",
+ "swp",
+ "bak",
+ "old",
+ "new");
}
bool is_device_path(const char *path) {
diff --git a/src/systemd/src/basic/path-util.h b/src/systemd/src/basic/path-util.h
index 2c2f87a9f2..a27c13fcc3 100644
--- a/src/systemd/src/basic/path-util.h
+++ b/src/systemd/src/basic/path-util.h
@@ -48,6 +48,23 @@ bool path_equal(const char *a, const char *b) _pure_;
bool path_equal_or_files_same(const char *a, const char *b);
char* path_join(const char *root, const char *path, const char *rest);
+static inline bool path_equal_ptr(const char *a, const char *b) {
+ return !!a == !!b && (!a || path_equal(a, b));
+}
+
+/* Note: the search terminates on the first NULL item. */
+#define PATH_IN_SET(p, ...) \
+ ({ \
+ char **s; \
+ bool _found = false; \
+ STRV_FOREACH(s, STRV_MAKE(__VA_ARGS__)) \
+ if (path_equal(p, *s)) { \
+ _found = true; \
+ break; \
+ } \
+ _found; \
+ })
+
int path_strv_make_absolute_cwd(char **l);
char** path_strv_resolve(char **l, const char *prefix);
char** path_strv_resolve_uniq(char **l, const char *prefix);
@@ -105,7 +122,6 @@ bool path_is_safe(const char *p) _pure_;
char *file_in_same_dir(const char *path, const char *filename);
-bool hidden_file_allow_backup(const char *filename);
-bool hidden_file(const char *filename) _pure_;
+bool hidden_or_backup_file(const char *filename) _pure_;
bool is_device_path(const char *path);
diff --git a/src/systemd/src/basic/signal-util.h b/src/systemd/src/basic/signal-util.h
new file mode 100644
index 0000000000..dfd6eb564d
--- /dev/null
+++ b/src/systemd/src/basic/signal-util.h
@@ -0,0 +1,56 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010-2015 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <signal.h>
+
+#include "macro.h"
+
+int reset_all_signal_handlers(void);
+int reset_signal_mask(void);
+
+int ignore_signals(int sig, ...);
+int default_signals(int sig, ...);
+int sigaction_many(const struct sigaction *sa, ...);
+
+int sigset_add_many(sigset_t *ss, ...);
+int sigprocmask_many(int how, sigset_t *old, ...);
+
+const char *signal_to_string(int i) _const_;
+int signal_from_string(const char *s) _pure_;
+
+int signal_from_string_try_harder(const char *s);
+
+void nop_signal_handler(int sig);
+
+static inline void block_signals_reset(sigset_t *ss) {
+ assert_se(sigprocmask(SIG_SETMASK, ss, NULL) >= 0);
+}
+
+#define BLOCK_SIGNALS(...) \
+ _cleanup_(block_signals_reset) _unused_ sigset_t _saved_sigset = ({ \
+ sigset_t t; \
+ assert_se(sigprocmask_many(SIG_BLOCK, &t, __VA_ARGS__, -1) >= 0); \
+ t; \
+ })
+
+static inline bool SIGNAL_VALID(int signo) {
+ return signo > 0 && signo < _NSIG;
+}
diff --git a/src/systemd/src/basic/socket-util.c b/src/systemd/src/basic/socket-util.c
index c68db7c32f..f4fa37127a 100644
--- a/src/systemd/src/basic/socket-util.c
+++ b/src/systemd/src/basic/socket-util.c
@@ -25,6 +25,7 @@
#include <net/if.h>
#include <netdb.h>
#include <netinet/ip.h>
+#include <poll.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -48,9 +49,11 @@
#include "socket-util.h"
#include "string-table.h"
#include "string-util.h"
+#include "strv.h"
#if 0 /* NM_IGNORED */
#include "user-util.h"
#endif /* NM_IGNORED */
+#include "utf8.h"
#include "util.h"
#if 0 /* NM_IGNORED */
@@ -803,6 +806,42 @@ static const char* const ip_tos_table[] = {
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
+bool ifname_valid(const char *p) {
+ bool numeric = true;
+
+ /* Checks whether a network interface name is valid. This is inspired by dev_valid_name() in the kernel sources
+ * but slightly stricter, as we only allow non-control, non-space ASCII characters in the interface name. We
+ * also don't permit names that only container numbers, to avoid confusion with numeric interface indexes. */
+
+ if (isempty(p))
+ return false;
+
+ if (strlen(p) >= IFNAMSIZ)
+ return false;
+
+ if (STR_IN_SET(p, ".", ".."))
+ return false;
+
+ while (*p) {
+ if ((unsigned char) *p >= 127U)
+ return false;
+
+ if ((unsigned char) *p <= 32U)
+ return false;
+
+ if (*p == ':' || *p == '/')
+ return false;
+
+ numeric = numeric && (*p >= '0' && *p <= '9');
+ p++;
+ }
+
+ if (numeric)
+ return false;
+
+ return true;
+}
+
int getpeercred(int fd, struct ucred *ucred) {
socklen_t n = sizeof(struct ucred);
struct ucred u;
@@ -980,3 +1019,42 @@ fallback:
return (ssize_t) k;
}
+
+int flush_accept(int fd) {
+
+ struct pollfd pollfd = {
+ .fd = fd,
+ .events = POLLIN,
+ };
+ int r;
+
+
+ /* Similar to flush_fd() but flushes all incoming connection by accepting them and immediately closing them. */
+
+ for (;;) {
+ int cfd;
+
+ r = poll(&pollfd, 1, 0);
+ if (r < 0) {
+ if (errno == EINTR)
+ continue;
+
+ return -errno;
+
+ } else if (r == 0)
+ return 0;
+
+ cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
+ if (cfd < 0) {
+ if (errno == EINTR)
+ continue;
+
+ if (errno == EAGAIN)
+ return 0;
+
+ return -errno;
+ }
+
+ close(cfd);
+ }
+}
diff --git a/src/systemd/src/basic/socket-util.h b/src/systemd/src/basic/socket-util.h
index d17a2f35f8..e9230e4a9f 100644
--- a/src/systemd/src/basic/socket-util.h
+++ b/src/systemd/src/basic/socket-util.h
@@ -123,6 +123,8 @@ int fd_inc_rcvbuf(int fd, size_t n);
int ip_tos_to_string_alloc(int i, char **s);
int ip_tos_from_string(const char *s);
+bool ifname_valid(const char *p);
+
int getpeercred(int fd, struct ucred *ucred);
int getpeersec(int fd, char **ret);
@@ -135,5 +137,18 @@ int receive_one_fd(int transport_fd, int flags);
ssize_t next_datagram_size_fd(int fd);
+int flush_accept(int fd);
+
#define CMSG_FOREACH(cmsg, mh) \
for ((cmsg) = CMSG_FIRSTHDR(mh); (cmsg); (cmsg) = CMSG_NXTHDR((mh), (cmsg)))
+
+/* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */
+#define SOCKADDR_UN_LEN(sa) \
+ ({ \
+ const struct sockaddr_un *_sa = &(sa); \
+ assert(_sa->sun_family == AF_UNIX); \
+ offsetof(struct sockaddr_un, sun_path) + \
+ (_sa->sun_path[0] == 0 ? \
+ 1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \
+ strnlen(_sa->sun_path, sizeof(_sa->sun_path))); \
+ })
diff --git a/src/systemd/src/basic/string-table.h b/src/systemd/src/basic/string-table.h
index b180488fe8..d88625fca7 100644
--- a/src/systemd/src/basic/string-table.h
+++ b/src/systemd/src/basic/string-table.h
@@ -56,26 +56,8 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k
return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \
}
-#define _DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \
- _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
- _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope) \
- struct __useless_struct_to_allow_trailing_semicolon__
-
-#define _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,scope) \
- _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
- _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \
- struct __useless_struct_to_allow_trailing_semicolon__
-
-#define DEFINE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,)
-#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,static)
-#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,static)
-#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,static)
-
-#define DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes) _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,)
-
-/* For string conversions where numbers are also acceptable */
-#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \
- int name##_to_string_alloc(type i, char **str) { \
+#define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,scope) \
+ scope int name##_to_string_alloc(type i, char **str) { \
char *s; \
if (i < 0 || i > max) \
return -ERANGE; \
@@ -89,7 +71,9 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k
} \
*str = s; \
return 0; \
- } \
+ }
+
+#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,scope) \
type name##_from_string(const char *s) { \
type i; \
unsigned u = 0; \
@@ -102,4 +86,32 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k
return (type) u; \
return (type) -1; \
} \
+
+
+#define _DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \
+ _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
+ _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope) \
+ struct __useless_struct_to_allow_trailing_semicolon__
+
+#define _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,scope) \
+ _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
+ _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \
+ struct __useless_struct_to_allow_trailing_semicolon__
+
+#define DEFINE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,)
+#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,static)
+#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,static)
+#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,static)
+
+#define DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes) _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,)
+
+/* For string conversions where numbers are also acceptable */
+#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \
+ _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,) \
+ _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,) \
struct __useless_struct_to_allow_trailing_semicolon__
+
+#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max) \
+ _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,static)
+#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max) \
+ _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,static)
diff --git a/src/systemd/src/basic/string-util.h b/src/systemd/src/basic/string-util.h
index ad0c813761..139cc8c91b 100644
--- a/src/systemd/src/basic/string-util.h
+++ b/src/systemd/src/basic/string-util.h
@@ -37,6 +37,7 @@
#define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS
#define ALPHANUMERICAL LETTERS DIGITS
+#define HEXDIGITS DIGITS "abcdefABCDEF"
#define streq(a,b) (strcmp((a),(b)) == 0)
#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
diff --git a/src/systemd/src/basic/strv.c b/src/systemd/src/basic/strv.c
index e885c5981e..4ee2e5cd69 100644
--- a/src/systemd/src/basic/strv.c
+++ b/src/systemd/src/basic/strv.c
@@ -28,9 +28,7 @@
#include "alloc-util.h"
#include "escape.h"
-#if 0 /* NM_IGNORED */
#include "extract-word.h"
-#endif /* NM_IGNORED */
#include "fileio.h"
#include "string-util.h"
#include "strv.h"
@@ -564,6 +562,42 @@ int strv_extend(char ***l, const char *value) {
return strv_consume(l, v);
}
+int strv_extend_front(char ***l, const char *value) {
+ size_t n, m;
+ char *v, **c;
+
+ assert(l);
+
+ /* Like strv_extend(), but prepends rather than appends the new entry */
+
+ if (!value)
+ return 0;
+
+ n = strv_length(*l);
+
+ /* Increase and overflow check. */
+ m = n + 2;
+ if (m < n)
+ return -ENOMEM;
+
+ v = strdup(value);
+ if (!v)
+ return -ENOMEM;
+
+ c = realloc_multiply(*l, sizeof(char*), m);
+ if (!c) {
+ free(v);
+ return -ENOMEM;
+ }
+
+ memmove(c+1, c, n * sizeof(char*));
+ c[0] = v;
+ c[n+1] = NULL;
+
+ *l = c;
+ return 0;
+}
+
char **strv_uniq(char **l) {
char **i;
diff --git a/src/systemd/src/basic/strv.h b/src/systemd/src/basic/strv.h
index 4a93818a42..f61bbb5386 100644
--- a/src/systemd/src/basic/strv.h
+++ b/src/systemd/src/basic/strv.h
@@ -25,9 +25,7 @@
#include <stddef.h>
#include "alloc-util.h"
-#if 0 /* NM_IGNORED */
#include "extract-word.h"
-#endif /* NM_IGNORED */
#include "macro.h"
#include "util.h"
@@ -52,6 +50,7 @@ int strv_extend_strv(char ***a, char **b, bool filter_duplicates);
int strv_extend_strv_concat(char ***a, char **b, const char *suffix);
int strv_extend(char ***l, const char *value);
int strv_extendf(char ***l, const char *format, ...) _printf_(2,0);
+int strv_extend_front(char ***l, const char *value);
int strv_push(char ***l, char *value);
int strv_push_pair(char ***l, char *a, char *b);
int strv_push_prepend(char ***l, char *value);
@@ -81,9 +80,7 @@ static inline bool strv_isempty(char * const *l) {
char **strv_split(const char *s, const char *separator);
char **strv_split_newlines(const char *s);
-#if 0 /* NM_IGNORED */
int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags);
-#endif /* NM_IGNORED */
char *strv_join(char **l, const char *separator);
char *strv_join_quoted(char **l);
diff --git a/src/systemd/src/basic/time-util.c b/src/systemd/src/basic/time-util.c
index 5b2b2180d8..ecff608712 100644
--- a/src/systemd/src/basic/time-util.c
+++ b/src/systemd/src/basic/time-util.c
@@ -49,15 +49,12 @@ static clockid_t map_clock_id(clockid_t c) {
/* Some more exotic archs (s390, ppc, …) lack the "ALARM" flavour of the clocks. Thus, clock_gettime() will
* fail for them. Since they are essentially the same as their non-ALARM pendants (their only difference is
* when timers are set on them), let's just map them accordingly. This way, we can get the correct time even on
- * those archs.
- *
- * Also, older kernels don't support CLOCK_BOOTTIME: fall back to CLOCK_MONOTONIC. */
+ * those archs. */
switch (c) {
- case CLOCK_BOOTTIME:
case CLOCK_BOOTTIME_ALARM:
- return clock_boottime_or_monotonic ();
+ return CLOCK_BOOTTIME;
case CLOCK_REALTIME_ALARM:
return CLOCK_REALTIME;
@@ -1089,22 +1086,31 @@ bool timezone_is_valid(const char *name) {
return true;
}
-clockid_t clock_boottime_or_monotonic(void) {
- static clockid_t clock = -1;
- int fd;
-
- if (clock != -1)
- return clock;
-
- fd = timerfd_create(CLOCK_BOOTTIME, TFD_NONBLOCK|TFD_CLOEXEC);
- if (fd < 0)
- clock = CLOCK_MONOTONIC;
- else {
- safe_close(fd);
- clock = CLOCK_BOOTTIME;
+bool clock_boottime_supported(void) {
+ static int supported = -1;
+
+ /* Note that this checks whether CLOCK_BOOTTIME is available in general as well as available for timerfds()! */
+
+ if (supported < 0) {
+ int fd;
+
+ fd = timerfd_create(CLOCK_BOOTTIME, TFD_NONBLOCK|TFD_CLOEXEC);
+ if (fd < 0)
+ supported = false;
+ else {
+ safe_close(fd);
+ supported = true;
+ }
}
- return clock;
+ return supported;
+}
+
+clockid_t clock_boottime_or_monotonic(void) {
+ if (clock_boottime_supported())
+ return CLOCK_BOOTTIME;
+ else
+ return CLOCK_MONOTONIC;
}
#if 0 /* NM_IGNORED */
diff --git a/src/systemd/src/basic/time-util.h b/src/systemd/src/basic/time-util.h
index 77e3cd08d4..a5e3f567ec 100644
--- a/src/systemd/src/basic/time-util.h
+++ b/src/systemd/src/basic/time-util.h
@@ -112,6 +112,7 @@ bool ntp_synced(void);
int get_timezones(char ***l);
bool timezone_is_valid(const char *name);
+bool clock_boottime_supported(void);
clockid_t clock_boottime_or_monotonic(void);
#define xstrftime(buf, fmt, tm) \
diff --git a/src/systemd/src/basic/util.c b/src/systemd/src/basic/util.c
index 6d641a4a3d..39eb79e360 100644
--- a/src/systemd/src/basic/util.c
+++ b/src/systemd/src/basic/util.c
@@ -60,13 +60,14 @@
#include "process-util.h"
#endif /* NM_IGNORED */
#include "set.h"
-#if 0 /* NM_IGNORED */
#include "signal-util.h"
+#if 0 /* NM_IGNORED */
#include "stat-util.h"
#endif /* NM_IGNORED */
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
+#include "umask-util.h"
#if 0 /* NM_IGNORED */
#include "user-util.h"
#endif /* NM_IGNORED */
@@ -436,13 +437,17 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa
_exit(EXIT_FAILURE);
}
- if (!stdout_is_tty)
- dup2(fd, STDOUT_FILENO);
+ if (!stdout_is_tty && dup2(fd, STDOUT_FILENO) < 0) {
+ log_error_errno(errno, "Failed to dup2 /dev/tty: %m");
+ _exit(EXIT_FAILURE);
+ }
- if (!stderr_is_tty)
- dup2(fd, STDERR_FILENO);
+ if (!stderr_is_tty && dup2(fd, STDERR_FILENO) < 0) {
+ log_error_errno(errno, "Failed to dup2 /dev/tty: %m");
+ _exit(EXIT_FAILURE);
+ }
- if (fd > 2)
+ if (fd > STDERR_FILENO)
close(fd);
}
@@ -534,7 +539,7 @@ int on_ac_power(void) {
if (!de)
break;
- if (hidden_file(de->d_name))
+ if (hidden_or_backup_file(de->d_name))
continue;
device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
@@ -790,15 +795,25 @@ uint64_t physical_memory(void) {
return (uint64_t) mem * (uint64_t) page_size();
}
-int update_reboot_param_file(const char *param) {
- int r = 0;
+int update_reboot_parameter_and_warn(const char *param) {
+ int r;
+
+ if (isempty(param)) {
+ if (unlink("/run/systemd/reboot-param") < 0) {
+ if (errno == ENOENT)
+ return 0;
+
+ return log_warning_errno(errno, "Failed to unlink reboot parameter file: %m");
+ }
+
+ return 0;
+ }
- if (param) {
- r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE);
+ RUN_WITH_UMASK(0022) {
+ r = write_string_file("/run/systemd/reboot-param", param, WRITE_STRING_FILE_CREATE);
if (r < 0)
- return log_error_errno(r, "Failed to write reboot param to "REBOOT_PARAM_FILE": %m");
- } else
- (void) unlink(REBOOT_PARAM_FILE);
+ return log_warning_errno(r, "Failed to write reboot parameter file: %m");
+ }
return 0;
}
diff --git a/src/systemd/src/basic/util.h b/src/systemd/src/basic/util.h
index 3225269acd..4b927e2e26 100644
--- a/src/systemd/src/basic/util.h
+++ b/src/systemd/src/basic/util.h
@@ -188,6 +188,6 @@ int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int
uint64_t physical_memory(void);
-int update_reboot_param_file(const char *param);
+int update_reboot_parameter_and_warn(const char *param);
int version(void);
diff --git a/src/systemd/src/libsystemd-network/dhcp-identifier.c b/src/systemd/src/libsystemd-network/dhcp-identifier.c
index c7a3eac5b7..69eecd0234 100644
--- a/src/systemd/src/libsystemd-network/dhcp-identifier.c
+++ b/src/systemd/src/libsystemd-network/dhcp-identifier.c
@@ -39,6 +39,37 @@
#define SYSTEMD_PEN 43793
#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
+int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
+ struct duid d;
+
+ assert_cc(sizeof(d.raw) >= MAX_DUID_LEN);
+ if (duid_len > MAX_DUID_LEN)
+ return -EINVAL;
+
+ switch (duid_type) {
+ case DUID_TYPE_LLT:
+ if (duid_len <= sizeof(d.llt))
+ return -EINVAL;
+ break;
+ case DUID_TYPE_EN:
+ if (duid_len != sizeof(d.en))
+ return -EINVAL;
+ break;
+ case DUID_TYPE_LL:
+ if (duid_len <= sizeof(d.ll))
+ return -EINVAL;
+ break;
+ case DUID_TYPE_UUID:
+ if (duid_len != sizeof(d.uuid))
+ return -EINVAL;
+ break;
+ default:
+ /* accept unknown type in order to be forward compatible */
+ break;
+ }
+ return 0;
+}
+
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
sd_id128_t machine_id;
uint64_t hash;
diff --git a/src/systemd/src/libsystemd-network/dhcp-identifier.h b/src/systemd/src/libsystemd-network/dhcp-identifier.h
index babae15c5b..1cc0f9fb71 100644
--- a/src/systemd/src/libsystemd-network/dhcp-identifier.h
+++ b/src/systemd/src/libsystemd-network/dhcp-identifier.h
@@ -26,7 +26,6 @@
#include "unaligned.h"
typedef enum DUIDType {
- DUID_TYPE_RAW = 0,
DUID_TYPE_LLT = 1,
DUID_TYPE_EN = 2,
DUID_TYPE_LL = 3,
@@ -40,27 +39,28 @@ typedef enum DUIDType {
*/
#define MAX_DUID_LEN 128
+/* https://tools.ietf.org/html/rfc3315#section-9.1 */
struct duid {
be16_t type;
union {
struct {
- /* DHCP6_DUID_LLT */
+ /* DUID_TYPE_LLT */
uint16_t htype;
uint32_t time;
uint8_t haddr[0];
} _packed_ llt;
struct {
- /* DHCP6_DUID_EN */
+ /* DUID_TYPE_EN */
uint32_t pen;
uint8_t id[8];
} _packed_ en;
struct {
- /* DHCP6_DUID_LL */
+ /* DUID_TYPE_LL */
int16_t htype;
uint8_t haddr[0];
} _packed_ ll;
struct {
- /* DHCP6_DUID_UUID */
+ /* DUID_TYPE_UUID */
sd_id128_t uuid;
} _packed_ uuid;
struct {
@@ -69,34 +69,6 @@ struct duid {
};
} _packed_;
+int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len);
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id);
-
-static inline int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
- struct duid d;
-
- assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
-
- switch (duid_type) {
- case DUID_TYPE_LLT:
- if (duid_len <= sizeof(d.llt))
- return -EINVAL;
- break;
- case DUID_TYPE_EN:
- if (duid_len != sizeof(d.en))
- return -EINVAL;
- break;
- case DUID_TYPE_LL:
- if (duid_len <= sizeof(d.ll))
- return -EINVAL;
- break;
- case DUID_TYPE_UUID:
- if (duid_len != sizeof(d.uuid))
- return -EINVAL;
- break;
- default:
- /* accept unknown type in order to be forward compatible */
- break;
- }
- return 0;
-}
diff --git a/src/systemd/src/libsystemd-network/dhcp-internal.h b/src/systemd/src/libsystemd-network/dhcp-internal.h
index 4662b0d847..99f690897d 100644
--- a/src/systemd/src/libsystemd-network/dhcp-internal.h
+++ b/src/systemd/src/libsystemd-network/dhcp-internal.h
@@ -65,4 +65,5 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum);
#define DHCP_CLIENT_DONT_DESTROY(client) \
_cleanup_(sd_dhcp_client_unrefp) _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client)
-#define log_dhcp_client(client, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__)
+#define log_dhcp_client_errno(client, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__)
+#define log_dhcp_client(client, fmt, ...) log_dhcp_client_errno(client, 0, fmt, ##__VA_ARGS__)
diff --git a/src/systemd/src/libsystemd-network/dhcp-protocol.h b/src/systemd/src/libsystemd-network/dhcp-protocol.h
index 3e32484c1d..5cf7abbff9 100644
--- a/src/systemd/src/libsystemd-network/dhcp-protocol.h
+++ b/src/systemd/src/libsystemd-network/dhcp-protocol.h
@@ -59,7 +59,7 @@ typedef struct DHCPPacket DHCPPacket;
#define DHCP_IP_UDP_SIZE (int32_t)(sizeof(struct udphdr) + DHCP_IP_SIZE)
#define DHCP_MESSAGE_SIZE (int32_t)(sizeof(DHCPMessage))
#define DHCP_DEFAULT_MIN_SIZE 576 /* the minimum internet hosts must be able to receive */
-#define DHCP_MIN_OPTIONS_SIZE DHCP_DEFAULT_MIN_SIZE - DHCP_IP_UDP_SIZE - DHCP_MESSAGE_SIZE
+#define DHCP_MIN_OPTIONS_SIZE (DHCP_DEFAULT_MIN_SIZE - DHCP_IP_UDP_SIZE - DHCP_MESSAGE_SIZE)
#define DHCP_MAGIC_COOKIE (uint32_t)(0x63825363)
enum {
diff --git a/src/systemd/src/libsystemd-network/dhcp6-internal.h b/src/systemd/src/libsystemd-network/dhcp6-internal.h
index 749086d33a..945c3b9721 100644
--- a/src/systemd/src/libsystemd-network/dhcp6-internal.h
+++ b/src/systemd/src/libsystemd-network/dhcp6-internal.h
@@ -55,7 +55,8 @@ struct DHCP6IA {
typedef struct DHCP6IA DHCP6IA;
-#define log_dhcp6_client(p, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
+#define log_dhcp6_client_errno(p, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
+#define log_dhcp6_client(p, fmt, ...) log_dhcp6_client_errno(p, 0, fmt, ##__VA_ARGS__)
int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
size_t optlen, const void *optval);
diff --git a/src/systemd/src/libsystemd-network/network-internal.c b/src/systemd/src/libsystemd-network/network-internal.c
index 55fcc1da03..25bad0f54b 100644
--- a/src/systemd/src/libsystemd-network/network-internal.c
+++ b/src/systemd/src/libsystemd-network/network-internal.c
@@ -31,11 +31,13 @@
#include "conf-parser.h"
#endif /* NM_IGNORED */
#include "dhcp-lease-internal.h"
+#include "ether-addr-util.h"
#include "hexdecoct.h"
#include "log.h"
#include "network-internal.h"
#include "parse-util.h"
#include "siphash24.h"
+#include "socket-util.h"
#include "string-util.h"
#include "strv.h"
#include "utf8.h"
@@ -180,58 +182,19 @@ int config_parse_net_condition(const char *unit,
return 0;
}
-int config_parse_ifname(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- char **s = data;
- _cleanup_free_ char *n = NULL;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- n = strdup(rvalue);
- if (!n)
- return log_oom();
-
- if (!ascii_is_valid(n) || strlen(n) >= IFNAMSIZ) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
- return 0;
- }
-
- free(*s);
- if (*n) {
- *s = n;
- n = NULL;
- } else
- *s = NULL;
-
- return 0;
-}
-
-int config_parse_ifnames(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
+int config_parse_ifnames(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
char ***sv = data;
- const char *word, *state;
- size_t l;
int r;
assert(filename);
@@ -239,22 +202,27 @@ int config_parse_ifnames(const char *unit,
assert(rvalue);
assert(data);
- FOREACH_WORD(word, l, rvalue, state) {
- char *n;
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
- n = strndup(word, l);
- if (!n)
- return log_oom();
+ r = extract_first_word(&rvalue, &word, NULL, 0);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse interface name list: %s", rvalue);
+ return 0;
+ }
+ if (r == 0)
+ break;
- if (!ascii_is_valid(n) || strlen(n) >= IFNAMSIZ) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
- free(n);
+ if (!ifname_valid(word)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not valid or too long, ignoring assignment: %s", rvalue);
return 0;
}
- r = strv_consume(sv, n);
+ r = strv_push(sv, word);
if (r < 0)
return log_oom();
+
+ word = NULL;
}
return 0;
@@ -310,6 +278,8 @@ int config_parse_hwaddr(const char *unit,
void *userdata) {
struct ether_addr **hwaddr = data;
struct ether_addr *n;
+ const char *start;
+ size_t offset;
int r;
assert(filename);
@@ -321,14 +291,10 @@ int config_parse_hwaddr(const char *unit,
if (!n)
return log_oom();
- r = sscanf(rvalue, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
- &n->ether_addr_octet[0],
- &n->ether_addr_octet[1],
- &n->ether_addr_octet[2],
- &n->ether_addr_octet[3],
- &n->ether_addr_octet[4],
- &n->ether_addr_octet[5]);
- if (r != 6) {
+ start = rvalue + strspn(rvalue, WHITESPACE);
+ r = ether_addr_from_string(start, n, &offset);
+
+ if (r || (start[offset + strspn(start + offset, WHITESPACE)] != '\0')) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Not a valid MAC address, ignoring assignment: %s", rvalue);
free(n);
return 0;
@@ -360,8 +326,9 @@ int config_parse_iaid(const char *unit,
r = safe_atou32(rvalue, &iaid);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Unable to read IAID: %s", rvalue);
- return r;
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Unable to read IAID, ignoring assignment: %s", rvalue);
+ return 0;
}
*((uint32_t *)data) = iaid;
@@ -385,28 +352,28 @@ void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) {
int deserialize_in_addrs(struct in_addr **ret, const char *string) {
_cleanup_free_ struct in_addr *addresses = NULL;
int size = 0;
- const char *word, *state;
- size_t len;
assert(ret);
assert(string);
- FOREACH_WORD(word, len, string, state) {
- _cleanup_free_ char *addr_str = NULL;
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
struct in_addr *new_addresses;
int r;
+ r = extract_first_word(&string, &word, NULL, 0);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
new_addresses = realloc(addresses, (size + 1) * sizeof(struct in_addr));
if (!new_addresses)
return -ENOMEM;
else
addresses = new_addresses;
- addr_str = strndup(word, len);
- if (!addr_str)
- return -ENOMEM;
-
- r = inet_pton(AF_INET, addr_str, &(addresses[size]));
+ r = inet_pton(AF_INET, word, &(addresses[size]));
if (r <= 0)
continue;
@@ -436,28 +403,28 @@ void serialize_in6_addrs(FILE *f, const struct in6_addr *addresses,
int deserialize_in6_addrs(struct in6_addr **ret, const char *string) {
_cleanup_free_ struct in6_addr *addresses = NULL;
int size = 0;
- const char *word, *state;
- size_t len;
assert(ret);
assert(string);
- FOREACH_WORD(word, len, string, state) {
- _cleanup_free_ char *addr_str = NULL;
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
struct in6_addr *new_addresses;
int r;
+ r = extract_first_word(&string, &word, NULL, 0);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
new_addresses = realloc(addresses, (size + 1) * sizeof(struct in6_addr));
if (!new_addresses)
return -ENOMEM;
else
addresses = new_addresses;
- addr_str = strndup(word, len);
- if (!addr_str)
- return -ENOMEM;
-
- r = inet_pton(AF_INET6, addr_str, &(addresses[size]));
+ r = inet_pton(AF_INET6, word, &(addresses[size]));
if (r <= 0)
continue;
@@ -498,29 +465,29 @@ void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, siz
int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string) {
_cleanup_free_ struct sd_dhcp_route *routes = NULL;
size_t size = 0, allocated = 0;
- const char *word, *state;
- size_t len;
assert(ret);
assert(ret_size);
assert(ret_allocated);
assert(string);
- FOREACH_WORD(word, len, string, state) {
- /* WORD FORMAT: dst_ip/dst_prefixlen,gw_ip */
- _cleanup_free_ char* entry = NULL;
+ /* WORD FORMAT: dst_ip/dst_prefixlen,gw_ip */
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
char *tok, *tok_end;
unsigned n;
int r;
- if (!GREEDY_REALLOC(routes, allocated, size + 1))
- return -ENOMEM;
+ r = extract_first_word(&string, &word, NULL, 0);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
- entry = strndup(word, len);
- if (!entry)
+ if (!GREEDY_REALLOC(routes, allocated, size + 1))
return -ENOMEM;
- tok = entry;
+ tok = word;
/* get the subnet */
tok_end = strchr(tok, '/');
diff --git a/src/systemd/src/libsystemd-network/network-internal.h b/src/systemd/src/libsystemd-network/network-internal.h
index 955cc89870..e91d3d2918 100644
--- a/src/systemd/src/libsystemd-network/network-internal.h
+++ b/src/systemd/src/libsystemd-network/network-internal.h
@@ -51,10 +51,6 @@ int config_parse_hwaddr(const char *unit, const char *filename, unsigned line,
const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_ifname(const char *unit, const char *filename, unsigned line,
- const char *section, unsigned section_line, const char *lvalue,
- int ltype, const char *rvalue, void *data, void *userdata);
-
int config_parse_ifnames(const char *unit, const char *filename, unsigned line,
const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
index 758dba4b66..f740075a12 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
@@ -55,7 +55,7 @@ struct sd_dhcp_client {
sd_event *event;
int event_priority;
sd_event_source *timeout_resend;
- int index;
+ int ifindex;
int fd;
union sockaddr_union link;
sd_event_source *receive_message;
@@ -103,7 +103,7 @@ struct sd_dhcp_client {
sd_event_source *timeout_t1;
sd_event_source *timeout_t2;
sd_event_source *timeout_expire;
- sd_dhcp_client_callback_t cb;
+ sd_dhcp_client_callback_t callback;
void *userdata;
sd_dhcp_lease *lease;
usec_t start_delay;
@@ -117,17 +117,26 @@ static const uint8_t default_req_opts[] = {
SD_DHCP_OPTION_DOMAIN_NAME_SERVER,
};
-static int client_receive_message_raw(sd_event_source *s, int fd,
- uint32_t revents, void *userdata);
-static int client_receive_message_udp(sd_event_source *s, int fd,
- uint32_t revents, void *userdata);
+static int client_receive_message_raw(
+ sd_event_source *s,
+ int fd,
+ uint32_t revents,
+ void *userdata);
+static int client_receive_message_udp(
+ sd_event_source *s,
+ int fd,
+ uint32_t revents,
+ void *userdata);
static void client_stop(sd_dhcp_client *client, int error);
-int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_callback_t cb,
- void *userdata) {
+int sd_dhcp_client_set_callback(
+ sd_dhcp_client *client,
+ sd_dhcp_client_callback_t cb,
+ void *userdata) {
+
assert_return(client, -EINVAL);
- client->cb = cb;
+ client->callback = cb;
client->userdata = userdata;
return 0;
@@ -145,10 +154,10 @@ int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
size_t i;
assert_return(client, -EINVAL);
- assert_return (IN_SET(client->state, DHCP_STATE_INIT,
- DHCP_STATE_STOPPED), -EBUSY);
+ assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY);
switch(option) {
+
case SD_DHCP_OPTION_PAD:
case SD_DHCP_OPTION_OVERLOAD:
case SD_DHCP_OPTION_MESSAGE_TYPE:
@@ -173,11 +182,12 @@ int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
return 0;
}
-int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
- const struct in_addr *last_addr) {
+int sd_dhcp_client_set_request_address(
+ sd_dhcp_client *client,
+ const struct in_addr *last_addr) {
+
assert_return(client, -EINVAL);
- assert_return (IN_SET(client->state, DHCP_STATE_INIT,
- DHCP_STATE_STOPPED), -EBUSY);
+ assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY);
if (last_addr)
client->last_addr = last_addr->s_addr;
@@ -187,19 +197,22 @@ int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
return 0;
}
-int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index) {
- assert_return(client, -EINVAL);
- assert_return (IN_SET(client->state, DHCP_STATE_INIT,
- DHCP_STATE_STOPPED), -EBUSY);
- assert_return(interface_index > 0, -EINVAL);
+int sd_dhcp_client_set_ifindex(sd_dhcp_client *client, int ifindex) {
- client->index = interface_index;
+ assert_return(client, -EINVAL);
+ assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY);
+ assert_return(ifindex > 0, -EINVAL);
+ client->ifindex = ifindex;
return 0;
}
-int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
- size_t addr_len, uint16_t arp_type) {
+int sd_dhcp_client_set_mac(
+ sd_dhcp_client *client,
+ const uint8_t *addr,
+ size_t addr_len,
+ uint16_t arp_type) {
+
DHCP_CLIENT_DONT_DESTROY(client);
bool need_restart = false;
@@ -220,8 +233,7 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
return 0;
if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
- log_dhcp_client(client, "Changing MAC address on running DHCP "
- "client, restarting");
+ log_dhcp_client(client, "Changing MAC address on running DHCP client, restarting");
need_restart = true;
client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
}
@@ -236,8 +248,11 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
return 0;
}
-int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
- const uint8_t **data, size_t *data_len) {
+int sd_dhcp_client_get_client_id(
+ sd_dhcp_client *client,
+ uint8_t *type,
+ const uint8_t **data,
+ size_t *data_len) {
assert_return(client, -EINVAL);
assert_return(type, -EINVAL);
@@ -256,8 +271,12 @@ int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
return 0;
}
-int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
- const uint8_t *data, size_t data_len) {
+int sd_dhcp_client_set_client_id(
+ sd_dhcp_client *client,
+ uint8_t type,
+ const uint8_t *data,
+ size_t data_len) {
+
DHCP_CLIENT_DONT_DESTROY(client);
bool need_restart = false;
@@ -266,14 +285,17 @@ int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
assert_return(data_len > 0 && data_len <= MAX_CLIENT_ID_LEN, -EINVAL);
switch (type) {
+
case ARPHRD_ETHER:
if (data_len != ETH_ALEN)
return -EINVAL;
break;
+
case ARPHRD_INFINIBAND:
if (data_len != INFINIBAND_ALEN)
return -EINVAL;
break;
+
default:
break;
}
@@ -301,18 +323,37 @@ int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
}
#if 0 /* NM_IGNORED */
-int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid,
- uint16_t duid_type, uint8_t *duid, size_t duid_len) {
+/**
+ * Sets IAID and DUID. If duid is non-null, the DUID is set to duid_type + duid
+ * without further modification. Otherwise, if duid_type is supported, DUID
+ * is set based on that type. Otherwise, an error is returned.
+ */
+int sd_dhcp_client_set_iaid_duid(
+ sd_dhcp_client *client,
+ uint32_t iaid,
+ uint16_t duid_type,
+ const void *duid,
+ size_t duid_len) {
+
DHCP_CLIENT_DONT_DESTROY(client);
int r;
+ size_t len;
+
assert_return(client, -EINVAL);
- zero(client->client_id);
+ assert_return(duid_len == 0 || duid != NULL, -EINVAL);
+ if (duid != NULL) {
+ r = dhcp_validate_duid_len(duid_type, duid_len);
+ if (r < 0)
+ return r;
+ }
+
+ zero(client->client_id);
client->client_id.type = 255;
/* If IAID is not configured, generate it. */
if (iaid == 0) {
- r = dhcp_identifier_set_iaid(client->index, client->mac_addr,
+ r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr,
client->mac_addr_len,
&client->client_id.ns.iaid);
if (r < 0)
@@ -320,22 +361,18 @@ int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid,
} else
client->client_id.ns.iaid = htobe32(iaid);
- /* If DUID is not configured, generate DUID-EN. */
- if (duid_len == 0) {
- r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid,
- &duid_len);
- if (r < 0)
- return r;
- } else {
- r = dhcp_validate_duid_len(client->client_id.type, duid_len);
- if (r < 0)
- return r;
+ if (duid != NULL) {
client->client_id.ns.duid.type = htobe16(duid_type);
memcpy(&client->client_id.ns.duid.raw.data, duid, duid_len);
- duid_len += sizeof(client->client_id.ns.duid.type);
- }
+ len = sizeof(client->client_id.ns.duid.type) + duid_len;
+ } else if (duid_type == DUID_TYPE_EN) {
+ r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &len);
+ if (r < 0)
+ return r;
+ } else
+ return -EOPNOTSUPP;
- client->client_id_len = sizeof(client->client_id.type) + duid_len +
+ client->client_id_len = sizeof(client->client_id.type) + len +
sizeof(client->client_id.ns.iaid);
if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
@@ -348,8 +385,10 @@ int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid,
}
#endif /* NM_IGNORED */
-int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
- const char *hostname) {
+int sd_dhcp_client_set_hostname(
+ sd_dhcp_client *client,
+ const char *hostname) {
+
char *new_hostname = NULL;
assert_return(client, -EINVAL);
@@ -372,8 +411,10 @@ int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
return 0;
}
-int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client,
- const char *vci) {
+int sd_dhcp_client_set_vendor_class_identifier(
+ sd_dhcp_client *client,
+ const char *vci) {
+
char *new_vci = NULL;
assert_return(client, -EINVAL);
@@ -400,28 +441,29 @@ int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu) {
int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
assert_return(client, -EINVAL);
- assert_return(ret, -EINVAL);
if (client->state != DHCP_STATE_BOUND &&
client->state != DHCP_STATE_RENEWING &&
client->state != DHCP_STATE_REBINDING)
return -EADDRNOTAVAIL;
- *ret = client->lease;
+ if (ret)
+ *ret = client->lease;
return 0;
}
static void client_notify(sd_dhcp_client *client, int event) {
- if (client->cb)
- client->cb(client, event, client->userdata);
+ assert(client);
+
+ if (client->callback)
+ client->callback(client, event, client->userdata);
}
static int client_initialize(sd_dhcp_client *client) {
assert_return(client, -EINVAL);
- client->receive_message =
- sd_event_source_unref(client->receive_message);
+ client->receive_message = sd_event_source_unref(client->receive_message);
client->fd = asynchronous_close(client->fd);
@@ -456,8 +498,13 @@ static void client_stop(sd_dhcp_client *client, int error) {
client_initialize(client);
}
-static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
- uint8_t type, size_t *_optlen, size_t *_optoffset) {
+static int client_message_init(
+ sd_dhcp_client *client,
+ DHCPPacket **ret,
+ uint8_t type,
+ size_t *_optlen,
+ size_t *_optoffset) {
+
_cleanup_free_ DHCPPacket *packet = NULL;
size_t optlen, optoffset, size;
be16_t max_size;
@@ -525,7 +572,7 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
client->client_id.type = 255;
- r = dhcp_identifier_set_iaid(client->index, client->mac_addr, client->mac_addr_len, &client->client_id.ns.iaid);
+ r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, &client->client_id.ns.iaid);
if (r < 0)
return r;
@@ -598,8 +645,12 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
return 0;
}
-static int client_append_fqdn_option(DHCPMessage *message, size_t optlen, size_t *optoffset,
- const char *fqdn) {
+static int client_append_fqdn_option(
+ DHCPMessage *message,
+ size_t optlen,
+ size_t *optoffset,
+ const char *fqdn) {
+
uint8_t buffer[3 + DHCP_MAX_FQDN_LENGTH];
int r;
@@ -616,8 +667,11 @@ static int client_append_fqdn_option(DHCPMessage *message, size_t optlen, size_t
return r;
}
-static int dhcp_client_send_raw(sd_dhcp_client *client, DHCPPacket *packet,
- size_t len) {
+static int dhcp_client_send_raw(
+ sd_dhcp_client *client,
+ DHCPPacket *packet,
+ size_t len) {
+
dhcp_packet_append_ip_headers(packet, INADDR_ANY, DHCP_PORT_CLIENT,
INADDR_BROADCAST, DHCP_PORT_SERVER, len);
@@ -704,8 +758,9 @@ static int client_send_request(sd_dhcp_client *client) {
size_t optoffset, optlen;
int r;
- r = client_message_init(client, &request, DHCP_REQUEST,
- &optlen, &optoffset);
+ assert(client);
+
+ r = client_message_init(client, &request, DHCP_REQUEST, &optlen, &optoffset);
if (r < 0)
return r;
@@ -802,18 +857,23 @@ static int client_send_request(sd_dhcp_client *client) {
return r;
switch (client->state) {
+
case DHCP_STATE_REQUESTING:
log_dhcp_client(client, "REQUEST (requesting)");
break;
+
case DHCP_STATE_INIT_REBOOT:
log_dhcp_client(client, "REQUEST (init-reboot)");
break;
+
case DHCP_STATE_RENEWING:
log_dhcp_client(client, "REQUEST (renewing)");
break;
+
case DHCP_STATE_REBINDING:
log_dhcp_client(client, "REQUEST (rebinding)");
break;
+
default:
log_dhcp_client(client, "REQUEST (invalid)");
break;
@@ -824,8 +884,11 @@ static int client_send_request(sd_dhcp_client *client) {
static int client_start(sd_dhcp_client *client);
-static int client_timeout_resend(sd_event_source *s, uint64_t usec,
- void *userdata) {
+static int client_timeout_resend(
+ sd_event_source *s,
+ uint64_t usec,
+ void *userdata) {
+
sd_dhcp_client *client = userdata;
DHCP_CLIENT_DONT_DESTROY(client);
usec_t next_timeout = 0;
@@ -842,6 +905,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec,
goto error;
switch (client->state) {
+
case DHCP_STATE_RENEWING:
time_left = (client->lease->t2 - client->lease->t1) / 2;
@@ -969,8 +1033,10 @@ error:
return 0;
}
-static int client_initialize_io_events(sd_dhcp_client *client,
- sd_event_io_handler_t io_callback) {
+static int client_initialize_io_events(
+ sd_dhcp_client *client,
+ sd_event_io_handler_t io_callback) {
+
int r;
assert(client);
@@ -1037,8 +1103,7 @@ error:
}
-static int client_initialize_events(sd_dhcp_client *client,
- sd_event_io_handler_t io_callback) {
+static int client_initialize_events(sd_dhcp_client *client, sd_event_io_handler_t io_callback) {
client_initialize_io_events(client, io_callback);
client_initialize_time_events(client);
@@ -1050,15 +1115,14 @@ static int client_start_delayed(sd_dhcp_client *client) {
assert_return(client, -EINVAL);
assert_return(client->event, -EINVAL);
- assert_return(client->index > 0, -EINVAL);
+ assert_return(client->ifindex > 0, -EINVAL);
assert_return(client->fd < 0, -EBUSY);
assert_return(client->xid == 0, -EINVAL);
- assert_return(client->state == DHCP_STATE_INIT ||
- client->state == DHCP_STATE_INIT_REBOOT, -EBUSY);
+ assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT), -EBUSY);
client->xid = random_u32();
- r = dhcp_network_bind_raw_socket(client->index, &client->link,
+ r = dhcp_network_bind_raw_socket(client->ifindex, &client->link,
client->xid, client->mac_addr,
client->mac_addr_len, client->arp_type);
if (r < 0) {
@@ -1078,8 +1142,7 @@ static int client_start(sd_dhcp_client *client) {
return client_start_delayed(client);
}
-static int client_timeout_expire(sd_event_source *s, uint64_t usec,
- void *userdata) {
+static int client_timeout_expire(sd_event_source *s, uint64_t usec, void *userdata) {
sd_dhcp_client *client = userdata;
DHCP_CLIENT_DONT_DESTROY(client);
@@ -1101,13 +1164,15 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
DHCP_CLIENT_DONT_DESTROY(client);
int r;
+ assert(client);
+
client->receive_message = sd_event_source_unref(client->receive_message);
client->fd = asynchronous_close(client->fd);
client->state = DHCP_STATE_REBINDING;
client->attempt = 1;
- r = dhcp_network_bind_raw_socket(client->index, &client->link,
+ r = dhcp_network_bind_raw_socket(client->ifindex, &client->link,
client->xid, client->mac_addr,
client->mac_addr_len, client->arp_type);
if (r < 0) {
@@ -1119,8 +1184,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
return client_initialize_events(client, client_receive_message_raw);
}
-static int client_timeout_t1(sd_event_source *s, uint64_t usec,
- void *userdata) {
+static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) {
sd_dhcp_client *client = userdata;
DHCP_CLIENT_DONT_DESTROY(client);
@@ -1130,8 +1194,7 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec,
return client_initialize_time_events(client);
}
-static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
- size_t len) {
+static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, size_t len) {
_cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
int r;
@@ -1182,8 +1245,7 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
return 0;
}
-static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force,
- size_t len) {
+static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force, size_t len) {
int r;
r = dhcp_option_parse(force, len, NULL, NULL, NULL);
@@ -1195,8 +1257,7 @@ static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force,
return 0;
}
-static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
- size_t len) {
+static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, size_t len) {
_cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
_cleanup_free_ char *error_message = NULL;
int r;
@@ -1424,8 +1485,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
return 0;
}
-static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
- int len) {
+static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, int len) {
DHCP_CLIENT_DONT_DESTROY(client);
char time_string[FORMAT_TIMESPAN_MAX];
int r = 0, notify_event = 0;
@@ -1571,11 +1631,15 @@ error:
return r;
}
-static int client_receive_message_udp(sd_event_source *s, int fd,
- uint32_t revents, void *userdata) {
+static int client_receive_message_udp(
+ sd_event_source *s,
+ int fd,
+ uint32_t revents,
+ void *userdata) {
+
sd_dhcp_client *client = userdata;
_cleanup_free_ DHCPMessage *message = NULL;
- const struct ether_addr zero_mac = { { 0, 0, 0, 0, 0, 0 } };
+ const struct ether_addr zero_mac = {};
const struct ether_addr *expected_chaddr = NULL;
uint8_t expected_hlen = 0;
ssize_t len, buflen;
@@ -1591,14 +1655,14 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
if (!message)
return -ENOMEM;
- len = read(fd, message, buflen);
+ len = recv(fd, message, buflen, 0);
if (len < 0) {
if (errno == EAGAIN || errno == EINTR)
return 0;
- log_dhcp_client(client, "Could not receive message from UDP socket: %m");
- return -errno;
- } else if ((size_t)len < sizeof(DHCPMessage)) {
+ return log_dhcp_client_errno(client, errno, "Could not receive message from UDP socket: %m");
+ }
+ if ((size_t) len < sizeof(DHCPMessage)) {
log_dhcp_client(client, "Too small to be a DHCP message: ignoring");
return 0;
}
@@ -1649,8 +1713,12 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
return client_handle_message(client, message, len);
}
-static int client_receive_message_raw(sd_event_source *s, int fd,
- uint32_t revents, void *userdata) {
+static int client_receive_message_raw(
+ sd_event_source *s,
+ int fd,
+ uint32_t revents,
+ void *userdata) {
+
sd_dhcp_client *client = userdata;
_cleanup_free_ DHCPPacket *packet = NULL;
uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
@@ -1725,7 +1793,7 @@ int sd_dhcp_client_start(sd_dhcp_client *client) {
r = client_start(client);
if (r >= 0)
- log_dhcp_client(client, "STARTED on ifindex %i", client->index);
+ log_dhcp_client(client, "STARTED on ifindex %i", client->ifindex);
return r;
}
@@ -1769,8 +1837,7 @@ int sd_dhcp_client_detach_event(sd_dhcp_client *client) {
}
sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
- if (!client)
- return NULL;
+ assert_return(client, NULL);
return client->event;
}
@@ -1826,13 +1893,12 @@ int sd_dhcp_client_new(sd_dhcp_client **ret) {
client->n_ref = 1;
client->state = DHCP_STATE_INIT;
- client->index = -1;
+ client->ifindex = -1;
client->fd = -1;
client->attempt = 1;
client->mtu = DHCP_DEFAULT_MIN_SIZE;
client->req_opts_size = ELEMENTSOF(default_req_opts);
-
client->req_opts = memdup(default_req_opts, client->req_opts_size);
if (!client->req_opts)
return -ENOMEM;
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
index 8fa1822f2d..a05bde637a 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
@@ -47,7 +47,7 @@ struct sd_dhcp6_client {
enum DHCP6State state;
sd_event *event;
int event_priority;
- int index;
+ int ifindex;
struct in6_addr local_address;
uint8_t mac_addr[MAX_MAC_ADDR_LEN];
size_t mac_addr_len;
@@ -66,7 +66,7 @@ struct sd_dhcp6_client {
uint8_t retransmit_count;
sd_event_source *timeout_resend;
sd_event_source *timeout_resend_expire;
- sd_dhcp6_client_callback_t cb;
+ sd_dhcp6_client_callback_t callback;
void *userdata;
struct duid duid;
size_t duid_len;
@@ -113,27 +113,33 @@ DEFINE_STRING_TABLE_LOOKUP(dhcp6_message_status, int);
static int client_start(sd_dhcp6_client *client, enum DHCP6State state);
-int sd_dhcp6_client_set_callback(sd_dhcp6_client *client, sd_dhcp6_client_callback_t cb, void *userdata) {
+int sd_dhcp6_client_set_callback(
+ sd_dhcp6_client *client,
+ sd_dhcp6_client_callback_t cb,
+ void *userdata) {
+
assert_return(client, -EINVAL);
- client->cb = cb;
+ client->callback = cb;
client->userdata = userdata;
return 0;
}
-int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index) {
- assert_return(client, -EINVAL);
- assert_return(interface_index >= -1, -EINVAL);
+int sd_dhcp6_client_set_ifindex(sd_dhcp6_client *client, int ifindex) {
+ assert_return(client, -EINVAL);
+ assert_return(ifindex >= -1, -EINVAL);
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
- client->index = interface_index;
-
+ client->ifindex = ifindex;
return 0;
}
-int sd_dhcp6_client_set_local_address(sd_dhcp6_client *client, const struct in6_addr *local_address) {
+int sd_dhcp6_client_set_local_address(
+ sd_dhcp6_client *client,
+ const struct in6_addr *local_address) {
+
assert_return(client, -EINVAL);
assert_return(local_address, -EINVAL);
assert_return(in_addr_is_link_local(AF_INET6, (const union in_addr_union *) local_address) > 0, -EINVAL);
@@ -182,20 +188,38 @@ static int client_ensure_duid(sd_dhcp6_client *client) {
return dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
}
-int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t duid_type,
- uint8_t *duid, size_t duid_len) {
+/**
+ * Sets DUID. If duid is non-null, the DUID is set to duid_type + duid
+ * without further modification. Otherwise, if duid_type is supported, DUID
+ * is set based on that type. Otherwise, an error is returned.
+ */
+int sd_dhcp6_client_set_duid(
+ sd_dhcp6_client *client,
+ uint16_t duid_type,
+ const void *duid,
+ size_t duid_len) {
+
int r;
assert_return(client, -EINVAL);
+ assert_return(duid_len == 0 || duid != NULL, -EINVAL);
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
- if (duid_len > 0) {
+ if (duid != NULL) {
r = dhcp_validate_duid_len(duid_type, duid_len);
if (r < 0)
return r;
+ }
+
+ if (duid != NULL) {
client->duid.type = htobe16(duid_type);
memcpy(&client->duid.raw.data, duid, duid_len);
- client->duid_len = duid_len + sizeof(client->duid.type);
- }
+ client->duid_len = sizeof(client->duid.type) + duid_len;
+ } else if (duid_type == DUID_TYPE_EN) {
+ r = dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
+ if (r < 0)
+ return r;
+ } else
+ return -EOPNOTSUPP;
return 0;
}
@@ -236,6 +260,7 @@ int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option)
assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
switch(option) {
+
case SD_DHCP6_OPTION_DNS_SERVERS:
case SD_DHCP6_OPTION_DOMAIN_LIST:
case SD_DHCP6_OPTION_SNTP_SERVERS:
@@ -272,20 +297,25 @@ int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret) {
}
static void client_notify(sd_dhcp6_client *client, int event) {
- if (client->cb)
- client->cb(client, event, client->userdata);
+ assert(client);
+
+ if (client->callback)
+ client->callback(client, event, client->userdata);
}
static void client_set_lease(sd_dhcp6_client *client, sd_dhcp6_lease *lease) {
+ assert(client);
+
if (client->lease) {
dhcp6_lease_clear_timers(&client->lease->ia);
sd_dhcp6_lease_unref(client->lease);
}
+
client->lease = lease;
}
static int client_reset(sd_dhcp6_client *client) {
- assert_return(client, -EINVAL);
+ assert(client);
client_set_lease(client, NULL);
@@ -333,6 +363,8 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
usec_t elapsed_usec;
be16_t elapsed_time;
+ assert(client);
+
len = sizeof(DHCP6Message) + optlen;
message = malloc0(len);
@@ -431,13 +463,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
return 0;
}
-static int client_timeout_t2(sd_event_source *s, uint64_t usec,
- void *userdata) {
+static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
sd_dhcp6_client *client = userdata;
- assert_return(s, -EINVAL);
- assert_return(client, -EINVAL);
- assert_return(client->lease, -EINVAL);
+ assert(s);
+ assert(client);
+ assert(client->lease);
client->lease->ia.timeout_t2 =
sd_event_source_unref(client->lease->ia.timeout_t2);
@@ -449,13 +480,12 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec,
return 0;
}
-static int client_timeout_t1(sd_event_source *s, uint64_t usec,
- void *userdata) {
+static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) {
sd_dhcp6_client *client = userdata;
- assert_return(s, -EINVAL);
- assert_return(client, -EINVAL);
- assert_return(client->lease, -EINVAL);
+ assert(s);
+ assert(client);
+ assert(client->lease);
client->lease->ia.timeout_t1 =
sd_event_source_unref(client->lease->ia.timeout_t1);
@@ -467,8 +497,7 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec,
return 0;
}
-static int client_timeout_resend_expire(sd_event_source *s, uint64_t usec,
- void *userdata) {
+static int client_timeout_resend_expire(sd_event_source *s, uint64_t usec, void *userdata) {
sd_dhcp6_client *client = userdata;
DHCP6_CLIENT_DONT_DESTROY(client);
enum DHCP6State state;
@@ -494,8 +523,7 @@ static usec_t client_timeout_compute_random(usec_t val) {
(random_u32() % (2 * USEC_PER_SEC)) * val / 10 / USEC_PER_SEC;
}
-static int client_timeout_resend(sd_event_source *s, uint64_t usec,
- void *userdata) {
+static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userdata) {
int r = 0;
sd_dhcp6_client *client = userdata;
usec_t time_now, init_retransmit_time = 0, max_retransmit_time = 0;
@@ -655,16 +683,18 @@ static int client_ensure_iaid(sd_dhcp6_client *client) {
if (client->ia_na.id)
return 0;
- r = dhcp_identifier_set_iaid(client->index, client->mac_addr, client->mac_addr_len, &client->ia_na.id);
+ r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, &client->ia_na.id);
if (r < 0)
return r;
return 0;
}
-static int client_parse_message(sd_dhcp6_client *client,
- DHCP6Message *message, size_t len,
- sd_dhcp6_lease *lease) {
+static int client_parse_message(
+ sd_dhcp6_client *client,
+ DHCP6Message *message,
+ size_t len,
+ sd_dhcp6_lease *lease) {
int r;
uint8_t *optval, *option, *id = NULL;
uint16_t optcode, status;
@@ -672,6 +702,11 @@ static int client_parse_message(sd_dhcp6_client *client,
bool clientid = false;
be32_t iaid_lease;
+ assert(client);
+ assert(message);
+ assert(len >= sizeof(DHCP6Message));
+ assert(lease);
+
option = (uint8_t *)message + sizeof(DHCP6Message);
len -= sizeof(DHCP6Message);
@@ -816,9 +851,12 @@ static int client_parse_message(sd_dhcp6_client *client,
}
static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, size_t len) {
- int r;
_cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
bool rapid_commit;
+ int r;
+
+ assert(client);
+ assert(reply);
if (reply->type != DHCP6_REPLY)
return 0;
@@ -847,9 +885,9 @@ static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, si
}
static int client_receive_advertise(sd_dhcp6_client *client, DHCP6Message *advertise, size_t len) {
- int r;
_cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
uint8_t pref_advertise = 0, pref_lease = 0;
+ int r;
if (advertise->type != DHCP6_ADVERTISE)
return 0;
@@ -880,7 +918,12 @@ static int client_receive_advertise(sd_dhcp6_client *client, DHCP6Message *adver
return r;
}
-static int client_receive_message(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+static int client_receive_message(
+ sd_event_source *s,
+ int fd, uint32_t
+ revents,
+ void *userdata) {
+
sd_dhcp6_client *client = userdata;
DHCP6_CLIENT_DONT_DESTROY(client);
_cleanup_free_ DHCP6Message *message = NULL;
@@ -899,16 +942,18 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
if (!message)
return -ENOMEM;
- len = read(fd, message, buflen);
+ len = recv(fd, message, buflen, 0);
if (len < 0) {
if (errno == EAGAIN || errno == EINTR)
return 0;
- log_dhcp6_client(client, "Could not receive message from UDP socket: %m");
+ return log_dhcp6_client_errno(client, errno, "Could not receive message from UDP socket: %m");
- return -errno;
- } else if ((size_t)len < sizeof(DHCP6Message))
+ }
+ if ((size_t) len < sizeof(DHCP6Message)) {
+ log_dhcp6_client(client, "Too small to be DHCP6 message: ignoring");
return 0;
+ }
switch(message->type) {
case DHCP6_SOLICIT:
@@ -929,8 +974,7 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
break;
default:
- log_dhcp6_client(client, "unknown message type %d",
- message->type);
+ log_dhcp6_client(client, "Unknown message type %d", message->type);
return 0;
}
@@ -989,10 +1033,9 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
return 0;
}
- if (r >= 0) {
+ if (r >= 0)
log_dhcp6_client(client, "Recv %s",
dhcp6_message_type_to_string(message->type));
- }
return 0;
}
@@ -1004,7 +1047,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
assert_return(client, -EINVAL);
assert_return(client->event, -EINVAL);
- assert_return(client->index > 0, -EINVAL);
+ assert_return(client->ifindex > 0, -EINVAL);
assert_return(client->state != state, -EINVAL);
client->timeout_resend_expire =
@@ -1045,7 +1088,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
if (client->lease->ia.lifetime_t1 == 0xffffffff ||
client->lease->ia.lifetime_t2 == 0xffffffff) {
- log_dhcp6_client(client, "infinite T1 0x%08x or T2 0x%08x",
+ log_dhcp6_client(client, "Infinite T1 0x%08x or T2 0x%08x",
be32toh(client->lease->ia.lifetime_t1),
be32toh(client->lease->ia.lifetime_t2));
@@ -1137,12 +1180,12 @@ int sd_dhcp6_client_is_running(sd_dhcp6_client *client) {
}
int sd_dhcp6_client_start(sd_dhcp6_client *client) {
- int r = 0;
enum DHCP6State state = DHCP6_STATE_SOLICITATION;
+ int r = 0;
assert_return(client, -EINVAL);
assert_return(client->event, -EINVAL);
- assert_return(client->index > 0, -EINVAL);
+ assert_return(client->ifindex > 0, -EINVAL);
assert_return(in_addr_is_link_local(AF_INET6, (const union in_addr_union *) &client->local_address) > 0, -EINVAL);
if (!IN_SET(client->state, DHCP6_STATE_STOPPED))
@@ -1160,9 +1203,14 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) {
if (r < 0)
return r;
- r = dhcp6_network_bind_udp_socket(client->index, &client->local_address);
- if (r < 0)
- return r;
+ r = dhcp6_network_bind_udp_socket(client->ifindex, &client->local_address);
+ if (r < 0) {
+ _cleanup_free_ char *p = NULL;
+
+ (void) in_addr_to_string(AF_INET6, (const union in_addr_union*) &client->local_address, &p);
+ return log_dhcp6_client_errno(client, r,
+ "Failed to bind to UDP socket at address %s: %m", strna(p));
+ }
client->fd = r;
@@ -1178,7 +1226,7 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) {
goto error;
r = sd_event_source_set_description(client->receive_message,
- "dhcp6-receive-message");
+ "dhcp6-receive-message");
if (r < 0)
goto error;
@@ -1186,8 +1234,8 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) {
state = DHCP6_STATE_INFORMATION_REQUEST;
log_dhcp6_client(client, "Started in %s mode",
- client->information_request? "Information request":
- "Managed");
+ client->information_request? "Information request":
+ "Managed");
return client_start(client, state);
@@ -1224,8 +1272,7 @@ int sd_dhcp6_client_detach_event(sd_dhcp6_client *client) {
}
sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client) {
- if (!client)
- return NULL;
+ assert_return(client, NULL);
return client->event;
}
@@ -1273,15 +1320,11 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret) {
return -ENOMEM;
client->n_ref = 1;
-
client->ia_na.type = SD_DHCP6_OPTION_IA_NA;
-
- client->index = -1;
-
+ client->ifindex = -1;
client->fd = -1;
client->req_opts_len = ELEMENTSOF(default_req_opts);
-
client->req_opts = new0(be16_t, client->req_opts_len);
if (!client->req_opts)
return -ENOMEM;
diff --git a/src/systemd/src/libsystemd-network/sd-ipv4acd.c b/src/systemd/src/libsystemd-network/sd-ipv4acd.c
index 9b5ce7200c..598307951f 100644
--- a/src/systemd/src/libsystemd-network/sd-ipv4acd.c
+++ b/src/systemd/src/libsystemd-network/sd-ipv4acd.c
@@ -30,45 +30,30 @@
#include "alloc-util.h"
#include "arp-util.h"
+#include "ether-addr-util.h"
#include "fd-util.h"
#include "in-addr-util.h"
#include "list.h"
#include "random-util.h"
-#include "refcnt.h"
#include "siphash24.h"
+#include "string-util.h"
#include "util.h"
/* Constants from the RFC */
-#define PROBE_WAIT 1
-#define PROBE_NUM 3
-#define PROBE_MIN 1
-#define PROBE_MAX 2
-#define ANNOUNCE_WAIT 2
-#define ANNOUNCE_NUM 2
-#define ANNOUNCE_INTERVAL 2
-#define MAX_CONFLICTS 10
-#define RATE_LIMIT_INTERVAL 60
-#define DEFEND_INTERVAL 10
-
-#define IPV4ACD_NETWORK 0xA9FE0000L
-#define IPV4ACD_NETMASK 0xFFFF0000L
-
-#define log_ipv4acd_full(ll, level, error, fmt, ...) log_internal(level, error, __FILE__, __LINE__, __func__, "ACD: " fmt, ##__VA_ARGS__)
-
-#define log_ipv4acd_debug(ll, ...) log_ipv4acd_full(ll, LOG_DEBUG, 0, ##__VA_ARGS__)
-#define log_ipv4acd_info(ll, ...) log_ipv4acd_full(ll, LOG_INFO, 0, ##__VA_ARGS__)
-#define log_ipv4acd_notice(ll, ...) log_ipv4acd_full(ll, LOG_NOTICE, 0, ##__VA_ARGS__)
-#define log_ipv4acd_warning(ll, ...) log_ipv4acd_full(ll, LOG_WARNING, 0, ##__VA_ARGS__)
-#define log_ipv4acd_error(ll, ...) log_ipv4acd_full(ll, LOG_ERR, 0, ##__VA_ARGS__)
-
-#define log_ipv4acd_debug_errno(ll, error, ...) log_ipv4acd_full(ll, LOG_DEBUG, error, ##__VA_ARGS__)
-#define log_ipv4acd_info_errno(ll, error, ...) log_ipv4acd_full(ll, LOG_INFO, error, ##__VA_ARGS__)
-#define log_ipv4acd_notice_errno(ll, error, ...) log_ipv4acd_full(ll, LOG_NOTICE, error, ##__VA_ARGS__)
-#define log_ipv4acd_warning_errno(ll, error, ...) log_ipv4acd_full(ll, LOG_WARNING, error, ##__VA_ARGS__)
-#define log_ipv4acd_error_errno(ll, error, ...) log_ipv4acd_full(ll, LOG_ERR, error, ##__VA_ARGS__)
+#define PROBE_WAIT_USEC (1U * USEC_PER_SEC)
+#define PROBE_NUM 3U
+#define PROBE_MIN_USEC (1U * USEC_PER_SEC)
+#define PROBE_MAX_USEC (2U * USEC_PER_SEC)
+#define ANNOUNCE_WAIT_USEC (2U * USEC_PER_SEC)
+#define ANNOUNCE_NUM 2U
+#define ANNOUNCE_INTERVAL_USEC (2U * USEC_PER_SEC)
+#define MAX_CONFLICTS 10U
+#define RATE_LIMIT_INTERVAL_USEC (60U * USEC_PER_SEC)
+#define DEFEND_INTERVAL_USEC (10U * USEC_PER_SEC)
typedef enum IPv4ACDState {
IPV4ACD_STATE_INIT,
+ IPV4ACD_STATE_STARTED,
IPV4ACD_STATE_WAITING_PROBE,
IPV4ACD_STATE_PROBING,
IPV4ACD_STATE_WAITING_ANNOUNCE,
@@ -79,156 +64,164 @@ typedef enum IPv4ACDState {
} IPv4ACDState;
struct sd_ipv4acd {
- RefCount n_ref;
+ unsigned n_ref;
IPv4ACDState state;
- int index;
+ int ifindex;
int fd;
- int iteration;
- int conflict;
- sd_event_source *receive_message;
- sd_event_source *timer;
+
+ unsigned n_iteration;
+ unsigned n_conflict;
+
+ sd_event_source *receive_message_event_source;
+ sd_event_source *timer_event_source;
+
usec_t defend_window;
be32_t address;
+
/* External */
struct ether_addr mac_addr;
+
sd_event *event;
int event_priority;
- sd_ipv4acd_callback_t cb;
+ sd_ipv4acd_callback_t callback;
void* userdata;
};
-sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *ll) {
- if (ll)
- assert_se(REFCNT_INC(ll->n_ref) >= 2);
+#define log_ipv4acd_errno(acd, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "IPV4ACD: " fmt, ##__VA_ARGS__)
+#define log_ipv4acd(acd, fmt, ...) log_ipv4acd_errno(acd, 0, fmt, ##__VA_ARGS__)
+
+static void ipv4acd_set_state(sd_ipv4acd *acd, IPv4ACDState st, bool reset_counter) {
+ assert(acd);
+ assert(st < _IPV4ACD_STATE_MAX);
+
+ if (st == acd->state && !reset_counter)
+ acd->n_iteration++;
+ else {
+ acd->state = st;
+ acd->n_iteration = 0;
+ }
+}
+
+static void ipv4acd_reset(sd_ipv4acd *acd) {
+ assert(acd);
+
+ acd->timer_event_source = sd_event_source_unref(acd->timer_event_source);
+ acd->receive_message_event_source = sd_event_source_unref(acd->receive_message_event_source);
+
+ acd->fd = safe_close(acd->fd);
+
+ ipv4acd_set_state(acd, IPV4ACD_STATE_INIT, true);
+}
+
+sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *acd) {
+ if (!acd)
+ return NULL;
+
+ assert_se(acd->n_ref >= 1);
+ acd->n_ref++;
- return ll;
+ return acd;
}
-sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *ll) {
- if (!ll || REFCNT_DEC(ll->n_ref) > 0)
+sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *acd) {
+ if (!acd)
return NULL;
- ll->receive_message = sd_event_source_unref(ll->receive_message);
- ll->fd = safe_close(ll->fd);
+ assert_se(acd->n_ref >= 1);
+ acd->n_ref--;
- ll->timer = sd_event_source_unref(ll->timer);
+ if (acd->n_ref > 0)
+ return NULL;
- sd_ipv4acd_detach_event(ll);
+ ipv4acd_reset(acd);
+ sd_ipv4acd_detach_event(acd);
- free(ll);
+ free(acd);
return NULL;
}
int sd_ipv4acd_new(sd_ipv4acd **ret) {
- _cleanup_(sd_ipv4acd_unrefp) sd_ipv4acd *ll = NULL;
+ _cleanup_(sd_ipv4acd_unrefp) sd_ipv4acd *acd = NULL;
assert_return(ret, -EINVAL);
- ll = new0(sd_ipv4acd, 1);
- if (!ll)
+ acd = new0(sd_ipv4acd, 1);
+ if (!acd)
return -ENOMEM;
- ll->n_ref = REFCNT_INIT;
- ll->state = IPV4ACD_STATE_INIT;
- ll->index = -1;
- ll->fd = -1;
+ acd->n_ref = 1;
+ acd->state = IPV4ACD_STATE_INIT;
+ acd->ifindex = -1;
+ acd->fd = -1;
- *ret = ll;
- ll = NULL;
+ *ret = acd;
+ acd = NULL;
return 0;
}
-static void ipv4acd_set_state(sd_ipv4acd *ll, IPv4ACDState st, bool reset_counter) {
-
- assert(ll);
- assert(st < _IPV4ACD_STATE_MAX);
-
- if (st == ll->state && !reset_counter)
- ll->iteration++;
- else {
- ll->state = st;
- ll->iteration = 0;
- }
-}
+static void ipv4acd_client_notify(sd_ipv4acd *acd, int event) {
+ assert(acd);
-static void ipv4acd_client_notify(sd_ipv4acd *ll, int event) {
- assert(ll);
+ if (!acd->callback)
+ return;
- if (ll->cb)
- ll->cb(ll, event, ll->userdata);
+ acd->callback(acd, event, acd->userdata);
}
-static void ipv4acd_stop(sd_ipv4acd *ll) {
- assert(ll);
+int sd_ipv4acd_stop(sd_ipv4acd *acd) {
+ assert_return(acd, -EINVAL);
- ll->receive_message = sd_event_source_unref(ll->receive_message);
- ll->fd = safe_close(ll->fd);
+ ipv4acd_reset(acd);
- ll->timer = sd_event_source_unref(ll->timer);
+ log_ipv4acd(acd, "STOPPED");
- log_ipv4acd_debug(ll, "STOPPED");
-
- ipv4acd_set_state (ll, IPV4ACD_STATE_INIT, true);
-}
-
-int sd_ipv4acd_stop(sd_ipv4acd *ll) {
- assert_return(ll, -EINVAL);
-
- ipv4acd_stop(ll);
-
- ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_STOP);
+ ipv4acd_client_notify(acd, SD_IPV4ACD_EVENT_STOP);
return 0;
}
static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata);
-static int ipv4acd_set_next_wakeup(sd_ipv4acd *ll, int sec, int random_sec) {
+static int ipv4acd_set_next_wakeup(sd_ipv4acd *acd, usec_t usec, usec_t random_usec) {
_cleanup_(sd_event_source_unrefp) sd_event_source *timer = NULL;
- usec_t next_timeout;
- usec_t time_now;
+ usec_t next_timeout, time_now;
int r;
- assert(sec >= 0);
- assert(random_sec >= 0);
- assert(ll);
+ assert(acd);
- next_timeout = sec * USEC_PER_SEC;
+ next_timeout = usec;
- if (random_sec)
- next_timeout += random_u32() % (random_sec * USEC_PER_SEC);
+ if (random_usec > 0)
+ next_timeout += (usec_t) random_u64() % random_usec;
- assert_se(sd_event_now(ll->event, clock_boottime_or_monotonic(), &time_now) >= 0);
+ assert_se(sd_event_now(acd->event, clock_boottime_or_monotonic(), &time_now) >= 0);
- r = sd_event_add_time(ll->event, &timer, clock_boottime_or_monotonic(),
- time_now + next_timeout, 0, ipv4acd_on_timeout, ll);
+ r = sd_event_add_time(acd->event, &timer, clock_boottime_or_monotonic(), time_now + next_timeout, 0, ipv4acd_on_timeout, acd);
if (r < 0)
return r;
- r = sd_event_source_set_priority(timer, ll->event_priority);
+ r = sd_event_source_set_priority(timer, acd->event_priority);
if (r < 0)
return r;
- r = sd_event_source_set_description(timer, "ipv4acd-timer");
- if (r < 0)
- return r;
+ (void) sd_event_source_set_description(timer, "ipv4acd-timer");
- ll->timer = sd_event_source_unref(ll->timer);
- ll->timer = timer;
+ sd_event_source_unref(acd->timer_event_source);
+ acd->timer_event_source = timer;
timer = NULL;
return 0;
}
-static bool ipv4acd_arp_conflict(sd_ipv4acd *ll, struct ether_arp *arp) {
- assert(ll);
+static bool ipv4acd_arp_conflict(sd_ipv4acd *acd, struct ether_arp *arp) {
+ assert(acd);
assert(arp);
/* see the BPF */
- if (memcmp(arp->arp_spa, &ll->address, sizeof(ll->address)) == 0)
+ if (memcmp(arp->arp_spa, &acd->address, sizeof(acd->address)) == 0)
return true;
/* the TPA matched instead of the SPA, this is not a conflict */
@@ -236,294 +229,300 @@ static bool ipv4acd_arp_conflict(sd_ipv4acd *ll, struct ether_arp *arp) {
}
static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
- sd_ipv4acd *ll = userdata;
+ sd_ipv4acd *acd = userdata;
int r = 0;
- assert(ll);
+ assert(acd);
+
+ switch (acd->state) {
- switch (ll->state) {
- case IPV4ACD_STATE_INIT:
+ case IPV4ACD_STATE_STARTED:
+ ipv4acd_set_state(acd, IPV4ACD_STATE_WAITING_PROBE, true);
- ipv4acd_set_state(ll, IPV4ACD_STATE_WAITING_PROBE, true);
+ if (acd->n_conflict >= MAX_CONFLICTS) {
+ char ts[FORMAT_TIMESPAN_MAX];
+ log_ipv4acd(acd, "Max conflicts reached, delaying by %s", format_timespan(ts, sizeof(ts), RATE_LIMIT_INTERVAL_USEC, 0));
- if (ll->conflict >= MAX_CONFLICTS) {
- log_ipv4acd_notice(ll, "Max conflicts reached, delaying by %us", RATE_LIMIT_INTERVAL);
- r = ipv4acd_set_next_wakeup(ll, RATE_LIMIT_INTERVAL, PROBE_WAIT);
+ r = ipv4acd_set_next_wakeup(acd, RATE_LIMIT_INTERVAL_USEC, PROBE_WAIT_USEC);
if (r < 0)
- goto out;
+ goto fail;
- ll->conflict = 0;
+ acd->n_conflict = 0;
} else {
- r = ipv4acd_set_next_wakeup(ll, 0, PROBE_WAIT);
+ r = ipv4acd_set_next_wakeup(acd, 0, PROBE_WAIT_USEC);
if (r < 0)
- goto out;
+ goto fail;
}
break;
+
case IPV4ACD_STATE_WAITING_PROBE:
case IPV4ACD_STATE_PROBING:
/* Send a probe */
- r = arp_send_probe(ll->fd, ll->index, ll->address, &ll->mac_addr);
+ r = arp_send_probe(acd->fd, acd->ifindex, acd->address, &acd->mac_addr);
if (r < 0) {
- log_ipv4acd_error_errno(ll, r, "Failed to send ARP probe: %m");
- goto out;
+ log_ipv4acd_errno(acd, r, "Failed to send ARP probe: %m");
+ goto fail;
} else {
_cleanup_free_ char *address = NULL;
- union in_addr_union addr = { .in.s_addr = ll->address };
+ union in_addr_union addr = { .in.s_addr = acd->address };
- r = in_addr_to_string(AF_INET, &addr, &address);
- if (r >= 0)
- log_ipv4acd_debug(ll, "Probing %s", address);
+ (void) in_addr_to_string(AF_INET, &addr, &address);
+ log_ipv4acd(acd, "Probing %s", strna(address));
}
- if (ll->iteration < PROBE_NUM - 2) {
- ipv4acd_set_state(ll, IPV4ACD_STATE_PROBING, false);
+ if (acd->n_iteration < PROBE_NUM - 2) {
+ ipv4acd_set_state(acd, IPV4ACD_STATE_PROBING, false);
- r = ipv4acd_set_next_wakeup(ll, PROBE_MIN, (PROBE_MAX-PROBE_MIN));
+ r = ipv4acd_set_next_wakeup(acd, PROBE_MIN_USEC, (PROBE_MAX_USEC-PROBE_MIN_USEC));
if (r < 0)
- goto out;
+ goto fail;
} else {
- ipv4acd_set_state(ll, IPV4ACD_STATE_WAITING_ANNOUNCE, true);
+ ipv4acd_set_state(acd, IPV4ACD_STATE_WAITING_ANNOUNCE, true);
- r = ipv4acd_set_next_wakeup(ll, ANNOUNCE_WAIT, 0);
+ r = ipv4acd_set_next_wakeup(acd, ANNOUNCE_WAIT_USEC, 0);
if (r < 0)
- goto out;
+ goto fail;
}
break;
case IPV4ACD_STATE_ANNOUNCING:
- if (ll->iteration >= ANNOUNCE_NUM - 1) {
- ipv4acd_set_state(ll, IPV4ACD_STATE_RUNNING, false);
-
+ if (acd->n_iteration >= ANNOUNCE_NUM - 1) {
+ ipv4acd_set_state(acd, IPV4ACD_STATE_RUNNING, false);
break;
}
+
+ /* fall through */
+
case IPV4ACD_STATE_WAITING_ANNOUNCE:
/* Send announcement packet */
- r = arp_send_announcement(ll->fd, ll->index, ll->address, &ll->mac_addr);
+ r = arp_send_announcement(acd->fd, acd->ifindex, acd->address, &acd->mac_addr);
if (r < 0) {
- log_ipv4acd_error_errno(ll, r, "Failed to send ARP announcement: %m");
- goto out;
+ log_ipv4acd_errno(acd, r, "Failed to send ARP announcement: %m");
+ goto fail;
} else
- log_ipv4acd_debug(ll, "ANNOUNCE");
+ log_ipv4acd(acd, "ANNOUNCE");
- ipv4acd_set_state(ll, IPV4ACD_STATE_ANNOUNCING, false);
+ ipv4acd_set_state(acd, IPV4ACD_STATE_ANNOUNCING, false);
- r = ipv4acd_set_next_wakeup(ll, ANNOUNCE_INTERVAL, 0);
+ r = ipv4acd_set_next_wakeup(acd, ANNOUNCE_INTERVAL_USEC, 0);
if (r < 0)
- goto out;
+ goto fail;
- if (ll->iteration == 0) {
- ll->conflict = 0;
- ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_BIND);
+ if (acd->n_iteration == 0) {
+ acd->n_conflict = 0;
+ ipv4acd_client_notify(acd, SD_IPV4ACD_EVENT_BIND);
}
break;
+
default:
assert_not_reached("Invalid state.");
}
-out:
- if (r < 0)
- sd_ipv4acd_stop(ll);
+ return 0;
- return 1;
+fail:
+ sd_ipv4acd_stop(acd);
+ return 0;
}
-static void ipv4acd_on_conflict(sd_ipv4acd *ll) {
+static void ipv4acd_on_conflict(sd_ipv4acd *acd) {
_cleanup_free_ char *address = NULL;
- union in_addr_union addr = { .in.s_addr = ll->address };
- int r;
+ union in_addr_union addr = { .in.s_addr = acd->address };
- assert(ll);
+ assert(acd);
- ll->conflict++;
+ acd->n_conflict++;
- r = in_addr_to_string(AF_INET, &addr, &address);
- if (r >= 0)
- log_ipv4acd_debug(ll, "Conflict on %s (%u)", address, ll->conflict);
+ (void) in_addr_to_string(AF_INET, &addr, &address);
+ log_ipv4acd(acd, "Conflict on %s (%u)", strna(address), acd->n_conflict);
- ipv4acd_stop(ll);
-
- ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_CONFLICT);
+ ipv4acd_reset(acd);
+ ipv4acd_client_notify(acd, SD_IPV4ACD_EVENT_CONFLICT);
}
-static int ipv4acd_on_packet(sd_event_source *s, int fd,
- uint32_t revents, void *userdata) {
- sd_ipv4acd *ll = userdata;
+static int ipv4acd_on_packet(
+ sd_event_source *s,
+ int fd,
+ uint32_t revents,
+ void *userdata) {
+
+ sd_ipv4acd *acd = userdata;
struct ether_arp packet;
+ ssize_t n;
int r;
- assert(ll);
+ assert(s);
+ assert(acd);
assert(fd >= 0);
- r = read(fd, &packet, sizeof(struct ether_arp));
- if (r < (int) sizeof(struct ether_arp))
- goto out;
+ n = recv(fd, &packet, sizeof(struct ether_arp), 0);
+ if (n < 0) {
+ if (errno == EAGAIN || errno == EINTR)
+ return 0;
+
+ log_ipv4acd_errno(acd, errno, "Failed to read ARP packet: %m");
+ goto fail;
+ }
+ if ((size_t) n != sizeof(struct ether_arp)) {
+ log_ipv4acd(acd, "Ignoring too short ARP packet.");
+ return 0;
+ }
+
+ switch (acd->state) {
- switch (ll->state) {
case IPV4ACD_STATE_ANNOUNCING:
case IPV4ACD_STATE_RUNNING:
- if (ipv4acd_arp_conflict(ll, &packet)) {
+
+ if (ipv4acd_arp_conflict(acd, &packet)) {
usec_t ts;
- assert_se(sd_event_now(ll->event, clock_boottime_or_monotonic(), &ts) >= 0);
+ assert_se(sd_event_now(acd->event, clock_boottime_or_monotonic(), &ts) >= 0);
/* Defend address */
- if (ts > ll->defend_window) {
- ll->defend_window = ts + DEFEND_INTERVAL * USEC_PER_SEC;
- r = arp_send_announcement(ll->fd, ll->index, ll->address, &ll->mac_addr);
+ if (ts > acd->defend_window) {
+ acd->defend_window = ts + DEFEND_INTERVAL_USEC;
+ r = arp_send_announcement(acd->fd, acd->ifindex, acd->address, &acd->mac_addr);
if (r < 0) {
- log_ipv4acd_error_errno(ll, r, "Failed to send ARP announcement: %m");
- goto out;
+ log_ipv4acd_errno(acd, r, "Failed to send ARP announcement: %m");
+ goto fail;
} else
- log_ipv4acd_debug(ll, "DEFEND");
+ log_ipv4acd(acd, "DEFEND");
} else
- ipv4acd_on_conflict(ll);
+ ipv4acd_on_conflict(acd);
}
-
break;
+
case IPV4ACD_STATE_WAITING_PROBE:
case IPV4ACD_STATE_PROBING:
case IPV4ACD_STATE_WAITING_ANNOUNCE:
/* BPF ensures this packet indicates a conflict */
- ipv4acd_on_conflict(ll);
-
+ ipv4acd_on_conflict(acd);
break;
+
default:
assert_not_reached("Invalid state.");
}
-out:
- if (r < 0)
- sd_ipv4acd_stop(ll);
+ return 0;
- return 1;
+fail:
+ sd_ipv4acd_stop(acd);
+ return 0;
}
-int sd_ipv4acd_set_index(sd_ipv4acd *ll, int interface_index) {
- assert_return(ll, -EINVAL);
- assert_return(interface_index > 0, -EINVAL);
- assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY);
+int sd_ipv4acd_set_ifindex(sd_ipv4acd *acd, int ifindex) {
+ assert_return(acd, -EINVAL);
+ assert_return(ifindex > 0, -EINVAL);
+ assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY);
- ll->index = interface_index;
+ acd->ifindex = ifindex;
return 0;
}
-int sd_ipv4acd_set_mac(sd_ipv4acd *ll, const struct ether_addr *addr) {
- assert_return(ll, -EINVAL);
+int sd_ipv4acd_set_mac(sd_ipv4acd *acd, const struct ether_addr *addr) {
+ assert_return(acd, -EINVAL);
assert_return(addr, -EINVAL);
- assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY);
+ assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY);
- memcpy(&ll->mac_addr, addr, ETH_ALEN);
+ acd->mac_addr = *addr;
return 0;
}
-int sd_ipv4acd_detach_event(sd_ipv4acd *ll) {
- assert_return(ll, -EINVAL);
+int sd_ipv4acd_detach_event(sd_ipv4acd *acd) {
+ assert_return(acd, -EINVAL);
- ll->event = sd_event_unref(ll->event);
+ acd->event = sd_event_unref(acd->event);
return 0;
}
-int sd_ipv4acd_attach_event(sd_ipv4acd *ll, sd_event *event, int64_t priority) {
+int sd_ipv4acd_attach_event(sd_ipv4acd *acd, sd_event *event, int64_t priority) {
int r;
- assert_return(ll, -EINVAL);
- assert_return(!ll->event, -EBUSY);
+ assert_return(acd, -EINVAL);
+ assert_return(!acd->event, -EBUSY);
if (event)
- ll->event = sd_event_ref(event);
+ acd->event = sd_event_ref(event);
else {
- r = sd_event_default(&ll->event);
+ r = sd_event_default(&acd->event);
if (r < 0)
return r;
}
- ll->event_priority = priority;
+ acd->event_priority = priority;
return 0;
}
-int sd_ipv4acd_set_callback(sd_ipv4acd *ll, sd_ipv4acd_callback_t cb, void *userdata) {
- assert_return(ll, -EINVAL);
+int sd_ipv4acd_set_callback(sd_ipv4acd *acd, sd_ipv4acd_callback_t cb, void *userdata) {
+ assert_return(acd, -EINVAL);
- ll->cb = cb;
- ll->userdata = userdata;
+ acd->callback = cb;
+ acd->userdata = userdata;
return 0;
}
-int sd_ipv4acd_set_address(sd_ipv4acd *ll, const struct in_addr *address) {
- assert_return(ll, -EINVAL);
+int sd_ipv4acd_set_address(sd_ipv4acd *acd, const struct in_addr *address) {
+ assert_return(acd, -EINVAL);
assert_return(address, -EINVAL);
- assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY);
+ assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY);
- ll->address = address->s_addr;
+ acd->address = address->s_addr;
return 0;
}
-int sd_ipv4acd_is_running(sd_ipv4acd *ll) {
- assert_return(ll, false);
+int sd_ipv4acd_is_running(sd_ipv4acd *acd) {
+ assert_return(acd, false);
- return ll->state != IPV4ACD_STATE_INIT;
+ return acd->state != IPV4ACD_STATE_INIT;
}
-static bool ether_addr_is_nul(const struct ether_addr *addr) {
- const struct ether_addr nul_addr = {};
-
- assert(addr);
-
- return memcmp(addr, &nul_addr, sizeof(struct ether_addr)) == 0;
-}
-
-#define HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2)
-
-int sd_ipv4acd_start(sd_ipv4acd *ll) {
+int sd_ipv4acd_start(sd_ipv4acd *acd) {
int r;
- assert_return(ll, -EINVAL);
- assert_return(ll->event, -EINVAL);
- assert_return(ll->index > 0, -EINVAL);
- assert_return(ll->address != 0, -EINVAL);
- assert_return(!ether_addr_is_nul(&ll->mac_addr), -EINVAL);
- assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY);
+ assert_return(acd, -EINVAL);
+ assert_return(acd->event, -EINVAL);
+ assert_return(acd->ifindex > 0, -EINVAL);
+ assert_return(acd->address != 0, -EINVAL);
+ assert_return(!ether_addr_is_null(&acd->mac_addr), -EINVAL);
+ assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY);
- ll->defend_window = 0;
-
- r = arp_network_bind_raw_socket(ll->index, ll->address, &ll->mac_addr);
+ r = arp_network_bind_raw_socket(acd->ifindex, acd->address, &acd->mac_addr);
if (r < 0)
- goto out;
+ return r;
- ll->fd = safe_close(ll->fd);
- ll->fd = r;
+ safe_close(acd->fd);
+ acd->fd = r;
+ acd->defend_window = 0;
+ acd->n_conflict = 0;
- r = sd_event_add_io(ll->event, &ll->receive_message, ll->fd,
- EPOLLIN, ipv4acd_on_packet, ll);
+ r = sd_event_add_io(acd->event, &acd->receive_message_event_source, acd->fd, EPOLLIN, ipv4acd_on_packet, acd);
if (r < 0)
- goto out;
+ goto fail;
- r = sd_event_source_set_priority(ll->receive_message, ll->event_priority);
+ r = sd_event_source_set_priority(acd->receive_message_event_source, acd->event_priority);
if (r < 0)
- goto out;
+ goto fail;
- r = sd_event_source_set_description(ll->receive_message, "ipv4acd-receive-message");
- if (r < 0)
- goto out;
+ (void) sd_event_source_set_description(acd->receive_message_event_source, "ipv4acd-receive-message");
- r = ipv4acd_set_next_wakeup(ll, 0, 0);
+ r = ipv4acd_set_next_wakeup(acd, 0, 0);
if (r < 0)
- goto out;
-out:
- if (r < 0) {
- ipv4acd_stop(ll);
- return r;
- }
+ goto fail;
+ ipv4acd_set_state(acd, IPV4ACD_STATE_STARTED, true);
return 0;
+
+fail:
+ ipv4acd_reset(acd);
+ return r;
}
diff --git a/src/systemd/src/libsystemd-network/sd-ipv4ll.c b/src/systemd/src/libsystemd-network/sd-ipv4ll.c
index 391be15a36..dc2fa370b4 100644
--- a/src/systemd/src/libsystemd-network/sd-ipv4ll.c
+++ b/src/systemd/src/libsystemd-network/sd-ipv4ll.c
@@ -30,16 +30,17 @@
#include "sd-ipv4ll.h"
#include "alloc-util.h"
+#include "ether-addr-util.h"
#include "in-addr-util.h"
#include "list.h"
#include "random-util.h"
-#include "refcnt.h"
#include "siphash24.h"
#include "sparse-endian.h"
+#include "string-util.h"
#include "util.h"
-#define IPV4LL_NETWORK 0xA9FE0000L
-#define IPV4LL_NETMASK 0xFFFF0000L
+#define IPV4LL_NETWORK UINT32_C(0xA9FE0000)
+#define IPV4LL_NETMASK UINT32_C(0xFFFF0000)
#define IPV4LL_DONT_DESTROY(ll) \
_cleanup_(sd_ipv4ll_unrefp) _unused_ sd_ipv4ll *_dont_destroy_##ll = sd_ipv4ll_ref(ll)
@@ -48,16 +49,28 @@ struct sd_ipv4ll {
unsigned n_ref;
sd_ipv4acd *acd;
+
be32_t address; /* the address pushed to ACD */
- struct random_data *random_data;
- char *random_data_state;
+ struct ether_addr mac;
+
+ struct {
+ le64_t value;
+ le64_t generation;
+ } seed;
+ bool seed_set;
/* External */
be32_t claimed_address;
- sd_ipv4ll_callback_t cb;
+
+ sd_ipv4ll_callback_t callback;
void* userdata;
};
+#define log_ipv4ll_errno(ll, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "IPV4LL: " fmt, ##__VA_ARGS__)
+#define log_ipv4ll(ll, fmt, ...) log_ipv4ll_errno(ll, 0, fmt, ##__VA_ARGS__)
+
+static void ipv4ll_on_acd(sd_ipv4acd *ll, int event, void *userdata);
+
sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll) {
if (!ll)
return NULL;
@@ -79,16 +92,11 @@ sd_ipv4ll *sd_ipv4ll_unref(sd_ipv4ll *ll) {
return NULL;
sd_ipv4acd_unref(ll->acd);
-
- free(ll->random_data);
- free(ll->random_data_state);
free(ll);
return NULL;
}
-static void ipv4ll_on_acd(sd_ipv4acd *ll, int event, void *userdata);
-
int sd_ipv4ll_new(sd_ipv4ll **ret) {
_cleanup_(sd_ipv4ll_unrefp) sd_ipv4ll *ll = NULL;
int r;
@@ -116,44 +124,32 @@ int sd_ipv4ll_new(sd_ipv4ll **ret) {
}
int sd_ipv4ll_stop(sd_ipv4ll *ll) {
- int r;
-
assert_return(ll, -EINVAL);
- r = sd_ipv4acd_stop(ll->acd);
- if (r < 0)
- return r;
-
- return 0;
+ return sd_ipv4acd_stop(ll->acd);
}
-int sd_ipv4ll_set_index(sd_ipv4ll *ll, int interface_index) {
+int sd_ipv4ll_set_ifindex(sd_ipv4ll *ll, int ifindex) {
assert_return(ll, -EINVAL);
+ assert_return(ifindex > 0, -EINVAL);
+ assert_return(sd_ipv4ll_is_running(ll) == 0, -EBUSY);
- return sd_ipv4acd_set_index(ll->acd, interface_index);
+ return sd_ipv4acd_set_ifindex(ll->acd, ifindex);
}
-#define HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2)
-
int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr) {
int r;
assert_return(ll, -EINVAL);
+ assert_return(addr, -EINVAL);
+ assert_return(sd_ipv4ll_is_running(ll) == 0, -EBUSY);
- if (!ll->random_data) {
- uint64_t seed;
-
- /* If no random data is set, generate some from the MAC */
- seed = siphash24(&addr->ether_addr_octet, ETH_ALEN, HASH_KEY.bytes);
-
- assert_cc(sizeof(unsigned) <= 8);
-
- r = sd_ipv4ll_set_address_seed(ll, (unsigned) htole64(seed));
- if (r < 0)
- return r;
- }
+ r = sd_ipv4acd_set_mac(ll->acd, addr);
+ if (r < 0)
+ return r;
- return sd_ipv4acd_set_mac(ll->acd, addr);
+ ll->mac = *addr;
+ return 0;
}
int sd_ipv4ll_detach_event(sd_ipv4ll *ll) {
@@ -163,21 +159,15 @@ int sd_ipv4ll_detach_event(sd_ipv4ll *ll) {
}
int sd_ipv4ll_attach_event(sd_ipv4ll *ll, sd_event *event, int64_t priority) {
- int r;
-
assert_return(ll, -EINVAL);
- r = sd_ipv4acd_attach_event(ll->acd, event, priority);
- if (r < 0)
- return r;
-
- return 0;
+ return sd_ipv4acd_attach_event(ll->acd, event, priority);
}
int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_callback_t cb, void *userdata) {
assert_return(ll, -EINVAL);
- ll->cb = cb;
+ ll->callback = cb;
ll->userdata = userdata;
return 0;
@@ -195,32 +185,12 @@ int sd_ipv4ll_get_address(sd_ipv4ll *ll, struct in_addr *address) {
return 0;
}
-int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, unsigned seed) {
- _cleanup_free_ struct random_data *random_data = NULL;
- _cleanup_free_ char *random_data_state = NULL;
- int r;
-
+int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, uint64_t seed) {
assert_return(ll, -EINVAL);
+ assert_return(sd_ipv4ll_is_running(ll) == 0, -EBUSY);
- random_data = new0(struct random_data, 1);
- if (!random_data)
- return -ENOMEM;
-
- random_data_state = new0(char, 128);
- if (!random_data_state)
- return -ENOMEM;
-
- r = initstate_r(seed, random_data_state, 128, random_data);
- if (r < 0)
- return r;
-
- free(ll->random_data);
- ll->random_data = random_data;
- random_data = NULL;
-
- free(ll->random_data_state);
- ll->random_data_state = random_data_state;
- random_data_state = NULL;
+ ll->seed.value = htole64(seed);
+ ll->seed_set = true;
return 0;
}
@@ -232,20 +202,12 @@ int sd_ipv4ll_is_running(sd_ipv4ll *ll) {
}
static bool ipv4ll_address_is_valid(const struct in_addr *address) {
- uint32_t addr;
-
assert(address);
if (!in_addr_is_link_local(AF_INET, (const union in_addr_union *) address))
return false;
- addr = be32toh(address->s_addr);
-
- if ((addr & 0x0000FF00) == 0x0000 ||
- (addr & 0x0000FF00) == 0xFF00)
- return false;
-
- return true;
+ return !IN_SET(be32toh(address->s_addr) & 0x0000FF00U, 0x0000U, 0xFF00U);
}
int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address) {
@@ -264,48 +226,67 @@ int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address) {
return 0;
}
+#define PICK_HASH_KEY SD_ID128_MAKE(15,ac,82,a6,d6,3f,49,78,98,77,5d,0c,69,02,94,0b)
+
static int ipv4ll_pick_address(sd_ipv4ll *ll) {
- struct in_addr in_addr;
+ _cleanup_free_ char *address = NULL;
be32_t addr;
- int r;
- int32_t random;
assert(ll);
- assert(ll->random_data);
do {
- r = random_r(ll->random_data, &random);
- if (r < 0)
- return r;
- addr = htonl((random & 0x0000FFFF) | IPV4LL_NETWORK);
- } while (addr == ll->address ||
- (ntohl(addr) & 0x0000FF00) == 0x0000 ||
- (ntohl(addr) & 0x0000FF00) == 0xFF00);
+ uint64_t h;
- in_addr.s_addr = addr;
+ h = siphash24(&ll->seed, sizeof(ll->seed), PICK_HASH_KEY.bytes);
- r = sd_ipv4ll_set_address(ll, &in_addr);
- if (r < 0)
- return r;
+ /* Increase the generation counter by one */
+ ll->seed.generation = htole64(le64toh(ll->seed.generation) + 1);
- return 0;
+ addr = htobe32((h & UINT32_C(0x0000FFFF)) | IPV4LL_NETWORK);
+ } while (addr == ll->address ||
+ IN_SET(be32toh(addr) & 0x0000FF00U, 0x0000U, 0xFF00U));
+
+ (void) in_addr_to_string(AF_INET, &(union in_addr_union) { .in.s_addr = addr }, &address);
+ log_ipv4ll(ll, "Picked new IP address %s.", strna(address));
+
+ return sd_ipv4ll_set_address(ll, &(struct in_addr) { addr });
}
+#define MAC_HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2)
+
int sd_ipv4ll_start(sd_ipv4ll *ll) {
int r;
+ bool picked_address = false;
assert_return(ll, -EINVAL);
- assert_return(ll->random_data, -EINVAL);
+ assert_return(!ether_addr_is_null(&ll->mac), -EINVAL);
+ assert_return(sd_ipv4ll_is_running(ll) == 0, -EBUSY);
+
+ /* If no random seed is set, generate some from the MAC address */
+ if (!ll->seed_set)
+ ll->seed.value = htole64(siphash24(ll->mac.ether_addr_octet, ETH_ALEN, MAC_HASH_KEY.bytes));
+
+ /* Restart the generation counter. */
+ ll->seed.generation = 0;
if (ll->address == 0) {
r = ipv4ll_pick_address(ll);
if (r < 0)
return r;
+
+ picked_address = true;
}
r = sd_ipv4acd_start(ll->acd);
- if (r < 0)
+ if (r < 0) {
+
+ /* We couldn't start? If so, let's forget the picked address again, the user might make a change and
+ * retry, and we want the new data to take effect when picking an address. */
+ if (picked_address)
+ ll->address = 0;
+
return r;
+ }
return 0;
}
@@ -313,8 +294,8 @@ int sd_ipv4ll_start(sd_ipv4ll *ll) {
static void ipv4ll_client_notify(sd_ipv4ll *ll, int event) {
assert(ll);
- if (ll->cb)
- ll->cb(ll, event, ll->userdata);
+ if (ll->callback)
+ ll->callback(ll, event, ll->userdata);
}
void ipv4ll_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
@@ -326,17 +307,17 @@ void ipv4ll_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
assert(ll);
switch (event) {
+
case SD_IPV4ACD_EVENT_STOP:
ipv4ll_client_notify(ll, SD_IPV4LL_EVENT_STOP);
-
ll->claimed_address = 0;
-
break;
+
case SD_IPV4ACD_EVENT_BIND:
ll->claimed_address = ll->address;
ipv4ll_client_notify(ll, SD_IPV4LL_EVENT_BIND);
-
break;
+
case SD_IPV4ACD_EVENT_CONFLICT:
/* if an address was already bound we must call up to the
user to handle this, otherwise we just try again */
@@ -355,6 +336,7 @@ void ipv4ll_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
}
break;
+
default:
assert_not_reached("Invalid IPv4ACD event.");
}
diff --git a/src/systemd/src/libsystemd/sd-event/sd-event.c b/src/systemd/src/libsystemd/sd-event/sd-event.c
index 31e8e7fa66..eba12b749a 100644
--- a/src/systemd/src/libsystemd/sd-event/sd-event.c
+++ b/src/systemd/src/libsystemd/sd-event/sd-event.c
@@ -42,9 +42,7 @@
#include "process-util.h"
#endif
#include "set.h"
-#if 0 /* NM_IGNORED */
#include "signal-util.h"
-#endif
#include "string-table.h"
#include "string-util.h"
#include "time-util.h"
@@ -1082,6 +1080,10 @@ _public_ int sd_event_add_time(
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
assert_return(!event_pid_changed(e), -ECHILD);
+ if (IN_SET(clock, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM) &&
+ !clock_boottime_supported())
+ return -EOPNOTSUPP;
+
if (!callback)
callback = time_exit_callback;
@@ -1156,8 +1158,7 @@ _public_ int sd_event_add_signal(
int r;
assert_return(e, -EINVAL);
- assert_return(sig > 0, -EINVAL);
- assert_return(sig < _NSIG, -EINVAL);
+ assert_return(SIGNAL_VALID(sig), -EINVAL);
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
assert_return(!event_pid_changed(e), -ECHILD);
@@ -2212,7 +2213,7 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) {
if (_unlikely_(n != sizeof(si)))
return -EIO;
- assert(si.ssi_signo < _NSIG);
+ assert(SIGNAL_VALID(si.ssi_signo));
read_one = true;
@@ -2540,7 +2541,8 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
}
dual_timestamp_get(&e->timestamp);
- e->timestamp_boottime = now(CLOCK_BOOTTIME);
+ if (clock_boottime_supported())
+ e->timestamp_boottime = now(CLOCK_BOOTTIME);
for (i = 0; i < m; i++) {
@@ -2774,6 +2776,9 @@ _public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) {
CLOCK_BOOTTIME,
CLOCK_BOOTTIME_ALARM), -EOPNOTSUPP);
+ if (IN_SET(clock, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM) && !clock_boottime_supported())
+ return -EOPNOTSUPP;
+
if (!dual_timestamp_is_set(&e->timestamp)) {
/* Implicitly fall back to now() if we never ran
* before and thus have no cached time. */
diff --git a/src/systemd/src/systemd/sd-dhcp-client.h b/src/systemd/src/systemd/sd-dhcp-client.h
index 374ff8774e..9a90c2ed42 100644
--- a/src/systemd/src/systemd/sd-dhcp-client.h
+++ b/src/systemd/src/systemd/sd-dhcp-client.h
@@ -84,28 +84,57 @@ enum {
typedef struct sd_dhcp_client sd_dhcp_client;
-typedef void (*sd_dhcp_client_callback_t)(sd_dhcp_client *client, int event,
- void *userdata);
-int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_callback_t cb,
- void *userdata);
-
-int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option);
-int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
- const struct in_addr *last_address);
-int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast);
-int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index);
-int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
- size_t addr_len, uint16_t arp_type);
-int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
- const uint8_t *data, size_t data_len);
-int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid,
- uint16_t duid_type, uint8_t *duid, size_t duid_len);
-int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
- const uint8_t **data, size_t *data_len);
-int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu);
-int sd_dhcp_client_set_hostname(sd_dhcp_client *client, const char *hostname);
-int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client, const char *vci);
-int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret);
+typedef void (*sd_dhcp_client_callback_t)(sd_dhcp_client *client, int event, void *userdata);
+int sd_dhcp_client_set_callback(
+ sd_dhcp_client *client,
+ sd_dhcp_client_callback_t cb,
+ void *userdata);
+
+int sd_dhcp_client_set_request_option(
+ sd_dhcp_client *client,
+ uint8_t option);
+int sd_dhcp_client_set_request_address(
+ sd_dhcp_client *client,
+ const struct in_addr *last_address);
+int sd_dhcp_client_set_request_broadcast(
+ sd_dhcp_client *client,
+ int broadcast);
+int sd_dhcp_client_set_ifindex(
+ sd_dhcp_client *client,
+ int interface_index);
+int sd_dhcp_client_set_mac(
+ sd_dhcp_client *client,
+ const uint8_t *addr,
+ size_t addr_len,
+ uint16_t arp_type);
+int sd_dhcp_client_set_client_id(
+ sd_dhcp_client *client,
+ uint8_t type,
+ const uint8_t *data,
+ size_t data_len);
+int sd_dhcp_client_set_iaid_duid(
+ sd_dhcp_client *client,
+ uint32_t iaid,
+ uint16_t duid_type,
+ const void *duid,
+ size_t duid_len);
+int sd_dhcp_client_get_client_id(
+ sd_dhcp_client *client,
+ uint8_t *type,
+ const uint8_t **data,
+ size_t *data_len);
+int sd_dhcp_client_set_mtu(
+ sd_dhcp_client *client,
+ uint32_t mtu);
+int sd_dhcp_client_set_hostname(
+ sd_dhcp_client *client,
+ const char *hostname);
+int sd_dhcp_client_set_vendor_class_identifier(
+ sd_dhcp_client *client,
+ const char *vci);
+int sd_dhcp_client_get_lease(
+ sd_dhcp_client *client,
+ sd_dhcp_lease **ret);
int sd_dhcp_client_stop(sd_dhcp_client *client);
int sd_dhcp_client_start(sd_dhcp_client *client);
@@ -115,7 +144,10 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client);
int sd_dhcp_client_new(sd_dhcp_client **ret);
-int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int64_t priority);
+int sd_dhcp_client_attach_event(
+ sd_dhcp_client *client,
+ sd_event *event,
+ int64_t priority);
int sd_dhcp_client_detach_event(sd_dhcp_client *client);
sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client);
diff --git a/src/systemd/src/systemd/sd-dhcp6-client.h b/src/systemd/src/systemd/sd-dhcp6-client.h
index 4604cb6382..7819f0d2de 100644
--- a/src/systemd/src/systemd/sd-dhcp6-client.h
+++ b/src/systemd/src/systemd/sd-dhcp6-client.h
@@ -76,29 +76,52 @@ enum {
typedef struct sd_dhcp6_client sd_dhcp6_client;
-typedef void (*sd_dhcp6_client_callback_t)(sd_dhcp6_client *client, int event,
- void *userdata);
-int sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
- sd_dhcp6_client_callback_t cb, void *userdata);
-
-int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index);
-int sd_dhcp6_client_set_local_address(sd_dhcp6_client *client, const struct in6_addr *local_address);
-int sd_dhcp6_client_set_mac(sd_dhcp6_client *client, const uint8_t *addr,
- size_t addr_len, uint16_t arp_type);
-int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t duid_type,
- uint8_t *duid, size_t duid_len);
-int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid);
-int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, int enabled);
-int sd_dhcp6_client_get_information_request(sd_dhcp6_client *client, int *enabled);
-int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,
- uint16_t option);
-
-int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret);
+typedef void (*sd_dhcp6_client_callback_t)(sd_dhcp6_client *client, int event, void *userdata);
+int sd_dhcp6_client_set_callback(
+ sd_dhcp6_client *client,
+ sd_dhcp6_client_callback_t cb,
+ void *userdata);
+
+int sd_dhcp6_client_set_ifindex(
+ sd_dhcp6_client *client,
+ int interface_index);
+int sd_dhcp6_client_set_local_address(
+ sd_dhcp6_client *client,
+ const struct in6_addr *local_address);
+int sd_dhcp6_client_set_mac(
+ sd_dhcp6_client *client,
+ const uint8_t *addr,
+ size_t addr_len,
+ uint16_t arp_type);
+int sd_dhcp6_client_set_duid(
+ sd_dhcp6_client *client,
+ uint16_t duid_type,
+ const void *duid,
+ size_t duid_len);
+int sd_dhcp6_client_set_iaid(
+ sd_dhcp6_client *client,
+ uint32_t iaid);
+int sd_dhcp6_client_set_information_request(
+ sd_dhcp6_client *client,
+ int enabled);
+int sd_dhcp6_client_get_information_request(
+ sd_dhcp6_client *client,
+ int *enabled);
+int sd_dhcp6_client_set_request_option(
+ sd_dhcp6_client *client,
+ uint16_t option);
+
+int sd_dhcp6_client_get_lease(
+ sd_dhcp6_client *client,
+ sd_dhcp6_lease **ret);
int sd_dhcp6_client_stop(sd_dhcp6_client *client);
int sd_dhcp6_client_start(sd_dhcp6_client *client);
int sd_dhcp6_client_is_running(sd_dhcp6_client *client);
-int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event, int64_t priority);
+int sd_dhcp6_client_attach_event(
+ sd_dhcp6_client *client,
+ sd_event *event,
+ int64_t priority);
int sd_dhcp6_client_detach_event(sd_dhcp6_client *client);
sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client);
sd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client);
diff --git a/src/systemd/src/systemd/sd-ipv4acd.h b/src/systemd/src/systemd/sd-ipv4acd.h
index 9e3e14a30c..16d99983a8 100644
--- a/src/systemd/src/systemd/sd-ipv4acd.h
+++ b/src/systemd/src/systemd/sd-ipv4acd.h
@@ -37,20 +37,20 @@ enum {
};
typedef struct sd_ipv4acd sd_ipv4acd;
-typedef void (*sd_ipv4acd_callback_t)(sd_ipv4acd *ll, int event, void *userdata);
-
-int sd_ipv4acd_detach_event(sd_ipv4acd *ll);
-int sd_ipv4acd_attach_event(sd_ipv4acd *ll, sd_event *event, int64_t priority);
-int sd_ipv4acd_get_address(sd_ipv4acd *ll, struct in_addr *address);
-int sd_ipv4acd_set_callback(sd_ipv4acd *ll, sd_ipv4acd_callback_t cb, void *userdata);
-int sd_ipv4acd_set_mac(sd_ipv4acd *ll, const struct ether_addr *addr);
-int sd_ipv4acd_set_index(sd_ipv4acd *ll, int interface_index);
-int sd_ipv4acd_set_address(sd_ipv4acd *ll, const struct in_addr *address);
-int sd_ipv4acd_is_running(sd_ipv4acd *ll);
-int sd_ipv4acd_start(sd_ipv4acd *ll);
-int sd_ipv4acd_stop(sd_ipv4acd *ll);
-sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *ll);
-sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *ll);
+typedef void (*sd_ipv4acd_callback_t)(sd_ipv4acd *acd, int event, void *userdata);
+
+int sd_ipv4acd_detach_event(sd_ipv4acd *acd);
+int sd_ipv4acd_attach_event(sd_ipv4acd *acd, sd_event *event, int64_t priority);
+int sd_ipv4acd_get_address(sd_ipv4acd *acd, struct in_addr *address);
+int sd_ipv4acd_set_callback(sd_ipv4acd *acd, sd_ipv4acd_callback_t cb, void *userdata);
+int sd_ipv4acd_set_mac(sd_ipv4acd *acd, const struct ether_addr *addr);
+int sd_ipv4acd_set_ifindex(sd_ipv4acd *acd, int interface_index);
+int sd_ipv4acd_set_address(sd_ipv4acd *acd, const struct in_addr *address);
+int sd_ipv4acd_is_running(sd_ipv4acd *acd);
+int sd_ipv4acd_start(sd_ipv4acd *acd);
+int sd_ipv4acd_stop(sd_ipv4acd *acd);
+sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *acd);
+sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *acd);
int sd_ipv4acd_new(sd_ipv4acd **ret);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ipv4acd, sd_ipv4acd_unref);
diff --git a/src/systemd/src/systemd/sd-ipv4ll.h b/src/systemd/src/systemd/sd-ipv4ll.h
index 6fa38a2243..1109ec52e0 100644
--- a/src/systemd/src/systemd/sd-ipv4ll.h
+++ b/src/systemd/src/systemd/sd-ipv4ll.h
@@ -43,15 +43,15 @@ int sd_ipv4ll_attach_event(sd_ipv4ll *ll, sd_event *event, int64_t priority);
int sd_ipv4ll_get_address(sd_ipv4ll *ll, struct in_addr *address);
int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_callback_t cb, void *userdata);
int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr);
-int sd_ipv4ll_set_index(sd_ipv4ll *ll, int interface_index);
+int sd_ipv4ll_set_ifindex(sd_ipv4ll *ll, int interface_index);
int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address);
-int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, unsigned seed);
+int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, uint64_t seed);
int sd_ipv4ll_is_running(sd_ipv4ll *ll);
int sd_ipv4ll_start(sd_ipv4ll *ll);
int sd_ipv4ll_stop(sd_ipv4ll *ll);
sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll);
sd_ipv4ll *sd_ipv4ll_unref(sd_ipv4ll *ll);
-int sd_ipv4ll_new (sd_ipv4ll **ret);
+int sd_ipv4ll_new(sd_ipv4ll **ret);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ipv4ll, sd_ipv4ll_unref);
diff --git a/src/systemd/src/systemd/sd-lldp.h b/src/systemd/src/systemd/sd-lldp.h
index 4f2a3b50c0..5772d5794a 100644
--- a/src/systemd/src/systemd/sd-lldp.h
+++ b/src/systemd/src/systemd/sd-lldp.h
@@ -33,20 +33,18 @@ _SD_BEGIN_DECLARATIONS;
typedef struct sd_lldp sd_lldp;
typedef struct sd_lldp_neighbor sd_lldp_neighbor;
-#define SD_LLDP_MULTICAST_ADDR { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }
-
/* IEEE 802.3AB Clause 9: TLV Types */
enum {
- SD_LLDP_TYPE_END = 0,
- SD_LLDP_TYPE_CHASSIS_ID = 1,
- SD_LLDP_TYPE_PORT_ID = 2,
- SD_LLDP_TYPE_TTL = 3,
- SD_LLDP_TYPE_PORT_DESCRIPTION = 4,
- SD_LLDP_TYPE_SYSTEM_NAME = 5,
- SD_LLDP_TYPE_SYSTEM_DESCRIPTION = 6,
- SD_LLDP_TYPE_SYSTEM_CAPABILITIES = 7,
- SD_LLDP_TYPE_MGMT_ADDRESS = 8,
- SD_LLDP_TYPE_PRIVATE = 127,
+ SD_LLDP_TYPE_END = 0,
+ SD_LLDP_TYPE_CHASSIS_ID = 1,
+ SD_LLDP_TYPE_PORT_ID = 2,
+ SD_LLDP_TYPE_TTL = 3,
+ SD_LLDP_TYPE_PORT_DESCRIPTION = 4,
+ SD_LLDP_TYPE_SYSTEM_NAME = 5,
+ SD_LLDP_TYPE_SYSTEM_DESCRIPTION = 6,
+ SD_LLDP_TYPE_SYSTEM_CAPABILITIES = 7,
+ SD_LLDP_TYPE_MGMT_ADDRESS = 8,
+ SD_LLDP_TYPE_PRIVATE = 127,
};
/* IEEE 802.3AB Clause 9.5.2: Chassis subtypes */
@@ -63,28 +61,28 @@ enum {
/* IEEE 802.3AB Clause 9.5.3: Port subtype */
enum {
- SD_LLDP_PORT_SUBTYPE_RESERVED = 0,
- SD_LLDP_PORT_SUBTYPE_INTERFACE_ALIAS = 1,
- SD_LLDP_PORT_SUBTYPE_PORT_COMPONENT = 2,
- SD_LLDP_PORT_SUBTYPE_MAC_ADDRESS = 3,
- SD_LLDP_PORT_SUBTYPE_NETWORK_ADDRESS = 4,
- SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME = 5,
- SD_LLDP_PORT_SUBTYPE_AGENT_CIRCUIT_ID = 6,
- SD_LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED = 7,
+ SD_LLDP_PORT_SUBTYPE_RESERVED = 0,
+ SD_LLDP_PORT_SUBTYPE_INTERFACE_ALIAS = 1,
+ SD_LLDP_PORT_SUBTYPE_PORT_COMPONENT = 2,
+ SD_LLDP_PORT_SUBTYPE_MAC_ADDRESS = 3,
+ SD_LLDP_PORT_SUBTYPE_NETWORK_ADDRESS = 4,
+ SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME = 5,
+ SD_LLDP_PORT_SUBTYPE_AGENT_CIRCUIT_ID = 6,
+ SD_LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED = 7,
};
enum {
- SD_LLDP_SYSTEM_CAPABILITIES_OTHER = 1 << 0,
- SD_LLDP_SYSTEM_CAPABILITIES_REPEATER = 1 << 1,
- SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE = 1 << 2,
- SD_LLDP_SYSTEM_CAPABILITIES_WLAN_AP = 1 << 3,
- SD_LLDP_SYSTEM_CAPABILITIES_ROUTER = 1 << 4,
- SD_LLDP_SYSTEM_CAPABILITIES_PHONE = 1 << 5,
- SD_LLDP_SYSTEM_CAPABILITIES_DOCSIS = 1 << 6,
- SD_LLDP_SYSTEM_CAPABILITIES_STATION = 1 << 7,
- SD_LLDP_SYSTEM_CAPABILITIES_CVLAN = 1 << 8,
- SD_LLDP_SYSTEM_CAPABILITIES_SVLAN = 1 << 9,
- SD_LLDP_SYSTEM_CAPABILITIES_TPMR = 1 << 10,
+ SD_LLDP_SYSTEM_CAPABILITIES_OTHER = 1 << 0,
+ SD_LLDP_SYSTEM_CAPABILITIES_REPEATER = 1 << 1,
+ SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE = 1 << 2,
+ SD_LLDP_SYSTEM_CAPABILITIES_WLAN_AP = 1 << 3,
+ SD_LLDP_SYSTEM_CAPABILITIES_ROUTER = 1 << 4,
+ SD_LLDP_SYSTEM_CAPABILITIES_PHONE = 1 << 5,
+ SD_LLDP_SYSTEM_CAPABILITIES_DOCSIS = 1 << 6,
+ SD_LLDP_SYSTEM_CAPABILITIES_STATION = 1 << 7,
+ SD_LLDP_SYSTEM_CAPABILITIES_CVLAN = 1 << 8,
+ SD_LLDP_SYSTEM_CAPABILITIES_SVLAN = 1 << 9,
+ SD_LLDP_SYSTEM_CAPABILITIES_TPMR = 1 << 10,
};
#define SD_LLDP_SYSTEM_CAPABILITIES_ALL ((uint16_t) -1)
@@ -100,18 +98,17 @@ enum {
SD_LLDP_SYSTEM_CAPABILITIES_SVLAN| \
SD_LLDP_SYSTEM_CAPABILITIES_TPMR))
-
#define SD_LLDP_OUI_802_1 (uint8_t[]) { 0x00, 0x80, 0xc2 }
#define SD_LLDP_OUI_802_3 (uint8_t[]) { 0x00, 0x12, 0x0f }
enum {
- SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID = 1,
- SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID = 2,
- SD_LLDP_OUI_802_1_SUBTYPE_VLAN_NAME = 3,
- SD_LLDP_OUI_802_1_SUBTYPE_PROTOCOL_IDENTITY = 4,
- SD_LLDP_OUI_802_1_SUBTYPE_VID_USAGE_DIGEST = 5,
- SD_LLDP_OUI_802_1_SUBTYPE_MANAGEMENT_VID = 6,
- SD_LLDP_OUI_802_1_SUBTYPE_LINK_AGGREGATION = 7,
+ SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID = 1,
+ SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID = 2,
+ SD_LLDP_OUI_802_1_SUBTYPE_VLAN_NAME = 3,
+ SD_LLDP_OUI_802_1_SUBTYPE_PROTOCOL_IDENTITY = 4,
+ SD_LLDP_OUI_802_1_SUBTYPE_VID_USAGE_DIGEST = 5,
+ SD_LLDP_OUI_802_1_SUBTYPE_MANAGEMENT_VID = 6,
+ SD_LLDP_OUI_802_1_SUBTYPE_LINK_AGGREGATION = 7,
};
typedef enum sd_lldp_event {
diff --git a/src/systemd/src/systemd/sd-ndisc.h b/src/systemd/src/systemd/sd-ndisc.h
index 29bcbe8e3e..2b774233b8 100644
--- a/src/systemd/src/systemd/sd-ndisc.h
+++ b/src/systemd/src/systemd/sd-ndisc.h
@@ -49,7 +49,7 @@ int sd_ndisc_set_callback(sd_ndisc *nd,
sd_ndisc_prefix_autonomous_callback_t pacb,
sd_ndisc_callback_t cb,
void *userdata);
-int sd_ndisc_set_index(sd_ndisc *nd, int interface_index);
+int sd_ndisc_set_ifindex(sd_ndisc *nd, int interface_index);
int sd_ndisc_set_mac(sd_ndisc *nd, const struct ether_addr *mac_addr);
int sd_ndisc_attach_event(sd_ndisc *nd, sd_event *event, int64_t priority);
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
index e1734b6d1b..70eb25bfd1 100644
--- a/src/tests/Makefile.am
+++ b/src/tests/Makefile.am
@@ -1,5 +1,7 @@
SUBDIRS = config
+@GNOME_CODE_COVERAGE_RULES@
+
AM_CPPFLAGS = \
-I$(top_srcdir)/shared \
-I$(top_builddir)/shared \
@@ -12,7 +14,10 @@ AM_CPPFLAGS = \
-I$(top_builddir)/src \
-DG_LOG_DOMAIN=\""NetworkManager"\" \
-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \
- $(GLIB_CFLAGS)
+ $(GLIB_CFLAGS) \
+ $(CODE_COVERAGE_CFLAGS)
+
+AM_LDFLAGS = $(CODE_COVERAGE_LDFLAGS)
noinst_PROGRAMS = \
test-general \
@@ -47,6 +52,7 @@ test_ip6_config_LDADD = \
test_route_manager_fake_CPPFLAGS = \
$(AM_CPPFLAGS) \
+ $(GUDEV_CFLAGS) \
-I$(top_srcdir)/src/platform/tests \
-DSETUP=nm_fake_platform_setup \
-DKERNEL_HACKS=0
@@ -64,6 +70,7 @@ test_route_manager_linux_SOURCES = \
test_route_manager_linux_CPPFLAGS = \
$(AM_CPPFLAGS) \
+ $(GUDEV_CFLAGS) \
-I$(top_srcdir)/src/platform/tests \
-DSETUP=nm_linux_platform_setup \
-DKERNEL_HACKS=1
diff --git a/src/tests/config/Makefile.am b/src/tests/config/Makefile.am
index 17876e4d00..ee8254bab3 100644
--- a/src/tests/config/Makefile.am
+++ b/src/tests/config/Makefile.am
@@ -9,8 +9,8 @@ AM_CPPFLAGS = \
-DG_LOG_DOMAIN=\""NetworkManager"\" \
-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \
$(GLIB_CFLAGS) \
- -DSRCDIR=\""$(srcdir)"\" \
- -DBUILDDIR=\""$(builddir)"\"
+ -DSRCDIR=\""$(abs_srcdir)"\" \
+ -DBUILDDIR=\""$(abs_builddir)"\"
noinst_PROGRAMS = \
test-config
@@ -28,6 +28,7 @@ TESTS = test-config
EXTRA_DIST = \
NetworkManager.conf \
+ NetworkManager.state \
bad.conf \
global-dns-invalid.conf \
conf.d/00-overrides.conf \
diff --git a/src/tests/config/NetworkManager.state b/src/tests/config/NetworkManager.state
new file mode 100644
index 0000000000..1b9d604ac5
--- /dev/null
+++ b/src/tests/config/NetworkManager.state
@@ -0,0 +1,4 @@
+[main]
+NetworkingEnabled=true
+WirelessEnabled=true
+WWANEnabled=true
diff --git a/src/tests/config/test-config.c b/src/tests/config/test-config.c
index d83ff4b5c5..defead0540 100644
--- a/src/tests/config/test-config.c
+++ b/src/tests/config/test-config.c
@@ -27,7 +27,7 @@
#include "nm-fake-platform.h"
#include "nm-bus-manager.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
/********************************************************************************/
@@ -930,6 +930,65 @@ test_config_enable (void)
/*****************************************************************************/
+static void
+test_config_state_file (void)
+{
+ NMConfig *config;
+ const NMConfigState *state;
+ gs_free_error GError *error = NULL;
+ gboolean ret;
+ gs_free char *file_data = NULL;
+ gsize file_size;
+ const char *const TMP_FILE = BUILDDIR "/tmp.state";
+
+ ret = g_file_get_contents (SRCDIR "/NetworkManager.state", &file_data, &file_size, &error);
+ nmtst_assert_success (ret, error);
+ ret = g_file_set_contents (TMP_FILE, file_data, file_size, &error);
+ nmtst_assert_success (ret, error);
+
+ config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR "/conf.d", "",
+ "--state-file", TMP_FILE, NULL);
+ g_assert (config);
+
+ state = nm_config_state_get (config);
+ g_assert (state);
+
+ g_assert_cmpint (state->net_enabled, ==, TRUE);
+ g_assert_cmpint (state->wifi_enabled, ==, TRUE);
+ g_assert_cmpint (state->wwan_enabled, ==, TRUE);
+
+ nm_config_state_set (config, TRUE, TRUE,
+ NM_CONFIG_STATE_PROPERTY_NETWORKING_ENABLED, FALSE,
+ NM_CONFIG_STATE_PROPERTY_WIFI_ENABLED, TRUE,
+ NM_CONFIG_STATE_PROPERTY_WWAN_ENABLED, FALSE);
+
+ state = nm_config_state_get (config);
+ g_assert (state);
+
+ g_assert_cmpint (state->net_enabled, ==, FALSE);
+ g_assert_cmpint (state->wifi_enabled, ==, TRUE);
+ g_assert_cmpint (state->wwan_enabled, ==, FALSE);
+
+ g_object_unref (config);
+
+ /* Reload configuration */
+ config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR "/conf.d", "",
+ "--state-file", TMP_FILE, NULL);
+ g_assert (config);
+
+ state = nm_config_state_get (config);
+ g_assert (state);
+
+ g_assert_cmpint (state->net_enabled, ==, FALSE);
+ g_assert_cmpint (state->wifi_enabled, ==, TRUE);
+ g_assert_cmpint (state->wwan_enabled, ==, FALSE);
+
+ g_object_unref (config);
+ unlink (TMP_FILE);
+}
+
+/*****************************************************************************/
+
NMTST_DEFINE ();
int
@@ -960,6 +1019,8 @@ main (int argc, char **argv)
g_test_add_func ("/config/enable", test_config_enable);
+ g_test_add_func ("/config/state-file", test_config_state_file);
+
/* This one has to come last, because it leaves its values in
* nm-config.c's global variables, and there's no way to reset
* those to NULL.
diff --git a/src/tests/test-dcb.c b/src/tests/test-dcb.c
index e8e1ec860b..0a133de369 100644
--- a/src/tests/test-dcb.c
+++ b/src/tests/test-dcb.c
@@ -24,7 +24,7 @@
#include "nm-dcb.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
typedef struct {
guint num;
diff --git a/src/tests/test-general-with-expect.c b/src/tests/test-general-with-expect.c
index 64b47bd38c..ab2b15b5f2 100644
--- a/src/tests/test-general-with-expect.c
+++ b/src/tests/test-general-with-expect.c
@@ -30,7 +30,7 @@
#include "NetworkManagerUtils.h"
#include "nm-multi-index.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
#ifndef CLOCK_BOOTTIME
#define CLOCK_BOOTTIME 7
diff --git a/src/tests/test-general.c b/src/tests/test-general.c
index a45357e810..d29cdc0eed 100644
--- a/src/tests/test-general.c
+++ b/src/tests/test-general.c
@@ -26,7 +26,7 @@
#include "NetworkManagerUtils.h"
#include "nm-core-internal.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
/* Reference implementation for nm_utils_ip6_address_clear_host_address.
* Taken originally from set_address_masked(), src/rdisc/nm-lndp-rdisc.c
diff --git a/src/tests/test-ip4-config.c b/src/tests/test-ip4-config.c
index 9d38dc27b7..95b221bc0c 100644
--- a/src/tests/test-ip4-config.c
+++ b/src/tests/test-ip4-config.c
@@ -26,7 +26,7 @@
#include "nm-ip4-config.h"
#include "nm-platform.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
static NMIP4Config *
build_test_config (void)
@@ -161,18 +161,18 @@ test_compare_with_source (void)
/* Address */
addr = *nmtst_platform_ip4_address ("1.2.3.4", NULL, 24);
- addr.source = NM_IP_CONFIG_SOURCE_USER;
+ addr.addr_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip4_config_add_address (a, &addr);
- addr.source = NM_IP_CONFIG_SOURCE_VPN;
+ addr.addr_source = NM_IP_CONFIG_SOURCE_VPN;
nm_ip4_config_add_address (b, &addr);
/* Route */
route = *nmtst_platform_ip4_route ("10.0.0.0", 8, "192.168.1.1");
- route.source = NM_IP_CONFIG_SOURCE_USER;
+ route.rt_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip4_config_add_route (a, &route);
- route.source = NM_IP_CONFIG_SOURCE_VPN;
+ route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
nm_ip4_config_add_route (b, &route);
/* Assert that the configs are basically the same, eg that the source is ignored */
@@ -193,31 +193,31 @@ test_add_address_with_source (void)
/* Test that a higher priority source is not overwritten */
addr = *nmtst_platform_ip4_address ("1.2.3.4", NULL, 24);
- addr.source = NM_IP_CONFIG_SOURCE_USER;
+ addr.addr_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip4_config_add_address (a, &addr);
test_addr = nm_ip4_config_get_address (a, 0);
- g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_USER);
+ g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER);
- addr.source = NM_IP_CONFIG_SOURCE_VPN;
+ addr.addr_source = NM_IP_CONFIG_SOURCE_VPN;
nm_ip4_config_add_address (a, &addr);
test_addr = nm_ip4_config_get_address (a, 0);
- g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_USER);
+ g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER);
/* Test that a lower priority address source is overwritten */
nm_ip4_config_del_address (a, 0);
- addr.source = NM_IP_CONFIG_SOURCE_KERNEL;
+ addr.addr_source = NM_IP_CONFIG_SOURCE_KERNEL;
nm_ip4_config_add_address (a, &addr);
test_addr = nm_ip4_config_get_address (a, 0);
- g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_KERNEL);
+ g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_KERNEL);
- addr.source = NM_IP_CONFIG_SOURCE_USER;
+ addr.addr_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip4_config_add_address (a, &addr);
test_addr = nm_ip4_config_get_address (a, 0);
- g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_USER);
+ g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER);
g_object_unref (a);
}
@@ -233,31 +233,31 @@ test_add_route_with_source (void)
/* Test that a higher priority source is not overwritten */
route = *nmtst_platform_ip4_route ("1.2.3.4", 24, "1.2.3.1");
- route.source = NM_IP_CONFIG_SOURCE_USER;
+ route.rt_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip4_config_add_route (a, &route);
test_route = nm_ip4_config_get_route (a, 0);
- g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_USER);
+ g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER);
- route.source = NM_IP_CONFIG_SOURCE_VPN;
+ route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
nm_ip4_config_add_route (a, &route);
test_route = nm_ip4_config_get_route (a, 0);
- g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_USER);
+ g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER);
/* Test that a lower priority address source is overwritten */
nm_ip4_config_del_route (a, 0);
- route.source = NM_IP_CONFIG_SOURCE_KERNEL;
+ route.rt_source = NM_IP_CONFIG_SOURCE_KERNEL;
nm_ip4_config_add_route (a, &route);
test_route = nm_ip4_config_get_route (a, 0);
- g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_KERNEL);
+ g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_KERNEL);
- route.source = NM_IP_CONFIG_SOURCE_USER;
+ route.rt_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip4_config_add_route (a, &route);
test_route = nm_ip4_config_get_route (a, 0);
- g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_USER);
+ g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER);
g_object_unref (a);
}
diff --git a/src/tests/test-ip6-config.c b/src/tests/test-ip6-config.c
index 5a2bb58905..3eceec0cbe 100644
--- a/src/tests/test-ip6-config.c
+++ b/src/tests/test-ip6-config.c
@@ -26,7 +26,7 @@
#include "nm-ip6-config.h"
#include "nm-platform.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
static NMIP6Config *
build_test_config (void)
@@ -132,18 +132,18 @@ test_compare_with_source (void)
/* Address */
addr = *nmtst_platform_ip6_address ("1122:3344:5566::7788", NULL, 64);
- addr.source = NM_IP_CONFIG_SOURCE_USER;
+ addr.addr_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip6_config_add_address (a, &addr);
- addr.source = NM_IP_CONFIG_SOURCE_VPN;
+ addr.addr_source = NM_IP_CONFIG_SOURCE_VPN;
nm_ip6_config_add_address (b, &addr);
/* Route */
route = *nmtst_platform_ip6_route ("abcd:1234:4321::", 24, "abcd:1234:4321:cdde::2");
- route.source = NM_IP_CONFIG_SOURCE_USER;
+ route.rt_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip6_config_add_route (a, &route);
- route.source = NM_IP_CONFIG_SOURCE_VPN;
+ route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
nm_ip6_config_add_route (b, &route);
/* Assert that the configs are basically the same, eg that the source is ignored */
@@ -164,31 +164,31 @@ test_add_address_with_source (void)
/* Test that a higher priority source is not overwritten */
addr = *nmtst_platform_ip6_address ("1122:3344:5566::7788", NULL, 64);
- addr.source = NM_IP_CONFIG_SOURCE_USER;
+ addr.addr_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip6_config_add_address (a, &addr);
test_addr = nm_ip6_config_get_address (a, 0);
- g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_USER);
+ g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER);
- addr.source = NM_IP_CONFIG_SOURCE_VPN;
+ addr.addr_source = NM_IP_CONFIG_SOURCE_VPN;
nm_ip6_config_add_address (a, &addr);
test_addr = nm_ip6_config_get_address (a, 0);
- g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_USER);
+ g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER);
/* Test that a lower priority address source is overwritten */
nm_ip6_config_del_address (a, 0);
- addr.source = NM_IP_CONFIG_SOURCE_KERNEL;
+ addr.addr_source = NM_IP_CONFIG_SOURCE_KERNEL;
nm_ip6_config_add_address (a, &addr);
test_addr = nm_ip6_config_get_address (a, 0);
- g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_KERNEL);
+ g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_KERNEL);
- addr.source = NM_IP_CONFIG_SOURCE_USER;
+ addr.addr_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip6_config_add_address (a, &addr);
test_addr = nm_ip6_config_get_address (a, 0);
- g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_USER);
+ g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER);
g_object_unref (a);
}
@@ -204,31 +204,31 @@ test_add_route_with_source (void)
/* Test that a higher priority source is not overwritten */
route = *nmtst_platform_ip6_route ("abcd:1234:4321::", 24, "abcd:1234:4321:cdde::2");
- route.source = NM_IP_CONFIG_SOURCE_USER;
+ route.rt_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip6_config_add_route (a, &route);
test_route = nm_ip6_config_get_route (a, 0);
- g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_USER);
+ g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER);
- route.source = NM_IP_CONFIG_SOURCE_VPN;
+ route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
nm_ip6_config_add_route (a, &route);
test_route = nm_ip6_config_get_route (a, 0);
- g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_USER);
+ g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER);
/* Test that a lower priority address source is overwritten */
nm_ip6_config_del_route (a, 0);
- route.source = NM_IP_CONFIG_SOURCE_KERNEL;
+ route.rt_source = NM_IP_CONFIG_SOURCE_KERNEL;
nm_ip6_config_add_route (a, &route);
test_route = nm_ip6_config_get_route (a, 0);
- g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_KERNEL);
+ g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_KERNEL);
- route.source = NM_IP_CONFIG_SOURCE_USER;
+ route.rt_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip6_config_add_route (a, &route);
test_route = nm_ip6_config_get_route (a, 0);
- g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_USER);
+ g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER);
g_object_unref (a);
}
diff --git a/src/tests/test-resolvconf-capture.c b/src/tests/test-resolvconf-capture.c
index 31b6e1777f..32bc97342a 100644
--- a/src/tests/test-resolvconf-capture.c
+++ b/src/tests/test-resolvconf-capture.c
@@ -28,7 +28,7 @@
#include "nm-ip6-config.h"
#include "nm-platform.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
static void
test_capture_empty (void)
diff --git a/src/tests/test-route-manager.c b/src/tests/test-route-manager.c
index c753174d8e..b81c263c08 100644
--- a/src/tests/test-route-manager.c
+++ b/src/tests/test-route-manager.c
@@ -23,12 +23,11 @@
#include <arpa/inet.h>
#include <linux/rtnetlink.h>
-#include "test-common.h"
-
#include "nm-platform.h"
+#include "nm-platform-utils.h"
#include "nm-route-manager.h"
-#include "nm-test-utils.h"
+#include "test-common.h"
typedef struct {
int ifindex0, ifindex1;
@@ -45,7 +44,7 @@ setup_dev0_ip4 (int ifindex, guint mss_of_first_route, guint32 metric_of_second_
route.ifindex = ifindex;
route.mss = 0;
- route.source = NM_IP_CONFIG_SOURCE_USER;
+ route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
inet_pton (AF_INET, "6.6.6.0", &route.network);
route.plen = 24;
route.gateway = INADDR_ANY;
@@ -53,7 +52,7 @@ setup_dev0_ip4 (int ifindex, guint mss_of_first_route, guint32 metric_of_second_
route.mss = mss_of_first_route;
g_array_append_val (routes, route);
- route.source = NM_IP_CONFIG_SOURCE_USER;
+ route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
inet_pton (AF_INET, "7.0.0.0", &route.network);
route.plen = 8;
inet_pton (AF_INET, "6.6.6.1", &route.gateway);
@@ -87,21 +86,21 @@ setup_dev1_ip4 (int ifindex)
route.mss))
g_assert_not_reached ();
- route.source = NM_IP_CONFIG_SOURCE_USER;
+ route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
inet_pton (AF_INET, "6.6.6.0", &route.network);
route.plen = 24;
route.gateway = INADDR_ANY;
route.metric = 20;
g_array_append_val (routes, route);
- route.source = NM_IP_CONFIG_SOURCE_USER;
+ route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
inet_pton (AF_INET, "7.0.0.0", &route.network);
route.plen = 8;
route.gateway = INADDR_ANY;
route.metric = 22;
g_array_append_val (routes, route);
- route.source = NM_IP_CONFIG_SOURCE_USER;
+ route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
inet_pton (AF_INET, "8.0.0.0", &route.network);
route.plen = 8;
inet_pton (AF_INET, "6.6.6.2", &route.gateway);
@@ -121,14 +120,14 @@ update_dev0_ip4 (int ifindex)
route.ifindex = ifindex;
route.mss = 0;
- route.source = NM_IP_CONFIG_SOURCE_USER;
+ route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
inet_pton (AF_INET, "6.6.6.0", &route.network);
route.plen = 24;
route.gateway = INADDR_ANY;
route.metric = 20;
g_array_append_val (routes, route);
- route.source = NM_IP_CONFIG_SOURCE_USER;
+ route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
inet_pton (AF_INET, "7.0.0.0", &route.network);
route.plen = 8;
route.gateway = INADDR_ANY;
@@ -163,7 +162,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
NMPlatformIP4Route state1[] = {
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = nmtst_inet4_from_string ("6.6.6.0"),
.plen = 24,
.ifindex = fixture->ifindex0,
@@ -173,7 +172,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = nmtst_inet4_from_string ("7.0.0.0"),
.plen = 8,
.ifindex = fixture->ifindex0,
@@ -183,7 +182,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.scope_inv = nm_platform_route_scope_inv (RT_SCOPE_UNIVERSE),
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = nmtst_inet4_from_string ("7.0.0.0"),
.plen = 8,
.ifindex = fixture->ifindex1,
@@ -193,7 +192,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = nmtst_inet4_from_string ("6.6.6.0"),
.plen = 24,
.ifindex = fixture->ifindex1,
@@ -203,7 +202,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = nmtst_inet4_from_string ("8.0.0.0"),
.plen = 8,
.ifindex = fixture->ifindex1,
@@ -216,7 +215,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
NMPlatformIP4Route state2[] = {
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = nmtst_inet4_from_string ("6.6.6.0"),
.plen = 24,
.ifindex = fixture->ifindex0,
@@ -226,7 +225,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = nmtst_inet4_from_string ("7.0.0.0"),
.plen = 8,
.ifindex = fixture->ifindex0,
@@ -236,7 +235,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = nmtst_inet4_from_string ("7.0.0.0"),
.plen = 8,
.ifindex = fixture->ifindex1,
@@ -246,7 +245,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = nmtst_inet4_from_string ("6.6.6.0"),
.plen = 24,
.ifindex = fixture->ifindex1,
@@ -256,7 +255,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = nmtst_inet4_from_string ("8.0.0.0"),
.plen = 8,
.ifindex = fixture->ifindex1,
@@ -269,7 +268,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
NMPlatformIP4Route state3[] = {
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = nmtst_inet4_from_string ("7.0.0.0"),
.plen = 8,
.ifindex = fixture->ifindex1,
@@ -279,7 +278,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = nmtst_inet4_from_string ("6.6.6.0"),
.plen = 24,
.ifindex = fixture->ifindex1,
@@ -289,7 +288,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = nmtst_inet4_from_string ("8.0.0.0"),
.plen = 8,
.ifindex = fixture->ifindex1,
@@ -299,7 +298,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.scope_inv = nm_platform_route_scope_inv (RT_SCOPE_UNIVERSE),
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = nmtst_inet4_from_string ("6.6.6.0"),
.plen = 24,
.ifindex = fixture->ifindex1,
@@ -542,7 +541,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
NMPlatformIP6Route state1[] = {
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:8086::"),
.plen = 48,
.ifindex = fixture->ifindex0,
@@ -551,7 +550,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:1337::"),
.plen = 48,
.ifindex = fixture->ifindex0,
@@ -560,7 +559,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:abad:c0de::"),
.plen = 64,
.ifindex = fixture->ifindex0,
@@ -569,7 +568,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:abad:c0de::"),
.plen = 64,
.ifindex = fixture->ifindex1,
@@ -578,7 +577,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:1337::"),
.plen = 48,
.ifindex = fixture->ifindex1,
@@ -587,7 +586,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:8086::"),
.plen = 48,
.ifindex = fixture->ifindex1,
@@ -596,7 +595,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:d34d::"),
.plen = 64,
.ifindex = fixture->ifindex1,
@@ -608,7 +607,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
NMPlatformIP6Route state2[] = {
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:8086::"),
.plen = 48,
.ifindex = fixture->ifindex0,
@@ -617,7 +616,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:1337::"),
.plen = 48,
.ifindex = fixture->ifindex0,
@@ -626,7 +625,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:abad:c0de::"),
.plen = 64,
.ifindex = fixture->ifindex0,
@@ -635,7 +634,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:abad:c0de::"),
.plen = 64,
.ifindex = fixture->ifindex1,
@@ -644,7 +643,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:1337::"),
.plen = 48,
.ifindex = fixture->ifindex1,
@@ -653,7 +652,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:8086::"),
.plen = 48,
.ifindex = fixture->ifindex1,
@@ -662,7 +661,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:d34d::"),
.plen = 64,
.ifindex = fixture->ifindex1,
@@ -674,7 +673,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
NMPlatformIP6Route state3[] = {
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:abad:c0de::"),
.plen = 64,
.ifindex = fixture->ifindex1,
@@ -683,7 +682,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:8086::"),
.plen = 48,
.ifindex = fixture->ifindex1,
@@ -692,7 +691,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:1337::"),
.plen = 48,
.ifindex = fixture->ifindex1,
@@ -701,7 +700,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:1337::"),
.plen = 48,
.ifindex = fixture->ifindex1,
@@ -710,7 +709,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:8086::"),
.plen = 48,
.ifindex = fixture->ifindex1,
@@ -719,7 +718,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
.mss = 0,
},
{
- .source = NM_IP_CONFIG_SOURCE_USER,
+ .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
.network = *nmtst_inet6_from_string ("2001:db8:d34d::"),
.plen = 64,
.ifindex = fixture->ifindex1,
@@ -787,6 +786,7 @@ static void
_assert_route_check (const NMPlatformVTableRoute *vtable, gboolean has, const NMPlatformIPXRoute *route)
{
const NMPlatformIPXRoute *r;
+ NMPlatformIPXRoute c;
g_assert (route);
@@ -800,11 +800,18 @@ _assert_route_check (const NMPlatformVTableRoute *vtable, gboolean has, const NM
} else {
char buf[sizeof (_nm_utils_to_string_buffer)];
- if (!r || vtable->route_cmp (route, r) != 0)
+ if (r) {
+ if (vtable->is_ip4)
+ c.r4 = route->r4;
+ else
+ c.r6 = route->r6;
+ c.rx.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (c.rx.rt_source);
+ }
+ if (!r || vtable->route_cmp (r, &c) != 0) {
g_error ("Invalid route. Expect %s, has %s",
- vtable->route_to_string (route, NULL, 0),
+ vtable->route_to_string (&c, NULL, 0),
vtable->route_to_string (r, buf, sizeof (buf)));
- g_assert (r);
+ }
}
}
diff --git a/src/tests/test-systemd.c b/src/tests/test-systemd.c
index 936bff204f..2dcb7af632 100644
--- a/src/tests/test-systemd.c
+++ b/src/tests/test-systemd.c
@@ -25,7 +25,7 @@
#include "sd-lldp.h"
#include "sd-event.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
/*****************************************************************************/
diff --git a/src/tests/test-utils.c b/src/tests/test-utils.c
index 6fc3978b9c..2cd8b8588d 100644
--- a/src/tests/test-utils.c
+++ b/src/tests/test-utils.c
@@ -26,7 +26,7 @@
#include "nm-core-utils.c"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
static void
test_stable_privacy (void)
diff --git a/src/tests/test-wired-defname.c b/src/tests/test-wired-defname.c
index 6edd5ff246..3ae3a19d95 100644
--- a/src/tests/test-wired-defname.c
+++ b/src/tests/test-wired-defname.c
@@ -24,7 +24,7 @@
#include "nm-setting-connection.h"
#include "nm-device-ethernet-utils.h"
-#include "nm-test-utils.h"
+#include "nm-test-utils-core.h"
static NMConnection *
_new_connection (const char *id)
@@ -41,12 +41,28 @@ _new_connection (const char *id)
/*******************************************/
+static char *
+_get_default_wired_name (GSList *list)
+{
+ gs_free NMConnection **v = NULL;
+ guint l, i;
+
+ l = g_slist_length (list);
+ v = g_new0 (NMConnection *, l + 1);
+ for (i = 0; list; list = list->next, i++)
+ v[i] = NM_CONNECTION (list->data);
+ g_assert (i == l);
+ return nm_device_ethernet_utils_get_default_wired_name (v);
+}
+
+/*******************************************/
+
static void
test_defname_no_connections (void)
{
gs_free char *name = NULL;
- name = nm_device_ethernet_utils_get_default_wired_name (NULL);
+ name = _get_default_wired_name (NULL);
g_assert_cmpstr (name, ==, "Wired connection 1");
}
@@ -62,7 +78,7 @@ test_defname_no_conflict (void)
list = g_slist_append (list, _new_connection ("work wifi"));
list = g_slist_append (list, _new_connection ("random gsm connection"));
- name = nm_device_ethernet_utils_get_default_wired_name (list);
+ name = _get_default_wired_name (list);
g_assert_cmpstr (name, ==, "Wired connection 1");
g_slist_free_full (list, g_object_unref);
@@ -80,7 +96,7 @@ test_defname_conflict (void)
list = g_slist_append (list, _new_connection ("Wired connection 1"));
list = g_slist_append (list, _new_connection ("random gsm connection"));
- name = nm_device_ethernet_utils_get_default_wired_name (list);
+ name = _get_default_wired_name (list);
g_assert_cmpstr (name, ==, "Wired connection 2");
g_slist_free_full (list, g_object_unref);
@@ -102,7 +118,7 @@ test_defname_multiple_conflicts (void)
list = g_slist_append (list, _new_connection ("work wifi"));
list = g_slist_append (list, _new_connection ("a vpn"));
- name = nm_device_ethernet_utils_get_default_wired_name (list);
+ name = _get_default_wired_name (list);
g_assert_cmpstr (name, ==, "Wired connection 4");
g_slist_free_full (list, g_object_unref);
diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c
index 31b94752af..b2aa8f6bc6 100644
--- a/src/vpn-manager/nm-vpn-connection.c
+++ b/src/vpn-manager/nm-vpn-connection.c
@@ -27,6 +27,8 @@
#include <arpa/inet.h>
#include <errno.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
#include "nm-vpn-connection.h"
#include "nm-ip4-config.h"
@@ -44,6 +46,7 @@
#include "nm-config.h"
#include "nm-vpn-plugin-info.h"
#include "nm-vpn-manager.h"
+#include "nm-dns-manager.h"
#include "nmdbus-vpn-connection.h"
@@ -192,14 +195,14 @@ __LOG_create_prefix (char *buf, NMVpnConnection *self)
"%s%s" /*con-uuid*/
"%s%s%s%s" /*con-id*/
",%d" /*ifindex*/
- "%s%s%s%s" /*iface*/
+ "%s%s%s" /*iface*/
"]",
_NMLOG_PREFIX_NAME,
self,
con ? "," : "--", con ? (nm_connection_get_uuid (con) ?: "??") : "",
con ? "," : "", NM_PRINT_FMT_QUOTED (id, "\"", id, "\"", con ? "??" : ""),
priv->ip_ifindex,
- priv->ip_iface ? ":" : "", NM_PRINT_FMT_QUOTED (priv->ip_iface, "(", priv->ip_iface, ")", "")
+ NM_PRINT_FMT_QUOTED (priv->ip_iface, ":(", priv->ip_iface, ")", "")
);
return buf;
@@ -680,7 +683,7 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32
if (nm_ip4_config_destination_is_direct (parent_config, vpn_gw, 32))
route.gateway = 0;
- route.source = NM_IP_CONFIG_SOURCE_VPN;
+ route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
route.metric = route_metric;
nm_ip4_config_add_route (config, &route);
@@ -692,7 +695,7 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32
memset (&route, 0, sizeof (route));
route.network = parent_gw;
route.plen = 32;
- route.source = NM_IP_CONFIG_SOURCE_VPN;
+ route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
route.metric = route_metric;
nm_ip4_config_add_route (config, &route);
@@ -732,7 +735,7 @@ add_ip6_vpn_gateway_route (NMIP6Config *config,
if (nm_ip6_config_destination_is_direct (parent_config, vpn_gw, 128))
route.gateway = in6addr_any;
- route.source = NM_IP_CONFIG_SOURCE_VPN;
+ route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
route.metric = route_metric;
nm_ip6_config_add_route (config, &route);
@@ -744,7 +747,7 @@ add_ip6_vpn_gateway_route (NMIP6Config *config,
memset (&route, 0, sizeof (route));
route.network = *parent_gw;
route.plen = 128;
- route.source = NM_IP_CONFIG_SOURCE_VPN;
+ route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
route.metric = route_metric;
nm_ip6_config_add_route (config, &route);
@@ -909,7 +912,7 @@ print_vpn_config (NMVpnConnection *self)
nm_utils_inet6_ntop (priv->ip6_external_gw, NULL));
}
- _LOGI ("Data: Tunnel Device: %s", priv->ip_iface ? priv->ip_iface : "(none)");
+ _LOGI ("Data: Tunnel Device: %s%s%s", NM_PRINT_FMT_QUOTE_STRING (priv->ip_iface));
if (priv->ip4_config) {
_LOGI ("Data: IPv4 configuration:");
@@ -1218,6 +1221,8 @@ process_generic_config (NMVpnConnection *self, GVariant *dict)
}
g_clear_pointer (&priv->ip_iface, g_free);
+ priv->ip_ifindex = 0;
+
if (g_variant_lookup (dict, NM_VPN_PLUGIN_CONFIG_TUNDEV, "&s", &str)) {
/* Backwards compat with NM-openswan */
if (g_strcmp0 (str, "_none_") != 0)
@@ -1228,7 +1233,13 @@ process_generic_config (NMVpnConnection *self, GVariant *dict)
/* Grab the interface index for address/routing operations */
priv->ip_ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, priv->ip_iface);
if (priv->ip_ifindex <= 0) {
+ nm_platform_process_events (NM_PLATFORM_GET);
+ priv->ip_ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, priv->ip_iface);
+ }
+ if (priv->ip_ifindex <= 0) {
_LOGE ("failed to look up VPN interface index for \"%s\"", priv->ip_iface);
+ g_clear_pointer (&priv->ip_iface, g_free);
+ priv->ip_ifindex = 0;
nm_vpn_connection_config_maybe_complete (self, FALSE);
return FALSE;
}
@@ -1329,7 +1340,6 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
const char *str;
GVariant *v;
gboolean b;
- int ifindex;
g_return_if_fail (dict && g_variant_is_of_type (dict, G_VARIANT_TYPE_VARDICT));
@@ -1357,13 +1367,8 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
priv->has_ip6 = FALSE;
}
- if (priv->ip_ifindex > 0) {
- ifindex = priv->ip_ifindex;
- } else {
- NMDevice *parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (self));
- ifindex = nm_device_get_ip_ifindex (parent_dev);
- }
- config = nm_ip4_config_new (ifindex);
+ config = nm_ip4_config_new (nm_vpn_connection_get_ip_ifindex (self, TRUE));
+ nm_ip4_config_set_dns_priority (config, NM_DNS_PRIORITY_DEFAULT_VPN);
memset (&address, 0, sizeof (address));
address.plen = 24;
@@ -1386,7 +1391,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
address.plen = u32;
if (address.address && address.plen && address.plen <= 32) {
- address.source = NM_IP_CONFIG_SOURCE_VPN;
+ address.addr_source = NM_IP_CONFIG_SOURCE_VPN;
nm_ip4_config_add_address (config, &address);
} else {
_LOGW ("invalid IP4 config received!");
@@ -1435,7 +1440,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
g_variant_get_child (v, 2, "u", &route.gateway);
/* 4th item is unused route metric */
route.metric = route_metric;
- route.source = NM_IP_CONFIG_SOURCE_VPN;
+ route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
if (route.plen > 32)
break;
@@ -1497,6 +1502,7 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict)
}
config = nm_ip6_config_new (priv->ip_ifindex);
+ nm_ip6_config_set_dns_priority (config, NM_DNS_PRIORITY_DEFAULT_VPN);
memset (&address, 0, sizeof (address));
address.plen = 128;
@@ -1523,7 +1529,7 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict)
address.plen = u32;
if (!IN6_IS_ADDR_UNSPECIFIED (&address.address) && address.plen && address.plen <= 128) {
- address.source = NM_IP_CONFIG_SOURCE_VPN;
+ address.addr_source = NM_IP_CONFIG_SOURCE_VPN;
nm_ip6_config_add_address (config, &address);
} else {
_LOGW ("invalid IP6 config received!");
@@ -1575,7 +1581,7 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict)
route.plen = prefix;
ip6_addr_from_variant (next_hop, &route.gateway);
route.metric = route_metric;
- route.source = NM_IP_CONFIG_SOURCE_VPN;
+ route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
/* Ignore host routes to the VPN gateway since NM adds one itself.
* Since NM knows more about the routing situation than the VPN
@@ -1919,6 +1925,41 @@ _daemon_exec_timeout (gpointer data)
return G_SOURCE_REMOVE;
}
+static int
+_get_log_level (void)
+{
+ NMLogLevel level;
+
+ /* curiously enough, nm-logging also uses syslog. But it
+ * maps NMLogLevel differently to the syslog levels then we
+ * do here.
+ *
+ * The reason is, that LOG_NOTICE is already something worth
+ * highlighting in the journal, but we have 3 levels that are
+ * lower then LOG_NOTICE (LOGL_TRACE, LOGL_DEBUG, LOGL_INFO),
+ * On the other hand, syslog only defines LOG_DEBUG and LOG_INFO.
+ * Thus, we must map them differently.
+ *
+ * Inside the VPN plugin, you might want to treat LOG_NOTICE as
+ * as low severity, not worthy to be highlighted (like NM does). */
+
+ level = nm_logging_get_level (LOGD_VPN_PLUGIN);
+ if (level != _LOGL_OFF) {
+ if (level <= LOGL_TRACE)
+ return LOG_DEBUG;
+ if (level <= LOGL_DEBUG)
+ return LOG_INFO;
+ if (level <= LOGL_INFO)
+ return LOG_NOTICE;
+ if (level <= LOGL_WARN)
+ return LOG_WARNING;
+ if (level <= LOGL_ERR)
+ return LOG_ERR;
+ }
+
+ return LOG_EMERG;
+}
+
static gboolean
nm_vpn_service_daemon_exec (NMVpnConnection *self, GError **error)
{
@@ -1927,20 +1968,50 @@ nm_vpn_service_daemon_exec (NMVpnConnection *self, GError **error)
char *vpn_argv[4];
gboolean success = FALSE;
GError *spawn_error = NULL;
- int i = 0;
+ guint i, j, n_environ;
+ gs_free char **envp = NULL;
+ char env_log_level[NM_STRLEN ("NM_VPN_LOG_LEVEL=") + 100];
+ char env_log_syslog[NM_STRLEN ("NM_VPN_LOG_SYSLOG=") + 10];
+ const int N_ENVIRON_EXTRA = 3;
+ char **p_environ;
g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), FALSE);
+
priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+ i = 0;
vpn_argv[i++] = (char *) nm_vpn_plugin_info_get_program (priv->plugin_info);
+ g_return_val_if_fail (vpn_argv[0], FALSE);
if (nm_vpn_plugin_info_supports_multiple (priv->plugin_info)) {
vpn_argv[i++] = "--bus-name";
vpn_argv[i++] = priv->bus_name;
}
- vpn_argv[i] = NULL;
- g_assert (vpn_argv[0]);
+ vpn_argv[i++] = NULL;
+
+ /* we include <unistd.h> and "config.h" defines _GNU_SOURCE for us. So, we have @environ. */
+ p_environ = environ;
+ n_environ = p_environ ? g_strv_length (p_environ) : 0;
+ envp = g_new (char *, n_environ + N_ENVIRON_EXTRA);
+ for (i = 0, j = 0; j < n_environ; j++) {
+ if ( g_str_has_prefix (p_environ[j], "NM_VPN_LOG_LEVEL=")
+ || g_str_has_prefix (p_environ[j], "NM_VPN_LOG_SYSLOG="))
+ continue;
+ envp[i++] = p_environ[j];
+ }
- success = g_spawn_async (NULL, vpn_argv, NULL, 0, nm_utils_setpgid, NULL, &pid, &spawn_error);
+ /* NM_VPN_LOG_LEVEL: the syslog logging level for the plugin. */
+ envp[i++] = nm_sprintf_buf (env_log_level, "NM_VPN_LOG_LEVEL=%d", _get_log_level ());
+
+ /* NM_VPN_LOG_SYSLOG: whether to log to stdout or syslog. If NetworkManager itself runs in
+ * foreground, we also want the plugin to log to stdout.
+ * If the plugin runs in background, the plugin should prefer logging to syslog. Otherwise
+ * logging messages will be lost (unless using journald, in which case it wouldn't matter). */
+ envp[i++] = nm_sprintf_buf (env_log_syslog, "NM_VPN_LOG_SYSLOG=%c", nm_logging_syslog_enabled () ? '1' : '0');
+
+ envp[i++] = NULL;
+ nm_assert (i <= n_environ + N_ENVIRON_EXTRA);
+
+ success = g_spawn_async (NULL, vpn_argv, envp, 0, nm_utils_setpgid, NULL, &pid, &spawn_error);
if (success) {
_LOGI ("Started the VPN service, PID %ld", (long int) pid);
@@ -2016,10 +2087,8 @@ nm_vpn_connection_activate (NMVpnConnection *self,
s_vpn = nm_connection_get_setting_vpn (_get_applied_connection (self));
g_return_if_fail (s_vpn);
- service = nm_vpn_plugin_info_lookup_property (plugin_info,
- NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION,
- "service");
- g_return_if_fail (service);
+ service = nm_vpn_plugin_info_get_service (plugin_info);
+ nm_assert (service);
if (nm_vpn_plugin_info_supports_multiple (plugin_info)) {
const char *path;
@@ -2082,20 +2151,67 @@ nm_vpn_connection_get_ip6_config (NMVpnConnection *self)
return NM_VPN_CONNECTION_GET_PRIVATE (self)->ip6_config;
}
+static int
+_get_ip_iface_for_device (NMVpnConnection *self, const char **out_iface)
+{
+ NMDevice *parent_dev;
+ int ifindex;
+ const char *iface;
+
+ nm_assert (NM_IS_VPN_CONNECTION (self));
+
+ /* the ifindex and the ifname in this case should come together.
+ * They either must be both set, or none. */
+
+ parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (self));
+ if (!parent_dev)
+ goto none;
+ ifindex = nm_device_get_ip_ifindex (parent_dev);
+ if (ifindex <= 0)
+ goto none;
+ iface = nm_device_get_ip_iface (parent_dev);
+ if (!iface)
+ goto none;
+
+ NM_SET_OUT (out_iface, iface);
+ return ifindex;
+none:
+ NM_SET_OUT (out_iface, NULL);
+ return 0;
+}
+
const char *
-nm_vpn_connection_get_ip_iface (NMVpnConnection *self)
+nm_vpn_connection_get_ip_iface (NMVpnConnection *self, gboolean fallback_device)
{
+ NMVpnConnectionPrivate *priv;
+ const char *iface;
+
g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), NULL);
- return NM_VPN_CONNECTION_GET_PRIVATE (self)->ip_iface;
+ priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+
+ if (priv->ip_iface || !fallback_device)
+ return priv->ip_iface;
+
+ _get_ip_iface_for_device (self, &iface);
+ return iface;
}
int
-nm_vpn_connection_get_ip_ifindex (NMVpnConnection *self)
+nm_vpn_connection_get_ip_ifindex (NMVpnConnection *self, gboolean fallback_device)
{
- g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), -1);
+ NMVpnConnectionPrivate *priv;
+
+ g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), 0);
+
+ priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+
+ if (priv->ip_ifindex > 0)
+ return priv->ip_ifindex;
+ if (!fallback_device)
+ return 0;
- return NM_VPN_CONNECTION_GET_PRIVATE (self)->ip_ifindex;
+ return _get_ip_iface_for_device (self, NULL);
}
guint32
diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h
index 19b0eb3feb..6837432926 100644
--- a/src/vpn-manager/nm-vpn-connection.h
+++ b/src/vpn-manager/nm-vpn-connection.h
@@ -91,8 +91,8 @@ void nm_vpn_connection_disconnect (NMVpnConnection *self,
NMIP4Config * nm_vpn_connection_get_ip4_config (NMVpnConnection *self);
NMIP6Config * nm_vpn_connection_get_ip6_config (NMVpnConnection *self);
-const char * nm_vpn_connection_get_ip_iface (NMVpnConnection *self);
-int nm_vpn_connection_get_ip_ifindex (NMVpnConnection *self);
+const char * nm_vpn_connection_get_ip_iface (NMVpnConnection *self, gboolean fallback_device);
+int nm_vpn_connection_get_ip_ifindex (NMVpnConnection *self, gboolean fallback_device);
guint32 nm_vpn_connection_get_ip4_internal_gateway (NMVpnConnection *self);
struct in6_addr * nm_vpn_connection_get_ip6_internal_gateway (NMVpnConnection *self);