summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-05-31 14:31:29 +0200
committerThomas Haller <thaller@redhat.com>2016-06-01 13:30:00 +0200
commit19ea8f44b7a3931ccd038cb0afd48a09fd403413 (patch)
treeb0cf018ca749ffef9b0e6ec0ae4c2c2be8311dfd
parent70d194c159c80266140157db535700f8e44dbe0b (diff)
parentec53ed2cbaab754ddf1283658b5adfba8134e757 (diff)
downloadNetworkManager-th/nm-1-2-merge.tar.gz
all: merge branch 'master' into nm-1-2th/nm-1-2-merge
Since releasing 1.2.0, we maintain a stable branch 'nm-1-2' and implement new features on 'master'. Occasionally, we backport patches by cherry-picking from 'master'. While developing RHEL-7.3, we want essentially all those features and fixes from 'master' also show up in final RHEL-7.3, because that largely determines our priorities. One way to get 'master' stuff into RHEL-7.3, would be to release 1.4.0, and bring that to RHEL-7.3. The downside is, that we already have downstreams as a user of 'nm-1-2' branch (Ubuntu 16.04 LTS). Obviously, there are many useful and important fixes on 'master' that also should reach downstream. Would downstream also rebase with us to 1.4.0? Do we want to invest the effort to heavily maintain both a 'nm-1-4' and 'nm-1-2' branch upstream? After releasing 1.4.0, upstream has less motivation for the additional work to maintain an old-stable 'nm-1-2' branch. So I think this either means more work for upstream, or less upstream help with old-stable branch. The latter possibly also means a worse expirience for 'nm-1-2' users. The alternative is to bring 'nm-1-2' to RHEL-7.3, but that means we backport essentially everything from 'master'. Of course, that temporarily destabilizes our 'nm-1-2' somewhat (our 'master' is in a decent shape, so it shouldn't be that bad). It also means, that 'nm-1-2' will see large development/backporting efforts and thus our upstream stable branch isn't what one would traditionally consider a bugfix-only, stable branch. This is also exactly what we did for 'nm-1-0' branch at the RHEL-7.2 time and although it has downsides, I think it is preferable to above option. Upstream is not going to maintain a bugfix-only 'nm-1-2' branch. If somebody wants that, he must be prepared to do the work and maintain such a "stable" branch based on 1.2.2 himself. Do note, that 'master' is supposed to be backward compatible, and all the gazillion of changes that happend there are considered to be an improvement. Thus, we bring all those improvements to 'nm-1-2', not only bugfixes. Also note, that after this large merge we are going to take the time to test and fix possible regressions before releasing 1.2.4. You can also think of 1.2.4 as a new backward compatible version of NetworkManager and 'master' was the development branch towards that. Now, instead of cherry-picking basically everything, re-merge 'master' into 'nm-1-2'. The outcome is pretty similar, the difference is: + doing it in one rush is considerabily less work, and you can easily verify that the backports are correct via `git diff master`. + we anyway backport everything. Thus a real merge in our git history better represents what is happening. + with a real merge, git has a new merge-parent and future backports will less conflict. - we don't have a fine-grained history of cherry-picked patches on 'nm-1-2'. Instead, there is only this one merge-commit. Of course, the real history is all here and comes from 'master', on HEAD^2. - it also means, if downstream wants to patch 1.2.2 release, it must find the appropriate patch on HEAD^2. - the large merge plays less nice with git-annotate and git-bisect, but still acceptable. I think the time to do this is good, because - 'master' is in a relatively good shape - there are many useful fixes to backport - 1.2.4 is still a bit out, and we can find regressions that this merge may cause. - RHEL-7.3 is even farther away and thus all the testing effort immediately benefits 'nm-1-2'. Yet another alternative to a real merge or extensive cherry-picking would be to do a `git merge --squash master`. However, I think that a real merge better expresses what actually happened. Conflicts: clients/cli/settings.c clients/common/nm-vpn-helpers.c configure.ac libnm-core/Makefile.am libnm-core/nm-vpn-editor-plugin.c man/common.ent.in po/pt_BR.po po/sv.po shared/nm-macros-internal.h shared/nm-test-utils.h shared/nm-version-macros.h.in src/devices/bluetooth/nm-bluez-device.c src/devices/nm-device-ethernet.c src/devices/nm-device.c src/devices/nm-device.h src/devices/wwan/nm-modem-broadband.c src/dhcp-manager/nm-dhcp-systemd.c src/dns-manager/nm-dns-dnsmasq.c src/dns-manager/nm-dns-manager.c src/dnsmasq-manager/tests/test-dnsmasq-utils.c src/nm-auth-subject.c src/nm-connection-provider.c src/nm-connection-provider.h src/nm-core-utils.c src/nm-ip4-config.c src/nm-ip6-config.c src/nm-manager.c src/platform/nm-fake-platform.c src/platform/nm-linux-platform.c src/platform/nm-platform-utils.c src/platform/nm-platform-utils.h src/platform/nm-platform.c src/platform/nm-platform.h src/ppp-manager/nm-ppp-manager.c src/settings/nm-settings.c src/tests/test-ip4-config.c src/vpn-manager/nm-vpn-connection.c
-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);